summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/f2mc16/f2mc16.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/f2mc16/f2mc16.cpp')
-rw-r--r--src/devices/cpu/f2mc16/f2mc16.cpp3895
1 files changed, 3333 insertions, 562 deletions
diff --git a/src/devices/cpu/f2mc16/f2mc16.cpp b/src/devices/cpu/f2mc16/f2mc16.cpp
index 9726bdf976a..546d240f543 100644
--- a/src/devices/cpu/f2mc16/f2mc16.cpp
+++ b/src/devices/cpu/f2mc16/f2mc16.cpp
@@ -12,11 +12,13 @@
There are two main branches: F and L. They appear to be compatible with
each other as far as their extentions to the base ISA not conflicting.
+ TODO: Correction values applied to instruction cycles.
+
***************************************************************************/
#include "emu.h"
#include "f2mc16.h"
-#include "f2mc16dasm.h"
+#include "f2mc16d.h"
// device type definitions
DEFINE_DEVICE_TYPE(F2MC16, f2mc16_device, "f2mc16", "Fujitsu Micro F2MC-16")
@@ -35,11 +37,12 @@ f2mc16_device::f2mc16_device(const machine_config &mconfig, device_type type, co
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0)
, m_program(nullptr)
+ , m_irq_level((7 << 13) | 0x1fff)
{
m_tmp8 = 0;
m_tmp16 = 0;
m_tmp32 = 0;
- m_tmp64 = 0;
+ m_tmpea = 0;
m_prefix_valid = false;
}
@@ -59,10 +62,10 @@ void f2mc16_device::device_start()
set_icountptr(m_icount);
- state_add(F2MC16_PCB, "PCB", m_pcb);
- state_add(F2MC16_PC, "PC", m_pc).formatstr("%04X");
+ state_add(F2MC16_PCB, "PCB", m_pcb).callimport();
+ state_add(F2MC16_PC, "PC", m_pc).callimport().formatstr("%04X");
state_add(STATE_GENPC, "GENPC", m_temp).callimport().callexport().noshow();
- state_add(STATE_GENPCBASE, "CURPC", m_temp).callimport().callexport().noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_pcbase).callimport().noshow();
state_add(F2MC16_PS, "PS", m_ps).formatstr("%04X");
state_add(STATE_GENFLAGS, "GENFLAGS", m_ps).callimport().formatstr("%7s").noshow();
state_add(F2MC16_DTB, "DTB", m_dtb).formatstr("%02X");
@@ -99,7 +102,6 @@ void f2mc16_device::device_start()
save_item(NAME(m_ssp));
save_item(NAME(m_ps));
save_item(NAME(m_tmp16));
- save_item(NAME(m_tmpea));
save_item(NAME(m_tmp16aux));
save_item(NAME(m_pcb));
save_item(NAME(m_dtb));
@@ -109,12 +111,14 @@ void f2mc16_device::device_start()
save_item(NAME(m_dpr));
save_item(NAME(m_tmp8));
save_item(NAME(m_prefix));
+ save_item(NAME(m_pcbase));
save_item(NAME(m_acc));
save_item(NAME(m_temp));
save_item(NAME(m_tmp32));
- save_item(NAME(m_tmp32aux));
- save_item(NAME(m_tmp64));
+ save_item(NAME(m_tmpea));
save_item(NAME(m_prefix_valid));
+ save_item(NAME(m_irq_level));
+ save_item(NAME(m_rmw));
}
void f2mc16_device::device_reset()
@@ -127,16 +131,11 @@ void f2mc16_device::device_reset()
m_dpr = 0x01;
m_dtb = 0;
- for (int &entry : m_vector_level)
- {
- entry = 7;
- }
- m_outstanding_irqs = 0;
-
m_pc = read_16_vector(0xffffdc);
m_pcb = read_8_vector(0xffffde);
m_prefix_valid = false;
+ m_rmw = false;
}
void f2mc16_device::state_import(const device_state_entry &entry)
@@ -144,9 +143,19 @@ void f2mc16_device::state_import(const device_state_entry &entry)
switch (entry.index())
{
case STATE_GENPC:
+ m_pcbase = m_temp;
+ m_pc = (m_pcbase & 0xffff);
+ m_pcb = (m_pcbase >> 16) & 0xff;
+ break;
+
case STATE_GENPCBASE:
- m_pc = (m_temp & 0xffff);
- m_pcb = (m_temp >> 16) & 0xff;
+ m_pc = (m_pcbase & 0xffff);
+ m_pcb = (m_pcbase >> 16) & 0xff;
+ break;
+
+ case F2MC16_PCB:
+ case F2MC16_PC:
+ m_pcbase = ((m_pcb & 0xff) << 16) | m_pc;
break;
case F2MC16_RW0: write_rwX(0, m_temp); break;
@@ -205,7 +214,6 @@ void f2mc16_device::state_export(const device_state_entry &entry)
case F2MC16_R7: m_temp = read_rX(7); break;
case STATE_GENPC:
- case STATE_GENPCBASE:
m_temp = m_pc;
m_temp |= (m_pcb << 16);
break;
@@ -233,34 +241,53 @@ void f2mc16_device::execute_run()
{
while (m_icount > 0)
{
- if (m_outstanding_irqs)
+ if (!m_prefix_valid && m_irq_level < m_ps && (m_ps & F_I))
{
- int cpulevel = m_ps >> 13;
-
- for (int irq = 0; irq < 256; irq++)
+ uint8_t irq_level = m_irq_level;
+ uint8_t irq_vector = standard_irq_callback(irq_level, m_pc);
+ if (irq_vector)
{
- if (m_vector_level[irq] < cpulevel)
- {
- take_irq(irq, m_vector_level[irq]);
- break;
- }
+ take_irq_vector(irq_vector);
+ m_ps = (m_ps | (7 << 13)) & irq_level;
}
}
//m_icount--;
- u8 opcode = read_8((m_pcb<<16) | m_pc);
+ if (!m_prefix_valid)
+ {
+ m_pcbase = (m_pcb << 16) | m_pc;
+ debugger_instruction_hook((m_pcb << 16) | m_pc);
+ }
+ u8 opcode = read_8((m_pcb << 16) | m_pc);
- debugger_instruction_hook((m_pcb<<16) | m_pc);
switch (opcode)
{
- case 0x00: // NOP
+ // NOP
+ case 0x00:
m_icount--;
m_pc++;
break;
+ // INT9
+ case 0x01:
+ m_pc++;
+ take_irq_vector(9);
+ m_ps &= ~F_I;
+ break;
+
+ // NEG A
case 0x03:
- // util::stream_format(stream, "NEG A");
+ m_tmp8 = doSUB_8(0, m_acc & 0xff);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_tmp8);
+ m_pc++;
+ m_icount -= 2;
break;
// PCB prefix
@@ -300,7 +327,7 @@ void f2mc16_device::execute_run()
// LINK #imm8
case 0x08:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
if (m_ps & F_S)
{
m_ssp-=2;
@@ -313,7 +340,7 @@ void f2mc16_device::execute_run()
m_usp-=2;
write_16((m_usb << 16) | m_usp, read_rwX(3));
write_rwX(3, m_usp);
- m_ssp -= m_tmp8;
+ m_usp -= m_tmp8;
}
m_pc += 2;
m_icount -= 6;
@@ -336,7 +363,7 @@ void f2mc16_device::execute_run()
// MOV RP, #imm8
case 0x0a:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1)) & 0x1f;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1)) & 0x1f;
m_ps &= 0xe0ff;
m_ps |= (m_tmp8<<8);
m_pc += 2;
@@ -345,10 +372,10 @@ void f2mc16_device::execute_run()
// NEGW A
case 0x0b:
- m_tmp32 = doSUB_32(0, m_acc&0xffff);
+ m_tmp16 = doSUB_16(0, m_acc & 0xffff);
m_acc &= 0xffff0000;
- m_acc |= m_tmp32 & 0xffff;
- setNZ_16(m_acc & 0xffff);
+ m_acc |= m_tmp16;
+ setNZ_16(m_tmp16);
m_pc++;
m_icount -= 2;
break;
@@ -429,19 +456,33 @@ void f2mc16_device::execute_run()
break;
case 0x10:
- // stream << "CMR ";
+ logerror("%s: Unimplemented F2MC instruction CMR\n", machine().describe_context());
break;
case 0x11:
- // stream << "NCC ";
+ logerror("%s: Unimplemented F2MC instruction NCC\n", machine().describe_context());
break;
case 0x12:
- // stream << "SUBDC A";
+ logerror("%s: Unimplemented F2MC instruction SUBDC A\n", machine().describe_context());
break;
+ // EXT
case 0x14:
- // stream << "EXT";
+ m_ps &= ~(F_N|F_Z);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ m_ps |= F_N;
+ }
+ else
+ {
+ m_acc &= 0xffff00ff;
+ if ((m_acc & 0xff) == 0)
+ m_ps |= F_Z;
+ }
+ m_pc++;
+ m_icount--;
break;
// ZEXT
@@ -456,20 +497,23 @@ void f2mc16_device::execute_run()
m_icount--;
break;
+ // SWAP
case 0x16:
- // stream << "SWAP";
+ m_acc = (m_acc & 0xffff0000) | swapendian_int16(m_acc & 0xffff);
+ m_pc++;
+ m_icount -= 3;
break;
// ADDSP #imm8
case 0x17:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
if (m_ps & F_S)
{
- m_ssp += m_tmp8;
+ m_ssp += s8(m_tmp8);
}
else
{
- m_usp += m_tmp8;
+ m_usp += s8(m_tmp8);
}
m_pc += 2;
m_icount -= 3;
@@ -477,7 +521,7 @@ void f2mc16_device::execute_run()
// ADDL A, #imm32
case 0x18:
- m_tmp32 = read_32((m_pcb << 16) | (m_pc+1));
+ m_tmp32 = read_32((m_pcb << 16) | (m_pc + 1));
m_acc = doADD_32(m_acc, m_tmp32);
m_pc += 5;
m_icount -= 4;
@@ -485,7 +529,7 @@ void f2mc16_device::execute_run()
// SUBL A, #imm32
case 0x19:
- m_tmp32 = read_32((m_pcb << 16) | (m_pc+1));
+ m_tmp32 = read_32((m_pcb << 16) | (m_pc + 1));
m_acc = doSUB_32(m_acc, m_tmp32);
m_pc += 5;
m_icount -= 4;
@@ -493,13 +537,21 @@ void f2mc16_device::execute_run()
// MOV ILM, #imm8
case 0x1a:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1)) & 7;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1)) & 7;
m_ps &= 0x1fff;
m_ps |= (m_tmp8<<13);
m_pc += 2;
m_icount -= 2;
break;
+ // CMPL A, #imm32
+ case 0x1b:
+ m_tmp32 = read_32((m_pcb << 16) | (m_pc + 1));
+ doCMP_32(m_acc, m_tmp32);
+ m_pc += 5;
+ m_icount -= 3;
+ break;
+
// EXTW
case 0x1c:
m_acc &= 0xffff;
@@ -509,7 +561,7 @@ void f2mc16_device::execute_run()
m_acc |= 0xffff0000;
m_ps |= F_N;
}
- else
+ else if (m_acc == 0)
{
m_ps |= F_Z;
}
@@ -534,28 +586,43 @@ void f2mc16_device::execute_run()
m_icount -= 2;
break;
+ // ADDSP #imm16
+ case 0x1f:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ if (m_ps & F_S)
+ {
+ m_ssp += m_tmp16;
+ }
+ else
+ {
+ m_usp += m_tmp16;
+ }
+ m_pc += 3;
+ m_icount -= 3;
+ break;
+
case 0x20:
- // util::stream_format(stream, "ADD A, $%02x", operand);
+ logerror("%s: Unimplemented F2MC instruction ADD A, dir\n", machine().describe_context());
break;
case 0x21:
- // util::stream_format(stream, "SUB A, $%02x", operand);
+ logerror("%s: Unimplemented F2MC instruction SUB A, dir\n", machine().describe_context());
break;
case 0x22:
- // stream << "ADDC A";
+ logerror("%s: Unimplemented F2MC instruction ADDC A\n", machine().describe_context());
break;
// CMP A
case 0x23:
- doCMP_16(m_acc>>16, m_acc&0xffff);
+ doCMP_16(m_acc>>16, m_acc & 0xffff);
m_pc++;
m_icount--;
break;
// AND CCR, #imm8
case 0x24:
- m_tmp16 = read_8((m_pcb<<16) | (m_pc+1)) | 0xff80;
+ m_tmp16 = read_8((m_pcb << 16) | (m_pc + 1)) | 0xff80;
m_ps &= m_tmp16;
m_pc += 2;
m_icount -= 3;
@@ -563,18 +630,18 @@ void f2mc16_device::execute_run()
// OR CCR, #imm8
case 0x25:
- m_tmp16 = read_8((m_pcb<<16) | (m_pc+1)) & 0x7f;
+ m_tmp16 = read_8((m_pcb << 16) | (m_pc + 1)) & 0x7f;
m_ps |= m_tmp16;
m_pc += 2;
m_icount -= 3;
break;
case 0x26:
- // stream << "DIVU A";
+ logerror("%s: Unimplemented F2MC instruction DIVU A\n", machine().describe_context());
break;
case 0x27:
- // stream << "MULU A";
+ logerror("%s: Unimplemented F2MC instruction MULU A\n", machine().describe_context());
break;
// ADDW A
@@ -597,7 +664,7 @@ void f2mc16_device::execute_run()
// CBNE A, #imm8
case 0x2a:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
doCMP_8(m_acc & 0xff, m_tmp8);
if (m_ps & F_Z) // they're equal
{
@@ -668,9 +735,9 @@ void f2mc16_device::execute_run()
// ADD A, #imm8
case 0x30:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
m_tmp8 = doADD_8(m_acc & 0xff, m_tmp8);
- m_acc &= ~0xff;
+ m_acc &= 0xffff0000;
m_acc |= m_tmp8;
m_pc += 2;
m_icount -= 2;
@@ -678,21 +745,21 @@ void f2mc16_device::execute_run()
// SUB A, #imm8
case 0x31:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
m_tmp8 = doSUB_8(m_acc & 0xff, m_tmp8);
- m_acc &= ~0xff;
+ m_acc &= 0xffff0000;
m_acc |= m_tmp8;
m_pc += 2;
m_icount -= 2;
break;
case 0x32:
- // stream << "SUBC A";
+ logerror("%s: Unimplemented F2MC instruction SUBC A\n", machine().describe_context());
break;
// CMP A, #imm8
case 0x33:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
doCMP_8(m_acc & 0xff, m_tmp8);
m_pc += 2;
m_icount -= 2;
@@ -700,7 +767,7 @@ void f2mc16_device::execute_run()
// AND A, #imm8
case 0x34:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp32 = read_8((m_pcb << 16) | (m_pc + 1));
m_tmp32 |= 0xffffff00;
m_acc &= m_tmp32;
setNZ_8(m_acc & 0xff);
@@ -709,16 +776,19 @@ void f2mc16_device::execute_run()
m_icount -= 2;
break;
+ // OR A, #imm8
case 0x35:
- // util::stream_format(stream, "OR A, #$%02x", operand);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
+ m_acc |= m_tmp8;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 2;
break;
// XOR A, #imm8
case 0x36:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp16 = m_acc & 0xffff;
- m_acc <<= 16;
- m_acc |= m_tmp16;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
m_acc ^= m_tmp8;
setNZ_8(m_acc & 0xff);
m_ps &= ~F_V;
@@ -737,7 +807,7 @@ void f2mc16_device::execute_run()
// ADDW A, #imm16
case 0x38:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_tmp16 = doADD_16(m_acc & 0xffff, m_tmp16);
m_acc &= 0xffff0000;
m_acc |= m_tmp16;
@@ -747,7 +817,7 @@ void f2mc16_device::execute_run()
// SUBW A, #imm16
case 0x39:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_tmp16 = doSUB_16(m_acc & 0xffff, m_tmp16);
m_acc &= 0xffff0000;
m_acc |= m_tmp16;
@@ -757,8 +827,8 @@ void f2mc16_device::execute_run()
// CWBNE A, #imm16, disp8
case 0x3a:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+3));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
doCMP_16(m_acc & 0xffff, m_tmp16);
if (m_ps & F_Z)
{
@@ -767,14 +837,14 @@ void f2mc16_device::execute_run()
}
else
{
- m_pc = m_pc + 4 + (s8)m_tmp8;
+ m_pc = m_pc + 4 + s8(m_tmp8);
m_icount -= 5;
}
break;
// CMPW A, #imm16
case 0x3b:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
doCMP_16(m_acc & 0xffff, m_tmp16);
m_pc += 3;
m_icount -= 2;
@@ -782,7 +852,7 @@ void f2mc16_device::execute_run()
// ANDW A, #imm16
case 0x3c:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp32 = read_16((m_pcb << 16) | (m_pc + 1));
m_tmp32 |= 0xffff0000;
m_acc &= m_tmp32;
setNZ_16(m_acc & 0xffff);
@@ -793,7 +863,7 @@ void f2mc16_device::execute_run()
// ORW A, #imm16
case 0x3d:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_acc |= m_tmp16;
setNZ_16(m_acc & 0xffff);
m_ps &= ~F_V;
@@ -803,7 +873,7 @@ void f2mc16_device::execute_run()
// XORW A, #imm16
case 0x3e:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_acc ^= m_tmp16;
setNZ_16(m_acc & 0xffff);
m_ps &= ~F_V;
@@ -822,21 +892,19 @@ void f2mc16_device::execute_run()
// MOV A, dir
case 0x40:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- m_tmp8 = read_8(m_tmp32);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 1)));
+ m_tmp8 = read_8(m_tmpea);
m_acc <<= 16;
m_acc |= m_tmp8;
- setNZ_16(m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
m_pc += 2;
m_icount -= 3;
break;
// MOV dir, A
case 0x41:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- write_8(m_tmp32, m_acc & 0xff);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 1)));
+ write_8(m_tmpea, m_acc & 0xff);
setNZ_8(m_acc & 0xff);
m_pc += 2;
m_icount -= 3;
@@ -844,7 +912,7 @@ void f2mc16_device::execute_run()
// MOV A, #imm8
case 0x42:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
m_acc <<= 16;
m_acc |= m_tmp8;
setNZ_8(m_tmp8);
@@ -854,7 +922,7 @@ void f2mc16_device::execute_run()
// MOVX A, #imm8
case 0x43:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
m_acc <<= 16;
m_acc |= m_tmp8;
if (m_acc & 0x80)
@@ -868,10 +936,9 @@ void f2mc16_device::execute_run()
// MOV dir, #imm8
case 0x44:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- write_8(m_tmp32, m_tmp8);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 1)));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ write_8(m_tmpea, m_tmp8);
m_pc += 3;
m_icount -= 5;
break;
@@ -907,9 +974,8 @@ void f2mc16_device::execute_run()
// MOVW A, dir
case 0x48:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- m_tmp16 = read_16(m_tmp32);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 1)));
+ m_tmp16 = read_16(m_tmpea);
m_acc <<= 16;
m_acc |= m_tmp16;
setNZ_16(m_acc & 0xffff);
@@ -919,9 +985,8 @@ void f2mc16_device::execute_run()
// MOVW dir, A
case 0x49:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- write_16(m_tmp32, m_acc & 0xffff);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 1)));
+ write_16(m_tmpea, m_acc & 0xffff);
setNZ_16(m_acc & 0xffff);
m_pc += 2;
m_icount -= 3;
@@ -929,7 +994,7 @@ void f2mc16_device::execute_run()
// MOVW A, #imm16
case 0x4a:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_acc <<= 16;
m_acc |= m_tmp16;
setNZ_16(m_tmp16);
@@ -937,9 +1002,9 @@ void f2mc16_device::execute_run()
m_pc += 3;
break;
- // MOVL A, #imm16
+ // MOVL A, #imm32
case 0x4b:
- m_acc = read_32((m_pcb<<16) | (m_pc + 1));
+ m_acc = read_32((m_pcb << 16) | (m_pc + 1));
setNZ_32(m_acc);
m_icount -= 3;
m_pc += 5;
@@ -968,7 +1033,7 @@ void f2mc16_device::execute_run()
// PUSHW (register bitmap)
case 0x4f:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
for (int i = 0; i < 8; i++)
{
if (m_tmp8 & (1<<i))
@@ -988,14 +1053,33 @@ void f2mc16_device::execute_run()
}
break;
- // MOV A, adr16
+ // MOV A, io
+ case 0x50:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // MOV io, A
+ case 0x51:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ write_8(m_tmpea, m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // MOV A, addr16
case 0x52:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_acc <<= 16;
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_acc |= read_8((m_prefix<<16) | m_tmp16);
+ m_acc |= read_8((m_prefix << 16) | m_tmp16);
}
else
{
@@ -1006,13 +1090,13 @@ void f2mc16_device::execute_run()
m_icount -= 4;
break;
- // MOV adr16, A
+ // MOV addr16, A
case 0x53:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
if (m_prefix_valid)
{
m_prefix_valid = false;
- write_8((m_prefix<<16) | m_tmp16, m_acc & 0xff);
+ write_8((m_prefix << 16) | m_tmp16, m_acc & 0xff);
}
else
{
@@ -1023,18 +1107,71 @@ void f2mc16_device::execute_run()
m_icount -= 4;
break;
+ // MOV io, #imm8
+ case 0x54:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ write_8(m_tmpea, m_tmp8);
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // MOVW io, #imm16
+ case 0x56:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ write_16(m_tmpea, m_tmp16);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOVX A, addr16
case 0x57:
- // util::stream_format(stream, "MOVX A, $%04x", opcodes.r16(pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_acc <<= 16;
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
+ }
+ else
+ {
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
+ }
+ m_tmp16 = (m_tmp8 & 0x80) ? (m_tmp8 | 0xff00) : m_tmp8;
+ m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 3;
+ m_icount -= 4;
+ break;
+
+ // MOVW A, io
+ case 0x58:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ m_acc <<= 16;
+ m_acc |= read_16(m_tmpea);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // MOVW io, A
+ case 0x59:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 1));
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 3;
break;
- // MOVW A, adr16
+ // MOVW A, addr16
case 0x5a:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
m_acc <<= 16;
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_acc |= read_16((m_prefix<<16) | m_tmp16);
+ m_acc |= read_16((m_prefix << 16) | m_tmp16);
}
else
{
@@ -1045,13 +1182,13 @@ void f2mc16_device::execute_run()
m_icount -= 4;
break;
- // MOVW adr16, A
+ // MOVW addr16, A
case 0x5b:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
if (m_prefix_valid)
{
m_prefix_valid = false;
- write_16((m_prefix<<16) | m_tmp16, m_acc & 0xffff);
+ write_16((m_prefix << 16) | m_tmp16, m_acc & 0xffff);
}
else
{
@@ -1087,7 +1224,7 @@ void f2mc16_device::execute_run()
// POPW register list
case 0x5f:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
for (int i = 7; i >= 0; i--)
{
if (m_tmp8 & (1<<i))
@@ -1108,30 +1245,41 @@ void f2mc16_device::execute_run()
take_branch();
break;
+ // JMP @A
case 0x61:
-// stream << "JMP @A";
+ m_pc = (m_pcb << 16) | (m_acc & 0xffff);
+ m_icount -= 2;
break;
- // JMP #imm16
+ // JMP addr16
case 0x62:
- m_pc = read_16((m_pcb<<16) | (m_pc+1));
+ m_pc = read_16((m_pcb << 16) | (m_pc + 1));
m_icount -= 3;
break;
+ // JMPP addr24
case 0x63:
- // util::stream_format(stream, "JMPP #$%06x", opcodes.r8(pc+3)<<16|opcodes.r8(pc+2)<<8|opcodes.r8(pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_pcb = m_tmp8;
+ m_pc = m_tmp16;
+ m_icount -= 4;
break;
+ // CALL addr16
case 0x64:
- // util::stream_format(stream, "CALL #$%04x", opcodes.r16(pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ push_16(m_pc + 3);
+ m_pc = m_tmp16;
+ m_icount -= 6;
break;
- // CALLP #imm24
+ // CALLP addr24
case 0x65:
- push_16(m_pcb);
- push_16(m_pc+4);
- m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ push_16(m_pcb);
+ push_16(m_pc + 4);
m_pcb = m_tmp8;
m_pc = m_tmp16;
m_icount -= 10;
@@ -1144,111 +1292,126 @@ void f2mc16_device::execute_run()
m_icount -= 5;
break;
+ // RET
case 0x67:
- // stream << "RET";
+ m_pc = pull_16();
+ m_icount -= 4;
break;
- // RETI
- case 0x6b:
- {
- bool bFoundVec = false;
+ // INT #vct8
+ case 0x68:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
+ m_pc += 2;
+ take_irq_vector(m_tmp8);
+ m_ps &= ~F_I;
+ break;
- // there's an IRQ chaining facility, let's do it
- if (m_outstanding_irqs)
- {
- int cpulevel = peek_stack_16() >> 13;
- for (int irq = 0; irq < 256; irq++)
- {
- if (m_vector_level[irq] < cpulevel)
- {
- m_ps = read_16((m_ssb << 16) | m_ssp);
- m_ps |= F_S;
- m_ps &= ~0x7000;
- m_ps |= (m_vector_level[irq] & 7) << 13;
-
- u32 uVecAddr = 0xfffffc - (irq * 4);
- m_pc = read_16(uVecAddr);
- m_pcb = read_8(uVecAddr + 2);
- bFoundVec = true;
- printf("RETI vector chain to %02x%04x\n", m_pcb, m_pc);
+ // INT addr16
+ case 0x69:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_pc += 3;
+ take_irq();
+ m_pc = m_tmp16;
+ m_ps &= ~F_I;
+ break;
+
+ // INTP addr24
+ case 0x6a:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_pc += 4;
+ take_irq();
+ m_pcb = m_tmp8;
+ m_pc = m_tmp16;
+ m_ps &= ~F_I;
break;
- }
- }
- }
- // if no new IRQ was found or could be dispatched by the level
- if (!bFoundVec)
- {
- m_ps = pull_16_ssp();
- m_pc = pull_16_ssp();
- m_tmp16 = pull_16_ssp();
- m_pcb = m_tmp16 & 0xff;
- m_dtb = m_tmp16 >> 8;
- m_tmp16 = pull_16_ssp();
- m_adb = m_tmp16 & 0xff;
- m_dpr = m_tmp16 >> 8;
- m_acc = 0;
- m_acc = pull_16_ssp();
- m_acc |= (pull_16_ssp() << 16);
- m_icount -= 17;
- }
- }
+ // RETI
+ case 0x6b:
+ m_ps = pull_16_ssp();
+ m_pc = pull_16_ssp();
+ m_tmp16 = pull_16_ssp();
+ m_pcb = m_tmp16 & 0xff;
+ m_dtb = m_tmp16 >> 8;
+ m_tmp16 = pull_16_ssp();
+ m_adb = m_tmp16 & 0xff;
+ m_dpr = m_tmp16 >> 8;
+ m_acc = 0;
+ m_acc = pull_16_ssp();
+ m_acc |= (pull_16_ssp() << 16);
+ m_icount -= 17;
break;
case 0x6c: // bit operation instructions
- opcodes_bo6c(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_bo6c(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x6e: // string instructions
- opcodes_str6e(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_str6e(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x6f: // 2-byte instructions
- opcodes_2b6f(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_2b6f(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x70: // ea-type instructions
- opcodes_ea70(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea70(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x71: // ea-type instructions
- opcodes_ea71(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea71(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x72: // ea-type instructions
- opcodes_ea72(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea72(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x73: // ea-type instructions
- opcodes_ea73(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea73(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x74: // ea-type instructions
- opcodes_ea74(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea74(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x75: // ea-type instructions
- opcodes_ea75(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea75(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x76: // ea-type instructions
- opcodes_ea76(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea76(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x77: // ea-type instructions
- opcodes_ea77(read_8((m_pcb<<16) | (m_pc+1)));
+ opcodes_ea77(read_8((m_pcb << 16) | (m_pc + 1)));
break;
case 0x78: // ea-type instructions
- opcodes_ea78(read_8((m_pcb<<16) | (m_pc+1)));
+ 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)));
+ case 0x79: // RWi,ea-type instructions
+ opcodes_rwiea79(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)));
+ case 0x7a: // Ri,ea-type instructions
+ opcodes_riea7a(read_8((m_pcb << 16) | (m_pc + 1)));
+ break;
+
+ case 0x7b: // RWi,ea-type instructions
+ opcodes_rwiea7b(read_8((m_pcb << 16) | (m_pc + 1)));
+ break;
+
+ case 0x7c: // ea,Ri-type instructions
+ opcodes_eari7c(read_8((m_pcb << 16) | (m_pc + 1)));
+ break;
+
+ case 0x7d: // ea,RWi-type instructions
+ opcodes_earwi7d(read_8((m_pcb << 16) | (m_pc + 1)));
+ break;
+
+ case 0x7f: // RWi,ea-type instructions
+ opcodes_rwiea7f(read_8((m_pcb << 16) | (m_pc + 1)));
break;
// MOV A, Rx
@@ -1264,7 +1427,7 @@ void f2mc16_device::execute_run()
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
m_acc <<= 16;
m_acc |= read_rwX(opcode & 7);
- setNZ_16(m_acc & 0xff);
+ setNZ_16(m_acc & 0xffff);
m_pc++;
m_icount -= 2;
break;
@@ -1287,7 +1450,7 @@ void f2mc16_device::execute_run()
// MOV Rx, #imm8
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
write_rX(opcode & 7, m_tmp8);
setNZ_8(m_tmp8);
m_icount -= 2;
@@ -1296,7 +1459,7 @@ void f2mc16_device::execute_run()
// MOVW RWx, #imm16
case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 1));
write_rwX(opcode & 7, m_tmp16);
setNZ_16(m_tmp16);
m_icount -= 2;
@@ -1305,37 +1468,49 @@ void f2mc16_device::execute_run()
// MOVX A, Rx
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
- // util::stream_format(stream, "MOVX A, R%d", (opcode & 0x7));
+ m_acc <<= 16;
+ m_acc |= read_rX(opcode & 7);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc++;
+ m_icount -= 2;
break;
// MOVW A, @RWx + disp8
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp16 = read_rwX(opcode & 0x7) + (s8)m_tmp8;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
+ m_tmp16 = read_rwX(opcode & 0x7) + s8(m_tmp8);
+ m_tmpea = getRWbank(opcode & 0x7, m_tmp16);
m_acc <<= 16;
- m_acc |= read_16(getRWbank(opcode & 0x7, m_tmp16));
+ m_acc |= read_16(m_tmpea);
setNZ_16(m_acc & 0xffff);
m_pc += 2;
m_icount -= 10;
break;
- // MOVX A, @Rx + disp8
+ // MOVX A, @RWx + disp8
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmpea = read_rwX(opcode & 0x7) + (s8)m_tmp8;
- m_tmp8 = read_8(getRWbank(opcode & 7, m_tmpea));
- m_tmp16 = (m_tmp8 & 0x80) ? (m_tmp8 | 0xff00) : m_tmp8;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
+ m_tmp16 = read_rwX(opcode & 0x7) + s8(m_tmp8);
+ m_tmpea = getRWbank(opcode & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp16 = u16(s16(s8(m_tmp8)));
m_acc <<= 16;
m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
m_pc += 2;
m_icount -= 3;
break;
// MOVW @RWx + disp8, A
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
- m_tmp16 = read_rwX(opcode & 0x7) + (s8)m_tmp8;
- write_16(getRWbank(opcode & 0x7, m_tmp16), m_acc & 0xffff);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 1));
+ m_tmp16 = read_rwX(opcode & 0x7) + s8(m_tmp8);
+ m_tmpea = getRWbank(opcode & 0x7, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
setNZ_16(m_acc & 0xffff);
m_pc += 2;
m_icount -= 10;
@@ -1357,7 +1532,7 @@ void f2mc16_device::execute_run()
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, "CALLV #$%01x", (opcode & 0xf));
+ logerror("%s: Unimplemented F2MC instruction CALLV #imm4\n", machine().describe_context());
break;
// BEQ
@@ -1412,7 +1587,7 @@ void f2mc16_device::execute_run()
}
break;
- //
+ // BN
case 0xf4:
if (m_ps & F_N)
{
@@ -1465,7 +1640,7 @@ void f2mc16_device::execute_run()
break;
// BT
- case 0xf8:;
+ case 0xf8:
if (m_ps & F_T)
{
take_branch();
@@ -1493,9 +1668,9 @@ void f2mc16_device::execute_run()
// BLT
case 0xfa:
{
- u8 n = (m_ps & F_N) ? 1 : 0;
- u8 v = (m_ps & F_V) ? 1 : 0;
- if ((v ^ n) == 1)
+ const u8 n = (m_ps & F_N) ? 1 : 0;
+ const u8 v = (m_ps & F_V) ? 1 : 0;
+ if (v ^ n)
{
take_branch();
}
@@ -1510,9 +1685,9 @@ void f2mc16_device::execute_run()
// BGE
case 0xfb:
{
- u8 n = (m_ps & F_N) ? 1 : 0;
- u8 v = (m_ps & F_V) ? 1 : 0;
- if ((v ^ n) == 0)
+ const u8 n = (m_ps & F_N) ? 1 : 0;
+ const u8 v = (m_ps & F_V) ? 1 : 0;
+ if (!(v ^ n))
{
take_branch();
}
@@ -1527,9 +1702,9 @@ void f2mc16_device::execute_run()
// BLE
case 0xfc:
{
- u8 n = (m_ps & F_N) ? 1 : 0;
- u8 v = (m_ps & F_V) ? 1 : 0;
- if (((v ^ n) == 1) || (m_ps & F_Z))
+ const u8 n = (m_ps & F_N) ? 1 : 0;
+ const u8 v = (m_ps & F_V) ? 1 : 0;
+ if ((v ^ n) || (m_ps & F_Z))
{
take_branch();
}
@@ -1544,9 +1719,9 @@ void f2mc16_device::execute_run()
// BGT
case 0xfd:
{
- u8 n = (m_ps & F_N) ? 1 : 0;
- u8 v = (m_ps & F_V) ? 1 : 0;
- if (((v ^ n) == 1) || !(m_ps & F_Z))
+ const u8 n = (m_ps & F_N) ? 1 : 0;
+ const u8 v = (m_ps & F_V) ? 1 : 0;
+ if (!(v ^ n) && !(m_ps & F_Z))
{
take_branch();
}
@@ -1573,7 +1748,7 @@ void f2mc16_device::execute_run()
// BHI
case 0xff:
- if (!(m_ps & F_C) || !(m_ps & F_Z))
+ if (!(m_ps & F_C) && !(m_ps & F_Z))
{
take_branch();
}
@@ -1594,31 +1769,62 @@ void f2mc16_device::execute_run()
void f2mc16_device::opcodes_str6e(u8 operand)
{
+ const u8 spb = (m_ps & F_S) ? m_ssb : m_usb;
+
+ // TODO: If an interrupt occurs during the transfer, the transfer is suspended to
+ // handle the interrupt. The transfer is resumed after the interrupt has been handled.
switch (operand)
{
- // MOVSI ADB, DTB
- case 0x09:
- if (read_rwX(0) > 0)
- {
- u16 al = (m_acc & 0xffff);
- u16 ah = (m_acc >> 16) & 0xffff;
- m_tmp8 = read_8((m_dtb<<16) | al);
- write_8((m_adb<<16) | ah, m_tmp8);
- al++;
- ah++;
- m_acc = (ah<<16) | al;
- write_rwX(0, read_rwX(0) - 1);
- m_icount -= 8;
- }
- else
- {
- m_pc += 2;
- m_icount -= 5;
- }
- break;
+ // MOVSI destination_bank, source_bank
+ case 0x00: movsi(m_pcb, m_pcb); break;
+ case 0x01: movsi(m_pcb, m_dtb); break;
+ case 0x02: movsi(m_pcb, m_adb); break;
+ case 0x03: movsi(m_pcb, spb); break;
+ case 0x04: movsi(m_dtb, m_pcb); break;
+ case 0x05: movsi(m_dtb, m_dtb); break;
+ case 0x06: movsi(m_dtb, m_adb); break;
+ case 0x07: movsi(m_dtb, spb); break;
+ case 0x08: movsi(m_adb, m_pcb); break;
+ case 0x09: movsi(m_adb, m_dtb); break;
+ case 0x0a: movsi(m_adb, m_adb); break;
+ case 0x0b: movsi(m_adb, spb); break;
+ case 0x0c: movsi(spb, m_pcb); break;
+ case 0x0d: movsi(spb, m_dtb); break;
+ case 0x0e: movsi(spb, m_adb); break;
+ case 0x0f: movsi(spb, spb); break;
+
+ // MOVSWI destination_bank, source_bank
+ case 0x20: movswi(m_pcb, m_pcb); break;
+ case 0x21: movswi(m_pcb, m_dtb); break;
+ case 0x22: movswi(m_pcb, m_adb); break;
+ case 0x23: movswi(m_pcb, spb); break;
+ case 0x24: movswi(m_dtb, m_pcb); break;
+ case 0x25: movswi(m_dtb, m_dtb); break;
+ case 0x26: movswi(m_dtb, m_adb); break;
+ case 0x27: movswi(m_dtb, spb); break;
+ case 0x28: movswi(m_adb, m_pcb); break;
+ case 0x29: movswi(m_adb, m_dtb); break;
+ case 0x2a: movswi(m_adb, m_adb); break;
+ case 0x2b: movswi(m_adb, spb); break;
+ case 0x2c: movswi(spb, m_pcb); break;
+ case 0x2d: movswi(spb, m_dtb); break;
+ case 0x2e: movswi(spb, m_adb); break;
+ case 0x2f: movswi(spb, spb); break;
+
+ // FILSI destination_bank
+ case 0xc0: filsi(m_pcb); break;
+ case 0xc1: filsi(m_dtb); break;
+ case 0xc2: filsi(m_adb); break;
+ case 0xc3: filsi( spb); break;
+
+ // FILSWI destination_bank
+ case 0xe0: filswi(m_pcb); break;
+ case 0xe1: filswi(m_dtb); break;
+ case 0xe2: filswi(m_adb); break;
+ case 0xe3: filswi( spb); break;
default:
- fatalerror("Unknown F2MC STR6E opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC STR6E opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -1627,64 +1833,178 @@ void f2mc16_device::opcodes_bo6c(u8 operand)
{
switch (operand)
{
- // CLRB adr16, bit
+ // MOVB A, io:bp
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8(m_tmpea);
+ m_acc &= 0xffff0000;
+ if (m_tmp8 & (1 << (operand & 7)))
+ m_acc |= 0xff;
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 4;
+ break;
+
+ // MOVB A, dir:bp
+ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmp8 = read_8(m_tmpea);
+ m_acc &= 0xffff0000;
+ if (m_tmp8 & (1 << (operand & 7)))
+ m_acc |= 0xff;
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // MOVB io:bp, A
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8(m_tmpea);
+ if (m_acc & 0xff)
+ m_tmp8 |= (1 << (operand & 7));
+ else
+ m_tmp8 &= ~(1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // MOVB dir:bp, A
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmp8 = read_8(m_tmpea);
+ if (m_acc & 0xff)
+ m_tmp8 |= (1 << (operand & 7));
+ else
+ m_tmp8 &= ~(1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // CLRB io:bp
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 &= ~(1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // CLRB dir:bp
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 &= ~(1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // CLRB addr16:bp
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
- m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp8 = read_8((m_prefix<<16) | m_tmp16);
- m_tmp8 |= (1 << (operand & 7));
- write_8((m_prefix<<16) | m_tmp16, m_tmp8);
+ m_tmpea |= (m_prefix << 16);
}
else
- {
- m_tmp8= read_8((m_dtb<<16) | m_tmp16);
- m_tmp8 |= (1 << (operand & 7));
- write_8((m_dtb<<16) | m_tmp16, m_tmp8);
- }
- m_pc += 2;
+ m_tmpea |= (m_dtb<<16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 &= ~(1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
m_icount -= 7;
break;
- // SETB adr16, bit
+ // SETB io:bp
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 |= (1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // SETB dir:bp
+ case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 |= (1 << (operand & 7));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // SETB addr16:bp
case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_rmw = true;
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp8 = read_8((m_prefix<<16) | m_tmp16);
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
m_tmp8 |= (1 << (operand & 7));
- write_8((m_prefix<<16) | m_tmp16, m_tmp8);
+ write_8((m_prefix << 16) | m_tmp16, m_tmp8);
}
else
{
- m_tmp8= read_8((m_dtb<<16) | m_tmp16);
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
m_tmp8 |= (1 << (operand & 7));
write_8((m_dtb<<16) | m_tmp16, m_tmp8);
}
- m_pc += 2;
+ m_rmw = false;
+ m_pc += 4;
m_icount -= 7;
break;
- // BBC dir8, bit, disp8
+ // BBC io:bp, disp8
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_ps &= ~F_Z;
+ m_pc += 4;
+ if (!(read_8(m_tmpea) & (1 << (operand & 7))))
+ {
+ m_ps |= F_Z;
+ m_pc += s8(m_tmp8);
+ m_icount--;
+ }
+ m_icount -= 6;
+ break;
+
+ // BBC dir:bp, disp8
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
- m_tmp32 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
- m_tmp8 = read_8(m_tmp32);
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
m_ps &= ~F_Z;
m_pc += 4;
- if (!(read_8(m_tmp32) & (1 << (operand & 7))))
+ if (!(read_8(m_tmpea) & (1 << (operand & 7))))
{
m_ps |= F_Z;
- m_pc += (s8)m_tmp8;
+ m_pc += s8(m_tmp8);
m_icount--;
}
m_icount -= 7;
break;
- // BBC adr16, bit, disp8
+ // BBC addr16:bp, disp8
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
@@ -1693,23 +2013,59 @@ void f2mc16_device::opcodes_bo6c(u8 operand)
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 = (m_prefix<<16) | m_tmp16;
+ m_tmpea = (m_prefix << 16) | m_tmp16;
}
else
{
- m_tmp32 = (m_dtb<<16) | m_tmp16;
+ m_tmpea = (m_dtb<<16) | m_tmp16;
}
- if (!(read_8(m_tmp32) & (1 << (operand & 7))))
+ if (!(read_8(m_tmpea) & (1 << (operand & 7))))
{
m_ps |= F_Z;
- m_pc += (s8)m_tmp8;
+ m_pc += s8(m_tmp8);
m_icount--;
}
m_icount -= 7;
break;
- // BBS adr16, bit, disp8
+ // BBS io:bp, disp8
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_ps &= ~F_Z;
+ m_pc += 4;
+ if (read_8(m_tmpea) & (1 << (operand & 7)))
+ {
+ m_pc += s8(m_tmp8);
+ m_icount--;
+ }
+ else
+ {
+ m_ps |= F_Z;
+ }
+ m_icount -= 6;
+ break;
+
+ // BBS dir:bp, disp8
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ m_tmpea = getdirbank(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_ps &= ~F_Z;
+ m_pc += 4;
+ if (read_8(m_tmpea) & (1 << (operand & 7)))
+ {
+ m_pc += s8(m_tmp8);
+ m_icount--;
+ }
+ else
+ {
+ m_ps |= F_Z;
+ }
+ m_icount -= 7;
+ break;
+
+ // BBS addr16:bp, disp8
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
@@ -1718,16 +2074,16 @@ void f2mc16_device::opcodes_bo6c(u8 operand)
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 = (m_prefix<<16) | m_tmp16;
+ m_tmpea = (m_prefix << 16) | m_tmp16;
}
else
{
- m_tmp32 = (m_dtb<<16) | m_tmp16;
+ m_tmpea = (m_dtb << 16) | m_tmp16;
}
- if (read_8(m_tmp32) & (1 << (operand & 7)))
+ if (read_8(m_tmpea) & (1 << (operand & 7)))
{
- m_pc += (s8)m_tmp8;
+ m_pc += s8(m_tmp8);
m_icount--;
}
else
@@ -1737,8 +2093,26 @@ void f2mc16_device::opcodes_bo6c(u8 operand)
m_icount -= 7;
break;
+ // WBTS io:bp
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8(m_tmpea);
+ if (m_tmp8 & (1 << (operand & 7)))
+ m_pc += 3;
+ m_icount -= 4;
+ break;
+
+ // WBTC io:bp
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmpea = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8(m_tmpea);
+ if (!(m_tmp8 & (1 << (operand & 7))))
+ m_pc += 3;
+ m_icount -= 4;
+ break;
+
default:
- fatalerror("Unknown F2MC 6C bit-op opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC 6C bit-op opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -1787,6 +2161,24 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_icount -= 2;
break;
+ // MOV A, @A
+ case 0x05:
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | (m_acc & 0xffff));
+ }
+ else
+ {
+ m_tmp8 = read_8((m_dtb << 16) | (m_acc & 0xffff));
+ }
+ setNZ_8(m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
// MOV A, PCB
case 0x06:
m_acc <<= 16;
@@ -1795,6 +2187,24 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_icount -= 1;
break;
+ // ROLC A
+ case 0x07:
+ m_shifted_carry = (m_ps & F_C) ? 1 : 0;
+ m_tmp8 = m_acc & 0xff;
+ m_ps &= ~F_C;
+ if (m_tmp8 & 0x80)
+ {
+ m_ps |= F_C;
+ }
+ m_tmp8 <<= 1;
+ m_tmp8 |= m_shifted_carry;
+ m_acc &= 0xffffff00;
+ m_acc |= m_tmp8;
+ setNZ_8(m_tmp8);
+ m_pc += 2;
+ m_icount -= 2;
+ break;
+
// LSLW A, R0
case 0x0c:
m_tmp8 = read_rX(0);
@@ -1819,6 +2229,24 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_pc += 2;
break;
+ // MOVW A, @A
+ case 0x0d:
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp16 = read_16((m_prefix << 16) | (m_acc & 0xffff));
+ }
+ else
+ {
+ m_tmp16 = read_16((m_dtb << 16) | (m_acc & 0xffff));
+ }
+ setNZ_16(m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
// ASRW A, R0
case 0x0e:
m_tmp8 = read_rX(0);
@@ -1832,6 +2260,7 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
}
else
{
+ m_icount -= 5;
m_tmp16 = m_acc & 0xffff;
for (u8 count = 0; count < m_tmp8; count++)
{
@@ -1858,7 +2287,7 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_tmp16 &= ~0x8000;
}
setNZ_16(m_tmp16);
- m_icount -= 5;
+ m_icount--; // 1 additional cycle per iteration
}
m_acc &= 0xffff0000;
@@ -1868,18 +2297,19 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
break;
// LSRW A, R0
- case 0xf:
+ case 0x0f:
m_tmp8 = read_rX(0);
if (m_tmp8 == 0)
{
// docs don't say if N is cleared in this case or not
- m_ps &= ~(F_C|F_T);
+ m_ps &= ~(F_C | F_T);
m_ps |= F_Z;
m_pc += 2;
m_icount -= 6;
}
else
{
+ m_icount -= 5;
m_tmp16 = m_acc & 0xffff;
for (u8 count = 0; count < m_tmp8; count++)
{
@@ -1897,7 +2327,7 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
m_tmp16 >>= 1;
setNZ_16(m_tmp16);
- m_icount -= 5;
+ m_icount--; // 1 additional cycle per iteration
}
m_acc &= 0xffff0000;
@@ -1946,11 +2376,33 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
if (m_prefix_valid)
{
m_prefix_valid = false;
- write_8((m_prefix<<16) | (m_acc & 0xffff), (m_acc>>16) & 0xff);
+ 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;
+
+ // MOVX A, @A
+ case 0x16:
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | (m_acc & 0xffff));
}
else
{
- write_8((m_dtb<<16) | (m_acc & 0xffff), (m_acc>>16) & 0xff);
+ m_tmp8 = read_8((m_dtb << 16) | (m_acc & 0xffff));
+ }
+ setNZ_8(m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
}
m_pc += 2;
m_icount -= 3;
@@ -1966,45 +2418,215 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
}
else
{
- m_icount -= 6;
for (u8 count = 0; count < m_tmp8; count++)
{
m_ps &= ~F_C;
m_ps |= (m_acc & 0x80000000) ? F_C : 0;
m_acc <<= 1;
- m_icount --; // 1 additional cycle per iteration
+ m_icount--; // 1 additional cycle per iteration
}
setNZ_32(m_acc);
}
m_pc += 2;
break;
- // MOV @RLx + #disp8, A
+ // ASRL A, R0
+ case 0x1e:
+ m_tmp8 = read_rX(0);
+ m_icount -= 6; // 6 cycles base
+ if (m_tmp8 == 0)
+ {
+ m_ps &= ~(F_C | F_T);
+ m_ps |= F_Z;
+ }
+ else
+ {
+ for (u8 count = 0; count < m_tmp8; count++)
+ {
+ // T is set if either carry or T are set beforehand
+ if ((m_ps & F_C) || (m_ps & F_T))
+ {
+ m_ps |= F_T;
+ }
+ // C becomes the previous LSB
+ m_ps &= ~F_C;
+ m_ps |= (m_acc & 1) ? F_C : 0;
+
+ if (m_acc & 0x80000000)
+ {
+ m_acc >>= 1;
+ m_acc |= 0x80000000;
+ }
+ else
+ {
+ m_acc >>= 1;
+ m_acc &= ~0x80000000;
+ }
+ setNZ_32(m_acc);
+ m_icount--; // 1 additional cycle per iteration
+ }
+ }
+ m_pc += 2;
+ break;
+
+ // LSRL A, R0
+ case 0x1f:
+ m_tmp8 = read_rX(0);
+ m_icount -= 6; // 6 cycles base
+ if (m_tmp8 == 0)
+ {
+ m_ps &= ~(F_C | F_T);
+ m_ps |= F_Z;
+ }
+ else
+ {
+ for (u8 count = 0; count < m_tmp8; count++)
+ {
+ // T is set if either carry or T are set beforehand
+ if ((m_ps & F_C) || (m_ps & F_T))
+ {
+ m_ps |= F_T;
+ }
+ // C becomes the previous LSB
+ m_ps &= ~F_C;
+ m_ps |= (m_acc & 1) ? F_C : 0;
+
+ m_acc >>= 1;
+ setNZ_32(m_acc);
+ m_icount--; // 1 additional cycle per iteration
+ }
+ }
+ m_pc += 2;
+ break;
+
+ // MOVX A, @RLx + disp8
+ case 0x20: case 0x22: case 0x24: case 0x26:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rlX((operand >> 1) & 0x3) + s8(m_tmp8);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 10;
+ break;
+
+ // LSL A, R0
+ case 0x2c:
+ m_tmp8 = read_rX(0);
+ if (m_tmp8 == 0)
+ {
+ m_icount -= 6;
+ }
+ else
+ {
+ m_tmp8aux = m_acc & 0xff;
+ for (u8 count = 0; count < m_tmp8; count++)
+ {
+ m_ps &= ~F_C;
+ m_ps |= (m_tmp8aux & 0x80) ? F_C : 0;
+ m_tmp8aux <<= 1;
+ m_icount -= 5;
+ }
+ setNZ_8(m_tmp8aux);
+ m_acc &= 0xffffff00;
+ m_acc |= m_tmp8aux;
+ }
+ m_pc += 2;
+ break;
+
+ // NRML A, R0
+ case 0x2d:
+ m_tmp8 = 0;
+ if (m_acc != 0)
+ {
+ while (!(m_acc & 0x80000000))
+ {
+ m_acc <<= 1;
+ m_tmp8++;
+ m_icount--; // 1 additional cycle per iteration
+ }
+ m_ps &= ~(F_Z);
+ m_icount -= 6;
+ }
+ else
+ {
+ m_ps |= F_Z;
+ m_icount -= 4;
+ }
+ write_rX(0, m_tmp8);
+ m_pc += 2;
+ break;
+
+ // LSR A, R0
+ case 0x2f:
+ m_tmp8 = read_rX(0);
+ if (m_tmp8 == 0)
+ {
+ // docs don't say if N is cleared in this case or not
+ m_ps &= ~(F_C|F_T);
+ m_ps |= F_Z;
+ m_pc += 2;
+ m_icount -= 6;
+ }
+ else
+ {
+ m_icount -= 5;
+ m_tmp8aux = m_acc & 0xff;
+ for (u8 count = 0; count < m_tmp8; count++)
+ {
+ // T is set if either carry or T are set beforehand
+ if ((m_ps & F_C) || (m_ps & F_T))
+ {
+ m_ps |= F_T;
+ }
+ // C becomes the previous LSB
+ m_ps &= ~F_C;
+ if (m_tmp8aux & 1)
+ {
+ m_ps |= F_C;
+ }
+
+ m_tmp8aux >>= 1;
+ setNZ_8(m_tmp8aux);
+ m_icount--; // 1 additional cycle per iteration
+ }
+
+ m_acc &= 0xffffff00;
+ m_acc |= m_tmp8aux;
+ m_pc += 2;
+ }
+ break;
+
+ // MOV @RLx + disp8, A
case 0x30: case 0x32: case 0x34: case 0x36:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp32 = read_rlX((operand>>1) & 0x3) + (s8)m_tmp8;
- write_8(m_tmp32, m_acc & 0xff);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rlX((operand >> 1) & 0x3) + s8(m_tmp8);
+ write_8(m_tmpea, m_acc & 0xff);
setNZ_8(m_acc & 0xff);
m_pc += 3;
m_icount -= 10;
break;
- // MOVW @RLx + #disp8, A
+ // MOVW @RLx + disp8, A
case 0x38: case 0x3a: case 0x3c: case 0x3e:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rlX((operand>>1) & 0x3) + (s8)m_tmp8;
- write_8(m_tmpea, m_acc & 0xffff);
- setNZ_8(m_acc & 0xffff);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rlX((operand >> 1) & 0x3) + s8(m_tmp8);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
m_pc += 3;
m_icount -= 10;
break;
// MOV A, @RLx + disp8
case 0x40: case 0x42: case 0x44: case 0x46:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp32 = read_rlX((operand>>1) & 0x3) + (s8)m_tmp8;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rlX((operand >> 1) & 0x3) + s8(m_tmp8);
m_acc <<= 16;
- m_acc |= read_8(m_tmp32);
+ m_acc |= read_8(m_tmpea);
setNZ_8(m_acc & 0xff);
m_pc += 3;
m_icount -= 10;
@@ -2012,17 +2634,17 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
// MOVW A, @RLx + disp8
case 0x48: case 0x4a: case 0x4c: case 0x4e:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp32 = read_rlX((operand>>1) & 0x3) + (s8)m_tmp8;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rlX((operand >> 1) & 0x3) + s8(m_tmp8);
m_acc <<= 16;
- m_acc |= read_16(m_tmp32);
- setNZ_8(m_acc & 0xffff);
+ m_acc |= read_16(m_tmpea);
+ setNZ_16(m_acc & 0xffff);
m_pc += 3;
m_icount -= 10;
break;
default:
- fatalerror("Unknown F2MC 2B6F opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC 2B6F opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2033,79 +2655,247 @@ void f2mc16_device::opcodes_ea70(u8 operand)
{
// ADDL A, RLx
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- m_acc = doADD_32(m_acc, read_rlX((operand>>1) & 3));
- m_pc += 3;
- m_icount -= 7;
+ m_acc = doADD_32(m_acc, read_rlX((operand >> 1) & 3));
+ m_pc += 2;
+ m_icount -= 6;
break;
// ADDL A, @RWx + disp8
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- m_tmp8 = read_32((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp32 = read_32(getRWbank(operand & 7, m_tmpea));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
m_acc = doADD_32(m_acc, m_tmp32);
m_pc += 3;
- m_icount -= 7;
+ m_icount -= 9;
+ break;
+
+ // ADDL A, @RWx + disp16
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
+ m_acc = doADD_32(m_acc, m_tmp32);
+ m_pc += 4;
+ m_icount -= 9;
+ break;
+
+ // ADDL A, addr16
+ case 0x1f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
+ }
+ else
+ {
+ m_tmpea |= (m_dtb << 16);
+ }
+ m_acc = doADD_32(m_acc, read_32(m_tmpea));
+ m_pc += 4;
+ m_icount -= 8;
break;
// SUBL A, RLx
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
- m_acc = doSUB_32(m_acc, read_rlX((operand>>1) & 3));
+ m_acc = doSUB_32(m_acc, read_rlX((operand >> 1) & 3));
m_pc += 2;
- m_icount -= 7;
+ m_icount -= 6;
break;
// SUBL A, @RWx + disp8
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- m_tmp8 = read_32((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp32 = read_32(getRWbank(operand & 7, m_tmpea));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
m_acc = doSUB_32(m_acc, m_tmp32);
m_pc += 3;
- m_icount -= 7;
+ m_icount -= 9;
+ break;
+
+ // SUBL A, @RWx + disp16
+ case 0x38: case 0x39: case 0x3a: case 0x3b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
+ m_acc = doSUB_32(m_acc, m_tmp32);
+ m_pc += 4;
+ m_icount -= 9;
+ break;
+
+ // SUBL A, addr16
+ case 0x3f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
+ }
+ else
+ {
+ m_tmpea |= (m_dtb << 16);
+ }
+ m_acc = doSUB_32(m_acc, read_32(m_tmpea));
+ m_pc += 4;
+ m_icount -= 8;
+ break;
+
+ // CWBNE RWx, #imm16, disp8
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
+ doCMP_16(read_rwX(operand & 7), m_tmp16);
+ if (m_ps & F_Z)
+ {
+ m_pc += 5;
+ m_icount -= 7;
+ }
+ else
+ {
+ m_pc = m_pc + 5 + s8(m_tmp8);
+ m_icount -= 8;
+ }
break;
// CMPL A, RLx
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
- doCMP_32(m_acc, read_rlX((operand>>1) & 3));
+ doCMP_32(m_acc, read_rlX((operand >> 1) & 3));
m_pc += 2;
- m_icount -= 7;
+ m_icount -= 6;
break;
// CMPL A, @RWx + disp8
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
- m_tmp8 = read_32((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp32 = read_32(getRWbank(operand & 7, m_tmpea));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
doCMP_32(m_acc, m_tmp32);
m_pc += 3;
- m_icount -= 7;
+ m_icount -= 9;
+ break;
+
+ // CMPL A, @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
+ doCMP_32(m_acc, m_tmp32);
+ m_pc += 4;
+ m_icount -= 9;
+ break;
+
+ // CMPL A, addr16
+ case 0x7f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
+ }
+ else
+ {
+ m_tmpea |= (m_dtb << 16);
+ }
+ doCMP_32(m_acc, read_32(m_tmpea));
+ m_pc += 4;
+ m_icount -= 8;
break;
// ANDL A, RLx
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
- m_tmp32 = read_rlX((operand>>1) & 3);
+ m_tmp32 = read_rlX((operand >> 1) & 3);
m_acc &= m_tmp32;
setNZ_32(m_acc);
m_ps &= ~F_V;
m_pc += 2;
- m_icount -= 7;
+ m_icount -= 6;
break;
// ANDL A, @RWx + disp8
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
- m_tmp8 = read_32((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp32 = read_32(getRWbank(operand & 7, m_tmpea));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
m_acc &= m_tmp32;
setNZ_32(m_acc);
m_ps &= ~F_V;
m_pc += 3;
- m_icount -= 7;
+ m_icount -= 9;
+ break;
+
+ // ORL A, RLx
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ m_tmp32 = read_rlX((operand >> 1) & 3);
+ m_acc |= m_tmp32;
+ setNZ_32(m_acc);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // ORL A, @RWx + disp8
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
+ m_acc |= m_tmp32;
+ setNZ_32(m_acc);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 9;
+ break;
+
+ // XORL A, RLx
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_tmp32 = read_rlX((operand >> 1) & 3);
+ m_acc ^= m_tmp32;
+ setNZ_32(m_acc);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // XORL A, @RWx + disp8
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
+ m_acc ^= m_tmp32;
+ setNZ_32(m_acc);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 9;
+ break;
+
+ // CBNE Rx, #imm8, disp8
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmp8aux = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 3));
+ doCMP_8(read_rX(operand & 7), m_tmp8aux);
+ if (m_ps & F_Z)
+ {
+ m_pc += 4;
+ m_icount -= 12;
+ }
+ else
+ {
+ m_pc = m_pc + 4 + s8(m_tmp8);
+ m_icount -= 13;
+ }
break;
default:
- fatalerror("Unknown F2MC EA70 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA70 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2117,10 +2907,11 @@ void f2mc16_device::opcodes_ea71(u8 operand)
// CALLP @RWx + disp8
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
push_16(m_pcb);
- push_16(m_pc+4);
+ push_16(m_pc + 4);
m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp32 = read_32(getRWbank(operand & 7, m_tmp16));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_32(m_tmpea);
m_pc = m_tmp32 & 0xffff;
m_pcb = (m_tmp32 >> 16) & 0xff;
m_icount -= 11;
@@ -2128,39 +2919,135 @@ void f2mc16_device::opcodes_ea71(u8 operand)
// INCL RLx
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
- m_tmp64 = read_rlX((operand>>1) & 3);
- m_tmp64++;
- write_rlX((operand>>1) & 3, m_tmp64&0xffffffff);
- setNZ_32(m_tmp64 & 0xffffffff);
- m_ps &= ~F_V;
- if (m_tmp64 & 0x100000000)
- {
- m_ps |= F_V;
- }
+ m_tmp32 = doINC_32(read_rlX((operand >> 1) & 3));
+ write_rlX((operand >> 1) & 3, m_tmp32);
m_pc += 2;
m_icount -= 7;
break;
// INCL @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;
- m_tmp64 = read_32(getRWbank(operand & 7, m_tmp16));
- m_tmp64++;
- write_32(getRWbank(operand & 7, m_tmp16), m_tmp64 & 0xffffffff);
- setNZ_32(m_tmp64 & 0xffffffff);
- m_ps &= ~F_V;
- if (m_tmp64 & 0x100000000)
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doINC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 11;
+ break;
+
+ // INCL @RWx + disp16
+ case 0x58: case 0x59: case 0x5a: case 0x5b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doINC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 11;
+ break;
+
+ // INCL @RWx + RW7
+ case 0x5c: case 0x5d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doINC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 13;
+ break;
+
+ // INCL addr16
+ case 0x5f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
{
- m_ps |= F_V;
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
}
- m_pc += 3;
+ else
+ m_tmpea |= (m_dtb << 16);
+ m_rmw = true;
+ m_tmp32 = doINC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 10;
+ break;
+
+ // DECL RLx
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ m_tmp32 = doDEC_32(read_rlX((operand >> 1) & 3));
+ write_rlX((operand >> 1) & 3, m_tmp32);
+ m_pc += 2;
m_icount -= 7;
break;
+ // DECL @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_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doDEC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 11;
+ break;
+
+ // DECL @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doDEC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 11;
+ break;
+
+ // DECL @RWx + RW7
+ case 0x7c: case 0x7d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_rmw = true;
+ m_tmp32 = doDEC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 13;
+ break;
+
+ // DECL addr16
+ case 0x7f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
+ }
+ else
+ m_tmpea |= (m_dtb << 16);
+ m_rmw = true;
+ m_tmp32 = doDEC_32(read_32(m_tmpea));
+ write_32(m_tmpea, m_tmp32);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 10;
+ 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);
+ m_acc = read_rlX((operand >> 1) & 3);
setNZ_32(m_acc);
m_pc += 2;
m_icount -= 4;
@@ -2168,37 +3055,49 @@ void f2mc16_device::opcodes_ea71(u8 operand)
// 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));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- m_acc = read_32(getRWbank(operand & 7, m_tmpea));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_acc = read_32(m_tmpea);
setNZ_32(m_acc);
m_pc += 3;
- m_icount -= 4;
+ m_icount -= 7;
break;
// MOVL A, @RWx + disp16
case 0x98: case 0x99: case 0x9a: case 0x9b:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
- m_tmpea = read_rwX(operand & 3) + (s16)m_tmp16;
- m_acc = read_32(getRWbank(operand & 3, m_tmpea));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc = read_32(m_tmpea);
setNZ_32(m_acc);
m_pc += 4;
- m_icount -= 4;
+ m_icount -= 7;
+ break;
+
+ // MOVL A, @RWx + RW7
+ case 0x9c: case 0x9d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_acc = read_32(m_tmpea);
+ setNZ_32(m_acc);
+ m_pc += 2;
+ m_icount -= 9;
break;
- // MOVL A, adr16
+ // MOVL A, addr16
case 0x9f:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 |= (m_prefix << 16);
+ m_tmpea |= (m_prefix << 16);
}
else
{
- m_tmp32 |= (m_dtb << 16);
+ m_tmpea |= (m_dtb << 16);
}
- m_acc = read_32(m_tmp32);
+ m_acc = read_32(m_tmpea);
setNZ_32(m_acc);
m_pc += 4;
m_icount -= 4;
@@ -2214,25 +3113,47 @@ void f2mc16_device::opcodes_ea71(u8 operand)
// MOVL @RWx + disp8, A
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- write_32(getRWbank(operand & 7, m_tmp16), m_acc);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ write_32(m_tmpea, m_acc);
setNZ_32(m_acc);
m_pc += 3;
- m_icount -= 4;
+ m_icount -= 7;
+ break;
+
+ // MOVL @RWx + disp16, A
+ case 0xb8: case 0xb9: case 0xba: case 0xbb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_32(m_tmpea, m_acc);
+ setNZ_32(m_acc);
+ m_pc += 4;
+ m_icount -= 7;
+ break;
+
+ // MOVL @RWx + RW7, A
+ case 0xbc: case 0xbd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ write_32(m_tmpea, m_acc);
+ setNZ_32(m_acc);
+ m_pc += 2;
+ m_icount -= 9;
break;
// MOVL addr16, A
case 0xbf:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- write_32((m_prefix<<16) | m_tmp16, m_acc);
+ write_32((m_prefix << 16) | m_tmp16, m_acc);
}
else
{
- write_32((m_dtb<<16) | m_tmp16, m_acc);
+ write_32((m_dtb << 16) | m_tmp16, m_acc);
}
setNZ_32(m_acc);
m_pc += 4;
@@ -2241,27 +3162,112 @@ void f2mc16_device::opcodes_ea71(u8 operand)
// MOV @RWx, #imm8
case 0xc8: case 0xc9: case 0xca: case 0xcb:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7);
- write_8(getRWbank(operand & 7, m_tmp16), m_tmp8);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_8(m_tmpea, m_tmp8);
setNZ_8(m_tmp8);
m_pc += 3;
- m_icount -= 2;
+ m_icount -= 6;
+ break;
+
+ // MOV @RWx+, #imm8
+ case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 1);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 3;
+ m_icount -= 8;
+ break;
+
+ // MOV @RWx + disp8, #imm8
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_8((m_pcb << 16) | (m_pc + 3));
+ m_tmpea = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmpea);
+ write_8(m_tmpea, m_tmp16 & 0xff);
+ setNZ_8(m_tmp16 & 0xff);
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // MOV @RWx + disp16, #imm8
+ case 0xd8: case 0xd9: case 0xda: case 0xdb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 5;
+ m_icount -= 6;
+ break;
+
+ // MOV @RWx + RW7, #imm8
+ case 0xdc: case 0xdd:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 3;
+ m_icount -= 8;
+ break;
+
+ // MOV addr16, #imm8
+ case 0xdf:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ write_8((m_prefix << 16) | m_tmp16, m_tmp8);
+ }
+ else
+ {
+ write_8((m_dtb << 16) | m_tmp16, m_tmp8);
+ }
+ setNZ_8(m_tmp8);
+ m_pc += 5;
+ m_icount -= 5;
break;
// MOVEA A, @RWx + disp8
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
m_acc <<= 16;
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7);
- m_tmp16 += (s8)m_tmp8;
m_acc |= m_tmp16;
m_pc += 3;
- m_icount -= 1;
+ m_icount -= 3;
+ break;
+
+ // MOVEA A, @RWx + disp16
+ case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_acc <<= 16;
+ m_acc |= m_tmp16;
+ m_pc += 4;
+ m_icount -= 3;
+ break;
+
+ // MOVEA A, @RWx + RW7
+ case 0xfc: case 0xfd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_acc <<= 16;
+ m_acc |= m_tmp16;
+ m_pc += 2;
+ m_icount -= 5;
break;
default:
- fatalerror("Unknown F2MC EA71 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA71 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2270,71 +3276,371 @@ void f2mc16_device::opcodes_ea72(u8 operand)
{
switch (operand)
{
- // INC @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;
- m_tmp32 = read_16(getRWbank(operand & 7, m_tmp16));
- m_tmp32++;
- write_8(getRWbank(operand & 7, m_tmp16), m_tmp32 & 0xff);
- setNZ_8(m_tmp32 & 0xff);
- m_ps &= ~F_V;
- if (m_tmp32 & 0x100)
+ // ROLC Rx
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_shifted_carry = (m_ps & F_C) ? 1 : 0;
+ m_tmp8 = read_rX(operand & 7);
+ m_ps &= ~F_C;
+ if (m_tmp8 & 0x80)
{
- m_ps |= F_V;
+ m_ps |= F_C;
}
+ m_tmp8 <<= 1;
+ m_tmp8 |= m_shifted_carry;
+ write_rX(operand & 7, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // RORC Rx
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ m_shifted_carry = (m_ps & F_C) ? 1 : 0;
+ m_tmp8 = read_rX(operand & 7);
+ m_ps &= ~F_C;
+ if (m_tmp8 & 1)
+ {
+ m_ps |= F_C;
+ }
+ m_tmp8 >>= 1;
+ m_tmp8 |= m_shifted_carry ? 0x80 : 0;
+ write_rX(operand & 7, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // INC Rx
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp8 = doINC_8(read_rX(operand & 7));
+ write_rX(operand & 7, m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // INC @RWx
+ case 0x48: case 0x49: case 0x4a: case 0x4b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doINC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // INC @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);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doINC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
m_pc += 3;
- m_icount -= 5;
+ m_icount -= 7;
+ break;
+
+ // INC @RWx + disp16
+ case 0x58: case 0x59: case 0x5a: case 0x5b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doINC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 7;
+ break;
+
+ // INC @RWx + RW7
+ case 0x5c: case 0x5d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doINC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 9;
break;
// INC addr16
case 0x5f:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 |= (m_prefix << 16);
+ m_tmpea |= (m_prefix << 16);
}
else
{
- m_tmp32 |= (m_dtb << 16);
+ m_tmpea |= (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_rmw = true;
+ m_tmp8 = doINC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // DEC Rx
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ m_tmp8 = doDEC_8(read_rX(operand & 7));
+ write_rX(operand & 7, m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // DEC @RWx
+ case 0x68: case 0x69: case 0x6a: case 0x6b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doDEC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // DEC @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_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doDEC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 7;
+ break;
+
+ // DEC @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doDEC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 7;
+ break;
+
+ // DEC @RWx + RW7
+ case 0x7c: case 0x7d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doDEC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 9;
+ break;
+
+ // DEC addr16
+ case 0x7f:
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmpea |= (m_prefix << 16);
+ }
+ else
{
- m_ps |= F_V;
+ m_tmpea |= (m_dtb << 16);
}
+ m_rmw = true;
+ m_tmp8 = doDEC_8(read_8(m_tmpea));
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // MOV A, @RWx
+ case 0x88: case 0x89: case 0x8a: case 0x8b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
m_icount -= 5;
break;
- // MOV A, @RWx + disp8
+ // MOV A, @RWx+
+ case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 1);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // MOV @RWx, A
+ case 0xa8: case 0xa9: case 0xaa: case 0xab:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_8(m_tmpea, m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
+ // MOV @RWx+, A
+ case 0xac: case 0xad: case 0xae: case 0xaf:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 1);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_8(m_tmpea, m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 7;
+ 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));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
m_acc <<= 16;
- m_acc |= read_8(getRWbank(operand & 7, m_tmp16));
+ m_acc |= read_8(m_tmpea);
setNZ_8(m_acc & 0xff);
m_pc += 3;
m_icount -= 5;
break;
+ // MOV A, @RWx + disp16
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOV A, @RWx + RW7
+ case 0x9c: case 0x9d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
// MOV @RWx + disp8, A
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- write_8(getRWbank(operand & 7, m_tmp16), m_acc & 0xff);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ write_8(m_tmpea, m_acc & 0xff);
setNZ_8(m_acc & 0xff);
m_pc += 3;
- m_icount -= 10;
+ m_icount -= 5;
+ break;
+
+ // MOV @RWx + disp16, A
+ case 0xb8: case 0xb9: case 0xba: case 0xbb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_8(m_tmpea, m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOV @RWx + RW7, A
+ case 0xbc: case 0xbd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ write_8(m_tmpea, m_acc & 0xff);
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // MOVX A, @RWx
+ case 0xc8: case 0xc9: case 0xca: case 0xcb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
+ // MOVX A, @RWx + disp8
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // MOVX A, @RWx + disp16
+ case 0xd8: case 0xd9: case 0xda: case 0xdb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOVX A, @RWx + RW7
+ case 0xdc: case 0xdd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_8(m_tmpea);
+ if (m_acc & 0x80)
+ {
+ m_acc |= 0xff00;
+ }
+ setNZ_8(m_acc & 0xff);
+ m_pc += 2;
+ m_icount -= 7;
break;
default:
- fatalerror("Unknown F2MC EA72 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA72 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2343,141 +3649,335 @@ void f2mc16_device::opcodes_ea73(u8 operand)
{
switch (operand)
{
+ // INCW RWx
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp16 = doINC_16(read_rwX(operand & 7));
+ write_rwX(operand & 7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // INCW @RWx
+ case 0x48: case 0x49: case 0x4a: case 0x4b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doINC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
// 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;
- m_tmp32 = read_16(getRWbank(operand & 7, m_tmp16));
- m_tmp32++;
- write_16(getRWbank(operand & 7, m_tmp16), m_tmp32 & 0xffff);
- setNZ_16(m_tmp32 & 0xffff);
- m_ps &= ~F_V;
- if (m_tmp32 & 0x10000)
- {
- m_ps |= F_V;
- }
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doINC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
m_pc += 3;
m_icount -= 5;
break;
+ // INCW @RWx + disp16
+ case 0x58: case 0x59: case 0x5a: case 0x5b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doINC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
// INCW addr16
case 0x5f:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 |= (m_prefix << 16);
+ m_tmpea |= (m_prefix << 16);
}
else
{
- m_tmp32 |= (m_dtb << 16);
- }
- m_tmp32aux = read_16(m_tmp32);
- m_tmp32aux++;
- write_16(m_tmp32, m_tmp32aux & 0xffff);
- setNZ_16(m_tmp32aux & 0xffff);
- m_ps &= ~F_V;
- if (m_tmp32aux & 0x10000)
- {
- m_ps |= F_V;
+ m_tmpea |= (m_dtb << 16);
}
+ m_rmw = true;
+ m_tmp16 = doINC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
m_pc += 4;
m_icount -= 5;
break;
+ // DECW RWx
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ m_tmp16 = doDEC_16(read_rwX(operand & 7));
+ write_rwX(operand & 7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // DECW @RWx
+ case 0x68: case 0x69: case 0x6a: case 0x6b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doDEC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 2;
+ 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_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doDEC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
m_pc += 3;
m_icount -= 5;
break;
+ // DECW @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doDEC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
// DECW addr16
case 0x7f:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
if (m_prefix_valid)
{
m_prefix_valid = false;
- m_tmp32 |= (m_prefix << 16);
+ m_tmpea |= (m_prefix << 16);
}
else
{
- m_tmp32 |= (m_dtb << 16);
- }
- m_tmp16 = read_16(m_tmp32);
- m_tmp16aux = m_tmp16;
- m_tmp16--;
- write_16(m_tmp32, m_tmp16);
- setNZ_16(m_tmp16);
- m_ps &= ~F_V;
- if ((m_tmp16aux ^ 0x0001) & (m_tmp16aux ^ m_tmp16) & 0x8000)
- {
- m_ps |= F_V;
+ m_tmpea |= (m_dtb << 16);
}
+ m_rmw = true;
+ m_tmp16 = doDEC_16(read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
m_pc += 4;
m_icount -= 5;
break;
// MOVW A, @RWx
case 0x88: case 0x89: case 0x8a: case 0x8b:
- m_tmpea = read_rwX(operand & 3);
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
m_acc <<= 16;
- m_acc |= read_16(getRWbank(operand & 3, m_tmpea));
+ m_acc |= read_16(m_tmpea);
setNZ_16(m_acc & 0xffff);
m_pc += 2;
- m_icount -= 2;
+ m_icount -= 5;
+ break;
+
+ // MOVW A, @RWx+
+ case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 2);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_16(m_tmpea);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // MOVW 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));
+ m_tmp16 = read_rwX(operand & 0x7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 0x7, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_16(m_tmpea);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // MOVW A, @RWx + disp16
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc <<= 16;
+ m_acc |= read_16(m_tmpea);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOVW @RWx, A
+ case 0xa8: case 0xa9: case 0xaa: case 0xab:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
+ // MOVW @RWx+, A
+ case 0xac: case 0xad: case 0xae: case 0xaf:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 2);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // MOVW @RWx + disp8, A
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // MOVW @RWx + disp16, A
+ case 0xb8: case 0xb9: case 0xba: case 0xbb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // MOVW @RWx + RW7, A
+ case 0xbc: case 0xbd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ write_16(m_tmpea, m_acc & 0xffff);
+ setNZ_16(m_acc & 0xffff);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // MOVW @RWx, #imm16
+ case 0xc8: case 0xc9: case 0xca: case 0xcb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmpea);
+ write_16(m_tmpea, m_tmp16);
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // MOVW @RWx+, #imm16
+ case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmpea = read_rwX(operand & 3);
+ write_rwX(operand & 3, (m_tmpea + 2) & 0xffff);
+ m_tmpea = getRWbank(operand & 3, m_tmpea);
+ write_16(m_tmpea, m_tmp16);
+ m_pc += 4;
+ m_icount -= 8;
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));
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+3));
- m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
- write_16(getRWbank(operand & 7, m_tmpea), m_tmp16);
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 3));
+ m_tmpea = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmpea);
+ write_16(m_tmpea, m_tmp16);
m_pc += 5;
- m_icount -= 4;
+ m_icount -= 6;
break;
// MOVW @RWx + disp16, #imm16
case 0xd8: case 0xd9: case 0xda: case 0xdb:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+4));
- m_tmpea = read_rwX(operand & 7) + (s16)m_tmp16;
- write_16(getRWbank(operand & 7, m_tmpea), m_tmp32 & 0xffff);
+ m_tmp16aux = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 4));
+ m_tmpea = read_rwX(operand & 3) + s16(m_tmp16aux);
+ m_tmpea = getRWbank(operand & 3, m_tmpea);
+ write_16(m_tmpea, m_tmp16);
m_pc += 6;
- m_icount -= 4;
+ m_icount -= 6;
break;
// MOVW addr16, #imm16
case 0xdf:
- m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+4));
+ m_tmpea = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 4));
if (m_prefix_valid)
{
m_prefix_valid = false;
- write_16((m_prefix<<16) | m_tmp32, m_tmp16);
+ write_16((m_prefix << 16) | m_tmpea, m_tmp16);
}
else
{
- write_16((m_dtb<<16) | m_tmp32, m_tmp16);
+ write_16((m_dtb<<16) | m_tmpea, m_tmp16);
}
m_pc += 6;
+ m_icount -= 5;
+ break;
+
+ // XCHW A, RWx
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmp16 = read_rwX(operand & 7);
+ write_rwX(operand & 7, m_acc & 0xffff);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
m_icount -= 4;
break;
+ // XCHW A, @RWx
+ case 0xe8: case 0xe9: case 0xea: case 0xeb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ write_rwX(operand & 3, m_acc & 0xffff);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // XCHW A, @RWx+
+ case 0xec: case 0xed: case 0xee: case 0xef:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, (m_tmpea + 2) & 0xffff);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ write_rwX(operand & 3, m_acc & 0xffff);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
+ m_icount -= 9;
+ break;
+
default:
- fatalerror("Unknown F2MC EA73 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA73 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2486,32 +3986,287 @@ void f2mc16_device::opcodes_ea74(u8 operand)
{
switch (operand)
{
+ // ADD A, Rx
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 = doADD_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ADD A, @RWx + disp8
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 = doADD_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // SUB A, Rx
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 = doSUB_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // SUB A, @RWx + disp8
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 = doSUB_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // ADDC A, Rx
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 = doADDC_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ADDC A, @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);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 = doADDC_8(m_acc & 0xff, m_tmp8);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp8;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // CMP A, Rx
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ doCMP_8(m_acc & 0xff, read_rX(operand & 7));
+ m_pc += 2;
+ m_icount -= 2;
+ break;
+
+ // CMP A, @RWx
+ case 0x68: case 0x69: case 0x6a: case 0x6b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ doCMP_8(m_acc & 0xff, read_8(m_tmpea));
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
+ // CMP A, @RWx+
+ case 0x6c: case 0x6d: case 0x6e: case 0x6f:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 1);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ doCMP_8(m_acc & 0xff, read_8(m_tmpea));
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
// CMP A, @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_tmp8 = read_8(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
doCMP_8(m_acc & 0xff, m_tmp8);
m_pc += 3;
- m_icount -= 10;
+ m_icount -= 5;
break;
- // DBNZ Rx, disp8
- case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
- m_tmp16 = read_rX(operand & 7);
- m_tmp16aux = m_tmp16;
- m_tmp16--;
- write_rX(operand & 7, m_tmp16 & 0xff);
- setNZ_8(m_tmp16 & 0xff);
+ // CMP A, @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ doCMP_8(m_acc & 0xff, m_tmp8);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // CMP A, @RWx + RW7
+ case 0x7c: case 0x7d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ doCMP_8(m_acc & 0xff, m_tmp8);
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // CMP A, addr16
+ case 0x7f:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
+ }
+ else
+ {
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
+ }
+ doCMP_8(m_acc & 0xff, m_tmp8);
+ m_pc += 4;
+ m_icount -= 4;
+ break;
+
+ // AND A, Rx
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
+ m_tmp32 = read_rX(operand & 7);
+ m_tmp32 |= 0xffffff00;
+ m_acc &= m_tmp32;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // AND 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));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_8(m_tmpea);
+ m_tmp32 |= 0xffffff00;
+ m_acc &= m_tmp32;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // OR A, Rx
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ m_acc |= read_rX(operand & 7);
+ setNZ_8(m_acc & 0xff);
m_ps &= ~F_V;
- if ((m_tmp16aux ^ 0x01) & (m_tmp16aux ^ m_tmp16) & 0x80)
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // OR A, @RWx
+ case 0xa8: case 0xa9: case 0xaa: case 0xab:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc |= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // OR A, @RWx + disp8
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_acc |= m_tmp8;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // OR A, addr16
+ case 0xbf:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
{
- m_ps |= F_V;
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
}
- if (m_tmp16 & 0xff)
+ else
{
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_pc = (m_pc + 3) + (s8)m_tmp8;
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
+ }
+ m_acc |= m_tmp8;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // XOR A, Rx
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_acc ^= read_rX(operand & 7);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // XOR A, @RWx
+ case 0xc8: case 0xc9: case 0xca: case 0xcb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_acc ^= read_8(m_tmpea);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // XOR A, @RWx + disp8
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ m_acc ^= m_tmp8;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 5;
+ break;
+
+ // XOR A, addr16
+ case 0xdf:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
+ }
+ else
+ {
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
+ }
+ m_acc ^= m_tmp8;
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // DBNZ Rx, disp8
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmp8 = doDEC_8(read_rX(operand & 7));
+ write_rX(operand & 7, m_tmp8);
+ if (m_tmp8 != 0)
+ {
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_pc = (m_pc + 3) + s8(m_tmp8);
m_icount -= 7;
}
else
@@ -2522,7 +4277,7 @@ void f2mc16_device::opcodes_ea74(u8 operand)
break;
default:
- fatalerror("Unknown F2MC EA74 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA74 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2531,8 +4286,251 @@ void f2mc16_device::opcodes_ea75(u8 operand)
{
switch (operand)
{
+ // ADD Rx, A
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_tmp8 = doADD_8(read_rX(operand & 7), m_acc & 0xff);
+ write_rX(operand & 7, m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ADD @RWx, A
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doADD_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 7;
+ break;
+
+ // ADD @RWx + disp8, A
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doADD_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // ADD @RWx + disp16, A
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doADD_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // SUB Rx, A
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ m_tmp8 = doSUB_8(read_rX(operand & 7), m_acc & 0xff);
+ write_rX(operand & 7, m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // SUB @RWx + disp8, A
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doSUB_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // SUB @RWx + disp16, A
+ case 0x38: case 0x39: case 0x3a: case 0x3b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doSUB_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // SUBC Rx, A
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp8 = doSUBC_8(read_rX(operand & 7), m_acc & 0xff);
+ write_rX(operand & 7, m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // SUBC @RWx + disp8, A
+ 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);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doSUBC_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // SUBC @RWx + disp16, A
+ case 0x58: case 0x59: case 0x5a: case 0x5b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = doSUBC_8(read_8(m_tmpea), m_acc & 0xff);
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // AND Rx, A
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 &= m_acc & 0xff;
+ write_rX(operand & 7, m_tmp8);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // AND @RWx + disp8, A
+ 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));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 &= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // AND @RWx + disp16, A
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 &= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // OR Rx, A
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 |= m_acc & 0xff;
+ write_rX(operand & 7, m_tmp8);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // OR @RWx + disp8, A
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 |= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // OR @RWx + disp16, A
+ case 0xb8: case 0xb9: case 0xba: case 0xbb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 |= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // XOR Rx, A
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_tmp8 = read_rX(operand & 7);
+ m_tmp8 ^= m_acc & 0xff;
+ write_rX(operand & 7, m_tmp8);
+ setNZ_8(m_acc & 0xff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // XOR @RWx + disp8, A
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 ^= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // XOR @RWx + disp16, A
+ case 0xd8: case 0xd9: case 0xda: case 0xdb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp8 = read_8(m_tmpea);
+ m_tmp8 ^= m_acc & 0xff;
+ write_8(m_tmpea, m_tmp8);
+ m_rmw = false;
+ setNZ_8(m_tmp8);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
default:
- fatalerror("Unknown F2MC EA75 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA75 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2542,7 +4540,7 @@ void f2mc16_device::opcodes_ea76(u8 operand)
switch (operand)
{
// ADDW A, RWx
- case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
m_tmp16 = doADD_16(m_acc & 0xffff, read_rwX(operand & 7));
m_acc &= 0xffff0000;
m_acc |= m_tmp16;
@@ -2550,16 +4548,73 @@ void f2mc16_device::opcodes_ea76(u8 operand)
m_icount -= 3;
break;
+ // ADDW A, @RWx
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doADD_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
// ADDW A, @RWx + disp8
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
m_tmp16aux = doADD_16(m_acc & 0xffff, m_tmp16);
m_acc &= 0xffff0000;
m_acc |= m_tmp16aux;
m_pc += 3;
- m_icount -= 3;
+ m_icount -= 6;
+ break;
+
+ // ADDW A, @RWx + disp16
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doADD_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // ADDW A, @RWx + RW7
+ case 0x1c: case 0x1d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doADD_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 2;
+ m_icount -= 8;
+ break;
+
+ // ADDW A, addr16
+ case 0x1f:
+ 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 = doADD_16(m_acc & 0xffff, m_tmp16aux);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 4;
+ m_icount -= 5;
break;
// SUBW A, RWx
@@ -2571,25 +4626,63 @@ void f2mc16_device::opcodes_ea76(u8 operand)
m_icount -= 3;
break;
+ // SUBW A, @RWx
+ case 0x28: case 0x29: case 0x2a: case 0x2b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
// SUBW A, @RWx + disp8
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16);
m_acc &= 0xffff0000;
m_acc |= m_tmp16aux;
m_pc += 3;
- m_icount -= 3;
+ m_icount -= 6;
+ break;
+
+ // SUBW A, @RWx + disp16
+ case 0x38: case 0x39: case 0x3a: case 0x3b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // SUBW A, @RWx + RW7
+ case 0x3c: case 0x3d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16);
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16aux;
+ m_pc += 2;
+ m_icount -= 8;
break;
// SUBW A, addr16
case 0x3f:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
+ 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);
+ m_tmp16aux = read_16((m_prefix << 16) | m_tmp16);
}
else
{
@@ -2599,6 +4692,15 @@ void f2mc16_device::opcodes_ea76(u8 operand)
m_acc &= 0xffff0000;
m_acc |= m_tmp16aux;
m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // ADDCW A, RWx
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp16 = doADDC_16(m_acc & 0xffff, read_rwX(operand & 7));
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
m_icount -= 3;
break;
@@ -2611,21 +4713,43 @@ void f2mc16_device::opcodes_ea76(u8 operand)
// CMPW A, @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_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
doCMP_16(m_acc & 0xffff, m_tmp16);
m_pc += 3;
- m_icount -= 10;
+ m_icount -= 5;
+ break;
+
+ // CMPW A, @RWx + disp16
+ case 0x78: case 0x79: case 0x7a: case 0x7b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ doCMP_16(m_acc & 0xffff, m_tmp16);
+ m_pc += 4;
+ m_icount -= 5;
+ break;
+
+ // CMPW A, @RWx + RW7
+ case 0x7c: case 0x7d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ doCMP_16(m_acc & 0xffff, m_tmp16);
+ m_pc += 2;
+ m_icount -= 7;
break;
// CMPW A, addr16
case 0x7f:
- m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
+ 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);
+ m_tmp16aux = read_16((m_prefix << 16) | m_tmp16);
}
else
{
@@ -2633,7 +4757,86 @@ void f2mc16_device::opcodes_ea76(u8 operand)
}
doCMP_16(m_acc & 0xffff, m_tmp16aux);
m_pc += 4;
- m_icount -= 10;
+ m_icount -= 4;
+ break;
+
+ // ANDW A, RWx
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
+ m_tmp32 = read_rwX(operand & 7);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ANDW A, @RWx
+ case 0x88: case 0x89: case 0x8a: case 0x8b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_16(m_tmpea);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // ANDW A, @RWx+
+ case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 2);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_16(m_tmpea);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
+ break;
+
+ // ANDW 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));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp32 = read_16(m_tmpea);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // ANDW A, @RWx + disp16
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp32 = read_16(m_tmpea);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // ANDW A, @RWx + RW7
+ case 0x9c: case 0x9d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp32 = read_16(m_tmpea);
+ m_tmp32 |= 0xffff0000;
+ m_acc &= m_tmp32;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
break;
// ORW A, RWx
@@ -2643,23 +4846,164 @@ void f2mc16_device::opcodes_ea76(u8 operand)
setNZ_16(m_acc & 0xffff);
m_ps &= ~F_V;
m_pc += 2;
- m_icount -= 4;
+ m_icount -= 3;
+ break;
+
+ // ORW A, @RWx
+ case 0xa8: case 0xa9: case 0xaa: case 0xab:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // ORW A, @RWx+
+ case 0xac: case 0xad: case 0xae: case 0xaf:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 2);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
break;
// ORW A, @RWx + disp8
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
m_acc |= m_tmp16;
setNZ_16(m_acc & 0xffff);
m_ps &= ~F_V;
m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // ORW A, @RWx + disp16
+ case 0xb8: case 0xb9: case 0xba: case 0xbb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // ORW A, @RWx + RW7
+ case 0xbc: case 0xbd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc |= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
+ break;
+
+ // XORW A, RWx
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_tmp16 = read_rwX(operand & 7);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
m_icount -= 3;
break;
+ // XORW A, @RWx
+ case 0xc8: case 0xc9: case 0xca: case 0xcb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // XORW A, @RWx+
+ case 0xcc: case 0xcd: case 0xce: case 0xcf:
+ m_tmp16 = read_rwX(operand & 3);
+ write_rwX(operand & 3, m_tmp16 + 2);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
+ break;
+
+ // XORW A, @RWx + disp8
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 3;
+ m_icount -= 6;
+ break;
+
+ // XORW A, @RWx + disp16
+ case 0xd8: case 0xd9: case 0xda: case 0xdb:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 4;
+ m_icount -= 6;
+ break;
+
+ // XORW A, @RWx + RW7
+ case 0xdc: case 0xdd:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ m_acc ^= m_tmp16;
+ setNZ_16(m_acc & 0xffff);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 8;
+ break;
+
+ // DWBNZ RWx, disp8
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmp16 = doDEC_16(read_rwX(operand & 7));
+ write_rwX(operand & 7, m_tmp16);
+ if (m_tmp16 != 0)
+ {
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_pc = (m_pc + 3) + s8(m_tmp8);
+ m_icount -= 7;
+ }
+ else
+ {
+ m_pc += 3;
+ m_icount -= 6;
+ }
+ break;
+
default:
- fatalerror("Unknown F2MC EA76 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA76 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2668,8 +5012,179 @@ void f2mc16_device::opcodes_ea77(u8 operand)
{
switch (operand)
{
+ // ADDW RWx, A
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_tmp16 = doADD_16(read_rwX(operand & 7), m_acc & 0xffff);
+ write_rwX(operand & 0x7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ADDW @RWx, A
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doADD_16(read_16(m_tmpea), m_acc & 0xffff);
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // SUBW RWx, A
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ m_tmp16 = doSUB_16(read_rwX(operand & 7), m_acc & 0xffff);
+ write_rwX(operand & 0x7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // SUBW @RWx, A
+ case 0x28: case 0x29: case 0x2a: case 0x2b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doSUB_16(read_16(m_tmpea), m_acc & 0xffff);
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // SUBCW A, RWx
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ m_tmp16 = doSUBC_16(m_acc & 0xffff, read_rwX(operand & 7));
+ m_acc &= 0xffff0000;
+ m_acc |= m_tmp16;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // NEGW RWx
+ case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
+ m_tmp16 = doSUB_16(0, read_rwX(operand & 7));
+ write_rwX(operand & 0x7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // NEGW @RWx
+ case 0x68: case 0x69: case 0x6a: case 0x6b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = doSUB_16(0, read_16(m_tmpea));
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // ANDW RWx, A
+ case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
+ m_tmp16 = read_rwX(operand & 7);
+ m_tmp16 &= (m_acc & 0xffff);
+ write_rwX(operand & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ANDW @RWx, A
+ case 0x88: case 0x89: case 0x8a: case 0x8b:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16 &= (m_acc & 0xffff);
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // ORW RWx, A
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ m_tmp16 = read_rwX(operand & 7);
+ m_tmp16 |= (m_acc & 0xffff);
+ write_rwX(operand & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // ORW @RWx, A
+ case 0xa8: case 0xa9: case 0xaa: case 0xab:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16 |= (m_acc & 0xffff);
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // XORW RWx, A
+ case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+ m_tmp16 = read_rwX(operand & 7);
+ m_tmp16 ^= (m_acc & 0xffff);
+ write_rwX(operand & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // XORW @RWx, A
+ case 0xc8: case 0xc9: case 0xca: case 0xcb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = read_16(m_tmpea);
+ m_tmp16 ^= (m_acc & 0xffff);
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
+ // NOTW RWx
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ m_tmp16 = read_rwX(operand & 7) ^ 0xffff;
+ write_rwX(operand & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 3;
+ break;
+
+ // NOTW @RWx
+ case 0xe8: case 0xe9: case 0xea: case 0xeb:
+ m_tmp16 = read_rwX(operand & 3);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_rmw = true;
+ m_tmp16 = read_16(m_tmpea) ^ 0xffff;
+ write_16(m_tmpea, m_tmp16);
+ m_rmw = false;
+ setNZ_16(m_tmp16);
+ m_ps &= ~F_V;
+ m_pc += 2;
+ m_icount -= 6;
+ break;
+
default:
- fatalerror("Unknown F2MC EA77 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
+ fatalerror("Unknown F2MC EA77 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
@@ -2678,6 +5193,45 @@ void f2mc16_device::opcodes_ea78(u8 operand)
{
switch (operand)
{
+ // MULU A, Rx
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ m_tmp16 = read_rX(operand & 7);
+ if (m_tmp16 == 0)
+ {
+ m_icount -= 4;
+ m_acc &= 0xffff0000;
+ }
+ else
+ {
+ m_icount -= 8;
+ m_tmp8aux = m_acc & 0xff;
+ m_acc &= 0xffff0000;
+ m_acc |= (m_tmp16 * m_tmp8aux) & 0xffff;
+ }
+ m_pc += 2;
+ break;
+
+ // MULU A, @RWx + disp8
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_8(m_tmpea);
+ if (m_tmp16 == 0)
+ {
+ m_icount -= 7;
+ m_acc &= 0xffff0000;
+ }
+ else
+ {
+ m_icount -= 11;
+ m_tmp8aux = m_acc & 0xff;
+ m_acc &= 0xffff0000;
+ m_acc |= (m_tmp16 * m_tmp8aux) & 0xffff;
+ }
+ m_pc += 3;
+ break;
+
// MULUW A, RWx
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
m_tmp16 = read_rwX(operand & 7);
@@ -2696,132 +5250,356 @@ void f2mc16_device::opcodes_ea78(u8 operand)
// MULUW A, @RWx + disp8
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
- m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
- m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ m_tmpea = getRWbank(operand & 7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
if (m_tmp16 == 0)
{
- m_icount -= 4;
+ m_icount -= 7;
m_acc = 0;
}
else
{
- m_icount -= 12;
+ m_icount -= 15;
m_acc = m_tmp16 * (m_acc & 0xffff);
}
m_pc += 3;
break;
+ // MULUW A, @RWx + disp16
+ case 0x38: case 0x39: case 0x3a: case 0x3b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ m_tmpea = getRWbank(operand & 3, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ if (m_tmp16 == 0)
+ {
+ m_icount -= 7;
+ m_acc = 0;
+ }
+ else
+ {
+ m_icount -= 15;
+ m_acc = m_tmp16 * (m_acc & 0xffff);
+ }
+ m_pc += 4;
+ break;
+
+ // MULUW A, @RWx + RW7
+ case 0x3c: case 0x3d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ m_tmpea = getRWbank(operand & 1, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ if (m_tmp16 == 0)
+ {
+ m_icount -= 9;
+ m_acc = 0;
+ }
+ else
+ {
+ m_icount -= 17;
+ m_acc = m_tmp16 * (m_acc & 0xffff);
+ }
+ m_pc += 2;
+ 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_tmp32 = m_acc / m_tmp16;
m_tmp16 = (m_acc % m_tmp16) & 0xffff;
// overflow?
- if (m_tmp32aux >= 0x10000)
+ if (m_tmp32 >= 0x10000)
{
m_ps |= F_V;
m_icount -= 7;
- m_ps |= F_V;
}
else // normal operation
{
m_acc &= ~0xffff;
- m_acc |= (m_tmp32aux & 0xffff);
+ m_acc |= (m_tmp32 & 0xffff);
write_rwX(operand & 7, m_tmp16);
m_icount -= 22;
}
}
else // divide by zero
{
+ m_ps |= (F_V|F_C);
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);
+ fatalerror("Unknown F2MC EA78 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
+ break;
+ }
+}
+
+void f2mc16_device::opcodes_rwiea79(u8 operand)
+{
+ switch (operand & 0x1f)
+ {
+ // MOVEA RWx, @RWy + disp8
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ m_tmp8 = read_8((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 7) + s8(m_tmp8);
+ write_rwX((operand>>5) & 0x7, m_tmp16);
+ m_pc += 3;
+ m_icount -= 3;
+ break;
+
+ // MOVEA RWx, @RWy + disp16
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ m_tmp16 = read_rwX(operand & 3) + s16(m_tmp16);
+ write_rwX((operand>>5) & 0x7, m_tmp16);
+ m_pc += 4;
+ m_icount -= 3;
+ break;
+
+ // MOVEA RWx, @RWy + RW7
+ case 0x1c: case 0x1d:
+ m_tmp16 = read_rwX(operand & 1) + read_rwX(7);
+ write_rwX((operand>>5) & 0x7, m_tmp16);
+ m_pc += 2;
+ m_icount -= 5;
+ break;
+
+ default:
+ fatalerror("Unknown F2MC EA79 opcode %02x (PC=%x)\n", operand, (m_pcb << 16) | m_pc);
break;
}
}
-void f2mc16_device::opcodes_rwi7a(u8 operand)
+void f2mc16_device::opcodes_riea7a(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);
+ if ((operand & 0x1f) == 0x1f)
+ {
+ // MOV Rx, addr16
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp8 = read_8((m_prefix << 16) | m_tmp16);
+ }
+ else
+ {
+ m_tmp8 = read_8((m_dtb<<16) | m_tmp16);
+ }
write_rX((operand>>5) & 0x7, m_tmp8);
setNZ_8(m_tmp8);
- m_pc += 3;
+ m_pc += 4;
m_icount -= 5;
}
+ else if (operand & 0x08)
+ {
+ fatalerror("Unknown F2MC EA7A operand %02x, PC=%02x%04x\n", operand, m_pcb, m_pc);
+ }
+ else if (operand & 0x10)
+ {
+ // MOV Rx, @RWy + disp8
+ m_tmp16 = read_rwX(operand & 7) + s8(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmpea = getRWbank(operand & 0x7, m_tmp16);
+ m_tmp8 = read_8(m_tmpea);
+ write_rX((operand >> 5) & 0x7, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 3;
+ m_icount -= 6;
+ }
else
- { // MOV Rx, Ry
+ {
+ // MOV Rx, Ry
m_tmp8 = read_rX(operand & 0x7);
- write_rX((operand>>5) & 0x7, m_tmp8);
+ write_rX((operand >> 5) & 0x7, m_tmp8);
setNZ_8(m_tmp8);
m_pc += 2;
- m_icount -= 4;
+ m_icount -= 3;
}
}
-void f2mc16_device::opcodes_rwi7b(u8 operand)
+void f2mc16_device::opcodes_rwiea7b(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);
+ if ((operand & 0x1f) == 0x1f)
+ {
+ // MOVW RWx, addr16
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ m_tmp16 = read_16((m_prefix << 16) | m_tmp16);
+ }
+ else
+ {
+ m_tmp16 = read_16((m_dtb << 16) | m_tmp16);
+ }
+ write_rwX((operand >> 5) & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_pc += 4;
+ m_icount -= 6;
+ }
+ else if (operand & 0x08)
+ {
+ fatalerror("Unknown F2MC EA7B operand %02x, PC=%02x%04x\n", operand, m_pcb, m_pc);
+ }
+ else if (operand & 0x10)
+ {
+ // MOVW RWx, @RWy + disp8
+ m_tmp16 = read_rwX(operand & 7) + s8(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmpea = getRWbank(operand & 0x7, m_tmp16);
+ m_tmp16 = read_16(m_tmpea);
+ write_rwX((operand >> 5) & 0x7, m_tmp16);
setNZ_16(m_tmp16);
m_pc += 3;
- m_icount -= 5;
+ m_icount -= 7;
}
else
- { // MOVW RWx, RWy
+ {
+ // MOVW RWx, RWy
m_tmp16 = read_rwX(operand & 0x7);
- write_rwX((operand>>5) & 0x7, m_tmp16);
+ 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)
+void f2mc16_device::opcodes_eari7c(u8 operand)
{
+ if ((operand & 0x1f) == 0x1f)
+ {
+ // MOV addr16, Rx
+ m_tmp8 = read_rX((operand >> 5) & 0x7);
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ write_8((m_prefix << 16) | m_tmp16, m_tmp8);
+ }
+ else
+ {
+ write_8((m_dtb << 16) | m_tmp16, m_tmp8);
+ }
+ setNZ_8(m_tmp8);
+ m_pc += 4;
+ m_icount -= 5;
+ }
+ else if (operand & 0x08)
+ {
+ fatalerror("Unknown F2MC EA7C operand %02x, PC=%02x%04x\n", operand, m_pcb, m_pc);
+ }
+ else if (operand & 0x10)
+ {
+ // MOV @RWx + disp8, Ry
+ m_tmp8 = read_rX((operand >> 5) & 0x7);
+ m_tmp16 = read_rwX(operand & 0x7) + s8(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmpea = getRWbank(operand & 0x7, m_tmp16);
+ write_8(m_tmpea, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 3;
+ m_icount -= 6;
+ }
+ else
+ {
+ // MOV Rx, Ry
+ m_tmp8 = read_rX((operand >> 5) & 0x7);
+ write_rX(operand & 0x7, m_tmp8);
+ setNZ_8(m_tmp8);
+ m_pc += 2;
+ m_icount -= 3;
+ }
}
-void f2mc16_device::set_irq(int vector, int level)
+void f2mc16_device::opcodes_earwi7d(u8 operand)
{
- if (m_vector_level[vector] != level)
+ if ((operand & 0x1f) == 0x1f)
+ {
+ // MOVW addr16, RWx
+ m_tmp16aux = read_rwX((operand >> 5) & 0x7);
+ m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
+ if (m_prefix_valid)
+ {
+ m_prefix_valid = false;
+ write_16((m_prefix << 16) | m_tmp16, m_tmp16aux);
+ }
+ else
+ {
+ write_16((m_dtb << 16) | m_tmp16, m_tmp16aux);
+ }
+ setNZ_16(m_tmp16aux);
+ m_pc += 4;
+ m_icount -= 5;
+ }
+ else if (operand & 0x08)
+ {
+ fatalerror("Unknown F2MC EA7D operand %02x, PC=%02x%04x\n", operand, m_pcb, m_pc);
+ }
+ else if (operand & 0x10)
+ {
+ // MOVW @RWx + disp8, RWy
+ m_tmp16aux = read_rwX((operand >> 5) & 0x7);
+ m_tmp16 = read_rwX(operand & 0x7) + s8(read_8((m_pcb << 16) | (m_pc + 2)));
+ m_tmpea = getRWbank(operand & 0x7, m_tmp16);
+ write_16(m_tmpea, m_tmp16aux);
+ setNZ_16(m_tmp16aux);
+ m_pc += 3;
+ m_icount -= 6;
+ }
+ else
{
- m_outstanding_irqs++;
- m_vector_level[vector] = level;
-// printf("set_irq: vec %d, level %d, %d outstanding\n", vector, level, m_outstanding_irqs);
+ // MOVW RWx, RWy
+ m_tmp16 = read_rwX((operand >> 5) & 0x7);
+ write_rwX(operand & 0x7, m_tmp16);
+ setNZ_16(m_tmp16);
+ m_pc += 2;
+ m_icount -= 3;
}
}
-void f2mc16_device::clear_irq(int vector)
+void f2mc16_device::opcodes_rwiea7f(u8 operand)
{
- if (m_vector_level[vector] < 7)
+ if (operand & 0x18)
{
- m_outstanding_irqs--;
- m_vector_level[vector] = 7;
- //printf("clear_irq: vec %d, %d outstanding\n", vector, m_outstanding_irqs);
+ fatalerror("Unknown F2MC EA7F operand %02x, PC=%02x%04x\n", operand, m_pcb, m_pc);
+ }
+ else
+ {
+ // XCHW RWx, RWy
+ m_tmp16 = read_rwX(operand & 0x7);
+ m_tmp16aux = read_rwX((operand>>5) & 0x7);
+ write_rwX((operand>>5) & 0x7, m_tmp16);
+ write_rwX(operand & 0x7, m_tmp16aux);
+ m_pc += 2;
+ m_icount -= 7;
}
}
-// note: this function must not use m_tmp16 unless you change RETI
-void f2mc16_device::take_irq(int vector, int level)
+void f2mc16_device::execute_set_input(int inputnum, int state)
+{
+}
+
+void f2mc16_device::set_irq_level(int irq_level)
+{
+ m_irq_level = (irq_level << 13) | 0x1fff;
+}
+
+void f2mc16_device::take_irq_vector(uint8_t irq_vector)
+{
+ take_irq();
+
+ u32 uVecAddr = 0xfffffc - (irq_vector * 4);
+ m_pc = read_16(uVecAddr);
+ m_pcb = read_8(uVecAddr + 2);
+}
+
+// note: this function must not use m_tmp8/m_tmp16
+void f2mc16_device::take_irq()
{
-// printf("take_irq: vector %d, level %d, old PC = %02x%04x\n", vector, level, m_pcb, m_pc);
push_16_ssp(m_acc>>16);
push_16_ssp(m_acc & 0xffff);
push_16_ssp((m_dpr<<8) | m_adb);
@@ -2830,11 +5608,4 @@ void f2mc16_device::take_irq(int vector, int level)
push_16_ssp(m_ps);
m_ps |= F_S;
- m_ps &= ~0xe000;
- m_ps |= (level & 7) << 13;
-
- u32 uVecAddr = 0xfffffc - (vector * 4);
- m_pc = read_16(uVecAddr);
- m_pcb = read_8(uVecAddr + 2);
- //printf("New PC = %02x%04x, new level=%d\n", m_pcb, m_pc, m_ps>>13);
}