BizHawk/waterbox/ngp/TLCS-900h/TLCS900h_interpret_reg.cpp

2188 lines
40 KiB
C++

//---------------------------------------------------------------------------
// 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_reg.c
//=========================================================================
//---------------------------------------------------------------------------
History of changes:
===================
20 JUL 2002 - neopop_uk
=======================================
- Cleaned and tidied up for the source release
22 JUL 2002 - neopop_uk
=======================================
- Added ANDCF,ORCF and XORCF in A mode and improved the remaining ones.
22 JUL 2002 - neopop_uk
=======================================
- Added LINK and UNLK to fix "Rockman Battle and Fighters"
23 JUL 2002 - neopop_uk
=======================================
- Added MIRR to fix "Card Fighters 2"
- Added cycle counts for TSET.
28 JUL 2002 - neopop_uk
=======================================
- Converted DIV/DIVS to use the generic function
16 AUG 2002 - neopop_uk
=======================================
- Removed all of the 'second & 7' with R as it's pre-calculated anyway.
- Fixed V flag emulation of INC/DEC, fixes "Cotton" menus
- Fixed MINC4
21 AUG 2002 - neopop_uk
=======================================
- Added TSET and MULA, both untested.
04 SEP 2002 - neopop_uk
=======================================
- Fixed GCC compatibility.
//---------------------------------------------------------------------------
*/
#include "../neopop.h"
#include "TLCS900h_interpret.h"
#include "TLCS900h_registers.h"
#include "../mem.h"
#include "../dma.h"
namespace TLCS900H
{
//=========================================================================
//===== LD r,#
void regLDi()
{
switch(size)
{
case 0: rCodeB(rCode) = FETCH8; cycles = 4; break;
case 1: rCodeW(rCode) = fetch16(); cycles = 4; break;
case 2: rCodeL(rCode) = fetch32(); cycles = 6; break;
}
}
//===== PUSH r
void regPUSH()
{
switch(size)
{
case 0: push8(rCodeB(rCode)); cycles = 5;break;
case 1: push16(rCodeW(rCode)); cycles = 5;break;
case 2: push32(rCodeL(rCode)); cycles = 7;break;
}
}
//===== POP r
void regPOP()
{
switch(size)
{
case 0: rCodeB(rCode) = pop8(); cycles = 6;break;
case 1: rCodeW(rCode) = pop16(); cycles = 6;break;
case 2: rCodeL(rCode) = pop32(); cycles = 8;break;
}
}
//===== CPL r
void regCPL()
{
switch(size)
{
case 0: rCodeB(rCode) = ~ rCodeB(rCode); break;
case 1: rCodeW(rCode) = ~ rCodeW(rCode); break;
}
SETFLAG_H1;
SETFLAG_N1;
cycles = 4;
}
//===== NEG r
void regNEG()
{
switch(size)
{
case 0: rCodeB(rCode) = generic_SUB_B(0, rCodeB(rCode)); break;
case 1: rCodeW(rCode) = generic_SUB_W(0, rCodeW(rCode)); break;
}
cycles = 5;
}
//===== MUL rr,#
void regMULi()
{
uint8 target = get_rr_Target();
if (target == 0x80)
{
#ifdef NEOPOP_DEBUG
instruction_error("reg: MULi bad \'rr\' dst code");
#endif
return;
}
switch(size)
{
case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * FETCH8;
cycles = 18; break;
case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * fetch16();
cycles = 26; break;
}
}
//===== MULS rr,#
void regMULSi()
{
uint8 target = get_rr_Target();
if (target == 0x80)
{
instruction_error("reg: MULSi bad \'rr\' dst code");
return;
}
switch(size)
{
case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)FETCH8;
cycles = 18; break;
case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)fetch16();
cycles = 26; break;
}
}
//===== DIV rr,#
void regDIVi()
{
uint8 target = get_rr_Target();
if (target == 0x80)
{
instruction_error("reg: DIVi bad \'rr\' dst code");
return;
}
switch(size)
{
case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), FETCH8);
cycles = 22;
break; }
case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), fetch16());
cycles = 30;
break; }
}
}
//===== DIVS rr,#
void regDIVSi()
{
uint8 target = get_rr_Target();
if (target == 0x80)
{
instruction_error("reg: DIVSi bad \'rr\' dst code");
return;
}
switch(size)
{
case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), FETCH8);
cycles = 24;
break; }
case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), fetch16());
cycles = 32;
break; }
}
}
//===== LINK r,dd
void regLINK()
{
int16 d = (int16)fetch16();
push32(rCodeL(rCode));
rCodeL(rCode) = REGXSP;
REGXSP += d;
cycles = 10;
}
//===== UNLK r
void regUNLK()
{
REGXSP = rCodeL(rCode);
rCodeL(rCode) = pop32();
cycles = 8;
}
//===== BS1F A,r
void regBS1F()
{
uint16 data = rCodeW(rCode), mask = 0x0001;
uint8 i;
SETFLAG_V0;
for (i = 0; i < 15; i++)
{
if (data & mask)
{
REGA = i;
return;
}
mask <<= 1;
}
SETFLAG_V1;
cycles = 4;
}
//===== BS1B A,r
void regBS1B()
{
uint16 data = rCodeW(rCode), mask = 0x8000;
uint8 i;
SETFLAG_V0;
for (i = 0; i < 15; i++)
{
if (data & mask)
{
REGA = 15 - i;
return;
}
mask >>= 1;
}
SETFLAG_V1;
cycles = 4;
}
//===== DAA r
void regDAA()
{
uint16 resultC;
uint8 src = rCodeB(rCode), result, added = 0, half;
bool setC = FALSE;
uint8 upper4 = (src & 0xF0);
uint8 lower4 = (src & 0x0F);
if (FLAG_C) // {C = 1}
{
if (FLAG_H) // {H = 1}
{
setC = TRUE;
added = 0x66;
}
else // {H = 0}
{
if (lower4 < 0x0a) { added = 0x60; }
else { added = 0x66; }
setC = TRUE;
}
}
else // {C = 0}
{
if (FLAG_H) // {H = 1}
{
if (src < 0x9A) { added = 0x06; }
else { added = 0x66; }
}
else // {H = 0}
{
if ((upper4 < 0x90) && (lower4 > 0x9)) { added = 0x06; }
else if ((upper4 > 0x80) && (lower4 > 0x9)) { added = 0x66; }
else if ((upper4 > 0x90) && (lower4 < 0xa)) { added = 0x60; }
}
}
if (FLAG_N)
{
resultC = (uint16)src - (uint16)added;
half = (src & 0xF) - (added & 0xF);
}
else
{
resultC = (uint16)src + (uint16)added;
half = (src & 0xF) + (added & 0xF);
}
result = (uint8)(resultC & 0xFF);
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
SETFLAG_H(half > 0xF);
if (FLAG_N) SETFLAG_C(result > src || setC)
else SETFLAG_C(result < src || setC)
parityB(result);
rCodeB(rCode) = result;
cycles = 6;
}
//===== EXTZ r
void regEXTZ()
{
switch(size)
{
case 1: rCodeW(rCode) &= 0xFF; break;
case 2: rCodeL(rCode) &= 0xFFFF; break;
}
cycles = 4;
}
//===== EXTS r
void regEXTS()
{
switch(size)
{
case 1: if (rCodeW(rCode) & 0x0080)
{ rCodeW(rCode) |= 0xFF00; } else
{ rCodeW(rCode) &= 0x00FF; }
break;
case 2: if (rCodeL(rCode) & 0x00008000)
{ rCodeL(rCode) |= 0xFFFF0000; } else
{ rCodeL(rCode) &= 0x0000FFFF; }
break;
}
cycles = 5;
}
//===== PAA r
void regPAA()
{
switch(size)
{
case 1: if (rCodeW(rCode) & 0x1) rCodeW(rCode)++; break;
case 2: if (rCodeL(rCode) & 0x1) rCodeL(rCode)++; break;
}
cycles = 4;
}
//===== MIRR r
void regMIRR()
{
uint16 src = rCodeW(rCode), dst = 0, bit;
//Undocumented - see p165 of CPU .PDF
//Seems to mirror bits completely, ie. 1234 -> 4321
for (bit = 0; bit < 16; bit++)
if (src & (1 << bit))
dst |= (1 << (15 - bit));
rCodeW(rCode) = dst;
cycles = 4;
}
//===== MULA rr
void regMULA()
{
uint32 src = (int16)loadW(regL(2/*XDE*/)) * (int16)loadW(regL(3/*XHL*/));
uint32 dst = rCodeL(rCode);
uint32 result = dst + src;
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
if ((((int32)dst >= 0) && ((int32)src >= 0) && ((int32)result < 0)) ||
(((int32)dst < 0) && ((int32)src < 0) && ((int32)result >= 0)))
{SETFLAG_V1} else {SETFLAG_V0}
cycles = 31;
}
//===== DJNZ r,d
void regDJNZ()
{
int8 offset = FETCH8;
cycles = 7;
switch(size)
{
case 0:
rCodeB(rCode) --;
if (rCodeB(rCode) != 0)
{
cycles = 11;
pc = pc + offset;
}
break;
case 1:
rCodeW(rCode) --;
if (rCodeW(rCode) != 0)
{
cycles = 11;
pc = pc + offset;
}
break;
}
}
//===== ANDCF #,r
void regANDCFi()
{
uint8 data, bit = FETCH8 & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C & data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C & data);
break; }
}
cycles = 4;
}
//===== ORCF #,r
void regORCFi()
{
uint8 data, bit = FETCH8 & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C | data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C | data);
break; }
}
cycles = 4;
}
//===== XORCF #,r
void regXORCFi()
{
uint8 data, bit = FETCH8 & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C ^ data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C ^ data);
break; }
}
cycles = 4;
}
//===== LDCF #,r
void regLDCFi()
{
uint8 bit = FETCH8 & 0xF;
switch(size)
{
case 0: { uint8 mask = (1 << bit);
if (bit < 8)
SETFLAG_C(rCodeB(rCode) & mask);
break; }
case 1: { uint16 mask = (1 << bit);
SETFLAG_C(rCodeW(rCode) & mask);
break; }
}
cycles = 4;
}
//===== STCF #,r
void regSTCFi()
{
uint8 bit = FETCH8 & 0xF;
switch(size)
{
case 0: { uint8 cmask = ~(1 << bit);
uint8 set = FLAG_C << bit;
if (bit < 8) rCodeB(rCode) = (rCodeB(rCode) & cmask) | set;
break; }
case 1: { uint16 cmask = ~(1 << bit);
uint16 set = FLAG_C << bit;
rCodeW(rCode) = (rCodeW(rCode) & cmask) | set;
break; }
}
cycles = 4;
}
//===== ANDCF A,r
void regANDCFA()
{
uint8 data, bit = REGA & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C & data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C & data);
break; }
}
cycles = 4;
}
//===== ORCF A,r
void regORCFA()
{
uint8 data, bit = REGA & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C | data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C | data);
break; }
}
cycles = 4;
}
//===== XORCF A,r
void regXORCFA()
{
uint8 data, bit = REGA & 0xF;
switch(size)
{
case 0: { data = (rCodeB(rCode) >> bit) & 1;
if (bit < 8) SETFLAG_C(FLAG_C ^ data);
break; }
case 1: { data = (rCodeW(rCode) >> bit) & 1;
SETFLAG_C(FLAG_C ^ data);
break; }
}
cycles = 4;
}
//===== LDCF A,r
void regLDCFA()
{
uint8 bit = REGA & 0xF;
uint32 mask = (1 << bit);
switch(size)
{
case 0: if (bit < 8) SETFLAG_C(rCodeB(rCode) & mask); break;
case 1: SETFLAG_C(rCodeW(rCode) & mask); break;
}
cycles = 4;
}
//===== STCF A,r
void regSTCFA()
{
switch(size)
{
case 0: { uint8 bit = REGA & 0xF;
uint8 cmask = ~(1 << bit);
uint8 set = FLAG_C << bit;
if (bit < 8) rCodeB(rCode) = (rCodeB(rCode) & cmask) | set;
break; }
case 1: { uint8 bit = REGA & 0xF;
uint16 cmask = ~(1 << bit);
uint16 set = FLAG_C << bit;
rCodeW(rCode) = (rCodeW(rCode) & cmask) | set;
break; }
}
cycles = 4;
}
//===== LDC cr,r
void regLDCcrr()
{
uint8 cr = FETCH8;
switch(size)
{
case 0: dmaStoreB(cr, rCodeB(rCode)); break;
case 1: dmaStoreW(cr, rCodeW(rCode)); break;
case 2: dmaStoreL(cr, rCodeL(rCode)); break;
}
cycles = 8;
}
//===== LDC r,cr
void regLDCrcr()
{
uint8 cr = FETCH8;
switch(size)
{
case 0: rCodeB(rCode) = dmaLoadB(cr); break;
case 1: rCodeW(rCode) = dmaLoadW(cr); break;
case 2: rCodeL(rCode) = dmaLoadL(cr); break;
}
cycles = 8;
}
//===== RES #,r
void regRES()
{
uint8 b = FETCH8 & 0xF;
switch(size)
{
case 0: rCodeB(rCode) &= ~(uint8)(1 << b); break;
case 1: rCodeW(rCode) &= ~(uint16)(1 << b); break;
}
cycles = 4;
}
//===== SET #,r
void regSET()
{
uint8 b = FETCH8 & 0xF;
switch(size)
{
case 0: rCodeB(rCode) |= (1 << b); break;
case 1: rCodeW(rCode) |= (1 << b); break;
}
cycles = 4;
}
//===== CHG #,r
void regCHG()
{
uint8 b = FETCH8 & 0xF;
switch(size)
{
case 0: rCodeB(rCode) ^= (1 << b); break;
case 1: rCodeW(rCode) ^= (1 << b); break;
}
cycles = 4;
}
//===== BIT #,r
void regBIT()
{
uint8 b = FETCH8 & 0xF;
switch(size)
{
case 0: SETFLAG_Z(! (rCodeB(rCode) & (1 << b)) ); break;
case 1: SETFLAG_Z(! (rCodeW(rCode) & (1 << b)) ); break;
}
SETFLAG_H1;
SETFLAG_N0;
cycles = 4;
}
//===== TSET #,r
void regTSET()
{
uint8 b = FETCH8 & 0xF;
switch(size)
{
case 0: SETFLAG_Z(! (rCodeB(rCode) & (1 << b)) );
rCodeB(rCode) |= (1 << b);
break;
case 1: SETFLAG_Z(! (rCodeW(rCode) & (1 << b)) );
rCodeW(rCode) |= (1 << b);
break;
}
SETFLAG_H1
SETFLAG_N0
cycles = 6;
}
//===== MINC1 #,r
void regMINC1()
{
uint16 num = fetch16() + 1;
if (size == 1)
{
if ((rCodeW(rCode) % num) == (num - 1))
rCodeW(rCode) -= (num - 1);
else
rCodeW(rCode) += 1;
}
cycles = 8;
}
//===== MINC2 #,r
void regMINC2()
{
uint16 num = fetch16() + 2;
if (size == 1)
{
if ((rCodeW(rCode) % num) == (num - 2))
rCodeW(rCode) -= (num - 2);
else
rCodeW(rCode) += 2;
}
cycles = 8;
}
//===== MINC4 #,r
void regMINC4()
{
uint16 num = fetch16() + 4;
if (size == 1)
{
if ((rCodeW(rCode) % num) == (num - 4))
rCodeW(rCode) -= (num - 4);
else
rCodeW(rCode) += 4;
}
cycles = 8;
}
//===== MDEC1 #,r
void regMDEC1()
{
uint16 num = fetch16() + 1;
if (size == 1)
{
if ((rCodeW(rCode) % num) == 0)
rCodeW(rCode) += (num - 1);
else
rCodeW(rCode) -= 1;
}
cycles = 7;
}
//===== MDEC2 #,r
void regMDEC2()
{
uint16 num = fetch16() + 2;
if (size == 1)
{
if ((rCodeW(rCode) % num) == 0)
rCodeW(rCode) += (num - 2);
else
rCodeW(rCode) -= 2;
}
cycles = 7;
}
//===== MDEC4 #,r
void regMDEC4()
{
uint16 num = fetch16() + 4;
if (size == 1)
{
if ((rCodeW(rCode) % num) == 0)
rCodeW(rCode) += (num - 4);
else
rCodeW(rCode) -= 4;
}
cycles = 7;
}
//===== MUL RR,r
void regMUL()
{
uint8 target = get_RR_Target();
if (target == 0x80)
{
instruction_error("reg: MUL bad \'RR\' dst code");
return;
}
switch(size)
{
case 0: rCodeW(target) = (rCodeW(target) & 0xFF) * rCodeB(rCode);
cycles = 18; break;
case 1: rCodeL(target) = (rCodeL(target) & 0xFFFF) * rCodeW(rCode);
cycles = 26; break;
}
}
//===== MULS RR,r
void regMULS()
{
uint8 target = get_RR_Target();
if (target == 0x80)
{
instruction_error("reg: MUL bad \'RR\' dst code");
return;
}
switch(size)
{
case 0: rCodeW(target) = (int8)(rCodeW(target) & 0xFF) * (int8)rCodeB(rCode);
cycles = 18; break;
case 1: rCodeL(target) = (int16)(rCodeL(target) & 0xFFFF) * (int16)rCodeW(rCode);
cycles = 26; break;
}
}
//===== DIV RR,r
void regDIV()
{
uint8 target = get_RR_Target();
if (target == 0x80)
{
instruction_error("reg: DIV bad \'RR\' dst code");
return;
}
switch(size)
{
case 0: { rCodeW(target) = generic_DIV_B(rCodeW(target), rCodeB(rCode));
cycles = 22;
break; }
case 1: { rCodeL(target) = generic_DIV_W(rCodeL(target), rCodeW(rCode));
cycles = 30;
break; }
}
}
//===== DIVS RR,r
void regDIVS()
{
uint8 target = get_RR_Target();
if (target == 0x80)
{
instruction_error("reg: DIVS bad \'RR\' dst code");
return;
}
switch(size)
{
case 0: { rCodeW(target) = generic_DIVS_B(rCodeW(target), rCodeB(rCode));
cycles = 24;
break; }
case 1: { rCodeL(target) = generic_DIVS_W(rCodeL(target), rCodeW(rCode));
cycles = 32;
break; }
}
}
//===== INC #3,r
void regINC()
{
uint8 val = R;
if (val == 0)
val = 8;
switch(size)
{
case 0: { uint8 dst = rCodeB(rCode);
uint8 half = (dst & 0xF) + val;
uint32 resultC = dst + val;
uint8 result = (uint8)(resultC & 0xFF);
SETFLAG_S(result & 0x80);
if (((int8)dst >= 0) && ((int8)result < 0))
{SETFLAG_V1} else {SETFLAG_V0}
SETFLAG_H(half > 0xF);
SETFLAG_Z(result == 0);
SETFLAG_N0;
rCodeB(rCode) = result;
break; }
case 1: { rCodeW(rCode) += val; break; }
case 2: { rCodeL(rCode) += val; break; }
}
cycles = 4;
}
//===== DEC #3,r
void regDEC()
{
uint8 val = R;
if (val == 0)
val = 8;
switch(size)
{
case 0: { uint8 dst = rCodeB(rCode);
uint8 half = (dst & 0xF) - val;
uint32 resultC = dst - val;
uint8 result = (uint8)(resultC & 0xFF);
SETFLAG_S(result & 0x80);
if (((int8)dst < 0) && ((int8)result >= 0))
{SETFLAG_V1} else {SETFLAG_V0}
SETFLAG_H(half > 0xF);
SETFLAG_Z(result == 0);
SETFLAG_N1;
rCodeB(rCode) = result;
cycles = 4;
break; }
case 1: { rCodeW(rCode) -= val; cycles = 4; break; }
case 2: { rCodeL(rCode) -= val; cycles = 5; break; }
}
}
//===== SCC cc,r
void regSCC()
{
uint32 result;
if (conditionCode(second & 0xF))
result = 1;
else
result = 0;
switch(size)
{
case 0: rCodeB(rCode) = (uint8)result; break;
case 1: rCodeW(rCode) = (uint16)result; break;
}
cycles = 6;
}
//===== LD R,r
void regLDRr()
{
switch(size)
{
case 0: regB(R) = rCodeB(rCode); break;
case 1: regW(R) = rCodeW(rCode); break;
case 2: regL(R) = rCodeL(rCode); break;
}
cycles = 4;
}
//===== LD r,R
void regLDrR()
{
switch(size)
{
case 0: rCodeB(rCode) = regB(R); break;
case 1: rCodeW(rCode) = regW(R); break;
case 2: rCodeL(rCode) = regL(R); break;
}
cycles = 4;
}
//===== ADD R,r
void regADD()
{
switch(size)
{
case 0: regB(R) = generic_ADD_B(regB(R), rCodeB(rCode)); cycles = 4; break;
case 1: regW(R) = generic_ADD_W(regW(R), rCodeW(rCode)); cycles = 4; break;
case 2: regL(R) = generic_ADD_L(regL(R), rCodeL(rCode)); cycles = 7; break;
}
}
//===== ADC R,r
void regADC()
{
switch(size)
{
case 0: regB(R) = generic_ADC_B(regB(R), rCodeB(rCode)); cycles = 4; break;
case 1: regW(R) = generic_ADC_W(regW(R), rCodeW(rCode)); cycles = 4; break;
case 2: regL(R) = generic_ADC_L(regL(R), rCodeL(rCode)); cycles = 7; break;
}
}
//===== SUB R,r
void regSUB()
{
switch(size)
{
case 0: regB(R) = generic_SUB_B(regB(R), rCodeB(rCode)); cycles = 4; break;
case 1: regW(R) = generic_SUB_W(regW(R), rCodeW(rCode)); cycles = 4; break;
case 2: regL(R) = generic_SUB_L(regL(R), rCodeL(rCode)); cycles = 7; break;
}
}
//===== SBC R,r
void regSBC()
{
switch(size)
{
case 0: regB(R) = generic_SBC_B(regB(R), rCodeB(rCode)); cycles = 4; break;
case 1: regW(R) = generic_SBC_W(regW(R), rCodeW(rCode)); cycles = 4; break;
case 2: regL(R) = generic_SBC_L(regL(R), rCodeL(rCode)); cycles = 7; break;
}
}
//===== LD r,#3
void regLDr3()
{
switch(size)
{
case 0: rCodeB(rCode) = R; break;
case 1: rCodeW(rCode) = R; break;
case 2: rCodeL(rCode) = R; break;
}
cycles = 4;
}
//===== EX R,r
void regEX()
{
switch(size)
{
case 0: { uint8 temp = regB(R); regB(R) = rCodeB(rCode); rCodeB(rCode) = temp; break;}
case 1: { uint16 temp = regW(R); regW(R) = rCodeW(rCode); rCodeW(rCode) = temp; break;}
case 2: { uint32 temp = regL(R); regL(R) = rCodeL(rCode); rCodeL(rCode) = temp; break;}
}
cycles = 5;
}
//===== ADD r,#
void regADDi()
{
switch(size)
{
case 0: rCodeB(rCode) = generic_ADD_B(rCodeB(rCode), FETCH8); cycles = 4;break;
case 1: rCodeW(rCode) = generic_ADD_W(rCodeW(rCode), fetch16()); cycles = 4;break;
case 2: rCodeL(rCode) = generic_ADD_L(rCodeL(rCode), fetch32()); cycles = 7;break;
}
}
//===== ADC r,#
void regADCi()
{
switch(size)
{
case 0: rCodeB(rCode) = generic_ADC_B(rCodeB(rCode), FETCH8); cycles = 4;break;
case 1: rCodeW(rCode) = generic_ADC_W(rCodeW(rCode), fetch16()); cycles = 4;break;
case 2: rCodeL(rCode) = generic_ADC_L(rCodeL(rCode), fetch32()); cycles = 7;break;
}
}
//===== SUB r,#
void regSUBi()
{
switch(size)
{
case 0: rCodeB(rCode) = generic_SUB_B(rCodeB(rCode), FETCH8); cycles = 4;break;
case 1: rCodeW(rCode) = generic_SUB_W(rCodeW(rCode), fetch16()); cycles = 4;break;
case 2: rCodeL(rCode) = generic_SUB_L(rCodeL(rCode), fetch32()); cycles = 7;break;
}
}
//===== SBC r,#
void regSBCi()
{
switch(size)
{
case 0: rCodeB(rCode) = generic_SBC_B(rCodeB(rCode), FETCH8); cycles = 4;break;
case 1: rCodeW(rCode) = generic_SBC_W(rCodeW(rCode), fetch16()); cycles = 4;break;
case 2: rCodeL(rCode) = generic_SBC_L(rCodeL(rCode), fetch32()); cycles = 7;break;
}
}
//===== CP r,#
void regCPi()
{
switch(size)
{
case 0: generic_SUB_B(rCodeB(rCode), FETCH8); cycles = 4;break;
case 1: generic_SUB_W(rCodeW(rCode), fetch16());cycles = 4; break;
case 2: generic_SUB_L(rCodeL(rCode), fetch32());cycles = 7; break;
}
}
//===== AND r,#
void regANDi()
{
switch(size)
{
case 0: { uint8 result = rCodeB(rCode) & FETCH8;
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
SETFLAG_S(result & 0x80);
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = rCodeW(rCode) & fetch16();
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
SETFLAG_S(result & 0x8000);
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = rCodeL(rCode) & fetch32();
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
SETFLAG_S(result & 0x80000000);
cycles = 7;
break; }
}
SETFLAG_H1;
SETFLAG_N0;
SETFLAG_C0;
}
//===== OR r,#
void regORi()
{
switch(size)
{
case 0: { uint8 result = rCodeB(rCode) | FETCH8;
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
rCodeB(rCode) = result;
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = rCodeW(rCode) | fetch16();
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
rCodeW(rCode) = result;
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = rCodeL(rCode) | fetch32();
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
rCodeL(rCode) = result;
cycles = 7;
break; }
}
SETFLAG_H0;
SETFLAG_N0;
SETFLAG_C0;
}
//===== XOR r,#
void regXORi()
{
switch(size)
{
case 0: { uint8 result = rCodeB(rCode) ^ FETCH8;
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
rCodeB(rCode) = result;
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = rCodeW(rCode) ^ fetch16();
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
rCodeW(rCode) = result;
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = rCodeL(rCode) ^ fetch32();
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
rCodeL(rCode) = result;
cycles = 7;
break; }
}
SETFLAG_H0;
SETFLAG_N0;
SETFLAG_C0;
}
//===== AND R,r
void regAND()
{
switch(size)
{
case 0: { uint8 result = regB(R) & rCodeB(rCode);
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
regB(R) = result;
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = regW(R) & rCodeW(rCode);
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
regW(R) = result;
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = regL(R) & rCodeL(rCode);
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
regL(R) = result;
cycles = 7;
break; }
}
SETFLAG_H1;
SETFLAG_N0;
SETFLAG_C0;
}
//===== OR R,r
void regOR()
{
switch(size)
{
case 0: { uint8 result = regB(R) | rCodeB(rCode);
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
regB(R) = result;
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = regW(R) | rCodeW(rCode);
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
regW(R) = result;
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = regL(R) | rCodeL(rCode);
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
regL(R) = result;
cycles = 7;
break; }
}
SETFLAG_H0;
SETFLAG_N0;
SETFLAG_C0;
}
//===== XOR R,r
void regXOR()
{
switch(size)
{
case 0: { uint8 result = regB(R) ^ rCodeB(rCode);
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
regB(R) = result;
parityB(result);
cycles = 4;
break; }
case 1: { uint16 result = regW(R) ^ rCodeW(rCode);
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
regW(R) = result;
parityW(result);
cycles = 4;
break; }
case 2: { uint32 result = regL(R) ^ rCodeL(rCode);
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
regL(R) = result;
cycles = 7;
break; }
}
SETFLAG_H0;
SETFLAG_N0;
SETFLAG_C0;
}
//===== CP r,#3
void regCPr3()
{
switch(size)
{
case 0: generic_SUB_B(rCodeB(rCode), R); break;
case 1: generic_SUB_W(rCodeW(rCode), R); break;
}
cycles = 4;
}
//===== CP R,r
void regCP()
{
switch(size)
{
case 0: generic_SUB_B(regB(R), rCodeB(rCode));cycles = 4; break;
case 1: generic_SUB_W(regW(R), rCodeW(rCode));cycles = 4; break;
case 2: generic_SUB_L(regL(R), rCodeL(rCode));cycles = 7; break;
}
}
//===== RLC #,r
void regRLCi()
{
int i;
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeB(rCode) & 0x80);
rCodeB(rCode) <<= 1;
if (FLAG_C) rCodeB(rCode) |= 1;
}
SETFLAG_S(rCodeB(rCode) & 0x80);
SETFLAG_Z(rCodeB(rCode) == 0);
parityB(rCodeB(rCode));
cycles = 6 + (2*sa);
break;
case 1: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeW(rCode) & 0x8000);
rCodeW(rCode) <<= 1;
if (FLAG_C) rCodeW(rCode) |= 1;
}
SETFLAG_S(rCodeW(rCode) & 0x8000);
SETFLAG_Z(rCodeW(rCode) == 0);
parityW(rCodeW(rCode));
cycles = 6 + (2*sa);
break;
case 2: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeL(rCode) & 0x80000000);
rCodeL(rCode) <<= 1;
if (FLAG_C) rCodeL(rCode) |= 1;
}
SETFLAG_S(rCodeL(rCode) & 0x80000000);
SETFLAG_Z(rCodeL(rCode) == 0);
cycles = 8 + (2*sa);
break;
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RRC #,r
void regRRCi()
{
int i;
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeB(rCode) & 1);
rCodeB(rCode) >>= 1;
if (FLAG_C) rCodeB(rCode) |= 0x80;
}
SETFLAG_S(rCodeB(rCode) & 0x80);
SETFLAG_Z(rCodeB(rCode) == 0);
parityB(rCodeB(rCode));
cycles = 6 + (2*sa);
break;
case 1: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeW(rCode) & 1);
rCodeW(rCode) >>= 1;
if (FLAG_C) rCodeW(rCode) |= 0x8000;
}
SETFLAG_S(rCodeW(rCode) & 0x8000);
SETFLAG_Z(rCodeW(rCode) == 0);
parityW(rCodeW(rCode));
cycles = 6 + (2*sa);
break;
case 2: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeL(rCode) & 1);
rCodeL(rCode) >>= 1;
if (FLAG_C) rCodeL(rCode) |= 0x80000000;
}
SETFLAG_S(rCodeL(rCode) & 0x80000000);
SETFLAG_Z(rCodeL(rCode) == 0);
cycles = 8 + (2*sa);
break;
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RL #,r
void regRLi()
{
int i;
bool tempC;
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: { uint8 result;
for (i = 0; i < sa; i++)
{
result = rCodeB(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x80);
result <<= 1;
if (tempC) result |= 1;
rCodeB(rCode) = result;
}
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + (2*sa);
break; }
case 1: { uint16 result;
for (i = 0; i < sa; i++)
{
result = rCodeW(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x8000);
result <<= 1;
if (tempC) result |= 1;
rCodeW(rCode) = result;
}
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + (2*sa);
break; }
case 2: { uint32 result;
for (i = 0; i < sa; i++)
{
result = rCodeL(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x80000000);
result <<= 1;
if (tempC) result |= 1;
rCodeL(rCode) = result;
}
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
cycles = 8 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RR #,r
void regRRi()
{
int i;
bool tempC;
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: { uint8 result;
for (i = 0; i < sa; i++)
{
result = rCodeB(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x80;
rCodeB(rCode) = result;
}
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityB(result);
break; }
case 1: { uint16 result;
for (i = 0; i < sa; i++)
{
result = rCodeW(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x8000;
rCodeW(rCode) = result;
}
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityW(result);
break; }
case 2: { uint32 result;
for (i = 0; i < sa; i++)
{
result = rCodeL(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x80000000;
rCodeL(rCode) = result;
}
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
cycles = 8 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SLA #,r
void regSLAi()
{
int8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { int8 result, data = (int8)rCodeB(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80);
result <<= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { int16 result, data = (int16)rCodeW(rCode);
result = (data << sa);
SETFLAG_C(result & 0x8000);
result <<= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { int32 result, data = (int32)rCodeL(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80000000);
result <<= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SRA #,r
void regSRAi()
{
int8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { int8 data = (int8)rCodeB(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { int16 data = (int16)rCodeW(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { int32 data = (int32)rCodeL(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SLL #,r
void regSLLi()
{
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { uint8 result, data = rCodeB(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80);
result <<= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { uint16 result, data = rCodeW(rCode);
result = (data << sa);
SETFLAG_C(result & 0x8000);
result <<= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { uint32 result, data = rCodeL(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80000000);
result <<= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SRL #,r
void regSRLi()
{
uint8 sa = FETCH8 & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { uint8 data = rCodeB(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { uint16 data = rCodeW(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { uint32 data = rCodeL(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RLC A,r
void regRLCA()
{
int i;
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeB(rCode) & 0x80);
rCodeB(rCode) <<= 1;
if (FLAG_C) rCodeB(rCode) |= 1;
}
SETFLAG_S(rCodeB(rCode) & 0x80);
SETFLAG_Z(rCodeB(rCode) == 0);
cycles = 6 + (2*sa);
parityB(rCodeB(rCode));
break;
case 1: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeW(rCode) & 0x8000);
rCodeW(rCode) <<= 1;
if (FLAG_C) rCodeW(rCode) |= 1;
}
SETFLAG_S(rCodeW(rCode) & 0x8000);
SETFLAG_Z(rCodeW(rCode) == 0);
cycles = 6 + (2*sa);
parityW(rCodeW(rCode));
break;
case 2: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeL(rCode) & 0x80000000);
rCodeL(rCode) <<= 1;
if (FLAG_C) rCodeL(rCode) |= 1;
}
SETFLAG_S(rCodeL(rCode) & 0x80000000);
SETFLAG_Z(rCodeL(rCode) == 0);
cycles = 8 + (2*sa);
break;
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RRC A,r
void regRRCA()
{
int i;
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeB(rCode) & 1);
rCodeB(rCode) >>= 1;
if (FLAG_C) rCodeB(rCode) |= 0x80;
}
SETFLAG_S(rCodeB(rCode) & 0x80);
SETFLAG_Z(rCodeB(rCode) == 0);
parityB(rCodeB(rCode));
cycles = 6 + (2*sa);
break;
case 1: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeW(rCode) & 1);
rCodeW(rCode) >>= 1;
if (FLAG_C) rCodeW(rCode) |= 0x8000;
}
SETFLAG_S(rCodeW(rCode) & 0x8000);
SETFLAG_Z(rCodeW(rCode) == 0);
parityW(rCodeW(rCode));
cycles = 6 + (2*sa);
break;
case 2: for (i = 0; i < sa; i++)
{
SETFLAG_C(rCodeL(rCode) & 1);
rCodeL(rCode) >>= 1;
if (FLAG_C) rCodeL(rCode) |= 0x80000000;
}
SETFLAG_S(rCodeL(rCode) & 0x80000000);
SETFLAG_Z(rCodeL(rCode) == 0);
cycles = 8 + (2*sa);
break;
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RL A,r
void regRLA()
{
int i;
bool tempC;
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: { uint8 result;
for (i = 0; i < sa; i++)
{
result = rCodeB(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x80);
result <<= 1;
if (tempC) result |= 1;
rCodeB(rCode) = result;
}
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityB(result);
break; }
case 1: { uint16 result;
for (i = 0; i < sa; i++)
{
result = rCodeW(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x8000);
result <<= 1;
if (tempC) result |= 1;
rCodeW(rCode) = result;
}
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityW(result);
break; }
case 2: { uint32 result;
for (i = 0; i < sa; i++)
{
result = rCodeL(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x80000000);
result <<= 1;
if (tempC) result |= 1;
rCodeL(rCode) = result;
}
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
cycles = 8 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== RR A,r
void regRRA()
{
int i;
bool tempC;
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
switch(size)
{
case 0: { uint8 result;
for (i = 0; i < sa; i++)
{
result = rCodeB(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x80;
rCodeB(rCode) = result;
}
SETFLAG_S(result & 0x80);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityB(result);
break; }
case 1: { uint16 result;
for (i = 0; i < sa; i++)
{
result = rCodeW(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x8000;
rCodeW(rCode) = result;
}
SETFLAG_S(result & 0x8000);
SETFLAG_Z(result == 0);
cycles = 6 + (2*sa);
parityW(result);
break; }
case 2: { uint32 result;
for (i = 0; i < sa; i++)
{
result = rCodeL(rCode);
tempC = FLAG_C;
SETFLAG_C(result & 0x01);
result >>= 1;
if (tempC) result |= 0x80000000;
rCodeL(rCode) = result;
}
SETFLAG_S(result & 0x80000000);
SETFLAG_Z(result == 0);
cycles = 8 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SLA A,r
void regSLAA()
{
int8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { int8 result, data = (int8)rCodeB(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80);
result <<= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { int16 result, data = (int16)rCodeW(rCode);
result = (data << sa);
SETFLAG_C(result & 0x8000);
result <<= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { int32 result, data = (int32)rCodeL(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80000000);
result <<= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SRA A,r
void regSRAA()
{
int8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { int8 data = (int8)rCodeB(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { int16 data = (int16)rCodeW(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { int32 data = (int32)rCodeL(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SLL A,r
void regSLLA()
{
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { uint8 result, data = rCodeB(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80);
result <<= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { uint16 result, data = rCodeW(rCode);
result = (data << sa);
SETFLAG_C(result & 0x8000);
result <<= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { uint32 result, data = rCodeL(rCode);
result = (data << sa);
SETFLAG_C(result & 0x80000000);
result <<= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
//===== SRL A,r
void regSRLA()
{
uint8 sa = REGA & 0xF;
if (sa == 0) sa = 16;
sa--;
switch(size)
{
case 0: { uint8 data = rCodeB(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80);
rCodeB(rCode) = result;
SETFLAG_Z(result == 0);
parityB(result);
cycles = 6 + 2 + (2*sa);
break; }
case 1: { uint16 data = rCodeW(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x8000);
rCodeW(rCode) = result;
SETFLAG_Z(result == 0);
parityW(result);
cycles = 6 + 2 + (2*sa);
break; }
case 2: { uint32 data = rCodeL(rCode), result;
result = (data >> sa);
SETFLAG_C(result & 1);
result >>= 1;
SETFLAG_S(result & 0x80000000);
rCodeL(rCode) = result;
SETFLAG_Z(result == 0);
cycles = 8 + 2 + (2*sa);
break; }
}
SETFLAG_H0;
SETFLAG_N0;
}
};
//=============================================================================