mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +03:00
hmcs40 WIP
This commit is contained in:
parent
9000997384
commit
42eafe6237
@ -65,7 +65,8 @@ ADDRESS_MAP_END
|
|||||||
|
|
||||||
static ADDRESS_MAP_START(data_160x4, AS_DATA, 8, hmcs40_cpu_device)
|
static ADDRESS_MAP_START(data_160x4, AS_DATA, 8, hmcs40_cpu_device)
|
||||||
AM_RANGE(0x00, 0x7f) AM_RAM
|
AM_RANGE(0x00, 0x7f) AM_RAM
|
||||||
AM_RANGE(0x80, 0x9f) AM_RAM AM_MIRROR(0x70)
|
AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x30)
|
||||||
|
AM_RANGE(0xc0, 0xcf) AM_RAM AM_MIRROR(0x30)
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
|
||||||
@ -95,6 +96,10 @@ void hmcs40_cpu_device::state_string_export(const device_state_entry &entry, ast
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case STATE_GENPC:
|
||||||
|
string.printf("%03X", m_pc << 1);
|
||||||
|
break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +128,7 @@ void hmcs40_cpu_device::device_start()
|
|||||||
m_data = &space(AS_DATA);
|
m_data = &space(AS_DATA);
|
||||||
m_prgmask = (1 << m_prgwidth) - 1;
|
m_prgmask = (1 << m_prgwidth) - 1;
|
||||||
m_datamask = (1 << m_datawidth) - 1;
|
m_datamask = (1 << m_datawidth) - 1;
|
||||||
|
m_xmask = (1 << (m_datawidth - 4)) - 1;
|
||||||
|
|
||||||
m_read_d.resolve_safe(0);
|
m_read_d.resolve_safe(0);
|
||||||
m_write_d.resolve_safe();
|
m_write_d.resolve_safe();
|
||||||
@ -130,6 +136,7 @@ void hmcs40_cpu_device::device_start()
|
|||||||
// zerofill
|
// zerofill
|
||||||
memset(m_stack, 0, sizeof(m_stack));
|
memset(m_stack, 0, sizeof(m_stack));
|
||||||
m_op = 0;
|
m_op = 0;
|
||||||
|
m_arg = 0;
|
||||||
m_pc = 0;
|
m_pc = 0;
|
||||||
m_a = 0;
|
m_a = 0;
|
||||||
m_b = 0;
|
m_b = 0;
|
||||||
@ -143,6 +150,7 @@ void hmcs40_cpu_device::device_start()
|
|||||||
// register for savestates
|
// register for savestates
|
||||||
save_item(NAME(m_stack));
|
save_item(NAME(m_stack));
|
||||||
save_item(NAME(m_op));
|
save_item(NAME(m_op));
|
||||||
|
save_item(NAME(m_arg));
|
||||||
save_item(NAME(m_pc));
|
save_item(NAME(m_pc));
|
||||||
save_item(NAME(m_a));
|
save_item(NAME(m_a));
|
||||||
save_item(NAME(m_b));
|
save_item(NAME(m_b));
|
||||||
@ -162,7 +170,7 @@ void hmcs40_cpu_device::device_start()
|
|||||||
state_add(HMCS40_Y, "Y", m_y).formatstr("%01X");
|
state_add(HMCS40_Y, "Y", m_y).formatstr("%01X");
|
||||||
state_add(HMCS40_SPY, "SPY", m_spy).formatstr("%01X");
|
state_add(HMCS40_SPY, "SPY", m_spy).formatstr("%01X");
|
||||||
|
|
||||||
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow();
|
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%03X").noshow();
|
||||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_s).formatstr("%2s").noshow();
|
state_add(STATE_GENFLAGS, "GENFLAGS", m_s).formatstr("%2s").noshow();
|
||||||
|
|
||||||
m_icountptr = &m_icount;
|
m_icountptr = &m_icount;
|
||||||
@ -176,7 +184,7 @@ void hmcs40_cpu_device::device_start()
|
|||||||
|
|
||||||
void hmcs40_cpu_device::device_reset()
|
void hmcs40_cpu_device::device_reset()
|
||||||
{
|
{
|
||||||
m_pc = 0;
|
m_pc = 0xffff & m_prgmask;
|
||||||
m_op = 0;
|
m_op = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,14 +194,41 @@ void hmcs40_cpu_device::device_reset()
|
|||||||
// execute
|
// execute
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline void hmcs40_cpu_device::increment_pc()
|
||||||
|
{
|
||||||
|
// PC lower bits is a LFSR identical to TI TMS1000
|
||||||
|
UINT8 mask = 0x3f;
|
||||||
|
UINT8 low = m_pc & mask;
|
||||||
|
int fb = (low << 1 & 0x20) == (low & 0x20);
|
||||||
|
|
||||||
|
if (low == (mask >> 1))
|
||||||
|
fb = 1;
|
||||||
|
else if (low == mask)
|
||||||
|
fb = 0;
|
||||||
|
|
||||||
|
m_pc = (m_pc & ~mask) | ((m_pc << 1 | fb) & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hmcs40_cpu_device::fetch_arg()
|
||||||
|
{
|
||||||
|
// P is the only 2-byte opcode
|
||||||
|
if (m_op == 0x3ff)
|
||||||
|
{
|
||||||
|
m_icount--;
|
||||||
|
m_arg = m_program->read_word(m_pc << 1);
|
||||||
|
increment_pc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::execute_run()
|
void hmcs40_cpu_device::execute_run()
|
||||||
{
|
{
|
||||||
while (m_icount > 0)
|
while (m_icount > 0)
|
||||||
{
|
{
|
||||||
m_icount--;
|
m_icount--;
|
||||||
|
|
||||||
debugger_instruction_hook(this, m_pc);
|
debugger_instruction_hook(this, m_pc << 1);
|
||||||
m_op = m_program->read_byte(m_pc);
|
m_op = m_program->read_word(m_pc << 1);
|
||||||
m_pc = (m_pc + 1) & m_prgmask;
|
increment_pc();
|
||||||
|
fetch_arg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,11 @@ protected:
|
|||||||
int m_datawidth;
|
int m_datawidth;
|
||||||
int m_prgmask;
|
int m_prgmask;
|
||||||
int m_datamask;
|
int m_datamask;
|
||||||
|
int m_xmask;
|
||||||
int m_stack_levels; // number of callstack levels
|
int m_stack_levels; // number of callstack levels
|
||||||
UINT16 m_stack[4]; // max 4
|
UINT16 m_stack[4]; // max 4
|
||||||
UINT16 m_op;
|
UINT16 m_op;
|
||||||
|
UINT16 m_arg;
|
||||||
int m_icount;
|
int m_icount;
|
||||||
|
|
||||||
UINT16 m_pc; // Program Counter
|
UINT16 m_pc; // Program Counter
|
||||||
@ -87,6 +89,15 @@ protected:
|
|||||||
devcb_read16 m_read_d;
|
devcb_read16 m_read_d;
|
||||||
devcb_write16 m_write_d;
|
devcb_write16 m_write_d;
|
||||||
|
|
||||||
|
// misc internal helpers
|
||||||
|
void increment_pc();
|
||||||
|
void fetch_arg();
|
||||||
|
|
||||||
|
UINT8 ram_r();
|
||||||
|
void ram_w(UINT8 data);
|
||||||
|
void pop_stack();
|
||||||
|
void push_stack();
|
||||||
|
|
||||||
// opcode handlers
|
// opcode handlers
|
||||||
void op_lab();
|
void op_lab();
|
||||||
void op_lba();
|
void op_lba();
|
||||||
@ -104,7 +115,7 @@ protected:
|
|||||||
void op_ayy();
|
void op_ayy();
|
||||||
void op_syy();
|
void op_syy();
|
||||||
void op_xspx();
|
void op_xspx();
|
||||||
void op_sxpy();
|
void op_xspy();
|
||||||
void op_xspxy();
|
void op_xspxy();
|
||||||
|
|
||||||
void op_lam();
|
void op_lam();
|
||||||
|
@ -2,6 +2,32 @@
|
|||||||
|
|
||||||
// internal helpers
|
// internal helpers
|
||||||
|
|
||||||
|
inline UINT8 hmcs40_cpu_device::ram_r()
|
||||||
|
{
|
||||||
|
UINT8 address = (m_x << 4 | m_y) & m_datamask;
|
||||||
|
return m_data->read_byte(address) & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hmcs40_cpu_device::ram_w(UINT8 data)
|
||||||
|
{
|
||||||
|
UINT8 address = (m_x << 4 | m_y) & m_datamask;
|
||||||
|
m_data->write_byte(address, data & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmcs40_cpu_device::pop_stack()
|
||||||
|
{
|
||||||
|
m_pc = m_stack[0] & m_prgmask;
|
||||||
|
for (int i = 0; i < m_stack_levels-1; i++)
|
||||||
|
m_stack[i] = m_stack[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmcs40_cpu_device::push_stack()
|
||||||
|
{
|
||||||
|
for (int i = m_stack_levels-1; i >= 1; i--)
|
||||||
|
m_stack[i] = m_stack[i-1];
|
||||||
|
m_stack[0] = m_pc;
|
||||||
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_illegal()
|
void hmcs40_cpu_device::op_illegal()
|
||||||
{
|
{
|
||||||
logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_pc);
|
logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_pc);
|
||||||
@ -16,37 +42,45 @@ void hmcs40_cpu_device::op_illegal()
|
|||||||
void hmcs40_cpu_device::op_lab()
|
void hmcs40_cpu_device::op_lab()
|
||||||
{
|
{
|
||||||
// LAB: Load A from B
|
// LAB: Load A from B
|
||||||
op_illegal();
|
m_a = m_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lba()
|
void hmcs40_cpu_device::op_lba()
|
||||||
{
|
{
|
||||||
// LBA: Load B from A
|
// LBA: Load B from A
|
||||||
op_illegal();
|
m_b = m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lay()
|
void hmcs40_cpu_device::op_lay()
|
||||||
{
|
{
|
||||||
// LAY: Load A from Y
|
// LAY: Load A from Y
|
||||||
op_illegal();
|
m_a = m_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_laspx()
|
void hmcs40_cpu_device::op_laspx()
|
||||||
{
|
{
|
||||||
// LASPX: Load A from SPX
|
// LASPX: Load A from SPX
|
||||||
op_illegal();
|
m_a = m_spx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_laspy()
|
void hmcs40_cpu_device::op_laspy()
|
||||||
{
|
{
|
||||||
// LASPY: Load A from SPY
|
// LASPY: Load A from SPY
|
||||||
op_illegal();
|
m_a = m_spy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_xamr()
|
void hmcs40_cpu_device::op_xamr()
|
||||||
{
|
{
|
||||||
// XAMR m: Exchange A and MR(m)
|
// XAMR m: Exchange A and MR(m)
|
||||||
op_illegal();
|
|
||||||
|
// determine MR(Memory Register) location
|
||||||
|
UINT8 y = m_op & 0xf;
|
||||||
|
UINT8 x = (y > 3) ? 0xf : (y + 12);
|
||||||
|
UINT8 address = (x << 4 | y) & m_datamask;
|
||||||
|
|
||||||
|
UINT8 old_a = m_a;
|
||||||
|
m_a = m_data->read_byte(address) & 0xf;
|
||||||
|
m_data->write_byte(address, old_a & 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,67 +89,78 @@ void hmcs40_cpu_device::op_xamr()
|
|||||||
void hmcs40_cpu_device::op_lxa()
|
void hmcs40_cpu_device::op_lxa()
|
||||||
{
|
{
|
||||||
// LXA: Load X from A
|
// LXA: Load X from A
|
||||||
op_illegal();
|
m_x = m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lya()
|
void hmcs40_cpu_device::op_lya()
|
||||||
{
|
{
|
||||||
// LYA: Load Y from A
|
// LYA: Load Y from A
|
||||||
op_illegal();
|
m_y = m_a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lxi()
|
void hmcs40_cpu_device::op_lxi()
|
||||||
{
|
{
|
||||||
// LXI i: Load X from Immediate
|
// LXI i: Load X from Immediate
|
||||||
op_illegal();
|
m_x = m_op & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lyi()
|
void hmcs40_cpu_device::op_lyi()
|
||||||
{
|
{
|
||||||
// LYI i: Load Y from Immediate
|
// LYI i: Load Y from Immediate
|
||||||
op_illegal();
|
m_y = m_op & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_iy()
|
void hmcs40_cpu_device::op_iy()
|
||||||
{
|
{
|
||||||
// IY: Increment Y
|
// IY: Increment Y
|
||||||
op_illegal();
|
m_y = (m_y + 1) & 0xf;
|
||||||
|
m_s = (m_y != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_dy()
|
void hmcs40_cpu_device::op_dy()
|
||||||
{
|
{
|
||||||
// DY: Decrement Y
|
// DY: Decrement Y
|
||||||
op_illegal();
|
m_y = (m_y - 1) & 0xf;
|
||||||
|
m_s = (m_y != 0xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_ayy()
|
void hmcs40_cpu_device::op_ayy()
|
||||||
{
|
{
|
||||||
// AYY: Add A to Y
|
// AYY: Add A to Y
|
||||||
op_illegal();
|
m_y += m_a;
|
||||||
|
m_s = m_y >> 4 & 1;
|
||||||
|
m_y &= 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_syy()
|
void hmcs40_cpu_device::op_syy()
|
||||||
{
|
{
|
||||||
// SYY: Subtract A from Y
|
// SYY: Subtract A from Y
|
||||||
op_illegal();
|
m_y -= m_a;
|
||||||
|
m_s = ~m_y >> 4 & 1;
|
||||||
|
m_y &= 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_xspx()
|
void hmcs40_cpu_device::op_xspx()
|
||||||
{
|
{
|
||||||
// XSPX: Exchange X and SPX
|
// XSPX: Exchange X and SPX
|
||||||
op_illegal();
|
UINT8 old_x = m_x;
|
||||||
|
m_x = m_spx;
|
||||||
|
m_spx = old_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_sxpy()
|
void hmcs40_cpu_device::op_xspy()
|
||||||
{
|
{
|
||||||
// SXPY: Exchange Y and SPY
|
// XSPY: Exchange Y and SPY
|
||||||
op_illegal();
|
UINT8 old_y = m_y;
|
||||||
|
m_y = m_spy;
|
||||||
|
m_spy = old_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_xspxy()
|
void hmcs40_cpu_device::op_xspxy()
|
||||||
{
|
{
|
||||||
// XSPXY: Exchange X and SPX, Y and SPY
|
// XSPXY: Exchange X and SPX, Y and SPY
|
||||||
op_illegal();
|
op_xspx();
|
||||||
|
op_xspy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -124,37 +169,49 @@ void hmcs40_cpu_device::op_xspxy()
|
|||||||
void hmcs40_cpu_device::op_lam()
|
void hmcs40_cpu_device::op_lam()
|
||||||
{
|
{
|
||||||
// LAM (XY): Load A from Memory
|
// LAM (XY): Load A from Memory
|
||||||
op_illegal();
|
m_a = ram_r();
|
||||||
|
op_xspxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lbm()
|
void hmcs40_cpu_device::op_lbm()
|
||||||
{
|
{
|
||||||
// LBM (XY): Load B from Memory
|
// LBM (XY): Load B from Memory
|
||||||
op_illegal();
|
m_b = ram_r();
|
||||||
|
op_xspxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_xma()
|
void hmcs40_cpu_device::op_xma()
|
||||||
{
|
{
|
||||||
// XMA (XY): Exchange Memory and A
|
// XMA (XY): Exchange Memory and A
|
||||||
op_illegal();
|
UINT8 old_a = m_a;
|
||||||
|
m_a = ram_r();
|
||||||
|
ram_w(old_a);
|
||||||
|
op_xspxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_xmb()
|
void hmcs40_cpu_device::op_xmb()
|
||||||
{
|
{
|
||||||
// XMB (XY): Exchange Memory and B
|
// XMB (XY): Exchange Memory and B
|
||||||
op_illegal();
|
UINT8 old_b = m_b;
|
||||||
|
m_b = ram_r();
|
||||||
|
ram_w(old_b);
|
||||||
|
op_xspxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lmaiy()
|
void hmcs40_cpu_device::op_lmaiy()
|
||||||
{
|
{
|
||||||
// LMAIY (X): Load Memory from A, Increment Y
|
// LMAIY (X): Load Memory from A, Increment Y
|
||||||
op_illegal();
|
ram_w(m_a);
|
||||||
|
op_iy();
|
||||||
|
op_xspx();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lmady()
|
void hmcs40_cpu_device::op_lmady()
|
||||||
{
|
{
|
||||||
// LMADY (X): Load Memory from A, Decrement Y
|
// LMADY (X): Load Memory from A, Decrement Y
|
||||||
op_illegal();
|
ram_w(m_a);
|
||||||
|
op_dy();
|
||||||
|
op_xspx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,19 +220,20 @@ void hmcs40_cpu_device::op_lmady()
|
|||||||
void hmcs40_cpu_device::op_lmiiy()
|
void hmcs40_cpu_device::op_lmiiy()
|
||||||
{
|
{
|
||||||
// LMIIY i: Load Memory from Immediate, Increment Y
|
// LMIIY i: Load Memory from Immediate, Increment Y
|
||||||
op_illegal();
|
ram_w(m_op & 0xf);
|
||||||
|
op_iy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lai()
|
void hmcs40_cpu_device::op_lai()
|
||||||
{
|
{
|
||||||
// LAI i: Load A from Immediate
|
// LAI i: Load A from Immediate
|
||||||
op_illegal();
|
m_a = m_op & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmcs40_cpu_device::op_lbi()
|
void hmcs40_cpu_device::op_lbi()
|
||||||
{
|
{
|
||||||
// LBI i: Load B from Immediate
|
// LBI i: Load B from Immediate
|
||||||
op_illegal();
|
m_b = m_op & 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user