f2mc16: more opcodes, improved disassembly (nw)

This commit is contained in:
arbee 2019-09-02 14:55:51 -04:00
parent c0f4fb7486
commit 4e612119e9
5 changed files with 346 additions and 51 deletions

View File

@ -852,6 +852,20 @@ void f2mc16_device::execute_run()
m_icount -= 2;
break;
// MOVX A, #imm8
case 0x43:
m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
m_acc <<= 16;
m_acc |= m_tmp8;
if (m_acc & 0x80)
{
m_acc |= 0xff00;
}
setNZ_8(m_tmp8);
m_pc += 2;
m_icount -= 2;
break;
// MOV dir, #imm8
case 0x44:
m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
@ -862,8 +876,19 @@ void f2mc16_device::execute_run()
m_icount -= 5;
break;
// MOVW A, SP
case 0x46:
// util::stream_format(stream, "MOVW A, SP");
m_acc <<= 16;
if (m_ps & F_S)
{
m_acc |= m_ssp;
}
else
{
m_acc |= m_usp;
}
m_pc++;
m_icount--;
break;
// MOVW SP, A
@ -876,8 +901,8 @@ void f2mc16_device::execute_run()
{
m_usp = m_acc & 0xffff;
}
m_icount -= 1;
m_pc += 1;
m_pc++;
m_icount--;
break;
// MOVW A, dir
@ -1218,6 +1243,14 @@ void f2mc16_device::execute_run()
opcodes_ea78(read_8((m_pcb<<16) | (m_pc+1)));
break;
case 0x7a: // ea RWi-type instructions
opcodes_rwi7a(read_8((m_pcb<<16) | (m_pc+1)));
break;
case 0x7b: // ea RWi-type instructions
opcodes_rwi7b(read_8((m_pcb<<16) | (m_pc+1)));
break;
// MOV A, Rx
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
m_acc <<= 16;
@ -1908,6 +1941,21 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_icount -= 1;
break;
// MOV @AL, AH
case 0x15:
if (m_prefix_valid)
{
m_prefix_valid = false;
write_8((m_prefix<<16) | (m_acc & 0xffff), (m_acc>>16) & 0xff);
}
else
{
write_8((m_dtb<<16) | (m_acc & 0xffff), (m_acc>>16) & 0xff);
}
m_pc += 2;
m_icount -= 3;
break;
// LSLL A, R0
case 0x1c:
m_tmp8 = read_rX(0);
@ -2110,6 +2158,14 @@ void f2mc16_device::opcodes_ea71(u8 operand)
m_icount -= 7;
break;
// MOVL A, RLx
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
m_acc = read_rlX((operand>>1) & 3);
setNZ_32(m_acc);
m_pc += 2;
m_icount -= 4;
break;
// MOVL A, @RWx + disp8
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
@ -2231,6 +2287,31 @@ void f2mc16_device::opcodes_ea72(u8 operand)
m_icount -= 5;
break;
// INC addr16
case 0x5f:
m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
if (m_prefix_valid)
{
m_prefix_valid = false;
m_tmp32 |= (m_prefix << 16);
}
else
{
m_tmp32 |= (m_dtb << 16);
}
m_tmp16 = read_8(m_tmp32);
m_tmp16++;
write_8(m_tmp32, m_tmp16 & 0xff);
setNZ_8(m_tmp16 & 0xff);
m_ps &= ~F_V;
if (m_tmp16 & 0x100)
{
m_ps |= F_V;
}
m_pc += 4;
m_icount -= 5;
break;
// MOV A, @RWx + disp8
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
@ -2262,7 +2343,7 @@ void f2mc16_device::opcodes_ea73(u8 operand)
{
switch (operand)
{
// INCW @RWx + disp8, A
// INCW @RWx + disp8
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
@ -2304,6 +2385,24 @@ void f2mc16_device::opcodes_ea73(u8 operand)
m_icount -= 5;
break;
// DECW @RWx + disp8
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
m_tmp32 = read_16(getRWbank(operand & 7, m_tmp16));
m_tmp32aux = m_tmp32;
m_tmp32--;
write_16(getRWbank(operand & 7, m_tmp16), m_tmp32 & 0xffff);
setNZ_16(m_tmp32 & 0xffff);
m_ps &= ~F_V;
if ((m_tmp32aux ^ 0x0001) & (m_tmp32aux ^ m_tmp32) & 0x8000)
{
m_ps |= F_V;
}
m_pc += 3;
m_icount -= 5;
break;
// DECW addr16
case 0x7f:
m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
@ -2330,6 +2429,16 @@ void f2mc16_device::opcodes_ea73(u8 operand)
m_icount -= 5;
break;
// MOVW A, @RWx
case 0x88: case 0x89: case 0x8a: case 0x8b:
m_tmpea = read_rwX(operand & 3);
m_acc <<= 16;
m_acc |= read_16(getRWbank(operand & 3, m_tmpea));
setNZ_16(m_acc & 0xffff);
m_pc += 2;
m_icount -= 2;
break;
// MOVW @RWx + disp8, #imm16
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
m_tmp8 = read_16((m_pcb<<16) | (m_pc+2));
@ -2474,6 +2583,25 @@ void f2mc16_device::opcodes_ea76(u8 operand)
m_icount -= 3;
break;
// SUBW A, addr16
case 0x3f:
m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
if (m_prefix_valid)
{
m_prefix_valid = false;
m_tmp16aux = read_16((m_prefix<<16) | m_tmp16);
}
else
{
m_tmp16aux = read_16((m_dtb<<16) | m_tmp16);
}
m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16aux);
m_acc &= 0xffff0000;
m_acc |= m_tmp16aux;
m_pc += 4;
m_icount -= 3;
break;
// CMPW A, RWx
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
doCMP_16(m_acc & 0xffff, read_rwX(operand & 7));
@ -2491,6 +2619,23 @@ void f2mc16_device::opcodes_ea76(u8 operand)
m_icount -= 10;
break;
// CMPW A, addr16
case 0x7f:
m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
if (m_prefix_valid)
{
m_prefix_valid = false;
m_tmp16aux = read_16((m_prefix<<16) | m_tmp16);
}
else
{
m_tmp16aux = read_16((m_dtb<<16) | m_tmp16);
}
doCMP_16(m_acc & 0xffff, m_tmp16aux);
m_pc += 4;
m_icount -= 10;
break;
// ORW A, RWx
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
m_tmp16 = read_rwX(operand & 7);
@ -2567,12 +2712,88 @@ void f2mc16_device::opcodes_ea78(u8 operand)
m_pc += 3;
break;
// DIVUW A, RWx
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
m_ps &= ~(F_V|F_C);
m_tmp16 = read_rwX(operand & 7);
if (m_tmp16)
{
m_tmp32aux = m_acc / m_tmp16;
m_tmp16 = (m_acc % m_tmp16) & 0xffff;
// overflow?
if (m_tmp32aux >= 0x10000)
{
m_ps |= F_V;
m_icount -= 7;
m_ps |= F_V;
}
else // normal operation
{
m_acc &= ~0xffff;
m_acc |= (m_tmp32aux & 0xffff);
write_rwX(operand & 7, m_tmp16);
m_icount -= 22;
}
}
else // divide by zero
{
m_icount -= 4;
m_ps |= F_V;
}
m_pc += 2;
break;
default:
fatalerror("Unknown F2MC EA78 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
break;
}
}
void f2mc16_device::opcodes_rwi7a(u8 operand)
{
if (operand & 0x10)
{ // MOV Rx, @RWy + disp8
m_tmpea = read_rwX(operand & 7) + (s8)read_8((m_pcb<<16) | (m_pc+2));
m_tmp32 = getRWbank(operand & 0x7, m_tmpea);
m_tmp8 = read_8(m_tmp32);
write_rX((operand>>5) & 0x7, m_tmp8);
setNZ_8(m_tmp8);
m_pc += 3;
m_icount -= 5;
}
else
{ // MOV Rx, Ry
m_tmp8 = read_rX(operand & 0x7);
write_rX((operand>>5) & 0x7, m_tmp8);
setNZ_8(m_tmp8);
m_pc += 2;
m_icount -= 4;
}
}
void f2mc16_device::opcodes_rwi7b(u8 operand)
{
if (operand & 0x10)
{ // MOVW RWx, @RWy + disp8
m_tmpea = read_rwX(operand & 7) + (s8)read_8((m_pcb<<16) | (m_pc+2));
m_tmp32 = getRWbank(operand & 0x7, m_tmpea);
m_tmp16 = read_16(m_tmp32);
write_rwX((operand>>5) & 0x7, m_tmp16);
setNZ_16(m_tmp16);
m_pc += 3;
m_icount -= 5;
}
else
{ // MOVW RWx, RWy
m_tmp16 = read_rwX(operand & 0x7);
write_rwX((operand>>5) & 0x7, m_tmp16);
setNZ_16(m_tmp16);
m_pc += 2;
m_icount -= 4;
}
}
void f2mc16_device::execute_set_input(int inputnum, int state)
{
}

