2896 lines
133 KiB
C++
2896 lines
133 KiB
C++
#include "z80.h"
|
|
#include "z80debug.h"
|
|
#include "zx_tape.h"
|
|
#include <stdio.h>
|
|
|
|
namespace z80
|
|
{
|
|
static uint8_t *memory = nullptr;
|
|
static uint8_t memtag[65536];
|
|
static uint8_t memtouched[65536];
|
|
static uint32_t t = 0;
|
|
static uint16_t current_opcode_address = 0;
|
|
bool options[Z80_NUM_OPTIONS] = { true, false };
|
|
int calls_stacked = 0;
|
|
|
|
int (*in_ports[256])(int);
|
|
void (*out_ports[256])(int, int);
|
|
|
|
#define _rM16(a) (uint16_t*)&memory[a]
|
|
#define rM16(a) *_rM16(a)
|
|
|
|
#define fC 0b00000001
|
|
#define fN 0b00000010
|
|
#define fP 0b00000100
|
|
#define fV 0b00000100
|
|
#define fX 0b00001000
|
|
#define fH 0b00010000
|
|
#define fY 0b00100000
|
|
#define fZ 0b01000000
|
|
#define fS 0b10000000
|
|
|
|
#define cNO 255
|
|
#define cNZ 0
|
|
#define cZ 1
|
|
#define cNC 2
|
|
#define cC 3
|
|
#define cPO 4
|
|
#define cPE 5
|
|
#define cP 6
|
|
#define cM 7
|
|
|
|
uint8_t regs[31];
|
|
|
|
uint8_t *_rF = ®s[0];
|
|
uint8_t *_rA = ®s[1];
|
|
uint8_t *_rC = ®s[2];
|
|
uint8_t *_rB = ®s[3];
|
|
uint8_t *_rE = ®s[4];
|
|
uint8_t *_rD = ®s[5];
|
|
uint8_t *_rL = ®s[6];
|
|
uint8_t *_rH = ®s[7];
|
|
|
|
uint16_t *_rAF = (uint16_t*)®s[0];
|
|
uint16_t *_rBC = (uint16_t*)®s[2];
|
|
uint16_t *_rDE = (uint16_t*)®s[4];
|
|
uint16_t *_rHL = (uint16_t*)®s[6];
|
|
|
|
uint8_t *_rF2 = ®s[8];
|
|
uint8_t *_rA2 = ®s[9];
|
|
uint8_t *_rC2 = ®s[10];
|
|
uint8_t *_rB2 = ®s[11];
|
|
uint8_t *_rE2 = ®s[12];
|
|
uint8_t *_rD2 = ®s[13];
|
|
uint8_t *_rL2 = ®s[14];
|
|
uint8_t *_rH2 = ®s[15];
|
|
|
|
uint16_t *_rAF2 = (uint16_t*)®s[8];
|
|
uint16_t *_rBC2 = (uint16_t*)®s[10];
|
|
uint16_t *_rDE2 = (uint16_t*)®s[12];
|
|
uint16_t *_rHL2 = (uint16_t*)®s[14];
|
|
|
|
uint8_t *_rIXL = ®s[16];
|
|
uint8_t *_rIXH = ®s[17];
|
|
uint8_t *_rIYL = ®s[18];
|
|
uint8_t *_rIYH = ®s[19];
|
|
uint16_t *_rIX = (uint16_t*)®s[16];
|
|
uint16_t *_rIY = (uint16_t*)®s[18];
|
|
|
|
uint16_t *_rSP = (uint16_t*)®s[20];
|
|
|
|
uint8_t *_rI = ®s[22];
|
|
uint8_t *_rR = ®s[23];
|
|
|
|
uint16_t *_rPC = (uint16_t*)®s[24];
|
|
|
|
uint16_t *_rWZ = (uint16_t*)®s[26];
|
|
uint8_t *_rZ = (uint8_t*)®s[26];
|
|
uint8_t *_rW = (uint8_t*)®s[27];
|
|
|
|
uint8_t *_rIFF1 = ®s[28];
|
|
uint8_t *_rIFF2 = ®s[29];
|
|
uint8_t *_rIM = ®s[30];
|
|
|
|
//uint8_t iff1, iff2, im;
|
|
bool exit_from_halt = false;
|
|
int pending_ei = 0;
|
|
|
|
#define rA (*_rA)
|
|
#define rF (*_rF)
|
|
#define rB (*_rB)
|
|
#define rC (*_rC)
|
|
#define rD (*_rD)
|
|
#define rE (*_rE)
|
|
#define rH (*_rH)
|
|
#define rL (*_rL)
|
|
#define rW (*_rW)
|
|
#define rZ (*_rZ)
|
|
|
|
#define rAF (*_rAF)
|
|
#define rBC (*_rBC)
|
|
#define rDE (*_rDE)
|
|
#define rHL (*_rHL)
|
|
#define rWZ (*_rWZ)
|
|
|
|
#define rA2 (*_rA2)
|
|
#define rF2 (*_rF2)
|
|
#define rB2 (*_rB2)
|
|
#define rC2 (*_rC2)
|
|
#define rD2 (*_rD2)
|
|
#define rE2 (*_rE2)
|
|
#define rH2 (*_rH2)
|
|
#define rL2 (*_rL2)
|
|
|
|
#define rAF2 (*_rAF2)
|
|
#define rBC2 (*_rBC2)
|
|
#define rDE2 (*_rDE2)
|
|
#define rHL2 (*_rHL2)
|
|
|
|
#define rIXH (*_rIXH)
|
|
#define rIXL (*_rIXL)
|
|
#define rIYH (*_rIYH)
|
|
#define rIYL (*_rIYL)
|
|
#define rIX (*_rIX)
|
|
#define rIY (*_rIY)
|
|
#define rSP (*_rSP)
|
|
|
|
#define rI (*_rI)
|
|
#define rR (*_rR)
|
|
|
|
#define rPC (*_rPC)
|
|
|
|
#define iff1 (*_rIFF1)
|
|
#define iff2 (*_rIFF2)
|
|
#define im (*_rIM)
|
|
|
|
#define EX(a,b) {auto temp=a;a=b;b=temp;}
|
|
|
|
bool reading_m1 = false;
|
|
|
|
uint8_t READ_MEM_8(const uint16_t addr, const bool code=false)
|
|
{
|
|
if (z80debug::isbreak(addr, 2)) z80debug::stop();
|
|
t+=3;
|
|
if (memtag[addr] != MEMTAG_IGNORE) {
|
|
if (!code) {
|
|
if ( memtag[addr] == MEMTAG_INST ) {
|
|
//printf("WARNING! READING DATA FROM CODE!!! $%4X\n", addr);
|
|
//z80debug::stop();
|
|
} else {
|
|
memtag[addr] = MEMTAG_DATA;
|
|
}
|
|
} else {
|
|
if ( (reading_m1) && (memtag[addr] == MEMTAG_DATA) ) {
|
|
//printf("WARNING! EXECUTING DATA AS CODE!!! $%4X\n", addr);
|
|
//z80debug::stop();
|
|
}
|
|
}
|
|
}
|
|
reading_m1 = false;
|
|
return memory[addr];
|
|
}
|
|
|
|
uint8_t READ_MEM_8()
|
|
{
|
|
uint8_t data = READ_MEM_8(rPC, true);
|
|
if ( (memtag[rPC] != MEMTAG_IGNORE) && (memtag[rPC] != MEMTAG_MIXED) ) {
|
|
if (memtag[rPC] == MEMTAG_DATA)
|
|
memtag[rPC] = MEMTAG_MIXED;
|
|
else
|
|
memtag[rPC] = MEMTAG_CODE;
|
|
}
|
|
rPC++;
|
|
return data;
|
|
}
|
|
|
|
uint8_t READ_M1()
|
|
{
|
|
t+=1;
|
|
reading_m1 = true;
|
|
if (rPC==0x056c) {
|
|
zx_tape::rewind();
|
|
zx_tape::play();
|
|
}
|
|
return READ_MEM_8();
|
|
}
|
|
|
|
uint16_t READ_MEM_16()
|
|
{
|
|
const uint8_t L = READ_MEM_8();
|
|
const uint8_t H = READ_MEM_8();
|
|
return (H << 8) + L;
|
|
}
|
|
|
|
uint16_t READ_MEM_16(const uint16_t addr)
|
|
{
|
|
return READ_MEM_8(addr) + (READ_MEM_8(addr+1) << 8);
|
|
}
|
|
|
|
const uint8_t WRITE_MEM_8(const uint16_t addr, const uint8_t value)
|
|
{
|
|
t+=3;
|
|
if (addr>=0x4000) memory[addr] = value;
|
|
if (z80debug::isbreak(addr, 4)) z80debug::stop();
|
|
//if (z80debug::debugging())
|
|
z80debug::setmemmodified(addr);
|
|
if ( (memtag[addr] != MEMTAG_IGNORE) && (memtag[addr] != MEMTAG_MIXED) ) {
|
|
if (memtag[addr]==MEMTAG_INST) {
|
|
//printf("WARNING! WRITING DATA OVER CODE!!! $%4X\n", addr);
|
|
//z80debug::stop();
|
|
} else if (memtag[addr] == MEMTAG_CODE) {
|
|
memtag[addr] = MEMTAG_MIXED;
|
|
} else {
|
|
memtag[addr] = MEMTAG_DATA;
|
|
memtouched[addr] = MEMTAG_DATA;
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
void WRITE_MEM_16(const uint16_t addr, const uint16_t value)
|
|
{
|
|
WRITE_MEM_8(addr, value & 0xff);
|
|
WRITE_MEM_8(addr+1, (value>>8) & 0xff);
|
|
//if (value==0x7229) z80debug::stop();
|
|
}
|
|
|
|
void PUSH(uint16_t b)
|
|
{
|
|
rSP-=2;
|
|
WRITE_MEM_16(rSP, b);
|
|
t+=1;
|
|
}
|
|
|
|
void POP(uint16_t *a)
|
|
{
|
|
*a = READ_MEM_16(rSP);
|
|
rSP+=2;
|
|
}
|
|
|
|
inline void KEEP_FLAGS(const uint8_t flags)
|
|
{
|
|
rF &= flags;
|
|
}
|
|
|
|
inline void SET_FLAGS(const uint8_t flags)
|
|
{
|
|
rF |= flags;
|
|
}
|
|
|
|
inline void FLAGS_SZXY(const uint8_t value)
|
|
{
|
|
rF |= value ? value & fS : fZ;
|
|
rF |= (value & (fY | fX));
|
|
}
|
|
|
|
inline void SET_PARITY_FLAG(const uint8_t value)
|
|
{
|
|
uint8_t count=0;
|
|
uint8_t v = value;
|
|
while (v>0) { count+=(v&1); v=v>>1; }
|
|
if (!(count&1)) rF |= fP;
|
|
}
|
|
|
|
void INC16(uint16_t *reg)
|
|
{
|
|
t+=2;
|
|
(*reg)++;
|
|
}
|
|
|
|
void DEC16(uint16_t *reg)
|
|
{
|
|
t+=2;
|
|
(*reg)--;
|
|
}
|
|
|
|
void ADD16(uint16_t* a, uint16_t b)
|
|
{
|
|
t++;
|
|
const uint32_t res = *a + b;
|
|
KEEP_FLAGS(fS | fZ | fV);
|
|
SET_FLAGS(((*a ^ res ^ b) >> 8) & fH);
|
|
SET_FLAGS((res >> 16) & fC);
|
|
SET_FLAGS((res >> 8) & (fY | fX));
|
|
*a = (uint16_t)res;
|
|
}
|
|
|
|
void ADC16(uint16_t* a, uint16_t b)
|
|
{
|
|
t++;
|
|
const uint32_t res = *a + b + (rF & fC);
|
|
rF=0;
|
|
SET_FLAGS(((*a ^ res ^ b) >> 8) & fH);
|
|
SET_FLAGS((res >> 16) & fC);
|
|
SET_FLAGS((res >> 8) & (fS | fY | fX));
|
|
SET_FLAGS((res & 0xffff) ? 0 : fZ);
|
|
SET_FLAGS(((b ^ *a ^ 0x8000) & (b ^ res) & 0x8000) >> 13);
|
|
*a = (uint16_t)res;
|
|
}
|
|
|
|
void SBC16(uint16_t* a, uint16_t b)
|
|
{
|
|
t++;
|
|
const uint32_t res = *a - b - (rF & fC);
|
|
rF = 0;
|
|
SET_FLAGS(((*a ^ res ^ b) >> 8) & fH);
|
|
SET_FLAGS(fN);
|
|
SET_FLAGS((res >> 16) & fC);
|
|
SET_FLAGS((res >> 8) & (fS | fY | fX));
|
|
SET_FLAGS((res & 0xffff) ? 0 : fZ);
|
|
SET_FLAGS(((b ^ *a) & (*a ^ res) & 0x8000) >> 13);
|
|
*a = (uint16_t)res;
|
|
}
|
|
|
|
void INC8(uint8_t *reg)
|
|
{
|
|
uint8_t value = *reg + 1;
|
|
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(value);
|
|
if (value == 0x80) SET_FLAGS(fV);
|
|
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
|
|
|
*reg = value;
|
|
}
|
|
|
|
void DEC8(uint8_t *reg)
|
|
{
|
|
uint8_t value = *reg - 1;
|
|
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(value);
|
|
SET_FLAGS(fN);
|
|
if (value == 0x7f) SET_FLAGS(fV);
|
|
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
|
|
|
*reg = value;
|
|
}
|
|
|
|
void INCMEM8(const uint16_t addr)
|
|
{
|
|
t++;
|
|
uint8_t value = READ_MEM_8(addr);
|
|
value++;
|
|
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(value);
|
|
if (value == 0x80) SET_FLAGS(fV);
|
|
if ( (value & 0x0f) == 0x00 ) SET_FLAGS(fH);
|
|
|
|
WRITE_MEM_8(addr, value);
|
|
}
|
|
|
|
void DECMEM8(const uint16_t addr)
|
|
{
|
|
t+=1;
|
|
uint8_t value = READ_MEM_8(addr);
|
|
value--;
|
|
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(value);
|
|
SET_FLAGS(fN);
|
|
if (value == 0x7f) SET_FLAGS(fV);
|
|
if ( (value & 0x0f) == 0x0f ) SET_FLAGS(fH);
|
|
|
|
WRITE_MEM_8(addr, value);
|
|
}
|
|
|
|
void ADD8(uint8_t b)
|
|
{
|
|
const uint8_t res = rA + b;
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if ( (res & 0x0f) < (rA & 0x0f) ) SET_FLAGS(fH);
|
|
if ( res < rA ) SET_FLAGS(fC);
|
|
if ( (b^rA^0x80) & (b^res) & 0x80 ) SET_FLAGS(fV);
|
|
rA = (uint8_t)res;
|
|
}
|
|
|
|
void ADC8(uint8_t b)
|
|
{
|
|
if (!(rF & fC))
|
|
ADD8(b);
|
|
else {
|
|
uint16_t res = rA + b + 1;
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if ( (res & 0x0f) <= (rA & 0x0f) ) SET_FLAGS(fH);
|
|
if ( res > 255 ) SET_FLAGS(fC);
|
|
if ( (b^rA^0x80) & (b^res) & 0x80 ) SET_FLAGS(fV);
|
|
rA = (uint8_t)res;
|
|
}
|
|
}
|
|
|
|
void SUB8(uint8_t b, const bool update=true)
|
|
{
|
|
const uint8_t res = rA - b;
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
SET_FLAGS(fN);
|
|
if ( (res & 0x0f) > (rA & 0x0f) ) SET_FLAGS(fH);
|
|
if ( res > rA ) SET_FLAGS(fC);
|
|
if ( (b^rA) & (rA^res) & 0x80 ) SET_FLAGS(fV);
|
|
if (update) rA = (uint8_t)res;
|
|
}
|
|
|
|
void SBC8(uint8_t b)
|
|
{
|
|
if (!(rF & fC))
|
|
SUB8(b);
|
|
else {
|
|
const uint8_t res = rA - b - 1;
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
SET_FLAGS(fN);
|
|
if ( (res & 0x0f) >= (rA & 0x0f) ) SET_FLAGS(fH);
|
|
if ( res >= rA ) SET_FLAGS(fC);
|
|
if ( (b^rA) & (rA^res) & 0x80 ) SET_FLAGS(fV);
|
|
rA = (uint8_t)res;
|
|
}
|
|
}
|
|
|
|
void NEG()
|
|
{
|
|
uint8_t val = rA;
|
|
rA = 0;
|
|
SUB8(val);
|
|
}
|
|
|
|
void AND(uint8_t b)
|
|
{
|
|
rA = rA & b;
|
|
rF=0;
|
|
FLAGS_SZXY(rA);
|
|
SET_PARITY_FLAG(rA);
|
|
SET_FLAGS(fH);
|
|
}
|
|
|
|
void XOR(uint8_t b)
|
|
{
|
|
rA = rA ^ b;
|
|
rF=0;
|
|
FLAGS_SZXY(rA);
|
|
SET_PARITY_FLAG(rA);
|
|
}
|
|
|
|
void OR(uint8_t b)
|
|
{
|
|
rA = rA | b;
|
|
rF=0;
|
|
FLAGS_SZXY(rA);
|
|
SET_PARITY_FLAG(rA);
|
|
}
|
|
|
|
void CP(uint8_t b)
|
|
{
|
|
SUB8(b, false);
|
|
}
|
|
|
|
void LD_A_I()
|
|
{
|
|
t++;
|
|
rA = rI;
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(rA);
|
|
if (iff2) SET_FLAGS(fP);
|
|
}
|
|
|
|
void LD_A_R()
|
|
{
|
|
t++;
|
|
rA = rR;
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(rA);
|
|
if (iff2) SET_FLAGS(fP);
|
|
}
|
|
|
|
void RLCA()
|
|
{
|
|
const bool should_carry = rA & 0x80;
|
|
rA = (rA>>7) | (rA<<1);
|
|
KEEP_FLAGS(fS | fZ | fP);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
if (should_carry) SET_FLAGS(fC);
|
|
}
|
|
|
|
void RRCA()
|
|
{
|
|
const bool should_carry = rA & 0x01;
|
|
rA = (rA<<7) | (rA>>1);
|
|
KEEP_FLAGS(fS | fZ | fP);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
if (should_carry) SET_FLAGS(fC);
|
|
}
|
|
|
|
void RLA()
|
|
{
|
|
const bool should_carry = rA & 0x80;
|
|
rA = (rA<<1) | (rF&fC);
|
|
KEEP_FLAGS(fS | fZ | fP);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
if (should_carry) SET_FLAGS(fC);
|
|
}
|
|
|
|
void RRA()
|
|
{
|
|
const bool should_carry = rA & 0x01;
|
|
rA = ((rF&fC)<<7) | (rA>>1);
|
|
KEEP_FLAGS(fS | fZ | fP);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
if (should_carry) SET_FLAGS(fC);
|
|
}
|
|
|
|
void RRD()
|
|
{
|
|
uint8_t a = rA;
|
|
uint8_t hl = READ_MEM_8(rHL);
|
|
rA = (rA & 0xF0) | (hl & 0x0F);
|
|
hl = (hl >> 4) | (a << 4);
|
|
WRITE_MEM_8(rHL, hl);
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(rA);
|
|
SET_PARITY_FLAG(rA);
|
|
t+=4;
|
|
}
|
|
|
|
void RLD()
|
|
{
|
|
uint8_t a = rA;
|
|
uint8_t hl = READ_MEM_8(rHL);
|
|
rA = (rA & 0xF0) | (hl >> 4);
|
|
hl = (hl << 4) | (a & 0x0F);
|
|
WRITE_MEM_8(rHL, hl);
|
|
KEEP_FLAGS(fC);
|
|
FLAGS_SZXY(rA);
|
|
SET_PARITY_FLAG(rA);
|
|
t+=4;
|
|
}
|
|
|
|
void new_DAA()
|
|
{
|
|
uint8_t cf = rA > 0x99;
|
|
uint8_t diff = ((rF & fH) || (rA & 0xF) > 9) ? 6 : 0;
|
|
|
|
if ((rF & fC) || cf) diff |= 0x60;
|
|
diff = (rF & fN) ? rA - diff : rA + diff;
|
|
|
|
KEEP_FLAGS(fN | fC);
|
|
FLAGS_SZXY(diff);
|
|
SET_FLAGS(!(diff) << 6);
|
|
SET_FLAGS((rA ^ diff) & fH);
|
|
SET_PARITY_FLAG(diff);
|
|
SET_FLAGS(cf);
|
|
/* FLAGS = (zuint8)(
|
|
(F & (NF | CF)) | // NF unchanged; CF dominant
|
|
(t & SYXF) | // SF = sign; YF = Y; XF = X
|
|
ZF_ZERO(t) | // ZF = zero
|
|
((A ^ t) & HF) | // HF = Ai.4 != Ao.4
|
|
PF_PARITY(t) | // PF = parity
|
|
cf); // CF |= 1 (if BCD carry)
|
|
*/
|
|
rA = diff;
|
|
t+=4;
|
|
}
|
|
|
|
void DAA()
|
|
{
|
|
bool carry_set = false;
|
|
uint8_t old = rA;
|
|
if ( (rA & 0x0F)>9 || (rF & fH) )
|
|
rA += 0x06;
|
|
if ( (rA >> 4)>9 || (rF & fC) ) { rA += 0x60; carry_set = true; }
|
|
KEEP_FLAGS(fN);
|
|
FLAGS_SZXY(rA);
|
|
if ( (rA & 0x0F) < (old & 0x0F) ) SET_FLAGS(fH);
|
|
if (carry_set) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(rA);
|
|
}
|
|
|
|
void CPL()
|
|
{
|
|
rA = ~rA;
|
|
KEEP_FLAGS(fS | fZ | fP | fC);
|
|
SET_FLAGS(fH | fN);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
}
|
|
|
|
void SCF()
|
|
{
|
|
KEEP_FLAGS( fS | fZ | fP );
|
|
SET_FLAGS(fC);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
}
|
|
|
|
void CCF()
|
|
{
|
|
const bool carry = (rF & fC);
|
|
KEEP_FLAGS( fS | fZ | fP );
|
|
SET_FLAGS(carry ? fH : fC);
|
|
SET_FLAGS(rA & (fX | fY));
|
|
}
|
|
|
|
void DJNZ()
|
|
{
|
|
const int8_t d = (int8_t)READ_MEM_8();
|
|
rB--;
|
|
if (rB!=0)
|
|
{
|
|
rPC = rPC + d;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void JR(uint8_t cond = cNO)
|
|
{
|
|
const int8_t d = (int8_t)READ_MEM_8();
|
|
if ( cond == cNO ||
|
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
|
( (cond == cZ) && (rF & fZ) ) ||
|
|
( (cond == cNC) && !(rF & fC) ) ||
|
|
( (cond == cC) && (rF & fC) ) )
|
|
{
|
|
rPC = rPC + d;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void JP(uint8_t cond, uint16_t addr)
|
|
{
|
|
if ( cond == cNO ||
|
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
|
( (cond == cZ) && (rF & fZ) ) ||
|
|
( (cond == cNC) && !(rF & fC) ) ||
|
|
( (cond == cC) && (rF & fC) ) ||
|
|
( (cond == cPO) && !(rF & fV) ) ||
|
|
( (cond == cPE) && (rF & fV) ) ||
|
|
( (cond == cM) && (rF & fS) ) ||
|
|
( (cond == cP) && !(rF & fS) ) )
|
|
rPC = addr;
|
|
}
|
|
|
|
void CALL(uint8_t cond, uint16_t addr)
|
|
{
|
|
if ( cond == cNO ||
|
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
|
( (cond == cZ) && (rF & fZ) ) ||
|
|
( (cond == cNC) && !(rF & fC) ) ||
|
|
( (cond == cC) && (rF & fC) ) ||
|
|
( (cond == cPO) && !(rF & fV) ) ||
|
|
( (cond == cPE) && (rF & fV) ) ||
|
|
( (cond == cM) && (rF & fS) ) ||
|
|
( (cond == cP) && !(rF & fS) ) )
|
|
{
|
|
PUSH(rPC);
|
|
rPC = addr;
|
|
|
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
|
calls_stacked++;
|
|
printf("CALL: calls stacked: %i", calls_stacked);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RET(uint8_t cond)
|
|
{
|
|
if ( cond == cNO ||
|
|
( (cond == cNZ) && !(rF & fZ) ) ||
|
|
( (cond == cZ) && (rF & fZ) ) ||
|
|
( (cond == cNC) && !(rF & fC) ) ||
|
|
( (cond == cC) && (rF & fC) ) ||
|
|
( (cond == cPO) && !(rF & fV) ) ||
|
|
( (cond == cPE) && (rF & fV) ) ||
|
|
( (cond == cM) && (rF & fS) ) ||
|
|
( (cond == cP) && !(rF & fS) ) )
|
|
{
|
|
POP(_rPC);
|
|
if (cond != cNO) t++;
|
|
|
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
|
if (calls_stacked>0) {
|
|
calls_stacked--;
|
|
printf("RET: calls still stacked: %i\n", calls_stacked);
|
|
} else {
|
|
printf("RET: BREAK\n");
|
|
options[Z80_OPTION_BREAK_ON_RET] = false;
|
|
z80debug::setcursor(rPC);
|
|
z80debug::history::store();
|
|
z80debug::stop();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
t++;
|
|
}
|
|
}
|
|
|
|
void RETN()
|
|
{
|
|
POP(_rPC);
|
|
iff1 = iff2;
|
|
|
|
if (options[Z80_OPTION_BREAK_ON_RET]) {
|
|
options[Z80_OPTION_BREAK_ON_RET] = false;
|
|
z80debug::setcursor(rPC);
|
|
z80debug::history::store();
|
|
z80debug::stop();
|
|
}
|
|
}
|
|
|
|
void RETI()
|
|
{
|
|
RETN();
|
|
}
|
|
|
|
void RST(uint8_t vec)
|
|
{
|
|
PUSH(rPC);
|
|
rPC = vec;
|
|
}
|
|
|
|
void IM(uint8_t mode)
|
|
{
|
|
im = mode;
|
|
}
|
|
|
|
void EX_MEM(uint16_t *reg, uint16_t addr)
|
|
{
|
|
auto temp = *reg;
|
|
*reg = READ_MEM_16(addr);
|
|
WRITE_MEM_16(addr, temp);
|
|
t+=3;
|
|
}
|
|
|
|
void DI()
|
|
{
|
|
iff1 = iff2 = 0;
|
|
}
|
|
|
|
void EI()
|
|
{
|
|
pending_ei=1;
|
|
}
|
|
|
|
void actualEI()
|
|
{
|
|
iff1 = iff2 = 1;
|
|
}
|
|
|
|
void HALT()
|
|
{
|
|
if (exit_from_halt) {
|
|
exit_from_halt = false;
|
|
} else {
|
|
//printf("HALT\n");
|
|
rPC--;
|
|
}
|
|
}
|
|
|
|
void interrupt()
|
|
{
|
|
if (!iff1) return;
|
|
DI();
|
|
exit_from_halt = true;
|
|
PUSH(rPC);
|
|
uint16_t address;
|
|
if (im==1) {
|
|
rPC = 0x38;
|
|
} else if (im==2) {
|
|
address = (rI<<8) | 0xFE;
|
|
rPC = READ_MEM_16(address);
|
|
} else if (im==0) {
|
|
printf("Interrupt mode 0!\n");
|
|
z80debug::stop();
|
|
return;
|
|
}
|
|
if (options[Z80_OPTION_BREAK_ON_INTERRUPT]) {
|
|
printf("Break on interrupt! 0x%2x, PC: 0x%2x\n", address, rPC);
|
|
z80debug::setcursor(rPC);
|
|
z80debug::history::store();
|
|
z80debug::stop();
|
|
}
|
|
}
|
|
|
|
static inline const uint8_t RLC(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v>>7) | (v<<1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (res&1) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t RRC(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v<<7) | (v>>1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (res&0x80) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t RL(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v<<1) | (rF&fC);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&0x80) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t RR(const uint8_t v)
|
|
{
|
|
const uint8_t res = ((rF&fC)<<7) | (v>>1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&1) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t SLA(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v<<1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&0x80) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t SRA(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v&0x80) | (v>>1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&1) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t SLL(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v<<1) | 1;
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&0x80) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
static inline const uint8_t SRL(const uint8_t v)
|
|
{
|
|
const uint8_t res = (v>>1);
|
|
rF=0;
|
|
FLAGS_SZXY(res);
|
|
if (v&1) SET_FLAGS(fC);
|
|
SET_PARITY_FLAG(res);
|
|
return res;
|
|
}
|
|
|
|
void BIT(uint8_t pos, uint8_t v)
|
|
{
|
|
const uint8_t res = v & 1<<pos;
|
|
KEEP_FLAGS(fC);
|
|
SET_FLAGS(fH);
|
|
if (!res) SET_FLAGS(fZ | fP);
|
|
if (res&0x80) SET_FLAGS(fS);
|
|
if (res&0x20) SET_FLAGS(fY);
|
|
if (res&0x08) SET_FLAGS(fX);
|
|
}
|
|
|
|
static inline const uint8_t SET(uint8_t pos, const uint8_t v)
|
|
{
|
|
return v | (1<<pos);
|
|
}
|
|
|
|
static inline const uint8_t RES(uint8_t pos, const uint8_t v)
|
|
{
|
|
return v & ~(1<<pos);
|
|
}
|
|
|
|
void LDI()
|
|
{
|
|
WRITE_MEM_8(rDE, READ_MEM_8(rHL));
|
|
rDE++;
|
|
rHL++;
|
|
rBC--;
|
|
t+=2;
|
|
KEEP_FLAGS(fS | fZ | fC);
|
|
if (rBC!=0) SET_FLAGS(fP);
|
|
}
|
|
|
|
void LDIR()
|
|
{
|
|
LDI();
|
|
if (rBC!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void LDD()
|
|
{
|
|
WRITE_MEM_8(rDE, READ_MEM_8(rHL));
|
|
rDE--;
|
|
rHL--;
|
|
rBC--;
|
|
t+=2;
|
|
KEEP_FLAGS(fS | fZ | fC);
|
|
if (rBC!=0) SET_FLAGS(fP);
|
|
}
|
|
|
|
void LDDR()
|
|
{
|
|
LDD();
|
|
if (rBC!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
uint8_t CPI()
|
|
{
|
|
bool keep_fC = (rF & fC);
|
|
const uint8_t hlmem = READ_MEM_8(rHL);
|
|
CP(hlmem);
|
|
rHL++;
|
|
rBC--;
|
|
t+=2;
|
|
KEEP_FLAGS(fS | fZ | fH | fN);
|
|
if (keep_fC) SET_FLAGS(fC);
|
|
if (rBC!=0) SET_FLAGS(fP);
|
|
//if (READ_MEM_8(rHL)==rA) SET_FLAGS(fZ);
|
|
return hlmem;
|
|
}
|
|
|
|
void CPIR()
|
|
{
|
|
const uint8_t hlmem = CPI();
|
|
if (rBC!=0 && hlmem!=rA)
|
|
{
|
|
rPC-=2;
|
|
t+=2;
|
|
}
|
|
}
|
|
|
|
void CPD()
|
|
{
|
|
bool keep_fC = (rF & fC);
|
|
CP(READ_MEM_8(rHL));
|
|
rHL--;
|
|
rBC--;
|
|
t+=2;
|
|
KEEP_FLAGS(fS | fZ | fH | fN);
|
|
if (keep_fC) SET_FLAGS(fC);
|
|
if (rBC!=0) SET_FLAGS(fP);
|
|
}
|
|
|
|
void CPDR()
|
|
{
|
|
CPD();
|
|
if (rBC!=0 && READ_MEM_8(rHL)!=rA)
|
|
{
|
|
rPC-=2;
|
|
t+=2;
|
|
}
|
|
}
|
|
|
|
const uint8_t IN(int port = 0x10000)
|
|
{
|
|
bool set_flags=true;
|
|
t+=4;
|
|
|
|
if (port == 0x10000) {
|
|
port = rBC;
|
|
} else {
|
|
set_flags=false;
|
|
port = (rA<<8) | port;
|
|
}
|
|
|
|
if (in_ports[port&0xff]) {
|
|
const uint8_t val = (uint8_t)in_ports[port&0xff](port);
|
|
if (set_flags) {
|
|
KEEP_FLAGS(fC);
|
|
SET_PARITY_FLAG(val);
|
|
FLAGS_SZXY(val);
|
|
}
|
|
return val;
|
|
} else
|
|
return 0xFF;
|
|
}
|
|
|
|
void OUT(uint8_t val, int port = 0x10000)
|
|
{
|
|
t+=4;
|
|
if (port == 0x10000) {
|
|
port = rBC;
|
|
}
|
|
if (out_ports[port&0xff]) out_ports[port&0xff](port, val);
|
|
}
|
|
|
|
void INI()
|
|
{
|
|
DEC8(_rB);
|
|
const uint8_t flags_after_dec = rF;
|
|
const uint8_t val = IN();
|
|
WRITE_MEM_8(rHL, val);
|
|
rHL++;
|
|
SET_FLAGS(flags_after_dec);
|
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
if (val&0x80) SET_FLAGS(fN);
|
|
uint16_t k = val + ((rC+1)&255);
|
|
if (k>255) SET_FLAGS(fH | fC);
|
|
SET_PARITY_FLAG((k&7)^rB);
|
|
t+=5;
|
|
}
|
|
|
|
void INIR()
|
|
{
|
|
INI();
|
|
if (rB!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void IND()
|
|
{
|
|
DEC8(_rB);
|
|
const uint8_t flags_after_dec = rF;
|
|
const uint8_t val = IN();
|
|
WRITE_MEM_8(rHL, val);
|
|
rHL--;
|
|
SET_FLAGS(flags_after_dec);
|
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
if (val&0x80) SET_FLAGS(fN);
|
|
uint16_t k = val + ((rC-1)&255);
|
|
if (k>255) SET_FLAGS(fH | fC);
|
|
SET_PARITY_FLAG((k&7)^rB);
|
|
t+=5;
|
|
}
|
|
|
|
void INDR()
|
|
{
|
|
IND();
|
|
if (rB!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void OUTI()
|
|
{
|
|
const uint8_t val = READ_MEM_8(rHL);
|
|
OUT(val);
|
|
rHL++;
|
|
DEC8(_rB);
|
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
if (val&0x80) SET_FLAGS(fN);
|
|
uint16_t k = rL+val;
|
|
if (k>255) SET_FLAGS(fH | fC);
|
|
SET_PARITY_FLAG((k&7)^rB);
|
|
t+=5;
|
|
}
|
|
|
|
void OUTIR()
|
|
{
|
|
OUTI();
|
|
if (rB!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void OUTD() {
|
|
const uint8_t val = READ_MEM_8(rHL);
|
|
OUT(val);
|
|
rHL--;
|
|
DEC8(_rB);
|
|
KEEP_FLAGS(fS | fZ | fY | fX);
|
|
if (val&0x80) SET_FLAGS(fN);
|
|
uint16_t k = rL+val;
|
|
if (k>255) SET_FLAGS(fH | fC);
|
|
SET_PARITY_FLAG((k&7)^rB);
|
|
t+=5;
|
|
}
|
|
|
|
void OUTDR() {
|
|
OUTD();
|
|
if (rB!=0)
|
|
{
|
|
rPC-=2;
|
|
t+=5;
|
|
}
|
|
}
|
|
|
|
void INVALID(uint8_t opcode)
|
|
{
|
|
printf("INVALID OPCODE AT: %04x\n", current_opcode_address);
|
|
if (options[Z80_OPTION_STOP_ON_INVALID]) z80debug::stop();
|
|
}
|
|
|
|
void reset(uint8_t* mem)
|
|
{
|
|
memory = mem;
|
|
for (int i=0; i<65536; ++i) memtag[i] = MEMTAG_NONE;
|
|
rPC = iff1 = iff2 = im = 0;
|
|
rAF = rAF2 = rBC = rBC2 = rDE = rDE2 = rHL = rHL2 = rIX = rIY = rSP = 0xffff;
|
|
t = 0;
|
|
for (int i=0; i<256; ++i)
|
|
{
|
|
in_ports[i] = nullptr;
|
|
out_ports[i] = nullptr;
|
|
}
|
|
}
|
|
|
|
void BIT_INSTRUCTIONS();
|
|
void IX_INSTRUCTIONS();
|
|
void IX_BIT_INSTRUCTIONS();
|
|
void MISC_INSTRUCTIONS();
|
|
void IY_INSTRUCTIONS();
|
|
void IY_BIT_INSTRUCTIONS();
|
|
|
|
void connect_port(int num, int (*in_ptr)(int), void (*out_ptr)(int,int))
|
|
{
|
|
if (in_ptr) in_ports[num] = in_ptr;
|
|
if (out_ptr) out_ports[num] = out_ptr;
|
|
}
|
|
|
|
bool opcode_ignored = false;
|
|
uint32_t step()
|
|
{
|
|
do {
|
|
opcode_ignored = false;
|
|
current_opcode_address = rPC;
|
|
t = 0;
|
|
const uint8_t opcode = READ_M1();
|
|
if (memtag[current_opcode_address] != MEMTAG_IGNORE) memtag[current_opcode_address] = MEMTAG_INST;
|
|
memtouched[current_opcode_address] = memtouched[current_opcode_address] != MEMTAG_NONE ? MEMTAG_REPEAT : MEMTAG_INST;
|
|
uint16_t tmp;
|
|
|
|
if (opcode!=0xED && opcode!=0xCB && opcode!=0xDD && opcode!=0xFD ) z80debug::useOpcode(opcode, 0);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: /* NOP */ break;
|
|
case 0x01: rBC = READ_MEM_16(); break;
|
|
case 0x02: WRITE_MEM_8(rBC, rA); break;
|
|
case 0x03: INC16(_rBC); break;
|
|
case 0x04: INC8(_rB); break;
|
|
case 0x05: DEC8(_rB); break;
|
|
case 0x06: rB = READ_MEM_8(); break;
|
|
case 0x07: RLCA(); break;
|
|
case 0x08: EX(rAF, rAF2); break;
|
|
case 0x09: ADD16(_rHL, rBC); break;
|
|
case 0x0A: rA = READ_MEM_8(rBC); break;
|
|
case 0x0B: DEC16(_rBC); break;
|
|
case 0x0C: INC8(_rC); break;
|
|
case 0x0D: DEC8(_rC); break;
|
|
case 0x0E: rC = READ_MEM_8(); break;
|
|
case 0x0F: RRCA(); break;
|
|
|
|
case 0x10: DJNZ(); break;
|
|
case 0x11: rDE = READ_MEM_16(); break;
|
|
case 0x12: WRITE_MEM_8(rDE, rA); break;
|
|
case 0x13: INC16(_rDE); break;
|
|
case 0x14: INC8(_rD); break;
|
|
case 0x15: DEC8(_rD); break;
|
|
case 0x16: rD = READ_MEM_8(); break;
|
|
case 0x17: RLA(); break;
|
|
case 0x18: JR(); break;
|
|
case 0x19: ADD16(_rHL, rDE); break;
|
|
case 0x1A: rA = READ_MEM_8(rDE); break;
|
|
case 0x1B: DEC16(_rDE); break;
|
|
case 0x1C: INC8(_rE); break;
|
|
case 0x1D: DEC8(_rE); break;
|
|
case 0x1E: rE = READ_MEM_8(); break;
|
|
case 0x1F: RRA(); break;
|
|
|
|
case 0x20: JR(cNZ); break;
|
|
case 0x21: rHL = READ_MEM_16(); break;
|
|
case 0x22: WRITE_MEM_16(READ_MEM_16(), rHL);break;
|
|
case 0x23: INC16(_rHL); break;
|
|
case 0x24: INC8(_rH); break;
|
|
case 0x25: DEC8(_rH); break;
|
|
case 0x26: rH = READ_MEM_8(); break;
|
|
case 0x27: DAA(); break;
|
|
case 0x28: JR(cZ); break;
|
|
case 0x29: ADD16(_rHL, rHL); break;
|
|
case 0x2A: rHL = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x2B: DEC16(_rHL); break;
|
|
case 0x2C: INC8(_rL); break;
|
|
case 0x2D: DEC8(_rL); break;
|
|
case 0x2E: rL = READ_MEM_8(); break;
|
|
case 0x2F: CPL(); break;
|
|
|
|
case 0x30: JR(cNC); break;
|
|
case 0x31: rSP = READ_MEM_16(); break;
|
|
case 0x32: WRITE_MEM_8(READ_MEM_16(), rA); break;
|
|
case 0x33: INC16(_rSP); break;
|
|
case 0x34: INCMEM8(rHL); break;
|
|
case 0x35: DECMEM8(rHL); break;
|
|
case 0x36: WRITE_MEM_8(rHL, READ_MEM_8()); break;
|
|
case 0x37: SCF(); break;
|
|
case 0x38: JR(cC); break;
|
|
case 0x39: ADD16(_rHL, rSP); break;
|
|
case 0x3A: rA = READ_MEM_8(READ_MEM_16()); break;
|
|
case 0x3B: DEC16(_rSP); break;
|
|
case 0x3C: INC8(_rA); break;
|
|
case 0x3D: DEC8(_rA); break;
|
|
case 0x3E: rA = READ_MEM_8(); break;
|
|
case 0x3F: CCF(); break;
|
|
|
|
case 0x40: rB = rB; break;
|
|
case 0x41: rB = rC; break;
|
|
case 0x42: rB = rD; break;
|
|
case 0x43: rB = rE; break;
|
|
case 0x44: rB = rH; break;
|
|
case 0x45: rB = rL; break;
|
|
case 0x46: rB = READ_MEM_8(rHL); break;
|
|
case 0x47: rB = rA; break;
|
|
case 0x48: rC = rB; break;
|
|
case 0x49: rC = rC; break;
|
|
case 0x4A: rC = rD; break;
|
|
case 0x4B: rC = rE; break;
|
|
case 0x4C: rC = rH; break;
|
|
case 0x4D: rC = rL; break;
|
|
case 0x4E: rC = READ_MEM_8(rHL); break;
|
|
case 0x4F: rC = rA; break;
|
|
|
|
case 0x50: rD = rB; break;
|
|
case 0x51: rD = rC; break;
|
|
case 0x52: rD = rD; break;
|
|
case 0x53: rD = rE; break;
|
|
case 0x54: rD = rH; break;
|
|
case 0x55: rD = rL; break;
|
|
case 0x56: rD = READ_MEM_8(rHL); break;
|
|
case 0x57: rD = rA; break;
|
|
case 0x58: rE = rB; break;
|
|
case 0x59: rE = rC; break;
|
|
case 0x5A: rE = rD; break;
|
|
case 0x5B: rE = rE; break;
|
|
case 0x5C: rE = rH; break;
|
|
case 0x5D: rE = rL; break;
|
|
case 0x5E: rE = READ_MEM_8(rHL); break;
|
|
case 0x5F: rE = rA; break;
|
|
|
|
case 0x60: rH = rB; break;
|
|
case 0x61: rH = rC; break;
|
|
case 0x62: rH = rD; break;
|
|
case 0x63: rH = rE; break;
|
|
case 0x64: rH = rH; break;
|
|
case 0x65: rH = rL; break;
|
|
case 0x66: rH = READ_MEM_8(rHL); break;
|
|
case 0x67: rH = rA; break;
|
|
case 0x68: rL = rB; break;
|
|
case 0x69: rL = rC; break;
|
|
case 0x6A: rL = rD; break;
|
|
case 0x6B: rL = rE; break;
|
|
case 0x6C: rL = rH; break;
|
|
case 0x6D: rL = rL; break;
|
|
case 0x6E: rL = READ_MEM_8(rHL); break;
|
|
case 0x6F: rL = rA; break;
|
|
|
|
case 0x70: WRITE_MEM_8(rHL, rB); break;
|
|
case 0x71: WRITE_MEM_8(rHL, rC); break;
|
|
case 0x72: WRITE_MEM_8(rHL, rD); break;
|
|
case 0x73: WRITE_MEM_8(rHL, rE); break;
|
|
case 0x74: WRITE_MEM_8(rHL, rH); break;
|
|
case 0x75: WRITE_MEM_8(rHL, rL); break;
|
|
case 0x76: HALT(); break;
|
|
case 0x77: WRITE_MEM_8(rHL, rA); break;
|
|
case 0x78: rA = rB; break;
|
|
case 0x79: rA = rC; break;
|
|
case 0x7A: rA = rD; break;
|
|
case 0x7B: rA = rE; break;
|
|
case 0x7C: rA = rH; break;
|
|
case 0x7D: rA = rL; break;
|
|
case 0x7E: rA = READ_MEM_8(rHL); break;
|
|
case 0x7F: rA = rA; break;
|
|
|
|
case 0x80: ADD8(rB); break;
|
|
case 0x81: ADD8(rC); break;
|
|
case 0x82: ADD8(rD); break;
|
|
case 0x83: ADD8(rE); break;
|
|
case 0x84: ADD8(rH); break;
|
|
case 0x85: ADD8(rL); break;
|
|
case 0x86: ADD8(READ_MEM_8(rHL)); break;
|
|
case 0x87: ADD8(rA); break;
|
|
case 0x88: ADC8(rB); break;
|
|
case 0x89: ADC8(rC); break;
|
|
case 0x8A: ADC8(rD); break;
|
|
case 0x8B: ADC8(rE); break;
|
|
case 0x8C: ADC8(rH); break;
|
|
case 0x8D: ADC8(rL); break;
|
|
case 0x8E: ADC8(READ_MEM_8(rHL)); break;
|
|
case 0x8F: ADC8(rA); break;
|
|
|
|
case 0x90: SUB8(rB); break;
|
|
case 0x91: SUB8(rC); break;
|
|
case 0x92: SUB8(rD); break;
|
|
case 0x93: SUB8(rE); break;
|
|
case 0x94: SUB8(rH); break;
|
|
case 0x95: SUB8(rL); break;
|
|
case 0x96: SUB8(READ_MEM_8(rHL)); break;
|
|
case 0x97: SUB8(rA); break;
|
|
case 0x98: SBC8(rB); break;
|
|
case 0x99: SBC8(rC); break;
|
|
case 0x9A: SBC8(rD); break;
|
|
case 0x9B: SBC8(rE); break;
|
|
case 0x9C: SBC8(rH); break;
|
|
case 0x9D: SBC8(rL); break;
|
|
case 0x9E: SBC8(READ_MEM_8(rHL)); break;
|
|
case 0x9F: SBC8(rA); break;
|
|
|
|
case 0xA0: AND(rB); break;
|
|
case 0xA1: AND(rC); break;
|
|
case 0xA2: AND(rD); break;
|
|
case 0xA3: AND(rE); break;
|
|
case 0xA4: AND(rH); break;
|
|
case 0xA5: AND(rL); break;
|
|
case 0xA6: AND(READ_MEM_8(rHL)); break;
|
|
case 0xA7: AND(rA); break;
|
|
case 0xA8: XOR(rB); break;
|
|
case 0xA9: XOR(rC); break;
|
|
case 0xAA: XOR(rD); break;
|
|
case 0xAB: XOR(rE); break;
|
|
case 0xAC: XOR(rH); break;
|
|
case 0xAD: XOR(rL); break;
|
|
case 0xAE: XOR(READ_MEM_8(rHL)); break;
|
|
case 0xAF: XOR(rA); break;
|
|
|
|
case 0xB0: OR(rB); break;
|
|
case 0xB1: OR(rC); break;
|
|
case 0xB2: OR(rD); break;
|
|
case 0xB3: OR(rE); break;
|
|
case 0xB4: OR(rH); break;
|
|
case 0xB5: OR(rL); break;
|
|
case 0xB6: OR(READ_MEM_8(rHL)); break;
|
|
case 0xB7: OR(rA); break;
|
|
case 0xB8: CP(rB); break;
|
|
case 0xB9: CP(rC); break;
|
|
case 0xBA: CP(rD); break;
|
|
case 0xBB: CP(rE); break;
|
|
case 0xBC: CP(rH); break;
|
|
case 0xBD: CP(rL); break;
|
|
case 0xBE: CP(READ_MEM_8(rHL)); break;
|
|
case 0xBF: CP(rA); break;
|
|
|
|
case 0xC0: RET(cNZ); break;
|
|
case 0xC1: POP(_rBC); break;
|
|
case 0xC2: JP(cNZ, READ_MEM_16()); break;
|
|
case 0xC3: JP(cNO, READ_MEM_16()); break;
|
|
case 0xC4: CALL(cNZ, READ_MEM_16()); break;
|
|
case 0xC5: PUSH(rBC); break;
|
|
case 0xC6: ADD8(READ_MEM_8()); break;
|
|
case 0xC7: RST(0x00); break;
|
|
case 0xC8: RET(cZ); break;
|
|
case 0xC9: RET(cNO); break;
|
|
case 0xCA: JP(cZ, READ_MEM_16()); break;
|
|
case 0xCB: BIT_INSTRUCTIONS(); break;
|
|
case 0xCC: CALL(cZ, READ_MEM_16()); break;
|
|
case 0xCD: CALL(cNO, READ_MEM_16()); break;
|
|
case 0xCE: ADC8(READ_MEM_8()); break;
|
|
case 0xCF: RST(0x08); break;
|
|
|
|
case 0xD0: RET(cNC); break;
|
|
case 0xD1: POP(_rDE); break;
|
|
case 0xD2: JP(cNC, READ_MEM_16()); break;
|
|
case 0xD3: OUT(rA, READ_MEM_8()); break;
|
|
case 0xD4: CALL(cNC, READ_MEM_16()); break;
|
|
case 0xD5: PUSH(rDE); break;
|
|
case 0xD6: SUB8(READ_MEM_8()); break;
|
|
case 0xD7: RST(0x10); break;
|
|
case 0xD8: RET(cC); break;
|
|
case 0xD9: EX(rBC, rBC2);EX(rDE, rDE2);EX(rHL, rHL2); break;
|
|
case 0xDA: JP(cC, READ_MEM_16()); break;
|
|
case 0xDB: rA = IN(READ_MEM_8()); break;
|
|
case 0xDC: CALL(cC, READ_MEM_16()); break;
|
|
case 0xDD: IX_INSTRUCTIONS(); break;
|
|
case 0xDE: SBC8(READ_MEM_8()); break;
|
|
case 0xDF: RST(0x18); break;
|
|
|
|
case 0xE0: RET(cPO); break;
|
|
case 0xE1: POP(_rHL); break;
|
|
case 0xE2: JP(cPO, READ_MEM_16()); break;
|
|
case 0xE3: EX_MEM(_rHL, rSP); break;
|
|
case 0xE4: CALL(cPO, READ_MEM_16()); break;
|
|
case 0xE5: PUSH(rHL); break;
|
|
case 0xE6: AND(READ_MEM_8()); break;
|
|
case 0xE7: RST(0x20); break;
|
|
case 0xE8: RET(cPE); break;
|
|
case 0xE9: JP(cNO, rHL); break;
|
|
case 0xEA: JP(cPE, READ_MEM_16()); break;
|
|
case 0xEB: EX(rDE, rHL); break;
|
|
case 0xEC: CALL(cPE, READ_MEM_16()); break;
|
|
case 0xED: MISC_INSTRUCTIONS(); break;
|
|
case 0xEE: XOR(READ_MEM_8()); break;
|
|
case 0xEF: RST(0x28); break;
|
|
|
|
case 0xF0: RET(cP); break;
|
|
case 0xF1: POP(_rAF); break;
|
|
case 0xF2: JP(cP, READ_MEM_16()); break;
|
|
case 0xF3: DI(); break;
|
|
case 0xF4: CALL(cP, READ_MEM_16()); break;
|
|
case 0xF5: PUSH(rAF); break;
|
|
case 0xF6: OR(READ_MEM_8()); break;
|
|
case 0xF7: RST(0x30); break;
|
|
case 0xF8: RET(cM); break;
|
|
case 0xF9: rSP = rHL; t+=2; break;
|
|
case 0xFA: JP(cM, READ_MEM_16()); break;
|
|
case 0xFB: EI(); break;
|
|
case 0xFC: CALL(cM, READ_MEM_16()); break;
|
|
case 0xFD: IY_INSTRUCTIONS(); break;
|
|
case 0xFE: CP(READ_MEM_8()); break;
|
|
case 0xFF: RST(0x38); break;
|
|
}
|
|
|
|
} while (opcode_ignored);
|
|
|
|
if (pending_ei==2) { pending_ei=0; actualEI(); }
|
|
if (pending_ei==1) pending_ei=2;
|
|
|
|
z80debug::setcursor(rPC);
|
|
z80debug::history::store();
|
|
return t;
|
|
}
|
|
|
|
void BIT_INSTRUCTIONS()
|
|
{
|
|
const uint8_t opcode = READ_M1();
|
|
|
|
z80debug::useOpcode(opcode, 2);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: rB = RLC(rB); break;
|
|
case 0x01: rC = RLC(rC); break;
|
|
case 0x02: rD = RLC(rD); break;
|
|
case 0x03: rE = RLC(rE); break;
|
|
case 0x04: rH = RLC(rH); break;
|
|
case 0x05: rL = RLC(rL); break;
|
|
case 0x06: WRITE_MEM_8(rHL, RLC(READ_MEM_8(rHL)));t++;break;
|
|
case 0x07: rA = RLC(rA); break;
|
|
case 0x08: rB = RRC(rB); break;
|
|
case 0x09: rC = RRC(rC); break;
|
|
case 0x0A: rD = RRC(rD); break;
|
|
case 0x0B: rE = RRC(rE); break;
|
|
case 0x0C: rH = RRC(rH); break;
|
|
case 0x0D: rL = RRC(rL); break;
|
|
case 0x0E: WRITE_MEM_8(rHL, RRC(READ_MEM_8(rHL)));t++;break;
|
|
case 0x0F: rA = RRC(rA); break;
|
|
|
|
case 0x10: rB = RL(rB); break;
|
|
case 0x11: rC = RL(rC); break;
|
|
case 0x12: rD = RL(rD); break;
|
|
case 0x13: rE = RL(rE); break;
|
|
case 0x14: rH = RL(rH); break;
|
|
case 0x15: rL = RL(rL); break;
|
|
case 0x16: WRITE_MEM_8(rHL, RL(READ_MEM_8(rHL)));t++;break;
|
|
case 0x17: rA = RL(rA); break;
|
|
case 0x18: rB = RR(rB); break;
|
|
case 0x19: rC = RR(rC); break;
|
|
case 0x1A: rD = RR(rD); break;
|
|
case 0x1B: rE = RR(rE); break;
|
|
case 0x1C: rH = RR(rH); break;
|
|
case 0x1D: rL = RR(rL); break;
|
|
case 0x1E: WRITE_MEM_8(rHL, RR(READ_MEM_8(rHL)));t++;break;
|
|
case 0x1F: rA = RR(rA); break;
|
|
|
|
case 0x20: rB = SLA(rB); break;
|
|
case 0x21: rC = SLA(rC); break;
|
|
case 0x22: rD = SLA(rD); break;
|
|
case 0x23: rE = SLA(rE); break;
|
|
case 0x24: rH = SLA(rH); break;
|
|
case 0x25: rL = SLA(rL); break;
|
|
case 0x26: WRITE_MEM_8(rHL, SLA(READ_MEM_8(rHL)));t++;break;
|
|
case 0x27: rA = SLA(rA); break;
|
|
case 0x28: rB = SRA(rB); break;
|
|
case 0x29: rC = SRA(rC); break;
|
|
case 0x2A: rD = SRA(rD); break;
|
|
case 0x2B: rE = SRA(rE); break;
|
|
case 0x2C: rH = SRA(rH); break;
|
|
case 0x2D: rL = SRA(rL); break;
|
|
case 0x2E: WRITE_MEM_8(rHL, SRA(READ_MEM_8(rHL)));t++;break;
|
|
case 0x2F: rA = SRA(rA); break;
|
|
|
|
case 0x30: rB = SLL(rB); break;
|
|
case 0x31: rC = SLL(rC); break;
|
|
case 0x32: rD = SLL(rD); break;
|
|
case 0x33: rE = SLL(rE); break;
|
|
case 0x34: rH = SLL(rH); break;
|
|
case 0x35: rL = SLL(rL); break;
|
|
case 0x36: WRITE_MEM_8(rHL, SLL(READ_MEM_8(rHL)));t++;break;
|
|
case 0x37: rA = SLL(rA); break;
|
|
case 0x38: rB = SRL(rB); break;
|
|
case 0x39: rC = SRL(rC); break;
|
|
case 0x3A: rD = SRL(rD); break;
|
|
case 0x3B: rE = SRL(rE); break;
|
|
case 0x3C: rH = SRL(rH); break;
|
|
case 0x3D: rL = SRL(rL); break;
|
|
case 0x3E: WRITE_MEM_8(rHL, SRL(READ_MEM_8(rHL)));t++;break;
|
|
case 0x3F: rA = SRL(rA); break;
|
|
|
|
case 0x40: BIT(0, rB); break;
|
|
case 0x41: BIT(0, rC); break;
|
|
case 0x42: BIT(0, rD); break;
|
|
case 0x43: BIT(0, rE); break;
|
|
case 0x44: BIT(0, rH); break;
|
|
case 0x45: BIT(0, rL); break;
|
|
case 0x46: BIT(0, READ_MEM_8(rHL)); t++; break;
|
|
case 0x47: BIT(0, rA); break;
|
|
case 0x48: BIT(1, rB); break;
|
|
case 0x49: BIT(1, rC); break;
|
|
case 0x4A: BIT(1, rD); break;
|
|
case 0x4B: BIT(1, rE); break;
|
|
case 0x4C: BIT(1, rH); break;
|
|
case 0x4D: BIT(1, rL); break;
|
|
case 0x4E: BIT(1, READ_MEM_8(rHL)); t++; break;
|
|
case 0x4F: BIT(1, rA); break;
|
|
|
|
case 0x50: BIT(2, rB); break;
|
|
case 0x51: BIT(2, rC); break;
|
|
case 0x52: BIT(2, rD); break;
|
|
case 0x53: BIT(2, rE); break;
|
|
case 0x54: BIT(2, rH); break;
|
|
case 0x55: BIT(2, rL); break;
|
|
case 0x56: BIT(2, READ_MEM_8(rHL)); t++; break;
|
|
case 0x57: BIT(2, rA); break;
|
|
case 0x58: BIT(3, rB); break;
|
|
case 0x59: BIT(3, rC); break;
|
|
case 0x5A: BIT(3, rD); break;
|
|
case 0x5B: BIT(3, rE); break;
|
|
case 0x5C: BIT(3, rH); break;
|
|
case 0x5D: BIT(3, rL); break;
|
|
case 0x5E: BIT(3, READ_MEM_8(rHL)); t++; break;
|
|
case 0x5F: BIT(3, rA); break;
|
|
|
|
case 0x60: BIT(4, rB); break;
|
|
case 0x61: BIT(4, rC); break;
|
|
case 0x62: BIT(4, rD); break;
|
|
case 0x63: BIT(4, rE); break;
|
|
case 0x64: BIT(4, rH); break;
|
|
case 0x65: BIT(4, rL); break;
|
|
case 0x66: BIT(4, READ_MEM_8(rHL)); t++; break;
|
|
case 0x67: BIT(4, rA); break;
|
|
case 0x68: BIT(5, rB); break;
|
|
case 0x69: BIT(5, rC); break;
|
|
case 0x6A: BIT(5, rD); break;
|
|
case 0x6B: BIT(5, rE); break;
|
|
case 0x6C: BIT(5, rH); break;
|
|
case 0x6D: BIT(5, rL); break;
|
|
case 0x6E: BIT(5, READ_MEM_8(rHL)); t++; break;
|
|
case 0x6F: BIT(5, rA); break;
|
|
|
|
case 0x70: BIT(6, rB); break;
|
|
case 0x71: BIT(6, rC); break;
|
|
case 0x72: BIT(6, rD); break;
|
|
case 0x73: BIT(6, rE); break;
|
|
case 0x74: BIT(6, rH); break;
|
|
case 0x75: BIT(6, rL); break;
|
|
case 0x76: BIT(6, READ_MEM_8(rHL)); t++; break;
|
|
case 0x77: BIT(6, rA); break;
|
|
case 0x78: BIT(7, rB); break;
|
|
case 0x79: BIT(7, rC); break;
|
|
case 0x7A: BIT(7, rD); break;
|
|
case 0x7B: BIT(7, rE); break;
|
|
case 0x7C: BIT(7, rH); break;
|
|
case 0x7D: BIT(7, rL); break;
|
|
case 0x7E: BIT(7, READ_MEM_8(rHL)); t++; break;
|
|
case 0x7F: BIT(7, rA); break;
|
|
|
|
case 0x80: rB = RES(0, rB); break;
|
|
case 0x81: rC = RES(0, rC); break;
|
|
case 0x82: rD = RES(0, rD); break;
|
|
case 0x83: rE = RES(0, rE); break;
|
|
case 0x84: rH = RES(0, rH); break;
|
|
case 0x85: rL = RES(0, rL); break;
|
|
case 0x86: WRITE_MEM_8(rHL, RES(0, READ_MEM_8(rHL)));t++;break;
|
|
case 0x87: rA = RES(0, rA); break;
|
|
case 0x88: rB = RES(1, rB); break;
|
|
case 0x89: rC = RES(1, rC); break;
|
|
case 0x8A: rD = RES(1, rD); break;
|
|
case 0x8B: rE = RES(1, rE); break;
|
|
case 0x8C: rH = RES(1, rH); break;
|
|
case 0x8D: rL = RES(1, rL); break;
|
|
case 0x8E: WRITE_MEM_8(rHL, RES(1, READ_MEM_8(rHL)));t++;break;
|
|
case 0x8F: rA = RES(1, rA); break;
|
|
|
|
case 0x90: rB = RES(2, rB); break;
|
|
case 0x91: rC = RES(2, rC); break;
|
|
case 0x92: rD = RES(2, rD); break;
|
|
case 0x93: rE = RES(2, rE); break;
|
|
case 0x94: rH = RES(2, rH); break;
|
|
case 0x95: rL = RES(2, rL); break;
|
|
case 0x96: WRITE_MEM_8(rHL, RES(2, READ_MEM_8(rHL)));t++;break;
|
|
case 0x97: rA = RES(2, rA); break;
|
|
case 0x98: rB = RES(3, rB); break;
|
|
case 0x99: rC = RES(3, rC); break;
|
|
case 0x9A: rD = RES(3, rD); break;
|
|
case 0x9B: rE = RES(3, rE); break;
|
|
case 0x9C: rH = RES(3, rH); break;
|
|
case 0x9D: rL = RES(3, rL); break;
|
|
case 0x9E: WRITE_MEM_8(rHL, RES(3, READ_MEM_8(rHL)));t++;break;
|
|
case 0x9F: rA = RES(3, rA); break;
|
|
|
|
case 0xA0: rB = RES(4, rB); break;
|
|
case 0xA1: rC = RES(4, rC); break;
|
|
case 0xA2: rD = RES(4, rD); break;
|
|
case 0xA3: rE = RES(4, rE); break;
|
|
case 0xA4: rH = RES(4, rH); break;
|
|
case 0xA5: rL = RES(4, rL); break;
|
|
case 0xA6: WRITE_MEM_8(rHL, RES(4, READ_MEM_8(rHL)));t++;break;
|
|
case 0xA7: rA = RES(4, rA); break;
|
|
case 0xA8: rB = RES(5, rB); break;
|
|
case 0xA9: rC = RES(5, rC); break;
|
|
case 0xAA: rD = RES(5, rD); break;
|
|
case 0xAB: rE = RES(5, rE); break;
|
|
case 0xAC: rH = RES(5, rH); break;
|
|
case 0xAD: rL = RES(5, rL); break;
|
|
case 0xAE: WRITE_MEM_8(rHL, RES(5, READ_MEM_8(rHL)));t++;break;
|
|
case 0xAF: rA = RES(5, rA); break;
|
|
|
|
case 0xB0: rB = RES(6, rB); break;
|
|
case 0xB1: rC = RES(6, rC); break;
|
|
case 0xB2: rD = RES(6, rD); break;
|
|
case 0xB3: rE = RES(6, rE); break;
|
|
case 0xB4: rH = RES(6, rH); break;
|
|
case 0xB5: rL = RES(6, rL); break;
|
|
case 0xB6: WRITE_MEM_8(rHL, RES(6, READ_MEM_8(rHL)));t++;break;
|
|
case 0xB7: rA = RES(6, rA); break;
|
|
case 0xB8: rB = RES(7, rB); break;
|
|
case 0xB9: rC = RES(7, rC); break;
|
|
case 0xBA: rD = RES(7, rD); break;
|
|
case 0xBB: rE = RES(7, rE); break;
|
|
case 0xBC: rH = RES(7, rH); break;
|
|
case 0xBD: rL = RES(7, rL); break;
|
|
case 0xBE: WRITE_MEM_8(rHL, RES(7, READ_MEM_8(rHL)));t++;break;
|
|
case 0xBF: rA = RES(7, rA); break;
|
|
|
|
case 0xC0: rB = SET(0, rB); break;
|
|
case 0xC1: rC = SET(0, rC); break;
|
|
case 0xC2: rD = SET(0, rD); break;
|
|
case 0xC3: rE = SET(0, rE); break;
|
|
case 0xC4: rH = SET(0, rH); break;
|
|
case 0xC5: rL = SET(0, rL); break;
|
|
case 0xC6: WRITE_MEM_8(rHL, SET(0, READ_MEM_8(rHL)));t++;break;
|
|
case 0xC7: rA = SET(0, rA); break;
|
|
case 0xC8: rB = SET(1, rB); break;
|
|
case 0xC9: rC = SET(1, rC); break;
|
|
case 0xCA: rD = SET(1, rD); break;
|
|
case 0xCB: rE = SET(1, rE); break;
|
|
case 0xCC: rH = SET(1, rH); break;
|
|
case 0xCD: rL = SET(1, rL); break;
|
|
case 0xCE: WRITE_MEM_8(rHL, SET(1, READ_MEM_8(rHL)));t++;break;
|
|
case 0xCF: rA = SET(1, rA); break;
|
|
|
|
case 0xD0: rB = SET(2, rB); break;
|
|
case 0xD1: rC = SET(2, rC); break;
|
|
case 0xD2: rD = SET(2, rD); break;
|
|
case 0xD3: rE = SET(2, rE); break;
|
|
case 0xD4: rH = SET(2, rH); break;
|
|
case 0xD5: rL = SET(2, rL); break;
|
|
case 0xD6: WRITE_MEM_8(rHL, SET(2, READ_MEM_8(rHL)));t++;break;
|
|
case 0xD7: rA = SET(2, rA); break;
|
|
case 0xD8: rB = SET(3, rB); break;
|
|
case 0xD9: rC = SET(3, rC); break;
|
|
case 0xDA: rD = SET(3, rD); break;
|
|
case 0xDB: rE = SET(3, rE); break;
|
|
case 0xDC: rH = SET(3, rH); break;
|
|
case 0xDD: rL = SET(3, rL); break;
|
|
case 0xDE: WRITE_MEM_8(rHL, SET(3, READ_MEM_8(rHL)));t++;break;
|
|
case 0xDF: rA = SET(3, rA); break;
|
|
|
|
case 0xE0: rB = SET(4, rB); break;
|
|
case 0xE1: rC = SET(4, rC); break;
|
|
case 0xE2: rD = SET(4, rD); break;
|
|
case 0xE3: rE = SET(4, rE); break;
|
|
case 0xE4: rH = SET(4, rH); break;
|
|
case 0xE5: rL = SET(4, rL); break;
|
|
case 0xE6: WRITE_MEM_8(rHL, SET(4, READ_MEM_8(rHL)));t++;break;
|
|
case 0xE7: rA = SET(4, rA); break;
|
|
case 0xE8: rB = SET(5, rB); break;
|
|
case 0xE9: rC = SET(5, rC); break;
|
|
case 0xEA: rD = SET(5, rD); break;
|
|
case 0xEB: rE = SET(5, rE); break;
|
|
case 0xEC: rH = SET(5, rH); break;
|
|
case 0xED: rL = SET(5, rL); break;
|
|
case 0xEE: WRITE_MEM_8(rHL, SET(5, READ_MEM_8(rHL)));t++;break;
|
|
case 0xEF: rA = SET(5, rA); break;
|
|
|
|
case 0xF0: rB = SET(6, rB); break;
|
|
case 0xF1: rC = SET(6, rC); break;
|
|
case 0xF2: rD = SET(6, rD); break;
|
|
case 0xF3: rE = SET(6, rE); break;
|
|
case 0xF4: rH = SET(6, rH); break;
|
|
case 0xF5: rL = SET(6, rL); break;
|
|
case 0xF6: WRITE_MEM_8(rHL, SET(6, READ_MEM_8(rHL)));t++;break;
|
|
case 0xF7: rA = SET(6, rA); break;
|
|
case 0xF8: rB = SET(7, rB); break;
|
|
case 0xF9: rC = SET(7, rC); break;
|
|
case 0xFA: rD = SET(7, rD); break;
|
|
case 0xFB: rE = SET(7, rE); break;
|
|
case 0xFC: rH = SET(7, rH); break;
|
|
case 0xFD: rL = SET(7, rL); break;
|
|
case 0xFE: WRITE_MEM_8(rHL, SET(7, READ_MEM_8(rHL)));t++;break;
|
|
case 0xFF: rA = SET(7, rA); break;
|
|
}
|
|
}
|
|
|
|
void IgnoreOpcode()
|
|
{
|
|
t-=3;
|
|
rPC--;
|
|
opcode_ignored=true;
|
|
}
|
|
|
|
void IX_INSTRUCTIONS()
|
|
{
|
|
const uint8_t opcode = READ_M1();
|
|
int8_t d;
|
|
|
|
if (opcode!=0xCB) z80debug::useOpcode(opcode, 3);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: IgnoreOpcode(); break;
|
|
case 0x01: IgnoreOpcode(); break;
|
|
case 0x02: IgnoreOpcode(); break;
|
|
case 0x03: IgnoreOpcode(); break;
|
|
case 0x04: INC8(_rB); break;
|
|
case 0x05: DEC8(_rB); break;
|
|
case 0x06: rB = READ_MEM_8(); break;
|
|
case 0x07: IgnoreOpcode(); break;
|
|
case 0x08: IgnoreOpcode(); break;
|
|
case 0x09: ADD16(_rIX, rBC); break;
|
|
case 0x0A: IgnoreOpcode(); break;
|
|
case 0x0B: IgnoreOpcode(); break;
|
|
case 0x0C: INC8(_rC); break;
|
|
case 0x0D: DEC8(_rC); break;
|
|
case 0x0E: rC = READ_MEM_8(); break;
|
|
case 0x0F: IgnoreOpcode(); break;
|
|
|
|
case 0x10: IgnoreOpcode(); break;
|
|
case 0x11: IgnoreOpcode(); break;
|
|
case 0x12: IgnoreOpcode(); break;
|
|
case 0x13: IgnoreOpcode(); break;
|
|
case 0x14: INC8(_rD); break;
|
|
case 0x15: DEC8(_rD); break;
|
|
case 0x16: rD = READ_MEM_8(); break;
|
|
case 0x17: IgnoreOpcode(); break;
|
|
case 0x18: IgnoreOpcode(); break;
|
|
case 0x19: ADD16(_rIX, rDE); break;
|
|
case 0x1A: IgnoreOpcode(); break;
|
|
case 0x1B: IgnoreOpcode(); break;
|
|
case 0x1C: INC8(_rE); break;
|
|
case 0x1D: DEC8(_rE); break;
|
|
case 0x1E: rE = READ_MEM_8(); break;
|
|
case 0x1F: IgnoreOpcode(); break;
|
|
|
|
case 0x20: IgnoreOpcode(); break;
|
|
case 0x21: rIX = READ_MEM_16(); break;
|
|
case 0x22: WRITE_MEM_16(READ_MEM_16(),rIX); break;
|
|
case 0x23: INC16(_rIX); break;
|
|
case 0x24: INC8(_rIXH); break;
|
|
case 0x25: DEC8(_rIXH); break;
|
|
case 0x26: rIXH = READ_MEM_8(); break;
|
|
case 0x27: IgnoreOpcode(); break;
|
|
case 0x28: IgnoreOpcode(); break;
|
|
case 0x29: ADD16(_rIX, rIX); break;
|
|
case 0x2A: rIX = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x2B: DEC16(_rIX); break;
|
|
case 0x2C: INC8(_rIXL); break;
|
|
case 0x2D: DEC8(_rIXL); break;
|
|
case 0x2E: rIXL = READ_MEM_8(); break;
|
|
case 0x2F: IgnoreOpcode(); break;
|
|
|
|
case 0x30: IgnoreOpcode(); break;
|
|
case 0x31: IgnoreOpcode(); break;
|
|
case 0x32: IgnoreOpcode(); break;
|
|
case 0x33: IgnoreOpcode(); break;
|
|
case 0x34: d=READ_MEM_8(); INCMEM8(rIX+d);t+=2; break;
|
|
case 0x35: d=READ_MEM_8(); DECMEM8(rIX+d);t+=2; break;
|
|
case 0x36: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, READ_MEM_8()); t+=2; break;
|
|
case 0x37: IgnoreOpcode(); break;
|
|
case 0x38: IgnoreOpcode(); break;
|
|
case 0x39: ADD16(_rIX, rSP); break;
|
|
case 0x3A: IgnoreOpcode(); break;
|
|
case 0x3B: IgnoreOpcode(); break;
|
|
case 0x3C: INC8(_rA); break;
|
|
case 0x3D: DEC8(_rA); break;
|
|
case 0x3E: rA = READ_MEM_8(); break;
|
|
case 0x3F: IgnoreOpcode(); break;
|
|
|
|
case 0x40: rB = rB; break;
|
|
case 0x41: rB = rC; break;
|
|
case 0x42: rB = rD; break;
|
|
case 0x43: rB = rE; break;
|
|
case 0x44: rB = rIXH; break;
|
|
case 0x45: rB = rIXL; break;
|
|
case 0x46: d=READ_MEM_8(); rB = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x47: rB = rA; break;
|
|
case 0x48: rC = rB; break;
|
|
case 0x49: rC = rC; break;
|
|
case 0x4A: rC = rD; break;
|
|
case 0x4B: rC = rE; break;
|
|
case 0x4C: rC = rIXH; break;
|
|
case 0x4D: rC = rIXL; break;
|
|
case 0x4E: d=READ_MEM_8(); rC = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x4F: rC = rA; break;
|
|
|
|
case 0x50: rD = rB; break;
|
|
case 0x51: rD = rC; break;
|
|
case 0x52: rD = rD; break;
|
|
case 0x53: rD = rE; break;
|
|
case 0x54: rD = rIXH; break;
|
|
case 0x55: rD = rIXL; break;
|
|
case 0x56: d=READ_MEM_8(); rD = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x57: rD = rA; break;
|
|
case 0x58: rE = rB; break;
|
|
case 0x59: rE = rC; break;
|
|
case 0x5A: rE = rD; break;
|
|
case 0x5B: rE = rE; break;
|
|
case 0x5C: rE = rIXH; break;
|
|
case 0x5D: rE = rIXL; break;
|
|
case 0x5E: d=READ_MEM_8(); rE = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x5F: rE = rA; break;
|
|
|
|
case 0x60: rIXH = rB; break;
|
|
case 0x61: rIXH = rC; break;
|
|
case 0x62: rIXH = rD; break;
|
|
case 0x63: rIXH = rE; break;
|
|
case 0x64: rIXH = rIXH; break;
|
|
case 0x65: rIXH = rIXL; break;
|
|
case 0x66: d=READ_MEM_8(); rH = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x67: rIXH = rA; break;
|
|
case 0x68: rIXL = rB; break;
|
|
case 0x69: rIXL = rC; break;
|
|
case 0x6A: rIXL = rD; break;
|
|
case 0x6B: rIXL = rE; break;
|
|
case 0x6C: rIXL = rIXH; break;
|
|
case 0x6D: rIXL = rIXL; break;
|
|
case 0x6E: d=READ_MEM_8(); rL = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x6F: rIXL = rA; break;
|
|
|
|
case 0x70: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rB);t+=5;break;
|
|
case 0x71: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rC);t+=5;break;
|
|
case 0x72: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rD);t+=5;break;
|
|
case 0x73: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rE);t+=5;break;
|
|
case 0x74: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rH);t+=5;break;
|
|
case 0x75: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rL);t+=5;break;
|
|
case 0x76: IgnoreOpcode(); break;
|
|
case 0x77: d=READ_MEM_8(); WRITE_MEM_8(rIX+d, rA);t+=5;break;
|
|
case 0x78: rA = rB; break;
|
|
case 0x79: rA = rC; break;
|
|
case 0x7A: rA = rD; break;
|
|
case 0x7B: rA = rE; break;
|
|
case 0x7C: rA = rIXH; break;
|
|
case 0x7D: rA = rIXL; break;
|
|
case 0x7E: d=READ_MEM_8(); rA = READ_MEM_8(rIX+d);t+=5;break;
|
|
case 0x7F: rA = rA; break;
|
|
|
|
case 0x80: ADD8(rB); break;
|
|
case 0x81: ADD8(rC); break;
|
|
case 0x82: ADD8(rD); break;
|
|
case 0x83: ADD8(rE); break;
|
|
case 0x84: ADD8(rIXH); break;
|
|
case 0x85: ADD8(rIXL); break;
|
|
case 0x86: d=READ_MEM_8(); ADD8(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0x87: ADD8(rA); break;
|
|
case 0x88: ADC8(rB); break;
|
|
case 0x89: ADC8(rC); break;
|
|
case 0x8A: ADC8(rD); break;
|
|
case 0x8B: ADC8(rE); break;
|
|
case 0x8C: ADC8(rIXH); break;
|
|
case 0x8D: ADC8(rIXL); break;
|
|
case 0x8E: d=READ_MEM_8(); ADC8(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0x8F: ADC8(rA); break;
|
|
|
|
case 0x90: SUB8(rB); break;
|
|
case 0x91: SUB8(rC); break;
|
|
case 0x92: SUB8(rD); break;
|
|
case 0x93: SUB8(rE); break;
|
|
case 0x94: SUB8(rIXH); break;
|
|
case 0x95: SUB8(rIXL); break;
|
|
case 0x96: d=READ_MEM_8(); SUB8(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0x97: SUB8(rA); break;
|
|
case 0x98: SBC8(rB); break;
|
|
case 0x99: SBC8(rC); break;
|
|
case 0x9A: SBC8(rD); break;
|
|
case 0x9B: SBC8(rE); break;
|
|
case 0x9C: SBC8(rIXH); break;
|
|
case 0x9D: SBC8(rIXL); break;
|
|
case 0x9E: d=READ_MEM_8(); SBC8(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0x9F: SBC8(rA); break;
|
|
|
|
case 0xA0: AND(rB); break;
|
|
case 0xA1: AND(rC); break;
|
|
case 0xA2: AND(rD); break;
|
|
case 0xA3: AND(rE); break;
|
|
case 0xA4: AND(rIXH); break;
|
|
case 0xA5: AND(rIXL); break;
|
|
case 0xA6: d=READ_MEM_8(); AND(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0xA7: AND(rA); break;
|
|
case 0xA8: XOR(rB); break;
|
|
case 0xA9: XOR(rC); break;
|
|
case 0xAA: XOR(rD); break;
|
|
case 0xAB: XOR(rE); break;
|
|
case 0xAC: XOR(rIXH); break;
|
|
case 0xAD: XOR(rIXL); break;
|
|
case 0xAE: d=READ_MEM_8(); XOR(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0xAF: XOR(rA); break;
|
|
|
|
case 0xB0: OR(rB); break;
|
|
case 0xB1: OR(rC); break;
|
|
case 0xB2: OR(rD); break;
|
|
case 0xB3: OR(rE); break;
|
|
case 0xB4: OR(rIXH); break;
|
|
case 0xB5: OR(rIXL); break;
|
|
case 0xB6: d=READ_MEM_8(); OR(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0xB7: OR(rA); break;
|
|
case 0xB8: CP(rB); break;
|
|
case 0xB9: CP(rC); break;
|
|
case 0xBA: CP(rD); break;
|
|
case 0xBB: CP(rE); break;
|
|
case 0xBC: CP(rIXH); break;
|
|
case 0xBD: CP(rIXL); break;
|
|
case 0xBE: d=READ_MEM_8(); CP(READ_MEM_8(rIX+d));t+=5; break;
|
|
case 0xBF: CP(rA); break;
|
|
|
|
case 0xCB: IX_BIT_INSTRUCTIONS(); break;
|
|
case 0xE1: POP(_rIX); break;
|
|
case 0xE3: EX_MEM(_rIX, rSP); break;
|
|
case 0xE5: PUSH(rIX); break;
|
|
case 0xE9: JP(cNO, rIX); break;
|
|
case 0xF9: rSP = rIX; t+=2; break;
|
|
default: IgnoreOpcode(); break;
|
|
}
|
|
}
|
|
|
|
void IX_BIT_INSTRUCTIONS()
|
|
{
|
|
const int8_t d = READ_MEM_8();
|
|
const uint8_t opcode = READ_MEM_8();
|
|
t+=3;
|
|
|
|
z80debug::useOpcode(opcode, 4);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: rB = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x01: rC = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x02: rD = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x03: rE = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x04: rH = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x05: rL = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x06: WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x07: rA = WRITE_MEM_8(rIX+d, RLC(READ_MEM_8(rIX+d))); break;
|
|
case 0x08: rB = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x09: rC = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0A: rD = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0B: rE = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0C: rH = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0D: rL = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0E: WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
case 0x0F: rA = WRITE_MEM_8(rIX+d, RRC(READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0x10: rB = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x11: rC = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x12: rD = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x13: rE = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x14: rH = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x15: rL = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x16: WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x17: rA = WRITE_MEM_8(rIX+d, RL(READ_MEM_8(rIX+d))); break;
|
|
case 0x18: rB = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x19: rC = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1A: rD = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1B: rE = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1C: rH = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1D: rL = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1E: WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
case 0x1F: rA = WRITE_MEM_8(rIX+d, RR(READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0x20: rB = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x21: rC = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x22: rD = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x23: rE = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x24: rH = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x25: rL = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x26: WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x27: rA = WRITE_MEM_8(rIX+d, SLA(READ_MEM_8(rIX+d))); break;
|
|
case 0x28: rB = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x29: rC = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2A: rD = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2B: rE = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2C: rH = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2D: rL = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2E: WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
case 0x2F: rA = WRITE_MEM_8(rIX+d, SRA(READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0x30: rB = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x31: rC = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x32: rD = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x33: rE = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x34: rH = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x35: rL = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x36: WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x37: rA = WRITE_MEM_8(rIX+d, SLL(READ_MEM_8(rIX+d))); break;
|
|
case 0x38: rB = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x39: rC = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3A: rD = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3B: rE = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3C: rH = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3D: rL = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3E: WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
case 0x3F: rA = WRITE_MEM_8(rIX+d, SRL(READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0x40: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x41: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x42: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x43: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x44: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x45: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x46: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x47: BIT(0, READ_MEM_8(rIX+d)); break;
|
|
case 0x48: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x49: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4A: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4B: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4C: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4D: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4E: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
case 0x4F: BIT(1, READ_MEM_8(rIX+d)); break;
|
|
|
|
case 0x50: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x51: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x52: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x53: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x54: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x55: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x56: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x57: BIT(2, READ_MEM_8(rIX+d)); break;
|
|
case 0x58: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x59: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5A: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5B: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5C: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5D: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5E: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
case 0x5F: BIT(3, READ_MEM_8(rIX+d)); break;
|
|
|
|
case 0x60: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x61: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x62: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x63: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x64: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x65: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x66: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x67: BIT(4, READ_MEM_8(rIX+d)); break;
|
|
case 0x68: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x69: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6A: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6B: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6C: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6D: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6E: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
case 0x6F: BIT(5, READ_MEM_8(rIX+d)); break;
|
|
|
|
case 0x70: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x71: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x72: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x73: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x74: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x75: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x76: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x77: BIT(6, READ_MEM_8(rIX+d)); break;
|
|
case 0x78: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x79: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7A: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7B: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7C: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7D: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7E: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
case 0x7F: BIT(7, READ_MEM_8(rIX+d)); break;
|
|
|
|
case 0x80: rB = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x81: rC = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x82: rD = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x83: rE = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x84: rH = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x85: rL = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x86: WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x87: rA = WRITE_MEM_8(rIX+d, RES(0, READ_MEM_8(rIX+d))); break;
|
|
case 0x88: rB = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x89: rC = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8A: rD = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8B: rE = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8C: rH = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8D: rL = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8E: WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
case 0x8F: rA = WRITE_MEM_8(rIX+d, RES(1, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0x90: rB = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x91: rC = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x92: rD = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x93: rE = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x94: rH = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x95: rL = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x96: WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x97: rA = WRITE_MEM_8(rIX+d, RES(2, READ_MEM_8(rIX+d))); break;
|
|
case 0x98: rB = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x99: rC = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9A: rD = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9B: rE = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9C: rH = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9D: rL = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9E: WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
case 0x9F: rA = WRITE_MEM_8(rIX+d, RES(3, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xA0: rB = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA1: rC = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA2: rD = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA3: rE = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA4: rH = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA5: rL = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA6: WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA7: rA = WRITE_MEM_8(rIX+d, RES(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xA8: rB = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xA9: rC = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAA: rD = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAB: rE = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAC: rH = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAD: rL = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAE: WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xAF: rA = WRITE_MEM_8(rIX+d, RES(5, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xB0: rB = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB1: rC = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB2: rD = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB3: rE = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB4: rH = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB5: rL = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB6: WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB7: rA = WRITE_MEM_8(rIX+d, RES(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xB8: rB = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xB9: rC = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBA: rD = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBB: rE = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBC: rH = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBD: rL = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBE: WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xBF: rA = WRITE_MEM_8(rIX+d, RES(7, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xC0: rB = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC1: rC = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC2: rD = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC3: rE = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC4: rH = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC5: rL = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC6: WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC7: rA = WRITE_MEM_8(rIX+d, SET(0, READ_MEM_8(rIX+d))); break;
|
|
case 0xC8: rB = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xC9: rC = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCA: rD = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCB: rE = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCC: rH = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCD: rL = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCE: WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
case 0xCF: rA = WRITE_MEM_8(rIX+d, SET(1, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xD0: rB = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD1: rC = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD2: rD = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD3: rE = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD4: rH = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD5: rL = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD6: WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD7: rA = WRITE_MEM_8(rIX+d, SET(2, READ_MEM_8(rIX+d))); break;
|
|
case 0xD8: rB = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xD9: rC = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDA: rD = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDB: rE = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDC: rH = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDD: rL = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDE: WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
case 0xDF: rA = WRITE_MEM_8(rIX+d, SET(3, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xE0: rB = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE1: rC = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE2: rD = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE3: rE = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE4: rH = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE5: rL = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE6: WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE7: rA = WRITE_MEM_8(rIX+d, SET(4, READ_MEM_8(rIX+d))); break;
|
|
case 0xE8: rB = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xE9: rC = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xEA: rD = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xEB: rE = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xEC: rH = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xED: rL = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xEE: WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
case 0xEF: rA = WRITE_MEM_8(rIX+d, SET(5, READ_MEM_8(rIX+d))); break;
|
|
|
|
case 0xF0: rB = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF1: rC = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF2: rD = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF3: rE = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF4: rH = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF5: rL = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF6: WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF7: rA = WRITE_MEM_8(rIX+d, SET(6, READ_MEM_8(rIX+d))); break;
|
|
case 0xF8: rB = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xF9: rC = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFA: rD = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFB: rE = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFC: rH = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFD: rL = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFE: WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
case 0xFF: rA = WRITE_MEM_8(rIX+d, SET(7, READ_MEM_8(rIX+d))); break;
|
|
}
|
|
}
|
|
|
|
void MISC_INSTRUCTIONS()
|
|
{
|
|
const uint8_t opcode = READ_M1();
|
|
|
|
z80debug::useOpcode(opcode, 1);
|
|
|
|
rR = (rR&0x80) + ((rR+1) & 0x7f);
|
|
uint16_t tmp;
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x40: rB = IN(); break;
|
|
case 0x41: OUT(rB, rC); break;
|
|
case 0x42: SBC16(_rHL, rBC); break;
|
|
case 0x43: WRITE_MEM_16(READ_MEM_16(), rBC);break;
|
|
case 0x44: NEG(); break;
|
|
case 0x45: RETN(); break;
|
|
case 0x46: IM(0); break;
|
|
case 0x47: rI = rA; t++; break;
|
|
case 0x48: rC = IN(); break;
|
|
case 0x49: OUT(rC, rC); break;
|
|
case 0x4A: ADC16(_rHL, rBC); break;
|
|
case 0x4B: rBC = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x4D: RETI(); break;
|
|
case 0x4F: rR = rA; t++; break;
|
|
|
|
case 0x50: rD = IN(); break;
|
|
case 0x51: OUT(rD, rC); break;
|
|
case 0x52: SBC16(_rHL, rDE); break;
|
|
case 0x53: WRITE_MEM_16(READ_MEM_16(), rDE);break;
|
|
case 0x56: IM(1); break;
|
|
case 0x57: LD_A_I(); break;
|
|
case 0x58: rE = IN(); break;
|
|
case 0x59: OUT(rE, rC); break;
|
|
case 0x5A: ADC16(_rHL, rDE); break;
|
|
case 0x5B: rDE = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x5E: IM(2); break;
|
|
case 0x5F: LD_A_R(); break;
|
|
|
|
case 0x60: rH = IN(); break;
|
|
case 0x61: OUT(rH, rC); break;
|
|
case 0x62: SBC16(_rHL, rHL); break;
|
|
case 0x63: WRITE_MEM_16(READ_MEM_16(), rHL);break;
|
|
case 0x67: RRD(); break;
|
|
case 0x68: rL = IN(); break;
|
|
case 0x69: OUT(rL, rC); break;
|
|
case 0x6A: ADC16(_rHL, rHL); break;
|
|
case 0x6B: rHL = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x6F: RLD(); break;
|
|
|
|
case 0x70: IN(); break;
|
|
case 0x71: OUT(0, rC); break;
|
|
case 0x72: SBC16(_rHL, rSP); break;
|
|
case 0x73: WRITE_MEM_16(READ_MEM_16(), rSP);break;
|
|
case 0x78: rA = IN(); break;
|
|
case 0x79: OUT(rA, rC); break;
|
|
case 0x7A: ADC16(_rHL, rSP); break;
|
|
case 0x7B: rSP = READ_MEM_16(READ_MEM_16());break;
|
|
|
|
case 0xA0: LDI(); break;
|
|
case 0xA1: CPI(); break;
|
|
case 0xA2: INI(); break;
|
|
case 0xA3: OUTI(); break;
|
|
case 0xA8: LDD(); break;
|
|
case 0xA9: CPD(); break;
|
|
case 0xAA: IND(); break;
|
|
case 0xAB: OUTD(); break;
|
|
|
|
case 0xB0: LDIR(); break;
|
|
case 0xB1: CPIR(); break;
|
|
case 0xB2: INIR(); break;
|
|
case 0xB3: OUTIR(); break;
|
|
case 0xB8: LDDR(); break;
|
|
case 0xB9: CPDR(); break;
|
|
case 0xBA: INDR(); break;
|
|
case 0xBB: OUTDR(); break;
|
|
|
|
default: INVALID(opcode); break;
|
|
}
|
|
|
|
}
|
|
|
|
void IY_INSTRUCTIONS()
|
|
{
|
|
const uint8_t opcode = READ_M1();
|
|
int8_t d;
|
|
|
|
if (opcode!=0xCB) z80debug::useOpcode(opcode, 5);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: IgnoreOpcode(); break;
|
|
case 0x01: IgnoreOpcode(); break;
|
|
case 0x02: IgnoreOpcode(); break;
|
|
case 0x03: IgnoreOpcode(); break;
|
|
case 0x04: INC8(_rB); break;
|
|
case 0x05: DEC8(_rB); break;
|
|
case 0x06: rB = READ_MEM_8(); break;
|
|
case 0x07: IgnoreOpcode(); break;
|
|
case 0x08: IgnoreOpcode(); break;
|
|
case 0x09: ADD16(_rIY, rBC); break;
|
|
case 0x0A: IgnoreOpcode(); break;
|
|
case 0x0B: IgnoreOpcode(); break;
|
|
case 0x0C: INC8(_rC); break;
|
|
case 0x0D: DEC8(_rC); break;
|
|
case 0x0E: rC = READ_MEM_8(); break;
|
|
case 0x0F: IgnoreOpcode(); break;
|
|
|
|
case 0x10: IgnoreOpcode(); break;
|
|
case 0x11: IgnoreOpcode(); break;
|
|
case 0x12: IgnoreOpcode(); break;
|
|
case 0x13: IgnoreOpcode(); break;
|
|
case 0x14: INC8(_rD); break;
|
|
case 0x15: DEC8(_rD); break;
|
|
case 0x16: rD = READ_MEM_8(); break;
|
|
case 0x17: IgnoreOpcode(); break;
|
|
case 0x18: IgnoreOpcode(); break;
|
|
case 0x19: ADD16(_rIY, rDE); break;
|
|
case 0x1A: IgnoreOpcode(); break;
|
|
case 0x1B: IgnoreOpcode(); break;
|
|
case 0x1C: INC8(_rE); break;
|
|
case 0x1D: DEC8(_rE); break;
|
|
case 0x1E: rE = READ_MEM_8(); break;
|
|
case 0x1F: IgnoreOpcode(); break;
|
|
|
|
case 0x20: IgnoreOpcode(); break;
|
|
case 0x21: rIY = READ_MEM_16(); break;
|
|
case 0x22: WRITE_MEM_16(READ_MEM_16(),rIY); break;
|
|
case 0x23: INC16(_rIY); break;
|
|
case 0x24: INC8(_rIYH); break;
|
|
case 0x25: DEC8(_rIYH); break;
|
|
case 0x26: rIYH = READ_MEM_8(); break;
|
|
case 0x27: IgnoreOpcode(); break;
|
|
case 0x28: IgnoreOpcode(); break;
|
|
case 0x29: ADD16(_rIY, rIY); break;
|
|
case 0x2A: rIY = READ_MEM_16(READ_MEM_16());break;
|
|
case 0x2B: DEC16(_rIY); break;
|
|
case 0x2C: INC8(_rIYL); break;
|
|
case 0x2D: DEC8(_rIYL); break;
|
|
case 0x2E: rIYL = READ_MEM_8(); break;
|
|
case 0x2F: IgnoreOpcode(); break;
|
|
|
|
case 0x30: IgnoreOpcode(); break;
|
|
case 0x31: IgnoreOpcode(); break;
|
|
case 0x32: IgnoreOpcode(); break;
|
|
case 0x33: IgnoreOpcode(); break;
|
|
case 0x34: d=READ_MEM_8(); INCMEM8(rIY+d);t+=2; break;
|
|
case 0x35: d=READ_MEM_8(); DECMEM8(rIY+d);t+=2; break;
|
|
case 0x36: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, READ_MEM_8()); t+=2; break;
|
|
case 0x37: IgnoreOpcode(); break;
|
|
case 0x38: IgnoreOpcode(); break;
|
|
case 0x39: ADD16(_rIY, rSP); break;
|
|
case 0x3A: IgnoreOpcode(); break;
|
|
case 0x3B: IgnoreOpcode(); break;
|
|
case 0x3C: INC8(_rA); break;
|
|
case 0x3D: DEC8(_rA); break;
|
|
case 0x3E: rA = READ_MEM_8(); break;
|
|
case 0x3F: IgnoreOpcode(); break;
|
|
|
|
case 0x40: rB = rB; break;
|
|
case 0x41: rB = rC; break;
|
|
case 0x42: rB = rD; break;
|
|
case 0x43: rB = rE; break;
|
|
case 0x44: rB = rIYH; break;
|
|
case 0x45: rB = rIYL; break;
|
|
case 0x46: d=READ_MEM_8(); rB = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x47: rB = rA; break;
|
|
case 0x48: rC = rB; break;
|
|
case 0x49: rC = rC; break;
|
|
case 0x4A: rC = rD; break;
|
|
case 0x4B: rC = rE; break;
|
|
case 0x4C: rC = rIYH; break;
|
|
case 0x4D: rC = rIYL; break;
|
|
case 0x4E: d=READ_MEM_8(); rC = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x4F: rC = rA; break;
|
|
|
|
case 0x50: rD = rB; break;
|
|
case 0x51: rD = rC; break;
|
|
case 0x52: rD = rD; break;
|
|
case 0x53: rD = rE; break;
|
|
case 0x54: rD = rIYH; break;
|
|
case 0x55: rD = rIYL; break;
|
|
case 0x56: d=READ_MEM_8(); rD = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x57: rD = rA; break;
|
|
case 0x58: rE = rB; break;
|
|
case 0x59: rE = rC; break;
|
|
case 0x5A: rE = rD; break;
|
|
case 0x5B: rE = rE; break;
|
|
case 0x5C: rE = rIYH; break;
|
|
case 0x5D: rE = rIYL; break;
|
|
case 0x5E: d=READ_MEM_8(); rE = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x5F: rE = rA; break;
|
|
|
|
case 0x60: rIYH = rB; break;
|
|
case 0x61: rIYH = rC; break;
|
|
case 0x62: rIYH = rD; break;
|
|
case 0x63: rIYH = rE; break;
|
|
case 0x64: rIYH = rIYH; break;
|
|
case 0x65: rIYH = rIYL; break;
|
|
case 0x66: d=READ_MEM_8(); rH = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x67: rIYH = rA; break;
|
|
case 0x68: rIYL = rB; break;
|
|
case 0x69: rIYL = rC; break;
|
|
case 0x6A: rIYL = rD; break;
|
|
case 0x6B: rIYL = rE; break;
|
|
case 0x6C: rIYL = rIYH; break;
|
|
case 0x6D: rIYL = rIYL; break;
|
|
case 0x6E: d=READ_MEM_8(); rL = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x6F: rIYL = rA; break;
|
|
|
|
case 0x70: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rB);t+=5;break;
|
|
case 0x71: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rC);t+=5;break;
|
|
case 0x72: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rD);t+=5;break;
|
|
case 0x73: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rE);t+=5;break;
|
|
case 0x74: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rH);t+=5;break;
|
|
case 0x75: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rL);t+=5;break;
|
|
case 0x76: IgnoreOpcode(); break;
|
|
case 0x77: d=READ_MEM_8(); WRITE_MEM_8(rIY+d, rA);t+=5;break;
|
|
case 0x78: rA = rB; break;
|
|
case 0x79: rA = rC; break;
|
|
case 0x7A: rA = rD; break;
|
|
case 0x7B: rA = rE; break;
|
|
case 0x7C: rA = rIYH; break;
|
|
case 0x7D: rA = rIYL; break;
|
|
case 0x7E: d=READ_MEM_8(); rA = READ_MEM_8(rIY+d);t+=5;break;
|
|
case 0x7F: rA = rA; break;
|
|
|
|
case 0x80: ADD8(rB); break;
|
|
case 0x81: ADD8(rC); break;
|
|
case 0x82: ADD8(rD); break;
|
|
case 0x83: ADD8(rE); break;
|
|
case 0x84: ADD8(rIYH); break;
|
|
case 0x85: ADD8(rIYL); break;
|
|
case 0x86: d=READ_MEM_8(); ADD8(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0x87: ADD8(rA); break;
|
|
case 0x88: ADC8(rB); break;
|
|
case 0x89: ADC8(rC); break;
|
|
case 0x8A: ADC8(rD); break;
|
|
case 0x8B: ADC8(rE); break;
|
|
case 0x8C: ADC8(rIYH); break;
|
|
case 0x8D: ADC8(rIYL); break;
|
|
case 0x8E: d=READ_MEM_8(); ADC8(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0x8F: ADC8(rA); break;
|
|
|
|
case 0x90: SUB8(rB); break;
|
|
case 0x91: SUB8(rC); break;
|
|
case 0x92: SUB8(rD); break;
|
|
case 0x93: SUB8(rE); break;
|
|
case 0x94: SUB8(rIYH); break;
|
|
case 0x95: SUB8(rIYL); break;
|
|
case 0x96: d=READ_MEM_8(); SUB8(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0x97: SUB8(rA); break;
|
|
case 0x98: SBC8(rB); break;
|
|
case 0x99: SBC8(rC); break;
|
|
case 0x9A: SBC8(rD); break;
|
|
case 0x9B: SBC8(rE); break;
|
|
case 0x9C: SBC8(rIYH); break;
|
|
case 0x9D: SBC8(rIYL); break;
|
|
case 0x9E: d=READ_MEM_8(); SBC8(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0x9F: SBC8(rA); break;
|
|
|
|
case 0xA0: AND(rB); break;
|
|
case 0xA1: AND(rC); break;
|
|
case 0xA2: AND(rD); break;
|
|
case 0xA3: AND(rE); break;
|
|
case 0xA4: AND(rIYH); break;
|
|
case 0xA5: AND(rIYL); break;
|
|
case 0xA6: d=READ_MEM_8(); AND(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0xA7: AND(rA); break;
|
|
case 0xA8: XOR(rB); break;
|
|
case 0xA9: XOR(rC); break;
|
|
case 0xAA: XOR(rD); break;
|
|
case 0xAB: XOR(rE); break;
|
|
case 0xAC: XOR(rIYH); break;
|
|
case 0xAD: XOR(rIYL); break;
|
|
case 0xAE: d=READ_MEM_8(); XOR(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0xAF: XOR(rA); break;
|
|
|
|
case 0xB0: OR(rB); break;
|
|
case 0xB1: OR(rC); break;
|
|
case 0xB2: OR(rD); break;
|
|
case 0xB3: OR(rE); break;
|
|
case 0xB4: OR(rIYH); break;
|
|
case 0xB5: OR(rIYL); break;
|
|
case 0xB6: d=READ_MEM_8(); OR(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0xB7: OR(rA); break;
|
|
case 0xB8: CP(rB); break;
|
|
case 0xB9: CP(rC); break;
|
|
case 0xBA: CP(rD); break;
|
|
case 0xBB: CP(rE); break;
|
|
case 0xBC: CP(rIYH); break;
|
|
case 0xBD: CP(rIYL); break;
|
|
case 0xBE: d=READ_MEM_8(); CP(READ_MEM_8(rIY+d));t+=5; break;
|
|
case 0xBF: CP(rA); break;
|
|
|
|
case 0xCB: IY_BIT_INSTRUCTIONS(); break;
|
|
case 0xE1: POP(_rIY); break;
|
|
case 0xE3: EX_MEM(_rIY, rSP); break;
|
|
case 0xE5: PUSH(rIY); break;
|
|
case 0xE9: JP(cNO, rIY); break;
|
|
case 0xF9: rSP = rIY; t+=2; break;
|
|
default: IgnoreOpcode(); break;
|
|
}
|
|
}
|
|
|
|
void IY_BIT_INSTRUCTIONS()
|
|
{
|
|
const int8_t d = READ_MEM_8();
|
|
const uint8_t opcode = READ_MEM_8();
|
|
t+=3;
|
|
|
|
z80debug::useOpcode(opcode, 6);
|
|
|
|
switch (opcode)
|
|
{
|
|
case 0x00: rB = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x01: rC = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x02: rD = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x03: rE = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x04: rH = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x05: rL = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x06: WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x07: rA = WRITE_MEM_8(rIY+d, RLC(READ_MEM_8(rIY+d))); break;
|
|
case 0x08: rB = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x09: rC = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0A: rD = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0B: rE = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0C: rH = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0D: rL = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0E: WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
case 0x0F: rA = WRITE_MEM_8(rIY+d, RRC(READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0x10: rB = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x11: rC = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x12: rD = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x13: rE = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x14: rH = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x15: rL = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x16: WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x17: rA = WRITE_MEM_8(rIY+d, RL(READ_MEM_8(rIY+d))); break;
|
|
case 0x18: rB = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x19: rC = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1A: rD = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1B: rE = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1C: rH = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1D: rL = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1E: WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
case 0x1F: rA = WRITE_MEM_8(rIY+d, RR(READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0x20: rB = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x21: rC = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x22: rD = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x23: rE = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x24: rH = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x25: rL = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x26: WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x27: rA = WRITE_MEM_8(rIY+d, SLA(READ_MEM_8(rIY+d))); break;
|
|
case 0x28: rB = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x29: rC = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2A: rD = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2B: rE = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2C: rH = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2D: rL = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2E: WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
case 0x2F: rA = WRITE_MEM_8(rIY+d, SRA(READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0x30: rB = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x31: rC = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x32: rD = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x33: rE = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x34: rH = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x35: rL = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x36: WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x37: rA = WRITE_MEM_8(rIY+d, SLL(READ_MEM_8(rIY+d))); break;
|
|
case 0x38: rB = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x39: rC = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3A: rD = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3B: rE = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3C: rH = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3D: rL = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3E: WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
case 0x3F: rA = WRITE_MEM_8(rIY+d, SRL(READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0x40: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x41: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x42: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x43: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x44: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x45: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x46: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x47: BIT(0, READ_MEM_8(rIY+d)); break;
|
|
case 0x48: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x49: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4A: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4B: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4C: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4D: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4E: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
case 0x4F: BIT(1, READ_MEM_8(rIY+d)); break;
|
|
|
|
case 0x50: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x51: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x52: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x53: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x54: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x55: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x56: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x57: BIT(2, READ_MEM_8(rIY+d)); break;
|
|
case 0x58: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x59: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5A: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5B: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5C: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5D: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5E: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
case 0x5F: BIT(3, READ_MEM_8(rIY+d)); break;
|
|
|
|
case 0x60: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x61: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x62: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x63: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x64: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x65: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x66: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x67: BIT(4, READ_MEM_8(rIY+d)); break;
|
|
case 0x68: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x69: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6A: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6B: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6C: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6D: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6E: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
case 0x6F: BIT(5, READ_MEM_8(rIY+d)); break;
|
|
|
|
case 0x70: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x71: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x72: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x73: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x74: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x75: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x76: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x77: BIT(6, READ_MEM_8(rIY+d)); break;
|
|
case 0x78: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x79: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7A: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7B: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7C: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7D: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7E: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
case 0x7F: BIT(7, READ_MEM_8(rIY+d)); break;
|
|
|
|
case 0x80: rB = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x81: rC = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x82: rD = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x83: rE = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x84: rH = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x85: rL = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x86: WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x87: rA = WRITE_MEM_8(rIY+d, RES(0, READ_MEM_8(rIY+d))); break;
|
|
case 0x88: rB = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x89: rC = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8A: rD = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8B: rE = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8C: rH = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8D: rL = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8E: WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
case 0x8F: rA = WRITE_MEM_8(rIY+d, RES(1, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0x90: rB = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x91: rC = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x92: rD = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x93: rE = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x94: rH = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x95: rL = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x96: WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x97: rA = WRITE_MEM_8(rIY+d, RES(2, READ_MEM_8(rIY+d))); break;
|
|
case 0x98: rB = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x99: rC = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9A: rD = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9B: rE = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9C: rH = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9D: rL = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9E: WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
case 0x9F: rA = WRITE_MEM_8(rIY+d, RES(3, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xA0: rB = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA1: rC = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA2: rD = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA3: rE = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA4: rH = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA5: rL = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA6: WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA7: rA = WRITE_MEM_8(rIY+d, RES(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xA8: rB = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xA9: rC = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAA: rD = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAB: rE = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAC: rH = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAD: rL = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAE: WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xAF: rA = WRITE_MEM_8(rIY+d, RES(5, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xB0: rB = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB1: rC = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB2: rD = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB3: rE = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB4: rH = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB5: rL = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB6: WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB7: rA = WRITE_MEM_8(rIY+d, RES(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xB8: rB = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xB9: rC = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBA: rD = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBB: rE = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBC: rH = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBD: rL = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBE: WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xBF: rA = WRITE_MEM_8(rIY+d, RES(7, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xC0: rB = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC1: rC = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC2: rD = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC3: rE = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC4: rH = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC5: rL = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC6: WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC7: rA = WRITE_MEM_8(rIY+d, SET(0, READ_MEM_8(rIY+d))); break;
|
|
case 0xC8: rB = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xC9: rC = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCA: rD = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCB: rE = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCC: rH = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCD: rL = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCE: WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
case 0xCF: rA = WRITE_MEM_8(rIY+d, SET(1, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xD0: rB = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD1: rC = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD2: rD = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD3: rE = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD4: rH = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD5: rL = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD6: WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD7: rA = WRITE_MEM_8(rIY+d, SET(2, READ_MEM_8(rIY+d))); break;
|
|
case 0xD8: rB = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xD9: rC = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDA: rD = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDB: rE = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDC: rH = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDD: rL = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDE: WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
case 0xDF: rA = WRITE_MEM_8(rIY+d, SET(3, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xE0: rB = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE1: rC = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE2: rD = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE3: rE = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE4: rH = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE5: rL = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE6: WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE7: rA = WRITE_MEM_8(rIY+d, SET(4, READ_MEM_8(rIY+d))); break;
|
|
case 0xE8: rB = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xE9: rC = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xEA: rD = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xEB: rE = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xEC: rH = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xED: rL = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xEE: WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
case 0xEF: rA = WRITE_MEM_8(rIY+d, SET(5, READ_MEM_8(rIY+d))); break;
|
|
|
|
case 0xF0: rB = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF1: rC = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF2: rD = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF3: rE = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF4: rH = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF5: rL = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF6: WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF7: rA = WRITE_MEM_8(rIY+d, SET(6, READ_MEM_8(rIY+d))); break;
|
|
case 0xF8: rB = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xF9: rC = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFA: rD = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFB: rE = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFC: rH = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFD: rL = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFE: WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
case 0xFF: rA = WRITE_MEM_8(rIY+d, SET(7, READ_MEM_8(rIY+d))); break;
|
|
}
|
|
}
|
|
|
|
uint8_t *getMem() { return memory; }
|
|
uint8_t *getRegs() { return regs; }
|
|
|
|
uint16_t getAF(const bool alt) { return alt?rAF2:rAF; }
|
|
uint16_t getBC(const bool alt) { return alt?rBC2:rBC; }
|
|
uint16_t getDE(const bool alt) { return alt?rDE2:rDE; }
|
|
uint16_t getHL(const bool alt) { return alt?rHL2:rHL; }
|
|
|
|
uint16_t getIX() { return rIX; }
|
|
uint16_t getIY() { return rIY; }
|
|
uint16_t getSP() { return rSP; }
|
|
|
|
uint16_t getPC() { return rPC; }
|
|
|
|
uint8_t getI() { return rI; }
|
|
uint8_t getR() { return rR; }
|
|
|
|
void setPC(const uint16_t addr) { rPC = addr; }
|
|
|
|
uint8_t getMemTag(const uint16_t addr) { return memtag[addr]; }
|
|
|
|
void setMemTag(const uint16_t addr, const uint8_t value) { memtag[addr] = value; }
|
|
|
|
void clearMemTag()
|
|
{
|
|
for (int i=0; i<65536; ++i) memtag[i] = MEMTAG_NONE;
|
|
}
|
|
|
|
uint8_t getMemTouched(const uint16_t addr) { return memtouched[addr]; }
|
|
|
|
void clearMemTouched()
|
|
{
|
|
for (int i=0; i<65536; ++i) memtouched[i] = MEMTAG_NONE;
|
|
}
|
|
|
|
void fixMemTouched()
|
|
{
|
|
for (int i=0; i<65536; ++i)
|
|
if ( (memtouched[i]==MEMTAG_INST) || (memtouched[i]==MEMTAG_REPEAT) )
|
|
memtouched[i] = MEMTAG_DATA;
|
|
//else if (memtouched[i]==MEMTAG_DATA)
|
|
// memtouched[i] = MEMTAG_REPEAT;
|
|
}
|
|
|
|
|
|
const bool getOption(const int option)
|
|
{
|
|
return options[option];
|
|
}
|
|
|
|
void setOption(const int option, const bool value)
|
|
{
|
|
options[option] = value;
|
|
}
|
|
|
|
void toggleOption(const int option)
|
|
{
|
|
options[option] = !options[option];
|
|
}
|
|
|
|
void resetStackedCalls()
|
|
{
|
|
calls_stacked=0;
|
|
}
|
|
} |