Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*====================================================================/*
  2.   opcodes_dd_fd.c -> This file executes the DD/FD PREFIX opcodes.
  3.  
  4.   The DD prefix "creates" some new instructions by changing HL to IX
  5.   on the opcode defined by the next byte on memory.
  6.  
  7.   The FD prefix "creates" some new instructions by changing HL to IY
  8.   on the opcode defined by the next byte on memory.
  9.  
  10.   Change the REGISTER variable to IX or HY before including this file.
  11.   Something like:
  12.  
  13.         #define REGISTER  regs->IX
  14.             #include "op_dd_fd.c"
  15.         #undef  REGISTER
  16.  
  17.  On this code, this REGISTER variable is used as REGISTER.W or
  18.  REGISTER.B.h and REGISTER.B.l ...
  19.  
  20.  This program is free software; you can redistribute it and/or modify
  21.  it under the terms of the GNU General Public License as published by
  22.  the Free Software Foundation; either version 2 of the License, or
  23.  (at your option) any later version.
  24.  
  25.  This program is distributed in the hope that it will be useful,
  26.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28.  GNU General Public License for more details.
  29.  
  30.  You should have received a copy of the GNU General Public License
  31.  along with this program; if not, write to the Free Software
  32.  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  33.  
  34.  Copyright (c) 2000 Santiago Romero Iglesias.
  35.  Email: sromero@escomposlinux.org
  36.  =====================================================================*/
  37.  
  38. /* 8 clock cycles minimum = DD opcode = FD opcode = 4 + 4 */
  39.  
  40. #define REG  REGISTER.W
  41. #define REGL REGISTER.B.l
  42. #define REGH REGISTER.B.h
  43.  
  44. opcode = Z80ReadMem( r_PC );
  45. r_PC++;
  46.  
  47. switch(opcode)
  48. {
  49. case  ADD_IXY_BC    : ADD_WORD(REG, r_BC); AddCycles( 4+4+7 ); break;
  50. case  ADD_IXY_DE    : ADD_WORD(REG, r_DE); AddCycles( 4+4+7 ); break;
  51. case  ADD_IXY_SP    : ADD_WORD(REG, r_SP); AddCycles( 4+4+7 ); break;
  52. case  ADD_IXY_IXY   : ADD_WORD(REG, REG); AddCycles( 4+4+7 ); break;
  53. case  DEC_IXY       : REG--; AddCycles( 4+4+2 ); break;
  54. case  INC_IXY       : REG++; AddCycles( 4+4 ); break;
  55.  
  56. case  JP_IXY        : r_PC = REG; AddCycles( 4+4 );break;
  57. case  LD_SP_IXY     : r_SP = REG; AddCycles( 4+4+2 ); break;
  58.  
  59. case  PUSH_IXY      : PUSH_IXYr(); AddCycles( 4+4+3+3+1 ); break;
  60. case  POP_IXY       : POP_IXYr();  AddCycles( 4+4+3+3 ); break;
  61.  
  62. case  EX_IXY_xSP    : r_meml = Z80ReadMem(r_SP);
  63.                       r_memh = Z80ReadMem(r_SP+1);
  64.                       Z80WriteMem( r_SP, REGL, regs );
  65.                       Z80WriteMem( r_SP+1, REGH, regs );
  66.                       REGL=r_meml; REGH=r_memh;
  67.                       AddCycles( 4+4+3+3+3+3+3 ); break;
  68.  
  69. case  LD_A_xIXY     : r_A = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
  70.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  71. case  LD_B_xIXY     : r_B = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
  72.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  73. case  LD_C_xIXY     : r_C = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
  74.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  75. case  LD_D_xIXY     : r_D = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
  76.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  77. case  LD_E_xIXY     : r_E = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
  78.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  79.  
  80. case  LD_xIXY_A     : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_A, regs );
  81.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  82. case  LD_xIXY_B     : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_B, regs );
  83.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  84. case  LD_xIXY_C     : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_C, regs );
  85.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  86. case  LD_xIXY_D     : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_D, regs );
  87.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  88. case  LD_xIXY_E     : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_E, regs );
  89.                       r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
  90.  
  91. case  INC_xIXY      : r_mem = REG+(offset)Z80ReadMem(r_PC);
  92.                       r_PC++;
  93.                       tmpreg.B.l = Z80ReadMem(r_mem);
  94.                       INC(tmpreg.B.l);
  95.                       Z80WriteMem(r_mem, tmpreg.B.l, regs );
  96.                       AddCycles( 4+3+3 + 3+3+3+ 3+1); break;
  97. case  DEC_xIXY      : r_mem = REG+(offset)Z80ReadMem(r_PC);
  98.                       r_PC++;
  99.                       tmpreg.B.l = Z80ReadMem(r_mem);
  100.                       DEC(tmpreg.B.l);
  101.                       Z80WriteMem(r_mem, tmpreg.B.l, regs );
  102.                       AddCycles( 4+3+3 + 3+3+3+ 3+1); break;
  103.  
  104. case  ADC_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC)); r_PC++;
  105.                       ADC(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  106. case  SBC_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  107.                       r_PC++;
  108.                       SBC(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  109. case  ADD_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  110.                       r_PC++;
  111.                       ADD(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  112. case  SUB_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  113.                       r_PC++;
  114.                       SUB(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  115. case  AND_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  116.                       r_PC++;
  117.                       AND(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  118. case  OR_xIXY       : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  119.                       r_PC++;
  120.                       OR(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  121. case  XOR_xIXY      : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  122.                       r_PC++;
  123.                       XOR(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  124.  
  125. case  CP_xIXY       : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
  126.                       r_PC++;
  127.                       CP(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
  128.  
  129. case  LD_IXY_NN     : REGL = Z80ReadMem(r_PC); r_PC++;
  130.                       REGH = Z80ReadMem(r_PC); r_PC++;
  131.                       AddCycles( 4+1+3+3+3 ); break;
  132.  
  133. case  LD_xIXY_N     : r_mem = REG + (offset) Z80ReadMem(r_PC); r_PC++;
  134.                       Z80WriteMem( r_mem, Z80ReadMem(r_PC), regs );  r_PC++;
  135.                       AddCycles( 4+3+3+3+3+3 ); break;
  136.  
  137. case  LD_IXY_xNN    : LOAD_rr_nn(REG);
  138.                       AddCycles( 4+3+3+3+3+3+1 ); break;
  139.  
  140. case  LD_xNN_IXY    : STORE_nn_rr(REG);
  141.                       AddCycles( 4+3+3+ 3+3+3+1 ); break;
  142.  
  143.  
  144. /* some undocumented opcodes: may be wrong: */
  145. case  LD_A_IXYh     : r_A  = REGH; AddCycles(4+4); break;
  146. case  LD_A_IXYl     : r_A  = REGL; AddCycles(4+4); break;
  147. case  LD_B_IXYh     : r_B  = REGH; AddCycles(4+4); break;
  148. case  LD_B_IXYl     : r_B  = REGL; AddCycles(4+4); break;
  149. case  LD_C_IXYh     : r_C  = REGH; AddCycles(4+4); break;
  150. case  LD_C_IXYl     : r_C  = REGL; AddCycles(4+4); break;
  151. case  LD_D_IXYh     : r_D  = REGH; AddCycles(4+4); break;
  152. case  LD_D_IXYl     : r_D  = REGL; AddCycles(4+4); break;
  153. case  LD_E_IXYh     : r_E  = REGH; AddCycles(4+4); break;
  154. case  LD_E_IXYl     : r_E  = REGL; AddCycles(4+4); break;
  155. case  LD_IXYh_A     : REGH = r_A;  AddCycles(4+4); break;
  156. case  LD_IXYh_B     : REGH = r_B;  AddCycles(4+4); break;
  157. case  LD_IXYh_C     : REGH = r_C;  AddCycles(4+4); break;
  158. case  LD_IXYh_D     : REGH = r_D;  AddCycles(4+4); break;
  159. case  LD_IXYh_E     : REGH = r_E;  AddCycles(4+4); break;
  160. case  LD_IXYh_IXYh  : AddCycles(4+4); break;
  161. case  LD_IXYh_IXYl  : REGH = REGL; AddCycles(4+4); break;
  162. case  LD_IXYl_A     : REGL = r_A;  AddCycles(4+4); break;
  163. case  LD_IXYl_B     : REGL = r_B;  AddCycles(4+4); break;
  164. case  LD_IXYl_C     : REGL = r_C;  AddCycles(4+4); break;
  165. case  LD_IXYl_D     : REGL = r_D;  AddCycles(4+4); break;
  166. case  LD_IXYl_E     : REGL = r_E;  AddCycles(4+4); break;
  167. case  LD_IXYl_IXYh  : REGL = REGH; AddCycles(4+4); break;
  168. case  LD_IXYl_IXYl  : AddCycles(4+4); break;
  169. case  LD_IXYh_N     : REGH = Z80ReadMem(r_PC); r_PC++;
  170.                       AddCycles(4+4+3); break;
  171. case  LD_IXYl_N     : REGL = Z80ReadMem(r_PC); r_PC++;
  172.                       AddCycles(4+4+3); break;
  173.  
  174.  
  175. case  ADD_IXYh      : ADD(REGH); AddCycles(4+4); break;
  176. case  ADD_IXYl      : ADD(REGL); AddCycles(4+4); break;
  177. case  ADC_IXYh      : ADC(REGH); AddCycles(4+4); break;
  178. case  ADC_IXYl      : ADC(REGL); AddCycles(4+4); break;
  179. case  SUB_IXYh      : SUB(REGH); AddCycles(4+4); break;
  180. case  SUB_IXYl      : SUB(REGL); AddCycles(4+4); break;
  181. case  SBC_IXYh      : SBC(REGH); AddCycles(4+4); break;
  182. case  SBC_IXYl      : SBC(REGL); AddCycles(4+4); break;
  183. case  AND_IXYh      : AND(REGH); AddCycles(4+4); break;
  184. case  AND_IXYl      : AND(REGL); AddCycles(4+4); break;
  185. case  XOR_IXYh      : XOR(REGH); AddCycles(4+4); break;
  186. case  XOR_IXYl      : XOR(REGL); AddCycles(4+4); break;
  187. case  OR_IXYh       : OR(REGH);  AddCycles(4+4); break;
  188. case  OR_IXYl       : OR(REGL);  AddCycles(4+4); break;
  189. case  CP_IXYh       : CP(REGH);  AddCycles(4+4); break;
  190. case  CP_IXYl       : CP(REGL);  AddCycles(4+4); break;
  191. case  INC_IXYh      : INC(REGH); AddCycles(4+4); break;
  192. case  INC_IXYl      : INC(REGL); AddCycles(4+4); break;
  193. case  DEC_IXYh      : DEC(REGH); AddCycles(4+4); break;
  194. case  DEC_IXYl      : DEC(REGL); AddCycles(4+4); break;
  195.  
  196. case  LD_xIXY_H     : r_meml =Z80ReadMem(r_PC); r_PC++;
  197.                       Z80WriteMem( REG+(offset)(r_meml), r_H, regs );
  198.                       AddCycles( 4+3+3+3+3+3 ); break;
  199. case  LD_xIXY_L     : r_meml =Z80ReadMem(r_PC); r_PC++;
  200.                       Z80WriteMem( REG+(offset)(r_meml), r_L, regs );
  201.                       AddCycles( 4+3+3+3+3+3 ); break;
  202. case  LD_H_xIXY     : r_meml =Z80ReadMem(r_PC); r_PC++;
  203.                       r_H = Z80ReadMem( REG+(offset)(r_meml));
  204.                       AddCycles( 4+3+3+3+3+3 ); break;
  205. case  LD_L_xIXY     : r_meml =Z80ReadMem(r_PC); r_PC++;
  206.                       r_L = Z80ReadMem( REG+(offset)(r_meml));
  207.                       AddCycles( 4+3+3+3+3+3 ); break;
  208.  
  209. case PREFIX_CB:
  210.                       #include "opddfdcb.c"
  211.                       break;
  212.  
  213. /*
  214. case PREFIX_DD:
  215. case PREFIX_FD:       AddCycles( 4 );
  216.                       r_PC--;                 // decode it the next time :)
  217.                       break;
  218. */
  219.  
  220. default:              AddCycles( 4 );
  221.                       r_PC--;                 /* decode it the next time :) */
  222.                       SubR(1);
  223.  
  224. //    exit(1);
  225. //    if( regs->DecodingErrors )
  226. //    {
  227. //      printf("z80 core: Unknown instruction: ");
  228. //      if ( regs->we_are_on_ddfd == WE_ARE_ON_DD )
  229. //         printf("DD ");
  230. //      else
  231. //         printf("FD ");
  232. //      printf("%02Xh at PC=%04Xh.\n", Z80ReadMem(r_PC-1), r_PC-2 );
  233. //    }
  234.     break;
  235. }
  236.  
  237. #undef REG
  238. #undef REGL
  239. #undef REGH
  240.