More work on gameking 3 [PeT]

This commit is contained in:
Miodrag Milanovic 2016-06-12 09:09:58 +02:00
parent d157408218
commit 550175d8b8
7 changed files with 718 additions and 97 deletions

View File

@ -1247,6 +1247,8 @@ if (CPUS["M6502"]~=null) then
MAME_DIR .. "src/devices/cpu/m6502/n2a03.h",
MAME_DIR .. "src/devices/cpu/m6502/r65c02.cpp",
MAME_DIR .. "src/devices/cpu/m6502/r65c02.h",
MAME_DIR .. "src/devices/cpu/m6502/r65c02gk.cpp",
MAME_DIR .. "src/devices/cpu/m6502/r65c02gk.h",
MAME_DIR .. "src/devices/cpu/m6502/m740.cpp",
MAME_DIR .. "src/devices/cpu/m6502/m740.h",
MAME_DIR .. "src/devices/cpu/m6502/m3745x.cpp",
@ -1265,6 +1267,7 @@ if (CPUS["M6502"]~=null) then
{ MAME_DIR .. "src/devices/cpu/m6502/m6510.cpp", GEN_DIR .. "emu/cpu/m6502/m6510.hxx" },
{ MAME_DIR .. "src/devices/cpu/m6502/n2a03.cpp", GEN_DIR .. "emu/cpu/m6502/n2a03.hxx" },
{ MAME_DIR .. "src/devices/cpu/m6502/r65c02.cpp", GEN_DIR .. "emu/cpu/m6502/r65c02.hxx" },
{ MAME_DIR .. "src/devices/cpu/m6502/r65c02gk.cpp", GEN_DIR .. "emu/cpu/m6502/r65c02gk.hxx" },
{ MAME_DIR .. "src/devices/cpu/m6502/m740.cpp", GEN_DIR .. "emu/cpu/m6502/m740.hxx" },
}
@ -1273,6 +1276,7 @@ if (CPUS["M6502"]~=null) then
{ MAME_DIR .. "src/devices/cpu/m6502/om4510.lst", GEN_DIR .. "emu/cpu/m6502/m4510.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm4510.lst" }, {"@echo Generating m4510 source file...", PYTHON .. " $(1) m4510_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om6502.lst", GEN_DIR .. "emu/cpu/m6502/m6502.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6502.lst" }, {"@echo Generating m6502 source file...", PYTHON .. " $(1) m6502_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om65c02.lst", GEN_DIR .. "emu/cpu/m6502/m65c02.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm65c02.lst" }, {"@echo Generating m65c02 source file...", PYTHON .. " $(1) m65c02_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om65c02gk.lst", GEN_DIR .. "emu/cpu/m6502/r65c02gk.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm65c02.lst" }, {"@echo Generating r65c02gk source file...", PYTHON .. " $(1) r65c02gk_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om65ce02.lst",GEN_DIR .. "emu/cpu/m6502/m65ce02.hxx",{ MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm65ce02.lst" }, {"@echo Generating m65ce02 source file...", PYTHON .. " $(1) m65ce02_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om6509.lst", GEN_DIR .. "emu/cpu/m6502/m6509.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6509.lst" }, {"@echo Generating m6509 source file...", PYTHON .. " $(1) m6509_device $(<) $(2) $(@)" }},
{ MAME_DIR .. "src/devices/cpu/m6502/om6510.lst", GEN_DIR .. "emu/cpu/m6502/m6510.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6510.lst" }, {"@echo Generating m6510 source file...", PYTHON .. " $(1) m6510_device $(<) $(2) $(@)" }},

View File

@ -0,0 +1,88 @@
# license:BSD-3-Clause
# copyright-holders:Peter Trauner
# r65c02gk opcodes
brk_c_imp
if(irq_taken || nmi_state) {
read_pc_noinc();
} else {
read_pc();
}
write(SP, PC >> 8);
dec_SP();
write(SP, PC);
dec_SP();
write(SP, irq_taken || nmi_state ? P & ~F_B : P);
dec_SP();
if(irq_taken && nmi_state) {
PC = read_arg(0x7ffa);
PC = set_h(PC, read_arg(0x7ffb));
nmi_state = false;
standard_irq_callback(NMI_LINE);
} else {
static int level=interrupt_controller.getlevel(); // !no gameking dual core expected
if (level==IRQ_GK3A) {
PC = read_arg(0x7fe2);
PC = set_h(PC, read_arg(0x7fe3));
} else if (level==IRQ_GK3B) {
PC = read_arg(0x7fe4);
PC = set_h(PC, read_arg(0x7fe5));
} else if (level==IRQ_TIMERUSER) {
m_bank4000->set_base(bank4000_irq);
PC = read_arg(0x7fee);
PC = set_h(PC, read_arg(0x7fef));
} else if (level==IRQ_INPUTS) {
m_bank4000->set_base(bank4000_irq);
PC = read_arg(0x7ff0);
PC = set_h(PC, read_arg(0x7ff1));
} else if (level==IRQ_USER) {
m_bank4000->set_base(bank4000_irq);
PC = read_arg(0x7ff2);
PC = set_h(PC, read_arg(0x7ff3));
} else if (level==IRQ_TIMER/*INPUT_LINE_IRQ9*/) {
m_bank4000->set_base(bank4000_irq);
PC = read_arg(0x7ff4);
PC = set_h(PC, read_arg(0x7ff5));
} else if (level==IRQ_6606) {
PC = read_arg(0x7ff6);
PC = set_h(PC, read_arg(0x7ff7));
} else {
PC = read_arg(0x7ffe);
PC = set_h(PC, read_arg(0x7fff));
if(irq_taken)
standard_irq_callback(IRQ_LINE);
}
}
irq_taken = false;
P = (P | F_I) & ~F_D; // Do *not* move after the prefetch
prefetch();
inst_state = -1;
rti_imp
read_pc_noinc();
read(SP);
inc_SP();
P = read(SP) | (F_B|F_E);
inc_SP();
PC = read(SP);
inc_SP();
PC = set_h(PC, read(SP));
m_bank4000->set_base(bank4000_normal);
prefetch();
wai_imp
read_pc_noinc(); /* same as m65c02 version, seams to be right*/
read_pc_noinc();
while(!nmi_state && !irq_state) {
eat-all-cycles;
}
prefetch();
# exceptions
reset
PC = read_arg(0x7ffc);
PC = set_h(PC, read_arg(0x7ffd));
prefetch();
inst_state = -1;

View File

@ -0,0 +1,109 @@
// license:BSD-3-Clause
// copyright-holders:Peter Trauner
/***************************************************************************
r65c02gk.c
Rockwell 65c02gb, additional interrupts, interrupt bankswitching
***************************************************************************/
#include "emu.h"
#include "r65c02gk.h"
const device_type R65C02GK = &device_creator<r65c02gk_device>;
r65c02gk_device::r65c02gk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
r65c02_device(mconfig, R65C02GK, "R65C02GK", tag, owner, clock, "r65c02gk", __FILE__)
{
}
r65c02gk_device::r65c02gk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
r65c02_device(mconfig, type, name, tag, owner, clock, shortname, source)
{
}
offs_t r65c02gk_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries);
}
void r65c02gk_device::device_reset()
{
r65c02_device::device_reset();
interrupt_controller.Reset();
}
void r65c02gk_device::set_irq_bank(memory_bank *m_bank4000_, UINT8 *bank4000_normal_, UINT8 *bank4000_irq_) {
m_bank4000 = m_bank4000_;
bank4000_normal=bank4000_normal_;
bank4000_irq=bank4000_irq_;
}
void r65c02gk_device::execute_set_input(int inputnum, int state)
{
switch(inputnum) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
interrupt_controller.states[inputnum]=state;
irq_state= interrupt_controller.getlevel()>=0;
break;
case R65C02GK_NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break;
#if 0
case APU_IRQ_LINE: apu_irq_state = state == ASSERT_LINE; break;
case V_LINE:
if(!v_state && state == ASSERT_LINE)
P |= F_V;
v_state = state == ASSERT_LINE;
break;
#endif
}
// logerror("%.6f irq num:%d state:%d irq:%x level:%x\n",machine().time().as_double(), inputnum, state, irq_state, interrupt_controller.getlevel());
}
#if 0
void r65c02gk_device::prefetch()
{
sync = true;
sync_w(ASSERT_LINE);
NPC = PC;
IR = mintf->read_decrypted(PC);
sync = false;
sync_w(CLEAR_LINE);
if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) {
irq_taken = true;
IR = 0x00;
} else
PC++;
}
void r65c02gk_device::prefetch_wai()
{
sync = true;
sync_w(ASSERT_LINE);
NPC = PC;
IR = mintf->read_decrypted(PC);
sync = false;
sync_w(CLEAR_LINE);
if (irq_state || nmi_state)
PC++;
if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) {
irq_taken = true;
IR = 0x00;
}
}
void r65c02gk_device::prefetch_noirq()
{
sync = true;
sync_w(ASSERT_LINE);
NPC = PC;
IR = mintf->read_decrypted(PC);
sync = false;
sync_w(CLEAR_LINE);
PC++;
}
#endif
#include "cpu/m6502/r65c02gk.hxx"

