3076 lines
164 KiB
C
3076 lines
164 KiB
C
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// z80 - Emulates Z80 CPU
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef EMU_COMPILE
|
|
#error "Hi I forgot to set EMU_COMPILE"
|
|
#endif
|
|
|
|
#include "z80.h"
|
|
|
|
// no 'conversion from _blah_ possible loss of data' warnings
|
|
#pragma warning (disable: 4244)
|
|
|
|
//#define TESTZ80
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Static information
|
|
//
|
|
static const uint8 cycletable_normal[0x100] = {
|
|
4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
|
|
8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
|
|
7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
|
|
7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
|
5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
|
|
5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
|
|
5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
|
|
5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11};
|
|
|
|
static const uint8 cycletable_cb[0x100] = {
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
|
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
|
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8};
|
|
|
|
static const uint8 cycletable_ed[0x100] = {
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
12,12,15,20, 8, 8, 8, 9,12,12,15,20, 8, 8, 8, 9,
|
|
12,12,15,20, 8, 8, 8, 9,12,12,15,20, 8, 8, 8, 9,
|
|
12,12,15,20, 8, 8, 8,18,12,12,15,20, 8, 8, 8,18,
|
|
12,12,15,20, 8, 8, 8, 8,12,12,15,20, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
|
|
16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
|
|
|
|
static const uint8 cycletable_xy[0x100] = {
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
|
|
4,14,20,10, 9, 9, 9, 4, 4,15,20,10, 9, 9, 9, 4,
|
|
4, 4, 4, 4,23,23,19, 4, 4,15, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
9, 9, 9, 9, 9, 9,19, 9, 9, 9, 9, 9, 9, 9,19, 9,
|
|
19,19,19,19,19,19, 4,19, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 9, 9,19, 4, 4, 4, 4, 4, 9, 9,19, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4,14, 4,23, 4,15, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4,10, 4, 4, 4, 4, 4, 4};
|
|
|
|
#define cycletable_dd cycletable_xy
|
|
#define cycletable_fd cycletable_xy
|
|
|
|
static const uint8 cycletable_xycb[0x100] = {
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
|
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
|
|
23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23};
|
|
|
|
// extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7
|
|
static const uint8 cycletable_ex[0x100] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // DJNZ
|
|
5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, // JR NZ/JR Z
|
|
5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, // JR NC/JR C
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, // LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR
|
|
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
|
|
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
|
|
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
|
|
6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2};
|
|
|
|
static uint8 SZ [0x100];
|
|
static uint8 SZP [0x100];
|
|
static uint8 SZHV_inc[0x100];
|
|
static uint8 SZHV_dec[0x100];
|
|
|
|
#define CF (0x01)
|
|
#define NF (0x02)
|
|
#define PF (0x04)
|
|
#define VF (PF)
|
|
#define XF (0x08)
|
|
#define HF (0x10)
|
|
#define YF (0x20)
|
|
#define ZF (0x40)
|
|
#define SF (0x80)
|
|
|
|
//
|
|
// Init: mainly just initialize the flag lookup tables
|
|
//
|
|
sint32 z80_init(void) {
|
|
uint32 i;
|
|
for (i = 0; i < 256; i++) {
|
|
uint32 nbits = 0;
|
|
if(i & 0x01) { nbits++; }
|
|
if(i & 0x02) { nbits++; }
|
|
if(i & 0x04) { nbits++; }
|
|
if(i & 0x08) { nbits++; }
|
|
if(i & 0x10) { nbits++; }
|
|
if(i & 0x20) { nbits++; }
|
|
if(i & 0x40) { nbits++; }
|
|
if(i & 0x80) { nbits++; }
|
|
SZ[i] = i ? i & SF : ZF;
|
|
SZ[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */
|
|
SZP[i] = SZ[i] | ((nbits & 1) ? 0 : PF);
|
|
SZHV_inc[i] = SZ[i];
|
|
if(i == 0x80) { SZHV_inc[i] |= VF; }
|
|
if((i & 0x0F) == 0x00) { SZHV_inc[i] |= HF; }
|
|
SZHV_dec[i] = SZ[i] | NF;
|
|
if(i == 0x7F) { SZHV_dec[i] |= VF; }
|
|
if((i & 0x0F) == 0x0F) { SZHV_dec[i] |= HF; }
|
|
}
|
|
|
|
//printf("z80 init\n");
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// State information
|
|
//
|
|
struct Z80_STATE {
|
|
uint16 af;
|
|
uint16 bc;
|
|
uint16 de;
|
|
uint16 hl;
|
|
uint16 pc;
|
|
uint16 sp;
|
|
uint16 ix;
|
|
uint16 iy;
|
|
uint16 af2;
|
|
uint16 bc2;
|
|
uint16 de2;
|
|
uint16 hl2;
|
|
uint8 r;
|
|
uint8 r2;
|
|
uint8 i;
|
|
uint8 irq_vector;
|
|
uint32 imflags; // nmistate,intstate,halt,badins,iff2,iff1,im(1-0)
|
|
|
|
#define IMFLAGS_NMISTATE (0x80)
|
|
#define IMFLAGS_IRQSTATE (0x40)
|
|
#define IMFLAGS_HALT (0x20)
|
|
#define IMFLAGS_BADINS (0x10)
|
|
#define IMFLAGS_IFF2 (0x08)
|
|
#define IMFLAGS_IFF1 (0x04)
|
|
#define IMFLAGS_IM (0x03)
|
|
|
|
sint32 cycles_remaining;
|
|
sint32 cycles_remaining_last_checkpoint;
|
|
sint32 cycles_deferred_from_break;
|
|
|
|
//
|
|
// These are REGISTERED EXTERNAL POINTERS.
|
|
//
|
|
z80_advance_callback_t advance;
|
|
void *hwstate;
|
|
struct Z80_MEMORY_MAP *map_op;
|
|
struct Z80_MEMORY_MAP *map_read;
|
|
struct Z80_MEMORY_MAP *map_write;
|
|
struct Z80_MEMORY_MAP *map_in;
|
|
struct Z80_MEMORY_MAP *map_out;
|
|
};
|
|
|
|
#define STATE ((struct Z80_STATE*)(state))
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TESTZ80 stuff
|
|
//
|
|
#ifdef TESTZ80
|
|
|
|
#define MAXRW (256)
|
|
|
|
static uint8 testz80_irq = 0;
|
|
|
|
static uint32 testz80_numrw = 0;
|
|
static uint32 testz80_subrw = 0;
|
|
static uint8 testz80_rwtype[MAXRW];
|
|
static uint16 testz80_rwaddr[MAXRW];
|
|
static uint8 testz80_rwdata[MAXRW];
|
|
#define TESTZ80_TYPE_READ (0x00)
|
|
#define TESTZ80_TYPE_WRITE (0x01)
|
|
#define TESTZ80_TYPE_IN (0x02)
|
|
#define TESTZ80_TYPE_OUT (0x03)
|
|
|
|
static struct Z80_STATE *testz80_state = 0;
|
|
|
|
static const char *testz80_typestr[4] = { "R","W","I","O" };
|
|
|
|
static void testz80_setstate(struct Z80_STATE *mainstate) {
|
|
testz80_state = mainstate;
|
|
}
|
|
|
|
static void testz80_newins(void) {
|
|
testz80_numrw = 0;
|
|
testz80_subrw = 0;
|
|
testz80_irq = 0;
|
|
}
|
|
|
|
static void testz80_logrw(uint8 t, uint16 a, uint8 d) {
|
|
if(testz80_numrw >= MAXRW) { *((volatile char*)0) = 0; }
|
|
testz80_rwtype[testz80_numrw] = t;
|
|
testz80_rwaddr[testz80_numrw] = a;
|
|
testz80_rwdata[testz80_numrw] = d;
|
|
testz80_numrw++;
|
|
}
|
|
|
|
static void testz80_logread (uint16 a, uint8 d) { testz80_logrw(TESTZ80_TYPE_READ , a, d); }
|
|
static void testz80_logwrite(uint16 a, uint8 d) { testz80_logrw(TESTZ80_TYPE_WRITE, a, d); }
|
|
static void testz80_login (uint16 a, uint8 d) { testz80_logrw(TESTZ80_TYPE_IN , a, d); }
|
|
static void testz80_logout (uint16 a, uint8 d) { testz80_logrw(TESTZ80_TYPE_OUT , a, d); }
|
|
|
|
uint16 testz80_getsub_af(void);
|
|
uint16 testz80_getsub_bc(void);
|
|
uint16 testz80_getsub_de(void);
|
|
uint16 testz80_getsub_hl(void);
|
|
uint16 testz80_getsub_pc(void);
|
|
uint16 testz80_getsub_sp(void);
|
|
uint16 testz80_getsub_ix(void);
|
|
uint16 testz80_getsub_iy(void);
|
|
uint16 testz80_getsub_af2(void);
|
|
uint16 testz80_getsub_bc2(void);
|
|
uint16 testz80_getsub_de2(void);
|
|
uint16 testz80_getsub_hl2(void);
|
|
|
|
static void testz80_dumprw(char *s) {
|
|
uint32 i;
|
|
for(i = 0; i < testz80_numrw; i++) {
|
|
sprintf(s+strlen(s), "[%s] 0x%04X,0x%02X %s\n",
|
|
(testz80_typestr[testz80_rwtype[i]&3]),
|
|
testz80_rwaddr[i],
|
|
testz80_rwdata[i],
|
|
(testz80_subrw == i) ? "<--subrw" : ""
|
|
);
|
|
}
|
|
if((testz80_numrw > 0) && (testz80_subrw >= i)) {
|
|
sprintf(s+strlen(s), "<--subrw\n");
|
|
}
|
|
}
|
|
|
|
static void testz80_dumpregs(char *s) {
|
|
sprintf(s+strlen(s), "regs (main) (sub)\n");
|
|
sprintf(s+strlen(s), "af = %04X %04X\n", testz80_state->af , testz80_getsub_af ());
|
|
sprintf(s+strlen(s), "bc = %04X %04X\n", testz80_state->bc , testz80_getsub_bc ());
|
|
sprintf(s+strlen(s), "de = %04X %04X\n", testz80_state->de , testz80_getsub_de ());
|
|
sprintf(s+strlen(s), "hl = %04X %04X\n", testz80_state->hl , testz80_getsub_hl ());
|
|
sprintf(s+strlen(s), "pc = %04X %04X\n", testz80_state->pc , testz80_getsub_pc ());
|
|
sprintf(s+strlen(s), "sp = %04X %04X\n", testz80_state->sp , testz80_getsub_sp ());
|
|
sprintf(s+strlen(s), "ix = %04X %04X\n", testz80_state->ix , testz80_getsub_ix ());
|
|
sprintf(s+strlen(s), "iy = %04X %04X\n", testz80_state->iy , testz80_getsub_iy ());
|
|
sprintf(s+strlen(s), "af2 = %04X %04X\n", testz80_state->af2, testz80_getsub_af2());
|
|
sprintf(s+strlen(s), "bc2 = %04X %04X\n", testz80_state->bc2, testz80_getsub_bc2());
|
|
sprintf(s+strlen(s), "de2 = %04X %04X\n", testz80_state->de2, testz80_getsub_de2());
|
|
sprintf(s+strlen(s), "hl2 = %04X %04X\n", testz80_state->hl2, testz80_getsub_hl2());
|
|
}
|
|
|
|
//#include <windows.h>
|
|
|
|
static void testz80_errorout(const char *name) {
|
|
char s[10000];
|
|
uint32 i;
|
|
strcpy(s, name);
|
|
strcat(s,"\n");
|
|
testz80_dumprw(s);
|
|
testz80_dumpregs(s);
|
|
|
|
{ FILE *f=fopen("C:\\corlett\\testz80.out","wt");
|
|
fprintf(f,s);
|
|
fclose(f);
|
|
exit(1);
|
|
}
|
|
// MessageBox(NULL,s,"testz80 error",MB_OK);
|
|
}
|
|
|
|
static void testz80_rwmismatch1(const char *name, uint16 a) {
|
|
char s[100]; sprintf(s, "mismatch sub %s(0x%04X)", name, a); testz80_errorout(s);
|
|
}
|
|
|
|
static void testz80_rwmismatch2(const char *name, uint16 a, uint8 d) {
|
|
char s[100]; sprintf(s, "mismatch sub %s(0x%04X,0x%02X)", name, a, d); testz80_errorout(s);
|
|
}
|
|
|
|
static void testz80_compareregs(void) {
|
|
if(testz80_state->af != testz80_getsub_af ()) testz80_errorout("af mismatch");
|
|
if(testz80_state->bc != testz80_getsub_bc ()) testz80_errorout("bc mismatch");
|
|
if(testz80_state->de != testz80_getsub_de ()) testz80_errorout("de mismatch");
|
|
if(testz80_state->hl != testz80_getsub_hl ()) testz80_errorout("hl mismatch");
|
|
if(testz80_state->pc != testz80_getsub_pc ()) testz80_errorout("pc mismatch");
|
|
if(testz80_state->sp != testz80_getsub_sp ()) testz80_errorout("sp mismatch");
|
|
if(testz80_state->ix != testz80_getsub_ix ()) testz80_errorout("ix mismatch");
|
|
if(testz80_state->iy != testz80_getsub_iy ()) testz80_errorout("iy mismatch");
|
|
if(testz80_state->af2 != testz80_getsub_af2()) testz80_errorout("af2 mismatch");
|
|
if(testz80_state->bc2 != testz80_getsub_bc2()) testz80_errorout("bc2 mismatch");
|
|
if(testz80_state->de2 != testz80_getsub_de2()) testz80_errorout("de2 mismatch");
|
|
if(testz80_state->hl2 != testz80_getsub_hl2()) testz80_errorout("hl2 mismatch");
|
|
if(testz80_numrw != testz80_subrw) testz80_errorout("rw count mismatch");
|
|
}
|
|
|
|
uint8 testz80_subread(uint16 a) {
|
|
if(
|
|
(testz80_subrw >= testz80_numrw) ||
|
|
(testz80_rwtype[testz80_subrw] != TESTZ80_TYPE_READ) ||
|
|
(testz80_rwaddr[testz80_subrw] != a)
|
|
) {
|
|
testz80_rwmismatch1("read", a);
|
|
}
|
|
testz80_subrw++;
|
|
return testz80_rwdata[testz80_subrw - 1];
|
|
}
|
|
|
|
uint8 testz80_subin(uint16 a) {
|
|
if(
|
|
(testz80_subrw >= testz80_numrw) ||
|
|
(testz80_rwtype[testz80_subrw] != TESTZ80_TYPE_IN) ||
|
|
(testz80_rwaddr[testz80_subrw] != a)
|
|
) {
|
|
testz80_rwmismatch1("in", a);
|
|
}
|
|
testz80_subrw++;
|
|
return testz80_rwdata[testz80_subrw - 1];
|
|
}
|
|
|
|
void testz80_subwrite(uint16 a, uint8 d) {
|
|
if(
|
|
(testz80_subrw >= testz80_numrw) ||
|
|
(testz80_rwtype[testz80_subrw] != TESTZ80_TYPE_WRITE) ||
|
|
(testz80_rwaddr[testz80_subrw] != a) ||
|
|
(testz80_rwdata[testz80_subrw] != d)
|
|
) {
|
|
testz80_rwmismatch2("write", a, d);
|
|
}
|
|
testz80_subrw++;
|
|
}
|
|
|
|
void testz80_subout(uint16 a, uint8 d) {
|
|
if(
|
|
(testz80_subrw >= testz80_numrw) ||
|
|
(testz80_rwtype[testz80_subrw] != TESTZ80_TYPE_OUT) ||
|
|
(testz80_rwaddr[testz80_subrw] != a) ||
|
|
(testz80_rwdata[testz80_subrw] != d)
|
|
) {
|
|
testz80_rwmismatch2("out", a, d);
|
|
}
|
|
testz80_subrw++;
|
|
}
|
|
|
|
void testz80_subexec(void);
|
|
void testz80_subinit(void);
|
|
void testz80_subrst38h(void);
|
|
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OFS_LO (0^(EMU_ENDIAN_XOR_L2H(1)))
|
|
#define OFS_HI (1^(EMU_ENDIAN_XOR_L2H(1)))
|
|
|
|
#define _AF (STATE->af)
|
|
#define _BC (STATE->bc)
|
|
#define _DE (STATE->de)
|
|
#define _HL (STATE->hl)
|
|
#define _PC (STATE->pc)
|
|
#define _SP (STATE->sp)
|
|
#define _IX (STATE->ix)
|
|
#define _IY (STATE->iy)
|
|
|
|
#define _A (((uint8*)(&(STATE->af)))[OFS_HI])
|
|
#define _F (((uint8*)(&(STATE->af)))[OFS_LO])
|
|
#define _B (((uint8*)(&(STATE->bc)))[OFS_HI])
|
|
#define _C (((uint8*)(&(STATE->bc)))[OFS_LO])
|
|
#define _D (((uint8*)(&(STATE->de)))[OFS_HI])
|
|
#define _E (((uint8*)(&(STATE->de)))[OFS_LO])
|
|
#define _H (((uint8*)(&(STATE->hl)))[OFS_HI])
|
|
#define _L (((uint8*)(&(STATE->hl)))[OFS_LO])
|
|
#define _HX (((uint8*)(&(STATE->ix)))[OFS_HI])
|
|
#define _LX (((uint8*)(&(STATE->ix)))[OFS_LO])
|
|
#define _HY (((uint8*)(&(STATE->iy)))[OFS_HI])
|
|
#define _LY (((uint8*)(&(STATE->iy)))[OFS_LO])
|
|
|
|
#define _R (STATE->r)
|
|
#define _I (STATE->i)
|
|
#define _R2 (STATE->r2)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
uint32 EMU_CALL z80_get_state_size(void) {
|
|
return sizeof(struct Z80_STATE);
|
|
}
|
|
|
|
void EMU_CALL z80_clear_state(void *state) {
|
|
memset(state, 0, sizeof(struct Z80_STATE));
|
|
_IX = 0xFFFF;
|
|
_IY = 0xFFFF;
|
|
_F = ZF;
|
|
#ifdef TESTZ80
|
|
testz80_subinit();
|
|
testz80_setstate(state);
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void EMU_CALL z80_set_memory_maps(
|
|
void *state,
|
|
struct Z80_MEMORY_MAP *map_op,
|
|
struct Z80_MEMORY_MAP *map_read,
|
|
struct Z80_MEMORY_MAP *map_write,
|
|
struct Z80_MEMORY_MAP *map_in,
|
|
struct Z80_MEMORY_MAP *map_out
|
|
) {
|
|
STATE->map_op = map_op;
|
|
STATE->map_read = map_read;
|
|
STATE->map_write = map_write;
|
|
STATE->map_in = map_in;
|
|
STATE->map_out = map_out;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void EMU_CALL z80_set_advance_callback(
|
|
void *state,
|
|
z80_advance_callback_t advance,
|
|
void *hwstate
|
|
) {
|
|
STATE->advance = advance;
|
|
STATE->hwstate = hwstate;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
uint16 EMU_CALL z80_getpc(void *state) { return _PC; }
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void EMU_CALL z80_break(void *state) {
|
|
if(STATE->cycles_remaining <= 0) return;
|
|
STATE->cycles_deferred_from_break += STATE->cycles_remaining;
|
|
STATE->cycles_remaining_last_checkpoint -= STATE->cycles_remaining;
|
|
STATE->cycles_remaining = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void EMU_CALL z80_setirq(void *state, uint8 irq, uint8 vector) {
|
|
if(!irq) {
|
|
STATE->imflags &= ~(IMFLAGS_IRQSTATE);
|
|
} else {
|
|
STATE->imflags |= IMFLAGS_IRQSTATE;
|
|
STATE->irq_vector = vector;
|
|
}
|
|
z80_break(state);
|
|
}
|
|
|
|
void EMU_CALL z80_setnmi(void *state, uint8 nmi) {
|
|
if(!nmi) {
|
|
STATE->imflags &= ~(IMFLAGS_NMISTATE);
|
|
} else {
|
|
STATE->imflags |= IMFLAGS_NMISTATE;
|
|
}
|
|
z80_break(state);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE struct Z80_MEMORY_TYPE* mmwalk(
|
|
struct Z80_MEMORY_MAP *map,
|
|
uint16 a
|
|
) {
|
|
for(;; map++) {
|
|
if(a < (map->x) || a > (map->y)) continue;
|
|
return &(map->type);
|
|
}
|
|
}
|
|
|
|
static EMU_INLINE void hw_sync(struct Z80_STATE *state) {
|
|
sint32 d = state->cycles_remaining_last_checkpoint - state->cycles_remaining;
|
|
if(d > 0) {
|
|
state->advance(state->hwstate, d);
|
|
state->cycles_remaining_last_checkpoint = state->cycles_remaining;
|
|
}
|
|
}
|
|
|
|
static EMU_INLINE uint8 map_readb(
|
|
struct Z80_STATE *state,
|
|
struct Z80_MEMORY_MAP *map,
|
|
uint16 a
|
|
) {
|
|
struct Z80_MEMORY_TYPE *t = mmwalk(map, a);
|
|
a &= t->mask;
|
|
if(t->n == Z80_MAP_TYPE_POINTER) {
|
|
return *((uint8*)(((uint8*)(t->p))+a));
|
|
} else {
|
|
hw_sync(state);
|
|
return ((z80_read_callback_t)(t->p))(state->hwstate, a);
|
|
}
|
|
}
|
|
|
|
static EMU_INLINE void map_writeb(
|
|
struct Z80_STATE *state,
|
|
struct Z80_MEMORY_MAP *map,
|
|
uint16 a,
|
|
uint8 d
|
|
) {
|
|
struct Z80_MEMORY_TYPE *t = mmwalk(map, a);
|
|
a &= t->mask;
|
|
if(t->n == Z80_MAP_TYPE_POINTER) {
|
|
*((uint8*)(((uint8*)(t->p))+a)) = d;
|
|
} else {
|
|
hw_sync(state);
|
|
((z80_write_callback_t)(t->p))(state->hwstate, a, d);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE uint8 z80_opb(struct Z80_STATE *state, uint16 a) {
|
|
uint8 d;
|
|
//printf("z80 op byte %04X", a); fflush(stdout);
|
|
d = map_readb(state, state->map_op, a);
|
|
//printf(" = %02X\n", d); fflush(stdout);
|
|
#ifdef TESTZ80
|
|
testz80_logread(a, d);
|
|
#endif
|
|
return d;
|
|
}
|
|
static EMU_INLINE uint8 z80_readb(struct Z80_STATE *state, uint16 a) {
|
|
uint8 d;
|
|
//printf("z80 read byte %04X", a); fflush(stdout);
|
|
d = map_readb(state, state->map_read, a);
|
|
//printf(" = %02X\n", d); fflush(stdout);
|
|
#ifdef TESTZ80
|
|
testz80_logread(a, d);
|
|
#endif
|
|
return d;
|
|
}
|
|
static EMU_INLINE void z80_writeb(struct Z80_STATE *state, uint16 a, uint8 d) {
|
|
//printf("z80 write byte %04X = %02X\n", a, d); fflush(stdout);
|
|
map_writeb(state, state->map_write, a, d);
|
|
#ifdef TESTZ80
|
|
testz80_logwrite(a, d);
|
|
#endif
|
|
}
|
|
static EMU_INLINE uint8 z80_inb(struct Z80_STATE *state, uint16 a) {
|
|
uint8 d;
|
|
d = map_readb(state, state->map_in, a);
|
|
#ifdef TESTZ80
|
|
testz80_login(a, d);
|
|
#endif
|
|
return d;
|
|
}
|
|
static EMU_INLINE void z80_outb(struct Z80_STATE *state, uint16 a, uint8 d) {
|
|
map_writeb(state, state->map_out, a, d);
|
|
#ifdef TESTZ80
|
|
testz80_logout(a, d);
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE uint16 z80_readw(struct Z80_STATE *state, uint16 a) {
|
|
uint16 t;
|
|
t = ((uint32)(z80_readb(state, a )));
|
|
t |= ((uint32)(z80_readb(state, a+1))) << 8;
|
|
return t;
|
|
}
|
|
static EMU_INLINE void z80_writew(struct Z80_STATE *state, uint16 a, uint16 d) {
|
|
z80_writeb(state, a , (uint8)(d ));
|
|
z80_writeb(state, a+1, (uint8)(d>>8));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE uint8 z80_ropb(struct Z80_STATE *state) {
|
|
uint16 t = _PC; _PC++; return z80_opb(state, t);
|
|
}
|
|
|
|
static EMU_INLINE uint8 z80_readpcb(struct Z80_STATE *state) {
|
|
uint16 t = _PC; _PC++; return z80_readb(state, t);
|
|
}
|
|
|
|
static EMU_INLINE uint16 z80_readpcw(struct Z80_STATE *state) {
|
|
uint16 t = _PC; _PC+=2; return z80_readw(state, t);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define RM(a) z80_readb(state,a)
|
|
#define RM16(a) z80_readw(state,a)
|
|
#define WM(a,d) z80_writeb(state,a,d)
|
|
#define WM16(a,d) z80_writew(state,a,d)
|
|
#define ARG() z80_readpcb(state)
|
|
#define ARG16() z80_readpcw(state)
|
|
#define ROP() z80_ropb(STATE)
|
|
#define Z80IN(a) z80_inb(state,a)
|
|
#define Z80OUT(a,d) z80_outb(state,a,d)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define CC(table,op) do{STATE->cycles_remaining-=cycletable_##table[(op)];}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define EXEC(type,op) do{ \
|
|
uint8 t=(op); \
|
|
z80_exec_##type(state,t); \
|
|
CC(type,t); \
|
|
}while(0)
|
|
|
|
#define EXEC_EA(type,op,ea) do{ \
|
|
uint8 t=(op); \
|
|
z80_exec_ea_##type(state,t,ea); \
|
|
CC(type,t); \
|
|
}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE uint16 op_pop(struct Z80_STATE *state) {
|
|
uint16 t = RM16(_SP); _SP += 2; return t;
|
|
}
|
|
#define POP() op_pop(state)
|
|
|
|
#define PUSH(x) do{ uint16 t=(x); _SP -= 1; WM(_SP, (t>>8)); _SP -= 1; WM(_SP, (t)); }while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void checkinterrupts(struct Z80_STATE *state) {
|
|
// IRQ
|
|
if(
|
|
(state->imflags & IMFLAGS_IRQSTATE) &&
|
|
(state->imflags & IMFLAGS_IFF1)
|
|
) {
|
|
#ifdef TESTZ80
|
|
testz80_irq = 1;
|
|
#endif
|
|
if(state->imflags & IMFLAGS_HALT) { _PC++; }
|
|
// auto-acknowledge interrupts. TODO: is this right?
|
|
state->imflags &= ~(IMFLAGS_HALT | IMFLAGS_IFF1 | IMFLAGS_IRQSTATE);
|
|
PUSH( _PC );
|
|
//printf("z80 interrupt(mode=%d)\n",state->imflags & IMFLAGS_IM);fflush(stdout);
|
|
switch(state->imflags & IMFLAGS_IM) {
|
|
case 0:
|
|
_PC = state->irq_vector & 0x38;
|
|
CC(normal,0xFF);
|
|
break;
|
|
case 1:
|
|
_PC = 0x38;
|
|
CC(normal,0xFF);
|
|
break;
|
|
case 2:
|
|
_PC = RM16(
|
|
(((uint32)(state->irq_vector)) ) |
|
|
(((uint32)(state->i )) << 8)
|
|
);
|
|
CC(normal,0xCD);
|
|
break;
|
|
}
|
|
}
|
|
// NMI
|
|
if(state->imflags & IMFLAGS_NMISTATE) {
|
|
if(state->imflags & IMFLAGS_HALT) { _PC++; }
|
|
state->imflags &= ~(IMFLAGS_HALT | IMFLAGS_IFF1 | IMFLAGS_NMISTATE);
|
|
PUSH( _PC );
|
|
_PC = 0x0066;
|
|
CC(normal,0xFF);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TODO: perhaps there's some latency after EI before interrupts really are
|
|
// enabled
|
|
//
|
|
#define EI do{state->imflags|= (IMFLAGS_IFF1|IMFLAGS_IFF2);checkinterrupts(state);}while(0)
|
|
#define DI do{state->imflags&=~(IMFLAGS_IFF1|IMFLAGS_IFF2);}while(0)
|
|
#define IM(x) do{state->imflags&=~(IMFLAGS_IM);state->imflags|=(x);}while(0)
|
|
|
|
#define RETN do{ \
|
|
_PC = POP(); \
|
|
if(state->imflags & IMFLAGS_IFF2) { \
|
|
state->imflags |= IMFLAGS_IFF1; \
|
|
checkinterrupts(state); \
|
|
} else { \
|
|
state->imflags &= ~(IMFLAGS_IFF1); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define RETI do{ \
|
|
_PC = POP(); \
|
|
if(state->imflags & IMFLAGS_IFF2) { \
|
|
state->imflags |= IMFLAGS_IFF1; \
|
|
checkinterrupts(state); \
|
|
} else { \
|
|
state->imflags &= ~(IMFLAGS_IFF1); \
|
|
} \
|
|
}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE uint8 op_inc(struct Z80_STATE *state, uint8 value) {
|
|
uint8 res = value + 1;
|
|
_F = (_F & CF) | SZHV_inc[res];
|
|
return res;
|
|
}
|
|
#define INC(d) op_inc(state,d)
|
|
|
|
static EMU_INLINE uint8 op_dec(struct Z80_STATE *state, uint8 value) {
|
|
uint8 res = value - 1;
|
|
_F = (_F & CF) | SZHV_dec[res];
|
|
return res;
|
|
}
|
|
#define DEC(d) op_dec(state,d)
|
|
|
|
#define RLCA do{ \
|
|
_A = (_A << 1) | (_A >> 7); \
|
|
_F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF)); \
|
|
}while(0)
|
|
|
|
#define RRCA do{ \
|
|
_F = (_F & (SF | ZF | PF)) | (_A & CF); \
|
|
_A = (_A >> 1) | (_A << 7); \
|
|
_F |= (_A & (YF | XF) ); \
|
|
}while(0)
|
|
|
|
#define RLA do{ \
|
|
uint8 res = (_A << 1) | (_F & CF); \
|
|
uint8 c = (_A & 0x80) ? CF : 0; \
|
|
_F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
|
|
_A = res; \
|
|
}while(0)
|
|
|
|
#define RRA do{ \
|
|
uint8 res = (_A >> 1) | (_F << 7); \
|
|
uint8 c = (_A & 0x01) ? CF : 0; \
|
|
_F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
|
|
_A = res; \
|
|
}while(0)
|
|
|
|
#define RRD do{ \
|
|
uint8 n = RM(_HL); \
|
|
WM( _HL, (n >> 4) | (_A << 4) ); \
|
|
_A = (_A & 0xf0) | (n & 0x0f); \
|
|
_F = (_F & CF) | SZP[_A]; \
|
|
}while(0)
|
|
|
|
#define RLD do{ \
|
|
uint8 n = RM(_HL); \
|
|
WM( _HL, (n << 4) | (_A & 0x0f) ); \
|
|
_A = (_A & 0xf0) | (n >> 4); \
|
|
_F = (_F & CF) | SZP[_A]; \
|
|
}while(0)
|
|
|
|
#define ADD(value) do{ \
|
|
uint32 val = (value); \
|
|
uint32 res = ((uint32)_A) + val; \
|
|
_F = SZ[(uint8)res] | ((res >> 8) & CF) | \
|
|
((_A ^ res ^ val) & HF) | \
|
|
(((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
|
|
_A = (uint8)res; \
|
|
}while(0)
|
|
|
|
#define ADC(value) do{ \
|
|
uint32 val = (value); \
|
|
uint32 res = ((uint32)_A) + val + ((uint32)(_F & CF)); \
|
|
_F = SZ[res & 0xff] | ((res >> 8) & CF) | \
|
|
((_A ^ res ^ val) & HF) | \
|
|
(((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
|
|
_A = res; \
|
|
}while(0)
|
|
|
|
#define SUB(value) do{ \
|
|
uint32 val = (value); \
|
|
uint32 res = ((uint32)_A) - val; \
|
|
_F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
|
|
((_A ^ res ^ val) & HF) | \
|
|
(((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
|
|
_A = res; \
|
|
}while(0)
|
|
|
|
#define SBC(value) do{ \
|
|
uint32 val = (value); \
|
|
uint32 res = ((uint32)_A) - val - ((uint32)(_F & CF)); \
|
|
_F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
|
|
((_A ^ res ^ val) & HF) | \
|
|
(((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
|
|
_A = res; \
|
|
}while(0)
|
|
|
|
#define NEG do{ \
|
|
uint8 value = _A; \
|
|
_A = 0; \
|
|
SUB(value); \
|
|
}while(0)
|
|
|
|
#define DAA do{ \
|
|
uint8 cf, nf, hf, lo, hi, diff; \
|
|
cf = _F & CF; \
|
|
nf = _F & NF; \
|
|
hf = _F & HF; \
|
|
lo = _A & 15; \
|
|
hi = _A / 16; \
|
|
\
|
|
if (cf) \
|
|
{ \
|
|
diff = (lo <= 9 && !hf) ? 0x60 : 0x66; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (lo >= 10) \
|
|
{ \
|
|
diff = hi <= 8 ? 0x06 : 0x66; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (hi >= 10) \
|
|
{ \
|
|
diff = hf ? 0x66 : 0x60; \
|
|
} \
|
|
else \
|
|
{ \
|
|
diff = hf ? 0x06 : 0x00; \
|
|
} \
|
|
} \
|
|
} \
|
|
if (nf) _A -= diff; \
|
|
else _A += diff; \
|
|
\
|
|
_F = SZP[_A] | (_F & NF); \
|
|
if (cf || (lo <= 9 ? hi >= 10 : hi >= 9)) _F |= CF; \
|
|
if (nf ? hf && lo <= 5 : lo >= 10) _F |= HF; \
|
|
}while(0)
|
|
|
|
#define AND(value) do{ _A &= (value); _F = SZP[_A] | HF; }while(0)
|
|
#define OR(value) do{ _A |= (value); _F = SZP[_A]; }while(0)
|
|
#define XOR(value) do{ _A ^= (value); _F = SZP[_A]; }while(0)
|
|
|
|
#define CP(value) do{ \
|
|
uint32 val = (value); \
|
|
uint32 res = ((uint32)_A) - val; \
|
|
_F = (SZ[res & 0xff] & (SF | ZF)) | \
|
|
(val & (YF | XF)) | ((res >> 8) & CF) | NF | \
|
|
((_A ^ res ^ val) & HF) | \
|
|
((((val ^ _A) & (_A ^ res)) >> 5) & VF); \
|
|
}while(0)
|
|
|
|
#define EX_AF do{uint16 t=state->af;state->af=state->af2;state->af2=t;}while(0)
|
|
#define EX_DE_HL do{uint16 t=state->de;state->de=state->hl ;state->hl =t;}while(0)
|
|
#define EXX do{ uint16 t; \
|
|
t=state->bc;state->bc=state->bc2;state->bc2=t; \
|
|
t=state->de;state->de=state->de2;state->de2=t; \
|
|
t=state->hl;state->hl=state->hl2;state->hl2=t; \
|
|
}while(0)
|
|
|
|
static EMU_INLINE uint16 op_exsp16(struct Z80_STATE *state,uint16 x) {
|
|
uint16 t = RM16(_SP); WM16(_SP,x); return t;
|
|
}
|
|
#define EXSP16(x) op_exsp16(state,x)
|
|
|
|
#define ADD16(DR,SR) do{ \
|
|
uint32 res = ((uint32)(DR))+((uint32)(SR)); \
|
|
_F = (_F & (SF | ZF | VF)) | \
|
|
(((DR ^ res ^ SR) >> 8) & HF) | \
|
|
((res >> 16) & CF) | ((res >> 8) & (YF | XF)); \
|
|
DR = res; \
|
|
}while(0)
|
|
|
|
#define ADC16(Reg) do{ \
|
|
uint32 res = \
|
|
((uint32)(_HL)) + \
|
|
((uint32)(Reg)) + \
|
|
((uint32)(_F & CF)); \
|
|
_F = (((_HL ^ res ^ Reg) >> 8) & HF) | \
|
|
((res >> 16) & CF) | \
|
|
((res >> 8) & (SF | YF | XF)) | \
|
|
((res & 0xFFFF) ? 0 : ZF) | \
|
|
(((Reg ^ _HL ^ 0x8000) & (Reg ^ res) & 0x8000) >> 13); \
|
|
_HL = res; \
|
|
}while(0)
|
|
|
|
#define SBC16(Reg) do{ \
|
|
uint32 res = \
|
|
((uint32)(_HL)) - \
|
|
((uint32)(Reg)) - \
|
|
((uint32)(_F & CF)); \
|
|
/* printf("SBC HL=%04X," #Reg "=%04X-F=%02X -> %08X\n",_HL,Reg,_F,res); */ \
|
|
_F = (((_HL ^ res ^ Reg) >> 8) & HF) | NF | \
|
|
((res >> 16) & CF) | \
|
|
((res >> 8) & (SF | YF | XF)) | \
|
|
((res & 0xFFFF) ? 0 : ZF) | \
|
|
(((Reg ^ _HL) & (_HL ^ res) &0x8000) >> 13); \
|
|
/* printf("_F=%02X\n",_F); */ \
|
|
_HL = res; \
|
|
}while(0)
|
|
|
|
static EMU_INLINE uint8 op_rlc(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x80) ? CF : 0;
|
|
res = ((res << 1) | (res >> 7)) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define RLC(d) op_rlc(state,d)
|
|
|
|
static EMU_INLINE uint8 op_rrc(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x01) ? CF : 0;
|
|
res = ((res >> 1) | (res << 7)) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define RRC(d) op_rrc(state,d)
|
|
|
|
static EMU_INLINE uint8 op_rl(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x80) ? CF : 0;
|
|
res = ((res << 1) | (_F & CF)) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define RL(d) op_rl(state,d)
|
|
|
|
static EMU_INLINE uint8 op_rr(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x01) ? CF : 0;
|
|
res = ((res >> 1) | (_F << 7)) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define RR(d) op_rr(state,d)
|
|
|
|
static EMU_INLINE uint8 op_sla(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x80) ? CF : 0;
|
|
res = (res << 1) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define SLA(d) op_sla(state,d)
|
|
|
|
static EMU_INLINE uint8 op_sra(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x01) ? CF : 0;
|
|
res = ((res >> 1) | (res & 0x80)) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define SRA(d) op_sra(state,d)
|
|
|
|
static EMU_INLINE uint8 op_sll(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x80) ? CF : 0;
|
|
res = ((res << 1) | 0x01) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define SLL(d) op_sll(state,d)
|
|
|
|
static EMU_INLINE uint8 op_srl(struct Z80_STATE *state, uint8 value) {
|
|
uint32 res = value;
|
|
uint32 c = (res & 0x01) ? CF : 0;
|
|
res = (res >> 1) & 0xff;
|
|
_F = SZP[res] | c;
|
|
return res;
|
|
}
|
|
#define SRL(d) op_srl(state,d)
|
|
|
|
#define BIT(bit,reg) do{ _F = (_F & CF) | HF | SZP[(reg) & (1<<(bit))]; }while(0)
|
|
//#define BIT(bit,reg) do{ _F = (_F & CF) | HF | SZP[(reg) & (1<<(bit))]; _F&=~(YF|XF);_F|=(reg)&(YF|XF);}while(0)
|
|
#define BIT_XY(bit,reg) do{ _F = (_F & CF) | HF | (SZP[(reg) & (1<<(bit))] & ~(YF|XF)) | ((EA>>8) & (YF|XF)); }while(0)
|
|
|
|
static EMU_INLINE uint8 RES(uint8 bit, uint8 value) { return value & ~(1<<bit); }
|
|
static EMU_INLINE uint8 SET(uint8 bit, uint8 value) { return value | (1<<bit); }
|
|
|
|
#define LDI do{ \
|
|
uint8 io = RM(_HL); \
|
|
WM( _DE, io ); \
|
|
/* printf("z80 ldi (%04X->%04X)\n",_HL,_DE); */ \
|
|
_F &= SF | ZF | CF; \
|
|
io += _A; \
|
|
if(io & 0x02) _F |= YF; /* bit 1 -> flag 5 */ \
|
|
if(io & 0x08) _F |= XF; /* bit 3 -> flag 3 */ \
|
|
_HL++; _DE++; _BC--; \
|
|
if( _BC ) _F |= VF; \
|
|
}while(0)
|
|
|
|
#define CPI do{ \
|
|
uint8 val = RM(_HL); \
|
|
uint8 res = _A - val; \
|
|
_HL++; _BC--; \
|
|
_F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
|
|
if( _F & HF ) res -= 1; \
|
|
if(res & 0x02) _F |= YF; /* bit 1 -> flag 5 */ \
|
|
if(res & 0x08) _F |= XF; /* bit 3 -> flag 3 */ \
|
|
if( _BC ) _F |= VF; \
|
|
}while(0)
|
|
|
|
#define INI do{ \
|
|
uint32 t; \
|
|
uint8 io = Z80IN(_BC); \
|
|
_B--; \
|
|
WM( _HL, io ); \
|
|
_HL++; \
|
|
_F = SZ[_B]; \
|
|
t = (uint32)((_C + 1) & 0xff) + (uint32)io; \
|
|
if( io & SF ) _F |= NF; \
|
|
if( t & 0x100 ) _F |= HF | CF; \
|
|
_F |= SZP[(uint8)(t & 0x07) ^ _B] & PF; \
|
|
}while(0)
|
|
|
|
#define OUTI do{ \
|
|
uint32 t; \
|
|
uint8 io = RM(_HL); \
|
|
_B--; \
|
|
Z80OUT( _BC, io ); \
|
|
_HL++; \
|
|
_F = SZ[_B]; \
|
|
t = (uint32)_L + (uint32)io; \
|
|
if( io & SF ) _F |= NF; \
|
|
if( t & 0x100 ) _F |= HF | CF; \
|
|
_F |= SZP[(uint8)(t & 0x07) ^ _B] & PF; \
|
|
}while(0)
|
|
|
|
#define LDD do{ \
|
|
uint8 io = RM(_HL); \
|
|
WM( _DE, io ); \
|
|
_F &= SF | ZF | CF; \
|
|
if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
|
|
if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
|
|
_HL--; _DE--; _BC--; \
|
|
if( _BC ) _F |= VF; \
|
|
}while(0)
|
|
|
|
#define CPD do{ \
|
|
uint8 val = RM(_HL); \
|
|
uint8 res = _A - val; \
|
|
_HL--; _BC--; \
|
|
_F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
|
|
if( _F & HF ) res -= 1; \
|
|
if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
|
|
if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
|
|
if( _BC ) _F |= VF; \
|
|
}while(0)
|
|
|
|
#define IND do{ \
|
|
uint32 t; \
|
|
uint8 io = Z80IN(_BC); \
|
|
_B--; \
|
|
WM( _HL, io ); \
|
|
_HL--; \
|
|
_F = SZ[_B]; \
|
|
t = ((uint32)(_C - 1) & 0xff) + (uint32)io; \
|
|
if( io & SF ) _F |= NF; \
|
|
if( t & 0x100 ) _F |= HF | CF; \
|
|
_F |= SZP[(uint8)(t & 0x07) ^ _B] & PF; \
|
|
}while(0)
|
|
|
|
#define OUTD do{ \
|
|
uint32 t; \
|
|
uint8 io = RM(_HL); \
|
|
_B--; \
|
|
Z80OUT( _BC, io ); \
|
|
_HL--; \
|
|
_F = SZ[_B]; \
|
|
t = (uint32)_L + (uint32)io; \
|
|
if( io & SF ) _F |= NF; \
|
|
if( t & 0x100 ) _F |= HF | CF; \
|
|
_F |= SZP[(uint8)(t & 0x07) ^ _B] & PF; \
|
|
}while(0)
|
|
|
|
#define LDIR do{ \
|
|
LDI; \
|
|
if( _BC ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb0); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define CPIR do{ \
|
|
CPI; \
|
|
if( _BC && !(_F & ZF) ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb1); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define INIR do{ \
|
|
INI; \
|
|
if( _B ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb2); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define OTIR do{ \
|
|
OUTI; \
|
|
if( _B ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb3); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define LDDR do{ \
|
|
LDD; \
|
|
if( _BC ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb8); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define CPDR do{ \
|
|
CPD; \
|
|
if( _BC && !(_F & ZF) ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xb9); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define INDR do{ \
|
|
IND; \
|
|
if( _B ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xba); \
|
|
} \
|
|
}while(0)
|
|
|
|
#define OTDR do{ \
|
|
OUTD; \
|
|
if( _B ) { \
|
|
_PC -= 2; \
|
|
CC(ex,0xbb); \
|
|
} \
|
|
}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define EAX do{EA=((uint32)((uint16)(_IX+((sint8)ARG()))));}while(0)
|
|
#define EAY do{EA=((uint32)((uint16)(_IY+((sint8)ARG()))));}while(0)
|
|
|
|
#define JP do{_PC=ARG16();}while(0)
|
|
#define JP_COND(cond) do{if(cond){JP;}else{_PC+=2;}}while(0)
|
|
|
|
#define JR do{sint16 o=((sint16)((sint8)(ARG())));_PC+=o;}while(0)
|
|
#define JR_COND(cond,op) do{if(cond){JR;CC(ex,op);}else{_PC+=1;}}while(0)
|
|
|
|
#define CALL do{ uint16 t=ARG16(); PUSH(_PC); _PC = t; }while(0)
|
|
#define CALL_COND(cond,op) do{if(cond){CALL;CC(ex,op);}else{_PC+=2;}}while(0)
|
|
|
|
#define RST(addr) do{ PUSH( _PC ); _PC = (addr); }while(0)
|
|
|
|
#define RET_COND(cond,op) do{if(cond){_PC=POP();CC(ex,op);}}while(0)
|
|
|
|
#define LD_R_A do{ \
|
|
_R = _A; \
|
|
_R2 = _A & 0x80; /* keep bit 7 of R */ \
|
|
}while(0)
|
|
|
|
#define LD_A_R do{ \
|
|
_A = (_R & 0x7f) | _R2; \
|
|
_F = (_F & CF) | SZ[_A]; \
|
|
if(state->imflags & IMFLAGS_IFF2) _F |= (1<<2); \
|
|
}while(0)
|
|
|
|
#define LD_I_A do{ \
|
|
_I = _A; \
|
|
}while(0)
|
|
|
|
#define LD_A_I do{ \
|
|
_A = _I; \
|
|
_F = (_F & CF) | SZ[_A]; \
|
|
if(state->imflags & IMFLAGS_IFF2) _F |= (1<<2); \
|
|
}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define illegal_1() do{ state->imflags = IMFLAGS_BADINS; z80_break(state); }while(0)
|
|
#define illegal_2() do{ state->imflags = IMFLAGS_BADINS; z80_break(state); }while(0)
|
|
|
|
#define HALT do{ \
|
|
state->imflags |= IMFLAGS_HALT; \
|
|
state->cycles_remaining = 0; \
|
|
}while(0)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_cb(struct Z80_STATE *state, uint8 op) {
|
|
|
|
//printf("PC=%04X exec cb %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*CB*/0x00: _B = RLC(_B); break; // RLC B
|
|
case /*CB*/0x01: _C = RLC(_C); break; // RLC C
|
|
case /*CB*/0x02: _D = RLC(_D); break; // RLC D
|
|
case /*CB*/0x03: _E = RLC(_E); break; // RLC E
|
|
case /*CB*/0x04: _H = RLC(_H); break; // RLC H
|
|
case /*CB*/0x05: _L = RLC(_L); break; // RLC L
|
|
case /*CB*/0x06: WM( _HL, RLC(RM(_HL)) ); break; // RLC (HL)
|
|
case /*CB*/0x07: _A = RLC(_A); break; // RLC A
|
|
|
|
case /*CB*/0x08: _B = RRC(_B); break; // RRC B
|
|
case /*CB*/0x09: _C = RRC(_C); break; // RRC C
|
|
case /*CB*/0x0a: _D = RRC(_D); break; // RRC D
|
|
case /*CB*/0x0b: _E = RRC(_E); break; // RRC E
|
|
case /*CB*/0x0c: _H = RRC(_H); break; // RRC H
|
|
case /*CB*/0x0d: _L = RRC(_L); break; // RRC L
|
|
case /*CB*/0x0e: WM( _HL, RRC(RM(_HL)) ); break; // RRC (HL)
|
|
case /*CB*/0x0f: _A = RRC(_A); break; // RRC A
|
|
|
|
case /*CB*/0x10: _B = RL(_B); break; // RL B
|
|
case /*CB*/0x11: _C = RL(_C); break; // RL C
|
|
case /*CB*/0x12: _D = RL(_D); break; // RL D
|
|
case /*CB*/0x13: _E = RL(_E); break; // RL E
|
|
case /*CB*/0x14: _H = RL(_H); break; // RL H
|
|
case /*CB*/0x15: _L = RL(_L); break; // RL L
|
|
case /*CB*/0x16: WM( _HL, RL(RM(_HL)) ); break; // RL (HL)
|
|
case /*CB*/0x17: _A = RL(_A); break; // RL A
|
|
|
|
case /*CB*/0x18: _B = RR(_B); break; // RR B
|
|
case /*CB*/0x19: _C = RR(_C); break; // RR C
|
|
case /*CB*/0x1a: _D = RR(_D); break; // RR D
|
|
case /*CB*/0x1b: _E = RR(_E); break; // RR E
|
|
case /*CB*/0x1c: _H = RR(_H); break; // RR H
|
|
case /*CB*/0x1d: _L = RR(_L); break; // RR L
|
|
case /*CB*/0x1e: WM( _HL, RR(RM(_HL)) ); break; // RR (HL)
|
|
case /*CB*/0x1f: _A = RR(_A); break; // RR A
|
|
|
|
case /*CB*/0x20: _B = SLA(_B); break; // SLA B
|
|
case /*CB*/0x21: _C = SLA(_C); break; // SLA C
|
|
case /*CB*/0x22: _D = SLA(_D); break; // SLA D
|
|
case /*CB*/0x23: _E = SLA(_E); break; // SLA E
|
|
case /*CB*/0x24: _H = SLA(_H); break; // SLA H
|
|
case /*CB*/0x25: _L = SLA(_L); break; // SLA L
|
|
case /*CB*/0x26: WM( _HL, SLA(RM(_HL)) ); break; // SLA (HL)
|
|
case /*CB*/0x27: _A = SLA(_A); break; // SLA A
|
|
|
|
case /*CB*/0x28: _B = SRA(_B); break; // SRA B
|
|
case /*CB*/0x29: _C = SRA(_C); break; // SRA C
|
|
case /*CB*/0x2a: _D = SRA(_D); break; // SRA D
|
|
case /*CB*/0x2b: _E = SRA(_E); break; // SRA E
|
|
case /*CB*/0x2c: _H = SRA(_H); break; // SRA H
|
|
case /*CB*/0x2d: _L = SRA(_L); break; // SRA L
|
|
case /*CB*/0x2e: WM( _HL, SRA(RM(_HL)) ); break; // SRA (HL)
|
|
case /*CB*/0x2f: _A = SRA(_A); break; // SRA A
|
|
|
|
case /*CB*/0x30: _B = SLL(_B); break; // SLL B
|
|
case /*CB*/0x31: _C = SLL(_C); break; // SLL C
|
|
case /*CB*/0x32: _D = SLL(_D); break; // SLL D
|
|
case /*CB*/0x33: _E = SLL(_E); break; // SLL E
|
|
case /*CB*/0x34: _H = SLL(_H); break; // SLL H
|
|
case /*CB*/0x35: _L = SLL(_L); break; // SLL L
|
|
case /*CB*/0x36: WM( _HL, SLL(RM(_HL)) ); break; // SLL (HL)
|
|
case /*CB*/0x37: _A = SLL(_A); break; // SLL A
|
|
|
|
case /*CB*/0x38: _B = SRL(_B); break; // SRL B
|
|
case /*CB*/0x39: _C = SRL(_C); break; // SRL C
|
|
case /*CB*/0x3a: _D = SRL(_D); break; // SRL D
|
|
case /*CB*/0x3b: _E = SRL(_E); break; // SRL E
|
|
case /*CB*/0x3c: _H = SRL(_H); break; // SRL H
|
|
case /*CB*/0x3d: _L = SRL(_L); break; // SRL L
|
|
case /*CB*/0x3e: WM( _HL, SRL(RM(_HL)) ); break; // SRL (HL)
|
|
case /*CB*/0x3f: _A = SRL(_A); break; // SRL A
|
|
|
|
case /*CB*/0x40: BIT(0,_B); break; // BIT 0,B
|
|
case /*CB*/0x41: BIT(0,_C); break; // BIT 0,C
|
|
case /*CB*/0x42: BIT(0,_D); break; // BIT 0,D
|
|
case /*CB*/0x43: BIT(0,_E); break; // BIT 0,E
|
|
case /*CB*/0x44: BIT(0,_H); break; // BIT 0,H
|
|
case /*CB*/0x45: BIT(0,_L); break; // BIT 0,L
|
|
case /*CB*/0x46: BIT(0,RM(_HL)); break; // BIT 0,(HL)
|
|
case /*CB*/0x47: BIT(0,_A); break; // BIT 0,A
|
|
|
|
case /*CB*/0x48: BIT(1,_B); break; // BIT 1,B
|
|
case /*CB*/0x49: BIT(1,_C); break; // BIT 1,C
|
|
case /*CB*/0x4a: BIT(1,_D); break; // BIT 1,D
|
|
case /*CB*/0x4b: BIT(1,_E); break; // BIT 1,E
|
|
case /*CB*/0x4c: BIT(1,_H); break; // BIT 1,H
|
|
case /*CB*/0x4d: BIT(1,_L); break; // BIT 1,L
|
|
case /*CB*/0x4e: BIT(1,RM(_HL)); break; // BIT 1,(HL)
|
|
case /*CB*/0x4f: BIT(1,_A); break; // BIT 1,A
|
|
|
|
case /*CB*/0x50: BIT(2,_B); break; // BIT 2,B
|
|
case /*CB*/0x51: BIT(2,_C); break; // BIT 2,C
|
|
case /*CB*/0x52: BIT(2,_D); break; // BIT 2,D
|
|
case /*CB*/0x53: BIT(2,_E); break; // BIT 2,E
|
|
case /*CB*/0x54: BIT(2,_H); break; // BIT 2,H
|
|
case /*CB*/0x55: BIT(2,_L); break; // BIT 2,L
|
|
case /*CB*/0x56: BIT(2,RM(_HL)); break; // BIT 2,(HL)
|
|
case /*CB*/0x57: BIT(2,_A); break; // BIT 2,A
|
|
|
|
case /*CB*/0x58: BIT(3,_B); break; // BIT 3,B
|
|
case /*CB*/0x59: BIT(3,_C); break; // BIT 3,C
|
|
case /*CB*/0x5a: BIT(3,_D); break; // BIT 3,D
|
|
case /*CB*/0x5b: BIT(3,_E); break; // BIT 3,E
|
|
case /*CB*/0x5c: BIT(3,_H); break; // BIT 3,H
|
|
case /*CB*/0x5d: BIT(3,_L); break; // BIT 3,L
|
|
case /*CB*/0x5e: BIT(3,RM(_HL)); break; // BIT 3,(HL)
|
|
case /*CB*/0x5f: BIT(3,_A); break; // BIT 3,A
|
|
|
|
case /*CB*/0x60: BIT(4,_B); break; // BIT 4,B
|
|
case /*CB*/0x61: BIT(4,_C); break; // BIT 4,C
|
|
case /*CB*/0x62: BIT(4,_D); break; // BIT 4,D
|
|
case /*CB*/0x63: BIT(4,_E); break; // BIT 4,E
|
|
case /*CB*/0x64: BIT(4,_H); break; // BIT 4,H
|
|
case /*CB*/0x65: BIT(4,_L); break; // BIT 4,L
|
|
case /*CB*/0x66: BIT(4,RM(_HL)); break; // BIT 4,(HL)
|
|
case /*CB*/0x67: BIT(4,_A); break; // BIT 4,A
|
|
|
|
case /*CB*/0x68: BIT(5,_B); break; // BIT 5,B
|
|
case /*CB*/0x69: BIT(5,_C); break; // BIT 5,C
|
|
case /*CB*/0x6a: BIT(5,_D); break; // BIT 5,D
|
|
case /*CB*/0x6b: BIT(5,_E); break; // BIT 5,E
|
|
case /*CB*/0x6c: BIT(5,_H); break; // BIT 5,H
|
|
case /*CB*/0x6d: BIT(5,_L); break; // BIT 5,L
|
|
case /*CB*/0x6e: BIT(5,RM(_HL)); break; // BIT 5,(HL)
|
|
case /*CB*/0x6f: BIT(5,_A); break; // BIT 5,A
|
|
|
|
case /*CB*/0x70: BIT(6,_B); break; // BIT 6,B
|
|
case /*CB*/0x71: BIT(6,_C); break; // BIT 6,C
|
|
case /*CB*/0x72: BIT(6,_D); break; // BIT 6,D
|
|
case /*CB*/0x73: BIT(6,_E); break; // BIT 6,E
|
|
case /*CB*/0x74: BIT(6,_H); break; // BIT 6,H
|
|
case /*CB*/0x75: BIT(6,_L); break; // BIT 6,L
|
|
case /*CB*/0x76: BIT(6,RM(_HL)); break; // BIT 6,(HL)
|
|
case /*CB*/0x77: BIT(6,_A); break; // BIT 6,A
|
|
|
|
case /*CB*/0x78: BIT(7,_B); break; // BIT 7,B
|
|
case /*CB*/0x79: BIT(7,_C); break; // BIT 7,C
|
|
case /*CB*/0x7a: BIT(7,_D); break; // BIT 7,D
|
|
case /*CB*/0x7b: BIT(7,_E); break; // BIT 7,E
|
|
case /*CB*/0x7c: BIT(7,_H); break; // BIT 7,H
|
|
case /*CB*/0x7d: BIT(7,_L); break; // BIT 7,L
|
|
case /*CB*/0x7e: BIT(7,RM(_HL)); break; // BIT 7,(HL)
|
|
case /*CB*/0x7f: BIT(7,_A); break; // BIT 7,A
|
|
|
|
case /*CB*/0x80: _B = RES(0,_B); break; // RES 0,B
|
|
case /*CB*/0x81: _C = RES(0,_C); break; // RES 0,C
|
|
case /*CB*/0x82: _D = RES(0,_D); break; // RES 0,D
|
|
case /*CB*/0x83: _E = RES(0,_E); break; // RES 0,E
|
|
case /*CB*/0x84: _H = RES(0,_H); break; // RES 0,H
|
|
case /*CB*/0x85: _L = RES(0,_L); break; // RES 0,L
|
|
case /*CB*/0x86: WM( _HL, RES(0,RM(_HL)) ); break; // RES 0,(HL)
|
|
case /*CB*/0x87: _A = RES(0,_A); break; // RES 0,A
|
|
|
|
case /*CB*/0x88: _B = RES(1,_B); break; // RES 1,B
|
|
case /*CB*/0x89: _C = RES(1,_C); break; // RES 1,C
|
|
case /*CB*/0x8a: _D = RES(1,_D); break; // RES 1,D
|
|
case /*CB*/0x8b: _E = RES(1,_E); break; // RES 1,E
|
|
case /*CB*/0x8c: _H = RES(1,_H); break; // RES 1,H
|
|
case /*CB*/0x8d: _L = RES(1,_L); break; // RES 1,L
|
|
case /*CB*/0x8e: WM( _HL, RES(1,RM(_HL)) ); break; // RES 1,(HL)
|
|
case /*CB*/0x8f: _A = RES(1,_A); break; // RES 1,A
|
|
|
|
case /*CB*/0x90: _B = RES(2,_B); break; // RES 2,B
|
|
case /*CB*/0x91: _C = RES(2,_C); break; // RES 2,C
|
|
case /*CB*/0x92: _D = RES(2,_D); break; // RES 2,D
|
|
case /*CB*/0x93: _E = RES(2,_E); break; // RES 2,E
|
|
case /*CB*/0x94: _H = RES(2,_H); break; // RES 2,H
|
|
case /*CB*/0x95: _L = RES(2,_L); break; // RES 2,L
|
|
case /*CB*/0x96: WM( _HL, RES(2,RM(_HL)) ); break; // RES 2,(HL)
|
|
case /*CB*/0x97: _A = RES(2,_A); break; // RES 2,A
|
|
|
|
case /*CB*/0x98: _B = RES(3,_B); break; // RES 3,B
|
|
case /*CB*/0x99: _C = RES(3,_C); break; // RES 3,C
|
|
case /*CB*/0x9a: _D = RES(3,_D); break; // RES 3,D
|
|
case /*CB*/0x9b: _E = RES(3,_E); break; // RES 3,E
|
|
case /*CB*/0x9c: _H = RES(3,_H); break; // RES 3,H
|
|
case /*CB*/0x9d: _L = RES(3,_L); break; // RES 3,L
|
|
case /*CB*/0x9e: WM( _HL, RES(3,RM(_HL)) ); break; // RES 3,(HL)
|
|
case /*CB*/0x9f: _A = RES(3,_A); break; // RES 3,A
|
|
|
|
case /*CB*/0xa0: _B = RES(4,_B); break; // RES 4,B
|
|
case /*CB*/0xa1: _C = RES(4,_C); break; // RES 4,C
|
|
case /*CB*/0xa2: _D = RES(4,_D); break; // RES 4,D
|
|
case /*CB*/0xa3: _E = RES(4,_E); break; // RES 4,E
|
|
case /*CB*/0xa4: _H = RES(4,_H); break; // RES 4,H
|
|
case /*CB*/0xa5: _L = RES(4,_L); break; // RES 4,L
|
|
case /*CB*/0xa6: WM( _HL, RES(4,RM(_HL)) ); break; // RES 4,(HL)
|
|
case /*CB*/0xa7: _A = RES(4,_A); break; // RES 4,A
|
|
|
|
case /*CB*/0xa8: _B = RES(5,_B); break; // RES 5,B
|
|
case /*CB*/0xa9: _C = RES(5,_C); break; // RES 5,C
|
|
case /*CB*/0xaa: _D = RES(5,_D); break; // RES 5,D
|
|
case /*CB*/0xab: _E = RES(5,_E); break; // RES 5,E
|
|
case /*CB*/0xac: _H = RES(5,_H); break; // RES 5,H
|
|
case /*CB*/0xad: _L = RES(5,_L); break; // RES 5,L
|
|
case /*CB*/0xae: WM( _HL, RES(5,RM(_HL)) ); break; // RES 5,(HL)
|
|
case /*CB*/0xaf: _A = RES(5,_A); break; // RES 5,A
|
|
|
|
case /*CB*/0xb0: _B = RES(6,_B); break; // RES 6,B
|
|
case /*CB*/0xb1: _C = RES(6,_C); break; // RES 6,C
|
|
case /*CB*/0xb2: _D = RES(6,_D); break; // RES 6,D
|
|
case /*CB*/0xb3: _E = RES(6,_E); break; // RES 6,E
|
|
case /*CB*/0xb4: _H = RES(6,_H); break; // RES 6,H
|
|
case /*CB*/0xb5: _L = RES(6,_L); break; // RES 6,L
|
|
case /*CB*/0xb6: WM( _HL, RES(6,RM(_HL)) ); break; // RES 6,(HL)
|
|
case /*CB*/0xb7: _A = RES(6,_A); break; // RES 6,A
|
|
|
|
case /*CB*/0xb8: _B = RES(7,_B); break; // RES 7,B
|
|
case /*CB*/0xb9: _C = RES(7,_C); break; // RES 7,C
|
|
case /*CB*/0xba: _D = RES(7,_D); break; // RES 7,D
|
|
case /*CB*/0xbb: _E = RES(7,_E); break; // RES 7,E
|
|
case /*CB*/0xbc: _H = RES(7,_H); break; // RES 7,H
|
|
case /*CB*/0xbd: _L = RES(7,_L); break; // RES 7,L
|
|
case /*CB*/0xbe: WM( _HL, RES(7,RM(_HL)) ); break; // RES 7,(HL)
|
|
case /*CB*/0xbf: _A = RES(7,_A); break; // RES 7,A
|
|
|
|
case /*CB*/0xc0: _B = SET(0,_B); break; // SET 0,B
|
|
case /*CB*/0xc1: _C = SET(0,_C); break; // SET 0,C
|
|
case /*CB*/0xc2: _D = SET(0,_D); break; // SET 0,D
|
|
case /*CB*/0xc3: _E = SET(0,_E); break; // SET 0,E
|
|
case /*CB*/0xc4: _H = SET(0,_H); break; // SET 0,H
|
|
case /*CB*/0xc5: _L = SET(0,_L); break; // SET 0,L
|
|
case /*CB*/0xc6: WM( _HL, SET(0,RM(_HL)) ); break; // SET 0,(HL)
|
|
case /*CB*/0xc7: _A = SET(0,_A); break; // SET 0,A
|
|
|
|
case /*CB*/0xc8: _B = SET(1,_B); break; // SET 1,B
|
|
case /*CB*/0xc9: _C = SET(1,_C); break; // SET 1,C
|
|
case /*CB*/0xca: _D = SET(1,_D); break; // SET 1,D
|
|
case /*CB*/0xcb: _E = SET(1,_E); break; // SET 1,E
|
|
case /*CB*/0xcc: _H = SET(1,_H); break; // SET 1,H
|
|
case /*CB*/0xcd: _L = SET(1,_L); break; // SET 1,L
|
|
case /*CB*/0xce: WM( _HL, SET(1,RM(_HL)) ); break; // SET 1,(HL)
|
|
case /*CB*/0xcf: _A = SET(1,_A); break; // SET 1,A
|
|
|
|
case /*CB*/0xd0: _B = SET(2,_B); break; // SET 2,B
|
|
case /*CB*/0xd1: _C = SET(2,_C); break; // SET 2,C
|
|
case /*CB*/0xd2: _D = SET(2,_D); break; // SET 2,D
|
|
case /*CB*/0xd3: _E = SET(2,_E); break; // SET 2,E
|
|
case /*CB*/0xd4: _H = SET(2,_H); break; // SET 2,H
|
|
case /*CB*/0xd5: _L = SET(2,_L); break; // SET 2,L
|
|
case /*CB*/0xd6: WM( _HL, SET(2,RM(_HL)) ); break; // SET 2,(HL)
|
|
case /*CB*/0xd7: _A = SET(2,_A); break; // SET 2,A
|
|
|
|
case /*CB*/0xd8: _B = SET(3,_B); break; // SET 3,B
|
|
case /*CB*/0xd9: _C = SET(3,_C); break; // SET 3,C
|
|
case /*CB*/0xda: _D = SET(3,_D); break; // SET 3,D
|
|
case /*CB*/0xdb: _E = SET(3,_E); break; // SET 3,E
|
|
case /*CB*/0xdc: _H = SET(3,_H); break; // SET 3,H
|
|
case /*CB*/0xdd: _L = SET(3,_L); break; // SET 3,L
|
|
case /*CB*/0xde: WM( _HL, SET(3,RM(_HL)) ); break; // SET 3,(HL)
|
|
case /*CB*/0xdf: _A = SET(3,_A); break; // SET 3,A
|
|
|
|
case /*CB*/0xe0: _B = SET(4,_B); break; // SET 4,B
|
|
case /*CB*/0xe1: _C = SET(4,_C); break; // SET 4,C
|
|
case /*CB*/0xe2: _D = SET(4,_D); break; // SET 4,D
|
|
case /*CB*/0xe3: _E = SET(4,_E); break; // SET 4,E
|
|
case /*CB*/0xe4: _H = SET(4,_H); break; // SET 4,H
|
|
case /*CB*/0xe5: _L = SET(4,_L); break; // SET 4,L
|
|
case /*CB*/0xe6: WM( _HL, SET(4,RM(_HL)) ); break; // SET 4,(HL)
|
|
case /*CB*/0xe7: _A = SET(4,_A); break; // SET 4,A
|
|
|
|
case /*CB*/0xe8: _B = SET(5,_B); break; // SET 5,B
|
|
case /*CB*/0xe9: _C = SET(5,_C); break; // SET 5,C
|
|
case /*CB*/0xea: _D = SET(5,_D); break; // SET 5,D
|
|
case /*CB*/0xeb: _E = SET(5,_E); break; // SET 5,E
|
|
case /*CB*/0xec: _H = SET(5,_H); break; // SET 5,H
|
|
case /*CB*/0xed: _L = SET(5,_L); break; // SET 5,L
|
|
case /*CB*/0xee: WM( _HL, SET(5,RM(_HL)) ); break; // SET 5,(HL)
|
|
case /*CB*/0xef: _A = SET(5,_A); break; // SET 5,A
|
|
|
|
case /*CB*/0xf0: _B = SET(6,_B); break; // SET 6,B
|
|
case /*CB*/0xf1: _C = SET(6,_C); break; // SET 6,C
|
|
case /*CB*/0xf2: _D = SET(6,_D); break; // SET 6,D
|
|
case /*CB*/0xf3: _E = SET(6,_E); break; // SET 6,E
|
|
case /*CB*/0xf4: _H = SET(6,_H); break; // SET 6,H
|
|
case /*CB*/0xf5: _L = SET(6,_L); break; // SET 6,L
|
|
case /*CB*/0xf6: WM( _HL, SET(6,RM(_HL)) ); break; // SET 6,(HL)
|
|
case /*CB*/0xf7: _A = SET(6,_A); break; // SET 6,A
|
|
|
|
case /*CB*/0xf8: _B = SET(7,_B); break; // SET 7,B
|
|
case /*CB*/0xf9: _C = SET(7,_C); break; // SET 7,C
|
|
case /*CB*/0xfa: _D = SET(7,_D); break; // SET 7,D
|
|
case /*CB*/0xfb: _E = SET(7,_E); break; // SET 7,E
|
|
case /*CB*/0xfc: _H = SET(7,_H); break; // SET 7,H
|
|
case /*CB*/0xfd: _L = SET(7,_L); break; // SET 7,L
|
|
case /*CB*/0xfe: WM( _HL, SET(7,RM(_HL)) ); break; // SET 7,(HL)
|
|
case /*CB*/0xff: _A = SET(7,_A); break; // SET 7,A
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_ea_xycb(
|
|
struct Z80_STATE *state, uint8 op, uint16 EA
|
|
) {
|
|
|
|
//printf("PC=%04X exec xycb %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*xycb*/0x00: _B = RLC( RM(EA) ); WM( EA,_B ); break; // RLC B=(XY+o)
|
|
case /*xycb*/0x01: _C = RLC( RM(EA) ); WM( EA,_C ); break; // RLC C=(XY+o)
|
|
case /*xycb*/0x02: _D = RLC( RM(EA) ); WM( EA,_D ); break; // RLC D=(XY+o)
|
|
case /*xycb*/0x03: _E = RLC( RM(EA) ); WM( EA,_E ); break; // RLC E=(XY+o)
|
|
case /*xycb*/0x04: _H = RLC( RM(EA) ); WM( EA,_H ); break; // RLC H=(XY+o)
|
|
case /*xycb*/0x05: _L = RLC( RM(EA) ); WM( EA,_L ); break; // RLC L=(XY+o)
|
|
case /*xycb*/0x06: WM( EA, RLC( RM(EA) ) ); break; // RLC (XY+o)
|
|
case /*xycb*/0x07: _A = RLC( RM(EA) ); WM( EA,_A ); break; // RLC A=(XY+o)
|
|
|
|
case /*xycb*/0x08: _B = RRC( RM(EA) ); WM( EA,_B ); break; // RRC B=(XY+o)
|
|
case /*xycb*/0x09: _C = RRC( RM(EA) ); WM( EA,_C ); break; // RRC C=(XY+o)
|
|
case /*xycb*/0x0a: _D = RRC( RM(EA) ); WM( EA,_D ); break; // RRC D=(XY+o)
|
|
case /*xycb*/0x0b: _E = RRC( RM(EA) ); WM( EA,_E ); break; // RRC E=(XY+o)
|
|
case /*xycb*/0x0c: _H = RRC( RM(EA) ); WM( EA,_H ); break; // RRC H=(XY+o)
|
|
case /*xycb*/0x0d: _L = RRC( RM(EA) ); WM( EA,_L ); break; // RRC L=(XY+o)
|
|
case /*xycb*/0x0e: WM( EA,RRC( RM(EA) ) ); break; // RRC (XY+o)
|
|
case /*xycb*/0x0f: _A = RRC( RM(EA) ); WM( EA,_A ); break; // RRC A=(XY+o)
|
|
|
|
case /*xycb*/0x10: _B = RL( RM(EA) ); WM( EA,_B ); break; // RL B=(XY+o)
|
|
case /*xycb*/0x11: _C = RL( RM(EA) ); WM( EA,_C ); break; // RL C=(XY+o)
|
|
case /*xycb*/0x12: _D = RL( RM(EA) ); WM( EA,_D ); break; // RL D=(XY+o)
|
|
case /*xycb*/0x13: _E = RL( RM(EA) ); WM( EA,_E ); break; // RL E=(XY+o)
|
|
case /*xycb*/0x14: _H = RL( RM(EA) ); WM( EA,_H ); break; // RL H=(XY+o)
|
|
case /*xycb*/0x15: _L = RL( RM(EA) ); WM( EA,_L ); break; // RL L=(XY+o)
|
|
case /*xycb*/0x16: WM( EA,RL( RM(EA) ) ); break; // RL (XY+o)
|
|
case /*xycb*/0x17: _A = RL( RM(EA) ); WM( EA,_A ); break; // RL A=(XY+o)
|
|
|
|
case /*xycb*/0x18: _B = RR( RM(EA) ); WM( EA,_B ); break; // RR B=(XY+o)
|
|
case /*xycb*/0x19: _C = RR( RM(EA) ); WM( EA,_C ); break; // RR C=(XY+o)
|
|
case /*xycb*/0x1a: _D = RR( RM(EA) ); WM( EA,_D ); break; // RR D=(XY+o)
|
|
case /*xycb*/0x1b: _E = RR( RM(EA) ); WM( EA,_E ); break; // RR E=(XY+o)
|
|
case /*xycb*/0x1c: _H = RR( RM(EA) ); WM( EA,_H ); break; // RR H=(XY+o)
|
|
case /*xycb*/0x1d: _L = RR( RM(EA) ); WM( EA,_L ); break; // RR L=(XY+o)
|
|
case /*xycb*/0x1e: WM( EA,RR( RM(EA) ) ); break; // RR (XY+o)
|
|
case /*xycb*/0x1f: _A = RR( RM(EA) ); WM( EA,_A ); break; // RR A=(XY+o)
|
|
|
|
case /*xycb*/0x20: _B = SLA( RM(EA) ); WM( EA,_B ); break; // SLA B=(XY+o)
|
|
case /*xycb*/0x21: _C = SLA( RM(EA) ); WM( EA,_C ); break; // SLA C=(XY+o)
|
|
case /*xycb*/0x22: _D = SLA( RM(EA) ); WM( EA,_D ); break; // SLA D=(XY+o)
|
|
case /*xycb*/0x23: _E = SLA( RM(EA) ); WM( EA,_E ); break; // SLA E=(XY+o)
|
|
case /*xycb*/0x24: _H = SLA( RM(EA) ); WM( EA,_H ); break; // SLA H=(XY+o)
|
|
case /*xycb*/0x25: _L = SLA( RM(EA) ); WM( EA,_L ); break; // SLA L=(XY+o)
|
|
case /*xycb*/0x26: WM( EA,SLA( RM(EA) ) ); break; // SLA (XY+o)
|
|
case /*xycb*/0x27: _A = SLA( RM(EA) ); WM( EA,_A ); break; // SLA A=(XY+o)
|
|
|
|
case /*xycb*/0x28: _B = SRA( RM(EA) ); WM( EA,_B ); break; // SRA B=(XY+o)
|
|
case /*xycb*/0x29: _C = SRA( RM(EA) ); WM( EA,_C ); break; // SRA C=(XY+o)
|
|
case /*xycb*/0x2a: _D = SRA( RM(EA) ); WM( EA,_D ); break; // SRA D=(XY+o)
|
|
case /*xycb*/0x2b: _E = SRA( RM(EA) ); WM( EA,_E ); break; // SRA E=(XY+o)
|
|
case /*xycb*/0x2c: _H = SRA( RM(EA) ); WM( EA,_H ); break; // SRA H=(XY+o)
|
|
case /*xycb*/0x2d: _L = SRA( RM(EA) ); WM( EA,_L ); break; // SRA L=(XY+o)
|
|
case /*xycb*/0x2e: WM( EA,SRA( RM(EA) ) ); break; // SRA (XY+o)
|
|
case /*xycb*/0x2f: _A = SRA( RM(EA) ); WM( EA,_A ); break; // SRA A=(XY+o)
|
|
|
|
case /*xycb*/0x30: _B = SLL( RM(EA) ); WM( EA,_B ); break; // SLL B=(XY+o)
|
|
case /*xycb*/0x31: _C = SLL( RM(EA) ); WM( EA,_C ); break; // SLL C=(XY+o)
|
|
case /*xycb*/0x32: _D = SLL( RM(EA) ); WM( EA,_D ); break; // SLL D=(XY+o)
|
|
case /*xycb*/0x33: _E = SLL( RM(EA) ); WM( EA,_E ); break; // SLL E=(XY+o)
|
|
case /*xycb*/0x34: _H = SLL( RM(EA) ); WM( EA,_H ); break; // SLL H=(XY+o)
|
|
case /*xycb*/0x35: _L = SLL( RM(EA) ); WM( EA,_L ); break; // SLL L=(XY+o)
|
|
case /*xycb*/0x36: WM( EA,SLL( RM(EA) ) ); break; // SLL (XY+o)
|
|
case /*xycb*/0x37: _A = SLL( RM(EA) ); WM( EA,_A ); break; // SLL A=(XY+o)
|
|
|
|
case /*xycb*/0x38: _B = SRL( RM(EA) ); WM( EA,_B ); break; // SRL B=(XY+o)
|
|
case /*xycb*/0x39: _C = SRL( RM(EA) ); WM( EA,_C ); break; // SRL C=(XY+o)
|
|
case /*xycb*/0x3a: _D = SRL( RM(EA) ); WM( EA,_D ); break; // SRL D=(XY+o)
|
|
case /*xycb*/0x3b: _E = SRL( RM(EA) ); WM( EA,_E ); break; // SRL E=(XY+o)
|
|
case /*xycb*/0x3c: _H = SRL( RM(EA) ); WM( EA,_H ); break; // SRL H=(XY+o)
|
|
case /*xycb*/0x3d: _L = SRL( RM(EA) ); WM( EA,_L ); break; // SRL L=(XY+o)
|
|
case /*xycb*/0x3e: WM( EA,SRL( RM(EA) ) ); break; // SRL (XY+o)
|
|
case /*xycb*/0x3f: _A = SRL( RM(EA) ); WM( EA,_A ); break; // SRL A=(XY+o)
|
|
|
|
case /*xycb*/0x40: BIT_XY(0,RM(EA)); break; // BIT 0,B=(XY+o)
|
|
case /*xycb*/0x41: BIT_XY(0,RM(EA)); break; // BIT 0,C=(XY+o)
|
|
case /*xycb*/0x42: BIT_XY(0,RM(EA)); break; // BIT 0,D=(XY+o)
|
|
case /*xycb*/0x43: BIT_XY(0,RM(EA)); break; // BIT 0,E=(XY+o)
|
|
case /*xycb*/0x44: BIT_XY(0,RM(EA)); break; // BIT 0,H=(XY+o)
|
|
case /*xycb*/0x45: BIT_XY(0,RM(EA)); break; // BIT 0,L=(XY+o)
|
|
case /*xycb*/0x46: BIT_XY(0,RM(EA)); break; // BIT 0,(XY+o)
|
|
case /*xycb*/0x47: BIT_XY(0,RM(EA)); break; // BIT 0,A=(XY+o)
|
|
|
|
case /*xycb*/0x48: BIT_XY(1,RM(EA)); break; // BIT 1,B=(XY+o)
|
|
case /*xycb*/0x49: BIT_XY(1,RM(EA)); break; // BIT 1,C=(XY+o)
|
|
case /*xycb*/0x4a: BIT_XY(1,RM(EA)); break; // BIT 1,D=(XY+o)
|
|
case /*xycb*/0x4b: BIT_XY(1,RM(EA)); break; // BIT 1,E=(XY+o)
|
|
case /*xycb*/0x4c: BIT_XY(1,RM(EA)); break; // BIT 1,H=(XY+o)
|
|
case /*xycb*/0x4d: BIT_XY(1,RM(EA)); break; // BIT 1,L=(XY+o)
|
|
case /*xycb*/0x4e: BIT_XY(1,RM(EA)); break; // BIT 1,(XY+o)
|
|
case /*xycb*/0x4f: BIT_XY(1,RM(EA)); break; // BIT 1,A=(XY+o)
|
|
|
|
case /*xycb*/0x50: BIT_XY(2,RM(EA)); break; // BIT 2,B=(XY+o)
|
|
case /*xycb*/0x51: BIT_XY(2,RM(EA)); break; // BIT 2,C=(XY+o)
|
|
case /*xycb*/0x52: BIT_XY(2,RM(EA)); break; // BIT 2,D=(XY+o)
|
|
case /*xycb*/0x53: BIT_XY(2,RM(EA)); break; // BIT 2,E=(XY+o)
|
|
case /*xycb*/0x54: BIT_XY(2,RM(EA)); break; // BIT 2,H=(XY+o)
|
|
case /*xycb*/0x55: BIT_XY(2,RM(EA)); break; // BIT 2,L=(XY+o)
|
|
case /*xycb*/0x56: BIT_XY(2,RM(EA)); break; // BIT 2,(XY+o)
|
|
case /*xycb*/0x57: BIT_XY(2,RM(EA)); break; // BIT 2,A=(XY+o)
|
|
|
|
case /*xycb*/0x58: BIT_XY(3,RM(EA)); break; // BIT 3,B=(XY+o)
|
|
case /*xycb*/0x59: BIT_XY(3,RM(EA)); break; // BIT 3,C=(XY+o)
|
|
case /*xycb*/0x5a: BIT_XY(3,RM(EA)); break; // BIT 3,D=(XY+o)
|
|
case /*xycb*/0x5b: BIT_XY(3,RM(EA)); break; // BIT 3,E=(XY+o)
|
|
case /*xycb*/0x5c: BIT_XY(3,RM(EA)); break; // BIT 3,H=(XY+o)
|
|
case /*xycb*/0x5d: BIT_XY(3,RM(EA)); break; // BIT 3,L=(XY+o)
|
|
case /*xycb*/0x5e: BIT_XY(3,RM(EA)); break; // BIT 3,(XY+o)
|
|
case /*xycb*/0x5f: BIT_XY(3,RM(EA)); break; // BIT 3,A=(XY+o)
|
|
|
|
case /*xycb*/0x60: BIT_XY(4,RM(EA)); break; // BIT 4,B=(XY+o)
|
|
case /*xycb*/0x61: BIT_XY(4,RM(EA)); break; // BIT 4,C=(XY+o)
|
|
case /*xycb*/0x62: BIT_XY(4,RM(EA)); break; // BIT 4,D=(XY+o)
|
|
case /*xycb*/0x63: BIT_XY(4,RM(EA)); break; // BIT 4,E=(XY+o)
|
|
case /*xycb*/0x64: BIT_XY(4,RM(EA)); break; // BIT 4,H=(XY+o)
|
|
case /*xycb*/0x65: BIT_XY(4,RM(EA)); break; // BIT 4,L=(XY+o)
|
|
case /*xycb*/0x66: BIT_XY(4,RM(EA)); break; // BIT 4,(XY+o)
|
|
case /*xycb*/0x67: BIT_XY(4,RM(EA)); break; // BIT 4,A=(XY+o)
|
|
|
|
case /*xycb*/0x68: BIT_XY(5,RM(EA)); break; // BIT 5,B=(XY+o)
|
|
case /*xycb*/0x69: BIT_XY(5,RM(EA)); break; // BIT 5,C=(XY+o)
|
|
case /*xycb*/0x6a: BIT_XY(5,RM(EA)); break; // BIT 5,D=(XY+o)
|
|
case /*xycb*/0x6b: BIT_XY(5,RM(EA)); break; // BIT 5,E=(XY+o)
|
|
case /*xycb*/0x6c: BIT_XY(5,RM(EA)); break; // BIT 5,H=(XY+o)
|
|
case /*xycb*/0x6d: BIT_XY(5,RM(EA)); break; // BIT 5,L=(XY+o)
|
|
case /*xycb*/0x6e: BIT_XY(5,RM(EA)); break; // BIT 5,(XY+o)
|
|
case /*xycb*/0x6f: BIT_XY(5,RM(EA)); break; // BIT 5,A=(XY+o)
|
|
|
|
case /*xycb*/0x70: BIT_XY(6,RM(EA)); break; // BIT 6,B=(XY+o)
|
|
case /*xycb*/0x71: BIT_XY(6,RM(EA)); break; // BIT 6,C=(XY+o)
|
|
case /*xycb*/0x72: BIT_XY(6,RM(EA)); break; // BIT 6,D=(XY+o)
|
|
case /*xycb*/0x73: BIT_XY(6,RM(EA)); break; // BIT 6,E=(XY+o)
|
|
case /*xycb*/0x74: BIT_XY(6,RM(EA)); break; // BIT 6,H=(XY+o)
|
|
case /*xycb*/0x75: BIT_XY(6,RM(EA)); break; // BIT 6,L=(XY+o)
|
|
case /*xycb*/0x76: BIT_XY(6,RM(EA)); break; // BIT 6,(XY+o)
|
|
case /*xycb*/0x77: BIT_XY(6,RM(EA)); break; // BIT 6,A=(XY+o)
|
|
|
|
case /*xycb*/0x78: BIT_XY(7,RM(EA)); break; // BIT 7,B=(XY+o)
|
|
case /*xycb*/0x79: BIT_XY(7,RM(EA)); break; // BIT 7,C=(XY+o)
|
|
case /*xycb*/0x7a: BIT_XY(7,RM(EA)); break; // BIT 7,D=(XY+o)
|
|
case /*xycb*/0x7b: BIT_XY(7,RM(EA)); break; // BIT 7,E=(XY+o)
|
|
case /*xycb*/0x7c: BIT_XY(7,RM(EA)); break; // BIT 7,H=(XY+o)
|
|
case /*xycb*/0x7d: BIT_XY(7,RM(EA)); break; // BIT 7,L=(XY+o)
|
|
case /*xycb*/0x7e: BIT_XY(7,RM(EA)); break; // BIT 7,(XY+o)
|
|
case /*xycb*/0x7f: BIT_XY(7,RM(EA)); break; // BIT 7,A=(XY+o)
|
|
|
|
case /*xycb*/0x80: _B = RES(0, RM(EA) ); WM( EA,_B ); break; // RES 0,B=(XY+o)
|
|
case /*xycb*/0x81: _C = RES(0, RM(EA) ); WM( EA,_C ); break; // RES 0,C=(XY+o)
|
|
case /*xycb*/0x82: _D = RES(0, RM(EA) ); WM( EA,_D ); break; // RES 0,D=(XY+o)
|
|
case /*xycb*/0x83: _E = RES(0, RM(EA) ); WM( EA,_E ); break; // RES 0,E=(XY+o)
|
|
case /*xycb*/0x84: _H = RES(0, RM(EA) ); WM( EA,_H ); break; // RES 0,H=(XY+o)
|
|
case /*xycb*/0x85: _L = RES(0, RM(EA) ); WM( EA,_L ); break; // RES 0,L=(XY+o)
|
|
case /*xycb*/0x86: WM( EA, RES(0,RM(EA)) ); break; // RES 0,(XY+o)
|
|
case /*xycb*/0x87: _A = RES(0, RM(EA) ); WM( EA,_A ); break; // RES 0,A=(XY+o)
|
|
|
|
case /*xycb*/0x88: _B = RES(1, RM(EA) ); WM( EA,_B ); break; // RES 1,B=(XY+o)
|
|
case /*xycb*/0x89: _C = RES(1, RM(EA) ); WM( EA,_C ); break; // RES 1,C=(XY+o)
|
|
case /*xycb*/0x8a: _D = RES(1, RM(EA) ); WM( EA,_D ); break; // RES 1,D=(XY+o)
|
|
case /*xycb*/0x8b: _E = RES(1, RM(EA) ); WM( EA,_E ); break; // RES 1,E=(XY+o)
|
|
case /*xycb*/0x8c: _H = RES(1, RM(EA) ); WM( EA,_H ); break; // RES 1,H=(XY+o)
|
|
case /*xycb*/0x8d: _L = RES(1, RM(EA) ); WM( EA,_L ); break; // RES 1,L=(XY+o)
|
|
case /*xycb*/0x8e: WM( EA, RES(1,RM(EA)) ); break; // RES 1,(XY+o)
|
|
case /*xycb*/0x8f: _A = RES(1, RM(EA) ); WM( EA,_A ); break; // RES 1,A=(XY+o)
|
|
|
|
case /*xycb*/0x90: _B = RES(2, RM(EA) ); WM( EA,_B ); break; // RES 2,B=(XY+o)
|
|
case /*xycb*/0x91: _C = RES(2, RM(EA) ); WM( EA,_C ); break; // RES 2,C=(XY+o)
|
|
case /*xycb*/0x92: _D = RES(2, RM(EA) ); WM( EA,_D ); break; // RES 2,D=(XY+o)
|
|
case /*xycb*/0x93: _E = RES(2, RM(EA) ); WM( EA,_E ); break; // RES 2,E=(XY+o)
|
|
case /*xycb*/0x94: _H = RES(2, RM(EA) ); WM( EA,_H ); break; // RES 2,H=(XY+o)
|
|
case /*xycb*/0x95: _L = RES(2, RM(EA) ); WM( EA,_L ); break; // RES 2,L=(XY+o)
|
|
case /*xycb*/0x96: WM( EA, RES(2,RM(EA)) ); break; // RES 2,(XY+o)
|
|
case /*xycb*/0x97: _A = RES(2, RM(EA) ); WM( EA,_A ); break; // RES 2,A=(XY+o)
|
|
|
|
case /*xycb*/0x98: _B = RES(3, RM(EA) ); WM( EA,_B ); break; // RES 3,B=(XY+o)
|
|
case /*xycb*/0x99: _C = RES(3, RM(EA) ); WM( EA,_C ); break; // RES 3,C=(XY+o)
|
|
case /*xycb*/0x9a: _D = RES(3, RM(EA) ); WM( EA,_D ); break; // RES 3,D=(XY+o)
|
|
case /*xycb*/0x9b: _E = RES(3, RM(EA) ); WM( EA,_E ); break; // RES 3,E=(XY+o)
|
|
case /*xycb*/0x9c: _H = RES(3, RM(EA) ); WM( EA,_H ); break; // RES 3,H=(XY+o)
|
|
case /*xycb*/0x9d: _L = RES(3, RM(EA) ); WM( EA,_L ); break; // RES 3,L=(XY+o)
|
|
case /*xycb*/0x9e: WM( EA, RES(3,RM(EA)) ); break; // RES 3,(XY+o)
|
|
case /*xycb*/0x9f: _A = RES(3, RM(EA) ); WM( EA,_A ); break; // RES 3,A=(XY+o)
|
|
|
|
case /*xycb*/0xa0: _B = RES(4, RM(EA) ); WM( EA,_B ); break; // RES 4,B=(XY+o)
|
|
case /*xycb*/0xa1: _C = RES(4, RM(EA) ); WM( EA,_C ); break; // RES 4,C=(XY+o)
|
|
case /*xycb*/0xa2: _D = RES(4, RM(EA) ); WM( EA,_D ); break; // RES 4,D=(XY+o)
|
|
case /*xycb*/0xa3: _E = RES(4, RM(EA) ); WM( EA,_E ); break; // RES 4,E=(XY+o)
|
|
case /*xycb*/0xa4: _H = RES(4, RM(EA) ); WM( EA,_H ); break; // RES 4,H=(XY+o)
|
|
case /*xycb*/0xa5: _L = RES(4, RM(EA) ); WM( EA,_L ); break; // RES 4,L=(XY+o)
|
|
case /*xycb*/0xa6: WM( EA, RES(4,RM(EA)) ); break; // RES 4,(XY+o)
|
|
case /*xycb*/0xa7: _A = RES(4, RM(EA) ); WM( EA,_A ); break; // RES 4,A=(XY+o)
|
|
|
|
case /*xycb*/0xa8: _B = RES(5, RM(EA) ); WM( EA,_B ); break; // RES 5,B=(XY+o)
|
|
case /*xycb*/0xa9: _C = RES(5, RM(EA) ); WM( EA,_C ); break; // RES 5,C=(XY+o)
|
|
case /*xycb*/0xaa: _D = RES(5, RM(EA) ); WM( EA,_D ); break; // RES 5,D=(XY+o)
|
|
case /*xycb*/0xab: _E = RES(5, RM(EA) ); WM( EA,_E ); break; // RES 5,E=(XY+o)
|
|
case /*xycb*/0xac: _H = RES(5, RM(EA) ); WM( EA,_H ); break; // RES 5,H=(XY+o)
|
|
case /*xycb*/0xad: _L = RES(5, RM(EA) ); WM( EA,_L ); break; // RES 5,L=(XY+o)
|
|
case /*xycb*/0xae: WM( EA, RES(5,RM(EA)) ); break; // RES 5,(XY+o)
|
|
case /*xycb*/0xaf: _A = RES(5, RM(EA) ); WM( EA,_A ); break; // RES 5,A=(XY+o)
|
|
|
|
case /*xycb*/0xb0: _B = RES(6, RM(EA) ); WM( EA,_B ); break; // RES 6,B=(XY+o)
|
|
case /*xycb*/0xb1: _C = RES(6, RM(EA) ); WM( EA,_C ); break; // RES 6,C=(XY+o)
|
|
case /*xycb*/0xb2: _D = RES(6, RM(EA) ); WM( EA,_D ); break; // RES 6,D=(XY+o)
|
|
case /*xycb*/0xb3: _E = RES(6, RM(EA) ); WM( EA,_E ); break; // RES 6,E=(XY+o)
|
|
case /*xycb*/0xb4: _H = RES(6, RM(EA) ); WM( EA,_H ); break; // RES 6,H=(XY+o)
|
|
case /*xycb*/0xb5: _L = RES(6, RM(EA) ); WM( EA,_L ); break; // RES 6,L=(XY+o)
|
|
case /*xycb*/0xb6: WM( EA, RES(6,RM(EA)) ); break; // RES 6,(XY+o)
|
|
case /*xycb*/0xb7: _A = RES(6, RM(EA) ); WM( EA,_A ); break; // RES 6,A=(XY+o)
|
|
|
|
case /*xycb*/0xb8: _B = RES(7, RM(EA) ); WM( EA,_B ); break; // RES 7,B=(XY+o)
|
|
case /*xycb*/0xb9: _C = RES(7, RM(EA) ); WM( EA,_C ); break; // RES 7,C=(XY+o)
|
|
case /*xycb*/0xba: _D = RES(7, RM(EA) ); WM( EA,_D ); break; // RES 7,D=(XY+o)
|
|
case /*xycb*/0xbb: _E = RES(7, RM(EA) ); WM( EA,_E ); break; // RES 7,E=(XY+o)
|
|
case /*xycb*/0xbc: _H = RES(7, RM(EA) ); WM( EA,_H ); break; // RES 7,H=(XY+o)
|
|
case /*xycb*/0xbd: _L = RES(7, RM(EA) ); WM( EA,_L ); break; // RES 7,L=(XY+o)
|
|
case /*xycb*/0xbe: WM( EA, RES(7,RM(EA)) ); break; // RES 7,(XY+o)
|
|
case /*xycb*/0xbf: _A = RES(7, RM(EA) ); WM( EA,_A ); break; // RES 7,A=(XY+o)
|
|
|
|
case /*xycb*/0xc0: _B = SET(0, RM(EA) ); WM( EA,_B ); break; // SET 0,B=(XY+o)
|
|
case /*xycb*/0xc1: _C = SET(0, RM(EA) ); WM( EA,_C ); break; // SET 0,C=(XY+o)
|
|
case /*xycb*/0xc2: _D = SET(0, RM(EA) ); WM( EA,_D ); break; // SET 0,D=(XY+o)
|
|
case /*xycb*/0xc3: _E = SET(0, RM(EA) ); WM( EA,_E ); break; // SET 0,E=(XY+o)
|
|
case /*xycb*/0xc4: _H = SET(0, RM(EA) ); WM( EA,_H ); break; // SET 0,H=(XY+o)
|
|
case /*xycb*/0xc5: _L = SET(0, RM(EA) ); WM( EA,_L ); break; // SET 0,L=(XY+o)
|
|
case /*xycb*/0xc6: WM( EA, SET(0,RM(EA)) ); break; // SET 0,(XY+o)
|
|
case /*xycb*/0xc7: _A = SET(0, RM(EA) ); WM( EA,_A ); break; // SET 0,A=(XY+o)
|
|
|
|
case /*xycb*/0xc8: _B = SET(1, RM(EA) ); WM( EA,_B ); break; // SET 1,B=(XY+o)
|
|
case /*xycb*/0xc9: _C = SET(1, RM(EA) ); WM( EA,_C ); break; // SET 1,C=(XY+o)
|
|
case /*xycb*/0xca: _D = SET(1, RM(EA) ); WM( EA,_D ); break; // SET 1,D=(XY+o)
|
|
case /*xycb*/0xcb: _E = SET(1, RM(EA) ); WM( EA,_E ); break; // SET 1,E=(XY+o)
|
|
case /*xycb*/0xcc: _H = SET(1, RM(EA) ); WM( EA,_H ); break; // SET 1,H=(XY+o)
|
|
case /*xycb*/0xcd: _L = SET(1, RM(EA) ); WM( EA,_L ); break; // SET 1,L=(XY+o)
|
|
case /*xycb*/0xce: WM( EA, SET(1,RM(EA)) ); break; // SET 1,(XY+o)
|
|
case /*xycb*/0xcf: _A = SET(1, RM(EA) ); WM( EA,_A ); break; // SET 1,A=(XY+o)
|
|
|
|
case /*xycb*/0xd0: _B = SET(2, RM(EA) ); WM( EA,_B ); break; // SET 2,B=(XY+o)
|
|
case /*xycb*/0xd1: _C = SET(2, RM(EA) ); WM( EA,_C ); break; // SET 2,C=(XY+o)
|
|
case /*xycb*/0xd2: _D = SET(2, RM(EA) ); WM( EA,_D ); break; // SET 2,D=(XY+o)
|
|
case /*xycb*/0xd3: _E = SET(2, RM(EA) ); WM( EA,_E ); break; // SET 2,E=(XY+o)
|
|
case /*xycb*/0xd4: _H = SET(2, RM(EA) ); WM( EA,_H ); break; // SET 2,H=(XY+o)
|
|
case /*xycb*/0xd5: _L = SET(2, RM(EA) ); WM( EA,_L ); break; // SET 2,L=(XY+o)
|
|
case /*xycb*/0xd6: WM( EA, SET(2,RM(EA)) ); break; // SET 2,(XY+o)
|
|
case /*xycb*/0xd7: _A = SET(2, RM(EA) ); WM( EA,_A ); break; // SET 2,A=(XY+o)
|
|
|
|
case /*xycb*/0xd8: _B = SET(3, RM(EA) ); WM( EA,_B ); break; // SET 3,B=(XY+o)
|
|
case /*xycb*/0xd9: _C = SET(3, RM(EA) ); WM( EA,_C ); break; // SET 3,C=(XY+o)
|
|
case /*xycb*/0xda: _D = SET(3, RM(EA) ); WM( EA,_D ); break; // SET 3,D=(XY+o)
|
|
case /*xycb*/0xdb: _E = SET(3, RM(EA) ); WM( EA,_E ); break; // SET 3,E=(XY+o)
|
|
case /*xycb*/0xdc: _H = SET(3, RM(EA) ); WM( EA,_H ); break; // SET 3,H=(XY+o)
|
|
case /*xycb*/0xdd: _L = SET(3, RM(EA) ); WM( EA,_L ); break; // SET 3,L=(XY+o)
|
|
case /*xycb*/0xde: WM( EA, SET(3,RM(EA)) ); break; // SET 3,(XY+o)
|
|
case /*xycb*/0xdf: _A = SET(3, RM(EA) ); WM( EA,_A ); break; // SET 3,A=(XY+o)
|
|
|
|
case /*xycb*/0xe0: _B = SET(4, RM(EA) ); WM( EA,_B ); break; // SET 4,B=(XY+o)
|
|
case /*xycb*/0xe1: _C = SET(4, RM(EA) ); WM( EA,_C ); break; // SET 4,C=(XY+o)
|
|
case /*xycb*/0xe2: _D = SET(4, RM(EA) ); WM( EA,_D ); break; // SET 4,D=(XY+o)
|
|
case /*xycb*/0xe3: _E = SET(4, RM(EA) ); WM( EA,_E ); break; // SET 4,E=(XY+o)
|
|
case /*xycb*/0xe4: _H = SET(4, RM(EA) ); WM( EA,_H ); break; // SET 4,H=(XY+o)
|
|
case /*xycb*/0xe5: _L = SET(4, RM(EA) ); WM( EA,_L ); break; // SET 4,L=(XY+o)
|
|
case /*xycb*/0xe6: WM( EA, SET(4,RM(EA)) ); break; // SET 4,(XY+o)
|
|
case /*xycb*/0xe7: _A = SET(4, RM(EA) ); WM( EA,_A ); break; // SET 4,A=(XY+o)
|
|
|
|
case /*xycb*/0xe8: _B = SET(5, RM(EA) ); WM( EA,_B ); break; // SET 5,B=(XY+o)
|
|
case /*xycb*/0xe9: _C = SET(5, RM(EA) ); WM( EA,_C ); break; // SET 5,C=(XY+o)
|
|
case /*xycb*/0xea: _D = SET(5, RM(EA) ); WM( EA,_D ); break; // SET 5,D=(XY+o)
|
|
case /*xycb*/0xeb: _E = SET(5, RM(EA) ); WM( EA,_E ); break; // SET 5,E=(XY+o)
|
|
case /*xycb*/0xec: _H = SET(5, RM(EA) ); WM( EA,_H ); break; // SET 5,H=(XY+o)
|
|
case /*xycb*/0xed: _L = SET(5, RM(EA) ); WM( EA,_L ); break; // SET 5,L=(XY+o)
|
|
case /*xycb*/0xee: WM( EA, SET(5,RM(EA)) ); break; // SET 5,(XY+o)
|
|
case /*xycb*/0xef: _A = SET(5, RM(EA) ); WM( EA,_A ); break; // SET 5,A=(XY+o)
|
|
|
|
case /*xycb*/0xf0: _B = SET(6, RM(EA) ); WM( EA,_B ); break; // SET 6,B=(XY+o)
|
|
case /*xycb*/0xf1: _C = SET(6, RM(EA) ); WM( EA,_C ); break; // SET 6,C=(XY+o)
|
|
case /*xycb*/0xf2: _D = SET(6, RM(EA) ); WM( EA,_D ); break; // SET 6,D=(XY+o)
|
|
case /*xycb*/0xf3: _E = SET(6, RM(EA) ); WM( EA,_E ); break; // SET 6,E=(XY+o)
|
|
case /*xycb*/0xf4: _H = SET(6, RM(EA) ); WM( EA,_H ); break; // SET 6,H=(XY+o)
|
|
case /*xycb*/0xf5: _L = SET(6, RM(EA) ); WM( EA,_L ); break; // SET 6,L=(XY+o)
|
|
case /*xycb*/0xf6: WM( EA, SET(6,RM(EA)) ); break; // SET 6,(XY+o)
|
|
case /*xycb*/0xf7: _A = SET(6, RM(EA) ); WM( EA,_A ); break; // SET 6,A=(XY+o)
|
|
|
|
case /*xycb*/0xf8: _B = SET(7, RM(EA) ); WM( EA,_B ); break; // SET 7,B=(XY+o)
|
|
case /*xycb*/0xf9: _C = SET(7, RM(EA) ); WM( EA,_C ); break; // SET 7,C=(XY+o)
|
|
case /*xycb*/0xfa: _D = SET(7, RM(EA) ); WM( EA,_D ); break; // SET 7,D=(XY+o)
|
|
case /*xycb*/0xfb: _E = SET(7, RM(EA) ); WM( EA,_E ); break; // SET 7,E=(XY+o)
|
|
case /*xycb*/0xfc: _H = SET(7, RM(EA) ); WM( EA,_H ); break; // SET 7,H=(XY+o)
|
|
case /*xycb*/0xfd: _L = SET(7, RM(EA) ); WM( EA,_L ); break; // SET 7,L=(XY+o)
|
|
case /*xycb*/0xfe: WM( EA, SET(7,RM(EA)) ); break; // SET 7,(XY+o)
|
|
case /*xycb*/0xff: _A = SET(7, RM(EA) ); WM( EA,_A ); break; // SET 7,A=(XY+o)
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_dd(struct Z80_STATE *state, uint8 op) {
|
|
uint16 EA;
|
|
|
|
//printf("PC=%04X exec dd %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*DD*/0x00: illegal_1(); /*op_00();*/ break; // DB DD
|
|
case /*DD*/0x01: illegal_1(); /*op_01();*/ break; // DB DD
|
|
case /*DD*/0x02: illegal_1(); /*op_02();*/ break; // DB DD
|
|
case /*DD*/0x03: illegal_1(); /*op_03();*/ break; // DB DD
|
|
case /*DD*/0x04: illegal_1(); /*op_04();*/ break; // DB DD
|
|
case /*DD*/0x05: illegal_1(); /*op_05();*/ break; // DB DD
|
|
case /*DD*/0x06: illegal_1(); /*op_06();*/ break; // DB DD
|
|
case /*DD*/0x07: illegal_1(); /*op_07();*/ break; // DB DD
|
|
|
|
case /*DD*/0x08: illegal_1(); /*op_08();*/ break; // DB DD
|
|
case /*DD*/0x09: _R++; ADD16(_IX,_BC); break; // ADD IX,BC
|
|
case /*DD*/0x0a: illegal_1(); /*op_0a();*/ break; // DB DD
|
|
case /*DD*/0x0b: illegal_1(); /*op_0b();*/ break; // DB DD
|
|
case /*DD*/0x0c: illegal_1(); /*op_0c();*/ break; // DB DD
|
|
case /*DD*/0x0d: illegal_1(); /*op_0d();*/ break; // DB DD
|
|
case /*DD*/0x0e: illegal_1(); /*op_0e();*/ break; // DB DD
|
|
case /*DD*/0x0f: illegal_1(); /*op_0f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x10: illegal_1(); /*op_10();*/ break; // DB DD
|
|
case /*DD*/0x11: illegal_1(); /*op_11();*/ break; // DB DD
|
|
case /*DD*/0x12: illegal_1(); /*op_12();*/ break; // DB DD
|
|
case /*DD*/0x13: illegal_1(); /*op_13();*/ break; // DB DD
|
|
case /*DD*/0x14: illegal_1(); /*op_14();*/ break; // DB DD
|
|
case /*DD*/0x15: illegal_1(); /*op_15();*/ break; // DB DD
|
|
case /*DD*/0x16: illegal_1(); /*op_16();*/ break; // DB DD
|
|
case /*DD*/0x17: illegal_1(); /*op_17();*/ break; // DB DD
|
|
|
|
case /*DD*/0x18: illegal_1(); /*op_18();*/ break; // DB DD
|
|
case /*DD*/0x19: _R++; ADD16(_IX,_DE); break; // ADD IX,DE
|
|
case /*DD*/0x1a: illegal_1(); /*op_1a();*/ break; // DB DD
|
|
case /*DD*/0x1b: illegal_1(); /*op_1b();*/ break; // DB DD
|
|
case /*DD*/0x1c: illegal_1(); /*op_1c();*/ break; // DB DD
|
|
case /*DD*/0x1d: illegal_1(); /*op_1d();*/ break; // DB DD
|
|
case /*DD*/0x1e: illegal_1(); /*op_1e();*/ break; // DB DD
|
|
case /*DD*/0x1f: illegal_1(); /*op_1f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x20: illegal_1(); /*op_20();*/ break; // DB DD
|
|
case /*DD*/0x21: _R++; _IX = ARG16(); break; // LD IX,w
|
|
case /*DD*/0x22: _R++; WM16( ARG16(), _IX ); break; // LD (w),IX
|
|
case /*DD*/0x23: _R++; _IX++; break; // INC IX
|
|
case /*DD*/0x24: _R++; _HX = INC(_HX); break; // INC HX
|
|
case /*DD*/0x25: _R++; _HX = DEC(_HX); break; // DEC HX
|
|
case /*DD*/0x26: _R++; _HX = ARG(); break; // LD HX,n
|
|
case /*DD*/0x27: illegal_1(); /*op_27();*/ break; // DB DD
|
|
|
|
case /*DD*/0x28: illegal_1(); /*op_28();*/ break; // DB DD
|
|
case /*DD*/0x29: _R++; ADD16(_IX,_IX); break; // ADD IX,IX
|
|
case /*DD*/0x2a: _R++; _IX = RM16( ARG16() ); break; // LD IX,(w)
|
|
case /*DD*/0x2b: _R++; _IX--; break; // DEC IX
|
|
case /*DD*/0x2c: _R++; _LX = INC(_LX); break; // INC LX
|
|
case /*DD*/0x2d: _R++; _LX = DEC(_LX); break; // DEC LX
|
|
case /*DD*/0x2e: _R++; _LX = ARG(); break; // LD LX,n
|
|
case /*DD*/0x2f: illegal_1(); /*op_2f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x30: illegal_1(); /*op_30();*/ break; // DB DD
|
|
case /*DD*/0x31: illegal_1(); /*op_31();*/ break; // DB DD
|
|
case /*DD*/0x32: illegal_1(); /*op_32();*/ break; // DB DD
|
|
case /*DD*/0x33: illegal_1(); /*op_33();*/ break; // DB DD
|
|
case /*DD*/0x34: _R++; EAX; WM( EA, INC(RM(EA)) ); break; // INC (IX+o)
|
|
case /*DD*/0x35: _R++; EAX; WM( EA, DEC(RM(EA)) ); break; // DEC (IX+o)
|
|
case /*DD*/0x36: _R++; EAX; WM( EA, ARG() ); break; // LD (IX+o),n
|
|
case /*DD*/0x37: illegal_1(); /*op_37();*/ break; // DB DD
|
|
|
|
case /*DD*/0x38: illegal_1(); /*op_38();*/ break; // DB DD
|
|
case /*DD*/0x39: _R++; ADD16(_IX,_SP); break; // ADD IX,SP
|
|
case /*DD*/0x3a: illegal_1(); /*op_3a();*/ break; // DB DD
|
|
case /*DD*/0x3b: illegal_1(); /*op_3b();*/ break; // DB DD
|
|
case /*DD*/0x3c: illegal_1(); /*op_3c();*/ break; // DB DD
|
|
case /*DD*/0x3d: illegal_1(); /*op_3d();*/ break; // DB DD
|
|
case /*DD*/0x3e: illegal_1(); /*op_3e();*/ break; // DB DD
|
|
case /*DD*/0x3f: illegal_1(); /*op_3f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x40: illegal_1(); /*op_40();*/ break; // DB DD
|
|
case /*DD*/0x41: illegal_1(); /*op_41();*/ break; // DB DD
|
|
case /*DD*/0x42: illegal_1(); /*op_42();*/ break; // DB DD
|
|
case /*DD*/0x43: illegal_1(); /*op_43();*/ break; // DB DD
|
|
case /*DD*/0x44: _R++; _B = _HX; break; // LD B,HX
|
|
case /*DD*/0x45: _R++; _B = _LX; break; // LD B,LX
|
|
case /*DD*/0x46: _R++; EAX; _B = RM(EA); break; // LD B,(IX+o)
|
|
case /*DD*/0x47: illegal_1(); /*op_47();*/ break; // DB DD
|
|
|
|
case /*DD*/0x48: illegal_1(); /*op_48();*/ break; // DB DD
|
|
case /*DD*/0x49: illegal_1(); /*op_49();*/ break; // DB DD
|
|
case /*DD*/0x4a: illegal_1(); /*op_4a();*/ break; // DB DD
|
|
case /*DD*/0x4b: illegal_1(); /*op_4b();*/ break; // DB DD
|
|
case /*DD*/0x4c: _R++; _C = _HX; break; // LD C,HX
|
|
case /*DD*/0x4d: _R++; _C = _LX; break; // LD C,LX
|
|
case /*DD*/0x4e: _R++; EAX; _C = RM(EA); break; // LD C,(IX+o)
|
|
case /*DD*/0x4f: illegal_1(); /*op_4f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x50: illegal_1(); /*op_50();*/ break; // DB DD
|
|
case /*DD*/0x51: illegal_1(); /*op_51();*/ break; // DB DD
|
|
case /*DD*/0x52: illegal_1(); /*op_52();*/ break; // DB DD
|
|
case /*DD*/0x53: illegal_1(); /*op_53();*/ break; // DB DD
|
|
case /*DD*/0x54: _R++; _D = _HX; break; // LD D,HX
|
|
case /*DD*/0x55: _R++; _D = _LX; break; // LD D,LX
|
|
case /*DD*/0x56: _R++; EAX; _D = RM(EA); break; // LD D,(IX+o)
|
|
case /*DD*/0x57: illegal_1(); /*op_57();*/ break; // DB DD
|
|
|
|
case /*DD*/0x58: illegal_1(); /*op_58();*/ break; // DB DD
|
|
case /*DD*/0x59: illegal_1(); /*op_59();*/ break; // DB DD
|
|
case /*DD*/0x5a: illegal_1(); /*op_5a();*/ break; // DB DD
|
|
case /*DD*/0x5b: illegal_1(); /*op_5b();*/ break; // DB DD
|
|
case /*DD*/0x5c: _R++; _E = _HX; break; // LD E,HX
|
|
case /*DD*/0x5d: _R++; _E = _LX; break; // LD E,LX
|
|
case /*DD*/0x5e: _R++; EAX; _E = RM(EA); break; // LD E,(IX+o)
|
|
case /*DD*/0x5f: illegal_1(); /*op_5f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x60: _R++; _HX = _B; break; // LD HX,B
|
|
case /*DD*/0x61: _R++; _HX = _C; break; // LD HX,C
|
|
case /*DD*/0x62: _R++; _HX = _D; break; // LD HX,D
|
|
case /*DD*/0x63: _R++; _HX = _E; break; // LD HX,E
|
|
case /*DD*/0x64: break; // LD HX,HX
|
|
case /*DD*/0x65: _R++; _HX = _LX; break; // LD HX,LX
|
|
case /*DD*/0x66: _R++; EAX; _H = RM(EA); break; // LD H,(IX+o)
|
|
case /*DD*/0x67: _R++; _HX = _A; break; // LD HX,A
|
|
|
|
case /*DD*/0x68: _R++; _LX = _B; break; // LD LX,B
|
|
case /*DD*/0x69: _R++; _LX = _C; break; // LD LX,C
|
|
case /*DD*/0x6a: _R++; _LX = _D; break; // LD LX,D
|
|
case /*DD*/0x6b: _R++; _LX = _E; break; // LD LX,E
|
|
case /*DD*/0x6c: _R++; _LX = _HX; break; // LD LX,HX
|
|
case /*DD*/0x6d: break; // LD LX,LX
|
|
case /*DD*/0x6e: _R++; EAX; _L = RM(EA); break; // LD L,(IX+o)
|
|
case /*DD*/0x6f: _R++; _LX = _A; break; // LD LX,A
|
|
|
|
case /*DD*/0x70: _R++; EAX; WM( EA, _B ); break; // LD (IX+o),B
|
|
case /*DD*/0x71: _R++; EAX; WM( EA, _C ); break; // LD (IX+o),C
|
|
case /*DD*/0x72: _R++; EAX; WM( EA, _D ); break; // LD (IX+o),D
|
|
case /*DD*/0x73: _R++; EAX; WM( EA, _E ); break; // LD (IX+o),E
|
|
case /*DD*/0x74: _R++; EAX; WM( EA, _H ); break; // LD (IX+o),H
|
|
case /*DD*/0x75: _R++; EAX; WM( EA, _L ); break; // LD (IX+o),L
|
|
case /*DD*/0x76: illegal_1(); /*op_76();*/ break; // DB DD
|
|
case /*DD*/0x77: _R++; EAX; WM( EA, _A ); break; // LD (IX+o),A
|
|
|
|
case /*DD*/0x78: illegal_1(); /*op_78();*/ break; // DB DD
|
|
case /*DD*/0x79: illegal_1(); /*op_79();*/ break; // DB DD
|
|
case /*DD*/0x7a: illegal_1(); /*op_7a();*/ break; // DB DD
|
|
case /*DD*/0x7b: illegal_1(); /*op_7b();*/ break; // DB DD
|
|
case /*DD*/0x7c: _R++; _A = _HX; break; // LD A,HX
|
|
case /*DD*/0x7d: _R++; _A = _LX; break; // LD A,LX
|
|
case /*DD*/0x7e: _R++; EAX; _A = RM(EA); break; // LD A,(IX+o)
|
|
case /*DD*/0x7f: illegal_1(); /*op_7f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x80: illegal_1(); /*op_80();*/ break; // DB DD
|
|
case /*DD*/0x81: illegal_1(); /*op_81();*/ break; // DB DD
|
|
case /*DD*/0x82: illegal_1(); /*op_82();*/ break; // DB DD
|
|
case /*DD*/0x83: illegal_1(); /*op_83();*/ break; // DB DD
|
|
case /*DD*/0x84: _R++; ADD(_HX); break; // ADD A,HX
|
|
case /*DD*/0x85: _R++; ADD(_LX); break; // ADD A,LX
|
|
case /*DD*/0x86: _R++; EAX; ADD(RM(EA)); break; // ADD A,(IX+o)
|
|
case /*DD*/0x87: illegal_1(); /*op_87();*/ break; // DB DD
|
|
|
|
case /*DD*/0x88: illegal_1(); /*op_88();*/ break; // DB DD
|
|
case /*DD*/0x89: illegal_1(); /*op_89();*/ break; // DB DD
|
|
case /*DD*/0x8a: illegal_1(); /*op_8a();*/ break; // DB DD
|
|
case /*DD*/0x8b: illegal_1(); /*op_8b();*/ break; // DB DD
|
|
case /*DD*/0x8c: _R++; ADC(_HX); break; // ADC A,HX
|
|
case /*DD*/0x8d: _R++; ADC(_LX); break; // ADC A,LX
|
|
case /*DD*/0x8e: _R++; EAX; ADC(RM(EA)); break; // ADC A,(IX+o)
|
|
case /*DD*/0x8f: illegal_1(); /*op_8f();*/ break; // DB DD
|
|
|
|
case /*DD*/0x90: illegal_1(); /*op_90();*/ break; // DB DD
|
|
case /*DD*/0x91: illegal_1(); /*op_91();*/ break; // DB DD
|
|
case /*DD*/0x92: illegal_1(); /*op_92();*/ break; // DB DD
|
|
case /*DD*/0x93: illegal_1(); /*op_93();*/ break; // DB DD
|
|
case /*DD*/0x94: _R++; SUB(_HX); break; // SUB HX
|
|
case /*DD*/0x95: _R++; SUB(_LX); break; // SUB LX
|
|
case /*DD*/0x96: _R++; EAX; SUB(RM(EA)); break; // SUB (IX+o)
|
|
case /*DD*/0x97: illegal_1(); /*op_97();*/ break; // DB DD
|
|
|
|
case /*DD*/0x98: illegal_1(); /*op_98();*/ break; // DB DD
|
|
case /*DD*/0x99: illegal_1(); /*op_99();*/ break; // DB DD
|
|
case /*DD*/0x9a: illegal_1(); /*op_9a();*/ break; // DB DD
|
|
case /*DD*/0x9b: illegal_1(); /*op_9b();*/ break; // DB DD
|
|
case /*DD*/0x9c: _R++; SBC(_HX); break; // SBC A,HX
|
|
case /*DD*/0x9d: _R++; SBC(_LX); break; // SBC A,LX
|
|
case /*DD*/0x9e: _R++; EAX; SBC(RM(EA)); break; // SBC A,(IX+o)
|
|
case /*DD*/0x9f: illegal_1(); /*op_9f();*/ break; // DB DD
|
|
|
|
case /*DD*/0xa0: illegal_1(); /*op_a0();*/ break; // DB DD
|
|
case /*DD*/0xa1: illegal_1(); /*op_a1();*/ break; // DB DD
|
|
case /*DD*/0xa2: illegal_1(); /*op_a2();*/ break; // DB DD
|
|
case /*DD*/0xa3: illegal_1(); /*op_a3();*/ break; // DB DD
|
|
case /*DD*/0xa4: _R++; AND(_HX); break; // AND HX
|
|
case /*DD*/0xa5: _R++; AND(_LX); break; // AND LX
|
|
case /*DD*/0xa6: _R++; EAX; AND(RM(EA)); break; // AND (IX+o)
|
|
case /*DD*/0xa7: illegal_1(); /*op_a7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xa8: illegal_1(); /*op_a8();*/ break; // DB DD
|
|
case /*DD*/0xa9: illegal_1(); /*op_a9();*/ break; // DB DD
|
|
case /*DD*/0xaa: illegal_1(); /*op_aa();*/ break; // DB DD
|
|
case /*DD*/0xab: illegal_1(); /*op_ab();*/ break; // DB DD
|
|
case /*DD*/0xac: _R++; XOR(_HX); break; // XOR HX
|
|
case /*DD*/0xad: _R++; XOR(_LX); break; // XOR LX
|
|
case /*DD*/0xae: _R++; EAX; XOR(RM(EA)); break; // XOR (IX+o)
|
|
case /*DD*/0xaf: illegal_1(); /*op_af();*/ break; // DB DD
|
|
|
|
case /*DD*/0xb0: illegal_1(); /*op_b0();*/ break; // DB DD
|
|
case /*DD*/0xb1: illegal_1(); /*op_b1();*/ break; // DB DD
|
|
case /*DD*/0xb2: illegal_1(); /*op_b2();*/ break; // DB DD
|
|
case /*DD*/0xb3: illegal_1(); /*op_b3();*/ break; // DB DD
|
|
case /*DD*/0xb4: _R++; OR(_HX); break; // OR HX
|
|
case /*DD*/0xb5: _R++; OR(_LX); break; // OR LX
|
|
case /*DD*/0xb6: _R++; EAX; OR(RM(EA)); break; // OR (IX+o)
|
|
case /*DD*/0xb7: illegal_1(); /*op_b7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xb8: illegal_1(); /*op_b8();*/ break; // DB DD
|
|
case /*DD*/0xb9: illegal_1(); /*op_b9();*/ break; // DB DD
|
|
case /*DD*/0xba: illegal_1(); /*op_ba();*/ break; // DB DD
|
|
case /*DD*/0xbb: illegal_1(); /*op_bb();*/ break; // DB DD
|
|
case /*DD*/0xbc: _R++; CP(_HX); break; // CP HX
|
|
case /*DD*/0xbd: _R++; CP(_LX); break; // CP LX
|
|
case /*DD*/0xbe: _R++; EAX; CP(RM(EA)); break; // CP (IX+o)
|
|
case /*DD*/0xbf: illegal_1(); /*op_bf();*/ break; // DB DD
|
|
|
|
case /*DD*/0xc0: illegal_1(); /*op_c0();*/ break; // DB DD
|
|
case /*DD*/0xc1: illegal_1(); /*op_c1();*/ break; // DB DD
|
|
case /*DD*/0xc2: illegal_1(); /*op_c2();*/ break; // DB DD
|
|
case /*DD*/0xc3: illegal_1(); /*op_c3();*/ break; // DB DD
|
|
case /*DD*/0xc4: illegal_1(); /*op_c4();*/ break; // DB DD
|
|
case /*DD*/0xc5: illegal_1(); /*op_c5();*/ break; // DB DD
|
|
case /*DD*/0xc6: illegal_1(); /*op_c6();*/ break; // DB DD
|
|
case /*DD*/0xc7: illegal_1(); /*op_c7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xc8: illegal_1(); /*op_c8();*/ break; // DB DD
|
|
case /*DD*/0xc9: illegal_1(); /*op_c9();*/ break; // DB DD
|
|
case /*DD*/0xca: illegal_1(); /*op_ca();*/ break; // DB DD
|
|
// pretty sure this is supposed to be ARG()
|
|
case /*DD*/0xcb: _R++; EAX; EXEC_EA(xycb,ARG(),EA); break; // ** DD CB xx
|
|
case /*DD*/0xcc: illegal_1(); /*op_cc();*/ break; // DB DD
|
|
case /*DD*/0xcd: illegal_1(); /*op_cd();*/ break; // DB DD
|
|
case /*DD*/0xce: illegal_1(); /*op_ce();*/ break; // DB DD
|
|
case /*DD*/0xcf: illegal_1(); /*op_cf();*/ break; // DB DD
|
|
|
|
case /*DD*/0xd0: illegal_1(); /*op_d0();*/ break; // DB DD
|
|
case /*DD*/0xd1: illegal_1(); /*op_d1();*/ break; // DB DD
|
|
case /*DD*/0xd2: illegal_1(); /*op_d2();*/ break; // DB DD
|
|
case /*DD*/0xd3: illegal_1(); /*op_d3();*/ break; // DB DD
|
|
case /*DD*/0xd4: illegal_1(); /*op_d4();*/ break; // DB DD
|
|
case /*DD*/0xd5: illegal_1(); /*op_d5();*/ break; // DB DD
|
|
case /*DD*/0xd6: illegal_1(); /*op_d6();*/ break; // DB DD
|
|
case /*DD*/0xd7: illegal_1(); /*op_d7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xd8: illegal_1(); /*op_d8();*/ break; // DB DD
|
|
case /*DD*/0xd9: illegal_1(); /*op_d9();*/ break; // DB DD
|
|
case /*DD*/0xda: illegal_1(); /*op_da();*/ break; // DB DD
|
|
case /*DD*/0xdb: illegal_1(); /*op_db();*/ break; // DB DD
|
|
case /*DD*/0xdc: illegal_1(); /*op_dc();*/ break; // DB DD
|
|
case /*DD*/0xdd: illegal_1(); /*op_dd();*/ break; // DB DD
|
|
case /*DD*/0xde: illegal_1(); /*op_de();*/ break; // DB DD
|
|
case /*DD*/0xdf: illegal_1(); /*op_df();*/ break; // DB DD
|
|
|
|
case /*DD*/0xe0: illegal_1(); /*op_e0();*/ break; // DB DD
|
|
case /*DD*/0xe1: _R++; _IX = POP(); break; // POP IX
|
|
case /*DD*/0xe2: illegal_1(); /*op_e2();*/ break; // DB DD
|
|
case /*DD*/0xe3: _R++; _IX = EXSP16(_IX); break; // EX (SP),IX
|
|
case /*DD*/0xe4: illegal_1(); /*op_e4();*/ break; // DB DD
|
|
case /*DD*/0xe5: _R++; PUSH( _IX ); break; // PUSH IX
|
|
case /*DD*/0xe6: illegal_1(); /*op_e6();*/ break; // DB DD
|
|
case /*DD*/0xe7: illegal_1(); /*op_e7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xe8: illegal_1(); /*op_e8();*/ break; // DB DD
|
|
case /*DD*/0xe9: _R++; _PC = _IX; break; // JP (IX)
|
|
case /*DD*/0xea: illegal_1(); /*op_ea();*/ break; // DB DD
|
|
case /*DD*/0xeb: illegal_1(); /*op_eb();*/ break; // DB DD
|
|
case /*DD*/0xec: illegal_1(); /*op_ec();*/ break; // DB DD
|
|
case /*DD*/0xed: illegal_1(); /*op_ed();*/ break; // DB DD
|
|
case /*DD*/0xee: illegal_1(); /*op_ee();*/ break; // DB DD
|
|
case /*DD*/0xef: illegal_1(); /*op_ef();*/ break; // DB DD
|
|
|
|
case /*DD*/0xf0: illegal_1(); /*op_f0();*/ break; // DB DD
|
|
case /*DD*/0xf1: illegal_1(); /*op_f1();*/ break; // DB DD
|
|
case /*DD*/0xf2: illegal_1(); /*op_f2();*/ break; // DB DD
|
|
case /*DD*/0xf3: illegal_1(); /*op_f3();*/ break; // DB DD
|
|
case /*DD*/0xf4: illegal_1(); /*op_f4();*/ break; // DB DD
|
|
case /*DD*/0xf5: illegal_1(); /*op_f5();*/ break; // DB DD
|
|
case /*DD*/0xf6: illegal_1(); /*op_f6();*/ break; // DB DD
|
|
case /*DD*/0xf7: illegal_1(); /*op_f7();*/ break; // DB DD
|
|
|
|
case /*DD*/0xf8: illegal_1(); /*op_f8();*/ break; // DB DD
|
|
case /*DD*/0xf9: _R++; _SP = _IX; break; // LD SP,IX
|
|
case /*DD*/0xfa: illegal_1(); /*op_fa();*/ break; // DB DD
|
|
case /*DD*/0xfb: illegal_1(); /*op_fb();*/ break; // DB DD
|
|
case /*DD*/0xfc: illegal_1(); /*op_fc();*/ break; // DB DD
|
|
case /*DD*/0xfd: illegal_1(); /*op_fd();*/ break; // DB DD
|
|
case /*DD*/0xfe: illegal_1(); /*op_fe();*/ break; // DB DD
|
|
case /*DD*/0xff: illegal_1(); /*op_ff();*/ break; // DB DD
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_ed(struct Z80_STATE *state, uint8 op) {
|
|
|
|
//printf("PC=%04X exec ed %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*ED*/0x00: illegal_2(); break; // DB ED
|
|
case /*ED*/0x01: illegal_2(); break; // DB ED
|
|
case /*ED*/0x02: illegal_2(); break; // DB ED
|
|
case /*ED*/0x03: illegal_2(); break; // DB ED
|
|
case /*ED*/0x04: illegal_2(); break; // DB ED
|
|
case /*ED*/0x05: illegal_2(); break; // DB ED
|
|
case /*ED*/0x06: illegal_2(); break; // DB ED
|
|
case /*ED*/0x07: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x08: illegal_2(); break; // DB ED
|
|
case /*ED*/0x09: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x0f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x10: illegal_2(); break; // DB ED
|
|
case /*ED*/0x11: illegal_2(); break; // DB ED
|
|
case /*ED*/0x12: illegal_2(); break; // DB ED
|
|
case /*ED*/0x13: illegal_2(); break; // DB ED
|
|
case /*ED*/0x14: illegal_2(); break; // DB ED
|
|
case /*ED*/0x15: illegal_2(); break; // DB ED
|
|
case /*ED*/0x16: illegal_2(); break; // DB ED
|
|
case /*ED*/0x17: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x18: illegal_2(); break; // DB ED
|
|
case /*ED*/0x19: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x1f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x20: illegal_2(); break; // DB ED
|
|
case /*ED*/0x21: illegal_2(); break; // DB ED
|
|
case /*ED*/0x22: illegal_2(); break; // DB ED
|
|
case /*ED*/0x23: illegal_2(); break; // DB ED
|
|
case /*ED*/0x24: illegal_2(); break; // DB ED
|
|
case /*ED*/0x25: illegal_2(); break; // DB ED
|
|
case /*ED*/0x26: illegal_2(); break; // DB ED
|
|
case /*ED*/0x27: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x28: illegal_2(); break; // DB ED
|
|
case /*ED*/0x29: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x2f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x30: illegal_2(); break; // DB ED
|
|
case /*ED*/0x31: illegal_2(); break; // DB ED
|
|
case /*ED*/0x32: illegal_2(); break; // DB ED
|
|
case /*ED*/0x33: illegal_2(); break; // DB ED
|
|
case /*ED*/0x34: illegal_2(); break; // DB ED
|
|
case /*ED*/0x35: illegal_2(); break; // DB ED
|
|
case /*ED*/0x36: illegal_2(); break; // DB ED
|
|
case /*ED*/0x37: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x38: illegal_2(); break; // DB ED
|
|
case /*ED*/0x39: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x3f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x40: _B = Z80IN(_BC); _F = (_F & CF) | SZP[_B]; break; // IN B,(C)
|
|
case /*ED*/0x41: Z80OUT(_BC,_B); break; // OUT (C),B
|
|
case /*ED*/0x42: SBC16( _BC ); break; // SBC HL,BC
|
|
case /*ED*/0x43: WM16( ARG16(), _BC ); break; // LD (w),BC
|
|
case /*ED*/0x44: NEG; break; // NEG
|
|
case /*ED*/0x45: RETN; break; // RETN;
|
|
case /*ED*/0x46: IM(0); break; // IM 0
|
|
case /*ED*/0x47: LD_I_A; break; // LD I,A
|
|
|
|
case /*ED*/0x48: _C = Z80IN(_BC); _F = (_F & CF) | SZP[_C]; break; // IN C,(C)
|
|
case /*ED*/0x49: Z80OUT(_BC,_C); break; // OUT (C),C
|
|
case /*ED*/0x4a: ADC16( _BC ); break; // ADC HL,BC
|
|
case /*ED*/0x4b: _BC = RM16( ARG16() ); break; // LD BC,(w)
|
|
case /*ED*/0x4c: NEG; break; // NEG
|
|
case /*ED*/0x4d: RETI; break; // RETI
|
|
case /*ED*/0x4e: IM(0); break; // IM 0
|
|
case /*ED*/0x4f: LD_R_A; break; // LD R,A
|
|
|
|
case /*ED*/0x50: _D = Z80IN(_BC); _F = (_F & CF) | SZP[_D]; break; // IN D,(C)
|
|
case /*ED*/0x51: Z80OUT(_BC,_D); break; // OUT (C),D
|
|
case /*ED*/0x52: SBC16( _DE ); break; // SBC HL,DE
|
|
case /*ED*/0x53: WM16( ARG16(), _DE ); break; // LD (w),DE
|
|
case /*ED*/0x54: NEG; break; // NEG
|
|
case /*ED*/0x55: RETN; break; // RETN;
|
|
case /*ED*/0x56: IM(1); break; // IM 1
|
|
case /*ED*/0x57: LD_A_I; break; // LD A,I
|
|
|
|
case /*ED*/0x58: _E = Z80IN(_BC); _F = (_F & CF) | SZP[_E]; break; // IN E,(C)
|
|
case /*ED*/0x59: Z80OUT(_BC,_E); break; // OUT (C),E
|
|
case /*ED*/0x5a: ADC16( _DE ); break; // ADC HL,DE
|
|
case /*ED*/0x5b: _DE = RM16( ARG16() ); break; // LD DE,(w)
|
|
case /*ED*/0x5c: NEG; break; // NEG
|
|
case /*ED*/0x5d: RETI; break; // RETI
|
|
case /*ED*/0x5e: IM(2); break; // IM 2
|
|
case /*ED*/0x5f: LD_A_R; break; // LD A,R
|
|
|
|
case /*ED*/0x60: _H = Z80IN(_BC); _F = (_F & CF) | SZP[_H]; break; // IN H,(C)
|
|
case /*ED*/0x61: Z80OUT(_BC,_H); break; // OUT (C),H
|
|
case /*ED*/0x62: SBC16( _HL ); break; // SBC HL,HL
|
|
case /*ED*/0x63: WM16( ARG16(), _HL ); break; // LD (w),HL
|
|
case /*ED*/0x64: NEG; break; // NEG
|
|
case /*ED*/0x65: RETN; break; // RETN;
|
|
case /*ED*/0x66: IM (0); break; // IM 0
|
|
case /*ED*/0x67: RRD; break; // RRD (HL)
|
|
|
|
case /*ED*/0x68: _L = Z80IN(_BC); _F = (_F & CF) | SZP[_L]; break; // IN L,(C)
|
|
case /*ED*/0x69: Z80OUT(_BC,_L); break; // OUT (C),L
|
|
case /*ED*/0x6a: ADC16( _HL ); break; // ADC HL,HL
|
|
case /*ED*/0x6b: _HL = RM16( ARG16() ); break; // LD HL,(w)
|
|
case /*ED*/0x6c: NEG; break; // NEG
|
|
case /*ED*/0x6d: RETI; break; // RETI
|
|
case /*ED*/0x6e: IM(0); break; // IM 0
|
|
case /*ED*/0x6f: RLD; break; // RLD (HL)
|
|
|
|
case /*ED*/0x70: _F = (_F & CF) | SZP[Z80IN(_BC)]; break; // IN 0,(C)
|
|
case /*ED*/0x71: Z80OUT(_BC,0); break; // OUT (C),0
|
|
case /*ED*/0x72: SBC16( _SP ); break; // SBC HL,SP
|
|
case /*ED*/0x73: WM16( ARG16(), _SP ); break; // LD (w),SP
|
|
case /*ED*/0x74: NEG; break; // NEG
|
|
case /*ED*/0x75: RETN; break; // RETN;
|
|
case /*ED*/0x76: IM(1); break; // IM 1
|
|
case /*ED*/0x77: illegal_2(); break; // DB ED,77
|
|
|
|
case /*ED*/0x78: _A = Z80IN(_BC); _F = (_F & CF) | SZP[_A]; break; // IN E,(C)
|
|
case /*ED*/0x79: Z80OUT(_BC,_A); break; // OUT (C),E
|
|
case /*ED*/0x7a: ADC16( _SP ); break; // ADC HL,SP
|
|
case /*ED*/0x7b: _SP = RM16( ARG16() ); break; // LD SP,(w)
|
|
case /*ED*/0x7c: NEG; break; // NEG
|
|
case /*ED*/0x7d: RETI; break; // RETI
|
|
case /*ED*/0x7e: IM(2); break; // IM 2
|
|
case /*ED*/0x7f: illegal_2(); break; // DB ED,7F
|
|
|
|
case /*ED*/0x80: illegal_2(); break; // DB ED
|
|
case /*ED*/0x81: illegal_2(); break; // DB ED
|
|
case /*ED*/0x82: illegal_2(); break; // DB ED
|
|
case /*ED*/0x83: illegal_2(); break; // DB ED
|
|
case /*ED*/0x84: illegal_2(); break; // DB ED
|
|
case /*ED*/0x85: illegal_2(); break; // DB ED
|
|
case /*ED*/0x86: illegal_2(); break; // DB ED
|
|
case /*ED*/0x87: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x88: illegal_2(); break; // DB ED
|
|
case /*ED*/0x89: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x8f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x90: illegal_2(); break; // DB ED
|
|
case /*ED*/0x91: illegal_2(); break; // DB ED
|
|
case /*ED*/0x92: illegal_2(); break; // DB ED
|
|
case /*ED*/0x93: illegal_2(); break; // DB ED
|
|
case /*ED*/0x94: illegal_2(); break; // DB ED
|
|
case /*ED*/0x95: illegal_2(); break; // DB ED
|
|
case /*ED*/0x96: illegal_2(); break; // DB ED
|
|
case /*ED*/0x97: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0x98: illegal_2(); break; // DB ED
|
|
case /*ED*/0x99: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9a: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9b: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9c: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9d: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9e: illegal_2(); break; // DB ED
|
|
case /*ED*/0x9f: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xa0: LDI; break; // LDI
|
|
case /*ED*/0xa1: CPI; break; // CPI
|
|
case /*ED*/0xa2: INI; break; // INI
|
|
case /*ED*/0xa3: OUTI; break; // OUTI
|
|
case /*ED*/0xa4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xa5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xa6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xa7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xa8: LDD; break; // LDD
|
|
case /*ED*/0xa9: CPD; break; // CPD
|
|
case /*ED*/0xaa: IND; break; // IND
|
|
case /*ED*/0xab: OUTD; break; // OUTD
|
|
case /*ED*/0xac: illegal_2(); break; // DB ED
|
|
case /*ED*/0xad: illegal_2(); break; // DB ED
|
|
case /*ED*/0xae: illegal_2(); break; // DB ED
|
|
case /*ED*/0xaf: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xb0: LDIR; break; // LDIR
|
|
case /*ED*/0xb1: CPIR; break; // CPIR
|
|
case /*ED*/0xb2: INIR; break; // INIR
|
|
case /*ED*/0xb3: OTIR; break; // OTIR
|
|
case /*ED*/0xb4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xb5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xb6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xb7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xb8: LDDR; break; // LDDR
|
|
case /*ED*/0xb9: CPDR; break; // CPDR
|
|
case /*ED*/0xba: INDR; break; // INDR
|
|
case /*ED*/0xbb: OTDR; break; // OTDR
|
|
case /*ED*/0xbc: illegal_2(); break; // DB ED
|
|
case /*ED*/0xbd: illegal_2(); break; // DB ED
|
|
case /*ED*/0xbe: illegal_2(); break; // DB ED
|
|
case /*ED*/0xbf: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xc0: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc1: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc2: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc3: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xc8: illegal_2(); break; // DB ED
|
|
case /*ED*/0xc9: illegal_2(); break; // DB ED
|
|
case /*ED*/0xca: illegal_2(); break; // DB ED
|
|
case /*ED*/0xcb: illegal_2(); break; // DB ED
|
|
case /*ED*/0xcc: illegal_2(); break; // DB ED
|
|
case /*ED*/0xcd: illegal_2(); break; // DB ED
|
|
case /*ED*/0xce: illegal_2(); break; // DB ED
|
|
case /*ED*/0xcf: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xd0: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd1: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd2: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd3: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xd8: illegal_2(); break; // DB ED
|
|
case /*ED*/0xd9: illegal_2(); break; // DB ED
|
|
case /*ED*/0xda: illegal_2(); break; // DB ED
|
|
case /*ED*/0xdb: illegal_2(); break; // DB ED
|
|
case /*ED*/0xdc: illegal_2(); break; // DB ED
|
|
case /*ED*/0xdd: illegal_2(); break; // DB ED
|
|
case /*ED*/0xde: illegal_2(); break; // DB ED
|
|
case /*ED*/0xdf: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xe0: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe1: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe2: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe3: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xe8: illegal_2(); break; // DB ED
|
|
case /*ED*/0xe9: illegal_2(); break; // DB ED
|
|
case /*ED*/0xea: illegal_2(); break; // DB ED
|
|
case /*ED*/0xeb: illegal_2(); break; // DB ED
|
|
case /*ED*/0xec: illegal_2(); break; // DB ED
|
|
case /*ED*/0xed: illegal_2(); break; // DB ED
|
|
case /*ED*/0xee: illegal_2(); break; // DB ED
|
|
case /*ED*/0xef: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xf0: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf1: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf2: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf3: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf4: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf5: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf6: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf7: illegal_2(); break; // DB ED
|
|
|
|
case /*ED*/0xf8: illegal_2(); break; // DB ED
|
|
case /*ED*/0xf9: illegal_2(); break; // DB ED
|
|
case /*ED*/0xfa: illegal_2(); break; // DB ED
|
|
case /*ED*/0xfb: illegal_2(); break; // DB ED
|
|
case /*ED*/0xfc: illegal_2(); break; // DB ED
|
|
case /*ED*/0xfd: illegal_2(); break; // DB ED
|
|
case /*ED*/0xfe: illegal_2(); break; // DB ED
|
|
case /*ED*/0xff: illegal_2(); break; // DB ED
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_fd(struct Z80_STATE *state, uint8 op) {
|
|
uint16 EA;
|
|
|
|
//printf("PC=%04X exec fd %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*FD*/0x00: illegal_1(); /*op_00();*/ break; // DB FD
|
|
case /*FD*/0x01: illegal_1(); /*op_01();*/ break; // DB FD
|
|
case /*FD*/0x02: illegal_1(); /*op_02();*/ break; // DB FD
|
|
case /*FD*/0x03: illegal_1(); /*op_03();*/ break; // DB FD
|
|
case /*FD*/0x04: illegal_1(); /*op_04();*/ break; // DB FD
|
|
case /*FD*/0x05: illegal_1(); /*op_05();*/ break; // DB FD
|
|
case /*FD*/0x06: illegal_1(); /*op_06();*/ break; // DB FD
|
|
case /*FD*/0x07: illegal_1(); /*op_07();*/ break; // DB FD
|
|
|
|
case /*FD*/0x08: illegal_1(); /*op_08();*/ break; // DB FD
|
|
case /*FD*/0x09: _R++; ADD16(_IY,_BC); break; // ADD IY,BC
|
|
case /*FD*/0x0a: illegal_1(); /*op_0a();*/ break; // DB FD
|
|
case /*FD*/0x0b: illegal_1(); /*op_0b();*/ break; // DB FD
|
|
case /*FD*/0x0c: illegal_1(); /*op_0c();*/ break; // DB FD
|
|
case /*FD*/0x0d: illegal_1(); /*op_0d();*/ break; // DB FD
|
|
case /*FD*/0x0e: illegal_1(); /*op_0e();*/ break; // DB FD
|
|
case /*FD*/0x0f: illegal_1(); /*op_0f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x10: illegal_1(); /*op_10();*/ break; // DB FD
|
|
case /*FD*/0x11: illegal_1(); /*op_11();*/ break; // DB FD
|
|
case /*FD*/0x12: illegal_1(); /*op_12();*/ break; // DB FD
|
|
case /*FD*/0x13: illegal_1(); /*op_13();*/ break; // DB FD
|
|
case /*FD*/0x14: illegal_1(); /*op_14();*/ break; // DB FD
|
|
case /*FD*/0x15: illegal_1(); /*op_15();*/ break; // DB FD
|
|
case /*FD*/0x16: illegal_1(); /*op_16();*/ break; // DB FD
|
|
case /*FD*/0x17: illegal_1(); /*op_17();*/ break; // DB FD
|
|
|
|
case /*FD*/0x18: illegal_1(); /*op_18();*/ break; // DB FD
|
|
case /*FD*/0x19: _R++; ADD16(_IY,_DE); break; // ADD IY,DE
|
|
case /*FD*/0x1a: illegal_1(); /*op_1a();*/ break; // DB FD
|
|
case /*FD*/0x1b: illegal_1(); /*op_1b();*/ break; // DB FD
|
|
case /*FD*/0x1c: illegal_1(); /*op_1c();*/ break; // DB FD
|
|
case /*FD*/0x1d: illegal_1(); /*op_1d();*/ break; // DB FD
|
|
case /*FD*/0x1e: illegal_1(); /*op_1e();*/ break; // DB FD
|
|
case /*FD*/0x1f: illegal_1(); /*op_1f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x20: illegal_1(); /*op_20();*/ break; // DB FD
|
|
case /*FD*/0x21: _R++; _IY = ARG16(); break; // LD IY,w
|
|
case /*FD*/0x22: _R++; WM16( ARG16(), _IY ); break; // LD (w),IY
|
|
case /*FD*/0x23: _R++; _IY++; break; // INC IY
|
|
case /*FD*/0x24: _R++; _HY = INC(_HY); break; // INC HY
|
|
case /*FD*/0x25: _R++; _HY = DEC(_HY); break; // DEC HY
|
|
case /*FD*/0x26: _R++; _HY = ARG(); break; // LD HY,n
|
|
case /*FD*/0x27: illegal_1(); /*op_27();*/ break; // DB FD
|
|
|
|
case /*FD*/0x28: illegal_1(); /*op_28();*/ break; // DB FD
|
|
case /*FD*/0x29: _R++; ADD16(_IY,_IY); break; // ADD IY,IY
|
|
case /*FD*/0x2a: _R++; _IY = RM16( ARG16() ); break; // LD IY,(w)
|
|
case /*FD*/0x2b: _R++; _IY--; break; // DEC IY
|
|
case /*FD*/0x2c: _R++; _LY = INC(_LY); break; // INC LY
|
|
case /*FD*/0x2d: _R++; _LY = DEC(_LY); break; // DEC LY
|
|
case /*FD*/0x2e: _R++; _LY = ARG(); break; // LD LY,n
|
|
case /*FD*/0x2f: illegal_1(); /*op_2f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x30: illegal_1(); /*op_30();*/ break; // DB FD
|
|
case /*FD*/0x31: illegal_1(); /*op_31();*/ break; // DB FD
|
|
case /*FD*/0x32: illegal_1(); /*op_32();*/ break; // DB FD
|
|
case /*FD*/0x33: illegal_1(); /*op_33();*/ break; // DB FD
|
|
case /*FD*/0x34: _R++; EAY; WM( EA, INC(RM(EA)) ); break; // INC (IY+o)
|
|
case /*FD*/0x35: _R++; EAY; WM( EA, DEC(RM(EA)) ); break; // DEC (IY+o)
|
|
case /*FD*/0x36: _R++; EAY; WM( EA, ARG() ); break; // LD (IY+o),n
|
|
case /*FD*/0x37: illegal_1(); /*op_37();*/ break; // DB FD
|
|
|
|
case /*FD*/0x38: illegal_1(); /*op_38();*/ break; // DB FD
|
|
case /*FD*/0x39: _R++; ADD16(_IY,_SP); break; // ADD IY,SP
|
|
case /*FD*/0x3a: illegal_1(); /*op_3a();*/ break; // DB FD
|
|
case /*FD*/0x3b: illegal_1(); /*op_3b();*/ break; // DB FD
|
|
case /*FD*/0x3c: illegal_1(); /*op_3c();*/ break; // DB FD
|
|
case /*FD*/0x3d: illegal_1(); /*op_3d();*/ break; // DB FD
|
|
case /*FD*/0x3e: illegal_1(); /*op_3e();*/ break; // DB FD
|
|
case /*FD*/0x3f: illegal_1(); /*op_3f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x40: illegal_1(); /*op_40();*/ break; // DB FD
|
|
case /*FD*/0x41: illegal_1(); /*op_41();*/ break; // DB FD
|
|
case /*FD*/0x42: illegal_1(); /*op_42();*/ break; // DB FD
|
|
case /*FD*/0x43: illegal_1(); /*op_43();*/ break; // DB FD
|
|
case /*FD*/0x44: _R++; _B = _HY; break; // LD B,HY
|
|
case /*FD*/0x45: _R++; _B = _LY; break; // LD B,LY
|
|
case /*FD*/0x46: _R++; EAY; _B = RM(EA); break; // LD B,(IY+o)
|
|
case /*FD*/0x47: illegal_1(); /*op_47();*/ break; // DB FD
|
|
|
|
case /*FD*/0x48: illegal_1(); /*op_48();*/ break; // DB FD
|
|
case /*FD*/0x49: illegal_1(); /*op_49();*/ break; // DB FD
|
|
case /*FD*/0x4a: illegal_1(); /*op_4a();*/ break; // DB FD
|
|
case /*FD*/0x4b: illegal_1(); /*op_4b();*/ break; // DB FD
|
|
case /*FD*/0x4c: _R++; _C = _HY; break; // LD C,HY
|
|
case /*FD*/0x4d: _R++; _C = _LY; break; // LD C,LY
|
|
case /*FD*/0x4e: _R++; EAY; _C = RM(EA); break; // LD C,(IY+o)
|
|
case /*FD*/0x4f: illegal_1(); /*op_4f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x50: illegal_1(); /*op_50();*/ break; // DB FD
|
|
case /*FD*/0x51: illegal_1(); /*op_51();*/ break; // DB FD
|
|
case /*FD*/0x52: illegal_1(); /*op_52();*/ break; // DB FD
|
|
case /*FD*/0x53: illegal_1(); /*op_53();*/ break; // DB FD
|
|
case /*FD*/0x54: _R++; _D = _HY; break; // LD D,HY
|
|
case /*FD*/0x55: _R++; _D = _LY; break; // LD D,LY
|
|
case /*FD*/0x56: _R++; EAY; _D = RM(EA); break; // LD D,(IY+o)
|
|
case /*FD*/0x57: illegal_1(); /*op_57();*/ break; // DB FD
|
|
|
|
case /*FD*/0x58: illegal_1(); /*op_58();*/ break; // DB FD
|
|
case /*FD*/0x59: illegal_1(); /*op_59();*/ break; // DB FD
|
|
case /*FD*/0x5a: illegal_1(); /*op_5a();*/ break; // DB FD
|
|
case /*FD*/0x5b: illegal_1(); /*op_5b();*/ break; // DB FD
|
|
case /*FD*/0x5c: _R++; _E = _HY; break; // LD E,HY
|
|
case /*FD*/0x5d: _R++; _E = _LY; break; // LD E,LY
|
|
case /*FD*/0x5e: _R++; EAY; _E = RM(EA); break; // LD E,(IY+o)
|
|
case /*FD*/0x5f: illegal_1(); /*op_5f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x60: _R++; _HY = _B; break; // LD HY,B
|
|
case /*FD*/0x61: _R++; _HY = _C; break; // LD HY,C
|
|
case /*FD*/0x62: _R++; _HY = _D; break; // LD HY,D
|
|
case /*FD*/0x63: _R++; _HY = _E; break; // LD HY,E
|
|
case /*FD*/0x64: _R++; break; // LD HY,HY
|
|
case /*FD*/0x65: _R++; _HY = _LY; break; // LD HY,LY
|
|
case /*FD*/0x66: _R++; EAY; _H = RM(EA); break; // LD H,(IY+o)
|
|
case /*FD*/0x67: _R++; _HY = _A; break; // LD HY,A
|
|
|
|
case /*FD*/0x68: _R++; _LY = _B; break; // LD LY,B
|
|
case /*FD*/0x69: _R++; _LY = _C; break; // LD LY,C
|
|
case /*FD*/0x6a: _R++; _LY = _D; break; // LD LY,D
|
|
case /*FD*/0x6b: _R++; _LY = _E; break; // LD LY,E
|
|
case /*FD*/0x6c: _R++; _LY = _HY; break; // LD LY,HY
|
|
case /*FD*/0x6d: _R++; break; // LD LY,LY
|
|
case /*FD*/0x6e: _R++; EAY; _L = RM(EA); break; // LD L,(IY+o)
|
|
case /*FD*/0x6f: _R++; _LY = _A; break; // LD LY,A
|
|
|
|
case /*FD*/0x70: _R++; EAY; WM( EA, _B ); break; // LD (IY+o),B
|
|
case /*FD*/0x71: _R++; EAY; WM( EA, _C ); break; // LD (IY+o),C
|
|
case /*FD*/0x72: _R++; EAY; WM( EA, _D ); break; // LD (IY+o),D
|
|
case /*FD*/0x73: _R++; EAY; WM( EA, _E ); break; // LD (IY+o),E
|
|
case /*FD*/0x74: _R++; EAY; WM( EA, _H ); break; // LD (IY+o),H
|
|
case /*FD*/0x75: _R++; EAY; WM( EA, _L ); break; // LD (IY+o),L
|
|
case /*FD*/0x76: illegal_1(); /*op_76();*/ break; // DB FD
|
|
case /*FD*/0x77: _R++; EAY; WM( EA, _A ); break; // LD (IY+o),A
|
|
|
|
case /*FD*/0x78: illegal_1(); /*op_78();*/ break; // DB FD
|
|
case /*FD*/0x79: illegal_1(); /*op_79();*/ break; // DB FD
|
|
case /*FD*/0x7a: illegal_1(); /*op_7a();*/ break; // DB FD
|
|
case /*FD*/0x7b: illegal_1(); /*op_7b();*/ break; // DB FD
|
|
case /*FD*/0x7c: _R++; _A = _HY; break; // LD A,HY
|
|
case /*FD*/0x7d: _R++; _A = _LY; break; // LD A,LY
|
|
case /*FD*/0x7e: _R++; EAY; _A = RM(EA); break; // LD A,(IY+o)
|
|
case /*FD*/0x7f: illegal_1(); /*op_7f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x80: illegal_1(); /*op_80();*/ break; // DB FD
|
|
case /*FD*/0x81: illegal_1(); /*op_81();*/ break; // DB FD
|
|
case /*FD*/0x82: illegal_1(); /*op_82();*/ break; // DB FD
|
|
case /*FD*/0x83: illegal_1(); /*op_83();*/ break; // DB FD
|
|
case /*FD*/0x84: _R++; ADD(_HY); break; // ADD A,HY
|
|
case /*FD*/0x85: _R++; ADD(_LY); break; // ADD A,LY
|
|
case /*FD*/0x86: _R++; EAY; ADD(RM(EA)); break; // ADD A,(IY+o)
|
|
case /*FD*/0x87: illegal_1(); /*op_87();*/ break; // DB FD
|
|
|
|
case /*FD*/0x88: illegal_1(); /*op_88();*/ break; // DB FD
|
|
case /*FD*/0x89: illegal_1(); /*op_89();*/ break; // DB FD
|
|
case /*FD*/0x8a: illegal_1(); /*op_8a();*/ break; // DB FD
|
|
case /*FD*/0x8b: illegal_1(); /*op_8b();*/ break; // DB FD
|
|
case /*FD*/0x8c: _R++; ADC(_HY); break; // ADC A,HY
|
|
case /*FD*/0x8d: _R++; ADC(_LY); break; // ADC A,LY
|
|
case /*FD*/0x8e: _R++; EAY; ADC(RM(EA)); break; // ADC A,(IY+o)
|
|
case /*FD*/0x8f: illegal_1(); /*op_8f();*/ break; // DB FD
|
|
|
|
case /*FD*/0x90: illegal_1(); /*op_90();*/ break; // DB FD
|
|
case /*FD*/0x91: illegal_1(); /*op_91();*/ break; // DB FD
|
|
case /*FD*/0x92: illegal_1(); /*op_92();*/ break; // DB FD
|
|
case /*FD*/0x93: illegal_1(); /*op_93();*/ break; // DB FD
|
|
case /*FD*/0x94: _R++; SUB(_HY); break; // SUB HY
|
|
case /*FD*/0x95: _R++; SUB(_LY); break; // SUB LY
|
|
case /*FD*/0x96: _R++; EAY; SUB(RM(EA)); break; // SUB (IY+o)
|
|
case /*FD*/0x97: illegal_1(); /*op_97();*/ break; // DB FD
|
|
|
|
case /*FD*/0x98: illegal_1(); /*op_98();*/ break; // DB FD
|
|
case /*FD*/0x99: illegal_1(); /*op_99();*/ break; // DB FD
|
|
case /*FD*/0x9a: illegal_1(); /*op_9a();*/ break; // DB FD
|
|
case /*FD*/0x9b: illegal_1(); /*op_9b();*/ break; // DB FD
|
|
case /*FD*/0x9c: _R++; SBC(_HY); break; // SBC A,HY
|
|
case /*FD*/0x9d: _R++; SBC(_LY); break; // SBC A,LY
|
|
case /*FD*/0x9e: _R++; EAY; SBC(RM(EA)); break; // SBC A,(IY+o)
|
|
case /*FD*/0x9f: illegal_1(); /*op_9f();*/ break; // DB FD
|
|
|
|
case /*FD*/0xa0: illegal_1(); /*op_a0();*/ break; // DB FD
|
|
case /*FD*/0xa1: illegal_1(); /*op_a1();*/ break; // DB FD
|
|
case /*FD*/0xa2: illegal_1(); /*op_a2();*/ break; // DB FD
|
|
case /*FD*/0xa3: illegal_1(); /*op_a3();*/ break; // DB FD
|
|
case /*FD*/0xa4: _R++; AND(_HY); break; // AND HY
|
|
case /*FD*/0xa5: _R++; AND(_LY); break; // AND LY
|
|
case /*FD*/0xa6: _R++; EAY; AND(RM(EA)); break; // AND (IY+o)
|
|
case /*FD*/0xa7: illegal_1(); /*op_a7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xa8: illegal_1(); /*op_a8();*/ break; // DB FD
|
|
case /*FD*/0xa9: illegal_1(); /*op_a9();*/ break; // DB FD
|
|
case /*FD*/0xaa: illegal_1(); /*op_aa();*/ break; // DB FD
|
|
case /*FD*/0xab: illegal_1(); /*op_ab();*/ break; // DB FD
|
|
case /*FD*/0xac: _R++; XOR(_HY); break; // XOR HY
|
|
case /*FD*/0xad: _R++; XOR(_LY); break; // XOR LY
|
|
case /*FD*/0xae: _R++; EAY; XOR(RM(EA)); break; // XOR (IY+o)
|
|
case /*FD*/0xaf: illegal_1(); /*op_af();*/ break; // DB FD
|
|
|
|
case /*FD*/0xb0: illegal_1(); /*op_b0();*/ break; // DB FD
|
|
case /*FD*/0xb1: illegal_1(); /*op_b1();*/ break; // DB FD
|
|
case /*FD*/0xb2: illegal_1(); /*op_b2();*/ break; // DB FD
|
|
case /*FD*/0xb3: illegal_1(); /*op_b3();*/ break; // DB FD
|
|
case /*FD*/0xb4: _R++; OR(_HY); break; // OR HY
|
|
case /*FD*/0xb5: _R++; OR(_LY); break; // OR LY
|
|
case /*FD*/0xb6: _R++; EAY; OR(RM(EA)); break; // OR (IY+o)
|
|
case /*FD*/0xb7: illegal_1(); /*op_b7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xb8: illegal_1(); /*op_b8();*/ break; // DB FD
|
|
case /*FD*/0xb9: illegal_1(); /*op_b9();*/ break; // DB FD
|
|
case /*FD*/0xba: illegal_1(); /*op_ba();*/ break; // DB FD
|
|
case /*FD*/0xbb: illegal_1(); /*op_bb();*/ break; // DB FD
|
|
case /*FD*/0xbc: _R++; CP(_HY); break; // CP HY
|
|
case /*FD*/0xbd: _R++; CP(_LY); break; // CP LY
|
|
case /*FD*/0xbe: _R++; EAY; CP(RM(EA)); break; // CP (IY+o)
|
|
case /*FD*/0xbf: illegal_1(); /*op_bf();*/ break; // DB FD
|
|
|
|
case /*FD*/0xc0: illegal_1(); /*op_c0();*/ break; // DB FD
|
|
case /*FD*/0xc1: illegal_1(); /*op_c1();*/ break; // DB FD
|
|
case /*FD*/0xc2: illegal_1(); /*op_c2();*/ break; // DB FD
|
|
case /*FD*/0xc3: illegal_1(); /*op_c3();*/ break; // DB FD
|
|
case /*FD*/0xc4: illegal_1(); /*op_c4();*/ break; // DB FD
|
|
case /*FD*/0xc5: illegal_1(); /*op_c5();*/ break; // DB FD
|
|
case /*FD*/0xc6: illegal_1(); /*op_c6();*/ break; // DB FD
|
|
case /*FD*/0xc7: illegal_1(); /*op_c7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xc8: illegal_1(); /*op_c8();*/ break; // DB FD
|
|
case /*FD*/0xc9: illegal_1(); /*op_c9();*/ break; // DB FD
|
|
case /*FD*/0xca: illegal_1(); /*op_ca();*/ break; // DB FD
|
|
// pretty sure this is supposed to be ARG
|
|
case /*FD*/0xcb: _R++; EAY; EXEC_EA(xycb,ARG(),EA); break; // ** FD CB xx
|
|
case /*FD*/0xcc: illegal_1(); /*op_cc();*/ break; // DB FD
|
|
case /*FD*/0xcd: illegal_1(); /*op_cd();*/ break; // DB FD
|
|
case /*FD*/0xce: illegal_1(); /*op_ce();*/ break; // DB FD
|
|
case /*FD*/0xcf: illegal_1(); /*op_cf();*/ break; // DB FD
|
|
|
|
case /*FD*/0xd0: illegal_1(); /*op_d0();*/ break; // DB FD
|
|
case /*FD*/0xd1: illegal_1(); /*op_d1();*/ break; // DB FD
|
|
case /*FD*/0xd2: illegal_1(); /*op_d2();*/ break; // DB FD
|
|
case /*FD*/0xd3: illegal_1(); /*op_d3();*/ break; // DB FD
|
|
case /*FD*/0xd4: illegal_1(); /*op_d4();*/ break; // DB FD
|
|
case /*FD*/0xd5: illegal_1(); /*op_d5();*/ break; // DB FD
|
|
case /*FD*/0xd6: illegal_1(); /*op_d6();*/ break; // DB FD
|
|
case /*FD*/0xd7: illegal_1(); /*op_d7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xd8: illegal_1(); /*op_d8();*/ break; // DB FD
|
|
case /*FD*/0xd9: illegal_1(); /*op_d9();*/ break; // DB FD
|
|
case /*FD*/0xda: illegal_1(); /*op_da();*/ break; // DB FD
|
|
case /*FD*/0xdb: illegal_1(); /*op_db();*/ break; // DB FD
|
|
case /*FD*/0xdc: illegal_1(); /*op_dc();*/ break; // DB FD
|
|
case /*FD*/0xdd: illegal_1(); /*op_dd();*/ break; // DB FD
|
|
case /*FD*/0xde: illegal_1(); /*op_de();*/ break; // DB FD
|
|
case /*FD*/0xdf: illegal_1(); /*op_df();*/ break; // DB FD
|
|
|
|
case /*FD*/0xe0: illegal_1(); /*op_e0();*/ break; // DB FD
|
|
case /*FD*/0xe1: _R++; _IY = POP(); break; // POP IY
|
|
case /*FD*/0xe2: illegal_1(); /*op_e2();*/ break; // DB FD
|
|
case /*FD*/0xe3: _R++; _IY = EXSP16(_IY); break; // EX (SP),IY
|
|
case /*FD*/0xe4: illegal_1(); /*op_e4();*/ break; // DB FD
|
|
case /*FD*/0xe5: _R++; PUSH( _IY ); break; // PUSH IY
|
|
case /*FD*/0xe6: illegal_1(); /*op_e6();*/ break; // DB FD
|
|
case /*FD*/0xe7: illegal_1(); /*op_e7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xe8: illegal_1(); /*op_e8();*/ break; // DB FD
|
|
case /*FD*/0xe9: _R++; _PC = _IY; break; // JP (IY)
|
|
case /*FD*/0xea: illegal_1(); /*op_ea();*/ break; // DB FD
|
|
case /*FD*/0xeb: illegal_1(); /*op_eb();*/ break; // DB FD
|
|
case /*FD*/0xec: illegal_1(); /*op_ec();*/ break; // DB FD
|
|
case /*FD*/0xed: illegal_1(); /*op_ed();*/ break; // DB FD
|
|
case /*FD*/0xee: illegal_1(); /*op_ee();*/ break; // DB FD
|
|
case /*FD*/0xef: illegal_1(); /*op_ef();*/ break; // DB FD
|
|
|
|
case /*FD*/0xf0: illegal_1(); /*op_f0();*/ break; // DB FD
|
|
case /*FD*/0xf1: illegal_1(); /*op_f1();*/ break; // DB FD
|
|
case /*FD*/0xf2: illegal_1(); /*op_f2();*/ break; // DB FD
|
|
case /*FD*/0xf3: illegal_1(); /*op_f3();*/ break; // DB FD
|
|
case /*FD*/0xf4: illegal_1(); /*op_f4();*/ break; // DB FD
|
|
case /*FD*/0xf5: illegal_1(); /*op_f5();*/ break; // DB FD
|
|
case /*FD*/0xf6: illegal_1(); /*op_f6();*/ break; // DB FD
|
|
case /*FD*/0xf7: illegal_1(); /*op_f7();*/ break; // DB FD
|
|
|
|
case /*FD*/0xf8: illegal_1(); /*op_f8();*/ break; // DB FD
|
|
case /*FD*/0xf9: _R++; _SP = _IY; break; // LD SP,IY
|
|
case /*FD*/0xfa: illegal_1(); /*op_fa();*/ break; // DB FD
|
|
case /*FD*/0xfb: illegal_1(); /*op_fb();*/ break; // DB FD
|
|
case /*FD*/0xfc: illegal_1(); /*op_fc();*/ break; // DB FD
|
|
case /*FD*/0xfd: illegal_1(); /*op_fd();*/ break; // DB FD
|
|
case /*FD*/0xfe: illegal_1(); /*op_fe();*/ break; // DB FD
|
|
case /*FD*/0xff: illegal_1(); /*op_ff();*/ break; // DB FD
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static EMU_INLINE void z80_exec_normal(struct Z80_STATE *state, uint8 op) {
|
|
|
|
//printf("PC=%04X exec normal %02X\n",_PC, op);fflush(stdout);
|
|
|
|
switch(op) {
|
|
case /*op*/0x00: break; // NOP
|
|
case /*op*/0x01: _BC = ARG16(); break; // LD BC,w
|
|
case /*op*/0x02: WM(_BC, _A); break; // LD (BC),A
|
|
case /*op*/0x03: _BC++; break; // INC BC
|
|
case /*op*/0x04: _B = INC(_B); break; // INC B
|
|
case /*op*/0x05: _B = DEC(_B); break; // DEC B
|
|
case /*op*/0x06: _B = ARG(); break; // LD B,n
|
|
case /*op*/0x07: RLCA; break; // RLCA
|
|
|
|
case /*op*/0x08: EX_AF; break; // EX AF,AF'
|
|
case /*op*/0x09: ADD16(_HL,_BC); break; // ADD HL,BC
|
|
case /*op*/0x0A: _A = RM(_BC); break; // LD A,(BC)
|
|
case /*op*/0x0B: _BC--; break; // DEC BC
|
|
case /*op*/0x0C: _C = INC(_C); break; // INC C
|
|
case /*op*/0x0D: _C = DEC(_C); break; // DEC C
|
|
case /*op*/0x0E: _C = ARG(); break; // LD C,n
|
|
case /*op*/0x0F: RRCA; break; // RRCA
|
|
|
|
case /*op*/0x10: _B--; JR_COND( _B, 0x10 ); break; // DJNZ o
|
|
case /*op*/0x11: _DE = ARG16(); break; // LD DE,w
|
|
case /*op*/0x12: WM( _DE, _A ); break; // LD (DE),A
|
|
case /*op*/0x13: _DE++; break; // INC DE
|
|
case /*op*/0x14: _D = INC(_D); break; // INC D
|
|
case /*op*/0x15: _D = DEC(_D); break; // DEC D
|
|
case /*op*/0x16: _D = ARG(); break; // LD D,n
|
|
case /*op*/0x17: RLA; break; // RLA
|
|
|
|
case /*op*/0x18: JR; break; // JR o
|
|
case /*op*/0x19: ADD16(_HL,_DE); break; // ADD HL,DE
|
|
case /*op*/0x1A: _A = RM(_DE); break; // LD A,(DE)
|
|
case /*op*/0x1B: _DE--; break; // DEC DE
|
|
case /*op*/0x1C: _E = INC(_E); break; // INC E
|
|
case /*op*/0x1D: _E = DEC(_E); break; // DEC E
|
|
case /*op*/0x1E: _E = ARG(); break; // LD E,n
|
|
case /*op*/0x1F: RRA; break; // RRA
|
|
|
|
case /*op*/0x20: JR_COND( !(_F & ZF), 0x20 ); break; // JR NZ,o
|
|
case /*op*/0x21: _HL = ARG16(); break; // LD HL,w
|
|
case /*op*/0x22: WM16( ARG16(), _HL ); break; // LD (w),HL
|
|
case /*op*/0x23: _HL++; break; // INC HL
|
|
case /*op*/0x24: _H = INC(_H); break; // INC H
|
|
case /*op*/0x25: _H = DEC(_H); break; // DEC H
|
|
case /*op*/0x26: _H = ARG(); break; // LD H,n
|
|
case /*op*/0x27: DAA; break; // DAA
|
|
|
|
case /*op*/0x28: JR_COND( _F & ZF, 0x28 ); break; // JR Z,o
|
|
case /*op*/0x29: ADD16(_HL,_HL); break; // ADD HL,HL
|
|
case /*op*/0x2A: _HL = RM16( ARG16() ); break; // LD HL,(w)
|
|
case /*op*/0x2B: _HL--; break; // DEC HL
|
|
case /*op*/0x2C: _L = INC(_L); break; // INC L
|
|
case /*op*/0x2D: _L = DEC(_L); break; // DEC L
|
|
case /*op*/0x2E: _L = ARG(); break; // LD L,n
|
|
case /*op*/0x2F: _A ^= 0xff; _F = (_F&(SF|ZF|PF|CF))|HF|NF|(_A&(YF|XF)); break; // CPL
|
|
|
|
case /*op*/0x30: JR_COND( !(_F & CF), 0x30 ); break; // JR NC,o
|
|
case /*op*/0x31: _SP = ARG16(); break; // LD SP,w
|
|
case /*op*/0x32: WM( ARG16(), _A ); break; // LD (w),A
|
|
case /*op*/0x33: _SP++; break; // INC SP
|
|
case /*op*/0x34: WM( _HL, INC(RM(_HL)) ); break; // INC (HL)
|
|
case /*op*/0x35: WM( _HL, DEC(RM(_HL)) ); break; // DEC (HL)
|
|
case /*op*/0x36: WM( _HL, ARG() ); break; // LD (HL),n
|
|
case /*op*/0x37: _F = (_F & (SF|ZF|PF)) | CF | (_A & (YF|XF)); break; // SCF
|
|
|
|
case /*op*/0x38: JR_COND( _F & CF, 0x38 ); break; // JR C,o
|
|
case /*op*/0x39: ADD16(_HL,_SP); break; // ADD HL,SP
|
|
case /*op*/0x3A: _A = RM( ARG16() ); break; // LD A,(w)
|
|
case /*op*/0x3B: _SP--; break; // DEC SP
|
|
case /*op*/0x3C: _A = INC(_A); break; // INC A
|
|
case /*op*/0x3D: _A = DEC(_A); break; // DEC A
|
|
case /*op*/0x3E: _A = ARG(); break; // LD A,n
|
|
case /*op*/0x3F: _F = ((_F&(SF|ZF|PF|CF))|((_F&CF)<<4)|(_A&(YF|XF)))^CF; break; // CCF
|
|
|
|
case /*op*/0x40: break; // LD B,B
|
|
case /*op*/0x41: _B = _C; break; // LD B,C
|
|
case /*op*/0x42: _B = _D; break; // LD B,D
|
|
case /*op*/0x43: _B = _E; break; // LD B,E
|
|
case /*op*/0x44: _B = _H; break; // LD B,H
|
|
case /*op*/0x45: _B = _L; break; // LD B,L
|
|
case /*op*/0x46: _B = RM(_HL); break; // LD B,(HL)
|
|
case /*op*/0x47: _B = _A; break; // LD B,A
|
|
|
|
case /*op*/0x48: _C = _B; break; // LD C,B
|
|
case /*op*/0x49: break; // LD C,C
|
|
case /*op*/0x4A: _C = _D; break; // LD C,D
|
|
case /*op*/0x4B: _C = _E; break; // LD C,E
|
|
case /*op*/0x4C: _C = _H; break; // LD C,H
|
|
case /*op*/0x4D: _C = _L; break; // LD C,L
|
|
case /*op*/0x4E: _C = RM(_HL); break; // LD C,(HL)
|
|
case /*op*/0x4F: _C = _A; break; // LD C,A
|
|
|
|
case /*op*/0x50: _D = _B; break; // LD D,B
|
|
case /*op*/0x51: _D = _C; break; // LD D,C
|
|
case /*op*/0x52: break; // LD D,D
|
|
case /*op*/0x53: _D = _E; break; // LD D,E
|
|
case /*op*/0x54: _D = _H; break; // LD D,H
|
|
case /*op*/0x55: _D = _L; break; // LD D,L
|
|
case /*op*/0x56: _D = RM(_HL); break; // LD D,(HL)
|
|
case /*op*/0x57: _D = _A; break; // LD D,A
|
|
|
|
case /*op*/0x58: _E = _B; break; // LD E,B
|
|
case /*op*/0x59: _E = _C; break; // LD E,C
|
|
case /*op*/0x5A: _E = _D; break; // LD E,D
|
|
case /*op*/0x5B: break; // LD E,E
|
|
case /*op*/0x5C: _E = _H; break; // LD E,H
|
|
case /*op*/0x5D: _E = _L; break; // LD E,L
|
|
case /*op*/0x5E: _E = RM(_HL); break; // LD E,(HL)
|
|
case /*op*/0x5F: _E = _A; break; // LD E,A
|
|
|
|
case /*op*/0x60: _H = _B; break; // LD H,B
|
|
case /*op*/0x61: _H = _C; break; // LD H,C
|
|
case /*op*/0x62: _H = _D; break; // LD H,D
|
|
case /*op*/0x63: _H = _E; break; // LD H,E
|
|
case /*op*/0x64: break; // LD H,H
|
|
case /*op*/0x65: _H = _L; break; // LD H,L
|
|
case /*op*/0x66: _H = RM(_HL); break; // LD H,(HL)
|
|
case /*op*/0x67: _H = _A; break; // LD H,A
|
|
|
|
case /*op*/0x68: _L = _B; break; // LD L,B
|
|
case /*op*/0x69: _L = _C; break; // LD L,C
|
|
case /*op*/0x6A: _L = _D; break; // LD L,D
|
|
case /*op*/0x6B: _L = _E; break; // LD L,E
|
|
case /*op*/0x6C: _L = _H; break; // LD L,H
|
|
case /*op*/0x6D: break; // LD L,L
|
|
case /*op*/0x6E: _L = RM(_HL); break; // LD L,(HL)
|
|
case /*op*/0x6F: _L = _A; break; // LD L,A
|
|
|
|
case /*op*/0x70: WM( _HL, _B ); break; // LD (HL),B
|
|
case /*op*/0x71: WM( _HL, _C ); break; // LD (HL),C
|
|
case /*op*/0x72: WM( _HL, _D ); break; // LD (HL),D
|
|
case /*op*/0x73: WM( _HL, _E ); break; // LD (HL),E
|
|
case /*op*/0x74: WM( _HL, _H ); break; // LD (HL),H
|
|
case /*op*/0x75: WM( _HL, _L ); break; // LD (HL),L
|
|
case /*op*/0x76: HALT; break; // HALT
|
|
case /*op*/0x77: WM( _HL, _A ); break; // LD (HL),A
|
|
|
|
case /*op*/0x78: _A = _B; break; // LD A,B
|
|
case /*op*/0x79: _A = _C; break; // LD A,C
|
|
case /*op*/0x7A: _A = _D; break; // LD A,D
|
|
case /*op*/0x7B: _A = _E; break; // LD A,E
|
|
case /*op*/0x7C: _A = _H; break; // LD A,H
|
|
case /*op*/0x7D: _A = _L; break; // LD A,L
|
|
case /*op*/0x7E: _A = RM(_HL); break; // LD A,(HL)
|
|
case /*op*/0x7F: break; // LD A,A
|
|
|
|
case /*op*/0x80: ADD(_B); break; // ADD A,B
|
|
case /*op*/0x81: ADD(_C); break; // ADD A,C
|
|
case /*op*/0x82: ADD(_D); break; // ADD A,D
|
|
case /*op*/0x83: ADD(_E); break; // ADD A,E
|
|
case /*op*/0x84: ADD(_H); break; // ADD A,H
|
|
case /*op*/0x85: ADD(_L); break; // ADD A,L
|
|
case /*op*/0x86: ADD(RM(_HL)); break; // ADD A,(HL)
|
|
case /*op*/0x87: ADD(_A); break; // ADD A,A
|
|
|
|
case /*op*/0x88: ADC(_B); break; // ADC A,B
|
|
case /*op*/0x89: ADC(_C); break; // ADC A,C
|
|
case /*op*/0x8A: ADC(_D); break; // ADC A,D
|
|
case /*op*/0x8B: ADC(_E); break; // ADC A,E
|
|
case /*op*/0x8C: ADC(_H); break; // ADC A,H
|
|
case /*op*/0x8D: ADC(_L); break; // ADC A,L
|
|
case /*op*/0x8E: ADC(RM(_HL)); break; // ADC A,(HL)
|
|
case /*op*/0x8F: ADC(_A); break; // ADC A,A
|
|
|
|
case /*op*/0x90: SUB(_B); break; // SUB B
|
|
case /*op*/0x91: SUB(_C); break; // SUB C
|
|
case /*op*/0x92: SUB(_D); break; // SUB D
|
|
case /*op*/0x93: SUB(_E); break; // SUB E
|
|
case /*op*/0x94: SUB(_H); break; // SUB H
|
|
case /*op*/0x95: SUB(_L); break; // SUB L
|
|
case /*op*/0x96: SUB(RM(_HL)); break; // SUB (HL)
|
|
case /*op*/0x97: SUB(_A); break; // SUB A
|
|
|
|
case /*op*/0x98: SBC(_B); break; // SBC A,B
|
|
case /*op*/0x99: SBC(_C); break; // SBC A,C
|
|
case /*op*/0x9A: SBC(_D); break; // SBC A,D
|
|
case /*op*/0x9B: SBC(_E); break; // SBC A,E
|
|
case /*op*/0x9C: SBC(_H); break; // SBC A,H
|
|
case /*op*/0x9D: SBC(_L); break; // SBC A,L
|
|
case /*op*/0x9E: SBC(RM(_HL)); break; // SBC A,(HL)
|
|
case /*op*/0x9F: SBC(_A); break; // SBC A,A
|
|
|
|
case /*op*/0xA0: AND(_B); break; // AND B
|
|
case /*op*/0xA1: AND(_C); break; // AND C
|
|
case /*op*/0xA2: AND(_D); break; // AND D
|
|
case /*op*/0xA3: AND(_E); break; // AND E
|
|
case /*op*/0xA4: AND(_H); break; // AND H
|
|
case /*op*/0xA5: AND(_L); break; // AND L
|
|
case /*op*/0xA6: AND(RM(_HL)); break; // AND (HL)
|
|
case /*op*/0xA7: AND(_A); break; // AND A
|
|
|
|
case /*op*/0xA8: XOR(_B); break; // XOR B
|
|
case /*op*/0xA9: XOR(_C); break; // XOR C
|
|
case /*op*/0xAA: XOR(_D); break; // XOR D
|
|
case /*op*/0xAB: XOR(_E); break; // XOR E
|
|
case /*op*/0xAC: XOR(_H); break; // XOR H
|
|
case /*op*/0xAD: XOR(_L); break; // XOR L
|
|
case /*op*/0xAE: XOR(RM(_HL)); break; // XOR (HL)
|
|
case /*op*/0xAF: XOR(_A); break; // XOR A
|
|
|
|
case /*op*/0xB0: OR(_B); break; // OR B
|
|
case /*op*/0xB1: OR(_C); break; // OR C
|
|
case /*op*/0xB2: OR(_D); break; // OR D
|
|
case /*op*/0xB3: OR(_E); break; // OR E
|
|
case /*op*/0xB4: OR(_H); break; // OR H
|
|
case /*op*/0xB5: OR(_L); break; // OR L
|
|
case /*op*/0xB6: OR(RM(_HL)); break; // OR (HL)
|
|
case /*op*/0xB7: OR(_A); break; // OR A
|
|
|
|
case /*op*/0xB8: CP(_B); break; // CP B
|
|
case /*op*/0xB9: CP(_C); break; // CP C
|
|
case /*op*/0xBA: CP(_D); break; // CP D
|
|
case /*op*/0xBB: CP(_E); break; // CP E
|
|
case /*op*/0xBC: CP(_H); break; // CP H
|
|
case /*op*/0xBD: CP(_L); break; // CP L
|
|
case /*op*/0xBE: CP(RM(_HL)); break; // CP (HL)
|
|
case /*op*/0xBF: CP(_A); break; // CP A
|
|
|
|
case /*op*/0xC0: RET_COND( !(_F & ZF), 0xc0 ); break; // RET NZ
|
|
case /*op*/0xC1: _BC = POP(); break; // POP BC
|
|
case /*op*/0xC2: JP_COND( !(_F & ZF) ); break; // JP NZ,a
|
|
case /*op*/0xC3: JP; break; // JP a
|
|
case /*op*/0xC4: CALL_COND( !(_F & ZF), 0xc4 ); break; // CALL NZ,a
|
|
case /*op*/0xC5: PUSH( _BC ); break; // PUSH BC
|
|
case /*op*/0xC6: ADD(ARG()); break; // ADD A,n
|
|
case /*op*/0xC7: RST(0x00); break; // RST 0
|
|
|
|
case /*op*/0xC8: RET_COND( _F & ZF, 0xc8 ); break; // RET Z
|
|
case /*op*/0xC9: _PC = POP(); break; // RET
|
|
case /*op*/0xCA: JP_COND( _F & ZF ); break; // JP Z,a
|
|
case /*op*/0xCB: _R++; EXEC(cb,ROP()); break; // **** CB xx
|
|
case /*op*/0xCC: CALL_COND( _F & ZF, 0xcc ); break; // CALL Z,a
|
|
case /*op*/0xCD: CALL; break; // CALL a
|
|
case /*op*/0xCE: ADC(ARG()); break; // ADC A,n
|
|
case /*op*/0xCF: RST(0x08); break; // RST 1
|
|
|
|
case /*op*/0xD0: RET_COND( !(_F & CF), 0xd0 ); break; // RET NC
|
|
case /*op*/0xD1: _DE = POP(); break; // POP DE
|
|
case /*op*/0xD2: JP_COND( !(_F & CF) ); break; // JP NC,a
|
|
case /*op*/0xD3: Z80OUT( ARG() | (_A << 8), _A ); break; // OUT (n),A
|
|
case /*op*/0xD4: CALL_COND( !(_F & CF), 0xd4 ); break; // CALL NC,a
|
|
case /*op*/0xD5: PUSH( _DE ); break; // PUSH DE
|
|
case /*op*/0xD6: SUB(ARG()); break; // SUB n
|
|
case /*op*/0xD7: RST(0x10); break; // RST 2
|
|
|
|
case /*op*/0xD8: RET_COND( _F & CF, 0xd8 ); break; // RET C
|
|
case /*op*/0xD9: EXX; break; // EXX
|
|
case /*op*/0xDA: JP_COND( _F & CF ); break; // JP C,a
|
|
case /*op*/0xDB: _A = Z80IN( ARG() | (_A << 8) ); break; // IN A,(n)
|
|
case /*op*/0xDC: CALL_COND( _F & CF, 0xdc ); break; // CALL C,a
|
|
case /*op*/0xDD: _R++; EXEC(dd,ROP()); break; // **** DD xx
|
|
case /*op*/0xDE: SBC(ARG()); break; // SBC A,n
|
|
case /*op*/0xDF: RST(0x18); break; // RST 3
|
|
|
|
case /*op*/0xE0: RET_COND( !(_F & PF), 0xe0 ); break; // RET PO
|
|
case /*op*/0xE1: _HL = POP(); break; // POP HL
|
|
case /*op*/0xE2: JP_COND( !(_F & PF) ); break; // JP PO,a
|
|
case /*op*/0xE3: _HL = EXSP16(_HL); break; // EX HL,(SP)
|
|
case /*op*/0xE4: CALL_COND( !(_F & PF), 0xe4 ); break; // CALL PO,a
|
|
case /*op*/0xE5: PUSH( _HL ); break; // PUSH HL
|
|
case /*op*/0xE6: AND(ARG()); break; // AND n
|
|
case /*op*/0xE7: RST(0x20); break; // RST 4
|
|
|
|
case /*op*/0xE8: RET_COND( _F & PF, 0xe8 ); break; // RET PE
|
|
case /*op*/0xE9: _PC = _HL; break; // JP (HL)
|
|
case /*op*/0xEA: JP_COND( _F & PF ); break; // JP PE,a
|
|
case /*op*/0xEB: EX_DE_HL; break; // EX DE,HL
|
|
case /*op*/0xEC: CALL_COND( _F & PF, 0xec ); break; // CALL PE,a
|
|
case /*op*/0xED: _R++; EXEC(ed,ROP()); break; // **** ED xx
|
|
case /*op*/0xEE: XOR(ARG()); break; // XOR n
|
|
case /*op*/0xEF: RST(0x28); break; // RST 5
|
|
|
|
case /*op*/0xF0: RET_COND( !(_F & SF), 0xf0 ); break; // RET P
|
|
case /*op*/0xF1: _AF = POP(); break; // POP AF
|
|
case /*op*/0xF2: JP_COND( !(_F & SF) ); break; // JP P,a
|
|
case /*op*/0xF3: DI; break; // DI
|
|
case /*op*/0xF4: CALL_COND( !(_F & SF), 0xf4 ); break; // CALL P,a
|
|
case /*op*/0xF5: PUSH( _AF ); break; // PUSH AF
|
|
case /*op*/0xF6: OR(ARG()); break; // OR n
|
|
case /*op*/0xF7: RST(0x30); break; // RST 6
|
|
|
|
case /*op*/0xF8: RET_COND( _F & SF, 0xf8 ); break; // RET M
|
|
case /*op*/0xF9: _SP = _HL; break; // LD SP,HL
|
|
case /*op*/0xFA: JP_COND(_F & SF); break; // JP M,a
|
|
case /*op*/0xFB: EI; break; // EI
|
|
case /*op*/0xFC: CALL_COND( _F & SF, 0xfc ); break; // CALL M,a
|
|
case /*op*/0xFD: _R++; EXEC(fd,ROP()); break; // **** FD xx
|
|
case /*op*/0xFE: CP(ARG()); break; // CP n
|
|
case /*op*/0xFF: RST(0x38); break; // RST 7
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Returns -1 on error
|
|
//
|
|
sint32 EMU_CALL z80_execute(void *state, sint32 cycles) {
|
|
|
|
if(STATE->imflags & IMFLAGS_BADINS) return -1;
|
|
|
|
STATE->cycles_remaining_last_checkpoint = cycles;
|
|
STATE->cycles_remaining = cycles;
|
|
STATE->cycles_deferred_from_break = 0;
|
|
|
|
if(STATE->imflags & IMFLAGS_HALT) { STATE->cycles_remaining = 0; }
|
|
|
|
#ifdef TESTZ80
|
|
testz80_newins();
|
|
#endif
|
|
checkinterrupts(STATE);
|
|
#ifdef TESTZ80
|
|
if(testz80_irq) { testz80_subrst38h(); testz80_irq = 0; }
|
|
testz80_compareregs();
|
|
#endif
|
|
|
|
while(STATE->cycles_remaining > 0) {
|
|
//printf("z80 pc=%04X\n",_PC);fflush(stdout);
|
|
#ifdef TESTZ80
|
|
testz80_newins();
|
|
#endif
|
|
_R++; EXEC(normal,ROP());
|
|
#ifdef TESTZ80
|
|
testz80_subexec();
|
|
if(testz80_irq) { testz80_subrst38h(); testz80_irq = 0; }
|
|
testz80_compareregs();
|
|
#endif
|
|
}
|
|
|
|
STATE->cycles_remaining_last_checkpoint += STATE->cycles_deferred_from_break;
|
|
STATE->cycles_remaining += STATE->cycles_deferred_from_break;
|
|
STATE->cycles_deferred_from_break = 0;
|
|
|
|
hw_sync(state);
|
|
return (STATE->imflags & IMFLAGS_BADINS) ? -1 : 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|