Subversion Repositories pentevo

Rev

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

  1. #include "defs.h"
  2. #include "tables.h"
  3. #include "op_noprefix.h"
  4. #include "op_ed.h"
  5.  
  6. /* ED opcodes */
  7.  
  8. //#ifndef Z80_COMMON
  9. static Z80OPCODE ope_40(Z80 *cpu) { // in b,(c)
  10.    cpu->t += 4;
  11.    cpu->memptr = cpu->bc+1;
  12.    cpu->b = cpu->in(cpu->bc);
  13.    cpu->f = log_f[cpu->b] | (cpu->f & CF);
  14. }
  15. static Z80OPCODE ope_41(Z80 *cpu) { // out (c),b | M:3 T:12 (4, 4, 4)
  16.    cpu->t += 4;
  17.    cpu->memptr = cpu->bc+1;
  18.    cpu->out(cpu->bc, cpu->b);
  19. }
  20. //#endif
  21. //#ifdef Z80_COMMON
  22. static Z80OPCODE ope_42(Z80 *cpu) { // sbc hl,bc
  23.    cpu->memptr = cpu->hl+1;
  24.    unsigned char fl = NF;
  25.    fl |= (((cpu->hl & 0x0FFF) - (cpu->bc & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */
  26.    unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->bc & 0xFFFF) - (cpu->af & CF);
  27.    if (tmp & 0x10000) fl |= CF;
  28.    if (!(tmp & 0xFFFF)) fl |= ZF;
  29.    int ri = (int)(short)cpu->hl - (int)(short)cpu->bc - (int)(cpu->af & CF);
  30.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  31.    cpu->hl = tmp;
  32.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  33.    cpu->t += 7;
  34. }
  35. //#endif
  36. //#ifndef Z80_COMMON
  37. static Z80OPCODE ope_43(Z80 *cpu) { // ld (nnnn),bc | M:6 T:20 (4, 4, 3, 3, 3, 3)
  38.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  39.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  40.    cpu->memptr = adr+1;
  41.    cpu->MemIf->wm(adr, cpu->c);
  42.    cpu->MemIf->wm(adr+1, cpu->b);
  43.    cpu->t += 12;
  44. }
  45. //#endif
  46. //#ifdef Z80_COMMON
  47. static Z80OPCODE ope_44(Z80 *cpu) { // neg
  48.    cpu->f = sbcf[cpu->a];
  49.    cpu->a = -cpu->a;
  50. }
  51. //#endif
  52. //#ifndef Z80_COMMON
  53. static Z80OPCODE ope_45(Z80 *cpu) { // retn
  54.    cpu->iff1 = cpu->iff2;
  55.    unsigned addr = cpu->MemIf->rm(cpu->sp++);
  56.    addr += 0x100*cpu->MemIf->rm(cpu->sp++);
  57.    cpu->last_branch = u16(cpu->pc-2);
  58.    cpu->pc = addr;
  59.    cpu->memptr = addr;
  60.    cpu->t += 6;
  61.    cpu->retn();
  62. }
  63. //#endif
  64. //#ifdef Z80_COMMON
  65. static Z80OPCODE ope_46(Z80 *cpu) { // im 0
  66.    cpu->im = 0;
  67. }
  68. static Z80OPCODE ope_47(Z80 *cpu) { // ld i,a
  69.    cpu->i = cpu->a;
  70.    cpu->t++;
  71. }
  72. //#endif
  73. //#ifndef Z80_COMMON
  74. static Z80OPCODE ope_48(Z80 *cpu) { // in c,(c)
  75.    cpu->t += 4;
  76.    cpu->memptr = cpu->bc+1;
  77.    cpu->c = cpu->in(cpu->bc);
  78.    cpu->f = log_f[cpu->c] | (cpu->f & CF);
  79. }
  80. static Z80OPCODE ope_49(Z80 *cpu) { // out (c),c | M:3 T:12 (4, 4, 4)
  81.    cpu->t += 4;
  82.    cpu->memptr = cpu->bc+1;
  83.    cpu->out(cpu->bc, cpu->c);
  84. }
  85. //#endif
  86. //#ifdef Z80_COMMON
  87. static Z80OPCODE ope_4A(Z80 *cpu) { // adc hl,bc
  88.    cpu->memptr = cpu->hl+1;
  89.    unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->bc & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */
  90.    unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->bc & 0xFFFF) + (cpu->af & CF);
  91.    if (tmp & 0x10000) fl |= CF;
  92.    if (!(tmp & 0xFFFF)) fl |= ZF;
  93.    int ri = (int)(short)cpu->hl + (int)(short)cpu->bc + (int)(cpu->af & CF);
  94.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  95.    cpu->hl = tmp;
  96.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  97.    cpu->t += 7;
  98. }
  99. //#endif
  100. //#ifndef Z80_COMMON
  101. static Z80OPCODE ope_4B(Z80 *cpu) { // ld bc,(nnnn)
  102.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  103.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  104.    cpu->memptr = adr+1;
  105.    cpu->c = cpu->MemIf->rm(adr);
  106.    cpu->b = cpu->MemIf->rm(adr+1);
  107.    cpu->t += 12;
  108. }
  109. #define ope_4C ope_44   // neg
  110. static Z80OPCODE ope_4D(Z80 *cpu) { // reti
  111.    cpu->iff1 = cpu->iff2;
  112.    unsigned addr = cpu->MemIf->rm(cpu->sp++);
  113.    addr += 0x100*cpu->MemIf->rm(cpu->sp++);
  114.    cpu->last_branch = u16(cpu->pc-2);
  115.    cpu->pc = addr;
  116.    cpu->memptr = addr;
  117.    cpu->t += 6;
  118. }
  119. //#endif
  120.  
  121. #define ope_4E ope_56  // im 0/1 -> im1
  122.  
  123. //#ifdef Z80_COMMON
  124. static Z80OPCODE ope_4F(Z80 *cpu) { // ld r,a
  125.    cpu->r_low = cpu->a;
  126.    cpu->r_hi = cpu->a & 0x80;
  127.    cpu->t++;
  128. }
  129. //#endif
  130. //#ifndef Z80_COMMON
  131. static Z80OPCODE ope_50(Z80 *cpu) { // in d,(c)
  132.    cpu->t += 4;
  133.    cpu->memptr = cpu->bc+1;
  134.    cpu->d = cpu->in(cpu->bc);
  135.    cpu->f = log_f[cpu->d] | (cpu->f & CF);
  136. }
  137. static Z80OPCODE ope_51(Z80 *cpu) { // out (c),d | M:3 T:12 (4, 4, 4)
  138.    cpu->t += 4;
  139.    cpu->memptr = cpu->bc+1;
  140.    cpu->out(cpu->bc, cpu->d);
  141. }
  142. //#endif
  143. //#ifdef Z80_COMMON
  144. static Z80OPCODE ope_52(Z80 *cpu) { // sbc hl,de
  145.    cpu->memptr = cpu->hl+1;
  146.    unsigned char fl = NF;
  147.    fl |= (((cpu->hl & 0x0FFF) - (cpu->de & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */
  148.    unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->de & 0xFFFF) - (cpu->af & CF);
  149.    if (tmp & 0x10000) fl |= CF;
  150.    if (!(tmp & 0xFFFF)) fl |= ZF;
  151.    int ri = (int)(short)cpu->hl - (int)(short)cpu->de - (int)(cpu->af & CF);
  152.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  153.    cpu->hl = tmp;
  154.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  155.    cpu->t += 7;
  156. }
  157. //#endif
  158. //#ifndef Z80_COMMON
  159. static Z80OPCODE ope_53(Z80 *cpu) { // ld (nnnn),de | M:6 T:20 (4, 4, 3, 3, 3, 3)
  160.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  161.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  162.    cpu->memptr = adr+1;
  163.    cpu->MemIf->wm(adr, cpu->e);
  164.    cpu->MemIf->wm(adr+1, cpu->d);
  165.    cpu->t += 12;
  166. }
  167. //#endif
  168.  
  169. #define ope_54 ope_44 // neg
  170. #define ope_55 ope_45 // retn
  171.  
  172. //#ifdef Z80_COMMON
  173. static Z80OPCODE ope_56(Z80 *cpu) { // im 1
  174.    cpu->im = 1;
  175. }
  176.  
  177. static Z80OPCODE ope_57(Z80 *cpu)
  178. { // ld a,i
  179.    cpu->a = cpu->i;
  180.    cpu->f = (log_f[cpu->a] | (cpu->f & CF)) & ~PV;
  181.    if (cpu->iff2 && (cpu->t+10 < cpu->tpi))
  182.        cpu->f |= PV;
  183.    cpu->t++;
  184. }
  185. //#endif
  186. //#ifndef Z80_COMMON
  187. static Z80OPCODE ope_58(Z80 *cpu) { // in e,(c)
  188.    cpu->t += 4;
  189.    cpu->memptr = cpu->bc+1;
  190.    cpu->e = cpu->in(cpu->bc);
  191.    cpu->f = log_f[cpu->e] | (cpu->f & CF);
  192. }
  193. static Z80OPCODE ope_59(Z80 *cpu) { // out (c),e | M:3 T:12 (4, 4, 4)
  194.    cpu->t += 4;
  195.    cpu->memptr = cpu->bc+1;
  196.    cpu->out(cpu->bc, cpu->e);
  197. }
  198. //#endif
  199. //#ifdef Z80_COMMON
  200. static Z80OPCODE ope_5A(Z80 *cpu) { // adc hl,de
  201.    cpu->memptr = cpu->hl+1;
  202.    unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->de & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */
  203.    unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->de & 0xFFFF) + (cpu->af & CF);
  204.    if (tmp & 0x10000) fl |= CF;
  205.    if (!(tmp & 0xFFFF)) fl |= ZF;
  206.    int ri = (int)(short)cpu->hl + (int)(short)cpu->de + (int)(cpu->af & CF);
  207.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  208.    cpu->hl = tmp;
  209.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  210.    cpu->t += 7;
  211. }
  212. //#endif
  213. //#ifndef Z80_COMMON
  214. static Z80OPCODE ope_5B(Z80 *cpu) { // ld de,(nnnn)
  215.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  216.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  217.    cpu->memptr = adr+1;
  218.    cpu->e = cpu->MemIf->rm(adr);
  219.    cpu->d = cpu->MemIf->rm(adr+1);
  220.    cpu->t += 12;
  221. }
  222. //#endif
  223.  
  224. #define ope_5C ope_44   // neg
  225. #define ope_5D ope_4D   // reti
  226.  
  227. //#ifdef Z80_COMMON
  228. static Z80OPCODE ope_5E(Z80 *cpu) { // im 2
  229.    cpu->im = 2;
  230. }
  231.  
  232. static Z80OPCODE ope_5F(Z80 *cpu)
  233. { // ld a,r
  234.    cpu->a = (cpu->r_low & 0x7F) | cpu->r_hi;
  235.    cpu->f = (log_f[cpu->a] | (cpu->f & CF)) & ~PV;
  236.    if (cpu->iff2 && ((cpu->t+10 < cpu->tpi) || cpu->eipos+8==cpu->t))
  237.        cpu->f |= PV;
  238.    cpu->t++;
  239. }
  240. //#endif
  241. //#ifndef Z80_COMMON
  242. static Z80OPCODE ope_60(Z80 *cpu) { // in h,(c)
  243.    cpu->t += 4;
  244.    cpu->memptr = cpu->bc+1;
  245.    cpu->h = cpu->in(cpu->bc);
  246.    cpu->f = log_f[cpu->h] | (cpu->f & CF);
  247. }
  248. static Z80OPCODE ope_61(Z80 *cpu) { // out (c),h | M:3 T:12 (4, 4, 4)
  249.    cpu->t += 4;
  250.    cpu->memptr = cpu->bc+1;
  251.    cpu->out(cpu->bc, cpu->h);
  252. }
  253. //#endif
  254. //#ifdef Z80_COMMON
  255. static Z80OPCODE ope_62(Z80 *cpu) { // sbc hl,hl
  256.    cpu->memptr = cpu->hl+1;
  257.    unsigned char fl = NF;
  258.    fl |= (cpu->f & CF) << 4; /* HF - copy from CF */
  259.    unsigned tmp = 0-(cpu->af & CF);
  260.    if (tmp & 0x10000) fl |= CF;
  261.    if (!(tmp & 0xFFFF)) fl |= ZF;
  262.    // never set PV
  263.    cpu->hl = tmp;
  264.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  265.    cpu->t += 7;
  266. }
  267. //#endif
  268.  
  269. #define ope_63 op_22 // ld (nnnn),hl
  270. #define ope_64 ope_44 // neg
  271. #define ope_65 ope_45 // retn
  272. #define ope_66 ope_46 // im 0
  273.  
  274. //#ifndef Z80_COMMON
  275. static Z80OPCODE ope_67(Z80 *cpu) { // rrd | M:5 T:18 (4, 4, 3, 4, 3)
  276.    unsigned char tmp = cpu->MemIf->rm(cpu->hl);
  277.    cpu->memptr = cpu->hl+1;
  278.    cpu->MemIf->wm(cpu->hl, u8(cpu->a << 4) | u8(tmp >> 4));
  279.    cpu->a = (cpu->a & 0xF0) | (tmp & 0x0F);
  280.    cpu->f = log_f[cpu->a] | (cpu->f & CF);
  281.    cpu->t += 10;
  282. }
  283. //#endif
  284. //#ifndef Z80_COMMON
  285. static Z80OPCODE ope_68(Z80 *cpu) { // in l,(c)
  286.    cpu->t += 4;
  287.    cpu->memptr = cpu->bc+1;
  288.    cpu->l = cpu->in(cpu->bc);
  289.    cpu->f = log_f[cpu->l] | (cpu->f & CF);
  290. }
  291. static Z80OPCODE ope_69(Z80 *cpu) { // out (c),l | M:3 T:12 (4, 4, 4)
  292.    cpu->t += 4;
  293.    cpu->memptr = cpu->bc+1;
  294.    cpu->out(cpu->bc, cpu->l);
  295. }
  296. //#endif
  297. //#ifdef Z80_COMMON
  298. static Z80OPCODE ope_6A(Z80 *cpu) { // adc hl,hl
  299.    cpu->memptr = cpu->hl+1;
  300.    unsigned char fl = ((cpu->h << 1) & 0x10); /* HF */
  301.    unsigned tmp = (cpu->hl & 0xFFFF)*2 + (cpu->af & CF);
  302.    if (tmp & 0x10000) fl |= CF;
  303.    if (!(tmp & 0xFFFF)) fl |= ZF;
  304.    int ri = 2*(int)(short)cpu->hl + (int)(cpu->af & CF);
  305.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  306.    cpu->hl = tmp;
  307.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  308.    cpu->t += 7;
  309. }
  310. //#endif
  311.  
  312. #define ope_6B op_2A // ld hl,(nnnn)
  313. #define ope_6C ope_44   // neg
  314. #define ope_6D ope_4D   // reti
  315. #define ope_6E ope_56   // im 0/1 -> im 1
  316.  
  317. //#ifndef Z80_COMMON
  318. static Z80OPCODE ope_6F(Z80 *cpu) { // rld | M:5 T:18 (4, 4, 3, 4, 3)
  319.    unsigned char tmp = cpu->MemIf->rm(cpu->hl);
  320.    cpu->memptr = cpu->hl+1;
  321.    cpu->MemIf->wm(cpu->hl, u8(cpu->a & 0x0F) | u8(tmp << 4));
  322.    cpu->a = (cpu->a & 0xF0) | (tmp >> 4);
  323.    cpu->f = log_f[cpu->a] | (cpu->f & CF);
  324.    cpu->t += 10;
  325. }
  326. static Z80OPCODE ope_70(Z80 *cpu) { // in (c)
  327.    cpu->t += 4;
  328.    cpu->memptr = cpu->bc+1;
  329.    cpu->f = log_f[cpu->in(cpu->bc)] | (cpu->f & CF);
  330. }
  331. static Z80OPCODE ope_71(Z80 *cpu) { // out (c),0
  332.    cpu->t += 4;
  333.    cpu->memptr = cpu->bc+1;
  334.    cpu->out(cpu->bc, 0);
  335. }
  336. //#endif
  337. //#ifdef Z80_COMMON
  338. static Z80OPCODE ope_72(Z80 *cpu) { // sbc hl,sp
  339.    cpu->memptr = cpu->hl+1;
  340.    unsigned char fl = NF;
  341.    fl |= (((cpu->hl & 0x0FFF) - (cpu->sp & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */
  342.    unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->sp & 0xFFFF) - (cpu->af & CF);
  343.    if (tmp & 0x10000) fl |= CF;
  344.    if (!(tmp & 0xFFFF)) fl |= ZF;
  345.    int ri = (int)(short)cpu->hl - (int)(short)cpu->sp - (int)(cpu->af & CF);
  346.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  347.    cpu->hl = tmp;
  348.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  349.    cpu->t += 7;
  350. }
  351. //#endif
  352. //#ifndef Z80_COMMON
  353. static Z80OPCODE ope_73(Z80 *cpu) { // ld (nnnn),sp | M:6 T:20 (4, 4, 3, 3, 3, 3)
  354.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  355.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  356.    cpu->memptr = adr+1;
  357.    cpu->MemIf->wm(adr, cpu->spl);
  358.    cpu->MemIf->wm(adr+1, cpu->sph);
  359.    cpu->t += 12;
  360. }
  361. //#endif
  362.  
  363. #define ope_74 ope_44 // neg
  364. #define ope_75 ope_45 // retn
  365.  
  366. //#ifdef Z80_COMMON
  367. static Z80OPCODE ope_76(Z80 *cpu) { // im 1
  368.    cpu->im = 1;
  369. }
  370. //#endif
  371.  
  372. #define ope_77 op_00  // nop
  373.  
  374. //#ifndef Z80_COMMON
  375. static Z80OPCODE ope_78(Z80 *cpu) { // in a,(c)
  376.    cpu->t += 4;
  377.    cpu->memptr = cpu->bc+1;
  378.    cpu->a = cpu->in(cpu->bc);
  379.    cpu->f = log_f[cpu->a] | (cpu->f & CF);
  380. }
  381. static Z80OPCODE ope_79(Z80 *cpu) { // out (c),a | M:3 T:12 (4, 4, 4)
  382.    cpu->t += 4;
  383.    cpu->memptr = cpu->bc+1;
  384.    cpu->out(cpu->bc, cpu->a);
  385. }
  386. //#endif
  387. //#ifdef Z80_COMMON
  388. static Z80OPCODE ope_7A(Z80 *cpu) { // adc hl,sp
  389.    cpu->memptr = cpu->hl+1;
  390.    unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->sp & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */
  391.    unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->sp & 0xFFFF) + (cpu->af & CF);
  392.    if (tmp & 0x10000) fl |= CF;
  393.    if (!(unsigned short)tmp) fl |= ZF;
  394.    int ri = (int)(short)cpu->hl + (int)(short)cpu->sp + (int)(cpu->af & CF);
  395.    if (ri < -0x8000 || ri >= 0x8000) fl |= PV;
  396.    cpu->hl = tmp;
  397.    cpu->f = fl | (cpu->h & (F3|F5|SF));
  398.    cpu->t += 7;
  399. }
  400. //#endif
  401. //#ifndef Z80_COMMON
  402. static Z80OPCODE ope_7B(Z80 *cpu) { // ld sp,(nnnn)
  403.    unsigned adr = cpu->MemIf->xm(cpu->pc++);
  404.    adr += cpu->MemIf->xm(cpu->pc++)*0x100;
  405.    cpu->memptr = adr+1;
  406.    cpu->spl = cpu->MemIf->rm(adr);
  407.    cpu->sph = cpu->MemIf->rm(adr+1);
  408.    cpu->t += 12;
  409. }
  410. //#endif
  411.  
  412. #define ope_7C ope_44   // neg
  413. #define ope_7D ope_4D   // reti
  414. #define ope_7E ope_5E   // im 2
  415. #define ope_7F op_00    // nop
  416.  
  417. //#ifndef Z80_COMMON
  418. static Z80OPCODE ope_A0(Z80 *cpu) { // ldi | M:4 T:16 (4, 4, 3, 5)
  419.    cpu->t += 8;
  420.    unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++);
  421.    cpu->MemIf->wm(cpu->de++, tempbyte);
  422.    tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5);
  423.    cpu->f = (cpu->f & ~(NF|HF|PV|F3|F5)) + tempbyte;
  424.    if (--cpu->bc16) cpu->f |= PV;
  425. }
  426. static Z80OPCODE ope_A1(Z80 *cpu) { // cpi
  427.    cpu->t += 8;
  428.    unsigned char cf = cpu->f & CF;
  429.    unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++);
  430.    cpu->f = cpf8b[cpu->a*0x100 + tempbyte] + cf;
  431.    if (--cpu->bc16) cpu->f |= PV;
  432.    cpu->memptr++;
  433. }
  434. static Z80OPCODE ope_A2(Z80 *cpu) { // ini | M:4 T:16 (4, 5, 3, 4)
  435.    cpu->memptr = cpu->bc+1;
  436.    cpu->t += 8;
  437.    u8 tmp = cpu->in(cpu->bc);
  438.    cpu->MemIf->wm(cpu->hl++, tmp);
  439.    cpu->b--;
  440.    u8 ftmp = tmp + cpu->c + 1;
  441.    cpu->f = log_f[cpu->b] & ~PV;
  442.    cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV);
  443.    if(ftmp < tmp) cpu->f |= (HF | CF);
  444.    cpu->f |= (tmp & 0x80) >> 6; // NF
  445. }
  446. static Z80OPCODE ope_A3(Z80 *cpu) { // outi | M:4 T:16 (4, 5, 3, 4)
  447.    cpu->t += 8;
  448.    cpu->b--;
  449.    u8 tmp = cpu->MemIf->rm(cpu->hl++);
  450.    cpu->out(cpu->bc, tmp);
  451.  
  452.    u8 ftmp = tmp + cpu->l;
  453.    cpu->f = log_f[cpu->b] & ~PV;
  454.    cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV);
  455.    if(ftmp < tmp) cpu->f |= (HF | CF);
  456.    cpu->f |= (tmp & 0x80) >> 6; // NF
  457.  
  458.    cpu->memptr = cpu->bc+1;
  459. }
  460. static Z80OPCODE ope_A8(Z80 *cpu) { // ldd | M:4 T:16 (4, 4, 3, 5)
  461.    cpu->t += 8;
  462.    unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--);
  463.    cpu->MemIf->wm(cpu->de--, tempbyte);
  464.    tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5);
  465.    cpu->f = (cpu->f & ~(NF|HF|PV|F3|F5)) + tempbyte;
  466.    if (--cpu->bc16) cpu->f |= PV;
  467. }
  468. static Z80OPCODE ope_A9(Z80 *cpu) { // cpd
  469.    cpu->t += 8;
  470.    unsigned char cf = cpu->f & CF;
  471.    unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--);
  472.    cpu->f = cpf8b[cpu->a*0x100 + tempbyte] + cf;
  473.    if (--cpu->bc16) cpu->f |= PV;
  474.    cpu->memptr--;
  475. }
  476. static Z80OPCODE ope_AA(Z80 *cpu) { // ind | M:4 T:16 (4, 5, 3, 4)
  477.    cpu->memptr = cpu->bc-1;
  478.    cpu->t += 8;
  479.    u8 tmp = cpu->in(cpu->bc);
  480.    cpu->MemIf->wm(cpu->hl--, tmp);
  481.    cpu->b--;
  482.    u8 ftmp = tmp + cpu->c - 1;
  483.    cpu->f = log_f[cpu->b] & ~PV;
  484.    cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV);
  485.    if(ftmp < tmp) cpu->f |= (HF | CF);
  486.    cpu->f |= (tmp & 0x80) >> 6; // NF
  487. }
  488. static Z80OPCODE ope_AB(Z80 *cpu) { // outd | M:4 T:16 (4, 5, 3, 4)
  489.    cpu->t += 8;
  490.    cpu->b--;
  491.  
  492.    u8 tmp = cpu->MemIf->rm(cpu->hl--);
  493.    cpu->out(cpu->bc, tmp);
  494.  
  495.    u8 ftmp = tmp + cpu->l;
  496.    cpu->f = log_f[cpu->b] & ~PV;
  497.    cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV);
  498.    if(ftmp < tmp) cpu->f |= (HF | CF);
  499.    cpu->f |= (tmp & 0x80) >> 6; // NF
  500.  
  501.    cpu->memptr = cpu->bc-1;
  502. }
  503. static Z80OPCODE ope_B0(Z80 *cpu) { // ldir | BC!=0 M:5 T:21 (4, 4, 3, 5, 5) | BC==0 M:4 T:16 (4, 4, 3, 5)
  504.     cpu->t += 8;
  505.     unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++);
  506.     cpu->MemIf->wm(cpu->de++, tempbyte);
  507.     tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5);
  508.     cpu->f = (cpu->f & ~(NF | HF | PV | F3 | F5)) + tempbyte;
  509.     if(--cpu->bc16)
  510.     {
  511.         cpu->f |= PV;
  512.         cpu->pc -= 2;
  513.         cpu->t += 5;
  514.         cpu->memptr = cpu->pc + 1;
  515.     }
  516. }
  517. static Z80OPCODE ope_B1(Z80 *cpu) { // cpir
  518.     cpu->memptr++;
  519.     cpu->t += 8;
  520.     unsigned char cf = cpu->f & CF;
  521.     unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++);
  522.     cpu->f = cpf8b[cpu->a * 0x100 + tempbyte] + cf;
  523.     if(--cpu->bc16)
  524.     {
  525.         cpu->f |= PV;
  526.         if(!(cpu->f & ZF))
  527.         {
  528.             cpu->pc -= 2;
  529.             cpu->t += 5;
  530.             cpu->memptr = cpu->pc + 1;
  531.         }
  532.     }
  533. }
  534. static Z80OPCODE ope_B2(Z80 *cpu) { // inir | BC!=0 M:5 T:21 (4, 5, 3, 4, 5) | BC==0 M:4 T:16 (4, 5, 3, 4)
  535.     cpu->t += 8;
  536.     cpu->memptr = cpu->bc + 1;
  537.     cpu->MemIf->wm(cpu->hl++, cpu->in(cpu->bc));
  538.     dec8(cpu, cpu->b);
  539.     if(cpu->b)
  540.     {
  541.         cpu->f |= PV;
  542.         cpu->pc -= 2;
  543.         cpu->t += 5;
  544.     }
  545.     else cpu->f &= ~PV;
  546. }
  547. static Z80OPCODE ope_B3(Z80 *cpu) { // otir | B!=0 M:5 T:21 (4, 5, 3, 4, 5) | B==0 M:4 T:16 (4, 5, 3, 4)
  548.     cpu->t += 8;
  549.     dec8(cpu, cpu->b);
  550.     cpu->out(cpu->bc, cpu->MemIf->rm(cpu->hl++));
  551.     if(cpu->b)
  552.     {
  553.         cpu->f |= PV;
  554.         cpu->pc -= 2;
  555.         cpu->t += 5;
  556.     }
  557.     else cpu->f &= ~PV;
  558.     cpu->f &= ~CF; if(!cpu->l) cpu->f |= CF;
  559.     cpu->memptr = cpu->bc + 1;
  560. }
  561. static Z80OPCODE ope_B8(Z80 *cpu) { // lddr | BC!=0 M:5 T:21 (4, 4, 3, 5, 5) | BC==0 M:4 T:16 (4, 4, 3, 5)
  562.     cpu->t += 8;
  563.     unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--);
  564.     cpu->MemIf->wm(cpu->de--, tempbyte);
  565.     tempbyte += cpu->a; tempbyte = (tempbyte & F3) | ((tempbyte << 4) & F5);
  566.     cpu->f = (cpu->f & ~(NF | HF | PV | F3 | F5)) | tempbyte;
  567.     if(--cpu->bc16)
  568.     {
  569.         cpu->f |= PV;
  570.         cpu->pc -= 2;
  571.         cpu->t += 5;
  572.         cpu->memptr = cpu->pc + 1;
  573.     }
  574. }
  575. static Z80OPCODE ope_B9(Z80 *cpu) { // cpdr
  576.     cpu->memptr--;
  577.     cpu->t += 8;
  578.     unsigned char cf = cpu->f & CF;
  579.     unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--);
  580.     cpu->f = cpf8b[cpu->a * 0x100 + tempbyte] + cf;
  581.     if(--cpu->bc16)
  582.     {
  583.         cpu->f |= PV;
  584.         if(!(cpu->f & ZF))
  585.         {
  586.             cpu->pc -= 2;
  587.             cpu->t += 5;
  588.             cpu->memptr = cpu->pc + 1;
  589.         }
  590.     }
  591. }
  592. static Z80OPCODE ope_BA(Z80 *cpu) { // indr | BC!=0 M:5 T:21 (4, 5, 3, 4, 5) | BC==0 M:4 T:16 (4, 5, 3, 4)
  593.     cpu->t += 8;
  594.     cpu->memptr = cpu->bc - 1;
  595.     cpu->MemIf->wm(cpu->hl--, cpu->in(cpu->bc));
  596.     dec8(cpu, cpu->b);
  597.     if(cpu->b)
  598.     {
  599.         cpu->f |= PV;
  600.         cpu->pc -= 2;
  601.         cpu->t += 5;
  602.     }
  603.     else cpu->f &= ~PV;
  604. }
  605. static Z80OPCODE ope_BB(Z80 *cpu) { // otdr | B!=0 M:5 T:21 (4, 5, 3, 4, 5) | B==0 M:4 T:16 (4, 5, 3, 4)
  606.    cpu->t += 8;
  607.    dec8(cpu, cpu->b);
  608.    cpu->out(cpu->bc, cpu->MemIf->rm(cpu->hl--));
  609.    if(cpu->b)
  610.    {
  611.        cpu->f |= PV;
  612.        cpu->pc -= 2;
  613.        cpu->t += 5;
  614.    }
  615.    else cpu->f &= ~PV;
  616.    cpu->f &= ~CF; if (cpu->l == 0xFF) cpu->f |= CF;
  617.    cpu->memptr = cpu->bc-1;
  618. }
  619.  
  620.  
  621. STEPFUNC const ext_opcode[0x100] = {
  622.  
  623.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  624.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  625.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  626.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  627.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  628.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  629.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  630.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  631.  
  632.    ope_40, ope_41, ope_42, ope_43, ope_44, ope_45, ope_46, ope_47,
  633.    ope_48, ope_49, ope_4A, ope_4B, ope_4C, ope_4D, ope_4E, ope_4F,
  634.    ope_50, ope_51, ope_52, ope_53, ope_54, ope_55, ope_56, ope_57,
  635.    ope_58, ope_59, ope_5A, ope_5B, ope_5C, ope_5D, ope_5E, ope_5F,
  636.    ope_60, ope_61, ope_62, ope_63, ope_64, ope_65, ope_66, ope_67,
  637.    ope_68, ope_69, ope_6A, ope_6B, ope_6C, ope_6D, ope_6E, ope_6F,
  638.    ope_70, ope_71, ope_72, ope_73, ope_74, ope_75, ope_76, ope_77,
  639.    ope_78, ope_79, ope_7A, ope_7B, ope_7C, ope_7D, ope_7E, ope_7F,
  640.  
  641.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  642.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  643.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  644.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  645.    ope_A0, ope_A1, ope_A2, ope_A3, op_00, op_00, op_00, op_00,
  646.    ope_A8, ope_A9, ope_AA, ope_AB, op_00, op_00, op_00, op_00,
  647.    ope_B0, ope_B1, ope_B2, ope_B3, op_00, op_00, op_00, op_00,
  648.    ope_B8, ope_B9, ope_BA, ope_BB, op_00, op_00, op_00, op_00,
  649.  
  650.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  651.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  652.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  653.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  654.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  655.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  656.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  657.    op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00,
  658.  
  659. };
  660.  
  661. Z80OPCODE op_ED(Z80 *cpu)
  662. {
  663.    unsigned char opcode = cpu->m1_cycle();
  664.    (ext_opcode[opcode])(cpu);
  665. }
  666. //#endif
  667.