View File

@ -478,6 +478,8 @@ private:
void opcodes_ea76(u8 operand);
void opcodes_ea77(u8 operand);
void opcodes_ea78(u8 operand);
void opcodes_rwi7a(u8 operand);
void opcodes_rwi7b(u8 operand);
void set_irq(int vector, int level);
void clear_irq(int vector);

View File

@ -387,7 +387,7 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
break;
case 0x3c:
util::stream_format(stream, "CMPW A, #$%04x", opcodes.r16(pc+1));
util::stream_format(stream, "ANDW A, #$%04x", opcodes.r16(pc+1));
bytes = 3;
break;
@ -420,6 +420,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
bytes = 2;
break;
case 0x43:
util::stream_format(stream, "MOVX A, #$%02x", operand);
bytes = 2;
break;
case 0x44:
util::stream_format(stream, "MOV dir(%02x), #$%02x", operand, opcodes.r8(pc+2));
bytes = 3;
@ -466,12 +471,23 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
break;
case 0x4f:
util::stream_format(stream, "PUSHW ");
for (int i = 0; i < 8; i++)
util::stream_format(stream, "PUSHW ");
{
if (operand & (1<<i))
bool bComma = false;
for (int i = 0; i < 8; i++)
{
util::stream_format(stream, "RW%d, ", i);
if (operand & (1<<i))
{
if (bComma)
{
util::stream_format(stream, ", RW%d", i);
}
else
{
util::stream_format(stream, "RW%d", i);
bComma = true;
}
}
}
}
bytes = 2;
@ -550,12 +566,24 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
break;
case 0x5f:
util::stream_format(stream, "POPW ");
for (int i = 0; i < 8; i++)
util::stream_format(stream, "POPW ");
{
if (operand & (1<<i))
bool bComma = false;
for (int i = 7; i >= 0; i--)
{
util::stream_format(stream, "RW%d, ", i);
if (operand & (1<<i))
{
if (bComma)
{
util::stream_format(stream, ", RW%d", i);
}
else
{
util::stream_format(stream, "RW%d", i);
bComma = true;
}
}
}
}
bytes = 2;
@ -579,20 +607,22 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
case 0x64:
util::stream_format(stream, "CALL #$%04x", opcodes.r16(pc+1));
bytes = 3;
bytes = 3 | STEP_OVER;
break;
case 0x65:
util::stream_format(stream, "CALLP #$%06x", opcodes.r8(pc+3)<<16|opcodes.r8(pc+2)<<8|opcodes.r8(pc+1));
bytes = 4;
bytes = 4 | STEP_OVER;
break;
case 0x66:
util::stream_format(stream, "RETP");
bytes |= STEP_OUT;
break;
case 0x67:
stream << "RET";
bytes |= STEP_OUT;
break;
case 0x68:
@ -612,6 +642,7 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
case 0x6b:
stream << "RETI";
bytes |= STEP_OUT;
break;
case 0x6c: // bit operations
@ -769,6 +800,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
bytes = 2;
break;
case 0x15:
util::stream_format(stream, "MOV @AL, AH");
bytes = 2;
break;
case 0x1c:
util::stream_format(stream, "LSLL A, R0");
bytes = 2;
@ -898,7 +934,7 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
{
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
bytes = ea_form1_helper_noA(stream, "CALLP @", pc, operand, opcodes.r16(pc+2));
bytes = ea_form1_helper_noA(stream, "CALLP @", pc, operand, opcodes.r16(pc+2)) | STEP_OVER;
break;
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
@ -1050,6 +1086,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
bytes = 3;
break;
case 0x5f:
util::stream_format(stream, "INC $%04x", opcodes.r16(pc+2));
bytes = 4;
break;
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
util::stream_format(stream, "DEC R%d", (operand & 0x7));
bytes = 2;
@ -1534,6 +1575,21 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
bytes = 3;
break;
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
util::stream_format(stream, "DIVUW A, RW%d", (operand & 0x7));
bytes = 2;
break;
case 0xa8: case 0xa9: case 0xaa: case 0xab:
util::stream_format(stream, "DIVUW A, @RW%d", (operand & 0x3));
bytes = 2;
break;
case 0xac: case 0xad: case 0xae: case 0xaf:
util::stream_format(stream, "DIVUW A, @RW%d+", (operand & 0x3));
bytes = 2;
break;
default:
stream << "UNK ea-type 78";
break;
@ -1541,44 +1597,28 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
break;
case 0x7a: // ea RWi-type instructions
switch (operand)
if (operand & 0x10)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
util::stream_format(stream, "MOV R%d, R%d", (opcode>>5) & 0x7, (opcode & 0x7));
bytes = 2;
break;
default:
stream << "UNK ea RWi-type 7A";
break;
util::stream_format(stream, "MOV RW%d, @RW%d + #$%02x", (operand>>5) & 0x7, (operand & 0x7), opcodes.r8(pc+2));
bytes = 3;
}
else
{
util::stream_format(stream, "MOV R%d, R%d", (operand>>5) & 0x7, (operand & 0x7));
bytes = 2;
}
break;
case 0x7b: // ea RWi-type instructions
switch (operand)
if (operand & 0x10)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
util::stream_format(stream, "MOVW RW%d, RW%d", (opcode>>5) & 0x7, (opcode & 0x7));
bytes = 2;
break;
default:
stream << "UNK ea RWi-type 7B";
break;
util::stream_format(stream, "MOVW RW%d, @RW%d + #$%02x", (operand>>5) & 0x7, (operand & 0x7), opcodes.r8(pc+2));
bytes = 3;
}
else
{
util::stream_format(stream, "MOVW RW%d, RW%d", (operand>>5) & 0x7, (operand & 0x7));
bytes = 2;
}
break;
@ -1635,6 +1675,7 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
util::stream_format(stream, "CALL #$%01x", (opcode & 0xf));
bytes |= STEP_OVER;
break;
case 0xf0: branch_helper(stream, "BEQ ", (pc & 0xffff)+2, (s8)operand); bytes = 2; break;