View File

@ -0,0 +1,74 @@
// license:BSD-3-Clause
// copyright-holders:Peter Trauner
/***************************************************************************
r65c02gk.h
gameking 65c02 with bitwise instructions and wai instruction, additional
interrupt vectors, special vector address base
***************************************************************************/
#ifndef __R65C02GK_H__
#define __R65C02GK_H__
#include "r65c02.h"
class r65c02gk_device : public r65c02_device {
public:
r65c02gk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
r65c02gk_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
static const disasm_entry disasm_entries[0x100];
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
virtual void do_exec_full() override;
virtual void do_exec_partial() override;
enum {
IRQ_GK3A=INPUT_LINE_IRQ0,
IRQ_GK3B,
IRQ_TIMERUSER=INPUT_LINE_IRQ6,
IRQ_INPUTS, //449C,
IRQ_USER, //=INPUT_LINE_IRQ8,
IRQ_TIMER, //=INPUT_LINE_IRQ9,
IRQ_6606,
R65C02GK_IRQ_LINE12 = IRQ_GK3A/*R65C02GK_IRQ_LINE0*/+12,
R65C02GK_NMI_LINE = INPUT_LINE_NMI // >12
// R65C02GK_SET_OVERFLOW = m6502_device::V_LINE,
};
void set_irq_bank(memory_bank *m_bank4000, UINT8 *bank4000_normal, UINT8 *bank4000_irq);
protected:
UINT8 *bank4000_normal, *bank4000_irq;
virtual void device_reset() override;
virtual void execute_set_input(int inputnum, int state) override;
memory_bank *m_bank4000;
#if 0
void prefetch();
void prefetch_noirq();
void prefetch_wai();
#endif
struct InterruptController { // nearly nothing known about it, only enough to get bios working
bool states[13];
int getlevel() { for (int i=12; i>=0; --i) { if (states[i]) return i; } return -1; }
void Reset() { memset(states, 0, sizeof(states)); }
} interrupt_controller;
#define O(o) void o ## _full(); void o ## _partial()
O(brk_c_imp);
O(rti_imp);
O(wai_imp);
// exceptions
O(reset);
};
extern const device_type R65C02GK;
#endif

