//--------------------------------------------------------------------------- // NEOPOP : Emulator as in Dreamland // // Copyright (c) 2001-2002 by neopop_uk //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. See also the license.txt file for // additional informations. //--------------------------------------------------------------------------- /* //--------------------------------------------------------------------------- //========================================================================= TLCS900h_interpret_src.c //========================================================================= //--------------------------------------------------------------------------- History of changes: =================== 20 JUL 2002 - neopop_uk ======================================= - Cleaned and tidied up for the source release 24 JUL 2002 - neopop_uk ======================================= - Fixed S flag in "RRC (mem)" 25 JUL 2002 - neopop_uk ======================================= - Removed unneeded Long mode from EX. 28 JUL 2002 - neopop_uk ======================================= - Improved the LDIR/LDDR/CPIR/CPDR instructions so that they finish with the correct register settings, even if there is a memory error. - Converted DIV/DIVS to use the generic function 16 AUG 2002 - neopop_uk ======================================= - Replaced 'second & 7' with 'R', clearer, faster - and for some reason more accurate... oh well! - Fixed V flag emulation of INC/DEC, fixes "Cotton" menus 21 AUG 2002 - neopop_uk ======================================= - Fixed "RR (mem)" - It was actually the [REG] version that hadn't been changed to use memory accesses! 30 AUG 2002 - neopop_uk ======================================= - Fixed "DIV RR,(mem)" in long mode, wrong operand size. 04 SEP 2002 - neopop_uk ======================================= - Fixed GCC compatibility. //--------------------------------------------------------------------------- */ #include "../neopop.h" #include "TLCS900h_interpret.h" #include "TLCS900h_registers.h" #include "../mem.h" namespace TLCS900H { //========================================================================= //===== PUSH (mem) void srcPUSH() { switch(size) { case 0: push8(loadB(mem)); break; case 1: push16(loadW(mem)); break; } cycles = 7; } //===== RLD A,(mem) void srcRLD() { uint8 al = REGA & 0xF, m, mh, ml; m = loadB(mem); mh = (m & 0xF0) >> 4; ml = (m & 0x0F) << 4; REGA = (REGA & 0xF0) | mh; storeB(mem, ml | al); SETFLAG_S(REGA & 0x80); SETFLAG_Z(REGA == 0); SETFLAG_H0 SETFLAG_N0 parityB(REGA); cycles = 12; } //===== RRD A,(mem) void srcRRD() { uint8 al = (REGA & 0xF) << 4, m, mh, ml; m = loadB(mem); mh = (m & 0xF0) >> 4; ml = m & 0x0F; REGA = (REGA & 0xF0) | ml; storeB(mem, al | mh); SETFLAG_S(REGA & 0x80); SETFLAG_Z(REGA == 0); SETFLAG_H0 SETFLAG_N0 parityB(REGA); cycles = 12; } //===== LDI void srcLDI() { uint8 dst = 2/*XDE*/, src = 3/*XHL*/; if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } switch(size) { case 0: storeB(regL(dst), loadB(regL(src))); regL(dst) += 1; regL(src) += 1; break; case 1: storeW(regL(dst), loadW(regL(src))); regL(dst) += 2; regL(src) += 2; break; } REGBC --; SETFLAG_V(REGBC); SETFLAG_H0; SETFLAG_N0; cycles = 10; } //===== LDIR void srcLDIR() { uint8 dst = 2/*XDE*/, src = 3/*XHL*/; if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } cycles = 10; do { switch(size) { case 0: if (debug_abort_memory == FALSE) storeB(regL(dst), loadB(regL(src))); regL(dst) += 1; regL(src) += 1; break; case 1: if (debug_abort_memory == FALSE) storeW(regL(dst), loadW(regL(src))); regL(dst) += 2; regL(src) += 2; break; } REGBC --; SETFLAG_V(REGBC); cycles += 14; } while (FLAG_V); SETFLAG_H0; SETFLAG_N0; } //===== LDD void srcLDD() { uint8 dst = 2/*XDE*/, src = 3/*XHL*/; if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } switch(size) { case 0: storeB(regL(dst), loadB(regL(src))); regL(dst) -= 1; regL(src) -= 1; break; case 1: storeW(regL(dst), loadW(regL(src))); regL(dst) -= 2; regL(src) -= 2; break; } REGBC --; SETFLAG_V(REGBC); SETFLAG_H0; SETFLAG_N0; cycles = 10; } //===== LDDR void srcLDDR() { uint8 dst = 2/*XDE*/, src = 3/*XHL*/; if ((first & 0xF) == 5) { dst = 4/*XIX*/; src = 5/*XIY*/; } cycles = 10; do { switch(size) { case 0: if (debug_abort_memory == FALSE) storeB(regL(dst), loadB(regL(src))); regL(dst) -= 1; regL(src) -= 1; break; case 1: if (debug_abort_memory == FALSE) storeW(regL(dst), loadW(regL(src))); regL(dst) -= 2; regL(src) -= 2; break; } REGBC --; SETFLAG_V(REGBC); cycles += 14; } while (FLAG_V); SETFLAG_H0; SETFLAG_N0; } //===== CPI void srcCPI() { uint8 R = first & 7; switch(size) { case 0: generic_SUB_B(REGA, loadB(regL(R))); regL(R) ++; break; case 1: generic_SUB_W(REGWA, loadW(regL(R))); regL(R) += 2; break; } REGBC --; SETFLAG_V(REGBC); cycles = 8; } //===== CPIR void srcCPIR() { uint8 R = first & 7; cycles = 10; do { switch(size) { case 0: if (debug_abort_memory == FALSE) generic_SUB_B(REGA, loadB(regL(R))); regL(R) ++; break; case 1: if (debug_abort_memory == FALSE) generic_SUB_W(REGWA, loadW(regL(R))); regL(R) += 2; break; } REGBC --; SETFLAG_V(REGBC); cycles += 14; } while (FLAG_V && (FLAG_Z == FALSE)); } //===== CPD void srcCPD() { uint8 R = first & 7; switch(size) { case 0: generic_SUB_B(REGA, loadB(regL(R))); regL(R) --; break; case 1: generic_SUB_W(REGWA, loadW(regL(R))); regL(R) -= 2; break; } REGBC --; SETFLAG_V(REGBC); cycles = 8; } //===== CPDR void srcCPDR() { uint8 R = first & 7; cycles = 10; do { switch(size) { case 0: if (debug_abort_memory == FALSE) generic_SUB_B(REGA, loadB(regL(R))); regL(R) -= 1; break; case 1: if (debug_abort_memory == FALSE) generic_SUB_W(REGWA, loadW(regL(R))); regL(R) -= 2; break; } REGBC --; SETFLAG_V(REGBC); cycles += 14; } while (FLAG_V && (FLAG_Z == FALSE)); } //===== LD (nn),(mem) void srcLD16m() { switch(size) { case 0: storeB(fetch16(), loadB(mem)); break; case 1: storeW(fetch16(), loadW(mem)); break; } cycles = 8; } //===== LD R,(mem) void srcLD() { switch(size) { case 0: regB(R) = loadB(mem); cycles = 4; break; case 1: regW(R) = loadW(mem); cycles = 4; break; case 2: regL(R) = loadL(mem); cycles = 6; break; } } //===== EX (mem),R void srcEX() { switch(size) { case 0: { uint8 temp = regB(R); regB(R) = loadB(mem); storeB(mem, temp); break; } case 1: { uint16 temp = regW(R); regW(R) = loadW(mem); storeW(mem, temp); break; } } cycles = 6; } //===== ADD (mem),# void srcADDi() { switch(size) { case 0: storeB(mem, generic_ADD_B(loadB(mem), FETCH8)); cycles = 7;break; case 1: storeW(mem, generic_ADD_W(loadW(mem), fetch16())); cycles = 8;break; } } //===== ADC (mem),# void srcADCi() { switch(size) { case 0: storeB(mem, generic_ADC_B(loadB(mem), FETCH8)); cycles = 7;break; case 1: storeW(mem, generic_ADC_W(loadW(mem), fetch16())); cycles = 8;break; } } //===== SUB (mem),# void srcSUBi() { switch(size) { case 0: storeB(mem, generic_SUB_B(loadB(mem), FETCH8)); cycles = 7;break; case 1: storeW(mem, generic_SUB_W(loadW(mem), fetch16())); cycles = 8;break; } } //===== SBC (mem),# void srcSBCi() { switch(size) { case 0: storeB(mem, generic_SBC_B(loadB(mem), FETCH8)); cycles = 7;break; case 1: storeW(mem, generic_SBC_W(loadW(mem), fetch16())); cycles = 8;break; } } //===== AND (mem),# void srcANDi() { switch(size) { case 0: { uint8 result = loadB(mem) & FETCH8; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); cycles = 7; break; } case 1: { uint16 result = loadW(mem) & fetch16(); storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); cycles = 8; break; } } SETFLAG_H1; SETFLAG_N0; SETFLAG_C0; } //===== OR (mem),# void srcORi() { switch(size) { case 0: { uint8 result = loadB(mem) | FETCH8; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); cycles = 7; break; } case 1: { uint16 result = loadW(mem) | fetch16(); storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); cycles = 8; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== XOR (mem),# void srcXORi() { switch(size) { case 0: { uint8 result = loadB(mem) ^ FETCH8; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); cycles = 7; break; } case 1: { uint16 result = loadW(mem) ^ fetch16(); storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); cycles = 8; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== CP (mem),# void srcCPi() { switch(size) { case 0: generic_SUB_B(loadB(mem), FETCH8); break; case 1: generic_SUB_W(loadW(mem), fetch16()); break; } cycles = 6; } //===== MUL RR,(mem) void srcMUL() { uint8 target = get_RR_Target(); if (target == 0x80) { instruction_error("src: MUL bad \'RR\' dst code"); return; } switch(size) { case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * loadB(mem); cycles = 18; break; case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * loadW(mem); cycles = 26; break; } } //===== MULS RR,(mem) void srcMULS() { uint8 target = get_RR_Target(); if (target == 0x80) { instruction_error("src: MUL bad \'RR\' dst code"); return; } switch(size) { case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)loadB(mem); cycles = 18; break; case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)loadW(mem); cycles = 26; break; } } //===== DIV RR,(mem) void srcDIV() { uint8 target = get_RR_Target(); if (target == 0x80) { instruction_error("src: DIV bad \'RR\' dst code"); return; } switch(size) { case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), loadB(mem)); cycles = 22; break; } case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), loadW(mem)); cycles = 30; break; } } } //===== DIVS RR,(mem) void srcDIVS() { uint8 target = get_RR_Target(); if (target == 0x80) { instruction_error("src: DIVS bad \'RR\' dst code"); return; } switch(size) { case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), loadB(mem)); cycles = 24; break; } case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), loadW(mem)); cycles = 32; break; } } } //===== INC #3,(mem) void srcINC() { uint8 val = R; if (val == 0) val = 8; switch(size) { case 0: { uint8 dst = loadB(mem); uint32 resultC = dst + val; uint8 half = (dst & 0xF) + val; uint8 result = (uint8)(resultC & 0xFF); SETFLAG_Z(result == 0); SETFLAG_H(half > 0xF); SETFLAG_S(result & 0x80); SETFLAG_N0; if (((int8)dst >= 0) && ((int8)result < 0)) {SETFLAG_V1} else {SETFLAG_V0} storeB(mem, result); break; } case 1: { uint16 dst = loadW(mem); uint32 resultC = dst + val; uint8 half = (dst & 0xF) + val; uint16 result = (uint16)(resultC & 0xFFFF); SETFLAG_Z(result == 0); SETFLAG_H(half > 0xF); SETFLAG_S(result & 0x8000); SETFLAG_N0; if (((int16)dst >= 0) && ((int16)result < 0)) {SETFLAG_V1} else {SETFLAG_V0} storeW(mem, result); break; } } cycles = 6; } //===== DEC #3,(mem) void srcDEC() { uint8 val = R; if (val == 0) val = 8; switch(size) { case 0: { uint8 dst = loadB(mem); uint32 resultC = dst - val; uint8 half = (dst & 0xF) - val; uint8 result = (uint8)(resultC & 0xFF); SETFLAG_Z(result == 0); SETFLAG_H(half > 0xF); SETFLAG_S(result & 0x80); SETFLAG_N1; if (((int8)dst < 0) && ((int8)result >= 0)) {SETFLAG_V1} else {SETFLAG_V0} storeB(mem, result); break; } case 1: { uint16 dst = loadW(mem); uint32 resultC = dst - val; uint8 half = (dst & 0xF) - val; uint16 result = (uint16)(resultC & 0xFFFF); SETFLAG_Z(result == 0); SETFLAG_H(half > 0xF); SETFLAG_S(result & 0x8000); SETFLAG_N1; if (((int16)dst < 0) && ((int16)result >= 0)) {SETFLAG_V1} else {SETFLAG_V0} storeW(mem, result); break; } } cycles = 6; } //===== RLC (mem) void srcRLC() { switch(size) { case 0: { uint8 result = loadB(mem); SETFLAG_C(result & 0x80); result <<= 1; if (FLAG_C) result |= 1; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result = loadW(mem); SETFLAG_C(result & 0x8000); result <<= 1; if (FLAG_C) result |= 1; storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== RRC (mem) void srcRRC() { switch(size) { case 0: { uint8 data = loadB(mem), result; SETFLAG_C(data & 1); result = data >> 1; if (FLAG_C) result |= 0x80; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 data = loadW(mem), result; SETFLAG_C(data & 1); result = data >> 1; if (FLAG_C) result |= 0x8000; storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== RL (mem) void srcRL() { bool tempC; switch(size) { case 0: { uint8 result = loadB(mem); tempC = FLAG_C; SETFLAG_C(result & 0x80); result <<= 1; if (tempC) result |= 1; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result = loadW(mem); tempC = FLAG_C; SETFLAG_C(result & 0x8000); result <<= 1; if (tempC) result |= 1; storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); break; } } cycles = 8; } //===== RR (mem) void srcRR() { bool tempC; switch(size) { case 0: { uint8 result = loadB(mem); tempC = FLAG_C; SETFLAG_C(result & 1); result >>= 1; if (tempC) result |= 0x80; storeB(mem, result); SETFLAG_S(result & 0x80); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result = loadW(mem); tempC = FLAG_C; SETFLAG_C(result & 1); result >>= 1; if (tempC) result |= 0x8000; storeW(mem, result); SETFLAG_S(result & 0x8000); SETFLAG_Z(result == 0); parityW(result); break; } } cycles = 8; } //===== SLA (mem) void srcSLA() { switch(size) { case 0: { uint8 result, data = loadB(mem); SETFLAG_C(data & 0x80); result = ((int8)data << 1); SETFLAG_S(result & 0x80); storeB(mem, result); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result, data = loadW(mem); SETFLAG_C(data & 0x8000); result = ((int16)data << 1); SETFLAG_S(result & 0x8000); storeW(mem, result); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== SRA (mem) void srcSRA() { switch(size) { case 0: { uint8 result, data = loadB(mem); SETFLAG_C(data & 0x1); result = ((int8)data >> 1); SETFLAG_S(result & 0x80); storeB(mem, result); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result, data = loadW(mem); SETFLAG_C(data & 0x1); result = ((int16)data >> 1); SETFLAG_S(result & 0x8000); storeW(mem, result); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== SLL (mem) void srcSLL() { switch(size) { case 0: { uint8 result, data = loadB(mem); SETFLAG_C(data & 0x80); result = (data << 1); SETFLAG_S(result & 0x80); storeB(mem, result); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result, data = loadW(mem); SETFLAG_C(data & 0x8000); result = (data << 1); SETFLAG_S(result & 0x8000); storeW(mem, result); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== SRL (mem) void srcSRL() { switch(size) { case 0: { uint8 result, data = loadB(mem); SETFLAG_C(data & 0x01); result = (data >> 1); SETFLAG_S(result & 0x80); storeB(mem, result); SETFLAG_Z(result == 0); parityB(result); break; } case 1: { uint16 result, data = loadW(mem); SETFLAG_C(data & 0x0001); result = (data >> 1); SETFLAG_S(result & 0x8000); storeW(mem, result); SETFLAG_Z(result == 0); parityW(result); break; } } SETFLAG_H0; SETFLAG_N0; cycles = 8; } //===== ADD R,(mem) void srcADDRm() { switch(size) { case 0: regB(R) = generic_ADD_B(regB(R), loadB(mem)); cycles = 4;break; case 1: regW(R) = generic_ADD_W(regW(R), loadW(mem)); cycles = 4;break; case 2: regL(R) = generic_ADD_L(regL(R), loadL(mem)); cycles = 6;break; } } //===== ADD (mem),R void srcADDmR() { switch(size) { case 0: storeB(mem, generic_ADD_B(loadB(mem), regB(R))); cycles = 6;break; case 1: storeW(mem, generic_ADD_W(loadW(mem), regW(R))); cycles = 6;break; case 2: storeL(mem, generic_ADD_L(loadL(mem), regL(R))); cycles = 10;break; } } //===== ADC R,(mem) void srcADCRm() { switch(size) { case 0: regB(R) = generic_ADC_B(regB(R), loadB(mem)); cycles = 4;break; case 1: regW(R) = generic_ADC_W(regW(R), loadW(mem)); cycles = 4;break; case 2: regL(R) = generic_ADC_L(regL(R), loadL(mem)); cycles = 6;break; } } //===== ADC (mem),R void srcADCmR() { switch(size) { case 0: storeB(mem, generic_ADC_B(loadB(mem), regB(R))); cycles = 6;break; case 1: storeW(mem, generic_ADC_W(loadW(mem), regW(R))); cycles = 6;break; case 2: storeL(mem, generic_ADC_L(loadL(mem), regL(R))); cycles = 10;break; } } //===== SUB R,(mem) void srcSUBRm() { switch(size) { case 0: regB(R) = generic_SUB_B(regB(R), loadB(mem)); cycles = 4;break; case 1: regW(R) = generic_SUB_W(regW(R), loadW(mem)); cycles = 4;break; case 2: regL(R) = generic_SUB_L(regL(R), loadL(mem)); cycles = 6;break; } } //===== SUB (mem),R void srcSUBmR() { switch(size) { case 0: storeB(mem, generic_SUB_B(loadB(mem), regB(R))); cycles = 6;break; case 1: storeW(mem, generic_SUB_W(loadW(mem), regW(R))); cycles = 6;break; case 2: storeL(mem, generic_SUB_L(loadL(mem), regL(R))); cycles = 10;break; } } //===== SBC R,(mem) void srcSBCRm() { switch(size) { case 0: regB(R) = generic_SBC_B(regB(R), loadB(mem)); cycles = 4;break; case 1: regW(R) = generic_SBC_W(regW(R), loadW(mem)); cycles = 4;break; case 2: regL(R) = generic_SBC_L(regL(R), loadL(mem)); cycles = 6;break; } } //===== SBC (mem),R void srcSBCmR() { switch(size) { case 0: storeB(mem, generic_SBC_B(loadB(mem), regB(R))); cycles = 6;break; case 1: storeW(mem, generic_SBC_W(loadW(mem), regW(R))); cycles = 6;break; case 2: storeL(mem, generic_SBC_L(loadL(mem), regL(R))); cycles = 10;break; } } //===== AND R,(mem) void srcANDRm() { switch(size) { case 0: { uint8 result = regB(R) & loadB(mem); regB(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 4; break; } case 1: { uint16 result = regW(R) & loadW(mem); regW(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 4; break; } case 2: { uint32 result = regL(R) & loadL(mem); regL(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 6; break; } } SETFLAG_H1; SETFLAG_N0; SETFLAG_C0; } //===== AND (mem),R void srcANDmR() { switch(size) { case 0: { uint8 result = regB(R) & loadB(mem); storeB(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 6; break; } case 1: { uint16 result = regW(R) & loadW(mem); storeW(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 6; break; } case 2: { uint32 result = regL(R) & loadL(mem); storeL(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 10; break; } } SETFLAG_H1; SETFLAG_N0; SETFLAG_C0; } //===== XOR R,(mem) void srcXORRm() { switch(size) { case 0: { uint8 result = regB(R) ^ loadB(mem); regB(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 4; break; } case 1: { uint16 result = regW(R) ^ loadW(mem); regW(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 4; break; } case 2: { uint32 result = regL(R) ^ loadL(mem); regL(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 6; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== XOR (mem),R void srcXORmR() { switch(size) { case 0: { uint8 result = regB(R) ^ loadB(mem); storeB(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 6; break; } case 1: { uint16 result = regW(R) ^ loadW(mem); storeW(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 6; break; } case 2: { uint32 result = regL(R) ^ loadL(mem); storeL(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 10; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== OR R,(mem) void srcORRm() { switch(size) { case 0: { uint8 result = regB(R) | loadB(mem); regB(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 4; break; } case 1: { uint16 result = regW(R) | loadW(mem); regW(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 4; break; } case 2: { uint32 result = regL(R) | loadL(mem); regL(R) = result; SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 6; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== OR (mem),R void srcORmR() { switch(size) { case 0: { uint8 result = regB(R) | loadB(mem); storeB(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80); parityB(result); cycles = 6; break; } case 1: { uint16 result = regW(R) | loadW(mem); storeW(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x8000); parityW(result); cycles = 6; break; } case 2: { uint32 result = regL(R) | loadL(mem); storeL(mem, result); SETFLAG_Z(result == 0); SETFLAG_S(result & 0x80000000); cycles = 10; break; } } SETFLAG_H0; SETFLAG_N0; SETFLAG_C0; } //===== CP R,(mem) void srcCPRm() { switch(size) { case 0: generic_SUB_B(regB(R), loadB(mem)); cycles = 4; break; case 1: generic_SUB_W(regW(R), loadW(mem)); cycles = 4; break; case 2: generic_SUB_L(regL(R), loadL(mem)); cycles = 6; break; } } //===== CP (mem),R void srcCPmR() { switch(size) { case 0: generic_SUB_B(loadB(mem), regB(R)); break; case 1: generic_SUB_W(loadW(mem), regW(R)); break; case 2: generic_SUB_L(loadL(mem), regL(R)); break; } cycles = 6; } }; //=============================================================================