View File

@ -263,6 +263,7 @@ void mb9061x_device::tin_common(int timer, int base, int state)
{
u8 ctl = m_timer_regs[base];
m_timer_regs[base] |= TCTL_UF;
//printf("Timer %d exp, CL %02x\n", timer, m_timer_regs[base]);
if (ctl & TCTL_INTE)
{
//printf("timer %d IRQ\n", timer);

View File

@ -75,17 +75,45 @@ private:
required_device<mb90611_device> m_maincpu;
required_device<timer_device> m_scantimer;
virtual void machine_reset() override;
TIMER_DEVICE_CALLBACK_MEMBER(scan_interrupt);
void princ_map(address_map &map);
u8 read_gpu_status();
uint32_t screen_update_tomy_princ(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
bool bFirstPort8Read;
};
TIMER_DEVICE_CALLBACK_MEMBER(tomy_princ_state::scan_interrupt)
{
m_maincpu->tin0_w(ASSERT_LINE);
m_maincpu->tin0_w(CLEAR_LINE);
for (int i = 0; i < 128; i++)
{
m_maincpu->tin0_w(ASSERT_LINE);
m_maincpu->tin0_w(CLEAR_LINE);
}
m_maincpu->tin1_w(ASSERT_LINE);
m_maincpu->tin1_w(CLEAR_LINE);
}
void tomy_princ_state::machine_reset()
{
bFirstPort8Read = true;
}
u8 tomy_princ_state::read_gpu_status()
{
if (bFirstPort8Read)
{
bFirstPort8Read = false;
return 0x20;
}
return 0x00;
}
uint32_t tomy_princ_state::screen_update_tomy_princ(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -96,7 +124,9 @@ uint32_t tomy_princ_state::screen_update_tomy_princ(screen_device &screen, bitma
// fe2d25
void tomy_princ_state::princ_map(address_map &map)
{
map(0x000008, 0x000008).lr8("free1", []() -> u8 { return 0x20; }); // else init function fails and princ goes into an infinite loop
map(0x000001, 0x000001).lw8("free2", [](u8 data) { return 0xff; });
map(0x000008, 0x000008).r(FUNC(tomy_princ_state::read_gpu_status));
map(0x68ff00, 0x68ff00).lw8("free1", [this](u8 data) { bFirstPort8Read = true; });
map(0x68ff44, 0x68ff44).lr8("free0", [this]() -> u8 { return m_screen->vblank() ? 0x11 : 0x10; });
map(0xe00000, 0xe07fff).ram(); // stacks are placed here
map(0xf00000, 0xffffff).rom().region("maincpu", 0x00000);