View File

@ -2,22 +2,21 @@
// copyright-holders:Peter Trauner
/* TimeTop - GameKing */
/*
PeT mess@utanet.at 2015
PeT mess@utanet.at 2015, 2016
Thanks to Deathadder, Judge, Porchy, Klaus Sommer, James Brolly & Brian Provinciano
hopefully my work (reverse engineerung, cartridge+bios backup, emulation) will be honored in future
and my name will not be removed entirely, especially by simple code rewrites of working emulation
flashcard, handheld, programmer, assembler ready to do some test on real hardware
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
search for rockwell r65c02 variant (cb:wai instruction) and several more exceptions
(with luck microcontroller peripherals match those in gameking)
work out bankswitching and exceptions
(improove emulation)
incomplete interrupt controller causes hangs
protection!? prevents 4in1 carts from working
(improve emulation, timer)
(add audio)
work out gameking3 problems (lcd position, additional interrupts/lcd emulation; audio expected to be the same)
use gameking3 cartridge to get illegal cartridge scroller
@ -27,11 +26,16 @@
#include <stddef.h>
#include "emu.h"
#include "cpu/m6502/r65c02.h"
#include "cpu/m6502/r65c02gk.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "softlist.h"
#include "gameking.lh"
//#include "gking3.lh"
//#define GK3_PIXEL // color pixel are too large, color part red green blue visible, even lines: red left, green top right blue bottom right; odd lines: red right, green left top, blue bottom left
class gameking_state : public driver_device
{
public:
@ -47,125 +51,282 @@ public:
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_PALETTE_INIT(gameking);
DECLARE_PALETTE_INIT(gameking3);
DECLARE_READ8_MEMBER(io_r);
DECLARE_WRITE8_MEMBER(io_w);
DECLARE_READ8_MEMBER(lcd_r);
DECLARE_WRITE8_MEMBER(lcd_w);
DECLARE_READ8_MEMBER(io2_r);
DECLARE_WRITE8_MEMBER(io2_w);
DECLARE_WRITE8_MEMBER(gk3_lcd_w);
INTERRUPT_GEN_MEMBER(gameking_frame_int);
TIMER_CALLBACK_MEMBER(gameking_timer);
TIMER_CALLBACK_MEMBER(gameking_timer2);
TIMER_CALLBACK_MEMBER(gameking_timeruser);
TIMER_CALLBACK_MEMBER(gameking_timeruser2);
UINT32 screen_update_gameking(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_gameking3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(gameking_cart);
struct Gkio {
UINT8 input, input2;
UINT8 timer;
UINT8 res3[0x2f];
UINT8 timer; // bit 5 red power led
UINT8 res3[0x1d];
UINT8 timeruser_on;
UINT8 timeruser_quit;
UINT8 res4[0x6];
UINT8 dma_src_low, dma_src_high, dma_dest_low, dma_dest_high, dma_length_low, dma_length_high;
UINT8 res5[2+1];
UINT8 bank4000_irq; //?
UINT8 bank4000_address; // 32
UINT8 bank4000_cart; //33 bit 0 only?
UINT8 bank8000_cart; //34 bit 7; bits 0,1,.. a15,a16,..
UINT8 res2[0x4c];
UINT8 bank8000_control;
UINT8 bank8000_dma_addr;
UINT8 bank8000_dma_control;
UINT8 res1[6];
UINT8 interrupt_enable; // bit 2 irq timer, bit 5 timeruser
UINT8 res2[1];
UINT8 lcd_pos_low, lcd_pos_high;
UINT8 res2a[0xe +0x30];
};
protected:
required_device<cpu_device> m_maincpu;
void gk3_pixel(bitmap_ind16 &bitmap, int y, int x, int color);
UINT8 Bank8000AddrRead(UINT8 bank, UINT8 control, UINT16 addr) {
if (addr<0x8000)
m_maincpu->space(AS_PROGRAM).read_byte(addr);
memory_region *maincpu_rom = memregion("maincpu");
if (control==1)
return maincpu_rom->base()[addr];
return 0;
}
void Bank8000AddrWrite(UINT8 bank, UINT8 control, UINT16 addr, UINT8 data) {
memory_region *maincpu_rom = memregion("maincpu");
if (addr<0x8000)
m_maincpu->space(AS_PROGRAM).write_byte(addr, data);
else
if (control==1)
maincpu_rom->base()[addr]=data;
}
required_device<r65c02gk_device> m_maincpu;
required_device<generic_slot_device> m_cart;
required_ioport m_io_joy;
required_device<palette_device> m_palette;
UINT8 *bank4000_normal, *bank4000_irq;
memory_region *m_cart_rom;
memory_bank *m_bank4000;
memory_bank *m_bank8000;
emu_timer *timer1;
emu_timer *timer2;
emu_timer *timeruser;
emu_timer *timeruser2;
bool timeruser_expired, timer_expired;
UINT8 inputs0, inputs1;
};
WRITE8_MEMBER(gameking_state::io_w)
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);
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/*?*/));
}
maincpu_rom->base()[offset]=data;
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
switch (offset) {
case offsetof(Gkio, dma_length_low):
{
UINT16 src=io->dma_src_low|(io->dma_src_high<<8);
UINT16 dst=io->dma_dest_low|(io->dma_dest_high<<8);
UINT16 len=io->dma_length_low|(io->dma_length_high<<8);
logerror("%.6f dma src:%x dst:%x len:%x\n",machine().time().as_double(), src, dst, len);
for (; len>0; len--, src++, dst++) { // in reality consumes times, on 6502 probably in the 2nd part of the cpu cycle
Bank8000AddrWrite(io->bank8000_dma_addr, io->bank8000_dma_control, dst, Bank8000AddrRead(io->bank8000_dma_addr, io->bank8000_dma_control, src));
}
}
break;
case offsetof(Gkio, timer):
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMER, CLEAR_LINE); // most likely wrong, removed until real interrupt start lokalized (or permanent active
timer1->enable(TRUE);
timer1->reset(m_maincpu->cycles_to_attotime(70000/*?*/)); // something like 64 hz
break;
case offsetof(Gkio, timeruser_on):
case offsetof(Gkio, timeruser_quit):
// m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMERUSER, CLEAR_LINE);
// timeruser_expired=false;
timeruser->enable(io->timeruser_on!=0);
if (io->timeruser_on&0x1f)
timeruser->reset(m_maincpu->cycles_to_attotime(2000000/(io->timeruser_on&0x1f)/*?*/)); // 1 somethink like 1.5 hz
break;
case offsetof(Gkio, bank4000_irq):
{
UINT8 bank=io->bank4000_irq^1;
bool cart=false; //m_cart_rom;
if (cart) {
// m_bank4000->set_base(m_cart_rom->base() + (bank*0x4000&(m_cart_rom->get_size()-1) );
bank4000_irq=m_cart_rom->base() + (bank*0x4000&(0x80000-1));
} else {
if (bank*0x4000>=0x80000)
bank4000_irq=maincpu_rom->base()+0x4000;
else
bank4000_irq=maincpu_rom->base()+0x10000 + (bank*0x4000&(0x80000-1));
}
}
m_maincpu->set_irq_bank(m_bank4000, bank4000_normal, bank4000_irq);
break;
case offsetof(Gkio, bank4000_address): case offsetof(Gkio, bank4000_cart):
{
UINT8 bank=io->bank4000_address^1;
bool cart=io->bank4000_cart&1/*?*/ && m_cart_rom;
if (cart) {
// m_bank4000->set_base(m_cart_rom->base() + (bank*0x4000&(m_cart_rom->get_size()-1) );
bank4000_normal=m_cart_rom->base() + (bank*0x4000&(0x80000-1));
} else {
if (bank*0x4000>=0x80000)
bank4000_normal=maincpu_rom->base()+0x4000;
else
bank4000_normal=maincpu_rom->base()+0x10000 + (bank*0x4000&(0x80000-1));
}
}
m_bank4000->set_base(bank4000_normal);
m_maincpu->set_irq_bank(m_bank4000, bank4000_normal, bank4000_irq);
break;
case offsetof(Gkio, bank8000_cart):
case offsetof(Gkio, bank8000_control):
Gkio *io = reinterpret_cast<Gkio*>(maincpu_rom->base());
if (offset == offsetof(Gkio, bank4000_address) || offset == offsetof(Gkio, bank4000_cart)) {
UINT8 bank = io->bank4000_address ^ 1;
UINT8 *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 *base = io->bank8000_cart & 0x80/*?*/ && m_cart_rom ? m_cart_rom->base() : maincpu_rom->base() + 0x10000;
UINT8 bank = io->bank8000_cart & 0x7f;
m_bank8000->set_base(base + bank * 0x8000);
}
{
bool cart=io->bank8000_cart&0x80/*?*/ && m_cart_rom;
UINT8 bank=io->bank8000_cart&0x7f;
if ((io->bank8000_control&7)!=0) {
m_bank8000->set_base(maincpu_rom->base()+0x8000);
} else if (cart) {
// m_bank8000->set_base(m_cart_rom->base() + (bank*0x8000&(m_cart_rom->get_size()-1) );
m_bank8000->set_base(m_cart_rom->base() + (bank*0x8000&(0x80000-1)) );
} else {
if (bank*0x8000>=0x80000)
m_bank8000->set_base(maincpu_rom->base()+0x8000);
else
m_bank8000->set_base(maincpu_rom->base()+0x10000+ (bank*0x8000&(0x80000-1)) );
}
}
break;
case offsetof(Gkio, interrupt_enable):
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMER, timer_expired && (io->interrupt_enable&4)?ASSERT_LINE:CLEAR_LINE);
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMERUSER, timeruser_expired && (io->interrupt_enable&0x20)?ASSERT_LINE:CLEAR_LINE);
break;
};
}
READ8_MEMBER(gameking_state::io_r)
READ8_MEMBER( gameking_state::io_r )
{
memory_region *maincpu_rom = memregion("maincpu");
UINT8 data = maincpu_rom->base()[offset];
UINT8 data=maincpu_rom->base()[offset];
switch (offset) {
case offsetof(Gkio, input):
data = m_io_joy->read() | ~3;
m_maincpu->set_input_line(r65c02gk_device::IRQ_INPUTS, CLEAR_LINE);
data=m_io_joy->read()>>8;
break;
case offsetof(Gkio, input2):
data = m_io_joy->read() | 3;
m_maincpu->set_input_line(r65c02gk_device::IRQ_USER, CLEAR_LINE);
data=m_io_joy->read();
break;
case 0x4c: data = 6;
break; // bios protection endless loop
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);
if (offset!=offsetof(Gkio, bank8000_cart) && offset!=offsetof(Gkio, input) )
logerror("%.6f io r %x %x\n",machine().time().as_double(), offset, data);
return data;
}
WRITE8_MEMBER( gameking_state::lcd_w )
WRITE8_MEMBER( gameking_state::io2_w )
{
if (offset>=4 && offset<=7)
logerror("%.6f protection w %x %x\n",machine().time().as_double(), offset, data);
else
logerror("%.6f io2 w %x %x\n",machine().time().as_double(), offset, data);
memory_region *maincpu_rom = memregion("maincpu");
maincpu_rom->base()[offset+0x600]=data;
maincpu_rom->base()[0x100+offset]=data;
}
READ8_MEMBER(gameking_state::lcd_r)
READ8_MEMBER( gameking_state::io2_r )
{
memory_region *maincpu_rom = memregion("maincpu");
UINT8 data = maincpu_rom->base()[offset + 0x600];
UINT8 data=maincpu_rom->base()[0x100+offset];
if (offset>=4 && offset<=7) {
UINT8 d=data;
if (offset==4) {
// if (data==0xc) data=0x95;
// if (data==0xce) data=0xd2; // no real improvement, but much slower
}
logerror("%.6f protection r %x %x (written %x)\n",machine().time().as_double(), offset, data, d);
}
else
logerror("%.6f io2 r %x %x\n",machine().time().as_double(), offset, data);
return data;
}
WRITE8_MEMBER( gameking_state::gk3_lcd_w )
{
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
if (io->bank8000_cart==0 && io->bank8000_control==1)
maincpu_rom->base()[offset+0x8000]=data;
else
logerror("%.6f gk3 lcd w %x %x\n",machine().time().as_double(), offset, data);
}
static ADDRESS_MAP_START( gameking_mem , AS_PROGRAM, 8, gameking_state )
AM_RANGE(0x0000, 0x007f) AM_READWRITE(io_r, io_w)
AM_RANGE(0x0080, 0x01ff) AM_RAM
AM_RANGE(0x0200, 0x03ff) AM_RAM // lcd 2nd copy
AM_RANGE(0x0600, 0x077f) AM_READWRITE(lcd_r, lcd_w)
AM_RANGE(0x0d00, 0x0fff) AM_RAM // d00, e00, f00 prooved on handheld
// AM_RANGE(0x1000, 0x1fff) AM_RAM // sthero writes to $19xx
// AM_RANGE(0x3000, 0x3fff) AM_ROMBANK("bank3000")
AM_RANGE(0x0080, 0x00ff) AM_RAM
AM_RANGE(0x0100, 0x017f) AM_READWRITE(io2_r, io2_w)
AM_RANGE(0x0180, 0x27ff) AM_RAM
AM_RANGE(0x2800, 0x2fff) AM_ROMBANK("bank2800") // proove if also write access like on 3000
AM_RANGE(0x3000, 0x3fff) AM_ROMBANK("bank3000")
AM_RANGE(0x4000, 0x7fff) AM_ROMBANK("bank4000")
AM_RANGE(0x8000, 0xffaf) AM_ROMBANK("bank8000")
AM_RANGE(0xffb0, 0xffff) AM_ROMBANK("bankboot") // cpu seems to read from 8000 bank, and for exceptions ignore bank
AM_RANGE(0x8000, 0xffff) AM_READ_BANK("bank8000") AM_WRITE(gk3_lcd_w)
ADDRESS_MAP_END
static INPUT_PORTS_START( gameking )
#if 1
PORT_START("JOY")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select") //?
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("A") //?
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start") // gk3 1 on address 0
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select") // ! 2 on address 1; gk3 2 on address 0
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("B")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) //?
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) //?
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("A")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)
PORT_BIT( 0xfd01, IP_ACTIVE_LOW, IPT_UNUSED )
#else
PORT_START("JOY")
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start") // gk3 1 on address 0
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select") // ! 2 on address 1; gk3 2 on address 0
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("B")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("A")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)
PORT_BIT( 0xfc03, IP_ACTIVE_LOW, IPT_UNUSED )
#endif
INPUT_PORTS_END
static INPUT_PORTS_START( gameking3 )
PORT_START("JOY")
PORT_BIT( 0xfc03, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start")
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("B")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("A")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)
INPUT_PORTS_END
@ -178,21 +339,50 @@ static const unsigned char gameking_palette[] =
0, 0, 0
};
static const unsigned char gameking3_palette[64*3] =
{
255, 255, 255,
127, 127, 127,
63, 63, 63,
0, 0, 0,
255, 0, 0,
127, 0, 0,
63, 0, 0,
31, 0, 0,
0, 255, 0,
0, 127, 127,
0, 63, 0,
0, 31, 0,
0, 0, 255,
0, 0, 127,
0, 0, 63,
0, 0, 31
};
PALETTE_INIT_MEMBER(gameking_state, gameking)
{
for (int i = 0; i < sizeof(gameking_palette) / 3; i++)
palette.set_pen_color(i, gameking_palette[i*3], gameking_palette[i*3+1], gameking_palette[i*3+2]);
}
PALETTE_INIT_MEMBER(gameking_state, gameking3)
{
for (int i = 0; i < sizeof(gameking3_palette) / 3; i++)
palette.set_pen_color(i, ((i&0xc)>>2)*(255/3), (i&3)*(255/3), ((i&0x30)>>4)*(255/3) ); // not quite as contrast rich on the real handheld, but not bad
}
UINT32 gameking_state::screen_update_gameking(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
UINT16 pos=io->lcd_pos_low|(io->lcd_pos_high<<8);
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 data=maincpu_rom->base()[0x600+j+i*12];
UINT8 data=machine().device("maincpu")->memory().space(AS_PROGRAM).read_byte(pos+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;
@ -202,16 +392,87 @@ UINT32 gameking_state::screen_update_gameking(screen_device &screen, bitmap_ind1
return 0;
}
void gameking_state::gk3_pixel(bitmap_ind16 &bitmap, int y, int x, int color)
{
if (!(y&1)) {
bitmap.pix16(y*2+1, x*2)=(color&0xc)==color? color: 0; // red
bitmap.pix16(y*2, x*2+1)=color&3? color: 0; // 0x3 green
bitmap.pix16(y*2+1, x*2+1)=color&0x30? color: 0; // 0x30 blue
} else {
bitmap.pix16(y*2+1, x*2+1)=(color&0xc)==color? color: 0;
bitmap.pix16(y*2, x*2)=color&3? color: 0;
bitmap.pix16(y*2+1, x*2)=color&0x30? color: 0;
}
}
UINT32 gameking_state::screen_update_gameking3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
memory_region *maincpu_rom = memregion("maincpu");
for (int y=0, i=0;y<56;i+=40*6,y+=4)
{
for (int j=0, x=0;x<80;j++, x+=2)
{
#if 1
UINT8 d1=maincpu_rom->base()[0x8000+i+j];
UINT8 d2=maincpu_rom->base()[0x8000+i+j+40];
UINT8 d3=maincpu_rom->base()[0x8000+i+j+80];
UINT8 d4=maincpu_rom->base()[0x8000+i+j+120];
UINT8 d5=maincpu_rom->base()[0x8000+i+j+160];
UINT8 d6=maincpu_rom->base()[0x8000+i+j+200];
#else // galaxy crisis stopped working
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
UINT16 pos=io->lcd_pos_low|(io->lcd_pos_high<<8);
UINT8 d1=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j);
UINT8 d2=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j+40);
UINT8 d3=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j+80);
UINT8 d4=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j+120);
UINT8 d5=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j+160);
UINT8 d6=m_maincpu->space(AS_PROGRAM).read_byte(pos+i+j+200);
#endif
UINT32 data=((d1&0xf0)>>4)|(d2&0xf0)|((d3&0xf0)<<4)|((d4&0xf0)<<8)|((d5&0xf0)<<12)|((d6&0xf0)<<16);
#ifdef GK3_PIXEL
gk3_pixel(bitmap, y+0, x, data&0x3f);
gk3_pixel(bitmap, y+1, x, (data>>6)&0x3f);
gk3_pixel(bitmap, y+2, x, (data>>12)&0x3f);
gk3_pixel(bitmap, y+3, x, (data>>18)&0x3f);
#else
bitmap.pix16(y+0, x)=data&0x3f;
bitmap.pix16(y+1, x)=(data>>6)&0x3f;
bitmap.pix16(y+2, x)=(data>>12)&0x3f;
bitmap.pix16(y+3, x)=(data>>18)&0x3f;
#endif
data=(d1&0xf)|((d2&0xf)<<4)|((d3&0xf)<<8)|((d4&0xf)<<12)|((d5&0xf)<<16)|((d6&0xf)<<20);
#ifdef GK3_PIXEL
gk3_pixel(bitmap, y+0, x+1, data&0x3f);
gk3_pixel(bitmap, y+1, x+1, (data>>6)&0x3f);
gk3_pixel(bitmap, y+2, x+1, (data>>12)&0x3f);
gk3_pixel(bitmap, y+3, x+1, (data>>18)&0x3f);
#else
bitmap.pix16(y+0, x+1)=data&0x3f;
bitmap.pix16(y+1, x+1)=(data>>6)&0x3f;
bitmap.pix16(y+2, x+1)=(data>>12)&0x3f;
bitmap.pix16(y+3, x+1)=(data>>18)&0x3f;
#endif
}
}
return 0;
}
DRIVER_INIT_MEMBER(gameking_state, gameking)
{
timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timer), this));
timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timer2), this));
timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timer),this));
timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timer2),this));
timeruser = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timeruser),this));
timeruser2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(gameking_state::gameking_timeruser2),this));
}
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_input_line(M6502_IRQ_LINE, ASSERT_LINE); // in reality int for vector at fff4
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
timer_expired=true;
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMER, io->interrupt_enable&4?ASSERT_LINE:CLEAR_LINE);
timer1->enable(FALSE);
timer2->enable(TRUE);
timer2->reset(m_maincpu->cycles_to_attotime(10/*?*/));
@ -219,12 +480,37 @@ 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
// 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(r65c02gk_device::IRQ_TIMER, CLEAR_LINE);
timer_expired=false;
timer2->enable(FALSE);
timer1->enable(TRUE);
Gkio *io = reinterpret_cast<Gkio*>(maincpu_rom->base());
timer1->reset(m_maincpu->cycles_to_attotime(io->timer * 300/*?*/));
//Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
timer1->reset(m_maincpu->cycles_to_attotime(50000/*?*/));
}
TIMER_CALLBACK_MEMBER(gameking_state::gameking_timeruser)
{
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
timeruser_expired=true;
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMERUSER, io->interrupt_enable&0x20?ASSERT_LINE:CLEAR_LINE);
timeruser->enable(FALSE);
timeruser2->enable(TRUE);
timeruser2->reset(m_maincpu->cycles_to_attotime(30/*?*/)); // 10 to few
}
TIMER_CALLBACK_MEMBER(gameking_state::gameking_timeruser2)
{
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
timeruser_expired=false;
m_maincpu->set_input_line(r65c02gk_device::IRQ_TIMERUSER, CLEAR_LINE);
timeruser->enable(io->timeruser_on!=0);
if (io->timeruser_on&0x1f)
timeruser->reset(m_maincpu->cycles_to_attotime(2000000/(io->timeruser_on&0x1f)/*?*/)); // 1 somethink like 1.5 hz
timeruser->enable(FALSE);
}
DEVICE_IMAGE_LOAD_MEMBER( gameking_state, gameking_cart )
@ -250,33 +536,52 @@ void gameking_state::machine_start()
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);
timeruser_expired=false;
timer_expired=false;
}
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);
maincpu_rom->base()[0x3e] = 0;
m_bank4000->set_base(maincpu_rom->base() + 0x10000+0x4000);
bank4000_normal=bank4000_irq=maincpu_rom->base() + 0x10000+0x4000;
m_maincpu->set_irq_bank(m_bank4000, bank4000_normal, bank4000_irq);
//m_bank8000->set_base(maincpu_rom->base()+0x10000); //? no reason to enforce this yet
memory_bank *bank2800=membank("bank2800");
memory_bank *bank3000=membank("bank3000");
if (m_cart_rom) {
bank2800->set_base(m_cart_rom->base()+0x2800);
bank3000->set_base(m_cart_rom->base()+0x3000);
} else {
bank2800->set_base(maincpu_rom->base()+0x10000+0x2800); // most likely access to cartridge space/antenne
bank3000->set_base(maincpu_rom->base()+0x10000+0x3000);
}
}
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
memory_region *maincpu_rom = memregion("maincpu");
Gkio *io=reinterpret_cast<Gkio*>(maincpu_rom->base());
UINT8 i=inputs0;
inputs1=m_io_joy->read()>>8;
if (i!=inputs0 && inputs0!=0xff)
m_maincpu->set_input_line(r65c02gk_device::IRQ_INPUTS, io->interrupt_enable&0x10?ASSERT_LINE:CLEAR_LINE); //? 4in1 popper depends on some effects on $90 bits effected by protection
i=inputs1;
inputs1=m_io_joy->read();
if (i!=inputs1 && inputs1!=0xff)
m_maincpu->set_input_line(r65c02gk_device::IRQ_USER, io->interrupt_enable&8?ASSERT_LINE:CLEAR_LINE); //? 4in1 popper depends on some effects on $90 bits effected by protection
}
static MACHINE_CONFIG_START( gameking, gameking_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", R65C02, 6000000)
MCFG_CPU_ADD("maincpu", R65C02GK, 6000000)
MCFG_CPU_PROGRAM_MAP(gameking_mem)
MCFG_CPU_VBLANK_INT_DRIVER("screen", gameking_state, gameking_frame_int)
@ -291,36 +596,64 @@ static MACHINE_CONFIG_START( gameking, gameking_state )
MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(gameking_palette) * 3)
MCFG_PALETTE_INIT_OWNER(gameking_state, gameking )
MCFG_DEFAULT_LAYOUT(layout_gameking)
/* cartridge */
MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "gameking_cart")
MCFG_GENERIC_EXTENSIONS("bin")
MCFG_GENERIC_LOAD(gameking_state, gameking_cart)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( gameking1, gameking )
/* Software lists */
MCFG_SOFTWARE_LIST_ADD("cart_list", "gameking")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( gameking3, gameking )
MCFG_SOFTWARE_LIST_ADD("cart_list", "gameking")
MCFG_SOFTWARE_LIST_ADD("cart_list_3", "gameking3")
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( gameking3, gameking_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", R65C02GK, 6000000)
MCFG_CPU_PROGRAM_MAP(gameking_mem)
MCFG_CPU_VBLANK_INT_DRIVER("screen", gameking_state, gameking_frame_int)
/* video hardware */
MCFG_SCREEN_ADD("screen", LCD)
MCFG_SCREEN_REFRESH_RATE(60)
#ifdef GK3_PIXEL
MCFG_SCREEN_SIZE(80*2, 56*2)
MCFG_SCREEN_VISIBLE_AREA(0, 80*2-1, 0, 53*2-1)
#else
MCFG_SCREEN_SIZE(80, 56)
MCFG_SCREEN_VISIBLE_AREA(0, 80-1, 0, 53-1)
#endif
MCFG_SCREEN_UPDATE_DRIVER(gameking_state, screen_update_gameking3)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(gameking3_palette) * 3)
MCFG_PALETTE_INIT_OWNER(gameking_state, gameking3 )
// MCFG_DEFAULT_LAYOUT(layout_gking3)
MCFG_DEFAULT_LAYOUT(layout_gameking)
/* cartridge */
MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "gameking_cart")
MCFG_GENERIC_EXTENSIONS("bin")
MCFG_GENERIC_LOAD(gameking_state, gameking_cart)
/* Software lists */
MCFG_SOFTWARE_LIST_ADD("cart_list", "gameking")
MACHINE_CONFIG_END
ROM_START(gameking)
ROM_REGION(0x10000+0x80000, "maincpu", ROMREGION_ERASE00)
ROM_REGION(0x10000+0x80000, "maincpu", ROMREGION_ERASEVAL(0x0d))
// ROM_LOAD("gm218.bin", 0x10000, 0x80000, CRC(8f52a928) SHA1(2e791fc7b642440d36820d2c53e1bb732375eb6e) ) // a14 inversed
ROM_LOAD("gm218.bin", 0x10000, 0x80000, CRC(5a1ade3d) SHA1(e0d056f8ebfdf52ef6796d0375eba7fcc4a6a9d3) )
ROM_END
ROM_START(gamekin3)
ROM_REGION(0x10000+0x80000, "maincpu", ROMREGION_ERASE00)
ROM_START(gking3)
ROM_REGION(0x10000+0x80000, "maincpu", ROMREGION_ERASEVAL(0x0D))
ROM_LOAD("gm220.bin", 0x10000, 0x80000, CRC(1dc43bd5) SHA1(f9dcd3cb76bb7cb10565a1acb070ab375c082b4c) )
ROM_END
CONS(2003, gameking, 0, 0, gameking1, gameking, gameking_state, gameking, "TimeTop", "GameKing GM-218", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
CONS(2003, gameking, 0, 0, gameking, gameking, gameking_state, gameking, "TimeTop", "GameKing GM-218", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// the GameKing 2 (GM-219) is probably identical HW
CONS(2003, gamekin3, 0, 0, gameking3, gameking, gameking_state, gameking, "TimeTop", "GameKing 3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
CONS(2005, gking3, 0, gameking, gameking3, gameking3, gameking_state, gameking, "TimeTop", "GameKing III", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// gameking 3: similiar cartridges, accepts gameking cartridges, gameking3 cartridges not working on gameking (illegal cartridge scroller)
// my gameking bios backup solution might work on it

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<mamelayout version="2">
<view name="HANDHELD(LCD)">
<screen index="0">
<bounds left="0" top="0" right="48" bottom="32" />
</screen>
</view>
<view name="Gameking3(LCD)">
<screen index="0">
<bounds left="0" top="0" right="44" bottom="27" />
</screen>
</view>
</mamelayout>

View File

@ -12813,7 +12813,7 @@ gamecst2 // MAME based bootleg, version 2.613
gamecstl // MAME based bootleg
@source:gameking.cpp
gamekin3 //
gking3 //
gameking //
@source:gameplan.cpp