kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
484 wiersze
10 KiB
C
Executable File
484 wiersze
10 KiB
C
Executable File
/*====================================================================
|
|
opcodes_dd_fd.c -> This file executes the DD/FD PREFIX opcodes.
|
|
|
|
The DD prefix "creates" some new instructions by changing HL to IX
|
|
on the opcode defined by the next byte on memory.
|
|
|
|
The FD prefix "creates" some new instructions by changing HL to IY
|
|
on the opcode defined by the next byte on memory.
|
|
|
|
Change the REGISTER variable to IX or HY before including this file.
|
|
Something like:
|
|
|
|
#define REGISTER regs->IX
|
|
#include "op_dd_fd.c"
|
|
#undef REGISTER
|
|
|
|
On this code, this REGISTER variable is used as REGISTER.W or
|
|
REGISTER.B.h and REGISTER.B.l ...
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
Copyright (c) 2000 Santiago Romero Iglesias.
|
|
Email: sromero@escomposlinux.org
|
|
=====================================================================*/
|
|
|
|
/* 8 clock cycles minimum = DD opcode = FD opcode = 4 + 4 */
|
|
|
|
#define REG REGISTER.W
|
|
#define REGL REGISTER.B.l
|
|
#define REGH REGISTER.B.h
|
|
|
|
opcode = Z80ReadMem (r_PC);
|
|
regs->PC.W++;
|
|
//r_PC++;
|
|
|
|
switch (opcode)
|
|
{
|
|
case ADD_IXY_BC:
|
|
ADD_WORD (REG, r_BC);
|
|
AddCycles (4 + 4 + 7);
|
|
break;
|
|
case ADD_IXY_DE:
|
|
ADD_WORD (REG, r_DE);
|
|
AddCycles (4 + 4 + 7);
|
|
break;
|
|
case ADD_IXY_SP:
|
|
ADD_WORD (REG, r_SP);
|
|
AddCycles (4 + 4 + 7);
|
|
break;
|
|
case ADD_IXY_IXY:
|
|
ADD_WORD (REG, REG);
|
|
AddCycles (4 + 4 + 7);
|
|
break;
|
|
case DEC_IXY:
|
|
REG--;
|
|
AddCycles (4 + 4 + 2);
|
|
break;
|
|
case INC_IXY:
|
|
REG++;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
|
|
case JP_IXY:
|
|
r_PC = REG;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_SP_IXY:
|
|
r_SP = REG;
|
|
AddCycles (4 + 4 + 2);
|
|
break;
|
|
|
|
case PUSH_IXY:
|
|
PUSH_IXYr ();
|
|
AddCycles (4 + 4 + 3 + 3 + 1);
|
|
break;
|
|
case POP_IXY:
|
|
POP_IXYr ();
|
|
AddCycles (4 + 4 + 3 + 3);
|
|
break;
|
|
|
|
case EX_IXY_xSP:
|
|
r_meml = Z80ReadMem (r_SP);
|
|
r_memh = Z80ReadMem (r_SP + 1);
|
|
Z80WriteMem (r_SP, REGL, regs);
|
|
Z80WriteMem (r_SP + 1, REGH, regs);
|
|
REGL = r_meml;
|
|
REGH = r_memh;
|
|
AddCycles (4 + 4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case LD_A_xIXY:
|
|
r_A = Z80ReadMem (REG + ((offset) Z80ReadMem (r_PC)));
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_B_xIXY:
|
|
r_B = Z80ReadMem (REG + ((offset) Z80ReadMem (r_PC)));
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_C_xIXY:
|
|
r_C = Z80ReadMem (REG + ((offset) Z80ReadMem (r_PC)));
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_D_xIXY:
|
|
r_D = Z80ReadMem (REG + ((offset) Z80ReadMem (r_PC)));
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_E_xIXY:
|
|
r_E = Z80ReadMem (REG + ((offset) Z80ReadMem (r_PC)));
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case LD_xIXY_A:
|
|
Z80WriteMem (REG + (offset) Z80ReadMem (r_PC), r_A, regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_xIXY_B:
|
|
Z80WriteMem (REG + (offset) Z80ReadMem (r_PC), r_B, regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_xIXY_C:
|
|
Z80WriteMem (REG + (offset) Z80ReadMem (r_PC), r_C, regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_xIXY_D:
|
|
Z80WriteMem (REG + (offset) Z80ReadMem (r_PC), r_D, regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_xIXY_E:
|
|
Z80WriteMem (REG + (offset) Z80ReadMem (r_PC), r_E, regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case INC_xIXY:
|
|
r_mem = REG + (offset) Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
tmpreg.B.l = Z80ReadMem (r_mem);
|
|
INC (tmpreg.B.l);
|
|
Z80WriteMem (r_mem, tmpreg.B.l, regs);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3 + 3 + 1);
|
|
break;
|
|
case DEC_xIXY:
|
|
r_mem = REG + (offset) Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
tmpreg.B.l = Z80ReadMem (r_mem);
|
|
DEC (tmpreg.B.l);
|
|
Z80WriteMem (r_mem, tmpreg.B.l, regs);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3 + 3 + 1);
|
|
break;
|
|
|
|
case ADC_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
ADC (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case SBC_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
SBC (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case ADD_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
ADD (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case SUB_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
SUB (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case AND_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
AND (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case OR_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
OR (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case XOR_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
XOR (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case CP_xIXY:
|
|
r_meml = Z80ReadMem (REG + (offset) Z80ReadMem (r_PC));
|
|
r_PC++;
|
|
CP (r_meml);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case LD_IXY_NN:
|
|
REGL = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
REGH = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
AddCycles (4 + 1 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case LD_xIXY_N:
|
|
r_mem = REG + (offset) Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
Z80WriteMem (r_mem, Z80ReadMem (r_PC), regs);
|
|
r_PC++;
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case LD_IXY_xNN:
|
|
LOAD_rr_nn (REG);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3 + 1);
|
|
break;
|
|
|
|
case LD_xNN_IXY:
|
|
STORE_nn_rr (REG);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3 + 1);
|
|
break;
|
|
|
|
|
|
/* some undocumented opcodes: may be wrong: */
|
|
case LD_A_IXYh:
|
|
r_A = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_A_IXYl:
|
|
r_A = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_B_IXYh:
|
|
r_B = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_B_IXYl:
|
|
r_B = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_C_IXYh:
|
|
r_C = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_C_IXYl:
|
|
r_C = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_D_IXYh:
|
|
r_D = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_D_IXYl:
|
|
r_D = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_E_IXYh:
|
|
r_E = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_E_IXYl:
|
|
r_E = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_A:
|
|
REGH = r_A;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_B:
|
|
REGH = r_B;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_C:
|
|
REGH = r_C;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_D:
|
|
REGH = r_D;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_E:
|
|
REGH = r_E;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_IXYh:
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_IXYl:
|
|
REGH = REGL;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_A:
|
|
REGL = r_A;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_B:
|
|
REGL = r_B;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_C:
|
|
REGL = r_C;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_D:
|
|
REGL = r_D;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_E:
|
|
REGL = r_E;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_IXYh:
|
|
REGL = REGH;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYl_IXYl:
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case LD_IXYh_N:
|
|
REGH = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
AddCycles (4 + 4 + 3);
|
|
break;
|
|
case LD_IXYl_N:
|
|
REGL = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
AddCycles (4 + 4 + 3);
|
|
break;
|
|
|
|
|
|
case ADD_IXYh:
|
|
ADD (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case ADD_IXYl:
|
|
ADD (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case ADC_IXYh:
|
|
ADC (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case ADC_IXYl:
|
|
ADC (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case SUB_IXYh:
|
|
SUB (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case SUB_IXYl:
|
|
SUB (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case SBC_IXYh:
|
|
SBC (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case SBC_IXYl:
|
|
SBC (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case AND_IXYh:
|
|
AND (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case AND_IXYl:
|
|
AND (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case XOR_IXYh:
|
|
XOR (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case XOR_IXYl:
|
|
XOR (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case OR_IXYh:
|
|
OR (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case OR_IXYl:
|
|
OR (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case CP_IXYh:
|
|
CP (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case CP_IXYl:
|
|
CP (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case INC_IXYh:
|
|
INC (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case INC_IXYl:
|
|
INC (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case DEC_IXYh:
|
|
DEC (REGH);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
case DEC_IXYl:
|
|
DEC (REGL);
|
|
AddCycles (4 + 4);
|
|
break;
|
|
|
|
case LD_xIXY_H:
|
|
r_meml = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
Z80WriteMem (REG + (offset) (r_meml), r_H, regs);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_xIXY_L:
|
|
r_meml = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
Z80WriteMem (REG + (offset) (r_meml), r_L, regs);
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_H_xIXY:
|
|
r_meml = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
r_H = Z80ReadMem (REG + (offset) (r_meml));
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
case LD_L_xIXY:
|
|
r_meml = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
r_L = Z80ReadMem (REG + (offset) (r_meml));
|
|
AddCycles (4 + 3 + 3 + 3 + 3 + 3);
|
|
break;
|
|
|
|
case PREFIX_CB:
|
|
#include "opddfdcb.h"
|
|
break;
|
|
|
|
/*
|
|
case PREFIX_DD:
|
|
case PREFIX_FD: AddCycles( 4 );
|
|
r_PC--; // decode it the next time :)
|
|
break;
|
|
*/
|
|
|
|
default:
|
|
AddCycles (4);
|
|
r_PC--; /* decode it the next time :) */
|
|
SubR (1);
|
|
|
|
break;
|
|
}
|
|
|
|
#undef REG
|
|
#undef REGL
|
|
#undef REGH
|