added jump opcodes

This commit is contained in:
hap 2015-01-30 20:40:00 +01:00
parent 9afc7cdb5b
commit d094328b4d
3 changed files with 74 additions and 8 deletions

View File

@ -134,6 +134,9 @@ void amis2000_device::device_start()
// zerofill // zerofill
memset(m_callstack, 0, sizeof(m_callstack)); memset(m_callstack, 0, sizeof(m_callstack));
m_pc = 0; m_pc = 0;
m_ppr = 0;
m_pbr = 0;
m_pp_index = 0;
m_skip = false; m_skip = false;
m_op = 0; m_op = 0;
m_f = 0; m_f = 0;
@ -148,6 +151,9 @@ void amis2000_device::device_start()
// register for savestates // register for savestates
save_item(NAME(m_callstack)); save_item(NAME(m_callstack));
save_item(NAME(m_pc)); save_item(NAME(m_pc));
save_item(NAME(m_ppr));
save_item(NAME(m_pbr));
save_item(NAME(m_pp_index));
save_item(NAME(m_skip)); save_item(NAME(m_skip));
save_item(NAME(m_op)); save_item(NAME(m_op));
save_item(NAME(m_f)); save_item(NAME(m_f));
@ -182,6 +188,8 @@ void amis2000_device::device_start()
void amis2000_device::device_reset() void amis2000_device::device_reset()
{ {
m_pc = 0; m_pc = 0;
m_skip = false;
m_op = 0;
} }
@ -198,6 +206,15 @@ void amis2000_device::execute_run()
{ {
m_icount--; m_icount--;
// increase PP prefix count
if ((m_op & 0xf0) == 0x60)
{
if (m_pp_index < 2)
m_pp_index++;
}
else
m_pp_index = 0;
debugger_instruction_hook(this, m_pc); debugger_instruction_hook(this, m_pc);
m_op = m_program->read_byte(m_pc); m_op = m_program->read_byte(m_pc);
m_pc = (m_pc + 1) & 0x1fff; m_pc = (m_pc + 1) & 0x1fff;

View File

@ -72,13 +72,16 @@ protected:
UINT8 m_bu_bits; UINT8 m_bu_bits;
UINT16 m_bu_mask; UINT16 m_bu_mask;
UINT8 m_callstack_bits; UINT8 m_callstack_bits; // number of program counter bits held in callstack
UINT16 m_callstack_mask; UINT16 m_callstack_mask;
UINT8 m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400 UINT8 m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400
UINT16 m_callstack[5]; // max 5 UINT16 m_callstack[5]; // max 5
UINT16 m_pc; UINT16 m_pc; // 13-bit program counter
bool m_skip; UINT8 m_ppr; // prepared page register (PP 1)
UINT8 m_pbr; // prepared bank register (PP 2)
UINT8 m_pp_index; // number of handled PP prefixes
bool m_skip; // skip next opcode, including PP prefixes
UINT8 m_op; UINT8 m_op;
UINT8 m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400 UINT8 m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400
UINT8 m_carry; // carry flag UINT8 m_carry; // carry flag
@ -99,6 +102,8 @@ protected:
UINT8 ram_r(); UINT8 ram_r();
void ram_w(UINT8 data); void ram_w(UINT8 data);
void pop_callstack();
void push_callstack();
void op_illegal(); void op_illegal();
void op_lai(); void op_lai();

View File

@ -14,6 +14,25 @@ void amis2000_device::ram_w(UINT8 data)
m_data->write_byte(address, data & 0xf); m_data->write_byte(address, data & 0xf);
} }
void amis2000_device::pop_callstack()
{
m_pc = (m_pc & ~m_callstack_mask) | (m_callstack[0] & m_callstack_mask);
for (int i = 0; i < m_callstack_depth-1; i++)
{
m_callstack[i] = m_callstack[i+1];
m_callstack[i+1] = 0;
}
}
void amis2000_device::push_callstack()
{
for (int i = m_callstack_depth-1; i >= 1; i--)
{
m_callstack[i] = m_callstack[i-1];
}
m_callstack[0] = m_pc & m_callstack_mask;
}
void amis2000_device::op_illegal() void amis2000_device::op_illegal()
{ {
logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc); logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc);
@ -207,31 +226,56 @@ void amis2000_device::op_eur()
void amis2000_device::op_pp() void amis2000_device::op_pp()
{ {
// PP _X: prepare page/bank with _X // PP _X: prepare page/bank with _X
op_illegal(); UINT8 param = ~m_op & 0x0f;
if (m_pp_index == 0)
m_ppr = param;
else
m_pbr = param & 7;
} }
void amis2000_device::op_jmp() void amis2000_device::op_jmp()
{ {
// JMP X: jump to X(+PP) // JMP X: jump to X(+PP)
op_illegal(); UINT16 mask = 0x3f;
UINT16 param = m_op & mask;
if (m_pp_index > 0)
{
param |= m_ppr << 6;
mask |= 0x3c0;
}
if (m_pp_index > 1)
{
param |= m_pbr << 10;
mask |= 0x1c00;
}
m_pc = (m_pc & ~mask) | param;
} }
void amis2000_device::op_jms() void amis2000_device::op_jms()
{ {
// JMS X: call to X(+PP) // JMS X: call to X(+PP)
op_illegal(); m_icount--;
push_callstack();
if (m_pp_index == 0)
{
// subroutines default location is page 15
m_ppr = 0xf;
m_pp_index++;
}
op_jmp();
} }
void amis2000_device::op_rt() void amis2000_device::op_rt()
{ {
// RT: return from subroutine // RT: return from subroutine
op_illegal(); pop_callstack();
} }
void amis2000_device::op_rts() void amis2000_device::op_rts()
{ {
// RTS: return from subroutine and skip next // RTS: return from subroutine and skip next
op_illegal(); op_rt();
m_skip = true;
} }
void amis2000_device::op_nop() void amis2000_device::op_nop()