cz80_op.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. /******************************************************************************
  2. *
  3. * CZ80 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 *JumpTable[Opcode];
  12. #else
  13. switch (Opcode)
  14. {
  15. #endif
  16. /*-----------------------------------------
  17. NOP
  18. -----------------------------------------*/
  19. OP(0x00): // NOP
  20. /*-----------------------------------------
  21. LD r8 (same register)
  22. -----------------------------------------*/
  23. OP(0x40): // LD B,B
  24. OP(0x49): // LD C,C
  25. OP(0x52): // LD D,D
  26. OP(0x5b): // LD E,E
  27. OP(0x64): // LD H,H
  28. OP(0x6d): // LD L,L
  29. OP(0x7f): // LD A,A
  30. RET(4)
  31. /*-----------------------------------------
  32. LD r8
  33. -----------------------------------------*/
  34. OP(0x41): // LD B,C
  35. OP(0x42): // LD B,D
  36. OP(0x43): // LD B,E
  37. OP(0x44): // LD B,H
  38. OP(0x45): // LD B,L
  39. OP(0x47): // LD B,A
  40. OP(0x48): // LD C,B
  41. OP(0x4a): // LD C,D
  42. OP(0x4b): // LD C,E
  43. OP(0x4c): // LD C,H
  44. OP(0x4d): // LD C,L
  45. OP(0x4f): // LD C,A
  46. OP(0x50): // LD D,B
  47. OP(0x51): // LD D,C
  48. OP(0x53): // LD D,E
  49. OP(0x54): // LD D,H
  50. OP(0x55): // LD D,L
  51. OP(0x57): // LD D,A
  52. OP(0x58): // LD E,B
  53. OP(0x59): // LD E,C
  54. OP(0x5a): // LD E,D
  55. OP(0x5c): // LD E,H
  56. OP(0x5d): // LD E,L
  57. OP(0x5f): // LD E,A
  58. OP(0x60): // LD H,B
  59. OP(0x61): // LD H,C
  60. OP(0x62): // LD H,D
  61. OP(0x63): // LD H,E
  62. OP(0x65): // LD H,L
  63. OP(0x67): // LD H,A
  64. OP(0x68): // LD L,B
  65. OP(0x69): // LD L,C
  66. OP(0x6a): // LD L,D
  67. OP(0x6b): // LD L,E
  68. OP(0x6c): // LD L,H
  69. OP(0x6f): // LD L,A
  70. OP(0x78): // LD A,B
  71. OP(0x79): // LD A,C
  72. OP(0x7a): // LD A,D
  73. OP(0x7b): // LD A,E
  74. OP(0x7c): // LD A,H
  75. OP(0x7d): // LD A,L
  76. OP_LD_R_R:
  77. zR8((Opcode >> 3) & 7) = zR8(Opcode & 7);
  78. RET(4)
  79. OP(0x06): // LD B,#imm
  80. OP(0x0e): // LD C,#imm
  81. OP(0x16): // LD D,#imm
  82. OP(0x1e): // LD E,#imm
  83. OP(0x26): // LD H,#imm
  84. OP(0x2e): // LD L,#imm
  85. OP(0x3e): // LD A,#imm
  86. OP_LD_R_imm:
  87. zR8(Opcode >> 3) = READ_ARG();
  88. RET(7)
  89. OP(0x46): // LD B,(HL)
  90. OP(0x4e): // LD C,(HL)
  91. OP(0x56): // LD D,(HL)
  92. OP(0x5e): // LD E,(HL)
  93. OP(0x66): // LD H,(HL)
  94. OP(0x6e): // LD L,(HL)
  95. OP(0x7e): // LD A,(HL)
  96. zR8((Opcode >> 3) & 7) = READ_MEM8(zHL);
  97. RET(7)
  98. OP(0x70): // LD (HL),B
  99. OP(0x71): // LD (HL),C
  100. OP(0x72): // LD (HL),D
  101. OP(0x73): // LD (HL),E
  102. OP(0x74): // LD (HL),H
  103. OP(0x75): // LD (HL),L
  104. OP(0x77): // LD (HL),A
  105. WRITE_MEM8(zHL, zR8(Opcode & 7));
  106. RET(7)
  107. OP(0x36): // LD (HL), #imm
  108. WRITE_MEM8(zHL, READ_ARG());
  109. RET(10)
  110. OP(0x0a): // LD A,(BC)
  111. OP_LOAD_A_mBC:
  112. adr = zBC;
  113. goto OP_LOAD_A_mxx;
  114. OP(0x1a): // LD A,(DE)
  115. OP_LOAD_A_mDE:
  116. adr = zDE;
  117. OP_LOAD_A_mxx:
  118. zA = READ_MEM8(adr);
  119. RET(7)
  120. OP(0x3a): // LD A,(nn)
  121. OP_LOAD_A_mNN:
  122. adr = READ_ARG16();
  123. zA = READ_MEM8(adr);
  124. RET(13)
  125. OP(0x02): // LD (BC),A
  126. OP_LOAD_mBC_A:
  127. adr = zBC;
  128. goto OP_LOAD_mxx_A;
  129. OP(0x12): // LD (DE),A
  130. OP_LOAD_mDE_A:
  131. adr = zDE;
  132. OP_LOAD_mxx_A:
  133. WRITE_MEM8(adr, zA);
  134. RET(7)
  135. OP(0x32): // LD (nn),A
  136. OP_LOAD_mNN_A:
  137. adr = READ_ARG16();
  138. WRITE_MEM8(adr, zA);
  139. RET(13)
  140. /*-----------------------------------------
  141. LD r16
  142. -----------------------------------------*/
  143. OP(0x01): // LD BC,nn
  144. OP(0x11): // LD DE,nn
  145. OP(0x21): // LD HL,nn
  146. OP_LOAD_RR_imm16:
  147. zR16(Opcode >> 4) = READ_ARG16();
  148. RET(10)
  149. OP(0x31): // LD SP,nn
  150. OP_LOAD_SP_imm16:
  151. zSP = READ_ARG16();
  152. RET(10)
  153. OP(0xf9): // LD SP,HL
  154. OP_LD_SP_xx:
  155. zSP = data->W;
  156. RET(6)
  157. OP(0x2a): // LD HL,(nn)
  158. OP_LD_xx_mNN:
  159. adr = READ_ARG16();
  160. data->W = READ_MEM16(adr);
  161. RET(16)
  162. OP(0x22): // LD (nn),HL
  163. OP_LD_mNN_xx:
  164. adr = READ_ARG16();
  165. WRITE_MEM16(adr, data->W);
  166. RET(16)
  167. /*-----------------------------------------
  168. POP
  169. -----------------------------------------*/
  170. OP(0xf1): // POP AF
  171. OP_POP_AF:
  172. POP_16(res)
  173. zA = res >> 8;
  174. zF = res & 0xFF;
  175. RET(10)
  176. OP(0xc1): // POP BC
  177. OP(0xd1): // POP DE
  178. OP_POP_RR:
  179. data = CPU->pzR16[(Opcode >> 4) & 3];
  180. OP(0xe1): // POP HL
  181. OP_POP:
  182. POP_16(data->W)
  183. RET(10)
  184. /*-----------------------------------------
  185. PUSH
  186. -----------------------------------------*/
  187. OP(0xf5): // PUSH AF
  188. OP_PUSH_AF:
  189. PUSH_16((zA << 8) | zF);
  190. RET(11)
  191. OP(0xc5): // PUSH BC
  192. OP(0xd5): // PUSH DE
  193. OP_PUSH_RR:
  194. data = CPU->pzR16[(Opcode >> 4) & 3];
  195. OP(0xe5): // PUSH HL
  196. OP_PUSH:
  197. PUSH_16(data->W);
  198. RET(11)
  199. /*-----------------------------------------
  200. EX
  201. -----------------------------------------*/
  202. OP(0x08): // EX AF,AF'
  203. OP_EX_AF_AF2:
  204. res = zFA;
  205. zFA = zFA2;
  206. zFA2 = res;
  207. RET(4)
  208. OP(0xeb): // EX DE,HL
  209. OP_EX_DE_HL:
  210. res = zDE;
  211. zDE = zHL;
  212. zHL = res;
  213. RET(4)
  214. OP(0xd9): // EXX
  215. OP_EXX:
  216. res = zBC;
  217. zBC = zBC2;
  218. zBC2 = res;
  219. res = zDE;
  220. zDE = zDE2;
  221. zDE2 = res;
  222. res = zHL;
  223. zHL = zHL2;
  224. zHL2 = res;
  225. RET(4)
  226. OP(0xe3): // EX HL,(SP)
  227. OP_EX_xx_mSP:
  228. adr = zSP;
  229. res = data->W;
  230. data->W = READ_MEM16(adr);
  231. WRITE_MEM16(adr, res);
  232. RET(19)
  233. /*-----------------------------------------
  234. INC r8
  235. -----------------------------------------*/
  236. OP(0x04): // INC B
  237. OP(0x0c): // INC C
  238. OP(0x14): // INC D
  239. OP(0x1c): // INC E
  240. OP(0x24): // INC H
  241. OP(0x2c): // INC L
  242. OP(0x3c): // INC A
  243. OP_INC_R:
  244. zR8(Opcode >> 3)++;
  245. zF = (zF & CF) | SZHV_inc[zR8(Opcode >> 3)];
  246. RET(4)
  247. OP(0x34): // INC (HL)
  248. adr = zHL;
  249. OP_INC_m:
  250. res = READ_MEM8(adr);
  251. res = (res + 1) & 0xff;
  252. zF = (zF & CF) | SZHV_inc[res];
  253. WRITE_MEM8(adr, res);
  254. RET(11)
  255. /*-----------------------------------------
  256. DEC r8
  257. -----------------------------------------*/
  258. OP(0x05): // DEC B
  259. OP(0x0d): // DEC C
  260. OP(0x15): // DEC D
  261. OP(0x1d): // DEC E
  262. OP(0x25): // DEC H
  263. OP(0x2d): // DEC L
  264. OP(0x3d): // DEC A
  265. OP_DEC_R:
  266. zR8(Opcode >> 3)--;
  267. zF = (zF & CF) | SZHV_dec[zR8(Opcode >> 3)];
  268. RET(4)
  269. OP(0x35): // DEC (HL)
  270. adr = zHL;
  271. OP_DEC_m:
  272. res = READ_MEM8(adr);
  273. res = (res - 1) & 0xff;
  274. zF = (zF & CF) | SZHV_dec[res];
  275. WRITE_MEM8(adr, res);
  276. RET(11)
  277. /*-----------------------------------------
  278. ADD r8
  279. -----------------------------------------*/
  280. OP(0x86): // ADD A,(HL)
  281. val = READ_MEM8(zHL);
  282. USE_CYCLES(3)
  283. goto OP_ADD;
  284. OP(0xc6): // ADD A,n
  285. OP_ADD_imm:
  286. val = READ_ARG();
  287. USE_CYCLES(3)
  288. goto OP_ADD;
  289. OP(0x80): // ADD A,B
  290. OP(0x81): // ADD A,C
  291. OP(0x82): // ADD A,D
  292. OP(0x83): // ADD A,E
  293. OP(0x84): // ADD A,H
  294. OP(0x85): // ADD A,L
  295. OP(0x87): // ADD A,A
  296. OP_ADD_R:
  297. val = zR8(Opcode & 7);
  298. OP_ADD:
  299. #if CZ80_BIG_FLAGS_ARRAY
  300. {
  301. UINT16 A = zA;
  302. res = (UINT8)(A + val);
  303. zF = SZHVC_add[(A << 8) | res];
  304. zA = res;
  305. }
  306. #else
  307. res = zA + val;
  308. zF = SZ[(UINT8)res] | ((res >> 8) & CF) |
  309. ((zA ^ res ^ val) & HF) |
  310. (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5);
  311. zA = res;
  312. #endif
  313. RET(4)
  314. /*-----------------------------------------
  315. ADC r8
  316. -----------------------------------------*/
  317. OP(0x8e): // ADC A,(HL)
  318. val = READ_MEM8(zHL);
  319. USE_CYCLES(3)
  320. goto OP_ADC;
  321. OP(0xce): // ADC A,n
  322. OP_ADC_imm:
  323. val = READ_ARG();
  324. USE_CYCLES(3)
  325. goto OP_ADC;
  326. OP(0x88): // ADC A,B
  327. OP(0x89): // ADC A,C
  328. OP(0x8a): // ADC A,D
  329. OP(0x8b): // ADC A,E
  330. OP(0x8c): // ADC A,H
  331. OP(0x8d): // ADC A,L
  332. OP(0x8f): // ADC A,A
  333. OP_ADC_R:
  334. val = zR8(Opcode & 7);
  335. OP_ADC:
  336. #if CZ80_BIG_FLAGS_ARRAY
  337. {
  338. UINT8 A = zA;
  339. UINT8 c = zF & CF;
  340. res = (UINT8)(A + val + c);
  341. zF = SZHVC_add[(c << 16) | (A << 8) | res];
  342. zA = res;
  343. }
  344. #else
  345. res = zA + val + (zF & CF);
  346. zF = SZ[res & 0xff] | ((res >> 8) & CF) |
  347. ((zA ^ res ^ val) & HF) |
  348. (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5);
  349. zA = res;
  350. #endif
  351. RET(4)
  352. /*-----------------------------------------
  353. SUB r8
  354. -----------------------------------------*/
  355. OP(0x96): // SUB (HL)
  356. val = READ_MEM8(zHL);
  357. USE_CYCLES(3)
  358. goto OP_SUB;
  359. OP(0xd6): // SUB A,n
  360. OP_SUB_imm:
  361. val = READ_ARG();
  362. USE_CYCLES(3)
  363. goto OP_SUB;
  364. OP(0x90): // SUB B
  365. OP(0x91): // SUB C
  366. OP(0x92): // SUB D
  367. OP(0x93): // SUB E
  368. OP(0x94): // SUB H
  369. OP(0x95): // SUB L
  370. OP(0x97): // SUB A
  371. OP_SUB_R:
  372. val = zR8(Opcode & 7);
  373. OP_SUB:
  374. #if CZ80_BIG_FLAGS_ARRAY
  375. {
  376. UINT8 A = zA;
  377. res = (UINT8)(A - val);
  378. zF = SZHVC_sub[(A << 8) | res];
  379. zA = res;
  380. }
  381. #else
  382. res = zA - val;
  383. zF = SZ[res & 0xff] | ((res >> 8) & CF) | NF |
  384. ((zA ^ res ^ val) & HF) |
  385. (((val ^ zA) & (zA ^ res) & 0x80) >> 5);
  386. zA = res;
  387. #endif
  388. RET(4)
  389. /*-----------------------------------------
  390. SBC r8
  391. -----------------------------------------*/
  392. OP(0x9e): // SBC A,(HL)
  393. val = READ_MEM8(zHL);
  394. USE_CYCLES(3)
  395. goto OP_SBC;
  396. OP(0xde): // SBC A,n
  397. OP_SBC_imm:
  398. val = READ_ARG();
  399. USE_CYCLES(3)
  400. goto OP_SBC;
  401. OP(0x98): // SBC A,B
  402. OP(0x99): // SBC A,C
  403. OP(0x9a): // SBC A,D
  404. OP(0x9b): // SBC A,E
  405. OP(0x9c): // SBC A,H
  406. OP(0x9d): // SBC A,L
  407. OP(0x9f): // SBC A,A
  408. OP_SBC_R:
  409. val = zR8(Opcode & 7);
  410. OP_SBC:
  411. #if CZ80_BIG_FLAGS_ARRAY
  412. {
  413. UINT8 A = zA;
  414. UINT8 c = zF & CF;
  415. res = (UINT8)(A - val - c);
  416. zF = SZHVC_sub[(c << 16) | (A << 8) | res];
  417. zA = res;
  418. }
  419. #else
  420. res = zA - val - (zF & CF);
  421. zF = SZ[res & 0xff] | ((res >> 8) & CF) | NF |
  422. ((zA ^ res ^ val) & HF) |
  423. (((val ^ zA) & (zA ^ res) & 0x80) >> 5);
  424. zA = res;
  425. #endif
  426. RET(4)
  427. /*-----------------------------------------
  428. CP r8
  429. -----------------------------------------*/
  430. OP(0xbe): // CP (HL)
  431. val = READ_MEM8(zHL);
  432. USE_CYCLES(3)
  433. goto OP_CP;
  434. OP(0xfe): // CP n
  435. OP_CP_imm:
  436. val = READ_ARG();
  437. USE_CYCLES(3)
  438. goto OP_CP;
  439. OP(0xb8): // CP B
  440. OP(0xb9): // CP C
  441. OP(0xba): // CP D
  442. OP(0xbb): // CP E
  443. OP(0xbc): // CP H
  444. OP(0xbd): // CP L
  445. OP(0xbf): // CP A
  446. OP_CP_R:
  447. val = zR8(Opcode & 7);
  448. OP_CP:
  449. #if CZ80_BIG_FLAGS_ARRAY
  450. {
  451. UINT8 A = zA;
  452. res = (UINT8)(A - val);
  453. zF = (SZHVC_sub[(A << 8) | res] & ~(YF | XF)) |
  454. (val & (YF | XF));
  455. }
  456. #else
  457. res = zA - val;
  458. zF = (SZ[res & 0xff] & (SF | ZF)) |
  459. (val & (YF | XF)) | ((res >> 8) & CF) | NF |
  460. ((zA ^ res ^ val) & HF) |
  461. (((val ^ zA) & (zA ^ res) >> 5) & VF);
  462. #endif
  463. RET(4)
  464. /*-----------------------------------------
  465. AND r8
  466. -----------------------------------------*/
  467. OP(0xa6): // AND (HL)
  468. val = READ_MEM8(zHL);
  469. USE_CYCLES(3)
  470. goto OP_AND;
  471. OP(0xe6): // AND A,n
  472. OP_AND_imm:
  473. val = READ_ARG();
  474. USE_CYCLES(3)
  475. goto OP_AND;
  476. OP(0xa0): // AND B
  477. OP(0xa1): // AND C
  478. OP(0xa2): // AND D
  479. OP(0xa3): // AND E
  480. OP(0xa4): // AND H
  481. OP(0xa5): // AND L
  482. OP(0xa7): // AND A
  483. OP_AND_R:
  484. val = zR8(Opcode & 7);
  485. OP_AND:
  486. zA &= val;
  487. zF = SZP[zA] | HF;
  488. RET(4)
  489. /*-----------------------------------------
  490. XOR r8
  491. -----------------------------------------*/
  492. OP(0xae): // XOR (HL)
  493. val = READ_MEM8(zHL);
  494. USE_CYCLES(3)
  495. goto OP_XOR;
  496. OP(0xee): // XOR A,n
  497. OP_XOR_imm:
  498. val = READ_ARG();
  499. USE_CYCLES(3)
  500. goto OP_XOR;
  501. OP(0xa8): // XOR B
  502. OP(0xa9): // XOR C
  503. OP(0xaa): // XOR D
  504. OP(0xab): // XOR E
  505. OP(0xac): // XOR H
  506. OP(0xad): // XOR L
  507. OP(0xaf): // XOR A
  508. OP_XOR_R:
  509. val = zR8(Opcode & 7);
  510. OP_XOR:
  511. zA ^= val;
  512. zF = SZP[zA];
  513. RET(4)
  514. /*-----------------------------------------
  515. OR r8
  516. -----------------------------------------*/
  517. OP(0xb6): // OR (HL)
  518. val = READ_MEM8(zHL);
  519. USE_CYCLES(3)
  520. goto OP_OR;
  521. OP(0xf6): // OR A,n
  522. OP_OR_imm:
  523. val = READ_ARG();
  524. USE_CYCLES(3)
  525. goto OP_OR;
  526. OP(0xb0): // OR B
  527. OP(0xb1): // OR C
  528. OP(0xb2): // OR D
  529. OP(0xb3): // OR E
  530. OP(0xb4): // OR H
  531. OP(0xb5): // OR L
  532. OP(0xb7): // OR A
  533. OP_OR_R:
  534. val = zR8(Opcode & 7);
  535. OP_OR:
  536. zA |= val;
  537. zF = SZP[zA];
  538. RET(4)
  539. /*-----------------------------------------
  540. MISC ARITHMETIC & CPU CONTROL
  541. -----------------------------------------*/
  542. OP(0x27): // DAA
  543. OP_DAA:
  544. {
  545. UINT8 F;
  546. UINT8 cf, nf, hf, lo, hi, diff;
  547. F = zF;
  548. cf = F & CF;
  549. nf = F & NF;
  550. hf = F & HF;
  551. lo = zA & 0x0f;
  552. hi = zA >> 4;
  553. if (cf)
  554. {
  555. diff = (lo <= 9 && !hf) ? 0x60 : 0x66;
  556. }
  557. else
  558. {
  559. if (lo >= 10)
  560. {
  561. diff = hi <= 8 ? 0x06 : 0x66;
  562. }
  563. else
  564. {
  565. if (hi >= 10)
  566. {
  567. diff = hf ? 0x66 : 0x60;
  568. }
  569. else
  570. {
  571. diff = hf ? 0x06 : 0x00;
  572. }
  573. }
  574. }
  575. if (nf) zA -= diff;
  576. else zA += diff;
  577. F = SZP[zA] | (F & NF);
  578. if (cf || (lo <= 9 ? hi >= 10 : hi >= 9)) F |= CF;
  579. if (nf ? hf && lo <= 5 : lo >= 10) F |= HF;
  580. zF = F;
  581. RET(4)
  582. }
  583. OP(0x2f): // CPL
  584. OP_CPL:
  585. zA ^= 0xff;
  586. zF = (zF & (SF | ZF | PF | CF)) | HF | NF | (zA & (YF | XF));
  587. RET(4)
  588. OP(0x37): // SCF
  589. OP_SCF:
  590. zF = (zF & (SF | ZF | PF)) | CF | (zA & (YF | XF));
  591. RET(4)
  592. OP(0x3f): // CCF
  593. OP_CCF:
  594. zF = ((zF & (SF | ZF | PF | CF)) | ((zF & CF) << 4) | (zA & (YF | XF))) ^ CF;
  595. RET(4)
  596. OP(0x76): // HALT
  597. OP_HALT:
  598. CPU->Status |= CZ80_HALTED;
  599. RET(4)
  600. OP(0xf3): // DI
  601. OP_DI:
  602. zIFF = 0;
  603. USE_CYCLES(4)
  604. goto Cz80_Exec_nocheck;
  605. OP(0xfb): // EI
  606. OP_EI:
  607. USE_CYCLES(4)
  608. if (!zIFF1)
  609. {
  610. zIFF1 = zIFF2 = (1 << 2);
  611. while (GET_OP() == 0xfb)
  612. {
  613. USE_CYCLES(4)
  614. PC++;
  615. #if CZ80_EMULATE_R_EXACTLY
  616. zR++;
  617. #endif
  618. }
  619. if (CPU->IRQState)
  620. {
  621. CPU->Status |= CZ80_HAS_INT;
  622. CPU->ExtraCycles -= CPU->ICount;
  623. CPU->ICount = 0;
  624. }
  625. }
  626. else zIFF2 = (1 << 2);
  627. goto Cz80_Exec_nocheck;
  628. /*-----------------------------------------
  629. INC r16
  630. -----------------------------------------*/
  631. OP(0x03): // INC BC
  632. OP_INC_BC:
  633. zBC++;
  634. RET(6)
  635. OP(0x13): // INC DE
  636. OP_INC_DE:
  637. zDE++;
  638. RET(6)
  639. OP(0x23): // INC HL
  640. OP_INC_xx:
  641. data->W++;
  642. RET(6)
  643. OP(0x33): // INC SP
  644. OP_INC_SP:
  645. zSP++;
  646. RET(6)
  647. /*-----------------------------------------
  648. DEC r16
  649. -----------------------------------------*/
  650. OP(0x0b): // DEC BC
  651. OP_DEC_BC:
  652. zBC--;
  653. RET(6)
  654. OP(0x1b): // DEC DE
  655. OP_DEC_DE:
  656. zDE--;
  657. RET(6)
  658. OP(0x2b): // DEC HL
  659. OP_DEC_xx:
  660. data->W--;
  661. RET(6)
  662. OP(0x3b): // DEC SP
  663. OP_DEC_SP:
  664. zSP--;
  665. RET(6)
  666. /*-----------------------------------------
  667. ADD r16
  668. -----------------------------------------*/
  669. OP(0x39): // ADD xx,SP
  670. OP_ADD16_xx_SP:
  671. val = zSP;
  672. goto OP_ADD16;
  673. OP(0x29): // ADD xx,xx
  674. OP_ADD16_xx_xx:
  675. val = data->W;
  676. goto OP_ADD16;
  677. OP(0x09): // ADD xx,BC
  678. OP_ADD16_xx_BC:
  679. val = zBC;
  680. goto OP_ADD16;
  681. OP(0x19): // ADD xx,DE
  682. OP_ADD16_xx_DE:
  683. val = zDE;
  684. OP_ADD16:
  685. res = data->W + val;
  686. zF = (zF & (SF | ZF | VF)) |
  687. (((data->W ^ res ^ val) >> 8) & HF) |
  688. ((res >> 16) & CF) | ((res >> 8) & (YF | XF));
  689. data->W = (UINT16)res;
  690. RET(11)
  691. /*-----------------------------------------
  692. ROTATE
  693. -----------------------------------------*/
  694. {
  695. UINT8 A;
  696. UINT8 F;
  697. OP(0x07): // RLCA
  698. OP_RLCA:
  699. A = zA;
  700. zA = (A << 1) | (A >> 7);
  701. zF = (zF & (SF | ZF | PF)) | (zA & (YF | XF | CF));
  702. RET(4)
  703. OP(0x0f): // RRCA
  704. OP_RRCA:
  705. A = zA;
  706. F = zF;
  707. F = (F & (SF | ZF | PF)) | (A & CF);
  708. zA = (A >> 1) | (A << 7);
  709. zF = F | (zA & (YF | XF));
  710. RET(4)
  711. OP(0x17): // RLA
  712. OP_RLA:
  713. A = zA;
  714. F = zF;
  715. zA = (A << 1) | (F & CF);
  716. zF = (F & (SF | ZF | PF)) | (A >> 7) | (zA & (YF | XF));
  717. RET(4)
  718. OP(0x1f): // RRA
  719. OP_RRA:
  720. A = zA;
  721. F = zF;
  722. zA = (A >> 1) | (F << 7);
  723. zF = (F & (SF | ZF | PF)) | (A & CF) | (zA & (YF | XF));
  724. RET(4)
  725. }
  726. /*-----------------------------------------
  727. JP
  728. -----------------------------------------*/
  729. OP(0xc3): // JP nn
  730. OP_JP:
  731. res = READ_ARG16();
  732. SET_PC(res);
  733. RET(10)
  734. OP(0xc2): // JP NZ,nn
  735. OP_JP_NZ:
  736. if (!(zF & ZF)) goto OP_JP;
  737. PC += 2;
  738. RET(10)
  739. OP(0xca): // JP Z,nn
  740. OP_JP_Z:
  741. if (zF & ZF) goto OP_JP;
  742. PC += 2;
  743. RET(10)
  744. OP(0xd2): // JP NC,nn
  745. OP_JP_NC:
  746. if (!(zF & CF)) goto OP_JP;
  747. PC += 2;
  748. RET(10)
  749. OP(0xda): // JP C,nn
  750. OP_JP_C:
  751. if (zF & CF) goto OP_JP;
  752. PC += 2;
  753. RET(10)
  754. OP(0xe2): // JP PO,nn
  755. OP_JP_PO:
  756. if (!(zF & VF)) goto OP_JP;
  757. PC += 2;
  758. RET(10)
  759. OP(0xea): // JP PE,nn
  760. OP_JP_PE:
  761. if (zF & VF) goto OP_JP;
  762. PC += 2;
  763. RET(10)
  764. OP(0xf2): // JP P,nn
  765. OP_JP_P:
  766. if (!(zF & SF)) goto OP_JP;
  767. PC += 2;
  768. RET(10)
  769. OP(0xfa): // JP M,nn
  770. OP_JP_M:
  771. if (zF & SF) goto OP_JP;
  772. PC += 2;
  773. RET(10)
  774. OP(0xe9): // JP (xx)
  775. OP_JP_xx:
  776. res = data->W;
  777. SET_PC(res);
  778. RET(4)
  779. /*-----------------------------------------
  780. JR
  781. -----------------------------------------*/
  782. OP(0x10): // DJNZ n
  783. OP_DJNZ:
  784. USE_CYCLES(1)
  785. if (--zB) goto OP_JR;
  786. PC++;
  787. RET(7)
  788. OP(0x18): // JR n
  789. OP_JR:
  790. adr = (INT8)READ_ARG();
  791. PC += (INT8)adr;
  792. RET(12)
  793. OP(0x20): // JR NZ,n
  794. OP_JR_NZ:
  795. if (!(zF & ZF)) goto OP_JR;
  796. PC++;
  797. RET(7)
  798. OP(0x28): // JR Z,n
  799. OP_JR_Z:
  800. if (zF & ZF) goto OP_JR;
  801. PC++;
  802. RET(7)
  803. OP(0x38): // JR C,n
  804. OP_JR_C:
  805. if (zF & CF) goto OP_JR;
  806. PC++;
  807. RET(7)
  808. OP(0x30): // JR NC,n
  809. OP_JR_NC:
  810. if (!(zF & CF)) goto OP_JR;
  811. PC++;
  812. RET(7)
  813. /*-----------------------------------------
  814. CALL
  815. -----------------------------------------*/
  816. OP(0xcd): // CALL nn
  817. OP_CALL:
  818. res = READ_ARG16();
  819. val = zRealPC;
  820. PUSH_16(val);
  821. SET_PC(res);
  822. RET(17)
  823. OP(0xc4): // CALL NZ,nn
  824. OP_CALL_NZ:
  825. if (!(zF & ZF)) goto OP_CALL;
  826. PC += 2;
  827. RET(10)
  828. OP(0xcc): // CALL Z,nn
  829. OP_CALL_Z:
  830. if (zF & ZF) goto OP_CALL;
  831. PC += 2;
  832. RET(10)
  833. OP(0xd4): // CALL NC,nn
  834. OP_CALL_NC:
  835. if (!(zF & CF)) goto OP_CALL;
  836. PC += 2;
  837. RET(10)
  838. OP(0xdc): // CALL C,nn
  839. OP_CALL_C:
  840. if (zF & CF) goto OP_CALL;
  841. PC += 2;
  842. RET(10)
  843. OP(0xe4): // CALL PO,nn
  844. OP_CALL_PO:
  845. if (!(zF & VF)) goto OP_CALL;
  846. PC += 2;
  847. RET(10)
  848. OP(0xec): // CALL PE,nn
  849. OP_CALL_PE:
  850. if (zF & VF) goto OP_CALL;
  851. PC += 2;
  852. RET(10)
  853. OP(0xf4): // CALL P,nn
  854. OP_CALL_P:
  855. if (!(zF & SF)) goto OP_CALL;
  856. PC += 2;
  857. RET(10)
  858. OP(0xfc): // CALL M,nn
  859. OP_CALL_M:
  860. if (zF & SF) goto OP_CALL;
  861. PC += 2;
  862. RET(10)
  863. /*-----------------------------------------
  864. RET
  865. -----------------------------------------*/
  866. OP_RET_COND:
  867. USE_CYCLES(1)
  868. OP(0xc9): // RET
  869. OP_RET:
  870. POP_16(res);
  871. SET_PC(res);
  872. RET(10)
  873. OP(0xc0): // RET NZ
  874. OP_RET_NZ:
  875. if (!(zF & ZF)) goto OP_RET_COND;
  876. RET(5)
  877. OP(0xc8): // RET Z
  878. OP_RET_Z:
  879. if (zF & ZF) goto OP_RET_COND;
  880. RET(5)
  881. OP(0xd0): // RET NC
  882. OP_RET_NC:
  883. if (!(zF & CF)) goto OP_RET_COND;
  884. RET(5)
  885. OP(0xd8): // RET C
  886. OP_RET_C:
  887. if (zF & CF) goto OP_RET_COND;
  888. RET(5)
  889. OP(0xe0): // RET PO
  890. OP_RET_PO:
  891. if (!(zF & VF)) goto OP_RET_COND;
  892. RET(5)
  893. OP(0xe8): // RET PE
  894. OP_RET_PE:
  895. if (zF & VF) goto OP_RET_COND;
  896. RET(5)
  897. OP(0xf0): // RET P
  898. OP_RET_P:
  899. if (!(zF & SF)) goto OP_RET_COND;
  900. RET(5)
  901. OP(0xf8): // RET M
  902. OP_RET_M:
  903. if (zF & SF) goto OP_RET_COND;
  904. RET(5)
  905. /*-----------------------------------------
  906. RST
  907. -----------------------------------------*/
  908. OP(0xc7): // RST 0
  909. OP(0xcf): // RST 1
  910. OP(0xd7): // RST 2
  911. OP(0xdf): // RST 3
  912. OP(0xe7): // RST 4
  913. OP(0xef): // RST 5
  914. OP(0xf7): // RST 6
  915. OP(0xff): // RST 7
  916. OP_RST:
  917. res = zRealPC;
  918. PUSH_16(res);
  919. res = Opcode & 0x38;
  920. SET_PC(res);
  921. RET(11)
  922. /*-----------------------------------------
  923. OUT
  924. -----------------------------------------*/
  925. OP(0xd3): // OUT (n),A
  926. OP_OUT_mN_A:
  927. adr = (zA << 8) | READ_ARG();
  928. OUT(adr, zA);
  929. RET(11)
  930. /*-----------------------------------------
  931. IN
  932. -----------------------------------------*/
  933. OP(0xdb): // IN A,(n)
  934. OP_IN_A_mN:
  935. adr = (zA << 8) | READ_ARG();
  936. zA = IN(adr);
  937. RET(11)
  938. /*-----------------------------------------
  939. PREFIX
  940. -----------------------------------------*/
  941. OP(0xcb): // CB prefix (BIT & SHIFT INSTRUCTIONS)
  942. {
  943. UINT8 src;
  944. UINT8 res;
  945. Opcode = READ_OP();
  946. #if CZ80_EMULATE_R_EXACTLY
  947. zR++;
  948. #endif
  949. #include "cz80_opCB.c"
  950. }
  951. OP(0xed): // ED prefix
  952. ED_PREFIX:
  953. USE_CYCLES(4)
  954. Opcode = READ_OP();
  955. #if CZ80_EMULATE_R_EXACTLY
  956. zR++;
  957. #endif
  958. #include "cz80_opED.c"
  959. OP(0xdd): // DD prefix (IX)
  960. DD_PREFIX:
  961. data = pzIX;
  962. goto XY_PREFIX;
  963. OP(0xfd): // FD prefix (IY)
  964. FD_PREFIX:
  965. data = pzIY;
  966. XY_PREFIX:
  967. USE_CYCLES(4)
  968. Opcode = READ_OP();
  969. #if CZ80_EMULATE_R_EXACTLY
  970. zR++;
  971. #endif
  972. #include "cz80_opXY.c"
  973. #if !CZ80_USE_JUMPTABLE
  974. }
  975. #endif