mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
More work on gameking 3 [PeT]
This commit is contained in:
parent
d157408218
commit
550175d8b8
@ -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) $(@)" }},
|
||||
|
88
src/devices/cpu/m6502/om65c02gk.lst
Normal file
88
src/devices/cpu/m6502/om65c02gk.lst
Normal 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;
|
||||
|
109
src/devices/cpu/m6502/r65c02gk.cpp
Normal file
109
src/devices/cpu/m6502/r65c02gk.cpp
Normal 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"
|
74
src/devices/cpu/m6502/r65c02gk.h
Normal file
74
src/devices/cpu/m6502/r65c02gk.h
Normal 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
|
@ -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
|
||||
|
13
src/mame/layout/gameking.lay
Normal file
13
src/mame/layout/gameking.lay
Normal 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>
|
@ -12813,7 +12813,7 @@ gamecst2 // MAME based bootleg, version 2.613
|
||||
gamecstl // MAME based bootleg
|
||||
|
||||
@source:gameking.cpp
|
||||
gamekin3 //
|
||||
gking3 //
|
||||
gameking //
|
||||
|
||||
@source:gameplan.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user