cz80_opED.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. /******************************************************************************
  2. *
  3. * CZ80 ED opcode include source file
  4. * CZ80 emulator version 0.9
  5. * Copyright 2004-2005 Stéphane Dallongeville
  6. *
  7. * (Modified by NJ)
  8. *
  9. *****************************************************************************/
  10. #if CZ80_USE_JUMPTABLE
  11. goto *JumpTableED[Opcode];
  12. #else
  13. switch (Opcode)
  14. {
  15. #endif
  16. /*-----------------------------------------
  17. ILLEGAL
  18. -----------------------------------------*/
  19. OPED(0x00):
  20. OPED(0x01):
  21. OPED(0x02):
  22. OPED(0x03):
  23. OPED(0x04):
  24. OPED(0x05):
  25. OPED(0x06):
  26. OPED(0x07):
  27. OPED(0x08):
  28. OPED(0x09):
  29. OPED(0x0a):
  30. OPED(0x0b):
  31. OPED(0x0c):
  32. OPED(0x0d):
  33. OPED(0x0e):
  34. OPED(0x0f):
  35. OPED(0x10):
  36. OPED(0x11):
  37. OPED(0x12):
  38. OPED(0x13):
  39. OPED(0x14):
  40. OPED(0x15):
  41. OPED(0x16):
  42. OPED(0x17):
  43. OPED(0x18):
  44. OPED(0x19):
  45. OPED(0x1a):
  46. OPED(0x1b):
  47. OPED(0x1c):
  48. OPED(0x1d):
  49. OPED(0x1e):
  50. OPED(0x1f):
  51. OPED(0x20):
  52. OPED(0x21):
  53. OPED(0x22):
  54. OPED(0x23):
  55. OPED(0x24):
  56. OPED(0x25):
  57. OPED(0x26):
  58. OPED(0x27):
  59. OPED(0x28):
  60. OPED(0x29):
  61. OPED(0x2a):
  62. OPED(0x2b):
  63. OPED(0x2c):
  64. OPED(0x2d):
  65. OPED(0x2e):
  66. OPED(0x2f):
  67. OPED(0x30):
  68. OPED(0x31):
  69. OPED(0x32):
  70. OPED(0x33):
  71. OPED(0x34):
  72. OPED(0x35):
  73. OPED(0x36):
  74. OPED(0x37):
  75. OPED(0x38):
  76. OPED(0x39):
  77. OPED(0x3a):
  78. OPED(0x3b):
  79. OPED(0x3c):
  80. OPED(0x3d):
  81. OPED(0x3e):
  82. OPED(0x3f):
  83. OPED(0x77):
  84. OPED(0x7f):
  85. OPED(0x80):
  86. OPED(0x81):
  87. OPED(0x82):
  88. OPED(0x83):
  89. OPED(0x84):
  90. OPED(0x85):
  91. OPED(0x86):
  92. OPED(0x87):
  93. OPED(0x88):
  94. OPED(0x89):
  95. OPED(0x8a):
  96. OPED(0x8b):
  97. OPED(0x8c):
  98. OPED(0x8d):
  99. OPED(0x8e):
  100. OPED(0x8f):
  101. OPED(0x90):
  102. OPED(0x91):
  103. OPED(0x92):
  104. OPED(0x93):
  105. OPED(0x94):
  106. OPED(0x95):
  107. OPED(0x96):
  108. OPED(0x97):
  109. OPED(0x98):
  110. OPED(0x99):
  111. OPED(0x9a):
  112. OPED(0x9b):
  113. OPED(0x9c):
  114. OPED(0x9d):
  115. OPED(0x9e):
  116. OPED(0x9f):
  117. OPED(0xa4):
  118. OPED(0xa5):
  119. OPED(0xa6):
  120. OPED(0xa7):
  121. OPED(0xac):
  122. OPED(0xad):
  123. OPED(0xae):
  124. OPED(0xaf):
  125. OPED(0xb4):
  126. OPED(0xb5):
  127. OPED(0xb6):
  128. OPED(0xb7):
  129. OPED(0xbc):
  130. OPED(0xbd):
  131. OPED(0xbe):
  132. OPED(0xbf):
  133. OPED(0xc0):
  134. OPED(0xc1):
  135. OPED(0xc2):
  136. OPED(0xc3):
  137. OPED(0xc4):
  138. OPED(0xc5):
  139. OPED(0xc6):
  140. OPED(0xc7):
  141. OPED(0xc8):
  142. OPED(0xc9):
  143. OPED(0xca):
  144. OPED(0xcb):
  145. OPED(0xcc):
  146. OPED(0xcd):
  147. OPED(0xce):
  148. OPED(0xcf):
  149. OPED(0xd0):
  150. OPED(0xd1):
  151. OPED(0xd2):
  152. OPED(0xd3):
  153. OPED(0xd4):
  154. OPED(0xd5):
  155. OPED(0xd6):
  156. OPED(0xd7):
  157. OPED(0xd8):
  158. OPED(0xd9):
  159. OPED(0xda):
  160. OPED(0xdb):
  161. OPED(0xdc):
  162. OPED(0xdd):
  163. OPED(0xde):
  164. OPED(0xdf):
  165. OPED(0xe0):
  166. OPED(0xe1):
  167. OPED(0xe2):
  168. OPED(0xe3):
  169. OPED(0xe4):
  170. OPED(0xe5):
  171. OPED(0xe6):
  172. OPED(0xe7):
  173. OPED(0xe8):
  174. OPED(0xe9):
  175. OPED(0xea):
  176. OPED(0xeb):
  177. OPED(0xec):
  178. OPED(0xed):
  179. OPED(0xee):
  180. OPED(0xef):
  181. OPED(0xf0):
  182. OPED(0xf1):
  183. OPED(0xf2):
  184. OPED(0xf3):
  185. OPED(0xf4):
  186. OPED(0xf5):
  187. OPED(0xf6):
  188. OPED(0xf7):
  189. OPED(0xf8):
  190. OPED(0xf9):
  191. OPED(0xfa):
  192. OPED(0xfb):
  193. OPED(0xfc):
  194. OPED(0xfd):
  195. OPED(0xfe):
  196. OPED(0xff):
  197. RET(4)
  198. /*-----------------------------------------
  199. LD r8
  200. -----------------------------------------*/
  201. OPED(0x47): // LD I,A
  202. zI = zA;
  203. RET(5)
  204. OPED(0x4f): // LD R,A
  205. #if CZ80_EMULATE_R_EXACTLY
  206. zR = zA;
  207. #else
  208. zR = zA - ((cycles - CPU->ICount) >> 2);
  209. #endif
  210. zR2 = zA & 0x80;
  211. RET(5)
  212. OPED(0x57): // LD A,I
  213. zA = zI;
  214. zF = (zF & CF) | SZ[zA] | zIFF2;
  215. RET(5)
  216. OPED(0x5f): // LD A,R
  217. #if CZ80_EMULATE_R_EXACTLY
  218. zA = (zR & 0x7f) | zR2;
  219. #else
  220. zA = ((zR + ((cycles - CPU->ICount) >> 2)) & 0x7f) | zR2;
  221. #endif
  222. zF = (zF & CF) | SZ[zA] | zIFF2;
  223. RET(5)
  224. /*-----------------------------------------
  225. LD r16
  226. -----------------------------------------*/
  227. OPED(0x43): // LD (w),BC
  228. data = pzBC;
  229. goto OP_LD_mNN_xx;
  230. OPED(0x53): // LD (w),DE
  231. data = pzDE;
  232. goto OP_LD_mNN_xx;
  233. OPED(0x63): // LD (w),HL
  234. data = pzHL;
  235. goto OP_LD_mNN_xx;
  236. OPED(0x73): // LD (w),SP
  237. data = pzSP;
  238. goto OP_LD_mNN_xx;
  239. OPED(0x4b): // LD BC,(w)
  240. data = pzBC;
  241. goto OP_LD_xx_mNN;
  242. OPED(0x5b): // LD DE,(w)
  243. data = pzDE;
  244. goto OP_LD_xx_mNN;
  245. OPED(0x6b): // LD HL,(w)
  246. data = pzHL;
  247. goto OP_LD_xx_mNN;
  248. OPED(0x7b): // LD SP,(w)
  249. data = pzSP;
  250. goto OP_LD_xx_mNN;
  251. /*-----------------------------------------
  252. NEG
  253. -----------------------------------------*/
  254. OPED(0x44): // NEG
  255. OPED(0x4c): // NEG
  256. OPED(0x54): // NEG
  257. OPED(0x5c): // NEG
  258. OPED(0x64): // NEG
  259. OPED(0x6c): // NEG
  260. OPED(0x74): // NEG
  261. OPED(0x7c): // NEG
  262. val = zA;
  263. zA = 0;
  264. goto OP_SUB;
  265. /*-----------------------------------------
  266. RRD
  267. -----------------------------------------*/
  268. OPED(0x67): // RRD (HL)
  269. adr = zHL;
  270. val = READ_MEM8(adr);
  271. WRITE_MEM8(adr, (val >> 4) | (zA << 4));
  272. zA = (zA & 0xf0) | (val & 0x0f);
  273. zF = (zF & CF) | SZP[zA];
  274. RET(14)
  275. /*-----------------------------------------
  276. RLD
  277. -----------------------------------------*/
  278. OPED(0x6f): // RLD (HL)
  279. adr = zHL;
  280. val = READ_MEM8(adr);
  281. WRITE_MEM8(adr, (val << 4) | (zA & 0x0f));
  282. zA = (zA & 0xf0) | (val >> 4);
  283. zF = (zF & CF) | SZP[zA];
  284. RET(14)
  285. /*-----------------------------------------
  286. ADC 16
  287. -----------------------------------------*/
  288. OPED(0x7a): // ADC HL,SP
  289. val = zSP;
  290. goto OP_ADC16;
  291. OPED(0x4a): // ADC HL,BC
  292. OPED(0x5a): // ADC HL,DE
  293. OPED(0x6a): // ADC HL,HL
  294. val = zR16((Opcode >> 4) & 3);
  295. OP_ADC16:
  296. res = zHL + val + (zF & CF);
  297. zF = (((zHL ^ res ^ val) >> 8) & HF) |
  298. ((res >> 16) & CF) |
  299. ((res >> 8) & (SF | YF | XF)) |
  300. ((res & 0xffff) ? 0 : ZF) |
  301. (((val ^ zHL ^ 0x8000) & (val ^ res) & 0x8000) >> 13);
  302. zHL = (UINT16)res;
  303. RET(11)
  304. /*-----------------------------------------
  305. SBC 16
  306. -----------------------------------------*/
  307. OPED(0x72): // SBC HL,SP
  308. val = zSP;
  309. goto OP_SBC16;
  310. OPED(0x42): // SBC HL,BC
  311. OPED(0x52): // SBC HL,DE
  312. OPED(0x62): // SBC HL,HL
  313. val = zR16((Opcode >> 4) & 3);
  314. OP_SBC16:
  315. res = zHL - val - (zF & CF);
  316. zF = (((zHL ^ res ^ val) >> 8) & HF) | NF |
  317. ((res >> 16) & CF) |
  318. ((res >> 8) & (SF | YF | XF)) |
  319. ((res & 0xffff) ? 0 : ZF) |
  320. (((val ^ zHL) & (zHL ^ res) & 0x8000) >> 13);
  321. zHL = (UINT16)res;
  322. RET(11)
  323. /*-----------------------------------------
  324. IN
  325. -----------------------------------------*/
  326. OPED(0x40): // IN B,(C)
  327. OPED(0x48): // IN C,(C)
  328. OPED(0x50): // IN D,(C)
  329. OPED(0x58): // IN E,(C)
  330. OPED(0x60): // IN H,(C)
  331. OPED(0x68): // IN L,(C)
  332. OPED(0x78): // IN E,(C)
  333. res = IN(zBC);
  334. zR8((Opcode >> 3) & 7) = res;
  335. zF = (zF & CF) | SZP[res];
  336. RET(8)
  337. OPED(0x70): // IN 0,(C)
  338. res = IN(zBC);
  339. zF = (zF & CF) | SZP[res];
  340. RET(8)
  341. /*-----------------------------------------
  342. OUT
  343. -----------------------------------------*/
  344. OPED(0x51): // OUT (C),D
  345. OPED(0x41): // OUT (C),B
  346. OPED(0x49): // OUT (C),C
  347. OPED(0x59): // OUT (C),E
  348. OPED(0x61): // OUT (C),H
  349. OPED(0x69): // OUT (C),L
  350. OPED(0x79): // OUT (C),E
  351. res = zR8((Opcode >> 3) & 7);
  352. OUT(zBC, res);
  353. RET(8)
  354. OPED(0x71): // OUT (C),0
  355. OUT(zBC, 0);
  356. RET(8)
  357. /*-----------------------------------------
  358. RETN
  359. -----------------------------------------*/
  360. OPED(0x45): // RETN;
  361. OPED(0x55): // RETN;
  362. OPED(0x65): // RETN;
  363. OPED(0x75): // RETN;
  364. POP_16(res);
  365. SET_PC(res);
  366. if (!zIFF1 && zIFF2)
  367. {
  368. zIFF1 = (1 << 2);
  369. if (CPU->IRQState)
  370. {
  371. CPU->Status |= CZ80_HAS_INT;
  372. }
  373. }
  374. else zIFF1 = zIFF2;
  375. RET(10)
  376. /*-----------------------------------------
  377. RETI
  378. -----------------------------------------*/
  379. OPED(0x4d): // RETI
  380. OPED(0x5d): // RETI
  381. OPED(0x6d): // RETI
  382. OPED(0x7d): // RETI
  383. POP_16(res);
  384. SET_PC(res);
  385. RET(10)
  386. /*-----------------------------------------
  387. IM
  388. -----------------------------------------*/
  389. OPED(0x46): // IM 0
  390. OPED(0x4e): // IM 0
  391. OPED(0x66): // IM 0
  392. OPED(0x6e): // IM 0
  393. zIM = 0;
  394. RET(4)
  395. OPED(0x56): // IM 1
  396. OPED(0x76): // IM 1
  397. zIM = 1;
  398. RET(4)
  399. OPED(0x5e): // IM 2
  400. OPED(0x7e): // IM 2
  401. zIM = 2;
  402. RET(4)
  403. {
  404. UINT8 val;
  405. UINT8 res;
  406. UINT8 F;
  407. /*-----------------------------------------
  408. LDI/LDD
  409. -----------------------------------------*/
  410. OPED(0xa0): // LDI
  411. val = READ_MEM8(zHL++);
  412. WRITE_MEM8(zDE++, val);
  413. goto OP_LDX;
  414. OPED(0xa8): // LDD
  415. val = READ_MEM8(zHL--);
  416. WRITE_MEM8(zDE--, val);
  417. OP_LDX:
  418. F = zF & (SF | ZF | CF);
  419. if ((zA + val) & 0x02) F |= YF;
  420. if ((zA + val) & 0x08) F |= XF;
  421. if (--zBC) F |= VF;
  422. zF = F;
  423. RET(12)
  424. /*-----------------------------------------
  425. LDIR/LDDR
  426. -----------------------------------------*/
  427. OPED(0xb0): // LDIR
  428. do
  429. {
  430. val = READ_MEM8(zHL++);
  431. WRITE_MEM8(zDE++, val);
  432. zBC--;
  433. USE_CYCLES(21)
  434. } while (zBC && (CPU->ICount > -4) && !CPU->Status);
  435. goto OP_LDXR;
  436. OPED(0xb8): // LDDR
  437. do
  438. {
  439. val = READ_MEM8(zHL--);
  440. WRITE_MEM8(zDE--, val);
  441. zBC--;
  442. USE_CYCLES(21)
  443. } while (zBC && (CPU->ICount > -4) && !CPU->Status);
  444. OP_LDXR:
  445. F = zF & (SF | ZF | CF);
  446. if ((zA + val) & 0x02) F |= YF;
  447. if ((zA + val) & 0x08) F |= XF;
  448. if (zBC)
  449. {
  450. zF = F | VF;
  451. PC -= 2;
  452. #if CZ80_EMULATE_R_EXACTLY
  453. zR--;
  454. #endif
  455. ADD_CYCLES(4)
  456. goto Cz80_Exec;
  457. }
  458. zF = F;
  459. ADD_CYCLES(4+5)
  460. goto Cz80_Exec;
  461. /*-----------------------------------------
  462. CPI/CPD
  463. -----------------------------------------*/
  464. OPED(0xa1): // CPI
  465. val = READ_MEM8(zHL++);
  466. goto OP_CPX;
  467. OPED(0xa9): // CPD
  468. val = READ_MEM8(zHL--);
  469. OP_CPX:
  470. res = zA - val;
  471. F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
  472. if (F & HF) res--;
  473. if (res & 0x02) F |= YF;
  474. if (res & 0x08) F |= XF;
  475. if (--zBC) F |= VF;
  476. zF = F;
  477. RET(12)
  478. /*-----------------------------------------
  479. CPIR/CPDR
  480. -----------------------------------------*/
  481. OPED(0xb1): // CPIR
  482. do
  483. {
  484. val = READ_MEM8(zHL++);
  485. res = zA - val;
  486. zBC--;
  487. F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
  488. if (F & HF) res--;
  489. if (res & 0x02) F |= YF;
  490. if (res & 0x08) F |= XF;
  491. if (zBC) F |= VF;
  492. zF = F;
  493. USE_CYCLES(21)
  494. } while (zBC && !(F & ZF) && (CPU->ICount > -4) && !CPU->Status);
  495. goto OP_CPXR;
  496. OPED(0xb9): // CPDR
  497. do
  498. {
  499. val = READ_MEM8(zHL--);
  500. res = zA - val;
  501. zBC--;
  502. F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
  503. if (F & HF) res--;
  504. if (res & 0x02) F |= YF;
  505. if (res & 0x08) F |= XF;
  506. if (zBC) F |= VF;
  507. zF = F;
  508. USE_CYCLES(21)
  509. } while (zBC && !(F & ZF) && (CPU->ICount > -4) && !CPU->Status);
  510. OP_CPXR:
  511. if (zBC && !(F & ZF))
  512. {
  513. PC -= 2;
  514. #if CZ80_EMULATE_R_EXACTLY
  515. zR--;
  516. #endif
  517. ADD_CYCLES(4)
  518. goto Cz80_Exec;
  519. }
  520. ADD_CYCLES(4+5)
  521. goto Cz80_Exec;
  522. /*-----------------------------------------
  523. INI/IND
  524. -----------------------------------------*/
  525. OPED(0xa2): // INI
  526. val = IN(zBC);
  527. zB--;
  528. WRITE_MEM8(zHL++, val);
  529. goto OP_INX;
  530. OPED(0xaa): // IND
  531. val = IN(zBC);
  532. zB--;
  533. WRITE_MEM8(zHL--, val);
  534. OP_INX:
  535. F = SZ[zB];
  536. res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
  537. if (val & SF) F |= NF;
  538. if (res < val) F |= HF | CF;
  539. F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
  540. zF = F;
  541. RET(12)
  542. /*-----------------------------------------
  543. INIR/INDR
  544. -----------------------------------------*/
  545. OPED(0xb2): // INIR
  546. do
  547. {
  548. val = IN(zBC);
  549. zB--;
  550. WRITE_MEM8(zHL++, val);
  551. USE_CYCLES(21)
  552. } while (zB && (CPU->ICount > -4) && !CPU->Status);
  553. goto OP_INXR;
  554. OPED(0xba): // INDR
  555. do
  556. {
  557. val = IN(zBC);
  558. zB--;
  559. WRITE_MEM8(zHL--, val);
  560. USE_CYCLES(21)
  561. } while (zB && (CPU->ICount > -4) && !CPU->Status);
  562. OP_INXR:
  563. F = SZ[zB];
  564. res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
  565. if (val & SF) F |= NF;
  566. if (res < val) F |= HF | CF;
  567. F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
  568. zF = F;
  569. if (zB)
  570. {
  571. PC -= 2;
  572. #if CZ80_EMULATE_R_EXACTLY
  573. zR--;
  574. #endif
  575. ADD_CYCLES(4)
  576. goto Cz80_Exec;
  577. }
  578. ADD_CYCLES(4+5);
  579. goto Cz80_Exec;
  580. /*-----------------------------------------
  581. OUTI/OUTD
  582. -----------------------------------------*/
  583. OPED(0xa3): // OUTI
  584. val = READ_MEM8(zHL++);
  585. zB--;
  586. OUT(zBC, val);
  587. goto OP_OUTX;
  588. OPED(0xab): // OUTD
  589. val = READ_MEM8(zHL--);
  590. zB--;
  591. OUT(zBC, val);
  592. OP_OUTX:
  593. F = SZ[zB];
  594. res = (UINT32)zL + (UINT32)val;
  595. if (val & SF) F |= NF;
  596. if (res < val) F |= HF | CF;
  597. F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
  598. zF = F;
  599. RET(12)
  600. /*-----------------------------------------
  601. OTIR/OTDR
  602. -----------------------------------------*/
  603. OPED(0xb3): // OTIR
  604. do
  605. {
  606. val = READ_MEM8(zHL++);
  607. zB--;
  608. OUT(zBC, val);
  609. USE_CYCLES(21)
  610. } while (zB && (CPU->ICount > -4) && !CPU->Status);
  611. goto OP_OTXR;
  612. OPED(0xbb): // OTDR
  613. do
  614. {
  615. val = READ_MEM8(zHL--);
  616. zB--;
  617. OUT(zBC, val);
  618. USE_CYCLES(21)
  619. } while (zB && (CPU->ICount > -4) && !CPU->Status);
  620. OP_OTXR:
  621. F = SZ[zB];
  622. res = (UINT32)zL + (UINT32)val;
  623. if (val & SF) F |= NF;
  624. if (res < val) F |= HF | CF;
  625. F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
  626. zF = F;
  627. if (zB)
  628. {
  629. PC -= 2;
  630. #if CZ80_EMULATE_R_EXACTLY
  631. zR--;
  632. #endif
  633. ADD_CYCLES(4)
  634. goto Cz80_Exec;
  635. }
  636. ADD_CYCLES(4+5)
  637. goto Cz80_Exec;
  638. }
  639. #if !CZ80_USE_JUMPTABLE
  640. }
  641. #endif