mirror of
https://github.com/holub/mame
synced 2025-07-05 01:48:29 +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)
|
||||
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
|
||||
|
||||
|
||||
@ -95,6 +96,10 @@ void hmcs40_cpu_device::state_string_export(const device_state_entry &entry, ast
|
||||
);
|
||||
break;
|
||||
|
||||
case STATE_GENPC:
|
||||
string.printf("%03X", m_pc << 1);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -123,6 +128,7 @@ void hmcs40_cpu_device::device_start()
|
||||
m_data = &space(AS_DATA);
|
||||
m_prgmask = (1 << m_prgwidth) - 1;
|
||||
m_datamask = (1 << m_datawidth) - 1;
|
||||
m_xmask = (1 << (m_datawidth - 4)) - 1;
|
||||
|
||||
m_read_d.resolve_safe(0);
|
||||
m_write_d.resolve_safe();
|
||||
@ -130,6 +136,7 @@ void hmcs40_cpu_device::device_start()
|
||||
// zerofill
|
||||
memset(m_stack, 0, sizeof(m_stack));
|
||||
m_op = 0;
|
||||
m_arg = 0;
|
||||
m_pc = 0;
|
||||
m_a = 0;
|
||||
m_b = 0;
|
||||
@ -143,6 +150,7 @@ void hmcs40_cpu_device::device_start()
|
||||
// register for savestates
|
||||
save_item(NAME(m_stack));
|
||||
save_item(NAME(m_op));
|
||||
save_item(NAME(m_arg));
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_a));
|
||||
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_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();
|
||||
|
||||
m_icountptr = &m_icount;
|
||||
@ -176,7 +184,7 @@ void hmcs40_cpu_device::device_start()
|
||||
|
||||
void hmcs40_cpu_device::device_reset()
|
||||
{
|
||||
m_pc = 0;
|
||||
m_pc = 0xffff & m_prgmask;
|
||||
m_op = 0;
|
||||
}
|
||||
|
||||
@ -186,14 +194,41 @@ void hmcs40_cpu_device::device_reset()
|
||||
// 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()
|
||||
{
|
||||
while (m_icount > 0)
|
||||
{
|
||||
m_icount--;
|
||||
|
||||
debugger_instruction_hook(this, m_pc);
|
||||
m_op = m_program->read_byte(m_pc);
|
||||
m_pc = (m_pc + 1) & m_prgmask;
|
||||
debugger_instruction_hook(this, m_pc << 1);
|
||||
m_op = m_program->read_word(m_pc << 1);
|
||||
increment_pc();
|
||||
fetch_arg();
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,11 @@ protected:
|
||||
int m_datawidth;
|
||||
int m_prgmask;
|
||||
int m_datamask;
|
||||
int m_xmask;
|
||||
int m_stack_levels; // number of callstack levels
|
||||
UINT16 m_stack[4]; // max 4
|
||||
UINT16 m_op;
|
||||
UINT16 m_arg;
|
||||
int m_icount;
|
||||
|
||||
UINT16 m_pc; // Program Counter
|
||||
@ -87,6 +89,15 @@ protected:
|
||||
devcb_read16 m_read_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
|
||||
void op_lab();
|
||||
void op_lba();
|
||||
@ -104,7 +115,7 @@ protected:
|
||||
void op_ayy();
|
||||
void op_syy();
|
||||
void op_xspx();
|
||||
void op_sxpy();
|
||||
void op_xspy();
|
||||
void op_xspxy();
|
||||
|
||||
void op_lam();
|
||||
|
@ -2,6 +2,32 @@
|
||||
|
||||
// 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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
// LAB: Load A from B
|
||||
op_illegal();
|
||||
m_a = m_b;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lba()
|
||||
{
|
||||
// LBA: Load B from A
|
||||
op_illegal();
|
||||
m_b = m_a;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lay()
|
||||
{
|
||||
// LAY: Load A from Y
|
||||
op_illegal();
|
||||
m_a = m_y;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_laspx()
|
||||
{
|
||||
// LASPX: Load A from SPX
|
||||
op_illegal();
|
||||
m_a = m_spx;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_laspy()
|
||||
{
|
||||
// LASPY: Load A from SPY
|
||||
op_illegal();
|
||||
m_a = m_spy;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_xamr()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// LXA: Load X from A
|
||||
op_illegal();
|
||||
m_x = m_a;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lya()
|
||||
{
|
||||
// LYA: Load Y from A
|
||||
op_illegal();
|
||||
m_y = m_a;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lxi()
|
||||
{
|
||||
// LXI i: Load X from Immediate
|
||||
op_illegal();
|
||||
m_x = m_op & 0xf;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lyi()
|
||||
{
|
||||
// LYI i: Load Y from Immediate
|
||||
op_illegal();
|
||||
m_y = m_op & 0xf;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_iy()
|
||||
{
|
||||
// IY: Increment Y
|
||||
op_illegal();
|
||||
m_y = (m_y + 1) & 0xf;
|
||||
m_s = (m_y != 0);
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_dy()
|
||||
{
|
||||
// DY: Decrement Y
|
||||
op_illegal();
|
||||
m_y = (m_y - 1) & 0xf;
|
||||
m_s = (m_y != 0xf);
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_ayy()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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
|
||||
op_illegal();
|
||||
// XSPY: Exchange Y and SPY
|
||||
UINT8 old_y = m_y;
|
||||
m_y = m_spy;
|
||||
m_spy = old_y;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_xspxy()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// LAM (XY): Load A from Memory
|
||||
op_illegal();
|
||||
m_a = ram_r();
|
||||
op_xspxy();
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lbm()
|
||||
{
|
||||
// LBM (XY): Load B from Memory
|
||||
op_illegal();
|
||||
m_b = ram_r();
|
||||
op_xspxy();
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_xma()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// LMAIY (X): Load Memory from A, Increment Y
|
||||
op_illegal();
|
||||
ram_w(m_a);
|
||||
op_iy();
|
||||
op_xspx();
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lmady()
|
||||
{
|
||||
// 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()
|
||||
{
|
||||
// LMIIY i: Load Memory from Immediate, Increment Y
|
||||
op_illegal();
|
||||
ram_w(m_op & 0xf);
|
||||
op_iy();
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lai()
|
||||
{
|
||||
// LAI i: Load A from Immediate
|
||||
op_illegal();
|
||||
m_a = m_op & 0xf;
|
||||
}
|
||||
|
||||
void hmcs40_cpu_device::op_lbi()
|
||||
{
|
||||
// LBI i: Load B from Immediate
|
||||
op_illegal();
|
||||
m_b = m_op & 0xf;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user