From 169d310d2e9572d208825c787d2e5acefef89974 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 3 Nov 2019 16:38:35 -0500 Subject: gameking: Switch to ST2204 emulation (nw) The hacks to get this half-working at this state may be a bit crude, but at least it's way cleaner than 550175d8b8ec9739c5e7810bbdba789cf6b49158. --- src/devices/cpu/m6502/st2204.cpp | 2 +- src/mame/drivers/gameking.cpp | 152 +++++++++------------------------------ 2 files changed, 35 insertions(+), 119 deletions(-) diff --git a/src/devices/cpu/m6502/st2204.cpp b/src/devices/cpu/m6502/st2204.cpp index cad69651872..88b421c3b2c 100644 --- a/src/devices/cpu/m6502/st2204.cpp +++ b/src/devices/cpu/m6502/st2204.cpp @@ -343,7 +343,7 @@ void st2204_device::int_map(address_map &map) map(0x0044, 0x0044).rw(FUNC(st2204_device::lymax_r), FUNC(st2204_device::lymax_w)); map(0x004c, 0x004c).rw(FUNC(st2204_device::pl_r), FUNC(st2204_device::pl_w)); map(0x004e, 0x004e).w(FUNC(st2204_device::pcl_w)); - map(0x0080, 0x27ff).ram(); // 10K internal SRAM; extent of mapping guessed + map(0x0080, 0x287f).ram(); map(0x4000, 0x7fff).rw(FUNC(st2204_device::pmem_r), FUNC(st2204_device::pmem_w)); map(0x8000, 0xffff).rw(FUNC(st2204_device::dmem_r), FUNC(st2204_device::dmem_w)); } diff --git a/src/mame/drivers/gameking.cpp b/src/mame/drivers/gameking.cpp index b1c1c2a4e77..7d0a834cf27 100644 --- a/src/mame/drivers/gameking.cpp +++ b/src/mame/drivers/gameking.cpp @@ -13,27 +13,20 @@ todo: !back up gameking3 bios so emulation of gameking3 gets possible; my gameking bios backup solution should work - search for rockwell r65c02 variant (cb:wai instruction) and several more exceptions, and implement it - (with luck microcontroller peripherals match those in gameking) - work out bankswitching and exceptions (improove emulation) (add audio) use gameking3 cartridge to get illegal cartridge scroller - - This system appears to be based on the GeneralPlus GPL133 system-on-chip or a close relative. - Datasheet: http://www.generalplus.com/doc/ds/GPL133AV10_spec.pdf */ #include "emu.h" -#include "cpu/m6502/r65c02.h" +#include "cpu/m6502/st2204.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" #include "emupal.h" #include "screen.h" #include "softlist.h" -#include class gameking_state : public driver_device { @@ -58,26 +51,15 @@ protected: private: void gameking_palette(palette_device &palette) const; - DECLARE_READ8_MEMBER(io_r); - DECLARE_WRITE8_MEMBER(io_w); - DECLARE_READ8_MEMBER(lcd_r); - DECLARE_WRITE8_MEMBER(lcd_w); - INTERRUPT_GEN_MEMBER(gameking_frame_int); + void timer_w(uint8_t data); + uint8_t input_r(); + uint8_t input2_r(); TIMER_CALLBACK_MEMBER(gameking_timer); TIMER_CALLBACK_MEMBER(gameking_timer2); uint32_t screen_update_gameking(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load); - struct Gkio { - uint8_t input, input2; - uint8_t timer; - uint8_t res3[0x2f]; - uint8_t bank4000_address; // 32 - uint8_t bank4000_cart; //33 bit 0 only? - uint8_t bank8000_cart; //34 bit 7; bits 0,1,.. a15,a16,.. - uint8_t res2[0x4c]; - }; void gameking_mem(address_map &map); required_device m_maincpu; @@ -86,88 +68,34 @@ private: required_device m_palette; memory_region *m_cart_rom; - memory_bank *m_bank4000; - memory_bank *m_bank8000; emu_timer *timer1; emu_timer *timer2; -}; - - -WRITE8_MEMBER(gameking_state::io_w) -{ - if (offset != offsetof(Gkio, bank8000_cart)) - logerror("%.6f io w %x %x\n", machine().time().as_double(), offset, data); - - memory_region *maincpu_rom = memregion("maincpu"); - maincpu_rom->base()[offset] = data; - if (offset == offsetof(Gkio, timer)) { - m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); - timer1->enable(true); - timer1->reset(m_maincpu->cycles_to_attotime(data * 300/*?*/)); - } + uint8_t m_timer; +}; - Gkio *io = reinterpret_cast(maincpu_rom->base()); - if (offset == offsetof(Gkio, bank4000_address) || offset == offsetof(Gkio, bank4000_cart)) { - uint8_t bank = io->bank4000_address ^ 1; - uint8_t *base = io->bank4000_cart & 1/*?*/ && m_cart_rom ? m_cart_rom->base() : maincpu_rom->base() + 0x10000; - m_bank4000->set_base(base + bank * 0x4000); - } - if (offset == offsetof(Gkio, bank8000_cart)) { - uint8_t *base = io->bank8000_cart & 0x80/*?*/ && m_cart_rom ? m_cart_rom->base() : maincpu_rom->base() + 0x10000; - uint8_t bank = io->bank8000_cart & 0x7f; - m_bank8000->set_base(base + bank * 0x8000); - } -} -READ8_MEMBER(gameking_state::io_r) +void gameking_state::timer_w(uint8_t data) { - memory_region *maincpu_rom = memregion("maincpu"); - uint8_t data = maincpu_rom->base()[offset]; - switch (offset) { - case offsetof(Gkio, input): - data = m_io_joy->read() | ~3; - break; - case offsetof(Gkio, input2): - data = m_io_joy->read() | 3; - break; - case 0x4c: data = 6; - break; // bios protection endless loop - } - - if (offset != offsetof(Gkio, bank8000_cart)) - logerror("%.6f io r %x %x\n", machine().time().as_double(), offset, data); - - return data; + m_timer = data; + //m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); + timer1->enable(true); + timer1->reset(m_maincpu->cycles_to_attotime(data * 300/*?*/)); } -WRITE8_MEMBER( gameking_state::lcd_w ) +uint8_t gameking_state::input_r() { - memory_region *maincpu_rom = memregion("maincpu"); - maincpu_rom->base()[offset+0x600]=data; + return m_io_joy->read() | ~3; } -READ8_MEMBER(gameking_state::lcd_r) +uint8_t gameking_state::input2_r() { - memory_region *maincpu_rom = memregion("maincpu"); - uint8_t data = maincpu_rom->base()[offset + 0x600]; - return data; + return m_io_joy->read() | 3; } void gameking_state::gameking_mem(address_map &map) { - map(0x0000, 0x007f).rw(FUNC(gameking_state::io_r), FUNC(gameking_state::io_w)); - map(0x0080, 0x01ff).ram(); - map(0x0200, 0x03ff).ram(); // lcd 2nd copy - - map(0x0600, 0x077f).rw(FUNC(gameking_state::lcd_r), FUNC(gameking_state::lcd_w)); - map(0x0d00, 0x0fff).ram(); // d00, e00, f00 prooved on handheld -// map(0x1000, 0x1fff).ram(); // sthero writes to $19xx - -// map(0x3000, 0x3fff).bankr("bank3000"); - map(0x4000, 0x7fff).bankr("bank4000"); - map(0x8000, 0xffaf).bankr("bank8000"); - map(0xffb0, 0xffff).bankr("bankboot"); // cpu seems to read from 8000 bank, and for exceptions ignore bank + map(0x000000, 0x07ffff).rom().region("maincpu", 0x10000); } @@ -199,12 +127,16 @@ void gameking_state::gameking_palette(palette_device &palette) const uint32_t gameking_state::screen_update_gameking(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + address_space *maincpu_ram = &m_maincpu->space(AS_PROGRAM); + offs_t lssa = m_maincpu->state_int(st2xxx_device::ST_LSSA); + if (lssa < 0x0080) + return 0; + for (int y=31, i=0;i<32;i++,y--) { for (int x=0, j=0;j<48/4;x+=4, j++) { - memory_region *maincpu_rom = memregion("maincpu"); - uint8_t data=maincpu_rom->base()[0x600+j+i*12]; + uint8_t data=maincpu_ram->read_byte(lssa+j+i*12); bitmap.pix16(y, x+3)=data&3; bitmap.pix16(y, x+2)=(data>>2)&3; bitmap.pix16(y, x+1)=(data>>4)&3; @@ -223,7 +155,8 @@ void gameking_state::init_gameking() TIMER_CALLBACK_MEMBER(gameking_state::gameking_timer) { - m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE); // in reality int for vector at fff4 + m_maincpu->set_state_int(st2xxx_device::ST_IREQ, + m_maincpu->state_int(st2xxx_device::ST_IREQ) | (0x016 & m_maincpu->state_int(st2xxx_device::ST_IENA))); timer1->enable(false); timer2->enable(true); timer2->reset(m_maincpu->cycles_to_attotime(10/*?*/)); @@ -231,12 +164,10 @@ TIMER_CALLBACK_MEMBER(gameking_state::gameking_timer) TIMER_CALLBACK_MEMBER(gameking_state::gameking_timer2) { - memory_region *maincpu_rom = memregion("maincpu"); - m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); // in reality int for vector at fff4 + //m_maincpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE); // in reality int for vector at fff4 timer2->enable(false); timer1->enable(true); - Gkio *io = reinterpret_cast(maincpu_rom->base()); - timer1->reset(m_maincpu->cycles_to_attotime(io->timer * 300/*?*/)); + timer1->reset(m_maincpu->cycles_to_attotime(m_timer * 300/*?*/)); } DEVICE_IMAGE_LOAD_MEMBER(gameking_state::cart_load) @@ -259,39 +190,24 @@ void gameking_state::machine_start() { std::string region_tag; m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str()); - - m_bank4000 = membank("bank4000"); - m_bank8000 = membank("bank8000"); - - memory_region *maincpu_rom = memregion("maincpu"); - memory_bank *bankboot=membank("bankboot"); - maincpu_rom->base()[0x10000+0x7ffe]=0xcf; // routing irq to timerint until r65c02gk hooked up - bankboot->set_base(maincpu_rom->base()+0x10000+0x7fb0); + if (m_cart_rom) + m_maincpu->space(AS_DATA).install_rom(0x400000, 0x400000 + m_cart_rom->bytes() - 1, m_cart_rom->base()); } void gameking_state::machine_reset() { - memory_region *maincpu_rom = memregion("maincpu"); - maincpu_rom->base()[0x32] = 0; // neccessary to boot correctly - maincpu_rom->base()[0x33] = 0; - m_bank4000->set_base(maincpu_rom->base() + 0x10000 + 0x4000); - //m_bank8000->set_base(maincpu_rom->base()+0x10000); //? no reason to enforce this yet -} - -INTERRUPT_GEN_MEMBER(gameking_state::gameking_frame_int) // guess to get over bios wai -{ - // static int line=0; - // line++; - // m_maincpu->set_input_line(M6502_IRQ_LINE, line&1? ASSERT_LINE: CLEAR_LINE); // in reality int for vector at fff4 } void gameking_state::gameking(machine_config &config) { /* basic machine hardware */ - R65C02(config, m_maincpu, 6000000); - m_maincpu->set_addrmap(AS_PROGRAM, &gameking_state::gameking_mem); - m_maincpu->set_vblank_int("screen", FUNC(gameking_state::gameking_frame_int)); + st2xxx_device &maincpu(ST2204(config, m_maincpu, 6000000)); + maincpu.set_addrmap(AS_DATA, &gameking_state::gameking_mem); + maincpu.in_pa_callback().set(FUNC(gameking_state::input_r)); + maincpu.in_pb_callback().set(FUNC(gameking_state::input2_r)); + maincpu.out_pc_callback().set(FUNC(gameking_state::timer_w)); // wrong + maincpu.in_pl_callback().set_constant(6); // bios protection endless loop /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); -- cgit v1.2.3