mirror of
https://github.com/libretro/RACE.git
synced 2024-11-27 11:00:21 +00:00
824 lines
17 KiB
C++
824 lines
17 KiB
C++
/********************************************************************************/
|
|
/* */
|
|
/* CZ80 ED opcode include source file */
|
|
/* C Z80 emulator version 0.92 */
|
|
/* Copyright 2004-2005 Stéphane Dallongeville */
|
|
/* */
|
|
/********************************************************************************/
|
|
|
|
#if CZ80_USE_JUMPTABLE
|
|
goto *JumpTableED[Opcode];
|
|
#else
|
|
switch (Opcode)
|
|
{
|
|
#endif
|
|
|
|
// ILLEGAL
|
|
|
|
OPED(0x00):
|
|
OPED(0x01):
|
|
OPED(0x02):
|
|
OPED(0x03):
|
|
OPED(0x04):
|
|
OPED(0x05):
|
|
OPED(0x06):
|
|
OPED(0x07):
|
|
OPED(0x08):
|
|
OPED(0x09):
|
|
OPED(0x0a):
|
|
OPED(0x0b):
|
|
OPED(0x0c):
|
|
OPED(0x0d):
|
|
OPED(0x0e):
|
|
OPED(0x0f):
|
|
OPED(0x10):
|
|
OPED(0x11):
|
|
OPED(0x12):
|
|
OPED(0x13):
|
|
OPED(0x14):
|
|
OPED(0x15):
|
|
OPED(0x16):
|
|
OPED(0x17):
|
|
OPED(0x18):
|
|
OPED(0x19):
|
|
OPED(0x1a):
|
|
OPED(0x1b):
|
|
OPED(0x1c):
|
|
OPED(0x1d):
|
|
OPED(0x1e):
|
|
OPED(0x1f):
|
|
OPED(0x20):
|
|
OPED(0x21):
|
|
OPED(0x22):
|
|
OPED(0x23):
|
|
OPED(0x24):
|
|
OPED(0x25):
|
|
OPED(0x26):
|
|
OPED(0x27):
|
|
OPED(0x28):
|
|
OPED(0x29):
|
|
OPED(0x2a):
|
|
OPED(0x2b):
|
|
OPED(0x2c):
|
|
OPED(0x2d):
|
|
OPED(0x2e):
|
|
OPED(0x2f):
|
|
OPED(0x30):
|
|
OPED(0x31):
|
|
OPED(0x32):
|
|
OPED(0x33):
|
|
OPED(0x34):
|
|
OPED(0x35):
|
|
OPED(0x36):
|
|
OPED(0x37):
|
|
OPED(0x38):
|
|
OPED(0x39):
|
|
OPED(0x3a):
|
|
OPED(0x3b):
|
|
OPED(0x3c):
|
|
OPED(0x3d):
|
|
OPED(0x3e):
|
|
OPED(0x3f):
|
|
OPED(0xbc):
|
|
OPED(0xbd):
|
|
OPED(0xbe):
|
|
OPED(0xbf):
|
|
OPED(0xc0):
|
|
OPED(0xc1):
|
|
OPED(0xc2):
|
|
OPED(0xc3):
|
|
OPED(0xc4):
|
|
OPED(0xc5):
|
|
OPED(0xc6):
|
|
OPED(0xc7):
|
|
OPED(0xc8):
|
|
OPED(0xc9):
|
|
OPED(0xca):
|
|
OPED(0xcb):
|
|
OPED(0xcc):
|
|
OPED(0xcd):
|
|
OPED(0xce):
|
|
OPED(0xcf):
|
|
OPED(0xd0):
|
|
OPED(0xd1):
|
|
OPED(0xd2):
|
|
OPED(0xd3):
|
|
OPED(0xd4):
|
|
OPED(0xd5):
|
|
OPED(0xd6):
|
|
OPED(0xd7):
|
|
OPED(0xd8):
|
|
OPED(0xd9):
|
|
OPED(0xda):
|
|
OPED(0xdb):
|
|
OPED(0xdc):
|
|
OPED(0xdd):
|
|
OPED(0xde):
|
|
OPED(0xdf):
|
|
OPED(0xe0):
|
|
OPED(0xe1):
|
|
OPED(0xe2):
|
|
OPED(0xe3):
|
|
OPED(0xe4):
|
|
OPED(0xe5):
|
|
OPED(0xe6):
|
|
OPED(0xe7):
|
|
OPED(0xe8):
|
|
OPED(0xe9):
|
|
OPED(0xea):
|
|
OPED(0xeb):
|
|
OPED(0xec):
|
|
OPED(0xed):
|
|
OPED(0xee):
|
|
OPED(0xef):
|
|
OPED(0xf0):
|
|
OPED(0xf1):
|
|
OPED(0xf2):
|
|
OPED(0xf3):
|
|
OPED(0xf4):
|
|
OPED(0xf5):
|
|
OPED(0xf6):
|
|
OPED(0xf7):
|
|
OPED(0xf8):
|
|
OPED(0xf9):
|
|
OPED(0xfa):
|
|
OPED(0xfb):
|
|
OPED(0xfc):
|
|
OPED(0xfd):
|
|
OPED(0xfe):
|
|
OPED(0xff):
|
|
OPED(0x77):
|
|
OPED(0x7f):
|
|
OPED(0x80):
|
|
OPED(0x81):
|
|
OPED(0x82):
|
|
OPED(0x83):
|
|
OPED(0x84):
|
|
OPED(0x85):
|
|
OPED(0x86):
|
|
OPED(0x87):
|
|
OPED(0x88):
|
|
OPED(0x89):
|
|
OPED(0x8a):
|
|
OPED(0x8b):
|
|
OPED(0x8c):
|
|
OPED(0x8d):
|
|
OPED(0x8e):
|
|
OPED(0x8f):
|
|
OPED(0x90):
|
|
OPED(0x91):
|
|
OPED(0x92):
|
|
OPED(0x93):
|
|
OPED(0x94):
|
|
OPED(0x95):
|
|
OPED(0x96):
|
|
OPED(0x97):
|
|
OPED(0x98):
|
|
OPED(0x99):
|
|
OPED(0x9a):
|
|
OPED(0x9b):
|
|
OPED(0x9c):
|
|
OPED(0x9d):
|
|
OPED(0x9e):
|
|
OPED(0x9f):
|
|
OPED(0xa4):
|
|
OPED(0xa5):
|
|
OPED(0xa6):
|
|
OPED(0xa7):
|
|
OPED(0xac):
|
|
OPED(0xad):
|
|
OPED(0xae):
|
|
OPED(0xaf):
|
|
OPED(0xb4):
|
|
OPED(0xb5):
|
|
OPED(0xb6):
|
|
OPED(0xb7):
|
|
goto OP_NOP;
|
|
|
|
OPED(0x43): // LD (w),BC
|
|
data = pzBC;
|
|
goto OP_LD_mNN_xx;
|
|
|
|
OPED(0x53): // LD (w),DE
|
|
data = pzDE;
|
|
goto OP_LD_mNN_xx;
|
|
|
|
OPED(0x63): // LD (w),HL
|
|
data = pzHL;
|
|
goto OP_LD_mNN_xx;
|
|
|
|
OPED(0x73): // LD (w),SP
|
|
data = pzSP;
|
|
goto OP_LD_mNN_xx;
|
|
|
|
OPED(0x4b): // LD BC,(w)
|
|
data = pzBC;
|
|
goto OP_LD_xx_mNN;
|
|
|
|
OPED(0x5b): // LD DE,(w)
|
|
data = pzDE;
|
|
goto OP_LD_xx_mNN;
|
|
|
|
OPED(0x6b): // LD HL,(w)
|
|
data = pzHL;
|
|
goto OP_LD_xx_mNN;
|
|
|
|
OPED(0x7b): // LD SP,(w)
|
|
data = pzSP;
|
|
goto OP_LD_xx_mNN;
|
|
|
|
|
|
OPED(0x47): // LD I,A
|
|
zI = zA;
|
|
RET(5)
|
|
|
|
OPED(0x4f): // LD R,A
|
|
zR = zA - ((CPU->CycleToDo - Z80_ICount) / 4);
|
|
zR2 = zA & 0x80;
|
|
RET(5)
|
|
|
|
OPED(0x57): // LD A,I
|
|
{
|
|
u8 F;
|
|
|
|
zA = zI;
|
|
F = zF & CZ80_CF;
|
|
F |= zA & (CZ80_SF | CZ80_YF | CZ80_XF);
|
|
F |= zIFF2;
|
|
if (!zA) F |= CZ80_ZF;
|
|
zF = F;
|
|
RET(5)
|
|
}
|
|
|
|
OPED(0x5f): // LD A,R
|
|
{
|
|
u8 F;
|
|
|
|
zA = zR2 + ((zR + ((CPU->CycleToDo - Z80_ICount) / 4)) & 0x7F);
|
|
F = zF & CZ80_CF;
|
|
F |= zA & (CZ80_SF | CZ80_YF | CZ80_XF);
|
|
F |= zIFF2;
|
|
if (!zA) F |= CZ80_ZF;
|
|
zF = F;
|
|
RET(5)
|
|
}
|
|
|
|
OPED(0x5c): // NEG
|
|
OPED(0x54): // NEG
|
|
OPED(0x4c): // NEG
|
|
OPED(0x44): // NEG
|
|
OPED(0x64): // NEG
|
|
OPED(0x6c): // NEG
|
|
OPED(0x74): // NEG
|
|
OPED(0x7c): // NEG
|
|
{
|
|
u32 val;
|
|
u32 res;
|
|
|
|
val = zA;
|
|
res = 0 - val;
|
|
zF = SZXY[res & 0xFF] | // S/Z/X/Y flag
|
|
((res ^ val) & CZ80_HF) | // H flag
|
|
(((val & res) & 0x80) >> 5) | // V flag
|
|
((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag
|
|
zA = res;
|
|
RET(4)
|
|
}
|
|
|
|
|
|
OPED(0x67): // RRD (HL)
|
|
{
|
|
u32 adr;
|
|
u8 src;
|
|
|
|
PRE_IO
|
|
adr = zHL;
|
|
READ_BYTE(adr, src)
|
|
WRITE_BYTE(adr, (src >> 4) | (zA << 4))
|
|
zA = (zA & 0xF0) | (src & 0x0F);
|
|
zF = SZXYP[zA] | (zF & CZ80_CF);
|
|
POST_IO
|
|
RET(14)
|
|
}
|
|
|
|
OPED(0x6f): // RLD (HL)
|
|
{
|
|
u32 adr;
|
|
u8 src;
|
|
|
|
PRE_IO
|
|
adr = zHL;
|
|
READ_BYTE(adr, src)
|
|
WRITE_BYTE(adr, (src << 4) | (zA & 0x0F))
|
|
zA = (zA & 0xF0) | (src >> 4);
|
|
zF = SZXYP[zA] | (zF & CZ80_CF);
|
|
POST_IO
|
|
RET(14)
|
|
}
|
|
|
|
|
|
{
|
|
u32 src;
|
|
u32 res;
|
|
|
|
OPED(0x7a): // ADC HL,SP
|
|
src = zSP;
|
|
goto OP_ADC_HL;
|
|
|
|
OPED(0x4a): // ADC HL,BC
|
|
OPED(0x5a): // ADC HL,DE
|
|
OPED(0x6a): // ADC HL,HL
|
|
src = zR16((Opcode >> 4) & 3);
|
|
|
|
OP_ADC_HL:
|
|
res = zHL + src + (zF & CZ80_CF);
|
|
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | // H flag
|
|
(((src ^ zHL ^ 0x8000) & (src ^ res) & 0x8000) >> 13) | // V flag
|
|
((res >> 8) & (CZ80_SF | CZ80_XF | CZ80_YF)) | // S/X/Y flag
|
|
((res >> 16) & CZ80_CF) | // C flag
|
|
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
|
|
zHL = res;
|
|
RET(11)
|
|
|
|
|
|
OPED(0x72): // SBC HL,SP
|
|
src = zSP;
|
|
goto OP_SBC_HL;
|
|
|
|
OPED(0x42): // SBC HL,BC
|
|
OPED(0x52): // SBC HL,DE
|
|
OPED(0x62): // SBC HL,HL
|
|
src = zR16((Opcode >> 4) & 3);
|
|
|
|
OP_SBC_HL:
|
|
res = zHL - src + (zF & CZ80_CF);
|
|
#if CZ80_DEBUG
|
|
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | CZ80_NF | // H/N flag
|
|
(((src ^ zHL) & (zHL ^ res) & 0x8000) >> 13) | // V flag
|
|
((res >> 8) & CZ80_SF) | // S flag
|
|
((res >> 16) & CZ80_CF) | // C flag
|
|
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
|
|
#else
|
|
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | CZ80_NF | // H/N flag
|
|
(((src ^ zHL) & (zHL ^ res) & 0x8000) >> 13) | // V flag
|
|
((res >> 8) & (CZ80_SF | CZ80_XF | CZ80_YF)) | // S/X/Y flag
|
|
((res >> 16) & CZ80_CF) | // C flag
|
|
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
|
|
#endif
|
|
zHL = res;
|
|
RET(11)
|
|
}
|
|
|
|
|
|
{
|
|
u32 res;
|
|
|
|
OPED(0x40): // IN B,(C)
|
|
OPED(0x48): // IN C,(C)
|
|
OPED(0x50): // IN D,(C)
|
|
OPED(0x58): // IN E,(C)
|
|
OPED(0x60): // IN H,(C)
|
|
OPED(0x68): // IN L,(C)
|
|
OPED(0x78): // IN E,(C)
|
|
|
|
IN(zBC, res);
|
|
zR8((Opcode >> 3) & 7) = res;
|
|
zF = (zF & CZ80_CF) | SZXYP[res];
|
|
RET(8)
|
|
|
|
OPED(0x70): // IN 0,(C)
|
|
|
|
IN(zBC, res);
|
|
zF = (zF & CZ80_CF) | SZXYP[res];
|
|
RET(8)
|
|
}
|
|
|
|
|
|
{
|
|
u32 src;
|
|
|
|
OPED(0x71): // OUT (C),0
|
|
src = 0;
|
|
goto OP_OUT_mBC;
|
|
|
|
OPED(0x51): // OUT (C),D
|
|
OPED(0x41): // OUT (C),B
|
|
OPED(0x49): // OUT (C),C
|
|
OPED(0x59): // OUT (C),E
|
|
OPED(0x61): // OUT (C),H
|
|
OPED(0x69): // OUT (C),L
|
|
OPED(0x79): // OUT (C),E
|
|
src = zR8((Opcode >> 3) & 7);
|
|
|
|
OP_OUT_mBC:
|
|
OUT(zBC, src);
|
|
RET(8)
|
|
}
|
|
|
|
{
|
|
u32 newPC;
|
|
|
|
OPED(0x4d): // RETI
|
|
OPED(0x5d): // RETI
|
|
OPED(0x6d): // RETI
|
|
OPED(0x7d): // RETI
|
|
// if (CPU->RetI) CPU->RetI();
|
|
|
|
OPED(0x45): // RETN;
|
|
OPED(0x55): // RETN;
|
|
OPED(0x65): // RETN;
|
|
OPED(0x75): // RETN;
|
|
PRE_IO
|
|
POP_16(newPC);
|
|
SET_PC(newPC);
|
|
POST_IO
|
|
zIFF1 = zIFF2;
|
|
Z80_ICount -= 10;
|
|
// we need to test for interrupt
|
|
goto Cz80_Check_Int;
|
|
}
|
|
|
|
OPED(0x46): // IM 0
|
|
OPED(0x4e): // IM 0
|
|
OPED(0x66): // IM 0
|
|
OPED(0x6e): // IM 0
|
|
zIM = 0;
|
|
RET(4)
|
|
|
|
OPED(0x76): // IM 1
|
|
OPED(0x56): // IM 1
|
|
zIM = 1;
|
|
RET(4)
|
|
|
|
OPED(0x5e): // IM 2
|
|
OPED(0x7e): // IM 2
|
|
zIM = 2;
|
|
RET(4)
|
|
|
|
|
|
{
|
|
u8 val;
|
|
u8 F;
|
|
|
|
OPED(0xa8): // LDD
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
WRITE_BYTE(zDE--, val)
|
|
goto OP_LDX;
|
|
|
|
OPED(0xa0): // LDI
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
WRITE_BYTE(zDE++, val)
|
|
|
|
OP_LDX:
|
|
#if CZ80_EXACT
|
|
val += zA;
|
|
F = (zF & (CZ80_SF | CZ80_ZF | CZ80_CF)) |
|
|
(val & CZ80_XF) | ((val << 4) & CZ80_YF);
|
|
#else
|
|
F = zF & (CZ80_SF | CZ80_ZF | CZ80_YF | CZ80_XF | CZ80_CF);
|
|
#endif
|
|
if (--zBC) F |= CZ80_PF;
|
|
zF = F;
|
|
POST_IO
|
|
RET(12)
|
|
}
|
|
|
|
{
|
|
u8 val;
|
|
u8 F;
|
|
|
|
OPED(0xb8): // LDDR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
WRITE_BYTE(zDE--, val)
|
|
POST_IO
|
|
zBC--;
|
|
Z80_ICount -= 21;
|
|
} while ((zBC) && (Z80_ICount > -4));
|
|
goto OP_LDXR;
|
|
|
|
OPED(0xb0): // LDIR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
WRITE_BYTE(zDE++, val)
|
|
POST_IO
|
|
zBC--;
|
|
Z80_ICount -= 21;
|
|
} while ((zBC) && (Z80_ICount > -4));
|
|
|
|
OP_LDXR:
|
|
#if CZ80_EXACT
|
|
val += zA;
|
|
F = (zF & (CZ80_SF | CZ80_ZF | CZ80_CF)) |
|
|
(val & CZ80_XF) | ((val << 4) & CZ80_YF);
|
|
#else
|
|
F = zF & (CZ80_SF | CZ80_ZF | CZ80_YF | CZ80_XF | CZ80_CF);
|
|
#endif
|
|
|
|
if (zBC)
|
|
{
|
|
// instruction not yet completed...
|
|
// we will continu it at next CZ80_Exec
|
|
zF = F | CZ80_PF;
|
|
zPC -= 2;
|
|
Z80_ICount += 4;
|
|
goto Cz80_Check_Int;
|
|
}
|
|
|
|
// instruction completed...
|
|
zF = F;
|
|
RET(-(5 + 4))
|
|
}
|
|
|
|
|
|
{
|
|
u8 val;
|
|
u8 res;
|
|
u8 F;
|
|
|
|
OPED(0xa9): // CPD
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
goto OP_CPX;
|
|
|
|
OPED(0xa1): // CPI
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
|
|
OP_CPX:
|
|
res = zA - val;
|
|
#if CZ80_EXACT
|
|
F = (zF & CZ80_CF) | (SZXY[res] & ~(CZ80_YF | CZ80_XF)) |
|
|
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
|
|
if (F & CZ80_HF) res--;
|
|
F |= (res & CZ80_XF) | ((res >> 4) & CZ80_YF);
|
|
#else
|
|
F = (zF & CZ80_CF) | SZXY[res] |
|
|
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
|
|
#endif
|
|
if (--zBC) F |= CZ80_PF;
|
|
zF = F;
|
|
POST_IO
|
|
RET(12)
|
|
}
|
|
|
|
{
|
|
u32 val;
|
|
u32 res;
|
|
u8 F;
|
|
|
|
OPED(0xb9): // CPDR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
res = zA - val;
|
|
POST_IO
|
|
zBC--;
|
|
Z80_ICount -= 21;
|
|
} while ((zBC) && (res) && (Z80_ICount > -4));
|
|
goto OP_CPXR;
|
|
|
|
OPED(0xb1): // CPIR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
res = zA - val;
|
|
POST_IO
|
|
zBC--;
|
|
Z80_ICount -= 21;
|
|
} while ((zBC) && (res) && (Z80_ICount > -4));
|
|
|
|
OP_CPXR:
|
|
#if CZ80_EXACT
|
|
F = (zF & CZ80_CF) | (SZXY[res] & ~(CZ80_YF | CZ80_XF)) |
|
|
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
|
|
if (F & CZ80_HF) res--;
|
|
F |= (res & CZ80_XF) | ((res >> 4) & CZ80_YF);
|
|
#else
|
|
F = (zF & CZ80_CF) | SZXY[res] |
|
|
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
|
|
#endif
|
|
|
|
if (zBC)
|
|
{
|
|
// instruction not yet completed...
|
|
// we will continu it at next CZ80_Exec
|
|
zF = F | CZ80_PF;
|
|
zPC -= 2;
|
|
Z80_ICount += 4;
|
|
goto Cz80_Check_Int;
|
|
}
|
|
|
|
// instruction completed...
|
|
zF = F;
|
|
RET(-(3 + 4))
|
|
}
|
|
|
|
|
|
{
|
|
u8 val;
|
|
#if CZ80_EXACT
|
|
u8 F;
|
|
#endif
|
|
|
|
OPED(0xaa): // IND
|
|
PRE_IO
|
|
IN(zBC, val)
|
|
WRITE_BYTE(zHL--, val)
|
|
#if CZ80_EXACT
|
|
if ((((zC - 1) & 0xFF) + val) & 0x100)
|
|
{
|
|
F = CZ80_HF | CZ80_CF;
|
|
goto OP_INX;
|
|
}
|
|
F = 0;
|
|
#endif
|
|
goto OP_INX;
|
|
|
|
OPED(0xa2): // INI
|
|
PRE_IO
|
|
IN(zBC, val)
|
|
WRITE_BYTE(zHL++, val)
|
|
#if CZ80_EXACT
|
|
if ((((zC + 1) & 0xFF) + val) & 0x100)
|
|
{
|
|
F = CZ80_HF | CZ80_CF;
|
|
goto OP_INX;
|
|
}
|
|
F = 0;
|
|
#endif
|
|
|
|
OP_INX:
|
|
#if CZ80_EXACT
|
|
// P FLAG isn't correct here !
|
|
zF = F | (SZXY[--zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF));
|
|
#else
|
|
zF = SZXY[--zB] + ((val >> 6) & CZ80_NF);
|
|
#endif
|
|
POST_IO
|
|
RET(12)
|
|
}
|
|
|
|
{
|
|
u8 val;
|
|
#if CZ80_EXACT
|
|
u8 F;
|
|
#endif
|
|
|
|
OPED(0xba): // INDR
|
|
do
|
|
{
|
|
PRE_IO
|
|
IN(zBC, val)
|
|
WRITE_BYTE(zHL--, val)
|
|
POST_IO
|
|
zB--;
|
|
Z80_ICount -= 21;
|
|
} while ((zB) && (Z80_ICount > -4));
|
|
#if CZ80_EXACT
|
|
if ((((zC - 1) & 0xFF) + val) & 0x100)
|
|
{
|
|
F = CZ80_HF | CZ80_CF;
|
|
goto OP_INXR;
|
|
}
|
|
F = 0;
|
|
#endif
|
|
goto OP_INXR;
|
|
|
|
OPED(0xb2): // INIR
|
|
do
|
|
{
|
|
PRE_IO
|
|
IN(zBC, val)
|
|
WRITE_BYTE(zHL++, val)
|
|
POST_IO
|
|
zB--;
|
|
Z80_ICount -= 21;
|
|
} while ((zB) && (Z80_ICount > -4));
|
|
#if CZ80_EXACT
|
|
if ((((zC + 1) & 0xFF) + val) & 0x100)
|
|
{
|
|
F = CZ80_HF | CZ80_CF;
|
|
goto OP_INXR;
|
|
}
|
|
F = 0;
|
|
#endif
|
|
|
|
OP_INXR:
|
|
#if CZ80_EXACT
|
|
// P FLAG isn't correct here !
|
|
zF = F | (SZXY[zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF));
|
|
#else
|
|
zF = SZXY[zB] + ((val >> 6) & CZ80_NF);
|
|
#endif
|
|
|
|
if (zB)
|
|
{
|
|
// instruction not yet completed...
|
|
// we will continu it at next CZ80_Exec
|
|
zPC -= 2;
|
|
Z80_ICount += 4;
|
|
goto Cz80_Check_Int;
|
|
}
|
|
|
|
// instruction completed...
|
|
RET(-(5 + 4))
|
|
}
|
|
|
|
|
|
{
|
|
u8 val;
|
|
#if CZ80_EXACT
|
|
u8 F;
|
|
#endif
|
|
|
|
OPED(0xab): // OUTD
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
OUT(zBC, val)
|
|
goto OP_OUTX;
|
|
|
|
OPED(0xa3): // OUTI
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
OUT(zBC, val)
|
|
|
|
OP_OUTX:
|
|
#if CZ80_EXACT
|
|
// P FLAG isn't correct here !
|
|
F = SZXY[--zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF);
|
|
if ((val + zL) & 0x100) F |= CZ80_HF | CZ80_CF;
|
|
zF = F;
|
|
#else
|
|
zF = SZXY[--zB] + ((val >> 6) & CZ80_NF);
|
|
#endif
|
|
POST_IO
|
|
RET(12)
|
|
}
|
|
|
|
|
|
{
|
|
u8 val;
|
|
#if CZ80_EXACT
|
|
u8 F;
|
|
#endif
|
|
|
|
OPED(0xbb): // OUTDR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL--, val)
|
|
OUT(zBC, val)
|
|
POST_IO
|
|
zB--;
|
|
Z80_ICount -= 21;
|
|
} while ((zB) && (Z80_ICount > -4));
|
|
goto OP_OUTXR;
|
|
|
|
OPED(0xb3): // OUTIR
|
|
do
|
|
{
|
|
PRE_IO
|
|
READ_BYTE(zHL++, val)
|
|
OUT(zBC, val)
|
|
POST_IO
|
|
zB--;
|
|
Z80_ICount -= 21;
|
|
} while ((zB) && (Z80_ICount > -4));
|
|
|
|
OP_OUTXR:
|
|
#if CZ80_EXACT
|
|
// P FLAG isn't correct here !
|
|
F = SZXY[zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF);
|
|
if ((val + zL) & 0x100) F |= CZ80_HF | CZ80_CF;
|
|
zF = F;
|
|
#else
|
|
zF = SZXY[zB] + ((val >> 6) & CZ80_NF);
|
|
#endif
|
|
|
|
if (zB)
|
|
{
|
|
// instruction not yet completed...
|
|
// we will continu it at next CZ80_Exec
|
|
zPC -= 2;
|
|
Z80_ICount += 4;
|
|
goto Cz80_Check_Int;
|
|
}
|
|
|
|
// instruction not yet completed...
|
|
RET(-(5 + 4))
|
|
}
|
|
|
|
#if CZ80_USE_JUMPTABLE
|
|
#else
|
|
}
|
|
#endif
|