mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
added e0c6200 add,sub,rotate opcodes
This commit is contained in:
parent
15aeebbbad
commit
18056df8a2
@ -9,7 +9,8 @@
|
||||
- 1998 MF1049-01a E0C6S46 Technical Manual
|
||||
|
||||
TODO:
|
||||
- niks
|
||||
- RLC is part of the r,q opcodes and requires that r == q, what happens otherwise?
|
||||
- documentation is conflicting on whether or not the zero flag is set on RLC/RRC
|
||||
|
||||
*/
|
||||
|
||||
@ -116,6 +117,9 @@ void e0c6200_cpu_device::device_start()
|
||||
|
||||
void e0c6200_cpu_device::device_reset()
|
||||
{
|
||||
m_op = 0xff; // nop
|
||||
m_pc = 0x100;
|
||||
m_f &= 3; // decimal flag is 0 on 6200A, undefined on 6200
|
||||
}
|
||||
|
||||
|
||||
@ -143,27 +147,27 @@ void e0c6200_cpu_device::execute_one()
|
||||
{
|
||||
// JP s: jump unconditional
|
||||
case 0x000:
|
||||
m_pc = m_jpc | (m_op & 0xff);
|
||||
do_branch();
|
||||
break;
|
||||
|
||||
// JP C,s: jump if carry
|
||||
case 0x200:
|
||||
if (m_f & 1) m_pc = m_jpc | (m_op & 0xff);
|
||||
do_branch(m_f & C_FLAG);
|
||||
break;
|
||||
|
||||
// JP NC,s: jump if no carry
|
||||
case 0x300:
|
||||
if (~m_f & 1) m_pc = m_jpc | (m_op & 0xff);
|
||||
do_branch(~m_f & C_FLAG);
|
||||
break;
|
||||
|
||||
// JP Z,s: jump if zero
|
||||
case 0x600:
|
||||
if (m_f & 2) m_pc = m_jpc | (m_op & 0xff);
|
||||
do_branch(m_f & Z_FLAG);
|
||||
break;
|
||||
|
||||
// JP NZ,s: jump if not zero
|
||||
case 0x700:
|
||||
if (~m_f & 2) m_pc = m_jpc | (m_op & 0xff);
|
||||
do_branch(~m_f & Z_FLAG);
|
||||
break;
|
||||
|
||||
// CALL s: call unconditional (on current bank)
|
||||
@ -335,121 +339,121 @@ void e0c6200_cpu_device::execute_one()
|
||||
case 0xff6: write_mx(m_sp & 0xf); break;
|
||||
case 0xff7: write_my(m_sp & 0xf); break;
|
||||
|
||||
// ADD r,q
|
||||
case 0xa80:
|
||||
case 0xa81:
|
||||
case 0xa82:
|
||||
case 0xa83:
|
||||
case 0xa84:
|
||||
case 0xa85:
|
||||
case 0xa86:
|
||||
case 0xa87:
|
||||
case 0xa88:
|
||||
case 0xa89:
|
||||
case 0xa8a:
|
||||
case 0xa8b:
|
||||
case 0xa8c:
|
||||
case 0xa8d:
|
||||
case 0xa8e:
|
||||
case 0xa8f:
|
||||
// ADD r,q: add register to register (flags: C, Z)
|
||||
case 0xa80: m_a = op_add(m_a, m_a, D_FLAG); break;
|
||||
case 0xa81: m_a = op_add(m_a, m_b, D_FLAG); break;
|
||||
case 0xa82: m_a = op_add(m_a, read_mx(), D_FLAG); break;
|
||||
case 0xa83: m_a = op_add(m_a, read_my(), D_FLAG); break;
|
||||
case 0xa84: m_b = op_add(m_b, m_a, D_FLAG); break;
|
||||
case 0xa85: m_b = op_add(m_b, m_b, D_FLAG); break;
|
||||
case 0xa86: m_b = op_add(m_b, read_mx(), D_FLAG); break;
|
||||
case 0xa87: m_b = op_add(m_b, read_my(), D_FLAG); break;
|
||||
case 0xa88: write_mx(op_add(read_mx(), m_a, D_FLAG)); break;
|
||||
case 0xa89: write_mx(op_add(read_mx(), m_b, D_FLAG)); break;
|
||||
case 0xa8a: write_mx(op_add(read_mx(), read_mx(), D_FLAG)); break;
|
||||
case 0xa8b: write_mx(op_add(read_mx(), read_my(), D_FLAG)); break;
|
||||
case 0xa8c: write_my(op_add(read_my(), m_a, D_FLAG)); break;
|
||||
case 0xa8d: write_my(op_add(read_my(), m_b, D_FLAG)); break;
|
||||
case 0xa8e: write_my(op_add(read_my(), read_mx(), D_FLAG)); break;
|
||||
case 0xa8f: write_my(op_add(read_my(), read_my(), D_FLAG)); break;
|
||||
|
||||
// ADC r,q
|
||||
case 0xa90:
|
||||
case 0xa91:
|
||||
case 0xa92:
|
||||
case 0xa93:
|
||||
case 0xa94:
|
||||
case 0xa95:
|
||||
case 0xa96:
|
||||
case 0xa97:
|
||||
case 0xa98:
|
||||
case 0xa99:
|
||||
case 0xa9a:
|
||||
case 0xa9b:
|
||||
case 0xa9c:
|
||||
case 0xa9d:
|
||||
case 0xa9e:
|
||||
case 0xa9f:
|
||||
// ADC r,q: add with carry register to register (flags: C, Z)
|
||||
case 0xa90: m_a = op_adc(m_a, m_a, D_FLAG); break;
|
||||
case 0xa91: m_a = op_adc(m_a, m_b, D_FLAG); break;
|
||||
case 0xa92: m_a = op_adc(m_a, read_mx(), D_FLAG); break;
|
||||
case 0xa93: m_a = op_adc(m_a, read_my(), D_FLAG); break;
|
||||
case 0xa94: m_b = op_adc(m_b, m_a, D_FLAG); break;
|
||||
case 0xa95: m_b = op_adc(m_b, m_b, D_FLAG); break;
|
||||
case 0xa96: m_b = op_adc(m_b, read_mx(), D_FLAG); break;
|
||||
case 0xa97: m_b = op_adc(m_b, read_my(), D_FLAG); break;
|
||||
case 0xa98: write_mx(op_adc(read_mx(), m_a, D_FLAG)); break;
|
||||
case 0xa99: write_mx(op_adc(read_mx(), m_b, D_FLAG)); break;
|
||||
case 0xa9a: write_mx(op_adc(read_mx(), read_mx(), D_FLAG)); break;
|
||||
case 0xa9b: write_mx(op_adc(read_mx(), read_my(), D_FLAG)); break;
|
||||
case 0xa9c: write_my(op_adc(read_my(), m_a, D_FLAG)); break;
|
||||
case 0xa9d: write_my(op_adc(read_my(), m_b, D_FLAG)); break;
|
||||
case 0xa9e: write_my(op_adc(read_my(), read_mx(), D_FLAG)); break;
|
||||
case 0xa9f: write_my(op_adc(read_my(), read_my(), D_FLAG)); break;
|
||||
|
||||
// ACPX MX,r
|
||||
case 0xf28:
|
||||
case 0xf29:
|
||||
case 0xf2a:
|
||||
case 0xf2b:
|
||||
// ACPX MX,r: ADC MX,r, then increment X (flags: C, Z)
|
||||
case 0xf28: write_mx(op_adc(read_mx(), m_a, D_FLAG)); inc_x(); break;
|
||||
case 0xf29: write_mx(op_adc(read_mx(), m_b, D_FLAG)); inc_x(); break;
|
||||
case 0xf2a: write_mx(op_adc(read_mx(), read_mx(), D_FLAG)); inc_x(); break;
|
||||
case 0xf2b: write_mx(op_adc(read_mx(), read_my(), D_FLAG)); inc_x(); break;
|
||||
|
||||
// ACPY MY,
|
||||
case 0xf2c:
|
||||
case 0xf2d:
|
||||
case 0xf2e:
|
||||
case 0xf2f:
|
||||
// ACPY MY,r: ADC MY,r, then increment Y (flags: C, Z)
|
||||
case 0xf2c: write_my(op_adc(read_my(), m_a, D_FLAG)); inc_y(); break;
|
||||
case 0xf2d: write_my(op_adc(read_my(), m_b, D_FLAG)); inc_y(); break;
|
||||
case 0xf2e: write_my(op_adc(read_my(), read_mx(), D_FLAG)); inc_y(); break;
|
||||
case 0xf2f: write_my(op_adc(read_my(), read_my(), D_FLAG)); inc_y(); break;
|
||||
|
||||
// SUB r,q
|
||||
case 0xaa0:
|
||||
case 0xaa1:
|
||||
case 0xaa2:
|
||||
case 0xaa3:
|
||||
case 0xaa4:
|
||||
case 0xaa5:
|
||||
case 0xaa6:
|
||||
case 0xaa7:
|
||||
case 0xaa8:
|
||||
case 0xaa9:
|
||||
case 0xaaa:
|
||||
case 0xaab:
|
||||
case 0xaac:
|
||||
case 0xaad:
|
||||
case 0xaae:
|
||||
case 0xaaf:
|
||||
// SUB r,q: subtract register from register (flags: C, Z)
|
||||
case 0xaa0: m_a = op_sub(m_a, m_a, D_FLAG); break;
|
||||
case 0xaa1: m_a = op_sub(m_a, m_b, D_FLAG); break;
|
||||
case 0xaa2: m_a = op_sub(m_a, read_mx(), D_FLAG); break;
|
||||
case 0xaa3: m_a = op_sub(m_a, read_my(), D_FLAG); break;
|
||||
case 0xaa4: m_b = op_sub(m_b, m_a, D_FLAG); break;
|
||||
case 0xaa5: m_b = op_sub(m_b, m_b, D_FLAG); break;
|
||||
case 0xaa6: m_b = op_sub(m_b, read_mx(), D_FLAG); break;
|
||||
case 0xaa7: m_b = op_sub(m_b, read_my(), D_FLAG); break;
|
||||
case 0xaa8: write_mx(op_sub(read_mx(), m_a, D_FLAG)); break;
|
||||
case 0xaa9: write_mx(op_sub(read_mx(), m_b, D_FLAG)); break;
|
||||
case 0xaaa: write_mx(op_sub(read_mx(), read_mx(), D_FLAG)); break;
|
||||
case 0xaab: write_mx(op_sub(read_mx(), read_my(), D_FLAG)); break;
|
||||
case 0xaac: write_my(op_sub(read_my(), m_a, D_FLAG)); break;
|
||||
case 0xaad: write_my(op_sub(read_my(), m_b, D_FLAG)); break;
|
||||
case 0xaae: write_my(op_sub(read_my(), read_mx(), D_FLAG)); break;
|
||||
case 0xaaf: write_my(op_sub(read_my(), read_my(), D_FLAG)); break;
|
||||
|
||||
// SBC r,q
|
||||
case 0xab0:
|
||||
case 0xab1:
|
||||
case 0xab2:
|
||||
case 0xab3:
|
||||
case 0xab4:
|
||||
case 0xab5:
|
||||
case 0xab6:
|
||||
case 0xab7:
|
||||
case 0xab8:
|
||||
case 0xab9:
|
||||
case 0xaba:
|
||||
case 0xabb:
|
||||
case 0xabc:
|
||||
case 0xabd:
|
||||
case 0xabe:
|
||||
case 0xabf:
|
||||
// SBC r,q: subtract with carry register from register (flags: C, Z)
|
||||
case 0xab0: m_a = op_sbc(m_a, m_a, D_FLAG); break;
|
||||
case 0xab1: m_a = op_sbc(m_a, m_b, D_FLAG); break;
|
||||
case 0xab2: m_a = op_sbc(m_a, read_mx(), D_FLAG); break;
|
||||
case 0xab3: m_a = op_sbc(m_a, read_my(), D_FLAG); break;
|
||||
case 0xab4: m_b = op_sbc(m_b, m_a, D_FLAG); break;
|
||||
case 0xab5: m_b = op_sbc(m_b, m_b, D_FLAG); break;
|
||||
case 0xab6: m_b = op_sbc(m_b, read_mx(), D_FLAG); break;
|
||||
case 0xab7: m_b = op_sbc(m_b, read_my(), D_FLAG); break;
|
||||
case 0xab8: write_mx(op_sbc(read_mx(), m_a, D_FLAG)); break;
|
||||
case 0xab9: write_mx(op_sbc(read_mx(), m_b, D_FLAG)); break;
|
||||
case 0xaba: write_mx(op_sbc(read_mx(), read_mx(), D_FLAG)); break;
|
||||
case 0xabb: write_mx(op_sbc(read_mx(), read_my(), D_FLAG)); break;
|
||||
case 0xabc: write_my(op_sbc(read_my(), m_a, D_FLAG)); break;
|
||||
case 0xabd: write_my(op_sbc(read_my(), m_b, D_FLAG)); break;
|
||||
case 0xabe: write_my(op_sbc(read_my(), read_mx(), D_FLAG)); break;
|
||||
case 0xabf: write_my(op_sbc(read_my(), read_my(), D_FLAG)); break;
|
||||
|
||||
// SCPX MX,
|
||||
case 0xf38:
|
||||
case 0xf39:
|
||||
case 0xf3a:
|
||||
case 0xf3b:
|
||||
// SCPX MX,r: SBC MX,r, then increment X (flags: C, Z)
|
||||
case 0xf38: write_mx(op_sbc(read_mx(), m_a, D_FLAG)); inc_x(); break;
|
||||
case 0xf39: write_mx(op_sbc(read_mx(), m_b, D_FLAG)); inc_x(); break;
|
||||
case 0xf3a: write_mx(op_sbc(read_mx(), read_mx(), D_FLAG)); inc_x(); break;
|
||||
case 0xf3b: write_mx(op_sbc(read_mx(), read_my(), D_FLAG)); inc_x(); break;
|
||||
|
||||
// SCPY MY,
|
||||
case 0xf3c:
|
||||
case 0xf3d:
|
||||
case 0xf3e:
|
||||
case 0xf3f:
|
||||
// SCPY MY,r: SBC MY,r, then increment Y (flags: C, Z)
|
||||
case 0xf3c: write_my(op_sbc(read_my(), m_a, D_FLAG)); inc_y(); break;
|
||||
case 0xf3d: write_my(op_sbc(read_my(), m_b, D_FLAG)); inc_y(); break;
|
||||
case 0xf3e: write_my(op_sbc(read_my(), read_mx(), D_FLAG)); inc_y(); break;
|
||||
case 0xf3f: write_my(op_sbc(read_my(), read_my(), D_FLAG)); inc_y(); break;
|
||||
|
||||
// CP r,q: SUB r,q, but discard result (D flag has no effect)
|
||||
case 0xf00:
|
||||
case 0xf01:
|
||||
case 0xf02:
|
||||
case 0xf03:
|
||||
case 0xf04:
|
||||
case 0xf05:
|
||||
case 0xf06:
|
||||
case 0xf07:
|
||||
case 0xf08:
|
||||
case 0xf09:
|
||||
case 0xf0a:
|
||||
case 0xf0b:
|
||||
case 0xf0c:
|
||||
case 0xf0d:
|
||||
case 0xf0e:
|
||||
case 0xf0f:
|
||||
// CP r,q: compare: SUB r,q, but discard result (flags: C, Z, no D flag)
|
||||
case 0xf00: op_sub(m_a, m_a); break;
|
||||
case 0xf01: op_sub(m_a, m_b); break;
|
||||
case 0xf02: op_sub(m_a, read_mx()); break;
|
||||
case 0xf03: op_sub(m_a, read_my()); break;
|
||||
case 0xf04: op_sub(m_b, m_a); break;
|
||||
case 0xf05: op_sub(m_b, m_b); break;
|
||||
case 0xf06: op_sub(m_b, read_mx()); break;
|
||||
case 0xf07: op_sub(m_b, read_my()); break;
|
||||
case 0xf08: op_sub(read_mx(), m_a); break;
|
||||
case 0xf09: op_sub(read_mx(), m_b); break;
|
||||
case 0xf0a: op_sub(read_mx(), read_mx()); break;
|
||||
case 0xf0b: op_sub(read_mx(), read_my()); break;
|
||||
case 0xf0c: op_sub(read_my(), m_a); break;
|
||||
case 0xf0d: op_sub(read_my(), m_b); break;
|
||||
case 0xf0e: op_sub(read_my(), read_mx()); break;
|
||||
case 0xf0f: op_sub(read_my(), read_my()); break;
|
||||
|
||||
// AND r,q: logical AND register with register (affect flags: Z)
|
||||
// AND r,q: logical AND register with register (flags: Z)
|
||||
case 0xac0: m_a = op_and(m_a, m_a); break;
|
||||
case 0xac1: m_a = op_and(m_a, m_b); break;
|
||||
case 0xac2: m_a = op_and(m_a, read_mx()); break;
|
||||
@ -467,7 +471,7 @@ void e0c6200_cpu_device::execute_one()
|
||||
case 0xace: write_my(op_and(read_my(), read_mx())); break;
|
||||
case 0xacf: write_my(op_and(read_my(), read_my())); break;
|
||||
|
||||
// FAN r,q: AND r,q, but discard result
|
||||
// FAN r,q: flag-check: AND r,q, but discard result (flags: Z)
|
||||
case 0xf10: op_and(m_a, m_a); break;
|
||||
case 0xf11: op_and(m_a, m_b); break;
|
||||
case 0xf12: op_and(m_a, read_mx()); break;
|
||||
@ -485,7 +489,7 @@ void e0c6200_cpu_device::execute_one()
|
||||
case 0xf1e: op_and(read_my(), read_mx()); break;
|
||||
case 0xf1f: op_and(read_my(), read_my()); break;
|
||||
|
||||
// OR r,q: logical OR register with register (affect flags: Z)
|
||||
// OR r,q: logical OR register with register (flags: Z)
|
||||
case 0xad0: m_a = op_or(m_a, m_a); break;
|
||||
case 0xad1: m_a = op_or(m_a, m_b); break;
|
||||
case 0xad2: m_a = op_or(m_a, read_mx()); break;
|
||||
@ -503,7 +507,7 @@ void e0c6200_cpu_device::execute_one()
|
||||
case 0xade: write_my(op_or(read_my(), read_mx())); break;
|
||||
case 0xadf: write_my(op_or(read_my(), read_my())); break;
|
||||
|
||||
// XOR r,q: exclusive-OR register with register (affect flags: Z)
|
||||
// XOR r,q: exclusive-OR register with register (flags: Z)
|
||||
case 0xae0: m_a = op_xor(m_a, m_a); break;
|
||||
case 0xae1: m_a = op_xor(m_a, m_b); break;
|
||||
case 0xae2: m_a = op_xor(m_a, read_mx()); break;
|
||||
@ -521,17 +525,17 @@ void e0c6200_cpu_device::execute_one()
|
||||
case 0xaee: write_my(op_xor(read_my(), read_mx())); break;
|
||||
case 0xaef: write_my(op_xor(read_my(), read_my())); break;
|
||||
|
||||
// RLC r: rotate register left through carry (affect flags: C, Z)
|
||||
case 0xaf0:
|
||||
case 0xaf5:
|
||||
case 0xafa: read_mx();
|
||||
case 0xaff: read_my();
|
||||
// RLC r(,r): rotate register left through carry (flags: C, Z)
|
||||
case 0xaf0: m_a = op_rlc(m_a); break;
|
||||
case 0xaf5: m_b = op_rlc(m_b); break;
|
||||
case 0xafa: read_mx(); write_mx(op_rlc(read_mx())); break;
|
||||
case 0xaff: read_my(); write_my(op_rlc(read_my())); break;
|
||||
|
||||
// RRC r: rotate register right through carry (affect flags: C, Z)
|
||||
case 0xe8c:
|
||||
case 0xe8d:
|
||||
case 0xe8e:
|
||||
case 0xe8f:
|
||||
// RRC r: rotate register right through carry (flags: C, Z)
|
||||
case 0xe8c: m_a = op_rrc(m_a); break;
|
||||
case 0xe8d: m_b = op_rrc(m_b); break;
|
||||
case 0xe8e: write_mx(op_rrc(read_mx())); break;
|
||||
case 0xe8f: write_my(op_rrc(read_my())); break;
|
||||
|
||||
// INC SP: increment stackpointer
|
||||
case 0xfdb:
|
||||
@ -645,100 +649,71 @@ void e0c6200_cpu_device::execute_one()
|
||||
write_mn(m_b);
|
||||
break;
|
||||
|
||||
// INC Mn: increment memory (affect flags: C, Z)
|
||||
// INC Mn: increment memory (flags: C, Z)
|
||||
case 0xf60:
|
||||
write_mn(op_inc(read_mn()));
|
||||
break;
|
||||
|
||||
// DEC Mn: decrement memory (affect flags: C, Z)
|
||||
// DEC Mn: decrement memory (flags: C, Z)
|
||||
case 0xf70:
|
||||
write_mn(op_dec(read_mn()));
|
||||
break;
|
||||
|
||||
// ADD r,i
|
||||
case 0xc00:
|
||||
case 0xc10:
|
||||
case 0xc20:
|
||||
case 0xc30:
|
||||
// ADD r,i: add 4-bit immediate data to register (flags: C, Z)
|
||||
case 0xc00: m_a = op_add(m_a, m_op & 0xf, D_FLAG); break;
|
||||
case 0xc10: m_b = op_add(m_b, m_op & 0xf, D_FLAG); break;
|
||||
case 0xc20: write_mx(op_add(read_mx(), m_op & 0xf, D_FLAG)); break;
|
||||
case 0xc30: write_my(op_add(read_my(), m_op & 0xf, D_FLAG)); break;
|
||||
|
||||
// ADC r,i
|
||||
case 0xc40:
|
||||
case 0xc50:
|
||||
case 0xc60:
|
||||
case 0xc70:
|
||||
// ADC r,i: add with carry 4-bit immediate data to register (flags: C, Z)
|
||||
case 0xc40: m_a = op_adc(m_a, m_op & 0xf, D_FLAG); break;
|
||||
case 0xc50: m_b = op_adc(m_b, m_op & 0xf, D_FLAG); break;
|
||||
case 0xc60: write_mx(op_adc(read_mx(), m_op & 0xf, D_FLAG)); break;
|
||||
case 0xc70: write_my(op_adc(read_my(), m_op & 0xf, D_FLAG)); break;
|
||||
|
||||
// ADC Xhl/Yhl,i: add with carry 4-bit immediate data to X/Y (flags: C, Z, no D flag)
|
||||
case 0xa00: m_xh = op_adc(m_xh, m_op & 0xf); break;
|
||||
case 0xa10: m_xl = op_adc(m_xl, m_op & 0xf); break;
|
||||
case 0xa20: m_yh = op_adc(m_yh, m_op & 0xf); break;
|
||||
case 0xa30: m_yl = op_adc(m_yl, m_op & 0xf); break;
|
||||
|
||||
// ADC XH,i
|
||||
case 0xa00:
|
||||
break;
|
||||
// SBC r,i: subtract with carry 4-bit immediate data from register (flags: C, Z)
|
||||
case 0xd40: m_a = op_sbc(m_a, m_op & 0xf, D_FLAG); break;
|
||||
case 0xd50: m_b = op_sbc(m_b, m_op & 0xf, D_FLAG); break;
|
||||
case 0xd60: write_mx(op_sbc(read_mx(), m_op & 0xf, D_FLAG)); break;
|
||||
case 0xd70: write_my(op_sbc(read_my(), m_op & 0xf, D_FLAG)); break;
|
||||
|
||||
// ADC XL,i
|
||||
case 0xa10:
|
||||
break;
|
||||
// CP r,i: compare: SUB r,i, but discard result (flags: C, Z, no D flag)
|
||||
case 0xdc0: op_sub(m_a, m_op & 0xf); break;
|
||||
case 0xdd0: op_sub(m_b, m_op & 0xf); break;
|
||||
case 0xde0: op_sub(read_mx(), m_op & 0xf); break;
|
||||
case 0xdf0: op_sub(read_my(), m_op & 0xf); break;
|
||||
|
||||
// ADC YH,i
|
||||
case 0xa20:
|
||||
break;
|
||||
// CP XH,i: compare: SUB Xhl/Yhl,i, but discard result (flags: C, Z, no D flag)
|
||||
case 0xa40: op_sub(m_xh, m_op & 0xf); break;
|
||||
case 0xa50: op_sub(m_xl, m_op & 0xf); break;
|
||||
case 0xa60: op_sub(m_yh, m_op & 0xf); break;
|
||||
case 0xa70: op_sub(m_yl, m_op & 0xf); break;
|
||||
|
||||
// ADC YL,i
|
||||
case 0xa30:
|
||||
break;
|
||||
|
||||
|
||||
|
||||
// SBC r,i
|
||||
case 0xd40:
|
||||
case 0xd50:
|
||||
case 0xd60:
|
||||
case 0xd70:
|
||||
|
||||
|
||||
// CP r,i: SUB r,i, but discard result (D flag has no effect)
|
||||
case 0xdc0:
|
||||
case 0xdd0:
|
||||
case 0xde0:
|
||||
case 0xdf0:
|
||||
|
||||
|
||||
// CP XH,i
|
||||
case 0xa40:
|
||||
break;
|
||||
|
||||
// CP XL,i
|
||||
case 0xa50:
|
||||
break;
|
||||
|
||||
// CP YH,i
|
||||
case 0xa60:
|
||||
break;
|
||||
|
||||
// CP YL,i
|
||||
case 0xa70:
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// AND r,i: logical AND register with 4-bit immediate data (affect flags: Z)
|
||||
// AND r,i: logical AND register with 4-bit immediate data (flags: Z)
|
||||
case 0xc80: m_a = op_and(m_a, m_op & 0xf); break;
|
||||
case 0xc90: m_b = op_and(m_b, m_op & 0xf); break;
|
||||
case 0xca0: write_mx(op_and(read_mx(), m_op & 0xf)); break;
|
||||
case 0xcb0: write_my(op_and(read_my(), m_op & 0xf)); break;
|
||||
|
||||
// FAN r,i: AND r,i, but discard result
|
||||
// FAN r,i: flag-check: AND r,i, but discard result (flags: Z)
|
||||
case 0xd80: op_and(m_a, m_op & 0xf); break;
|
||||
case 0xd90: op_and(m_b, m_op & 0xf); break;
|
||||
case 0xda0: op_and(read_mx(), m_op & 0xf); break;
|
||||
case 0xdb0: op_and(read_my(), m_op & 0xf); break;
|
||||
|
||||
// OR r,i: logical OR register with 4-bit immediate data (affect flags: Z)
|
||||
// OR r,i: logical OR register with 4-bit immediate data (flags: Z)
|
||||
case 0xcc0: m_a = op_or(m_a, m_op & 0xf); break;
|
||||
case 0xcd0: m_b = op_or(m_b, m_op & 0xf); break;
|
||||
case 0xce0: write_mx(op_or(read_mx(), m_op & 0xf)); break;
|
||||
case 0xcf0: write_my(op_or(read_my(), m_op & 0xf)); break;
|
||||
|
||||
// XOR r,i: exclusive-OR register with 4-bit immediate data (affect flags: Z)
|
||||
// XOR r,i: exclusive-OR register with 4-bit immediate data (flags: Z)
|
||||
case 0xd00: m_a = op_xor(m_a, m_op & 0xf); break;
|
||||
case 0xd10: m_b = op_xor(m_b, m_op & 0xf); break;
|
||||
case 0xd20: write_mx(op_xor(read_mx(), m_op & 0xf)); break;
|
||||
|
@ -92,17 +92,21 @@ protected:
|
||||
inline void set_zf(UINT8 data);
|
||||
inline void inc_x();
|
||||
inline void inc_y();
|
||||
void do_branch(int condition = 0);
|
||||
|
||||
// opcode handlers
|
||||
UINT8 op_inc(UINT8 x);
|
||||
UINT8 op_dec(UINT8 x);
|
||||
UINT8 op_add(UINT8 x, UINT8 y, int decimal = 0);
|
||||
UINT8 op_adc(UINT8 x, UINT8 y, int decimal = 0);
|
||||
UINT8 op_sub(UINT8 x, UINT8 y, int decimal = 0);
|
||||
UINT8 op_sbc(UINT8 x, UINT8 y, int decimal = 0);
|
||||
|
||||
UINT8 op_and(UINT8 x, UINT8 y);
|
||||
UINT8 op_or(UINT8 x, UINT8 y);
|
||||
UINT8 op_xor(UINT8 x, UINT8 y);
|
||||
|
||||
//UINT8 op_rlc(UINT8 x);
|
||||
//UINT8 op_rrc(UINT8 x);
|
||||
UINT8 op_rlc(UINT8 x);
|
||||
UINT8 op_rrc(UINT8 x);
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
enum
|
||||
{
|
||||
FLAG_C = 1,
|
||||
FLAG_Z = 2,
|
||||
FLAG_D = 4,
|
||||
FLAG_I = 8
|
||||
C_FLAG = 1,
|
||||
Z_FLAG = 2,
|
||||
D_FLAG = 4,
|
||||
I_FLAG = 8
|
||||
};
|
||||
|
||||
|
||||
@ -86,13 +86,13 @@ inline void e0c6200_cpu_device::pop_pc()
|
||||
inline void e0c6200_cpu_device::set_cf(UINT8 data)
|
||||
{
|
||||
// set carry flag if bit 4 is set, reset otherwise
|
||||
m_f = (m_f & ~FLAG_C) | ((data & 0x10) ? FLAG_C : 0);
|
||||
m_f = (m_f & ~C_FLAG) | ((data & 0x10) ? C_FLAG : 0);
|
||||
}
|
||||
|
||||
inline void e0c6200_cpu_device::set_zf(UINT8 data)
|
||||
{
|
||||
// set zero flag if 4-bit data is 0, reset otherwise
|
||||
m_f = (m_f & ~FLAG_Z) | ((data & 0xf) ? 0 : FLAG_Z);
|
||||
m_f = (m_f & ~Z_FLAG) | ((data & 0xf) ? 0 : Z_FLAG);
|
||||
}
|
||||
|
||||
inline void e0c6200_cpu_device::inc_x()
|
||||
@ -111,15 +111,22 @@ inline void e0c6200_cpu_device::inc_y()
|
||||
m_yl &= 0xf;
|
||||
}
|
||||
|
||||
void e0c6200_cpu_device::do_branch(int condition)
|
||||
{
|
||||
// branch on condition
|
||||
if (condition)
|
||||
m_pc = m_jpc | (m_op & 0xff);
|
||||
}
|
||||
|
||||
// common opcodes
|
||||
// note: it is implied that all handled opcodes below take 7 clock cycles (5 already deducted)
|
||||
|
||||
// common opcodes (simpler ones are handled directly)
|
||||
// note: it is implied that most opcodes below take 7 clock cycles (5 already deducted)
|
||||
|
||||
// artithmetic instructions
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_inc(UINT8 x)
|
||||
{
|
||||
// INC x: increment x (affect flags: C, Z)
|
||||
// INC x: increment x (flags: C, Z)
|
||||
m_icount -= 2;
|
||||
x++;
|
||||
set_cf(x); set_zf(x);
|
||||
@ -128,19 +135,64 @@ UINT8 e0c6200_cpu_device::op_inc(UINT8 x)
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_dec(UINT8 x)
|
||||
{
|
||||
// DEC x: decrement x (affect flags: C, Z)
|
||||
// DEC x: decrement x (flags: C, Z)
|
||||
m_icount -= 2;
|
||||
x--;
|
||||
set_cf(x); set_zf(x);
|
||||
return x & 0xf;
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_add(UINT8 x, UINT8 y, int decimal)
|
||||
{
|
||||
// ADD x,y: add y to x (flags: C, Z)
|
||||
m_icount -= 2;
|
||||
x += y;
|
||||
set_cf(x);
|
||||
|
||||
// decimal correction
|
||||
if (m_f & decimal && x >= 10)
|
||||
{
|
||||
x -= 10;
|
||||
m_f |= C_FLAG;
|
||||
}
|
||||
|
||||
set_zf(x);
|
||||
return x & 0xf;
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_adc(UINT8 x, UINT8 y, int decimal)
|
||||
{
|
||||
// ADC x,y: add with carry y to x (flags: C, Z)
|
||||
return op_add(x, y + (m_f & 1), decimal);
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_sub(UINT8 x, UINT8 y, int decimal)
|
||||
{
|
||||
// SUB x,y: subtract y from x (flags: C, Z)
|
||||
m_icount -= 2;
|
||||
x -= y;
|
||||
set_cf(x);
|
||||
|
||||
// decimal correction (carry remains same)
|
||||
if (m_f & decimal && m_f & C_FLAG)
|
||||
x -= 6;
|
||||
|
||||
set_zf(x);
|
||||
return x & 0xf;
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_sbc(UINT8 x, UINT8 y, int decimal)
|
||||
{
|
||||
// SBC x,y: subtract with carry y from x (flags: C, Z)
|
||||
return op_sub(x, y + (m_f & 1), decimal);
|
||||
}
|
||||
|
||||
|
||||
// logical instructions
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_and(UINT8 x, UINT8 y)
|
||||
{
|
||||
// AND x,y: logical AND x with y (affect flags: Z)
|
||||
// AND x,y: logical AND x with y (flags: Z)
|
||||
m_icount -= 2;
|
||||
x &= y;
|
||||
set_zf(x);
|
||||
@ -149,7 +201,7 @@ UINT8 e0c6200_cpu_device::op_and(UINT8 x, UINT8 y)
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_or(UINT8 x, UINT8 y)
|
||||
{
|
||||
// OR x,y: logical OR x with y (affect flags: Z)
|
||||
// OR x,y: logical OR x with y (flags: Z)
|
||||
m_icount -= 2;
|
||||
x |= y;
|
||||
set_zf(x);
|
||||
@ -158,9 +210,29 @@ UINT8 e0c6200_cpu_device::op_or(UINT8 x, UINT8 y)
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_xor(UINT8 x, UINT8 y)
|
||||
{
|
||||
// XOR x,y: exclusive-OR x with y (affect flags: Z)
|
||||
// XOR x,y: exclusive-OR x with y (flags: Z)
|
||||
m_icount -= 2;
|
||||
x ^= y;
|
||||
set_zf(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_rlc(UINT8 x)
|
||||
{
|
||||
// RLC x: rotate x left through carry (flags: C, Z)
|
||||
m_icount -= 2;
|
||||
x = (x << 1) | (m_f & 1);
|
||||
set_cf(x); set_zf(x);
|
||||
return x & 0xf;
|
||||
}
|
||||
|
||||
UINT8 e0c6200_cpu_device::op_rrc(UINT8 x)
|
||||
{
|
||||
// RRC x: rotate x right through carry (flags: C, Z)
|
||||
// note: RRC only takes 5 clock cycles
|
||||
int c = x & 1;
|
||||
x = (x >> 1) | (m_f << 3 & 8);
|
||||
m_f = (m_f & ~C_FLAG) | c;
|
||||
set_zf(x);
|
||||
return x & 0xf;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user