summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-10-18 18:49:43 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-10-18 18:50:11 +0200
commit1603f8bf28fd7e747068f5d31b71aa3cad2da6e3 (patch)
tree982fdd55a352cf448f00d940c7ae2c5675ac7d5f
parent2da107644df4a032febd98fec81a1c13a5ce157b (diff)
-spg2xx: Added chip select callback and rudimentary ADC hookup. [Ryan Holtz]
-vii: Initial V.Smile support; BIOS runs, games do not. [Ryan Holtz] Note: V.Smile changes are currently very WIP, needs code cleanup. Just checking in so others can have a look.
-rw-r--r--src/devices/cpu/unsp/unsp.cpp11
-rw-r--r--src/devices/machine/spg2xx.cpp126
-rw-r--r--src/devices/machine/spg2xx.h4
-rw-r--r--src/mame/drivers/vii.cpp318
4 files changed, 356 insertions, 103 deletions
diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp
index 4d820214608..ca8b149fe5d 100644
--- a/src/devices/cpu/unsp/unsp.cpp
+++ b/src/devices/cpu/unsp/unsp.cpp
@@ -245,6 +245,7 @@ void unsp_device::trigger_irq(int line)
{
if (!m_enable_irq || m_irq || m_fiq)
{
+ //logerror("Enable %d, IRQ %d, FIQ %d, bailing\n", m_enable_irq ? 1 : 0, m_irq ? 1 : 0, m_fiq ? 1 : 0);
return;
}
@@ -279,10 +280,12 @@ void unsp_device::check_irqs()
if (highest_irq == UNSP_FIQ_LINE)
{
+ //logerror("Trying to trigger FIQ\n");
trigger_fiq();
}
else
{
+ //logerror("Trying to trigger IRQ\n");
trigger_irq(highest_irq - 1);
}
}
@@ -620,7 +623,7 @@ void unsp_device::execute_run()
case 0x00: // r, [bp+imm6]
m_icount -= 6;
- r2 = UNSP_REG(BP) + OPIMM;
+ r2 = (uint16_t)(UNSP_REG(BP) + OPIMM);
if (OP0 != 0x0d)
r1 = read16(r2);
break;
@@ -685,19 +688,19 @@ void unsp_device::execute_run()
if (OP0 != 0x0d)
r1 = read16(r2);
break;
- case 1: // r, [<ds:>r--]
+ case 1: // r, [r--]
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)--;
break;
- case 2: // r, [<ds:>r++]
+ case 2: // r, [r++]
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
r1 = read16(r2);
UNSP_REG_I(opb)++;
break;
- case 3: // r, [<ds:>++r]
+ case 3: // r, [++r]
UNSP_REG_I(opb)++;
r2 = UNSP_REG_I(opb);
if (OP0 != 0x0d)
diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp
index fa4a45d14ff..fb7e1c0e2ad 100644
--- a/src/devices/machine/spg2xx.cpp
+++ b/src/devices/machine/spg2xx.cpp
@@ -18,28 +18,34 @@ DEFINE_DEVICE_TYPE(SPG28X, spg28x_device, "spg28x", "SPG280-series System-on-a-C
#define LOG_IO_READS (1U << 0)
#define LOG_IO_WRITES (1U << 1)
-#define LOG_IRQS (1U << 2)
-#define LOG_VLINES (1U << 3)
-#define LOG_GPIO (1U << 4)
-#define LOG_UART (1U << 5)
-#define LOG_I2C (1U << 6)
-#define LOG_DMA (1U << 7)
-#define LOG_WATCHDOG (1U << 8)
-#define LOG_SPU_READS (1U << 9)
-#define LOG_SPU_WRITES (1U << 10)
-#define LOG_CHANNEL_READS (1U << 11)
-#define LOG_CHANNEL_WRITES (1U << 12)
-#define LOG_ENVELOPES (1U << 13)
-#define LOG_SAMPLES (1U << 14)
-#define LOG_RAMPDOWN (1U << 15)
-#define LOG_BEAT (1U << 16)
-#define LOG_PPU_READS (1U << 17)
-#define LOG_PPU_WRITES (1U << 18)
-#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_DMA)
+#define LOG_UNKNOWN_IO (1U << 2)
+#define LOG_IRQS (1U << 3)
+#define LOG_VLINES (1U << 4)
+#define LOG_GPIO (1U << 5)
+#define LOG_UART (1U << 6)
+#define LOG_I2C (1U << 7)
+#define LOG_DMA (1U << 8)
+#define LOG_SEGMENT (1U << 9)
+#define LOG_WATCHDOG (1U << 10)
+#define LOG_TIMERS (1U << 11)
+#define LOG_SPU_READS (1U << 12)
+#define LOG_SPU_WRITES (1U << 13)
+#define LOG_UNKNOWN_SPU (1U << 14)
+#define LOG_CHANNEL_READS (1U << 15)
+#define LOG_CHANNEL_WRITES (1U << 16)
+#define LOG_ENVELOPES (1U << 17)
+#define LOG_SAMPLES (1U << 18)
+#define LOG_RAMPDOWN (1U << 19)
+#define LOG_BEAT (1U << 20)
+#define LOG_PPU_READS (1U << 21)
+#define LOG_PPU_WRITES (1U << 22)
+#define LOG_UNKNOWN_PPU (1U << 23)
+#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_DMA | LOG_TIMERS | LOG_UNKNOWN_IO)
#define LOG_CHANNELS (LOG_CHANNEL_READS | LOG_CHANNEL_WRITES)
-#define LOG_SPU (LOG_SPU_READS | LOG_SPU_WRITES | LOG_CHANNEL_READS | LOG_CHANNEL_WRITES | LOG_ENVELOPES | LOG_SAMPLES | LOG_RAMPDOWN | LOG_BEAT)
-#define LOG_PPU (LOG_PPU_READS | LOG_PPU_WRITES)
-#define LOG_ALL (LOG_IO | LOG_SPU | LOG_PPU | LOG_VLINES)
+#define LOG_SPU (LOG_SPU_READS | LOG_SPU_WRITES | LOG_UNKNOWN_SPU | LOG_CHANNEL_READS | LOG_CHANNEL_WRITES \
+ | LOG_ENVELOPES | LOG_SAMPLES | LOG_RAMPDOWN | LOG_BEAT)
+#define LOG_PPU (LOG_PPU_READS | LOG_PPU_WRITES | LOG_UNKNOWN_PPU)
+#define LOG_ALL (LOG_IO | LOG_SPU | LOG_PPU | LOG_VLINES | LOG_SEGMENT)
#define VERBOSE (0)
#include "logmacro.h"
@@ -81,6 +87,7 @@ spg2xx_device::spg2xx_device(const machine_config &mconfig, device_type type, co
, m_eeprom_w(*this)
, m_eeprom_r(*this)
, m_uart_tx(*this)
+ , m_chip_sel(*this)
, m_cpu(*this, finder_base::DUMMY_TAG)
, m_screen(*this, finder_base::DUMMY_TAG)
, m_scrollram(*this, "scrollram")
@@ -127,6 +134,7 @@ void spg2xx_device::device_start()
m_eeprom_w.resolve_safe();
m_eeprom_r.resolve_safe(0);
m_uart_tx.resolve_safe();
+ m_chip_sel.resolve_safe();
m_tmb1 = timer_alloc(TIMER_TMB1);
m_tmb2 = timer_alloc(TIMER_TMB2);
@@ -597,7 +605,7 @@ READ16_MEMBER(spg2xx_device::video_r)
return VIDEO_IRQ_STATUS;
default:
- LOGMASKED(LOG_PPU_READS, "video_r: Unknown register %04x = %04x\n", 0x2800 + offset, m_video_regs[offset]);
+ LOGMASKED(LOG_UNKNOWN_PPU, "video_r: Unknown register %04x = %04x\n", 0x2800 + offset, m_video_regs[offset]);
break;
}
return m_video_regs[offset];
@@ -776,7 +784,7 @@ WRITE16_MEMBER(spg2xx_device::video_w)
break;
default:
- LOGMASKED(LOG_PPU_WRITES, "video_w: Unknown register %04x = %04x\n", 0x2800 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_PPU, "video_w: Unknown register %04x = %04x\n", 0x2800 + offset, data);
m_video_regs[offset] = data;
break;
}
@@ -845,6 +853,7 @@ void spg2xx_device::uart_rx(uint8_t data)
{
m_uart_rx_fifo[m_uart_rx_index] = data;
m_uart_rx_index++;
+ m_io_regs[0x31] |= 1;
if (m_uart_rx_index > (m_io_regs[0x37] & 7))
{
const uint16_t old = IO_IRQ_STATUS;
@@ -910,6 +919,11 @@ READ16_MEMBER(spg2xx_device::io_r)
LOGMASKED(LOG_IO_READS, "io_r: ADC Control = %04x\n", val);
break;
+ case 0x27: // ADC Data
+ m_io_regs[0x27] = 0;
+ LOGMASKED(LOG_IO_READS, "io_r: ADC Data = %04x\n", val);
+ break;
+
case 0x29: // Wakeup Source
LOGMASKED(LOG_IO_READS, "io_r: Wakeup Source = %04x\n", val);
break;
@@ -929,7 +943,7 @@ READ16_MEMBER(spg2xx_device::io_r)
case 0x2f: // Data Segment
val = m_cpu->state_int(UNSP_SR) >> 10;
- LOGMASKED(LOG_IO_READS, "io_r: Data Segment = %04x\n", val);
+ LOGMASKED(LOG_SEGMENT, "io_r: Data Segment = %04x\n", val);
break;
case 0x31: // UART Status
@@ -988,7 +1002,7 @@ READ16_MEMBER(spg2xx_device::io_r)
break;
default:
- LOGMASKED(LOG_IO_READS, "io_r: Unknown register %04x\n", 0x3d00 + offset);
+ LOGMASKED(LOG_UNKNOWN_IO, "io_r: Unknown register %04x\n", 0x3d00 + offset);
break;
}
@@ -1212,6 +1226,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
LOGMASKED(LOG_IO_WRITES, " WaitStates:%d, BusArbPrio:%s\n", (data >> 1) & 3, s_bus_arb[(data >> 3) & 7]);
LOGMASKED(LOG_IO_WRITES, " ROMAddrDecode:%s\n", s_addr_decode[(data >> 6) & 3]);
LOGMASKED(LOG_IO_WRITES, " RAMAddrDecode:%s\n", s_ram_decode[(data >> 8) & 15]);
+ m_chip_sel((data >> 6) & 3);
m_io_regs[offset] = data;
break;
}
@@ -1221,9 +1236,21 @@ WRITE16_MEMBER(spg2xx_device::io_w)
break;
case 0x25: // ADC Control
+ {
LOGMASKED(LOG_IO_WRITES, "io_w: ADC Control = %04x\n", data);
+ const uint16_t changed = m_io_regs[offset] ^ data;
m_io_regs[offset] = data;
+ if (BIT(changed, 12) && BIT(data, 12) && !BIT(m_io_regs[offset], 1))
+ {
+ m_io_regs[0x27] = 0x80ff;
+ const uint16_t old = IO_IRQ_STATUS;
+ IO_IRQ_STATUS |= 0x2000;
+ const uint16_t changed = IO_IRQ_STATUS ^ old;
+ if (changed)
+ check_irqs(changed);
+ }
break;
+ }
case 0x28: // Sleep Mode
LOGMASKED(LOG_IO_WRITES, "io_w: Sleep Mode (%s enter value) = %04x\n", data == 0xaa55 ? "valid" : "invalid", data);
@@ -1270,7 +1297,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
{
uint16_t ds = m_cpu->state_int(UNSP_SR);
m_cpu->set_state_int(UNSP_SR, (ds & 0x03ff) | ((data & 0x3f) << 10));
- LOGMASKED(LOG_IO_WRITES, "io_w: Data Segment = %04x\n", data);
+ LOGMASKED(LOG_SEGMENT, "io_w: Data Segment = %04x\n", data);
break;
}
@@ -1279,18 +1306,23 @@ WRITE16_MEMBER(spg2xx_device::io_w)
static const char* const s_9th_bit[4] = { "0", "1", "Odd", "Even" };
LOGMASKED(LOG_UART, "io_w: UART Control = %04x (TxEn:%d, RxEn:%d, Bits:%d, MultiProc:%d, 9thBit:%s, TxIntEn:%d, RxIntEn:%d\n", data
, BIT(data, 7), BIT(data, 6), BIT(data, 5) ? 9 : 8, BIT(data, 4), s_9th_bit[(data >> 2) & 3], BIT(data, 1), BIT(data, 0));
+ const uint16_t changed = m_io_regs[offset] ^ data;
m_io_regs[offset] = data;
if (!BIT(data, 6))
{
m_uart_rx_index = 0;
memset(m_uart_rx_fifo, 0, 8);
}
+ if (BIT(changed, 7) && BIT(data, 7))
+ {
+ m_io_regs[0x31] |= 0x0002;
+ }
break;
}
case 0x31: // UART Status
- LOGMASKED(LOG_UART, "io_w: UART Status (read only) = %04x\n", data);
- m_io_regs[offset] = data;
+ LOGMASKED(LOG_UART, "io_w: UART Status = %04x\n", data);
+ //m_io_regs[offset] &= ~data;
break;
case 0x33: // UART Baud Rate
@@ -1301,6 +1333,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
case 0x35: // UART TX Data
LOGMASKED(LOG_UART, "io_w: UART Tx Data = %02x\n", data & 0x00ff);
m_io_regs[offset] = data;
+ m_uart_tx((uint8_t)data);
break;
case 0x36: // UART RX Data
@@ -1382,7 +1415,7 @@ WRITE16_MEMBER(spg2xx_device::io_w)
break;
default:
- LOGMASKED(LOG_IO_WRITES, "io_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_IO, "io_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
m_io_regs[offset] = data;
break;
}
@@ -1394,21 +1427,17 @@ void spg2xx_device::device_timer(emu_timer &timer, device_timer_id id, int param
{
case TIMER_TMB1:
{
- const uint16_t old = (IO_IRQ_ENABLE & IO_IRQ_STATUS);
+ LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
IO_IRQ_STATUS |= 1;
- const uint16_t changed = old ^ (IO_IRQ_ENABLE & IO_IRQ_STATUS);
- if (changed)
- check_irqs(changed);
+ check_irqs(0x0001);
break;
}
case TIMER_TMB2:
{
- const uint16_t old = m_io_regs[0x22] & m_io_regs[0x21];
+ LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
IO_IRQ_STATUS |= 2;
- const uint16_t changed = old ^ (IO_IRQ_ENABLE & IO_IRQ_STATUS);
- if (changed)
- check_irqs(changed);
+ check_irqs(0x0002);
break;
}
@@ -1440,10 +1469,14 @@ void spg2xx_device::check_irqs(const uint16_t changed)
// }
if (changed & 0x0c00) // Timer A, Timer B IRQ
+ {
m_cpu->set_input_line(UNSP_IRQ2_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
+ }
if (changed & 0x2100) // UART, ADC IRQ
+ {
m_cpu->set_input_line(UNSP_IRQ3_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE);
+ }
if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) // Beat IRQ
{
@@ -1460,13 +1493,20 @@ void spg2xx_device::check_irqs(const uint16_t changed)
}
if (changed & 0x1200) // External IRQ
+ {
m_cpu->set_input_line(UNSP_IRQ5_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE);
+ }
if (changed & 0x0070) // 1024Hz, 2048Hz, 4096Hz IRQ
+ {
m_cpu->set_input_line(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
+ }
if (changed & 0x008b) // TMB1, TMB2, 4Hz, key change IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting timer IRQ (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
m_cpu->set_input_line(UNSP_IRQ7_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE);
+ }
}
void spg2xx_device::do_gpio(uint32_t offset)
@@ -1665,7 +1705,7 @@ READ16_MEMBER(spg2xx_device::audio_r)
break;
default:
- LOGMASKED(LOG_SPU_READS, "audio_r: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Unknown register %04x = %04x\n", 0x3000 + offset, data);
break;
}
}
@@ -1767,13 +1807,13 @@ READ16_MEMBER(spg2xx_device::audio_r)
break;
default:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Unknown register %04x\n", 0x3000 + offset);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Unknown register %04x\n", 0x3000 + offset);
break;
}
}
else if (channel >= 16)
{
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Trying to read from channel %d\n", channel);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Trying to read from channel %d\n", channel);
}
return data;
}
@@ -2039,7 +2079,7 @@ WRITE16_MEMBER(spg2xx_device::audio_w)
default:
m_audio_regs[offset] = data;
- LOGMASKED(LOG_SPU_WRITES, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
break;
}
}
@@ -2167,13 +2207,13 @@ WRITE16_MEMBER(spg2xx_device::audio_w)
default:
m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
break;
}
}
else if (channel >= 16)
{
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Trying to write to channel %d: %04x = %04x\n", channel, 0x3000 + offset, data);
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Trying to write to channel %d: %04x = %04x\n", channel, 0x3000 + offset, data);
}
else
{
diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h
index 534f655b3c0..3e85537dbef 100644
--- a/src/devices/machine/spg2xx.h
+++ b/src/devices/machine/spg2xx.h
@@ -44,6 +44,8 @@ public:
auto uart_tx() { return m_uart_tx.bind(); }
+ auto chip_select() { return m_chip_sel.bind(); }
+
void uart_rx(uint8_t data);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -456,6 +458,8 @@ protected:
devcb_write8 m_uart_tx;
+ devcb_write8 m_chip_sel;
+
emu_timer *m_tmb1;
emu_timer *m_tmb2;
emu_timer *m_screenpos_timer;
diff --git a/src/mame/drivers/vii.cpp b/src/mame/drivers/vii.cpp
index 85c999d71f5..a05a68c231b 100644
--- a/src/mame/drivers/vii.cpp
+++ b/src/mame/drivers/vii.cpp
@@ -77,9 +77,10 @@ Detailed list of bugs:
#include "emu.h"
#include "cpu/unsp/unsp.h"
-#include "machine/spg2xx.h"
+#include "machine/bankdev.h"
#include "machine/i2cmem.h"
#include "machine/nvram.h"
+#include "machine/spg2xx.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
@@ -100,7 +101,7 @@ public:
, m_debug_screen(*this, "debug_screen")
#endif
, m_spg(*this, "spg")
- , m_bank(*this, "cart")
+ , m_bank(*this, "cartbank")
, m_io_p1(*this, "P1")
, m_io_p2(*this, "P2")
, m_io_p3(*this, "P3")
@@ -142,7 +143,7 @@ protected:
required_device<screen_device> m_debug_screen;
#endif
required_device<spg2xx_device> m_spg;
- required_memory_bank m_bank;
+ optional_memory_bank m_bank;
protected:
DECLARE_WRITE_LINE_MEMBER(poll_controls);
@@ -152,7 +153,7 @@ protected:
virtual void machine_reset() override;
- void mem_map(address_map &map);
+ virtual void mem_map(address_map &map);
uint32_t m_current_bank;
@@ -178,6 +179,55 @@ protected:
DECLARE_READ16_MEMBER(rad_crik_hack_r);
};
+class vsmile_state : public spg2xx_game_state
+{
+public:
+ vsmile_state(const machine_config &mconfig, device_type type, const char *tag)
+ : spg2xx_game_state(mconfig, type, tag)
+ , m_cart(*this, "cartslot")
+ , m_bankdev(*this, "bank")
+ , m_cart_banks(*this, "cartbank%u", 0U)
+ { }
+
+ void vsmile(machine_config &config);
+ void vsmilep(machine_config &config);
+
+private:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ static const device_timer_id TIMER_PAD = 0;
+
+ virtual void mem_map(address_map &map) override;
+ void banked_map(address_map &map);
+
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart);
+
+ DECLARE_READ16_MEMBER(portb_r);
+ DECLARE_READ16_MEMBER(portc_r);
+ DECLARE_WRITE16_MEMBER(portb_w);
+ DECLARE_WRITE16_MEMBER(portc_w);
+
+ DECLARE_WRITE8_MEMBER(chip_sel_w);
+
+ DECLARE_WRITE8_MEMBER(uart_tx);
+
+ DECLARE_READ16_MEMBER(bank0_r);
+ DECLARE_READ16_MEMBER(bank1_r);
+ DECLARE_READ16_MEMBER(bank2_r);
+ DECLARE_READ16_MEMBER(bank3_r);
+ optional_device<generic_slot_device> m_cart;
+ memory_region *m_cart_rom;
+ required_device<address_map_bank_device> m_bankdev;
+ optional_memory_bank_array<4> m_cart_banks;
+
+ emu_timer *m_pad_timer;
+ uint8_t m_pad_counter;
+
+ uint16_t m_portb_data;
+ uint16_t m_portc_data;
+};
class spg2xx_cart_state : public spg2xx_game_state
{
@@ -188,33 +238,17 @@ public:
{ }
void vii(machine_config &config);
- void vsmile(machine_config &config);
- void vsmilep(machine_config &config);
-
- void init_vii();
private:
DECLARE_WRITE16_MEMBER(vii_portb_w);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(vii_cart);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(vsmile_cart);
-
- DECLARE_READ16_MEMBER(vsmile_porta_r);
- DECLARE_READ16_MEMBER(vsmile_portb_r);
- DECLARE_READ16_MEMBER(vsmile_portc_r);
- DECLARE_WRITE16_MEMBER(vsmile_porta_w);
- DECLARE_WRITE16_MEMBER(vsmile_portb_w);
- DECLARE_WRITE16_MEMBER(vsmile_portc_w);
virtual void machine_start() override;
virtual void machine_reset() override;
optional_device<generic_slot_device> m_cart;
memory_region *m_cart_rom;
-
- uint16_t m_vsmile_porta_data;
- uint16_t m_vsmile_portb_data;
- uint16_t m_vsmile_portc_data;
};
#define VERBOSE_LEVEL (4)
@@ -298,40 +332,119 @@ WRITE16_MEMBER(spg2xx_cart_state::vii_portb_w)
switch_bank(((data & 0x80) >> 7) | ((data & 0x20) >> 4));
}
-READ16_MEMBER(spg2xx_cart_state::vsmile_porta_r)
+void vsmile_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- logerror("V.Smile Port A read, pull mask %04x\n", mem_mask);
- return m_vsmile_porta_data & mem_mask;
+ if (id == TIMER_PAD)
+ {
+ m_pad_counter++;
+ if (m_pad_counter >= 100)
+ {
+ m_pad_counter = 0;
+ m_spg->uart_rx(0x55);
+ }
+ }
}
-READ16_MEMBER(spg2xx_cart_state::vsmile_portb_r)
+#define VSMILE_PORTB_CS1 0x0001
+#define VSMILE_PORTB_CS2 0x0002
+#define VSMILE_PORTB_CART 0x0004
+#define VSMILE_PORTB_RESET 0x0008
+#define VSMILE_PORTB_FRONT24 0x0010
+#define VSMILE_PORTB_OFF 0x0020
+#define VSMILE_PORTB_OFF_SW 0x0040
+#define VSMILE_PORTB_ON_SW 0x0080
+
+#define VSMILE_PORTC_VER 0x000f
+#define VSMILE_PORTC_LOGO 0x0010
+#define VSMILE_PORTC_TEST 0x0020
+#define VSMILE_PORTC_AMP 0x0040
+#define VSMILE_PORTC_SYSRESET 0x0080
+
+READ16_MEMBER(vsmile_state::bank0_r)
{
- logerror("V.Smile Port B read, pull mask %04x\n", mem_mask);
- return m_vsmile_portb_data & mem_mask;
+ const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset];
+ //printf("bank0_r: %06x: %04x\n", offset, data);
+ return data;
}
-READ16_MEMBER(spg2xx_cart_state::vsmile_portc_r)
+READ16_MEMBER(vsmile_state::bank1_r)
{
- logerror("V.Smile Port C read, pull mask %04x\n", mem_mask);
- return m_vsmile_portc_data & mem_mask;
+ const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset + 0x100000];
+ //printf("bank1_r: %06x: %04x\n", offset + 0x100000, data);
+ return data;
}
-WRITE16_MEMBER(spg2xx_cart_state::vsmile_porta_w)
+READ16_MEMBER(vsmile_state::bank2_r)
{
- logerror("V.Smile Port A write %04x, push mask %04x\n", data, mem_mask);
- m_vsmile_porta_data = data & mem_mask;
+ const uint16_t data = ((uint16_t*)m_cart_rom->base())[offset + 0x200000];
+ //printf("bank2_r: %06x: %04x\n", offset + 0x200000, data);
+ return data;
}
-WRITE16_MEMBER(spg2xx_cart_state::vsmile_portb_w)
+READ16_MEMBER(vsmile_state::bank3_r)
{
- logerror("V.Smile Port B write %04x, push mask %04x\n", data, mem_mask);
- m_vsmile_portb_data = data & mem_mask;
+ const uint16_t data = ((uint16_t*)memregion("maincpu")->base())[offset];
+ //printf("bank3_r: %06x: %04x\n", offset + 0x300000, data);
+ return data;
}
-WRITE16_MEMBER(spg2xx_cart_state::vsmile_portc_w)
+READ16_MEMBER(vsmile_state::portb_r)
{
- logerror("V.Smile Port C write %04x, push mask %04x\n", data, mem_mask);
- m_vsmile_portc_data = data & mem_mask;
+ //const uint8_t inputs = m_io_p2->read();
+ //const uint16_t input_bits = BIT(inputs, 0) ? VSMILE_PORTB_ON_SW : 0;
+ const uint16_t data = VSMILE_PORTB_ON_SW | (m_cart && m_cart->exists() ? VSMILE_PORTB_CART : 0);
+ logerror("V.Smile Port B read %04x, mask %04x\n", data, mem_mask);
+ //printf("V.Smile Port B read %04x, mask %04x\n", data, mem_mask);
+ return data;
+}
+
+READ16_MEMBER(vsmile_state::portc_r)
+{
+ const uint16_t data = VSMILE_PORTC_LOGO | 0x0004;
+ logerror("V.Smile Port C read %04x, mask %04x\n", data, mem_mask);
+ return data;
+}
+
+WRITE16_MEMBER(vsmile_state::portb_w)
+{
+ m_portb_data = data & mem_mask;
+ logerror("V.Smile Port B write %04x, mask %04x\n", m_portb_data, mem_mask);
+ //printf("V.Smile Port B write %04x, mask %04x\n", m_portb_data, mem_mask);
+}
+
+WRITE16_MEMBER(vsmile_state::portc_w)
+{
+ m_portc_data = data & mem_mask;
+ logerror("V.Smile Port C write %04x, mask %04x\n", m_portc_data, mem_mask);
+ //printf("V.Smile Port C write %04x, mask %04x\n", m_portc_data, mem_mask);
+ //printf("%02x ", data >> 8);
+}
+
+WRITE8_MEMBER(vsmile_state::uart_tx)
+{
+ logerror("UART Tx: %02x\n", data);
+}
+
+WRITE8_MEMBER(vsmile_state::chip_sel_w)
+{
+ logerror("Chip select mode: %d\n", data);
+ const uint16_t cart_offset = m_cart && m_cart->exists() ? 4 : 0;
+ switch (data)
+ {
+ case 0:
+ logerror("Setting bank %d\n", cart_offset);
+ m_bankdev->set_bank(cart_offset);
+ break;
+ case 1:
+ logerror("Setting bank %d\n", 1 + cart_offset);
+ m_bankdev->set_bank(1 + cart_offset);
+ break;
+ case 2:
+ case 3:
+ logerror("Setting bank %d\n", 2 + cart_offset);
+ m_bankdev->set_bank(2 + cart_offset);
+ break;
+ }
}
READ16_MEMBER(spg2xx_game_state::walle_portc_r)
@@ -382,7 +495,46 @@ READ16_MEMBER(spg2xx_game_state::jakks_porta_r)
void spg2xx_game_state::mem_map(address_map &map)
{
- map(0x000000, 0x3fffff).bankr("cart");
+ map(0x000000, 0x3fffff).bankr("cartbank");
+ map(0x000000, 0x003fff).m(m_spg, FUNC(spg2xx_device::map));
+}
+
+void vsmile_state::banked_map(address_map &map)
+{
+ map(0x0000000, 0x00fffff).rom().region("maincpu", 0);
+ map(0x0100000, 0x01fffff).rom().region("maincpu", 0);
+ map(0x0200000, 0x02fffff).rom().region("maincpu", 0);
+ map(0x0300000, 0x03fffff).rom().region("maincpu", 0);
+
+ map(0x0400000, 0x04fffff).rom().region("maincpu", 0);
+ map(0x0500000, 0x05fffff).rom().region("maincpu", 0);
+ map(0x0600000, 0x06fffff).rom().region("maincpu", 0);
+ map(0x0700000, 0x07fffff).rom().region("maincpu", 0);
+
+ map(0x0800000, 0x08fffff).rom().region("maincpu", 0);
+ map(0x0900000, 0x09fffff).rom().region("maincpu", 0);
+ map(0x0a00000, 0x0afffff).rom().region("maincpu", 0);
+ map(0x0b00000, 0x0bfffff).rom().region("maincpu", 0);
+
+ map(0x1000000, 0x10fffff).bankr("cartbank0");
+ map(0x1100000, 0x11fffff).bankr("cartbank0");
+ map(0x1200000, 0x12fffff).bankr("cartbank0");
+ map(0x1300000, 0x13fffff).bankr("cartbank0");
+
+ map(0x1400000, 0x14fffff).bankr("cartbank0");
+ map(0x1500000, 0x15fffff).bankr("cartbank0");
+ map(0x1600000, 0x16fffff).bankr("cartbank1");
+ map(0x1700000, 0x17fffff).bankr("cartbank1");
+
+ map(0x1800000, 0x18fffff).r(FUNC(vsmile_state::bank0_r));
+ map(0x1900000, 0x19fffff).r(FUNC(vsmile_state::bank1_r));
+ map(0x1a00000, 0x1afffff).nopr();
+ map(0x1b00000, 0x1bfffff).r(FUNC(vsmile_state::bank3_r));
+}
+
+void vsmile_state::mem_map(address_map &map)
+{
+ map(0x000000, 0x3fffff).r(m_bankdev, FUNC(address_map_bank_device::read16));
map(0x000000, 0x003fff).m(m_spg, FUNC(spg2xx_device::map));
}
@@ -429,6 +581,14 @@ static INPUT_PORTS_START( vsmile )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("Menu")
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("B Button")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("X Button")
+
+ PORT_START("P2")
+ PORT_DIPNAME( 0x0001, 0x0001, "POWER ON" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, "POWER OFF" )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START( walle )
@@ -620,10 +780,48 @@ void spg2xx_cart_state::machine_start()
m_bank->configure_entries(0, ceilf((float)m_cart_rom->bytes() / 0x800000), m_cart_rom->base(), 0x800000);
m_bank->set_entry(0);
}
+}
+
+void vsmile_state::machine_start()
+{
+ // if there's a cart, override the standard banking
+ if (m_cart && m_cart->exists())
+ {
+ std::string region_tag;
+ m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+ for (uint32_t i = 0; i < 2; i++)
+ {
+ m_cart_banks[i]->configure_entries(0, (m_cart_rom->bytes() + 0x1fffff) / 0x200000, m_cart_rom->base(), 0x200000);
+ m_cart_banks[i]->set_entry(i);
+ }
+ }
+ else
+ {
+ for (uint32_t i = 0; i < 2; i++)
+ {
+ m_cart_rom = memregion("maincpu");
+ m_cart_banks[i]->configure_entries(0, (m_cart_rom->bytes() + 0x1fffff) / 0x200000, m_cart_rom->base(), 0x200000);
+ m_cart_banks[i]->set_entry(0);
+ }
+ }
- m_vsmile_porta_data = 0;
- m_vsmile_portb_data = 0;
- m_vsmile_portc_data = 0;
+ m_bankdev->set_bank(m_cart && m_cart->exists() ? 4 : 0);
+
+ m_serial_eeprom = std::make_unique<uint8_t[]>(0x400);
+ if (m_nvram)
+ m_nvram->set_base(&m_serial_eeprom[0], 0x400);
+
+ m_pad_timer = timer_alloc(TIMER_PAD);
+ m_pad_timer->adjust(attotime::never);
+}
+
+void vsmile_state::machine_reset()
+{
+ m_portb_data = 0;
+ m_portc_data = 0;
+
+ m_pad_timer->adjust(attotime::from_hz(100), 0, attotime::from_hz(100));
+ m_pad_counter = 0;
}
void spg2xx_cart_state::machine_reset()
@@ -699,7 +897,7 @@ DEVICE_IMAGE_LOAD_MEMBER(spg2xx_cart_state, vii_cart)
return image_init_result::PASS;
}
-DEVICE_IMAGE_LOAD_MEMBER(spg2xx_cart_state, vsmile_cart)
+DEVICE_IMAGE_LOAD_MEMBER(vsmile_state, cart)
{
uint32_t size = m_cart->common_get_size("rom");
@@ -778,7 +976,7 @@ void spg2xx_cart_state::vii(machine_config &config)
SOFTWARE_LIST(config, "vii_cart").set_original("vii");
}
-void spg2xx_cart_state::vsmile(machine_config &config)
+void vsmile_state::vsmile(machine_config &config)
{
#if SPG2XX_VISUAL_AUDIO_DEBUG
SPG24X(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen, m_debug_screen);
@@ -786,22 +984,30 @@ void spg2xx_cart_state::vsmile(machine_config &config)
SPG24X(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen);
#endif
spg2xx_base(config);
+ m_maincpu->set_addrmap(AS_PROGRAM, &vsmile_state::mem_map);
- m_spg->porta_in().set(FUNC(spg2xx_cart_state::vsmile_porta_r));
- m_spg->portb_in().set(FUNC(spg2xx_cart_state::vsmile_portb_r));
- m_spg->portc_in().set(FUNC(spg2xx_cart_state::vsmile_portc_r));
- m_spg->porta_out().set(FUNC(spg2xx_cart_state::vsmile_porta_w));
- m_spg->portb_out().set(FUNC(spg2xx_cart_state::vsmile_portb_w));
- m_spg->portc_out().set(FUNC(spg2xx_cart_state::vsmile_portc_w));
+ m_spg->portb_in().set(FUNC(vsmile_state::portb_r));
+ m_spg->portc_in().set(FUNC(vsmile_state::portc_r));
+ m_spg->portb_out().set(FUNC(vsmile_state::portb_w));
+ m_spg->portc_out().set(FUNC(vsmile_state::portc_w));
+ m_spg->chip_select().set(FUNC(vsmile_state::chip_sel_w));
+ m_spg->uart_tx().set(FUNC(vsmile_state::uart_tx));
GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "vsmile_cart");
m_cart->set_width(GENERIC_ROM16_WIDTH);
- m_cart->set_device_load(device_image_load_delegate(&spg2xx_cart_state::device_image_load_vsmile_cart, this));
+ m_cart->set_device_load(device_image_load_delegate(&vsmile_state::device_image_load_cart, this));
+
+ ADDRESS_MAP_BANK(config, m_bankdev);
+ m_bankdev->set_addrmap(AS_PROGRAM, &vsmile_state::banked_map);
+ m_bankdev->set_endianness(ENDIANNESS_LITTLE);
+ m_bankdev->set_data_width(16);
+ m_bankdev->set_shift(-1);
+ m_bankdev->set_stride(0x400000);
SOFTWARE_LIST(config, "cart_list").set_original("vsmile_cart");
}
-void spg2xx_cart_state::vsmilep(machine_config &config)
+void vsmile_state::vsmilep(machine_config &config)
{
vsmile(config);
m_spg->set_pal(true);
@@ -1091,10 +1297,10 @@ ROM_END
// year, name, parent, compat, machine, input, class, init, company, fullname, flags
// VTech systems
-CONS( 2005, vsmile, 0, 0, vsmile, vsmile, spg2xx_cart_state, empty_init, "VTech", "V.Smile (US)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
-CONS( 2005, vsmileg, vsmile, 0, vsmilep, vsmile, spg2xx_cart_state, empty_init, "VTech", "V.Smile (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
-CONS( 2005, vsmilef, vsmile, 0, vsmilep, vsmile, spg2xx_cart_state, empty_init, "VTech", "V.Smile (France)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
-CONS( 2005, vsmileb, 0, 0, vsmile, vsmile, spg2xx_cart_state, empty_init, "VTech", "V.Smile Baby (US)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
+CONS( 2005, vsmile, 0, 0, vsmile, vsmile, vsmile_state, empty_init, "VTech", "V.Smile (US)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
+CONS( 2005, vsmileg, vsmile, 0, vsmilep, vsmile, vsmile_state, empty_init, "VTech", "V.Smile (Germany)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
+CONS( 2005, vsmilef, vsmile, 0, vsmilep, vsmile, vsmile_state, empty_init, "VTech", "V.Smile (France)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
+CONS( 2005, vsmileb, 0, 0, vsmile, vsmile, vsmile_state, empty_init, "VTech", "V.Smile Baby (US)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING )
// Jungle Soft TV games
CONS( 2007, vii, 0, 0, vii, vii, spg2xx_cart_state, empty_init, "Jungle Soft / KenSingTon / Siatronics", "Vii", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // motion controls are awkward, but playable for the most part