mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
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 550175d8b8
.
This commit is contained in:
parent
ed087f295e
commit
169d310d2e
@ -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));
|
||||
}
|
||||
|
@ -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 <stddef.h>
|
||||
|
||||
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<cpu_device> m_maincpu;
|
||||
@ -86,88 +68,34 @@ private:
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
memory_region *m_cart_rom;
|
||||
memory_bank *m_bank4000;
|
||||
memory_bank *m_bank8000;
|
||||
emu_timer *timer1;
|
||||
emu_timer *timer2;
|
||||
|
||||
uint8_t m_timer;
|
||||
};
|
||||
|
||||
|
||||
WRITE8_MEMBER(gameking_state::io_w)
|
||||
void gameking_state::timer_w(uint8_t data)
|
||||
{
|
||||
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/*?*/));
|
||||
}
|
||||
|
||||
Gkio *io = reinterpret_cast<Gkio*>(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);
|
||||
}
|
||||
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/*?*/));
|
||||
}
|
||||
|
||||
READ8_MEMBER(gameking_state::io_r)
|
||||
uint8_t gameking_state::input_r()
|
||||
{
|
||||
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;
|
||||
return m_io_joy->read() | ~3;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( gameking_state::lcd_w )
|
||||
uint8_t gameking_state::input2_r()
|
||||
{
|
||||
memory_region *maincpu_rom = memregion("maincpu");
|
||||
maincpu_rom->base()[offset+0x600]=data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(gameking_state::lcd_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<Gkio*>(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));
|
||||
|
Loading…
Reference in New Issue
Block a user