cz80_op.c 21 KB

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