mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
-st62xx: Added a skeleton driver for the STmicro ST6 series of microcontrollers. [Ryan Holtz]
New machines marked as NOT_WORKING ---------------------------------- Catherine Wheel [f205v, Ryan Holtz]
This commit is contained in:
parent
25ee9eb21c
commit
40efe9785f
@ -748,6 +748,23 @@ if (CPUS["SH"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/sh/sh_dasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- STmicro ST62xx
|
||||
--@src/devices/cpu/st62xx/st62xx.h,CPUS["ST62XX"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["ST62XX"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/st62xx/st62xx.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/st62xx/st62xx.h",
|
||||
}
|
||||
end
|
||||
|
||||
if (CPUS["ST62XX"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/st62xx/st62xx_dasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/st62xx/st62xx_dasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- HP Hybrid processor
|
||||
--@src/devices/cpu/hphybrid/hphybrid.h,CPUS["HPHYBRID"] = true
|
||||
|
@ -131,6 +131,7 @@ CPUS["HMCS40"] = true
|
||||
--CPUS["MELPS4"] = true
|
||||
--CPUS["HPHYBRID"] = true
|
||||
--CPUS["SM510"] = true
|
||||
CPUS["ST62XX"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores
|
||||
@ -4560,6 +4561,7 @@ files {
|
||||
MAME_DIR .. "src/mame/machine/inder_vid.cpp",
|
||||
MAME_DIR .. "src/mame/machine/inder_vid.h",
|
||||
MAME_DIR .. "src/mame/drivers/corona.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/cwheel.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/crystal.cpp",
|
||||
MAME_DIR .. "src/mame/video/vrender0.cpp",
|
||||
MAME_DIR .. "src/mame/video/vrender0.h",
|
||||
|
@ -756,9 +756,7 @@ void avr8_device::device_start()
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_shifted_pc).noshow();
|
||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_r[AVR8_REGIDX_SREG]).callimport().callexport().formatstr("%8s").noshow();
|
||||
state_add(AVR8_SREG, "STATUS", m_r[AVR8_REGIDX_SREG]).mask(0xff);
|
||||
state_add(AVR8_PC, "PC", m_shifted_pc).mask(m_addr_mask);
|
||||
state_add(AVR8_SPH, "SPH", m_r[AVR8_REGIDX_SPH]).mask(0xff);
|
||||
state_add(AVR8_SPL, "SPL", m_r[AVR8_REGIDX_SPL]).mask(0xff);
|
||||
state_add(AVR8_PC, "SP", m_stack_level).mask(0x7);
|
||||
state_add(AVR8_R0, "R0", m_r[ 0]).mask(0xff);
|
||||
state_add(AVR8_R1, "R1", m_r[ 1]).mask(0xff);
|
||||
state_add(AVR8_R2, "R2", m_r[ 2]).mask(0xff);
|
||||
|
@ -93,8 +93,8 @@ public:
|
||||
uint64_t get_elapsed_cycles() const { return m_elapsed_cycles; }
|
||||
|
||||
// register handling
|
||||
DECLARE_WRITE8_MEMBER( regs_w );
|
||||
DECLARE_READ8_MEMBER( regs_r );
|
||||
DECLARE_WRITE8_MEMBER(regs_w);
|
||||
DECLARE_READ8_MEMBER(regs_r);
|
||||
uint32_t m_shifted_pc;
|
||||
|
||||
protected:
|
||||
|
955
src/devices/cpu/st62xx/st62xx.cpp
Normal file
955
src/devices/cpu/st62xx/st62xx.cpp
Normal file
@ -0,0 +1,955 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/**********************************************************************
|
||||
|
||||
STmicro ST6-series microcontroller emulation skeleton
|
||||
|
||||
To Do:
|
||||
- Cycle counts
|
||||
- STOP, WAIT opcodes
|
||||
- Peripherals
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "st62xx.h"
|
||||
#include "st62xx_dasm.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(ST6228, st6228_device, "st6228", "STmicro ST6228")
|
||||
|
||||
void st6228_device::st6228_program_map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x7ff).bankr("program_rombank");
|
||||
map(0x800, 0xfff).rom().region(tag(), 0x800);
|
||||
}
|
||||
|
||||
void st6228_device::st6228_data_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x3f).bankrw("rambank");
|
||||
map(0x40, 0x7f).bankr("data_rombank");
|
||||
map(0x80, 0xff).rw(FUNC(st6228_device::regs_r), FUNC(st6228_device::regs_w));
|
||||
}
|
||||
|
||||
st6228_device::st6228_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cpu_device(mconfig, ST6228, tag, owner, clock)
|
||||
, m_pc(0)
|
||||
, m_mode(MODE_NMI)
|
||||
, m_prev_mode(MODE_NORMAL)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 8, 12, 0, address_map_constructor(FUNC(st6228_device::st6228_program_map), this))
|
||||
, m_data_config("data", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(st6228_device::st6228_data_map), this))
|
||||
, m_program(nullptr)
|
||||
, m_data(nullptr)
|
||||
, m_rambank(*this, "^rambank")
|
||||
, m_program_rombank(*this, "^program_rombank")
|
||||
, m_data_rombank(*this, "^data_rombank")
|
||||
, m_rom(*this, this->tag())
|
||||
{
|
||||
}
|
||||
|
||||
void st6228_device::unimplemented_opcode(uint8_t op)
|
||||
{
|
||||
fatalerror("ST62xx: unknown opcode (%02x) at %04x\n", op, m_pc);
|
||||
}
|
||||
|
||||
void st6228_device::device_start()
|
||||
{
|
||||
m_pc = 0;
|
||||
|
||||
m_program = &space(AS_PROGRAM);
|
||||
m_data = &space(AS_DATA);
|
||||
|
||||
// register our state for the debugger
|
||||
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
|
||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_flags[0]).callimport().callexport().formatstr("%6s").noshow();
|
||||
state_add(STATE_FLAGS, "FLAGS", m_flags[0]).mask(0x3f);
|
||||
state_add(STATE_PC, "PC", m_pc).mask(0xfff);
|
||||
state_add(STATE_SP, "SP", m_stack_index).mask(0x7);
|
||||
state_add(STATE_STACK, "STACK", m_stack[0]).callimport().callexport().formatstr("%04X");
|
||||
state_add(STATE_A, "A", m_regs[REG_A]);
|
||||
state_add(STATE_X, "X", m_regs[REG_X]);
|
||||
state_add(STATE_Y, "Y", m_regs[REG_Y]);
|
||||
state_add(STATE_V, "V", m_regs[REG_V]);
|
||||
state_add(STATE_W, "W", m_regs[REG_W]);
|
||||
|
||||
save_item(NAME(m_regs));
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_prev_mode));
|
||||
save_item(NAME(m_flags));
|
||||
save_item(NAME(m_stack));
|
||||
save_item(NAME(m_stack_index));
|
||||
save_item(NAME(m_icount));
|
||||
|
||||
// set our instruction counter
|
||||
set_icountptr(m_icount);
|
||||
|
||||
m_rambank->configure_entries(0, 2, m_ram, 0x40);
|
||||
m_program_rombank->configure_entries(0, 2, m_rom, 0x800);
|
||||
m_data_rombank->configure_entries(0, 128, m_rom, 0x40);
|
||||
}
|
||||
|
||||
void st6228_device::device_reset()
|
||||
{
|
||||
std::fill(std::begin(m_regs), std::end(m_regs), 0);
|
||||
std::fill(std::begin(m_ram), std::end(m_ram), 0);
|
||||
std::fill(std::begin(m_stack), std::end(m_stack), 0);
|
||||
std::fill(std::begin(m_flags), std::end(m_flags), 0);
|
||||
|
||||
m_pc = m_program->read_word(VEC_RESET);
|
||||
m_stack_index = 0;
|
||||
m_mode = MODE_NMI;
|
||||
m_prev_mode = MODE_NORMAL;
|
||||
|
||||
m_rambank->set_entry(0);
|
||||
m_program_rombank->set_entry(0);
|
||||
m_data_rombank->set_entry(0);
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector st6228_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
std::make_pair(AS_DATA, &m_data_config)
|
||||
};
|
||||
}
|
||||
|
||||
void st6228_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||
{
|
||||
switch (entry.index())
|
||||
{
|
||||
case STATE_GENFLAGS:
|
||||
str = string_format("%c%c%c%c%c%c",
|
||||
(m_flags[2] & FLAG_C) ? 'C' : '.',
|
||||
(m_flags[2] & FLAG_Z) ? 'Z' : '.',
|
||||
(m_flags[1] & FLAG_C) ? 'C' : '.',
|
||||
(m_flags[1] & FLAG_Z) ? 'Z' : '.',
|
||||
(m_flags[0] & FLAG_C) ? 'C' : '.',
|
||||
(m_flags[0] & FLAG_Z) ? 'Z' : '.');
|
||||
break;
|
||||
case STATE_STACK:
|
||||
str = string_format("%04X", m_stack[m_stack_index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<util::disasm_interface> st6228_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<st62xx_disassembler>();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(st6228_device::regs_w)
|
||||
{
|
||||
offset += 0x80;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case REG_X:
|
||||
case REG_Y:
|
||||
case REG_V:
|
||||
case REG_W:
|
||||
case REG_A:
|
||||
m_regs[offset] = data;
|
||||
break;
|
||||
default:
|
||||
logerror("%s: Unknown register write: %02x = %02x\n", machine().describe_context(), offset, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(st6228_device::regs_r)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
offset += 0x80;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case REG_X:
|
||||
case REG_Y:
|
||||
case REG_V:
|
||||
case REG_W:
|
||||
case REG_A:
|
||||
ret = m_regs[offset];
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: Unknown register read: %02x\n", machine().describe_context(), offset);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t st6228_device::execute_min_cycles() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint32_t st6228_device::execute_max_cycles() const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
uint32_t st6228_device::execute_input_lines() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void st6228_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
logerror("%s: Unimplemented: execute_set_input line %d = %d\n", machine().describe_context(), inputnum, state);
|
||||
}
|
||||
|
||||
void st6228_device::tick_timers(int cycles)
|
||||
{
|
||||
}
|
||||
|
||||
void st6228_device::execute_run()
|
||||
{
|
||||
while (m_icount > 0)
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
uint8_t op = m_program->read_byte(m_pc);
|
||||
m_pc++;
|
||||
|
||||
int cycles = 4;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x00: case 0x10: case 0x20: case 0x30: case 0x40: case 0x50: case 0x60: case 0x70:
|
||||
case 0x80: case 0xa0: case 0xb0: case 0xc0: case 0xd0: case 0xe0: case 0xf0:
|
||||
case 0x08: case 0x18: case 0x28: case 0x38: case 0x48: case 0x58: case 0x68: case 0x78:
|
||||
case 0x88: case 0xa8: case 0xb8: case 0xc8: case 0xd8: case 0xe8: case 0xf8: // JRNZ e
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
if (!(m_flags[m_mode] & FLAG_Z))
|
||||
m_pc += e;
|
||||
break;
|
||||
}
|
||||
case 0x01: case 0x11: case 0x21: case 0x31: case 0x41: case 0x51: case 0x61: case 0x71:
|
||||
case 0x81: case 0x91: case 0xa1: case 0xb1: case 0xc1: case 0xd1: case 0xe1: case 0xf1: // CALL abc
|
||||
{
|
||||
const uint8_t ab = m_program->read_byte(m_pc);
|
||||
m_pc++;
|
||||
const uint16_t abc = ((op & 0xf0) >> 4) | (ab << 4);
|
||||
if (m_stack_index < 6) // FIXME: magic numbers
|
||||
{
|
||||
m_stack[m_stack_index] = m_pc;
|
||||
m_stack_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Per documentation: "If more calls [than the maximum] are nested, the latest stacked PC
|
||||
// values will be lost. In this case, returns will return to the PC
|
||||
// values stacked first."
|
||||
}
|
||||
m_pc = abc;
|
||||
break;
|
||||
}
|
||||
case 0x09: case 0x19: case 0x29: case 0x39: case 0x49: case 0x59: case 0x69: case 0x79:
|
||||
case 0x89: case 0x99: case 0xa9: case 0xb9: case 0xc9: case 0xd9: case 0xe9: case 0xf9: // JP abc
|
||||
{
|
||||
const uint8_t ab = m_program->read_byte(m_pc);
|
||||
m_pc++;
|
||||
const uint16_t abc = ((op & 0xf0) >> 4) | (ab << 4);
|
||||
m_pc = abc;
|
||||
break;
|
||||
}
|
||||
case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72:
|
||||
case 0x82: case 0x92: case 0xa2: case 0xb2: case 0xc2: case 0xd2: case 0xe2: case 0xf2:
|
||||
case 0x0a: case 0x1a: case 0x2a: case 0x3a: case 0x4a: case 0x5a: case 0x6a: case 0x7a:
|
||||
case 0x8a: case 0x9a: case 0xaa: case 0xba: case 0xca: case 0xda: case 0xea: case 0xfa: // JRNC abc
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
if (!(m_flags[m_mode] & FLAG_C))
|
||||
m_pc += e;
|
||||
break;
|
||||
}
|
||||
case 0x03: case 0x23: case 0x43: case 0x63: case 0x83: case 0xa3: case 0xc3: case 0xe3: // JRR b,rr,ee
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = m_program->read_byte(m_pc+1);
|
||||
const int8_t ee = (int8_t)m_program->read_byte(m_pc+2);
|
||||
const uint8_t value = m_data->read_byte(rr);
|
||||
if (BIT(value, b))
|
||||
m_pc += 2;
|
||||
else
|
||||
m_pc += ee;
|
||||
break;
|
||||
}
|
||||
case 0x13: case 0x33: case 0x53: case 0x73: case 0x93: case 0xb3: case 0xd3: case 0xf3: // JRS b,rr,ee
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = m_program->read_byte(m_pc+1);
|
||||
const int8_t ee = (int8_t)m_program->read_byte(m_pc+2);
|
||||
const uint8_t value = m_data->read_byte(rr);
|
||||
if (BIT(value, b))
|
||||
m_pc += ee;
|
||||
else
|
||||
m_pc += 2;
|
||||
break;
|
||||
}
|
||||
case 0x0b: case 0x2b: case 0x4b: case 0x6b: case 0x8b: case 0xab: case 0xcb: case 0xeb: // RES b,rr
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = m_program->read_byte(m_pc);
|
||||
const uint8_t nn = m_data->read_byte(rr);
|
||||
m_data->write_byte(rr, nn & ~(1 << b));
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x1b: case 0x3b: case 0x5b: case 0x7b: case 0x9b: case 0xbb: case 0xdb: case 0xfb: // SET b,rr
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = m_program->read_byte(m_pc);
|
||||
const uint8_t nn = m_data->read_byte(rr);
|
||||
m_data->write_byte(rr, nn | (1 << b));
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x04: case 0x14: case 0x24: case 0x34: case 0x44: case 0x54: case 0x64: case 0x74:
|
||||
case 0x84: case 0x94: case 0xa4: case 0xb4: case 0xc4: case 0xd4: case 0xe4: case 0xf4:
|
||||
case 0x0c: case 0x1c: case 0x2c: case 0x3c: case 0x4c: case 0x5c: case 0x6c: case 0x7c:
|
||||
case 0x8c: case 0x9c: case 0xac: case 0xbc: case 0xcc: case 0xdc: case 0xec: case 0xfc: // JRZ e
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
if (m_flags[m_mode] & FLAG_Z)
|
||||
m_pc += e;
|
||||
break;
|
||||
}
|
||||
case 0x06: case 0x16: case 0x26: case 0x36: case 0x46: case 0x56: case 0x66: case 0x76:
|
||||
case 0x86: case 0x96: case 0xa6: case 0xb6: case 0xc6: case 0xd6: case 0xe6: case 0xf6:
|
||||
case 0x0e: case 0x1e: case 0x2e: case 0x3e: case 0x4e: case 0x5e: case 0x6e: case 0x7e:
|
||||
case 0x8e: case 0x9e: case 0xae: case 0xbe: case 0xce: case 0xde: case 0xee: case 0xfe: // JRC e
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
if (m_flags[m_mode] & FLAG_C)
|
||||
m_pc += e;
|
||||
break;
|
||||
}
|
||||
case 0x15: // INC X
|
||||
m_regs[REG_X]++;
|
||||
|
||||
if (m_regs[REG_X])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x35: // LD A,X
|
||||
m_regs[REG_A] = m_regs[REG_X];
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x55: // INC Y
|
||||
m_regs[REG_Y]++;
|
||||
|
||||
if (m_regs[REG_Y])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x75: // LD A,Y
|
||||
m_regs[REG_A] = m_regs[REG_Y];
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x95: // INC V
|
||||
m_regs[REG_V]++;
|
||||
|
||||
if (m_regs[REG_V])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xb5: // LD A,V
|
||||
m_regs[REG_A] = m_regs[REG_V];
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xd5: // INC W
|
||||
m_regs[REG_W]++;
|
||||
|
||||
if (m_regs[REG_W])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xf5: // LD A,W
|
||||
m_regs[REG_A] = m_regs[REG_W];
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x0d: // LDI rr,nn
|
||||
{
|
||||
const uint8_t rr = m_program->read_byte(m_pc);
|
||||
const uint8_t nn = m_program->read_byte(m_pc);
|
||||
m_data->write_byte(rr, nn);
|
||||
|
||||
if (nn)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc += 2;
|
||||
break;
|
||||
}
|
||||
case 0x1d: // DEC X
|
||||
m_regs[REG_X]--;
|
||||
|
||||
if (m_regs[REG_X])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x2d: // COM A
|
||||
if (BIT(m_regs[REG_A], 7))
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
else
|
||||
m_flags[m_mode] &= FLAG_C;
|
||||
|
||||
m_regs[REG_A] = ~m_regs[REG_A];
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x3d: // LD X,A
|
||||
m_regs[REG_X] = m_regs[REG_A];
|
||||
|
||||
if (m_regs[REG_X])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x4d:
|
||||
if (m_stack_index > 0)
|
||||
{
|
||||
m_stack_index--;
|
||||
m_pc = m_stack[m_stack_index];
|
||||
m_mode = m_prev_mode;
|
||||
m_prev_mode = MODE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror("Attempted to RETI with nothing on the stack");
|
||||
}
|
||||
break;
|
||||
case 0x5d: // DEC Y
|
||||
m_regs[REG_Y]--;
|
||||
|
||||
if (m_regs[REG_Y])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x6d:
|
||||
//util::stream_format(stream, "STOP");
|
||||
break;
|
||||
case 0x7d: // LD Y,A
|
||||
m_regs[REG_Y] = m_regs[REG_A];
|
||||
|
||||
if (m_regs[REG_Y])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x9d: // DEC V
|
||||
m_regs[REG_V]--;
|
||||
|
||||
if (m_regs[REG_V])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xad: // RLC
|
||||
{
|
||||
const uint8_t old_c = (m_flags[m_mode] & FLAG_C) ? 1 : 0;
|
||||
if (BIT(m_regs[REG_A], 7))
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
m_regs[REG_A] = (m_regs[REG_A] << 1) | old_c;
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
}
|
||||
case 0xbd: // LD V,A
|
||||
m_regs[REG_V] = m_regs[REG_A];
|
||||
|
||||
if (m_regs[REG_V])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xcd:
|
||||
if (m_stack_index > 0)
|
||||
{
|
||||
m_stack_index--;
|
||||
m_pc = m_stack[m_stack_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror("Attempted to RET with nothing on the stack");
|
||||
}
|
||||
break;
|
||||
case 0xdd: // DEC W
|
||||
m_regs[REG_W]--;
|
||||
|
||||
if (m_regs[REG_W])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xed:
|
||||
//util::stream_format(stream, "WAIT");
|
||||
break;
|
||||
case 0xfd: // LD W,A
|
||||
m_regs[REG_W] = m_regs[REG_A];
|
||||
|
||||
if (m_regs[REG_W])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x07: // LD A,(X)
|
||||
m_regs[REG_A] = m_data->read_byte(m_regs[REG_X]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x17: // LDI A,rr
|
||||
{
|
||||
m_regs[REG_A] = m_program->read_byte(m_pc);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x27: // CP A,(X)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_X]);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x37: // CPI A,nn
|
||||
{
|
||||
const uint8_t nn = m_program->read_byte(m_pc);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x47: // ADD A,(X)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_X]);
|
||||
const uint16_t sum = m_regs[REG_A] + nn;
|
||||
|
||||
if (sum > 0xff)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (sum == 0)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] = (uint8_t)sum;
|
||||
break;
|
||||
}
|
||||
case 0x57: // ADDI A,nn
|
||||
{
|
||||
const uint8_t nn = m_program->read_byte(m_pc);
|
||||
const uint16_t sum = m_regs[REG_A] + nn;
|
||||
|
||||
if (sum > 0xff)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (sum == 0)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] = (uint8_t)sum;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x67: // INC (X)
|
||||
{
|
||||
const uint8_t rr = m_data->read_byte(m_regs[REG_X]) + 1;
|
||||
m_data->write_byte(m_regs[REG_X], rr);
|
||||
|
||||
if (rr)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
}
|
||||
case 0x87: // LD (X),A
|
||||
m_data->write_byte(m_regs[REG_X], m_regs[REG_A]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xa7: // AND A,(X)
|
||||
m_regs[REG_A] &= m_data->read_byte(m_regs[REG_X]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0xb7: // ANDI A,nn
|
||||
{
|
||||
m_regs[REG_A] &= m_program->read_byte(m_pc);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0xc7: // SUB A,(X)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_X]);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] -= nn;
|
||||
break;
|
||||
}
|
||||
case 0xd7: // SUBI A,nn
|
||||
{
|
||||
const uint8_t nn = m_program->read_byte(m_pc);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] -= nn;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0xe7: // DEC (X)
|
||||
{
|
||||
const uint8_t rr = m_data->read_byte(m_regs[REG_X]) - 1;
|
||||
m_data->write_byte(m_regs[REG_X], rr);
|
||||
|
||||
if (rr)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
}
|
||||
case 0x0f: // LD A,(Y)
|
||||
m_regs[REG_A] = m_data->read_byte(m_regs[REG_Y]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x1f: // LD A,rr
|
||||
{
|
||||
m_regs[REG_A] = m_data->read_byte(m_program->read_byte(m_pc));
|
||||
|
||||
if (m_regs[REG_V])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x2f: // CP A,(Y)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_Y]);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x3f: // CP A,rr
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_program->read_byte(m_pc));
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x4f: // ADD A,(Y)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_Y]);
|
||||
const uint16_t sum = m_regs[REG_A] + nn;
|
||||
|
||||
if (sum > 0xff)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (sum == 0)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] = (uint8_t)sum;
|
||||
break;
|
||||
}
|
||||
case 0x5f: // ADD A,rr
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_program->read_byte(m_pc));
|
||||
const uint16_t sum = m_regs[REG_A] + nn;
|
||||
|
||||
if (sum > 0xff)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (sum == 0)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] = (uint8_t)sum;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x6f: // INC (Y)
|
||||
{
|
||||
const uint8_t rr = m_data->read_byte(m_regs[REG_Y]) + 1;
|
||||
m_data->write_byte(m_regs[REG_Y], rr);
|
||||
|
||||
if (rr)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
}
|
||||
case 0x7f: // INC A
|
||||
{
|
||||
m_regs[REG_A]++;
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0x8f: // LD (Y),A
|
||||
m_data->write_byte(m_regs[REG_Y], m_regs[REG_A]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
case 0x9f: // LD rr,A
|
||||
{
|
||||
m_regs[REG_A] = m_data->read_byte(m_program->read_byte(m_pc));
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0xaf: // AND A,(Y)
|
||||
m_regs[REG_A] &= m_data->read_byte(m_regs[REG_Y]);
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
|
||||
break;
|
||||
case 0xbf: // AND A,rr
|
||||
{
|
||||
m_regs[REG_A] &= m_data->read_byte(m_program->read_byte(m_pc));
|
||||
|
||||
if (m_regs[REG_A])
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0xcf: // SUB A,(Y)
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_regs[REG_Y]);
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] -= nn;
|
||||
break;
|
||||
}
|
||||
case 0xdf: // SUB A,rr
|
||||
{
|
||||
const uint8_t nn = m_data->read_byte(m_program->read_byte(m_pc));
|
||||
|
||||
if (m_regs[REG_A] < nn)
|
||||
{
|
||||
m_flags[m_mode] |= FLAG_C;
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags[m_mode] &= ~FLAG_C;
|
||||
if (m_regs[REG_A] == nn)
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
}
|
||||
m_regs[REG_A] -= nn;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
case 0xef: // DEC (Y)
|
||||
{
|
||||
const uint8_t rr = m_data->read_byte(m_regs[REG_Y]) - 1;
|
||||
m_data->write_byte(m_regs[REG_Y], rr);
|
||||
|
||||
if (rr)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
break;
|
||||
}
|
||||
case 0xff: // DEC rr
|
||||
{
|
||||
const uint8_t rr = m_program->read_byte(m_pc);
|
||||
const uint8_t value = m_data->read_byte(rr) - 1;
|
||||
m_data->write_byte(rr, value);
|
||||
|
||||
if (value)
|
||||
m_flags[m_mode] &= ~FLAG_Z;
|
||||
else
|
||||
m_flags[m_mode] |= FLAG_Z;
|
||||
m_pc++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logerror("%s: Unsupported opcode: %02x\n", op);
|
||||
}
|
||||
|
||||
tick_timers(cycles);
|
||||
|
||||
m_icount -= cycles;
|
||||
}
|
||||
}
|
176
src/devices/cpu/st62xx/st62xx.h
Normal file
176
src/devices/cpu/st62xx/st62xx.h
Normal file
@ -0,0 +1,176 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/**********************************************************************
|
||||
|
||||
STmicro ST6-series microcontroller emulation
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
Vdd 1 |* \_/ | 28 Vss
|
||||
TIMER 2 | | 27 PA0
|
||||
OSCin 3 | | 26 PA1
|
||||
OSCout 4 | | 25 PA2/ARTIMout
|
||||
NMI 5 | | 24 PA3/ARTIMin
|
||||
PC7 6 | | 23 PA4
|
||||
PC6 7 | ST62T28C | 22 PA5
|
||||
Ain/PC5 8 | ST62E28C | 21 PD1/Ain/Scl
|
||||
Ain/PC4 9 | | 20 PD2/Ain/Sin
|
||||
TEST/Vpp 10 | | 19 PD3/Ain/Sout
|
||||
/RESET 11 | | 18 PD4/Ain/RXD1
|
||||
Ain/PB6 12 | | 17 PD5/Ain/TXD1
|
||||
Ain/PB5 13 | | 16 PD6/Ain
|
||||
Ain/PB4 14 |_____________| 15 PD7/Ain
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_ST62XX_H
|
||||
#define MAME_CPU_ST62XX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class st6228_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
st6228_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual uint32_t execute_min_cycles() const override;
|
||||
virtual uint32_t execute_max_cycles() const override;
|
||||
virtual uint32_t execute_input_lines() const override;
|
||||
virtual void execute_run() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
// device_disasm_interface overrides
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
// device_state_interface overrides
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
// address spaces
|
||||
void st6228_program_map(address_map &map);
|
||||
void st6228_data_map(address_map &map);
|
||||
|
||||
void unimplemented_opcode(uint8_t op);
|
||||
void tick_timers(int cycles);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(regs_w);
|
||||
DECLARE_READ8_MEMBER(regs_r);
|
||||
|
||||
enum
|
||||
{
|
||||
STATE_FLAGS = 1,
|
||||
STATE_PC,
|
||||
STATE_SP,
|
||||
STATE_STACK,
|
||||
STATE_A,
|
||||
STATE_X,
|
||||
STATE_Y,
|
||||
STATE_V,
|
||||
STATE_W
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROGRAM_ROM_START = 0x40,
|
||||
REGS_START = 0x80,
|
||||
REG_X = 0x80,
|
||||
REG_Y = 0x81,
|
||||
REG_V = 0x82,
|
||||
REG_W = 0x83,
|
||||
DATA_RAM_START = 0x84,
|
||||
REG_PORTA_DATA = 0xc0,
|
||||
REG_PORTB_DATA = 0xc1,
|
||||
REG_PORTC_DATA = 0xc2,
|
||||
REG_PORTD_DATA = 0xc3,
|
||||
REG_PORTA_DIR = 0xc4,
|
||||
REG_PORTB_DIR = 0xc5,
|
||||
REG_PORTC_DIR = 0xc6,
|
||||
REG_PORTD_DIR = 0xc7,
|
||||
REG_INT_OPTION = 0xc8,
|
||||
REG_DATA_ROM_WINDOW = 0xc9,
|
||||
REG_ROM_BANK_SELECT = 0xca,
|
||||
REG_RAM_BANK_SELECT = 0xcb,
|
||||
REG_PORTA_OPTION = 0xcc,
|
||||
REG_PORTB_OPTION = 0xcd,
|
||||
REG_PORTC_OPTION = 0xce,
|
||||
REG_PORTD_OPTION = 0xcf,
|
||||
REG_AD_DATA = 0xd0,
|
||||
REG_AD_CONTROL = 0xd1,
|
||||
REG_TIMER_PRESCALE = 0xd2,
|
||||
REG_TIMER_COUNT = 0xd3,
|
||||
REG_TIMER_CONTROL = 0xd4,
|
||||
REG_UART_DATA = 0xd6,
|
||||
REG_UART_CONTROL = 0xd7,
|
||||
REG_WATCHDOG = 0xd8,
|
||||
REG_INT_POLARITY = 0xda,
|
||||
REG_SPI_INT_DISABLE = 0xdc,
|
||||
REG_SPI_DATA = 0xdd,
|
||||
REG_ARTIMER_MODE = 0xe5,
|
||||
REG_ARTIMER_ARCS0 = 0xe6,
|
||||
REG_ARTIMER_ARCS1 = 0xe7,
|
||||
REG_ARTIMER_RELOAD = 0xe9,
|
||||
REG_ARTIMER_COMPARE = 0xea,
|
||||
REG_ARTIMER_LOAD = 0xeb,
|
||||
REG_A = 0xff
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_NORMAL,
|
||||
MODE_IRQ,
|
||||
MODE_NMI
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VEC_IRQ0 = 0xff0,
|
||||
VEC_IRQ1 = 0xff2,
|
||||
VEC_IRQ2 = 0xff4,
|
||||
VEC_IRQ3 = 0xff6,
|
||||
VEC_NMI = 0xffc,
|
||||
VEC_RESET = 0xffe
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FLAG_C = 0x01,
|
||||
FLAG_Z = 0x02
|
||||
};
|
||||
|
||||
// CPU registers
|
||||
uint8_t m_regs[0x100];
|
||||
uint8_t m_ram[64*2];
|
||||
|
||||
uint16_t m_pc;
|
||||
uint8_t m_mode;
|
||||
uint8_t m_prev_mode;
|
||||
uint8_t m_flags[3];
|
||||
|
||||
uint16_t m_stack[6];
|
||||
uint8_t m_stack_index;
|
||||
|
||||
int m_icount;
|
||||
|
||||
const address_space_config m_program_config;
|
||||
const address_space_config m_data_config;
|
||||
|
||||
address_space *m_program;
|
||||
address_space *m_data;
|
||||
|
||||
required_memory_bank m_rambank;
|
||||
required_memory_bank m_program_rombank;
|
||||
required_memory_bank m_data_rombank;
|
||||
required_memory_region m_rom;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ST6228, st6228_device)
|
||||
|
||||
#endif // MAME_CPU_ST62XX_H
|
388
src/devices/cpu/st62xx/st62xx_dasm.cpp
Normal file
388
src/devices/cpu/st62xx/st62xx_dasm.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/**********************************************************************
|
||||
|
||||
STmicro ST6-series microcontroller disassembler
|
||||
|
||||
To Do:
|
||||
- Named registers/bits
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "st62xx_dasm.h"
|
||||
|
||||
uint32_t st62xx_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
offs_t st62xx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
|
||||
{
|
||||
offs_t base_pc = pc;
|
||||
const uint8_t op = opcodes.r8(pc);
|
||||
pc++;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x00: case 0x10: case 0x20: case 0x30: case 0x40: case 0x50: case 0x60: case 0x70:
|
||||
case 0x80: case 0xa0: case 0xb0: case 0xc0: case 0xd0: case 0xe0: case 0xf0:
|
||||
case 0x08: case 0x18: case 0x28: case 0x38: case 0x48: case 0x58: case 0x68: case 0x78:
|
||||
case 0x88: case 0xa8: case 0xb8: case 0xc8: case 0xd8: case 0xe8: case 0xf8:
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
util::stream_format(stream, "JRNZ $%d", e);
|
||||
break;
|
||||
}
|
||||
case 0x01: case 0x11: case 0x21: case 0x31: case 0x41: case 0x51: case 0x61: case 0x71:
|
||||
case 0x81: case 0x91: case 0xa1: case 0xb1: case 0xc1: case 0xd1: case 0xe1: case 0xf1:
|
||||
{
|
||||
const uint8_t ab = opcodes.r8(pc);
|
||||
pc++;
|
||||
const uint16_t abc = ((op & 0xf0) >> 4) | (ab << 4);
|
||||
util::stream_format(stream, "CALL %Xh", abc);
|
||||
break;
|
||||
}
|
||||
case 0x09: case 0x19: case 0x29: case 0x39: case 0x49: case 0x59: case 0x69: case 0x79:
|
||||
case 0x89: case 0x99: case 0xa9: case 0xb9: case 0xc9: case 0xd9: case 0xe9: case 0xf9:
|
||||
{
|
||||
const uint8_t ab = opcodes.r8(pc);
|
||||
pc++;
|
||||
const uint16_t abc = ((op & 0xf0) >> 4) | (ab << 4);
|
||||
util::stream_format(stream, "JP %Xh", abc);
|
||||
break;
|
||||
}
|
||||
case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72:
|
||||
case 0x82: case 0x92: case 0xa2: case 0xb2: case 0xc2: case 0xd2: case 0xe2: case 0xf2:
|
||||
case 0x0a: case 0x1a: case 0x2a: case 0x3a: case 0x4a: case 0x5a: case 0x6a: case 0x7a:
|
||||
case 0x8a: case 0x9a: case 0xaa: case 0xba: case 0xca: case 0xda: case 0xea: case 0xfa:
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
util::stream_format(stream, "JRNC $%d", e);
|
||||
break;
|
||||
}
|
||||
case 0x03: case 0x23: case 0x43: case 0x63: case 0x83: case 0xa3: case 0xc3: case 0xe3:
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
const int8_t ee = (int8_t)opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "JRR %d,%Xh,$%Xh", b, rr, ee);
|
||||
break;
|
||||
}
|
||||
case 0x13: case 0x33: case 0x53: case 0x73: case 0x93: case 0xb3: case 0xd3: case 0xf3:
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
const int8_t ee = (int8_t)opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "JRS %d,%Xh,$%Xh", b, rr, ee);
|
||||
break;
|
||||
}
|
||||
case 0x0b: case 0x2b: case 0x4b: case 0x6b: case 0x8b: case 0xab: case 0xcb: case 0xeb:
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "RES %d,%Xh", b, rr);
|
||||
break;
|
||||
}
|
||||
case 0x1b: case 0x3b: case 0x5b: case 0x7b: case 0x9b: case 0xbb: case 0xdb: case 0xfb:
|
||||
{
|
||||
const uint8_t b = (op >> 5) & 7;
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "SET %d,%Xh", b, rr);
|
||||
break;
|
||||
}
|
||||
case 0x04: case 0x14: case 0x24: case 0x34: case 0x44: case 0x54: case 0x64: case 0x74:
|
||||
case 0x84: case 0x94: case 0xa4: case 0xb4: case 0xc4: case 0xd4: case 0xe4: case 0xf4:
|
||||
case 0x0c: case 0x1c: case 0x2c: case 0x3c: case 0x4c: case 0x5c: case 0x6c: case 0x7c:
|
||||
case 0x8c: case 0x9c: case 0xac: case 0xbc: case 0xcc: case 0xdc: case 0xec: case 0xfc:
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
util::stream_format(stream, "JRZ $%d", e);
|
||||
break;
|
||||
}
|
||||
case 0x06: case 0x16: case 0x26: case 0x36: case 0x46: case 0x56: case 0x66: case 0x76:
|
||||
case 0x86: case 0x96: case 0xa6: case 0xb6: case 0xc6: case 0xd6: case 0xe6: case 0xf6:
|
||||
case 0x0e: case 0x1e: case 0x2e: case 0x3e: case 0x4e: case 0x5e: case 0x6e: case 0x7e:
|
||||
case 0x8e: case 0x9e: case 0xae: case 0xbe: case 0xce: case 0xde: case 0xee: case 0xfe:
|
||||
{
|
||||
const int8_t e = ((int8_t)op) >> 3;
|
||||
util::stream_format(stream, "JRC $%d", e);
|
||||
break;
|
||||
}
|
||||
case 0x15:
|
||||
util::stream_format(stream, "INC X"); // x
|
||||
break;
|
||||
case 0x35:
|
||||
util::stream_format(stream, "LD A,X"); // a,x
|
||||
break;
|
||||
case 0x55:
|
||||
util::stream_format(stream, "INC Y"); // y
|
||||
break;
|
||||
case 0x75:
|
||||
util::stream_format(stream, "LD A,Y"); // a,y
|
||||
break;
|
||||
case 0x95:
|
||||
util::stream_format(stream, "INC V"); // v
|
||||
break;
|
||||
case 0xb5:
|
||||
util::stream_format(stream, "LD A,V"); // a,v
|
||||
break;
|
||||
case 0xd5:
|
||||
util::stream_format(stream, "INC W"); // w
|
||||
break;
|
||||
case 0xf5:
|
||||
util::stream_format(stream, "LD A,W"); // a,w
|
||||
break;
|
||||
case 0x0d:
|
||||
{
|
||||
const uint8_t nn = opcodes.r8(pc);
|
||||
pc++;
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0 && nn == 0x80)
|
||||
util::stream_format(stream, "CLR X");
|
||||
else if (rr == 0 && nn == 0x81)
|
||||
util::stream_format(stream, "CLR Y");
|
||||
else if (rr == 0 && nn == 0x82)
|
||||
util::stream_format(stream, "CLR V");
|
||||
else if (rr == 0 && nn == 0x83)
|
||||
util::stream_format(stream, "CLR W");
|
||||
else if (rr == 0)
|
||||
util::stream_format(stream, "CLR $%Xh", nn);
|
||||
else
|
||||
util::stream_format(stream, "LDI $%Xh,%Xh", rr, nn);
|
||||
break;
|
||||
}
|
||||
case 0x1d:
|
||||
util::stream_format(stream, "DEC X"); // x
|
||||
break;
|
||||
case 0x2d:
|
||||
util::stream_format(stream, "COM A"); // a
|
||||
break;
|
||||
case 0x3d:
|
||||
util::stream_format(stream, "LD X,A"); // x,a
|
||||
break;
|
||||
case 0x4d:
|
||||
util::stream_format(stream, "RETI");
|
||||
break;
|
||||
case 0x5d:
|
||||
util::stream_format(stream, "DEC Y"); // y
|
||||
break;
|
||||
case 0x6d:
|
||||
util::stream_format(stream, "STOP");
|
||||
break;
|
||||
case 0x7d:
|
||||
util::stream_format(stream, "LD Y,A"); // y,a
|
||||
break;
|
||||
case 0x9d:
|
||||
util::stream_format(stream, "DEC V"); // v
|
||||
break;
|
||||
case 0xad:
|
||||
util::stream_format(stream, "RLC"); // a
|
||||
break;
|
||||
case 0xbd:
|
||||
util::stream_format(stream, "LD V,A"); // v,a
|
||||
break;
|
||||
case 0xcd:
|
||||
util::stream_format(stream, "RET");
|
||||
break;
|
||||
case 0xdd:
|
||||
util::stream_format(stream, "DEC W"); // w
|
||||
break;
|
||||
case 0xed:
|
||||
util::stream_format(stream, "WAIT");
|
||||
break;
|
||||
case 0xfd:
|
||||
util::stream_format(stream, "LD W,A"); // w,a
|
||||
break;
|
||||
case 0x07:
|
||||
util::stream_format(stream, "LD A,(X)"); // a,(x)
|
||||
break;
|
||||
case 0x17:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "LDI A,%Xh", rr);
|
||||
break;
|
||||
}
|
||||
case 0x27:
|
||||
util::stream_format(stream, "CP A,(X)"); // a,(x)
|
||||
break;
|
||||
case 0x37:
|
||||
{
|
||||
const uint8_t nn = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "CPI A,%Xh", nn);
|
||||
break;
|
||||
}
|
||||
case 0x47:
|
||||
util::stream_format(stream, "ADD A,(X)"); // a,(x)
|
||||
break;
|
||||
case 0x57:
|
||||
{
|
||||
const uint8_t nn = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "ADDI A,%Xh", nn);
|
||||
break;
|
||||
}
|
||||
case 0x67:
|
||||
util::stream_format(stream, "INC (X)"); // (x)
|
||||
break;
|
||||
case 0x87:
|
||||
util::stream_format(stream, "LD (X),A"); // (x),a
|
||||
break;
|
||||
case 0xa7:
|
||||
util::stream_format(stream, "AND A,(X)"); // a,(x)
|
||||
break;
|
||||
case 0xb7:
|
||||
{
|
||||
const uint8_t nn = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "ANDI A,%Xh", nn);
|
||||
break;
|
||||
}
|
||||
case 0xc7:
|
||||
util::stream_format(stream, "SUB A,(X)");
|
||||
break;
|
||||
case 0xd7:
|
||||
{
|
||||
const uint8_t nn = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "SUBI A,%Xh", nn);
|
||||
break;
|
||||
}
|
||||
case 0xe7:
|
||||
util::stream_format(stream, "DEC (X)"); // (x)
|
||||
break;
|
||||
case 0x0f:
|
||||
util::stream_format(stream, "LD A,(Y)"); // a,(y)
|
||||
break;
|
||||
case 0x1f:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "LD A,%Xh", rr);
|
||||
break;
|
||||
}
|
||||
case 0x2f:
|
||||
util::stream_format(stream, "CP A,(Y)"); // a,(y)
|
||||
break;
|
||||
case 0x3f:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "CP A,%Xh", rr); // rr
|
||||
break;
|
||||
}
|
||||
case 0x4f:
|
||||
util::stream_format(stream, "ADD A,(Y)"); // a,(y)
|
||||
break;
|
||||
case 0x5f:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0xff)
|
||||
util::stream_format(stream, "SLA A");
|
||||
else
|
||||
util::stream_format(stream, "ADD A,%Xh", rr);
|
||||
break;
|
||||
}
|
||||
case 0x6f:
|
||||
util::stream_format(stream, "INC (Y)"); // (y)
|
||||
break;
|
||||
case 0x7f:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0xff)
|
||||
util::stream_format(stream, "INC A"); // rr
|
||||
else if (rr == 0x80)
|
||||
util::stream_format(stream, "INC X"); // rr
|
||||
else if (rr == 0x81)
|
||||
util::stream_format(stream, "INC Y"); // rr
|
||||
else if (rr == 0x82)
|
||||
util::stream_format(stream, "INC V"); // rr
|
||||
else if (rr == 0x83)
|
||||
util::stream_format(stream, "INC W"); // rr
|
||||
else
|
||||
util::stream_format(stream, "INC %Xh", rr); // rr
|
||||
break;
|
||||
}
|
||||
case 0x8f:
|
||||
util::stream_format(stream, "LD (Y),A"); // (y),a
|
||||
break;
|
||||
case 0x9f:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
util::stream_format(stream, "LD %Xh,A", rr); // rr
|
||||
break;
|
||||
}
|
||||
case 0xaf:
|
||||
util::stream_format(stream, "AND A,(Y)"); // a,(y)
|
||||
break;
|
||||
case 0xbf:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0xff)
|
||||
util::stream_format(stream, "AND A,A"); // rr
|
||||
else if (rr == 0x80)
|
||||
util::stream_format(stream, "AND A,X"); // rr
|
||||
else if (rr == 0x81)
|
||||
util::stream_format(stream, "AND A,Y"); // rr
|
||||
else if (rr == 0x82)
|
||||
util::stream_format(stream, "AND A,V"); // rr
|
||||
else if (rr == 0x83)
|
||||
util::stream_format(stream, "AND A,W"); // rr
|
||||
else
|
||||
util::stream_format(stream, "AND A,%Xh", rr); // rr
|
||||
break;
|
||||
}
|
||||
case 0xcf:
|
||||
util::stream_format(stream, "SUB A,(Y)"); // a,(y)
|
||||
break;
|
||||
case 0xdf:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0xff)
|
||||
util::stream_format(stream, "CLR A", rr);
|
||||
else
|
||||
util::stream_format(stream, "SUB A,%Xh", rr);
|
||||
break;
|
||||
}
|
||||
case 0xef:
|
||||
util::stream_format(stream, "DEC (Y)"); // (y)
|
||||
break;
|
||||
case 0xff:
|
||||
{
|
||||
const uint8_t rr = opcodes.r8(pc);
|
||||
pc++;
|
||||
if (rr == 0xff)
|
||||
util::stream_format(stream, "DEC A"); // rr
|
||||
else if (rr == 0x80)
|
||||
util::stream_format(stream, "DEC X"); // rr
|
||||
else if (rr == 0x81)
|
||||
util::stream_format(stream, "DEC Y"); // rr
|
||||
else if (rr == 0x82)
|
||||
util::stream_format(stream, "DEC V"); // rr
|
||||
else if (rr == 0x83)
|
||||
util::stream_format(stream, "DEC W"); // rr
|
||||
else
|
||||
util::stream_format(stream, "DEC %Xh", rr); // rr
|
||||
break;
|
||||
}
|
||||
default:
|
||||
util::stream_format(stream, "undefined");
|
||||
break;
|
||||
}
|
||||
|
||||
return (pc - base_pc) | SUPPORTED;
|
||||
}
|
24
src/devices/cpu/st62xx/st62xx_dasm.h
Normal file
24
src/devices/cpu/st62xx/st62xx_dasm.h
Normal file
@ -0,0 +1,24 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/**********************************************************************
|
||||
|
||||
STmicro ST6-series microcontroller disassembler
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_ST62XX_DASM_H
|
||||
#define MAME_CPU_ST62XX_DASM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class st62xx_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
st62xx_disassembler() = default;
|
||||
virtual ~st62xx_disassembler() = default;
|
||||
|
||||
virtual uint32_t opcode_alignment() const override;
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_ST62XX_DASM_H
|
@ -267,6 +267,7 @@ cultures.cpp
|
||||
cupidon.cpp
|
||||
cv1k.cpp
|
||||
cvs.cpp
|
||||
cwheel.cpp
|
||||
cyberbal.cpp
|
||||
cybertnk.cpp
|
||||
cybstorm.cpp
|
||||
|
53
src/mame/drivers/cwheel.cpp
Normal file
53
src/mame/drivers/cwheel.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/******************************************************************************
|
||||
|
||||
Gamebar Catherine Wheel skeleton driver
|
||||
|
||||
Notable parts:
|
||||
- ST62T28C6: 8-bit microcontroller from STmicro, ST6 series
|
||||
- 3x MM5450N LED drivers
|
||||
- 8MHz crystal oscillator
|
||||
- 60x red LEDs in a circle
|
||||
- 5x 7-segment 1-digit LEDs
|
||||
- ULN2003A darlington transistor array
|
||||
|
||||
TODO:
|
||||
- Everything
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/st62xx/st62xx.h"
|
||||
|
||||
class cwheel_state : public driver_device
|
||||
{
|
||||
public:
|
||||
cwheel_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
{
|
||||
}
|
||||
|
||||
void cwheel(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device <st6228_device> m_maincpu;
|
||||
};
|
||||
|
||||
static INPUT_PORTS_START( cwheel )
|
||||
INPUT_PORTS_END
|
||||
|
||||
void cwheel_state::cwheel(machine_config &config)
|
||||
{
|
||||
ST6228(config, m_maincpu, XTAL(8'000'000));
|
||||
}
|
||||
|
||||
ROM_START( cwheel )
|
||||
ROM_REGION( 0x2000, "maincpu", 0 )
|
||||
ROM_LOAD( "u4.bin", 0x0000, 0x2000, CRC(2eaab25d) SHA1(c41ad372ec25435cdb6a063b094fd785b19dafd6) )
|
||||
ROM_END
|
||||
|
||||
|
||||
// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS
|
||||
GAME( 19??, cwheel, 0, cwheel, cwheel, cwheel_state, empty_init, ROT0, "Gamebar", "Catherine Wheel", MACHINE_IS_SKELETON )
|
@ -10823,6 +10823,9 @@ spacefrt // (c) 1981 Century
|
||||
superbik // (c) 1983 Century
|
||||
wallst // (c) 1982 Century
|
||||
|
||||
@source:cwheel.cpp
|
||||
cwheel // (c) 19?? Gamebar
|
||||
|
||||
@source:cxgz80.cpp
|
||||
ch2001 //
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user