Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "defs.h"
  2. #include "op_noprefix.h"
  3. #include "tables.h"
  4. #include "op_ed.h"
  5. #include "op_dd.h"
  6. #include "op_fd.h"
  7.  
  8. /* DDCB/FDCB opcodes */
  9. /* note: cpu.t and destination updated in step(), here process 'byte' */
  10.  
  11. //#ifdef Z80_COMMON
  12. static Z80LOGIC oplx_00(Z80 *cpu, unsigned char byte) { // rlc (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  13.    cpu->f = rlcf[byte]; return rol[byte];
  14. }
  15. static Z80LOGIC oplx_08(Z80 *cpu, unsigned char byte) { // rrc (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  16.    cpu->f = rrcf[byte]; return ror[byte];
  17. }
  18. static Z80LOGIC oplx_10(Z80 *cpu, unsigned char byte) { // rl (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  19.     if(cpu->f & CF)
  20.     {
  21.         cpu->f = rl1[byte];
  22.         return u8((byte << 1) | 1);
  23.     }
  24.     else
  25.     {
  26.         cpu->f = rl0[byte];
  27.         return u8(byte << 1);
  28.     }
  29. }
  30. static Z80LOGIC oplx_18(Z80 *cpu, unsigned char byte) { // rr (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  31.    if (cpu->f & CF) {
  32.       cpu->f = rr1[byte]; return (byte >> 1) + 0x80;
  33.    } else {
  34.       cpu->f = rr0[byte]; return (byte >> 1);
  35.    }
  36. }
  37. static Z80LOGIC oplx_20(Z80 *cpu, unsigned char byte) { // sla (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  38.    cpu->f = rl0[byte];
  39.    return u8(byte << 1);
  40. }
  41. static Z80LOGIC oplx_28(Z80 *cpu, unsigned char byte) { // sra (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  42.    cpu->f = sraf[byte]; return (byte >> 1) + (byte & 0x80);
  43. }
  44. static Z80LOGIC oplx_30(Z80 *cpu, unsigned char byte) { // sli (ix+nn)
  45.    cpu->f = rl1[byte];
  46.    return u8((byte << 1) | 1);
  47. }
  48. static Z80LOGIC oplx_38(Z80 *cpu, unsigned char byte) { // srl (ix+nn) |  M:6 T:23 (4, 4, 3, 5, 4, 3)
  49.    cpu->f = rr0[byte]; return (byte >> 1);
  50. }
  51. static Z80LOGIC oplx_40(Z80 *cpu, unsigned char byte) { // bit 0,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  52.    bitmem(cpu, byte, 0); return byte;
  53. }
  54. static Z80LOGIC oplx_48(Z80 *cpu, unsigned char byte) { // bit 1,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  55.    bitmem(cpu, byte, 1); return byte;
  56. }
  57. static Z80LOGIC oplx_50(Z80 *cpu, unsigned char byte) { // bit 2,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  58.    bitmem(cpu, byte, 2); return byte;
  59. }
  60. static Z80LOGIC oplx_58(Z80 *cpu, unsigned char byte) { // bit 3,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  61.    bitmem(cpu, byte, 3); return byte;
  62. }
  63. static Z80LOGIC oplx_60(Z80 *cpu, unsigned char byte) { // bit 4,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  64.    bitmem(cpu, byte, 4); return byte;
  65. }
  66. static Z80LOGIC oplx_68(Z80 *cpu, unsigned char byte) { // bit 5,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  67.    bitmem(cpu, byte, 5); return byte;
  68. }
  69. static Z80LOGIC oplx_70(Z80 *cpu, unsigned char byte) { // bit 6,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  70.    bitmem(cpu, byte, 6); return byte;
  71. }
  72. static Z80LOGIC oplx_78(Z80 *cpu, unsigned char byte) { // bit 7,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4)
  73.    bitmem(cpu, byte, 7); return byte;
  74. }
  75. static Z80LOGIC oplx_80(Z80 *cpu, unsigned char byte) { // res 0,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  76.     (void)cpu;
  77.     return resbyte(byte, 0);
  78. }
  79. static Z80LOGIC oplx_88(Z80 *cpu, unsigned char byte) { // res 1,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  80.     (void)cpu;
  81.     return resbyte(byte, 1);
  82. }
  83. static Z80LOGIC oplx_90(Z80 *cpu, unsigned char byte) { // res 2,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  84.     (void)cpu;
  85.     return resbyte(byte, 2);
  86. }
  87. static Z80LOGIC oplx_98(Z80 *cpu, unsigned char byte) { // res 3,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  88.     (void)cpu;
  89.     return resbyte(byte, 3);
  90. }
  91. static Z80LOGIC oplx_A0(Z80 *cpu, unsigned char byte) { // res 4,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  92.     (void)cpu;
  93.     return resbyte(byte, 4);
  94. }
  95. static Z80LOGIC oplx_A8(Z80 *cpu, unsigned char byte) { // res 5,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  96.     (void)cpu;
  97.     return resbyte(byte, 5);
  98. }
  99. static Z80LOGIC oplx_B0(Z80 *cpu, unsigned char byte) { // res 6,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  100.     (void)cpu;
  101.     return resbyte(byte, 6);
  102. }
  103. static Z80LOGIC oplx_B8(Z80 *cpu, unsigned char byte) { // res 7,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  104.     (void)cpu;
  105.     return resbyte(byte, 7);
  106. }
  107. static Z80LOGIC oplx_C0(Z80 *cpu, unsigned char byte) { // set 0,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  108.     (void)cpu;
  109.     return setbyte(byte, 0);
  110. }
  111. static Z80LOGIC oplx_C8(Z80 *cpu, unsigned char byte) { // set 1,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  112.     (void)cpu;
  113.     return setbyte(byte, 1);
  114. }
  115. static Z80LOGIC oplx_D0(Z80 *cpu, unsigned char byte) { // set 2,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  116.     (void)cpu;
  117.     return setbyte(byte, 2);
  118. }
  119. static Z80LOGIC oplx_D8(Z80 *cpu, unsigned char byte) { // set 3,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  120.     (void)cpu;
  121.     return setbyte(byte, 3);
  122. }
  123. static Z80LOGIC oplx_E0(Z80 *cpu, unsigned char byte) { // set 4,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  124.     (void)cpu;
  125.     return setbyte(byte, 4);
  126. }
  127. static Z80LOGIC oplx_E8(Z80 *cpu, unsigned char byte) { // set 5,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  128.     (void)cpu;
  129.     return setbyte(byte, 5);
  130. }
  131. static Z80LOGIC oplx_F0(Z80 *cpu, unsigned char byte) { // set 6,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  132.     (void)cpu;
  133.     return setbyte(byte, 6);
  134. }
  135. static Z80LOGIC oplx_F8(Z80 *cpu, unsigned char byte) { // set 7,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3)
  136.     (void)cpu;
  137.     return setbyte(byte, 7);
  138. }
  139.  
  140. LOGICFUNC const logic_ix_opcode[0x100] = {
  141.  
  142.    oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00,
  143.    oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08,
  144.    oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10,
  145.    oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18,
  146.    oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20,
  147.    oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28,
  148.    oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30,
  149.    oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38,
  150.  
  151.    oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40,
  152.    oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48,
  153.    oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50,
  154.    oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58,
  155.    oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60,
  156.    oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68,
  157.    oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70,
  158.    oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78,
  159.  
  160.    oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80,
  161.    oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88,
  162.    oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90,
  163.    oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98,
  164.    oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0,
  165.    oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8,
  166.    oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0,
  167.    oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8,
  168.  
  169.    oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0,
  170.    oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8,
  171.    oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0,
  172.    oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8,
  173.    oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0,
  174.    oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8,
  175.    oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0,
  176.    oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8,
  177.  
  178. };
  179.  
  180. // offsets to b,c,d,e,h,l,trash,a  from cpu.c
  181. static const unsigned reg_offset[] =
  182. {
  183.     (offsetof(TZ80State, b) - offsetof(TZ80State, c)),
  184.     (offsetof(TZ80State, c) - offsetof(TZ80State, c)),
  185.     (offsetof(TZ80State, d) - offsetof(TZ80State, c)),
  186.     (offsetof(TZ80State, e) - offsetof(TZ80State, c)),
  187.     (offsetof(TZ80State, h) - offsetof(TZ80State, c)),
  188.     (offsetof(TZ80State, l) - offsetof(TZ80State, c)),
  189.     (offsetof(TZ80State, trash) - offsetof(TZ80State, c)),
  190.     (offsetof(TZ80State, a) - offsetof(TZ80State, c))
  191. };
  192. static_assert((offsetof(TZ80State, b) - offsetof(TZ80State, c)) == 1, "bad offset b->c");
  193. static_assert((offsetof(TZ80State, c) - offsetof(TZ80State, c)) == 0, "bad offset c->c");
  194. static_assert((offsetof(TZ80State, d) - offsetof(TZ80State, c)) == 5, "bad offset d->c");
  195. static_assert((offsetof(TZ80State, e) - offsetof(TZ80State, c)) == 4, "bad offset e->c");
  196. static_assert((offsetof(TZ80State, h) - offsetof(TZ80State, c)) == 9, "bad offset h->c");
  197. static_assert((offsetof(TZ80State, l) - offsetof(TZ80State, c)) == 8, "bad offset l->c");
  198. static_assert((offsetof(TZ80State, trash) - offsetof(TZ80State, c)) == 2, "bad offset trash->c");
  199. static_assert((offsetof(TZ80State, a) - offsetof(TZ80State, c)) == 13, "bad offset a->c");
  200. //#endif
  201.  
  202. //#ifndef Z80_COMMON
  203. Z80INLINE void Z80FAST ddfd(Z80 *cpu, unsigned char opcode)
  204. {
  205.    unsigned char op1; // last DD/FD prefix
  206.    do {
  207.       op1 = opcode;
  208.       opcode = cpu->m1_cycle();
  209.    } while ((opcode | 0x20) == 0xFD); // opcode == DD/FD
  210.  
  211.    if (opcode == 0xCB) {
  212.  
  213.       unsigned ptr; // pointer to DDCB operand
  214.       ptr = unsigned(int((op1 == 0xDD) ? cpu->ix:cpu->iy) + i8(cpu->MemIf->xm(cpu->pc++)));
  215.       cpu->memptr = ptr;
  216.       // DDCBnnXX,FDCBnnXX increment R by 2, not 3!
  217.       opcode = cpu->m1_cycle(); cpu->r_low--;
  218.       unsigned char byte = (logic_ix_opcode[opcode])(cpu, cpu->MemIf->rm(ptr));
  219.       if ((opcode & 0xC0) == 0x40) { cpu->t += 8; return; } // bit n,rm
  220.  
  221.       // select destination register for shift/res/set
  222.       *(&cpu->c + reg_offset[opcode & 7]) = byte;
  223.       cpu->MemIf->wm(ptr, byte);
  224.       cpu->t += 11;
  225.       return;
  226.    }
  227.  
  228.    if (opcode == 0xED) {
  229.       opcode = cpu->m1_cycle();
  230.       (ext_opcode[opcode])(cpu);
  231.       return;
  232.    }
  233.  
  234.    // one prefix: DD/FD
  235.    ((op1 == 0xDD) ? ix_opcode[opcode] : iy_opcode[opcode])(cpu);
  236. }
  237.  
  238. Z80OPCODE op_DD(Z80 *cpu)
  239. {
  240.    ddfd(cpu, 0xDD);
  241. }
  242.  
  243. Z80OPCODE op_FD(Z80 *cpu)
  244. {
  245.    ddfd(cpu, 0xFD);
  246. }
  247. //#endif
  248.