home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2038 < prev    next >
Internet Message Format  |  1990-12-28  |  46KB

  1. From: mrapple@quack.sac.ca.us (Nick Sayer)
  2. Newsgroups: alt.sources
  3. Subject: Z-80 emulator in C with CP/M BIOS (part 2/2)
  4. Message-ID: <kDCdLS0@quack.sac.ca.us>
  5. Date: 8 Nov 90 17:18:49 GMT
  6.  
  7.  
  8. #!/bin/sh
  9. # this is foo.02 (part 2 of a multipart archive)
  10. # do not concatenate these parts, unpack them in order with /bin/sh
  11. # file z80.c continued
  12. #
  13. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  14.  then TOUCH=touch
  15.  else TOUCH=true
  16. fi
  17. if test ! -r shar3_seq_.tmp; then
  18.     echo "Please unpack part 1 first!"
  19.     exit 1
  20. fi
  21. (read Scheck
  22.  if test "$Scheck" != 2; then
  23.     echo "Please unpack part $Scheck next!"
  24.     exit 1
  25.  else
  26.     exit 0
  27.  fi
  28. ) < shar3_seq_.tmp || exit 1
  29. echo "x - Continuing file z80.c"
  30. sed 's/^X//' << 'SHAR_EOF' >> z80.c &&
  31. X
  32. X/* If last instruction was a HALT, we're out of here - NOT what a real
  33. X   Z-80 does, of course. */
  34. X  }
  35. X  while (!STOP_FLAG);
  36. X}
  37. X
  38. Xz80_instr()
  39. X{
  40. X  BYTE opcode,op_p1,op_p2,op_p3,op_p13;
  41. X
  42. X  opcode=z80_mem(PC++);
  43. X  op_p1=opcode&0x7;                /* Piece 1 - bottom 3 bits */
  44. X  op_p2=(opcode&0x38)>>3;          /* Piece 2 - middle 3 bits */
  45. X  op_p3=(opcode&0xC0)>>6;          /* Piece 3 - top 2 bits */
  46. X  op_p13=(opcode&0xC7);            /* Piece 1 and 3 OR'ed */
  47. X
  48. X/*
  49. X
  50. XNow we perform what amounts to just a bunch of ifs...
  51. X
  52. XSections noted as Z-80 only are not present on the 8080. To make
  53. Xan 8080 interpreter, comment these sections out. This is not
  54. Xstrictly necessary, however, since an 8080 program (e.g. CP/M)
  55. Xwill run just fine on a Z-80.
  56. X
  57. XFirst take care of the multi-byte opcodes. These are Z-80 only.
  58. X
  59. X*/
  60. X
  61. X  if (opcode==0xCB)
  62. X  {
  63. X    dlog("CB:");
  64. X    cb_ops(HL); /* see notes in z80_cbed.c */
  65. X    return;
  66. X  }
  67. X  if (opcode==0xFD || opcode==0xDD)
  68. X  {
  69. X    dlog(opcode==0xFD?"FD:":"DD:");
  70. X    ixy_ops(opcode==0xFD); /* pass 1 if IY */
  71. X    return;
  72. X  }
  73. X  if (opcode==0xED)
  74. X  {
  75. X    dlog("ED:");
  76. X    ed_ops();
  77. X    return;
  78. X  }
  79. X  
  80. X/*
  81. X
  82. XNOP & HALT
  83. X
  84. X*/
  85. X
  86. X  if (opcode==0x00) /* NOP */
  87. X    {
  88. X      dlog("NOP\n");
  89. X      return;
  90. X    }
  91. X
  92. X  if (opcode==0x76) /* HALT */
  93. X  {
  94. X    STOP_FLAG++;
  95. X    PC--;
  96. X    dlog("HALT\n");
  97. X    return;
  98. X  }
  99. X
  100. X/*
  101. X
  102. XInterrupt control: EI, DI
  103. X
  104. X*/
  105. X
  106. X  if (opcode==0xFB) /* EI */
  107. X  {
  108. X    INT_FLAGS|=0x20; /* counter decremented after this & next instr */
  109. X    dlog("EI\n");
  110. X    return;
  111. X  }
  112. X
  113. X  if (opcode==0xF3) /* DI */
  114. X  {
  115. X    INT_FLAGS&=~(IFF1|IFF2);
  116. X    dlog("DI\n");
  117. X    return;
  118. X  }
  119. X/*
  120. X
  121. XExchange group: EX, EXX
  122. X
  123. X*/
  124. X
  125. X  if (opcode==0x08) /* EX AF,AF' [Z-80 only] */
  126. X  {
  127. X    register WORD temp;
  128. X    temp=AF; AF=AF2; AF2=temp;
  129. X    dlog("EX AF,AF'\n");
  130. X    return;
  131. X  }
  132. X  if (opcode==0xEB) /* EX DE,HL */
  133. X  {
  134. X    register WORD temp;
  135. X    temp=DE; DE=HL; HL=temp;
  136. X    dlog("EX DE,HL\n");
  137. X    return;
  138. X  }
  139. X  if (opcode==0xE3) /* EX (SP),HL */
  140. X  {
  141. X    register WORD temp;
  142. X    temp=z80_mem(SP)|(z80_mem(SP+1)<<8);
  143. X    wr_z80_mem(SP,HL&0xff); wr_z80_mem(SP+1,HL>>8);
  144. X    HL=temp;
  145. X    dlog("EX (SP),HL\n");
  146. X    return;
  147. X  }
  148. X  if (opcode==0xD9) /* EXX [Z-80 only] */
  149. X  {
  150. X    register WORD temp;
  151. X    temp=BC; BC=BC2; BC2=temp;
  152. X    temp=DE; DE=DE2; DE2=temp;
  153. X    temp=HL; HL=HL2; HL2=temp;
  154. X    dlog("EXX\n");
  155. X    return;
  156. X  }
  157. X
  158. X/*
  159. X
  160. XExecution control: JP, JR, CALL, RET, RST
  161. X
  162. X*/
  163. X
  164. X  if (opcode==0xC3) /* JP uncond */
  165. X  {
  166. X    register WORD operand;
  167. X
  168. X    operand=z80_mem(PC++);
  169. X    operand|=z80_mem(PC++)<<8;
  170. X    PC=operand;
  171. X    dlog("JP 0x%04x\n",PC);
  172. X    return;
  173. X  }
  174. X
  175. X  if (op_p13==0xC2) /* JP conditional */
  176. X  {
  177. X    register WORD operand;
  178. X
  179. X    operand=z80_mem(PC++);
  180. X    operand|=z80_mem(PC++)<<8;
  181. X    switch(op_p2)
  182. X    {
  183. X      case 0: if (~AF&FLAG_Z)
  184. X                PC=operand;
  185. X      break;
  186. X      case 1: if (AF&FLAG_Z)
  187. X                PC=operand;
  188. X      break;
  189. X      case 2: if (~AF&FLAG_C)
  190. X                PC=operand;
  191. X      break;
  192. X      case 3: if (AF&FLAG_C)
  193. X                PC=operand;
  194. X      break;
  195. X      case 4: if (~AF&FLAG_PV)
  196. X                PC=operand;
  197. X      break;
  198. X      case 5: if (AF&FLAG_PV)
  199. X                PC=operand;
  200. X      break;
  201. X      case 6: if (~AF&FLAG_S)
  202. X                PC=operand;
  203. X      break;
  204. X      case 7: if (AF&FLAG_S)
  205. X                PC=operand;
  206. X    }   
  207. X    dlog("JP %c%c, 0x%04x\n",
  208. X     "NZ ZNC CPOPE P M"[(op_p2<<1)],
  209. X     "NZ ZNC CPOPE P M"[(op_p2<<1)+1],
  210. X     operand);
  211. X    return;
  212. X  }
  213. X
  214. X  if (opcode==0xE9) /* JP (HL) */
  215. X  {
  216. X    PC=HL;  /* The old 8080 called this instruction "PCHL" */
  217. X    dlog("JP (HL)\n");
  218. X    return;
  219. X  }
  220. X
  221. X  if (opcode==0x10) /* DJNZ [Z-80 only] */
  222. X  {
  223. X    register BYTE operand;
  224. X
  225. X    operand=z80_mem(PC++);
  226. X    BC-= 0x100;  /* B-- */
  227. X    if ( BC>>8 )
  228. X      DO_JR;
  229. X    dlog("DJNZ 0x%04x\n",PC);
  230. X    return;
  231. X  }
  232. X
  233. X  if (opcode==0x18) /* JR [Z-80 only] */
  234. X  {
  235. X    register BYTE operand;
  236. X
  237. X    operand=z80_mem(PC++);
  238. X    DO_JR;
  239. X    dlog("JR 0x%04x\n",PC);
  240. X    return;
  241. X  }
  242. X
  243. X  if ((opcode&0xE7)==0x20) /* JR cond [Z-80 only] */
  244. X  {
  245. X    register BYTE operand;
  246. X
  247. X    operand=z80_mem(PC++);
  248. X
  249. X/* if the flag in question is false and the 4th bit is false */
  250. X
  251. X#define XOR(a,b) ( (a!=0) != (b!=0) ) /* logical XOR, not standard C */
  252. X
  253. X    if ( XOR ( (AF&((opcode&0x10)?FLAG_C:FLAG_Z)) , !(opcode&0x08) ) )
  254. X      DO_JR;
  255. X    dlog("JR %d,0x%04x\n",opcode,PC);
  256. X    return;
  257. X  }
  258. X
  259. X  if (opcode==0xCD) /* CALL */
  260. X  {
  261. X    register WORD operand;
  262. X
  263. X    operand=z80_mem(PC++);
  264. X    operand|=z80_mem(PC++)<<8;
  265. X    push(PC);
  266. X    PC=operand;
  267. X    dlog("CALL 0x%04x\n",PC);
  268. X    return;
  269. X  }
  270. X
  271. X  if (op_p13==0xC4) /* CALL cond */
  272. X  {
  273. X    register WORD operand;
  274. X
  275. X    operand=z80_mem(PC++);
  276. X    operand|=z80_mem(PC++)<<8;
  277. X
  278. X    switch(op_p2)
  279. X    {
  280. X      case 0:if (~AF&FLAG_Z)
  281. X         {
  282. X           push(PC);
  283. X           PC=operand;
  284. X             }
  285. X      break;
  286. X      case 1:if (AF&FLAG_Z)
  287. X         {
  288. X           push(PC);
  289. X           PC=operand;
  290. X             }
  291. X      break;
  292. X      case 2:if (~AF&FLAG_C)
  293. X         {
  294. X           push(PC);
  295. X           PC=operand;
  296. X         }
  297. X      break;
  298. X      case 3:if (AF&FLAG_C)
  299. X         {
  300. X           push(PC);
  301. X           PC=operand;
  302. X             }
  303. X      break;
  304. X      case 4:if (~AF&FLAG_PV)
  305. X         {
  306. X           push(PC);
  307. X           PC=operand;
  308. X         }
  309. X      break;
  310. X      case 5:if (AF&FLAG_PV)
  311. X         {
  312. X           push(PC);
  313. X           PC=operand;
  314. X         }
  315. X      break;
  316. X      case 6:if (~AF&FLAG_S)
  317. X         {
  318. X           push(PC);
  319. X           PC=operand;
  320. X         }
  321. X      break;
  322. X      case 7:if (AF&FLAG_S)
  323. X         {
  324. X           push(PC);
  325. X           PC=operand;
  326. X         }
  327. X      break;
  328. X    }
  329. X    dlog("CALL %c%c, 0x%04x\n","NZ ZNC CPOPE P M"[(op_p2<<1)],
  330. X     "NZ ZNC CPOPE P M"[(op_p2<<1)+1],
  331. X     PC);    
  332. X    return;
  333. X  }
  334. X
  335. X  if (opcode==0xC9) /* RET */
  336. X  {
  337. X    PC=pop();
  338. X    dlog("RET\n");
  339. X    return;
  340. X  }
  341. X
  342. X  if (op_p13==0xC0) /* RET cond */
  343. X  {
  344. X    switch(op_p2)
  345. X    {
  346. X      case 0:if (~AF&FLAG_Z)
  347. X           PC=pop();
  348. X      break;
  349. X      case 1:if (AF&FLAG_Z)
  350. X           PC=pop();
  351. X      break;
  352. X      case 2:if (~AF&FLAG_C)
  353. X           PC=pop();
  354. X      break;
  355. X      case 3:if (AF&FLAG_C)
  356. X           PC=pop();
  357. X      break;
  358. X      case 4:if (~AF&FLAG_PV)
  359. X           PC=pop();
  360. X      break;
  361. X      case 5:if (AF&FLAG_PV)
  362. X           PC=pop();
  363. X      break;
  364. X      case 6:if (~AF&FLAG_S)
  365. X           PC=pop();
  366. X      break;
  367. X      case 7:if (AF&FLAG_S)
  368. X           PC=pop();
  369. X      break;
  370. X    }
  371. X    dlog("RET %c%c\n","NZ ZNC CPOPE P M"[op_p2<<1],
  372. X     "NZ ZNC CPOPE P M"[(op_p2<<1)+1]);
  373. X    return;
  374. X  }
  375. X
  376. X  if (op_p13==0xC7) /* RST ?? */
  377. X  {
  378. X    push(PC);
  379. X    PC=op_p2<<3;
  380. X    dlog("RST 0x%02x\n",PC);
  381. X    return;
  382. X  }
  383. X
  384. X/*
  385. X
  386. XLD
  387. X
  388. X*/
  389. X
  390. X  if (opcode==0x3A) /* LD A,(imm) */
  391. X  {
  392. X    register WORD operand;
  393. X
  394. X    operand=z80_mem(PC++);
  395. X    operand|=z80_mem(PC++)<<8;
  396. X    AF=(AF&0x00ff)|z80_mem(operand)<<8;
  397. X    dlog("LD A,(0x%04x)\n",operand);
  398. X    return;
  399. X  }
  400. X  if (opcode==0x32) /* LD (imm),A */
  401. X  {
  402. X    register WORD operand;
  403. X
  404. X    operand=z80_mem(PC++);
  405. X    operand|=z80_mem(PC++)<<8;
  406. X    wr_z80_mem(operand,AF>>8);
  407. X    dlog("LD (0x%04x),A\n",operand);
  408. X    return;
  409. X  }
  410. X  if ((opcode&0xEF)==0x0A) /* LD A,(rp) */
  411. X  {
  412. X    AF=(AF&0xff)|z80_mem((opcode&0x10)?DE:BC)<<8;
  413. X    dlog("LD A,(%s)\n",(opcode&0x10)?"DE":"BC");
  414. X    return;
  415. X  }
  416. X  if ((opcode&0xEF)==0x02) /* LD (rp),A */
  417. X  {
  418. X    wr_z80_mem((opcode&0x10)?DE:BC,AF>>8);
  419. X    dlog("LD (%s),A\n",(opcode&0x10)?"DE":"BC");
  420. X    return;
  421. X  }
  422. X  if (op_p3==0x1) /* LD reg,reg [and (HL) too] */
  423. X  {
  424. X    register BYTE value;
  425. X    switch(op_p1)
  426. X    {
  427. X      case 0:value=BC>>8;       break;
  428. X      case 1:value=BC&0xff;     break;
  429. X      case 2:value=DE>>8;       break;
  430. X      case 3:value=DE&0xff;     break;
  431. X      case 4:value=HL>>8;       break;
  432. X      case 5:value=HL&0xff;     break;
  433. X      case 6:value=z80_mem(HL); break;
  434. X      case 7:value=AF>>8;       break;
  435. X    }
  436. X    switch(op_p2)
  437. X    {
  438. X      case 0:BC=(BC&0xff)|(value<<8);  break;
  439. X      case 1:BC=(BC&0xff00)|value;     break;
  440. X      case 2:DE=(DE&0xff)|(value<<8);  break;
  441. X      case 3:DE=(DE&0xff00)|value;     break;
  442. X      case 4:HL=(HL&0xff)|(value<<8);  break;
  443. X      case 5:HL=(HL&0xff00)|value;     break;
  444. X      case 6:wr_z80_mem(HL,value);     break;
  445. X      case 7:AF=(AF&0xff)|(value<<8);  break;
  446. X    }
  447. X    dlog("LD %c,%c\n","BCDEHLMA"[op_p2],"BCDEHLMA"[op_p1]);
  448. X    return;
  449. X  }
  450. X  if (opcode==0x2A) /* LD HL,(imm) */
  451. X  {
  452. X    register WORD operand;
  453. X
  454. X    operand=z80_mem(PC++);
  455. X    operand|=z80_mem(PC++)<<8;
  456. X    HL=z80_mem(operand)|(z80_mem(operand+1)<<8);
  457. X    dlog("LD HL,(0x%04x)\n",operand);
  458. X    return;
  459. X  }
  460. X  if (opcode==0x22) /* LD (imm),HL */
  461. X  {
  462. X    register WORD operand;
  463. X
  464. X    operand=z80_mem(PC++);
  465. X    operand|=z80_mem(PC++)<<8;
  466. X    wr_z80_mem(operand,HL&0xff);
  467. X    wr_z80_mem(operand+1,HL>>8);
  468. X    dlog("LD (0x%04x),HL\n",operand);
  469. X    return;
  470. X  }
  471. X  if (op_p13==0x06) /* LD reg,imm and LD (HL),imm */
  472. X  {
  473. X    register BYTE operand;
  474. X
  475. X    operand=z80_mem(PC++);
  476. X
  477. X    switch (op_p2)
  478. X    {
  479. X      case 0:BC=(BC&0xff)|(operand<<8);
  480. X      break;
  481. X      case 1:BC=(BC&0xff00)|operand;
  482. X      break;
  483. X      case 2:DE=(DE&0xff)|(operand<<8);
  484. X      break;
  485. X      case 3:DE=(DE&0xFF00)|operand;
  486. X      break;
  487. X      case 4:HL=(HL&0xff)|(operand<<8);
  488. X      break;
  489. X      case 5:HL=(HL&0xff00)|operand;
  490. X      break;
  491. X      case 6:wr_z80_mem(HL,operand);
  492. X      break;
  493. X      case 7:AF=(AF&0xff)|(operand<<8);
  494. X      break;
  495. X    }
  496. X    dlog("LD %c,0x%x\n","BCDEHLMA"[op_p2],operand);
  497. X    return;
  498. X  }
  499. X  if ((opcode&0xCF)==0x01) /* LD rp,imm */
  500. X  {
  501. X    register WORD operand;
  502. X
  503. X    operand=z80_mem(PC++);
  504. X    operand|=z80_mem(PC++)<<8;
  505. X
  506. X    switch ((opcode&0x30)>>4)
  507. X    {
  508. X      case 0:BC=operand;
  509. X    dlog("LD BC,");
  510. X      break;
  511. X      case 1:DE=operand;
  512. X    dlog("LD DE,");
  513. X      break;
  514. X      case 2:HL=operand;
  515. X    dlog("LD HL,");
  516. X      break;
  517. X      case 3:SP=operand;
  518. X    dlog("LD SP,");
  519. X      break;
  520. X    }
  521. X    dlog("0x%04x\n",operand);
  522. X    return;
  523. X  }
  524. X  if (opcode==0xF9) /* LD SP,HL */
  525. X  {
  526. X    SP=HL;
  527. X    dlog("LD SP,HL\n");
  528. X    return;
  529. X  }
  530. X
  531. X/*
  532. X
  533. XPUSH & POP
  534. X
  535. X*/
  536. X
  537. X  if ((opcode&0xCF)==0xC5) /* PUSH rp */
  538. X  {
  539. X    switch ((opcode>>4)&3)
  540. X    {
  541. X      case 0:push(BC); break;
  542. X      case 1:push(DE); break;
  543. X      case 2:push(HL); break;
  544. X      case 3:push(AF); break;
  545. X      break;
  546. X    }
  547. X    dlog("PUSH %c%c\n","BDHA"[(opcode>>4)&3],"CELF"[(opcode>>4)&3]);
  548. X    return;
  549. X  }
  550. X
  551. X  if ((opcode&0xCF)==0xC1) /* POP rp */
  552. X  {
  553. X    switch ((opcode>>4)&3)
  554. X    {
  555. X      case 0:BC=pop(); break;
  556. X      case 1:DE=pop(); break;
  557. X      case 2:HL=pop(); break;
  558. X      case 3:AF=pop(); break;
  559. X      break;
  560. X    }
  561. X    dlog("POP %c%c\n","BDHA"[(opcode>>4)&3],"CELF"[(opcode>>4)&3]);
  562. X    return;
  563. X  }
  564. X
  565. X/*
  566. X
  567. XMATH & LOGICAL instructions
  568. X
  569. X*/
  570. X
  571. X  if (op_p13==0x03) /* 16 bit INC/DEC */
  572. X  {
  573. X    switch(op_p2>>1)
  574. X    {
  575. X      case 0:BC+=(op_p2&0x1)?-1:1;
  576. X      break;
  577. X      case 1:DE+=(op_p2&0x1)?-1:1;
  578. X      break;
  579. X      case 2:HL+=(op_p2&0x1)?-1:1;
  580. X      break;
  581. X      case 3:SP+=(op_p2&0x1)?-1:1;
  582. X      break;
  583. X    }
  584. X    dlog("%s %c%c\n",(op_p2&1)?"DEC":"INC","BDHS"[op_p2>>1],"CELP"[op_p2>>1]);
  585. X    return;
  586. X  }
  587. X
  588. X  if ((op_p13&0xFE)==0x04) /* 8 bit INC/DEC */
  589. X  {
  590. X    char temp;
  591. X    BYTE dir; WORD t;
  592. X
  593. X    temp=AF&FLAG_C; /* save carry flag */
  594. X
  595. X    dir=(op_p1&0x1)?~0:1; /* which direction? */
  596. X
  597. X    switch(op_p2)
  598. X    {
  599. X      case 0:BC=(BC&0xff)|(alu_add(BC>>8,dir)<<8);
  600. X      break;
  601. X      case 1:BC=(BC&0xff00)|alu_add(BC&0xff,dir);
  602. X      break;
  603. X      case 2:DE=(DE&0xff)|(alu_add(DE>>8,dir)<<8);
  604. X      break;
  605. X      case 3:DE=(DE&0xff00)|alu_add(DE&0xff,dir);
  606. X      break;
  607. X      case 4:HL=(HL&0xff)|(alu_add(HL>>8,dir)<<8);
  608. X      break;
  609. X      case 5:HL=(HL&0xff00)|alu_add(HL&0xff,dir);
  610. X      break;
  611. X      case 6:wr_z80_mem(HL,alu_add(z80_mem(HL),dir));
  612. X      break;
  613. X      case 7:t=alu_add(AF>>8,dir); AF&=0xff; AF|=t<<8;
  614. X      break;
  615. X    }
  616. X    AF=(AF&~FLAG_N)|((opcode&1)?FLAG_N:0);
  617. X    AF=(AF&~FLAG_C)|temp; /* restore carry flag */
  618. X    dlog("%s %c\n",(dir==1)?"INC":"DEC","BCDEHLMA"[op_p2]);
  619. X    return;
  620. X  }
  621. X
  622. X  if (op_p3==0x2) /* 8 bit ADD, ADC, SUB, SBC, AND, OR, XOR, CMP */
  623. X  {
  624. X    WORD t;
  625. X    switch(op_p2)
  626. X    {
  627. X      case 0: /* ADD */
  628. X    switch(op_p1)
  629. X    {
  630. X      case 0:t=alu_add(AF>>8,BC>>8)<<8; AF&=0xff; AF|=t;
  631. X      break;
  632. X      case 1:t=alu_add(AF>>8,BC&0xff)<<8; AF&=0xff; AF|=t;
  633. X      break;
  634. X      case 2:t=alu_add(AF>>8,DE>>8)<<8; AF&=0xff; AF|=t;
  635. X      break;
  636. X          case 3:t=alu_add(AF>>8,DE&0xff)<<8; AF&=0xff; AF|=t;
  637. X      break;
  638. X      case 4:t=alu_add(AF>>8,HL>>8)<<8; AF&=0xff; AF|=t;
  639. X      break;
  640. X      case 5:t=alu_add(AF>>8,HL&0xff)<<8; AF&=0xff; AF|=t;
  641. X      break;
  642. X      case 6:t=alu_add(AF>>8,z80_mem(HL))<<8; AF&=0xff; AF|=t;
  643. X      break;
  644. X      case 7:t=alu_add(AF>>8,AF>>8)<<8; /* Sigh */ AF&=0xff; AF|=t;
  645. X      break;
  646. X    }
  647. X    dlog("ADD %c\n","BCDEHLMA"[op_p1]);
  648. X      break;
  649. X      case 1: /* ADC */
  650. X    switch(op_p1)
  651. X    {
  652. X      case 0:t=alu_adc(AF>>8,BC>>8)<<8; AF&=0xff; AF|=t;
  653. X      break;
  654. X      case 1:t=alu_adc(AF>>8,BC&0xff)<<8; AF&=0xff; AF|=t;
  655. X      break;
  656. X      case 2:t=alu_adc(AF>>8,DE>>8)<<8; AF&=0xff; AF|=t;
  657. X      break;
  658. X          case 3:t=alu_adc(AF>>8,DE&0xff)<<8; AF&=0xff; AF|=t;
  659. X      break;
  660. X      case 4:t=alu_adc(AF>>8,HL>>8)<<8; AF&=0xff; AF|=t;
  661. X      break;
  662. X      case 5:t=alu_adc(AF>>8,HL&0xff)<<8; AF&=0xff; AF|=t;
  663. X      break;
  664. X      case 6:t=alu_adc(AF>>8,z80_mem(HL))<<8; AF&=0xff; AF|=t;
  665. X      break;
  666. X      case 7:t=alu_adc(AF>>8,AF>>8)<<8; /* Sigh */ AF&=0xff; AF|=t;
  667. X      break;
  668. X    }
  669. X    dlog("ADC %c\n","BCDEHLMA"[op_p1]);
  670. X      break;
  671. X      case 2: /* SUB */
  672. X    switch(op_p1)
  673. X    {
  674. X      case 0:t=alu_sub(AF>>8,BC>>8)<<8; AF&=0xff; AF|=t;
  675. X      break;
  676. X      case 1:t=alu_sub(AF>>8,BC&0xff)<<8; AF&=0xff; AF|=t;
  677. X      break;
  678. X      case 2:t=alu_sub(AF>>8,DE>>8)<<8; AF&=0xff; AF|=t;
  679. X      break;
  680. X          case 3:t=alu_sub(AF>>8,DE&0xff)<<8; AF&=0xff; AF|=t;
  681. X      break;
  682. X      case 4:t=alu_sub(AF>>8,HL>>8)<<8; AF&=0xff; AF|=t;
  683. X      break;
  684. X      case 5:t=alu_sub(AF>>8,HL&0xff)<<8; AF&=0xff; AF|=t;
  685. X      break;
  686. X      case 6:t=alu_sub(AF>>8,z80_mem(HL))<<8; AF&=0xff; AF|=t;
  687. X      break;
  688. X      case 7:t=alu_sub(AF>>8,AF>>8)<<8; /* Sigh */ AF&=0xff; AF|=t;
  689. X      break;
  690. X    }
  691. X    dlog("SUB %c\n","BCDEHLMA"[op_p1]);
  692. X      break;
  693. X      case 3: /* SBC */
  694. X    switch(op_p1)
  695. X    {
  696. X      case 0:t=alu_sbc(AF>>8,BC>>8)<<8; AF&=0xff; AF|=t;
  697. X      break;
  698. X      case 1:t=alu_sbc(AF>>8,BC&0xff)<<8; AF&=0xff; AF|=t;
  699. X      break;
  700. X      case 2:t=alu_sbc(AF>>8,DE>>8)<<8; AF&=0xff; AF|=t;
  701. X      break;
  702. X          case 3:t=alu_sbc(AF>>8,DE&0xff)<<8; AF&=0xff; AF|=t;
  703. X      break;
  704. X      case 4:t=alu_sbc(AF>>8,HL>>8)<<8; AF&=0xff; AF|=t;
  705. X      break;
  706. X      case 5:t=alu_sbc(AF>>8,HL&0xff)<<8; AF&=0xff; AF|=t;
  707. X      break;
  708. X      case 6:t=alu_sbc(AF>>8,z80_mem(HL))<<8; AF&=0xff; AF|=t;
  709. X      break;
  710. X      case 7:t=alu_sbc(AF>>8,AF>>8)<<8; /* Sigh */ AF&=0xff; AF|=t;
  711. X      break;
  712. X    }
  713. X    dlog("SBC %c\n","BCDEHLMA"[op_p1]);
  714. X      break;
  715. X      case 4: /* AND */
  716. X    switch (op_p1)
  717. X    {
  718. X      case 0:AF=(AF&0xff)|( ((AF>>8)&(BC>>8)) <<8 ); log_flags(AF>>8);
  719. X      break;
  720. X      case 1:AF=(AF&0xff)|( ((AF>>8)&(BC&0xff)) <<8 ); log_flags(AF>>8);
  721. X      break;
  722. X      case 2:AF=(AF&0xff)|( ((AF>>8)&(DE>>8)) <<8 ); log_flags(AF>>8);
  723. X      break;
  724. X      case 3:AF=(AF&0xff)|( ((AF>>8)&(DE&0xff)) <<8 ); log_flags(AF>>8);
  725. X      break;
  726. X      case 4:AF=(AF&0xff)|( ((AF>>8)&(HL>>8)) <<8 ); log_flags(AF>>8);
  727. X      break;
  728. X      case 5:AF=(AF&0xff)|( ((AF>>8)&(HL&0xff)) <<8 ); log_flags(AF>>8);
  729. X      break;
  730. X      case 6:AF=(AF&0xff)|( ((AF>>8)&(z80_mem(HL))) <<8 );
  731. X         log_flags(AF>>8);
  732. X      break;
  733. X      case 7:AF=(AF&0xff)|( ((AF>>8)&(AF>>8)) <<8 ); log_flags(AF>>8);
  734. X      break;
  735. X    }
  736. X    AF&=~FLAG_C;
  737. X    dlog("AND %c\n","BCDEHLMA"[op_p1]);
  738. X      break;
  739. X      case 5: /* XOR */
  740. X    switch (op_p1)
  741. X    {
  742. X      case 0:AF=(AF&0xff)|( ((AF>>8)^(BC>>8)) <<8 ); log_flags(AF>>8);
  743. X      break;
  744. X      case 1:AF=(AF&0xff)|( ((AF>>8)^(BC&0xff)) <<8 ); log_flags(AF>>8);
  745. X      break;
  746. X      case 2:AF=(AF&0xff)|( ((AF>>8)^(DE>>8)) <<8 ); log_flags(AF>>8);
  747. X      break;
  748. X      case 3:AF=(AF&0xff)|( ((AF>>8)^(DE&0xff)) <<8 ); log_flags(AF>>8);
  749. X      break;
  750. X      case 4:AF=(AF&0xff)|( ((AF>>8)^(HL>>8)) <<8 ); log_flags(AF>>8);
  751. X      break;
  752. X      case 5:AF=(AF&0xff)|( ((AF>>8)^(HL&0xff)) <<8 ); log_flags(AF>>8);
  753. X      break;
  754. X      case 6:AF=(AF&0xff)|( ((AF>>8)^(z80_mem(HL))) <<8 );
  755. X         log_flags(AF>>8);
  756. X      break;
  757. X      case 7:AF=(AF&0xff)|( ((AF>>8)^(AF>>8)) <<8 ); log_flags(AF>>8);
  758. X      break;
  759. X    }
  760. X    dlog("XOR %c\n","BCDEHLMA"[op_p1]);
  761. X    AF&=~FLAG_C;
  762. X      break;
  763. X      case 6: /* OR */
  764. X    switch (op_p1)
  765. X    {
  766. X      case 0:AF=(AF&0xff)|( ((AF>>8)|(BC>>8)) <<8 ); log_flags(AF>>8);
  767. X      break;
  768. X      case 1:AF=(AF&0xff)|( ((AF>>8)|(BC&0xff)) <<8 ); log_flags(AF>>8);
  769. X      break;
  770. X      case 2:AF=(AF&0xff)|( ((AF>>8)|(DE>>8)) <<8 ); log_flags(AF>>8);
  771. X      break;
  772. X      case 3:AF=(AF&0xff)|( ((AF>>8)|(DE&0xff)) <<8 ); log_flags(AF>>8);
  773. X      break;
  774. X      case 4:AF=(AF&0xff)|( ((AF>>8)|(HL>>8)) <<8 ); log_flags(AF>>8);
  775. X      break;
  776. X      case 5:AF=(AF&0xff)|( ((AF>>8)|(HL&0xff)) <<8 ); log_flags(AF>>8);
  777. X      break;
  778. X      case 6:AF=(AF&0xff)|( ((AF>>8)|(z80_mem(HL))) <<8 );
  779. X         log_flags(AF>>8);
  780. X      break;
  781. X      case 7:AF=(AF&0xff)|( ((AF>>8)|(AF>>8)) <<8 ); log_flags(AF>>8);
  782. X      break;
  783. X    }
  784. X    dlog("OR %c\n","BCDEHLMA"[op_p1]);
  785. X    AF&=~FLAG_C;
  786. X      break;
  787. X      case 7: /* CMP */
  788. X    switch(op_p1)
  789. X    {
  790. X      case 0:alu_sub(AF>>8,BC>>8);
  791. X      break;
  792. X      case 1:alu_sub(AF>>8,BC&0xff);
  793. X      break;
  794. X      case 2:alu_sub(AF>>8,DE>>8);
  795. X      break;
  796. X      case 3:alu_sub(AF>>8,DE&0xff);
  797. X      break;
  798. X      case 4:alu_sub(AF>>8,HL>>8);
  799. X      break;
  800. X      case 5:alu_sub(AF>>8,HL&0xff);
  801. X      break;
  802. X      case 6:alu_sub(AF>>8,z80_mem(HL));
  803. X      break;
  804. X      case 7:alu_sub(AF>>8,AF>>8); /* Sigh... What a waste */
  805. X      break;
  806. X    }
  807. X    dlog("CMP %c\n","BCDEHLMA"[op_p1]);
  808. X    }
  809. X    return;
  810. X  }
  811. X  if (op_p13==0xC6) /* 8 bit math with immediate operands. */
  812. X  {
  813. X    register BYTE operand;
  814. X    WORD t;
  815. X    
  816. X    operand=z80_mem(PC++);
  817. X
  818. X    switch(op_p2)
  819. X    {
  820. X      case 0:t=alu_add(AF>>8,operand)<<8; AF&=0xff; AF|=t;
  821. X    dlog("ADD 0x%02x\n",operand);
  822. X      break;
  823. X      case 1:t=alu_adc(AF>>8,operand)<<8; AF&=0xff; AF|=t;
  824. X    dlog("ADC 0x%02x\n",operand);
  825. X      break;
  826. X      case 2:t=alu_sub(AF>>8,operand)<<8; AF&=0xff; AF|=t;
  827. X    dlog("SUB 0x%02x\n",operand);
  828. X      break;
  829. X      case 3:t=alu_sbc(AF>>8,operand)<<8; AF&=0xff; AF|=t;
  830. X    dlog("SBC 0x%02x\n",operand);
  831. X      break;
  832. X      case 4:AF=(AF&0xff)|( ((AF>>8)&operand) <<8 ); log_flags(AF>>8);
  833. X         AF&=~FLAG_C;
  834. X    dlog("AND 0x%02x\n",operand);
  835. X      break;
  836. X      case 5:AF=(AF&0xff)|( ((AF>>8)|operand) <<8 ); log_flags(AF>>8);
  837. X         AF&=~FLAG_C;
  838. X    dlog("OR 0x%02x\n",operand);
  839. X      break;
  840. X      case 6:AF=(AF&0xff)|( ((AF>>8)^operand) <<8 ); log_flags(AF>>8);
  841. X         AF&=~FLAG_C;
  842. X    dlog("XOR 0x%02x\n",operand);
  843. X      break;
  844. X      case 7:alu_sub(AF>>8,operand);
  845. X    dlog("CMP 0x%02x\n",operand);
  846. X      break;
  847. X    }
  848. X
  849. X    return;
  850. X  }
  851. X
  852. X  if ((opcode&0xCF)==0x09) /* ADD HL,rp */
  853. X  {
  854. X    register int temp;
  855. X    
  856. X    switch ((opcode&0x30)>>4)
  857. X    {
  858. X      case 0:temp=HL+BC; break;
  859. X      case 1:temp=HL+DE; break;
  860. X      case 2:temp=HL+HL; break;
  861. X      case 3:temp=HL+SP; break;
  862. X    }
  863. X    HL=(WORD) temp;
  864. X    AF=(AF&~FLAG_C)|((temp>0xffff)?FLAG_C:0);
  865. X    AF&=~FLAG_N;
  866. X    dlog("ADD HL,%c%c\n","BDHS"[op_p2>>1],"CELP"[op_p2>>1]);
  867. X    return;
  868. X
  869. X  }
  870. X
  871. X  if (opcode==0x27) /* DAA */
  872. X  {
  873. X    WORD t;
  874. X    if ( (((AF>>8)&0xf)>9) || (AF&FLAG_H) )
  875. X      if (AF&FLAG_N)
  876. X    { t=alu_sbc(AF>>8,6)<<8;  AF&=0xff; AF|=t; }
  877. X      else
  878. X    { t=alu_add(AF>>8,6)<<8;  AF&=0xff; AF|=t; }
  879. X    if ( (AF&FLAG_C) || (((AF>>8)&0xf0)>0x90) )
  880. X      if (AF&FLAG_N)
  881. X    { t=alu_sbc(AF>>8,0x60)<<8;  AF&=0xff; AF|=t; }
  882. X      else
  883. X    { t=alu_add(AF>>8,0x60)<<8;  AF&=0xff; AF|=t; }
  884. X
  885. X    dlog("DAA\n");
  886. X    return;
  887. X  }
  888. X
  889. X/*
  890. X
  891. XROTATES
  892. X
  893. X*/
  894. X
  895. X  if ((opcode&0xE7)==0x07)
  896. X  {
  897. X    switch ((opcode&0x18)>>3)
  898. X    {
  899. X      case 0:if (AF&0x8000) /* RLCA */
  900. X           {
  901. X         AF=(AF&0xff)|((AF&0x7f00)<<1)|0x100|FLAG_C;
  902. X           }
  903. X           else
  904. X           {
  905. X         AF=(AF&0xff&~FLAG_C)|((AF&0x7f00)<<1);
  906. X           }
  907. X    dlog("RLCA\n");
  908. X      break;
  909. X      case 1:if (AF&0x100) /* RRCA */
  910. X           {
  911. X         AF=(AF&0xff)|((AF&0xfe00)>>1)|0x8000|FLAG_C;
  912. X           }
  913. X           else
  914. X           {
  915. X         AF=(AF&0xff&~FLAG_C)|((AF&0xfe00)>>1);
  916. X           }
  917. X    dlog("RRCA\n");
  918. X      break;
  919. X      case 2:if (AF&FLAG_C) /* RLA */
  920. X         {
  921. X           AF=(AF&~FLAG_C)|((AF&0x8000)?FLAG_C:0);
  922. X           AF=(AF&0xff)|((AF&0x7f00)<<1)|0x100;
  923. X         }
  924. X         else
  925. X         {
  926. X           AF=(AF&~FLAG_C)|((AF&0x8000)?FLAG_C:0);
  927. X           AF=(AF&0xff)|((AF&0x7f00)<<1);
  928. X         }
  929. X    dlog("RLA\n");
  930. X      break;
  931. X      case 3:if (AF&FLAG_C) /* RRA */
  932. X         {
  933. X           /*  clr carry  then set it if bit 0 set */
  934. X           AF=(AF&~FLAG_C)|((AF&0x100)?FLAG_C:0);
  935. X           /* set A to A>>1, then add in known carry on top */
  936. X           AF=(AF&0xff)|((AF&0xfe00)>>1)|0x8000;
  937. X         }
  938. X         else
  939. X         {
  940. X           AF=(AF&~FLAG_C)|((AF&0x100)?FLAG_C:0);
  941. X           AF=(AF&0xff)|((AF&0xfe00)>>1);
  942. X         }
  943. X    dlog("RRA\n");
  944. X      break;
  945. X    }
  946. X    AF&=~(FLAG_H|FLAG_N);    /* according to Z80 prod spec, p. 13 */
  947. X    return;
  948. X  }
  949. X
  950. X/*
  951. X
  952. XI/O
  953. X
  954. X*/
  955. X
  956. X  if (opcode==0xD3) /* OUT (port),A */
  957. X  {
  958. X    wrport(z80_mem(PC++),AF>>8);
  959. X    dlog("OUT (0x%02x),A\n",z80_mem(PC-1));
  960. X    return;
  961. X  }
  962. X
  963. X  if (opcode==0xDB) /* IN A,(port) */
  964. X  {
  965. X    AF=(AF&0xff)|rdport(z80_mem(PC++))<<8;
  966. X    dlog("IN A,(0x%02x)\n",z80_mem(PC-1));
  967. X    return;
  968. X  }
  969. X
  970. X/*
  971. X
  972. Xmisc - xCF, CPL
  973. X
  974. X*/
  975. X
  976. X  if (opcode==0x3f) /* CCF */
  977. X  {
  978. X    AF^=FLAG_C;
  979. X    AF&=~(FLAG_N);
  980. X    dlog("CCF\n");
  981. X    return;
  982. X  }
  983. X
  984. X  if (opcode==0x37) /* SCF */
  985. X  {
  986. X    AF|=FLAG_C;
  987. X    AF&=~(FLAG_N|FLAG_H);
  988. X    dlog("SCF\n");
  989. X    return;
  990. X  }
  991. X
  992. X  if (opcode==0x2f) /* CPL */
  993. X  {
  994. X    AF^=0xff00;
  995. X    AF|=FLAG_H|FLAG_N;
  996. X    dlog("CPL\n");
  997. X    return;
  998. X  }
  999. X
  1000. X/*
  1001. X
  1002. XWE SHOULD NEVER APPEAR HERE!!!!
  1003. X
  1004. XThere is no value of the first opcode byte of a Z-80 instruction that is
  1005. Xinvalid. If we get here, the above code is severely hosed.
  1006. X
  1007. X*/
  1008. X
  1009. X  printf("OH NO!!! PARSE ERROR - FIRST OPCODE BYTE!!!!!\n");
  1010. X  printf("PC = %4x  (PC) = %2x\n\n",PC-1,opcode);
  1011. X  exit(99);
  1012. X
  1013. X}
  1014. X
  1015. X/*
  1016. X
  1017. Xadditional routines:
  1018. X
  1019. Xalu_adc takes two bytes and adds them, creating the proper effect
  1020. Xon the flags register. For an add without carry, c=0. S, Z, C and H are
  1021. Xset as defined. P/V is set to indicate overflow.
  1022. X
  1023. XFor 16 bit add, lo=add(lo(a),lo(b)); hi=add(hi(a),hi(b)+((AF&FLAG_C)!=0));
  1024. XTHIS PRESUMES THAT != OPERATIONS ON YOUR COMPILER RETURN 0 OR 1!!!
  1025. X
  1026. X*/
  1027. X
  1028. XBYTE alu_adc(a,b)        /* X+Y+c... */
  1029. XWORD a,b;
  1030. X{
  1031. X    BYTE answer;
  1032. X    answer = alu_add(a,b+((AF&FLAG_C)!=0));
  1033. X    return answer;
  1034. X}
  1035. X
  1036. XBYTE alu_add(a,b)        /* essentially, X+Y, set FLAG_C as needed */
  1037. XWORD a,b;
  1038. X{
  1039. X
  1040. X  register BYTE answer=(a+b)&0xff;
  1041. X  register WORD flags=AF&0xff;
  1042. X  flags&= ~FLAG_N; /* Addition op */
  1043. X  flags=(flags&~FLAG_Z)|((answer==0)?FLAG_Z:0);
  1044. X  flags=(flags&~FLAG_S)|((answer&0x80)?FLAG_S:0);
  1045. X
  1046. X/*  For the H flag, we chop to 1 nibble each and check LSB of hi nibble
  1047. X    for carry. Yuck! */
  1048. X  flags=(flags&~FLAG_H)|( (((a&0xf)+(b&0xf))&0x10) ?FLAG_H:0);
  1049. X
  1050. X/* Bring the operands out to WORD size, add and see if the result's too big. */
  1051. X  flags=(flags&~FLAG_C)|(  ( (((WORD)a)+((WORD)b)) >0xff )  ?FLAG_C:0);
  1052. X
  1053. X/* The next one is complicated. It reads, "if the high bits of the operands
  1054. X   are the same, and the high bit of the first operand is different from
  1055. X   the high bit of the answer, overflow has occurred." Bleahack!!! */
  1056. X
  1057. X  flags=(flags&~FLAG_PV) |(( ((a>0x7f)==(b>0x7f)) && ((a>0x7f)!=(answer>0x7f)))
  1058. X               ?FLAG_PV:0);
  1059. X  AF &= 0xff00; AF |= flags;
  1060. X  return answer;
  1061. X}
  1062. X
  1063. XBYTE alu_sbc(a,b)
  1064. XBYTE a,b;
  1065. X{
  1066. X  BYTE answer;
  1067. X  AF ^= FLAG_C;
  1068. X  answer=alu_adc(a,(~b)&0xff);
  1069. X  AF ^= FLAG_C;
  1070. X  AF^=FLAG_H; /* same for half-carry */
  1071. X  AF|=FLAG_N; /* set for subtract op */
  1072. X  return answer;
  1073. X}
  1074. X
  1075. XBYTE alu_sub(a,b)
  1076. XBYTE a,b;
  1077. X{
  1078. X  BYTE answer;
  1079. X/*  AF ^= FLAG_C; */
  1080. X  answer=alu_add(a,(0xff&~b)+1);
  1081. X  AF ^= FLAG_C;
  1082. X  AF^=FLAG_H; /* same for half-carry */
  1083. X  AF|=FLAG_N; /* set for subtract op */
  1084. X  return answer;
  1085. X}
  1086. X
  1087. X/*
  1088. X
  1089. Xlog_flags - set flags after a logical operation. N & H =0, P/V set to
  1090. Xindicate parity, S with sign, and Z if zero as expected.
  1091. X
  1092. X*/
  1093. X
  1094. Xlog_flags(a)
  1095. XBYTE a;
  1096. X{
  1097. X  char count=0,i;
  1098. X
  1099. X  AF&=~(FLAG_N|FLAG_H);
  1100. X  AF=(AF&~FLAG_S)|((a&0x80)?FLAG_S:0);
  1101. X  AF=(AF&~FLAG_Z)|((a==0)?FLAG_Z:0);
  1102. X
  1103. X/*  for(i=0;i<8;i++)
  1104. X    {
  1105. X      if (a&1)
  1106. X    count++;
  1107. X      a=a>>1;
  1108. X    }
  1109. X  AF=(AF&~FLAG_PV)|((count%2)?0:FLAG_PV);
  1110. X*/
  1111. X  i = a;
  1112. X  i = (i & 0xf0) ^ ( (i&0x0f) << 4);
  1113. X  i = (i & 0xc0) ^ ( (i&0x30) << 2);
  1114. X  i = (i & 0x80) ^ ( (i&0x40) << 1);
  1115. X  AF=(AF&~FLAG_PV)|((0x80==i)?0:FLAG_PV);
  1116. X}
  1117. X
  1118. X/*
  1119. X
  1120. XStack routines
  1121. X
  1122. Xpush & pop do the obvious.
  1123. X
  1124. X*/
  1125. X
  1126. Xpush(a)
  1127. XWORD a;
  1128. X{
  1129. X  wr_z80_mem(--SP,a>>8);
  1130. X  wr_z80_mem(--SP,a&0xff);
  1131. X}
  1132. X
  1133. XWORD pop()
  1134. X{
  1135. X  register WORD temp;
  1136. X  temp=z80_mem(SP++);
  1137. X  temp|=z80_mem(SP++)<<8;
  1138. X  return temp;
  1139. X}
  1140. X
  1141. SHAR_EOF
  1142. echo "File z80.c is complete" &&
  1143. $TOUCH -am 0928182190 z80.c &&
  1144. chmod 0644 z80.c ||
  1145. echo "restore of z80.c failed"
  1146. set `wc -c z80.c`;Wc_c=$1
  1147. if test "$Wc_c" != "27243"; then
  1148.     echo original size 27243, current size $Wc_c
  1149. fi
  1150. # ============= z80.h ==============
  1151. echo "x - extracting z80.h (Text)"
  1152. sed 's/^X//' << 'SHAR_EOF' > z80.h &&
  1153. X/*
  1154. X
  1155. Xz80.h - defines for the z80 emulator.
  1156. X
  1157. XCopyright MCMXC - Nick Sayer - All rights reserved.
  1158. X
  1159. XSee COPYRIGHT file for more info.
  1160. X
  1161. X
  1162. XThere's only one configuration option. Some compilers have trouble
  1163. Xwith signed chars, and that's how we do JR, so choose one of these
  1164. Xtwo definitions to be used in the JR instructions
  1165. X
  1166. X*/
  1167. X
  1168. X    
  1169. X/* #define DO_JR PC+= (operand>127)?(-(256-operand)):(operand); */
  1170. X#define DO_JR PC+= (char) operand /* */
  1171. X/* #define DO_JR PC+= (operand>127)?256-(operand&0x7f):operand /* */
  1172. X
  1173. X/*
  1174. X
  1175. XGlobal types, data, and routines:
  1176. X
  1177. X*/
  1178. X
  1179. X#define BYTE unsigned char
  1180. X#define WORD unsigned short
  1181. X
  1182. Xextern BYTE real_z80_mem[65536];
  1183. X#define z80_mem(x) real_z80_mem[x]
  1184. X#define wr_z80_mem(x,y) debug_write(x,y)
  1185. Xextern WORD AF,BC,DE,HL,IX,IY,AF2,BC2,DE2,HL2,IR,PC,SP,INT_FLAGS;
  1186. Xextern z80_instr(),z80_run(),wrport();
  1187. Xextern BYTE rdport(),int_read();
  1188. Xextern char INT,NMI,RESET;
  1189. X
  1190. X/*
  1191. X
  1192. Xflag bits - these represent positions within the AF register.
  1193. X
  1194. X*/
  1195. X
  1196. X#define FLAG_C    0x01
  1197. X#define FLAG_N    0x02
  1198. X#define FLAG_PV    0x04
  1199. X#define FLAG_H    0x10
  1200. X#define FLAG_Z    0x40
  1201. X#define FLAG_S    0x80
  1202. X
  1203. X/*
  1204. X
  1205. XThe INT_FLAGS register doesn't really exist, we use it to store the IM status
  1206. Xand the two IFF flags.
  1207. X
  1208. XIFTMP is a counter to allow EI to take effect after the NEXT
  1209. Xinstruction.
  1210. X
  1211. X*/
  1212. X
  1213. X#define IM_STAT    0x03
  1214. X#define IFF1    0x04
  1215. X#define IFF2    0x08
  1216. X#define IFTMP    0x30
  1217. X
  1218. X/*
  1219. X
  1220. XThese routines are internal. We include it here just to keep
  1221. Xz80_cbed.c happy. Don't use 'em!!
  1222. X
  1223. X*/
  1224. X
  1225. XWORD pop();
  1226. XBYTE alu_adc(),alu_sbc(),alu_sub(),alu_add();
  1227. X
  1228. Xint dlogflag;
  1229. Xint debugflag;
  1230. Xint biosflag;
  1231. Xint TRAPval;
  1232. Xint TWRTval;
  1233. X
  1234. X#define dlog if(dlogflag) printf
  1235. X#define bioslog if(biosflag) printf
  1236. X/* static void dlog() { return; }  */
  1237. SHAR_EOF
  1238. $TOUCH -am 0928182190 z80.h &&
  1239. chmod 0644 z80.h ||
  1240. echo "restore of z80.h failed"
  1241. set `wc -c z80.h`;Wc_c=$1
  1242. if test "$Wc_c" != "1672"; then
  1243.     echo original size 1672, current size $Wc_c
  1244. fi
  1245. # ============= z80_cbed.c ==============
  1246. echo "x - extracting z80_cbed.c (Text)"
  1247. sed 's/^X//' << 'SHAR_EOF' > z80_cbed.c &&
  1248. X/*
  1249. X
  1250. Xz80_cbed.c - Z-80 microprocessor emulator, part 2.
  1251. X
  1252. XCopyright MCMXC - Nick Sayer - All rights reserved.
  1253. X
  1254. XSee COPYRIGHT file for details.
  1255. X
  1256. Xv0.0   - 04/08/90 - epoch
  1257. Xv0.0A0 - 04/13/90 - alpha-test.
  1258. Xv0.0A1 - 08/03/90 - alpha-test 2.
  1259. Xv0.0A2 - 09/04/90 - alpha-test 3.
  1260. X
  1261. XCB, ED, and DD/FD ops:
  1262. X
  1263. Xcb_ops(mem);
  1264. XWORD mem;
  1265. X
  1266. Xed_ops();
  1267. X
  1268. Xixy_ops(iy_reg);
  1269. Xchar iy_reg;
  1270. X
  1271. Xcb_ops called if first opcode byte is CB. PC points to byte after the
  1272. XCB. CB is passed the location of the "M" register. See comments before
  1273. Xcb_ops() for details.
  1274. X
  1275. Xed_ops called if first opcode byte is ED.
  1276. X
  1277. Xixy_ops similarly called if first opcode byte is DD or FD. iy_reg true for FD.
  1278. X
  1279. X*/
  1280. X
  1281. X#include "z80.h"
  1282. X
  1283. Xed_ops()
  1284. X{
  1285. X  BYTE op2,op2_p1,op2_p2,op2_p3,op2_p13;
  1286. X
  1287. X  op2=z80_mem(PC++);
  1288. X  op2_p1=op2&0x7;
  1289. X  op2_p2=(op2&0x38)>>3;
  1290. X  op2_p3=(op2&0xC0)>>6;
  1291. X  op2_p13=op2&0xC7;
  1292. X
  1293. X/* Now another horrendous if statement string... */
  1294. X
  1295. X  if (op2_p13==0x42) /* SBC/ADC HL,rp */
  1296. X  {
  1297. X    register WORD temp,temp2,sub_flag=0;
  1298. X
  1299. X    switch(op2_p2)
  1300. X    {
  1301. X      case 0:temp=BC; sub_flag++; break;
  1302. X      case 1:temp=BC;             break;
  1303. X      case 2:temp=DE; sub_flag++; break;
  1304. X      case 3:temp=DE;          break;
  1305. X      case 4:temp=HL; sub_flag++; break;
  1306. X      case 5:temp=HL;          break;
  1307. X      case 6:temp=SP; sub_flag++; break;
  1308. X      case 7:temp=SP;          break;
  1309. X    }
  1310. X    if (sub_flag)
  1311. X    {
  1312. X      temp2=alu_sbc(HL&0xff,temp&0xff);
  1313. X      AF^=FLAG_C; /* proper chaining! */
  1314. X      HL=temp2|(alu_sbc(HL>>8,(temp>>8))<<8);
  1315. X    }
  1316. X    else
  1317. X    {
  1318. X      temp2=alu_adc(HL&0xff,temp&0xff);
  1319. X      HL=temp2|(alu_adc(HL>>8,temp>>8)<<8);
  1320. X    }
  1321. X    return;
  1322. X  }
  1323. X
  1324. X  if (op2_p13==0x43) /* LD (imm),rp & rp,(imm) */
  1325. X  {
  1326. X    register WORD operand;
  1327. X
  1328. X    operand=z80_mem(PC++);
  1329. X    operand|=z80_mem(PC++)<<8;
  1330. X    switch(op2_p2)
  1331. X    {
  1332. X      case 0:wr_z80_mem(operand,BC&0xff); wr_z80_mem(operand+1,BC>>8); break;
  1333. X      case 1:BC=z80_mem(operand)|(z80_mem(operand+1)<<8); break;
  1334. X      case 2:wr_z80_mem(operand,DE&0xff); wr_z80_mem(operand+1,DE>>8); break;
  1335. X      case 3:DE=z80_mem(operand)|(z80_mem(operand+1)<<8); break;
  1336. X      case 4:wr_z80_mem(operand,HL&0xff); wr_z80_mem(operand+1,HL>>8); break;
  1337. X      case 5:HL=z80_mem(operand)|(z80_mem(operand+1)<<8); break;
  1338. X      case 6:wr_z80_mem(operand,SP&0xff); wr_z80_mem(operand+1,SP>>8); break;
  1339. X      case 7:SP=z80_mem(operand)|(z80_mem(operand+1)<<8); break;
  1340. X    }
  1341. X    return;
  1342. X  }
  1343. X
  1344. X  if ((op2&0xF7)==0x67) /* RLD or RRD */
  1345. X  {
  1346. X    register BYTE temp;
  1347. X
  1348. X    if (op2&0x8)
  1349. X    {
  1350. X      temp=z80_mem(HL)>>4;
  1351. X      wr_z80_mem(HL,(z80_mem(HL)<<4)|((AF&0x0f00)>>8));
  1352. X      AF=(AF&0xf0ff)|(temp<<8);
  1353. X    }
  1354. X    else
  1355. X    {
  1356. X      temp=z80_mem(HL)&0xf;
  1357. X      wr_z80_mem(HL,(z80_mem(HL)>>4)|((AF&0x0f00)>>4));
  1358. X      AF=(AF&0xf0ff)|(temp<<8);
  1359. X    }
  1360. X    log_flags(AF>>8);
  1361. X
  1362. X    return;
  1363. X  }
  1364. X
  1365. X  if (op2_p13==0x40) /* IN reg,(C) */
  1366. X  {
  1367. X    switch (op2_p2)
  1368. X    {
  1369. X      case 0:BC=(HL&0xff)|(rdport(BC&0xff)<<8); break;
  1370. X      case 1:BC=(BC&0xff00)|rdport(BC&0xff);    break;
  1371. X      case 2:DE=(DE&0xff)|(rdport(BC&0xff)<<8); break;
  1372. X      case 3:DE=(DE&0xff00)|rdport(DE&0xff);    break;
  1373. X      case 4:HL=(HL&0xff)|(rdport(BC&0xff)<<8); break;
  1374. X      case 5:HL=(HL&0xff00)|rdport(BC&0xff);    break;
  1375. X      case 6:wr_z80_mem(HL,rdport(BC&0xff));   break;/* is this REALLY true? */
  1376. X      case 7:AF=(AF&0xFF)|(rdport(BC&0xff)<<8); break;
  1377. X    }
  1378. X    return;
  1379. X  }
  1380. X
  1381. X  if (op2_p13==0x41) /* OUT (C),reg */
  1382. X  {
  1383. X    switch (op2_p2)
  1384. X    {
  1385. X      case 0:wrport(BC&0xff,BC>>8);       break;
  1386. X      case 1:wrport(BC&0xff,BC&0xff);     break;
  1387. X      case 2:wrport(BC&0xff,DE>>8);       break;
  1388. X      case 3:wrport(BC&0xff,DE&0xff);     break;
  1389. X      case 4:wrport(BC&0xff,HL>>8);       break;
  1390. X      case 5:wrport(BC&0xff,HL&0xff);     break;
  1391. X      case 6:wrport(BC&0xff,z80_mem(HL)); break; /* Is this REALLY true? */
  1392. X      case 7:wrport(BC&0xff,AF>>8);       break;
  1393. X    }
  1394. X    return;
  1395. X  }
  1396. X
  1397. X  if (op2==0x44) /* NEG */
  1398. X  {
  1399. X    WORD t;
  1400. X    t=alu_sub(0,AF>>8)<<8; AF&=0xff; AF|=t;
  1401. X    return;
  1402. X  }
  1403. X
  1404. X  if (op2==0x45) /* RETN */
  1405. X  {
  1406. X     /* restore IFF1 from IFF2 */
  1407. X    INT_FLAGS=(INT_FLAGS&~IFF1)|((INT_FLAGS&IFF2)?IFF1:0);
  1408. X    PC=pop();
  1409. X    return;
  1410. X  }
  1411. X
  1412. X  if (op2==0x4D) /* RETI */
  1413. X  {
  1414. X    PC=pop();
  1415. X    return;
  1416. X  }
  1417. X
  1418. X  if ((op2&0xE7)==0x46) /* IM ? */
  1419. X  {
  1420. X    INT_FLAGS&=~IM_STAT;
  1421. X    switch ((op2&0x18)>>3)
  1422. X    {
  1423. X      case 0: /* IM 0 - we're done! */
  1424. X      break;
  1425. X      case 2:INT_FLAGS|=1; /* IM 1 - perverse, isn't it? */
  1426. X      break;
  1427. X      case 3:INT_FLAGS|=2; /* IM 2 */
  1428. X    }
  1429. X    return;
  1430. X  }
  1431. X
  1432. X  if ((op2&0xE7)==0x47) /* moves involving I & R */
  1433. X  {
  1434. X    switch((op2&0x10)>>4) /* which way? */
  1435. X    {
  1436. X      case 1:switch ((op2&0x8)>>3) /* which reg? */
  1437. X         {
  1438. X           case 0:AF=(AF&0xff)|(IR&0xff00); break;  /* A,I */
  1439. X           case 1:AF=(AF&0xff)|(IR<<8);     break;  /* A,R */
  1440. X         }
  1441. X         AF=(AF&~(FLAG_H|FLAG_N));
  1442. X         AF=(AF&~FLAG_PV)|((INT_FLAGS&IFF1)?FLAG_PV:0);
  1443. X         AF=(AF&~FLAG_S)|((AF&0x8000)?FLAG_S:0);
  1444. X         AF=(AF&~FLAG_Z)|(((AF>>8)==0)?FLAG_Z:0);
  1445. X      break;
  1446. X      case 0:switch ((op2&0x8)>>3)
  1447. X             {
  1448. X           case 0:IR=(IR&0xff)|(AF&0xff00); break; /* I,A */
  1449. X           case 1:IR=(IR&0xff00)|(AF>>8);   break; /* R,A */
  1450. X         }
  1451. X      break;
  1452. X    }
  1453. X    return;
  1454. X  }
  1455. X
  1456. X/*
  1457. X
  1458. X{LD,CP,OT,IN}[ID][R] instructions (e.g. LDIR, OTD, etc)
  1459. X
  1460. X*/
  1461. X
  1462. X  if ((op2&0xE4)==0xA0)
  1463. X  {
  1464. X    register BYTE dir;
  1465. X    register BYTE repeat;
  1466. X
  1467. X    dir=op2&0x8;
  1468. X    repeat=op2&0x10;
  1469. X    switch (op2&3)
  1470. X    {
  1471. X      case 0:wr_z80_mem(DE,z80_mem(HL));
  1472. X         if (dir)
  1473. X           DE--,HL--;
  1474. X         else
  1475. X           DE++,HL++;
  1476. X             BC--;
  1477. X         AF=AF&~(FLAG_N|FLAG_H);
  1478. X         AF=(AF&FLAG_PV)|((BC==0)?FLAG_PV:0);
  1479. X         if (repeat && BC)
  1480. X           PC-= 2;
  1481. X      break;
  1482. X      case 1:alu_sbc(AF>>8,z80_mem(HL));
  1483. X         if (dir)
  1484. X           HL--;
  1485. X             else
  1486. X           HL++;
  1487. X             BC--;
  1488. X         AF=(AF&FLAG_PV)|((BC==0)?FLAG_PV:0);
  1489. X         if (repeat && BC && !(AF&FLAG_Z))
  1490. X           PC-= 2;
  1491. X      break;
  1492. X      case 2:wr_z80_mem(HL,rdport(BC&0xff));
  1493. X         if (dir)
  1494. X           HL--;
  1495. X             else
  1496. X           HL++;
  1497. X             BC-=0x100;
  1498. X         AF=FLAG_N|(AF&FLAG_Z)|(((BC>>8)==0)?FLAG_Z:0);
  1499. X         if (repeat && (BC>>8))
  1500. X           PC-= 2;
  1501. X      break;
  1502. X      case 3:wrport(BC&0xff,z80_mem(HL));
  1503. X         if (dir)
  1504. X           HL--;
  1505. X         else
  1506. X           HL++;
  1507. X             BC-= 0x100;
  1508. X         AF=FLAG_N|(AF&FLAG_Z)|(((BC>>8)==0)?FLAG_Z:0);
  1509. X         if (repeat && (BC>>8))
  1510. X           PC-= 2;
  1511. X      break;
  1512. X    }
  1513. X    return;
  1514. X  }
  1515. X
  1516. X/* I don't know if there are any unparsable ED ops or not. If
  1517. X   we get here, crash'n'burn */
  1518. X
  1519. X   printf("OH NO!!!!! PARSE ERROR - 2nd opcode - ED ops\n");
  1520. X   printf("PC = %4x  (PC) = %2x\n\n",PC-1,op2);
  1521. X   exit(99);
  1522. X
  1523. X}
  1524. X
  1525. X/*
  1526. X
  1527. XCB operations can also be activated with index registers, e.g.
  1528. XBIT 0,(IY+5). The opcodes for this are FD CB 05 46. In machine-type
  1529. Xlanguage, this says "use index register IY+5 instead of HL for
  1530. Xthe operation "CB 46". The operation "CB 46" says BIT 6,(HL). This
  1531. Xis in fact how all the index operations work. The opcode after
  1532. XFD/ED relates in some way to (HL). Its just as easy to rewrite
  1533. Xthe small portion of the opcode table relating to index registers
  1534. Xin this file, but for CB ops, it's just easier to pass the
  1535. Xaddress to the CB parser it should use if (HL) is referred to.
  1536. XIf we are parsing a straight CB op, this routine is called
  1537. Xwith the contents of HL. If it's an FD/ED op, we call it with
  1538. XIX/IY + d. Calling this number "mem" is a throwback to the 8080.
  1539. X(HL) was called "M" the meta-register "memory." LD A,(HL) was written
  1540. X"MOV A,M". That sort of thing can be seen all over in the opcode
  1541. Xtable - especially the math and load ops. register "M" was number 6 in
  1542. Xthe numbering scheme (BCDEHLMA).
  1543. X
  1544. XThe problem with doing this is that if we're passed a CB op from the
  1545. XFD/ED parser, and that op doesn't refer to mem, it will act as if the
  1546. Xindex register is not involved. But such an op would have unpredictable
  1547. Xresults on a real Z-80 anyway. fnord.
  1548. X
  1549. X*/
  1550. X
  1551. Xcb_ops(mem)
  1552. XWORD mem;
  1553. X{
  1554. X  register BYTE op2,op_typ,op_reg;
  1555. X
  1556. X  op2=z80_mem(PC++);
  1557. X  op_typ=(op2&0x38)>>3;
  1558. X  op_reg=op2&0x7;
  1559. X
  1560. X/* And off we go again... */
  1561. X
  1562. X  switch((op2&0xC0)>>6)
  1563. X  {
  1564. X    case 1: /* BIT */
  1565. X      switch(op_reg)
  1566. X      {
  1567. X    case 0:AF=(AF&~FLAG_Z)|((BC&(1<<(op_typ+8)))?0:FLAG_Z);       break;
  1568. X    case 1:AF=(AF&~FLAG_Z)|((BC&(1<<op_typ))?0:FLAG_Z);           break;
  1569. X    case 2:AF=(AF&~FLAG_Z)|((DE&(1<<(op_typ+8)))?0:FLAG_Z);       break;
  1570. X    case 3:AF=(AF&~FLAG_Z)|((DE&(1<<op_typ))?0:FLAG_Z);           break;
  1571. X    case 4:AF=(AF&~FLAG_Z)|((HL&(1<<(op_typ+8)))?0:FLAG_Z);       break;
  1572. X    case 5:AF=(AF&~FLAG_Z)|((HL&(1<<op_typ))?0:FLAG_Z);           break;
  1573. X    case 6:AF=(AF&~FLAG_Z)|((z80_mem(mem)&(1<<op_typ))?0:FLAG_Z); break;
  1574. X    case 7:AF=(AF&~FLAG_Z)|((AF&(1<<(op_typ+8)))?0:FLAG_Z);       break;
  1575. X      }
  1576. X      AF|=FLAG_H;
  1577. X      AF&=~FLAG_N;
  1578. X    break;
  1579. X    case 2: /* RES */
  1580. X      switch(op_reg)
  1581. X      {
  1582. X    case 0:BC&=~(1<<(op_typ+8));        break;
  1583. X    case 1:BC&=~(1<<op_typ);            break;
  1584. X    case 2:DE&=~(1<<(op_typ+8));        break;
  1585. X    case 3:DE&=~(1<<op_typ);            break;
  1586. X    case 4:HL&=~(1<<(op_typ+8));        break;
  1587. X    case 5:HL&=~(1<<op_typ);            break;
  1588. X    case 6:wr_z80_mem(mem,z80_mem(mem)&~(1<<op_typ));  break;
  1589. X    case 7:AF&=~(1<<(op_typ+8));        break;
  1590. X      }
  1591. X    break;
  1592. X    case 3: /* SET */
  1593. X      switch(op_reg)
  1594. X      {
  1595. X    case 0:BC|=1<<(op_typ+8);       break;
  1596. X    case 1:BC|=1<<op_typ;           break;
  1597. X    case 2:DE|=1<<(op_typ+8);       break;
  1598. X    case 3:DE|=1<<op_typ;           break;
  1599. X    case 4:HL|=1<<(op_typ+8);       break;
  1600. X    case 5:HL|=1<<op_typ;           break;
  1601. X    case 6:wr_z80_mem(mem,z80_mem(mem)|1<<op_typ); break;
  1602. X    case 7:AF|=1<<(op_typ+8);       break;
  1603. X      }
  1604. X    break;
  1605. X    case 0: /* Additional rotate/shift section */
  1606. X    {
  1607. X      register BYTE temp,temp2;
  1608. X
  1609. X      switch(op_reg) /* get it out */
  1610. X      {
  1611. X    case 0:temp=((BC&0xff00)>>8); break;
  1612. X    case 1:temp=BC&0xff;          break;
  1613. X    case 2:temp=((DE&0xff00)>>8); break;
  1614. X    case 3:temp=DE&0xff;          break;
  1615. X    case 4:temp=((HL&0xff00)>>8); break;
  1616. X    case 5:temp=HL&0xff;          break;
  1617. X    case 6:temp=z80_mem(mem);     break;
  1618. X    case 7:temp=((AF&0xff00)>>8); break;
  1619. X      }
  1620. X      switch(op_typ)
  1621. X      {
  1622. X    case 0: /* RLC */
  1623. X           temp=(temp<<1)|((temp&0x80)?1:0);
  1624. X           log_flags(temp);
  1625. X           AF=(AF&~FLAG_C)|((temp&1)?FLAG_C:0);
  1626. X        break;
  1627. X        case 1: /* RRC */
  1628. X           temp=(temp>>1)|((temp&1)?0x80:0);
  1629. X           log_flags(temp);
  1630. X           AF=(AF&~FLAG_C)|((temp&0x80)?FLAG_C:0);
  1631. X    break;
  1632. X        case 2: /* RL */
  1633. X           temp2=temp&0x80;
  1634. X           temp=(temp<<1)|((AF&FLAG_C)?1:0);
  1635. X           log_flags(temp);
  1636. X           AF=(AF&~FLAG_C)|(temp2?FLAG_C:0);
  1637. X        break;
  1638. X        case 3: /* RR */
  1639. X           temp2=temp&0x1;
  1640. X           temp=(temp>>1)|((AF&FLAG_C)?0x80:0);
  1641. X           log_flags(temp);
  1642. X           AF=(AF&~FLAG_C)|(temp2?FLAG_C:0);
  1643. X        break;
  1644. X        case 4: /* SLA */
  1645. X           AF=(AF&~FLAG_C)|((temp&0x80)?FLAG_C:0);
  1646. X           temp=temp<<1;
  1647. X           log_flags(temp);
  1648. X        break;
  1649. X        case 5: /* SRA */
  1650. X           AF=(AF&~FLAG_C)|((temp&1)?FLAG_C:0);
  1651. X           temp=(temp>>1)|((temp&0x80)?0x80:0);
  1652. X           log_flags(temp);
  1653. X        break;
  1654. X        case 6: /* NOT USED - NOP */
  1655. X        break;
  1656. X    case 7: /* SRL */
  1657. X           AF=(AF&~FLAG_C)|((temp&1)?FLAG_C:0);
  1658. X           temp=temp>>1;
  1659. X           log_flags(temp);
  1660. X        break;
  1661. X      }
  1662. X      switch(op_reg) /* put it back */
  1663. X      {
  1664. X    case 0:BC=(BC&0xff)|(temp<<8); break;
  1665. X    case 1:BC=(BC&0xff00)|temp;    break;
  1666. X    case 2:DE=(DE&0xff)|(temp<<8); break;
  1667. X    case 3:DE=(DE&0xff00)|temp;    break;
  1668. X    case 4:HL=(HL&0xff)|(temp<<8); break;
  1669. X    case 5:HL=(HL&0xff00)|temp;    break;
  1670. X    case 6:wr_z80_mem(mem,temp);   break;
  1671. X    case 7:AF=(AF&0xff)|(temp<<8); break;
  1672. X      }
  1673. X    }
  1674. X    break;
  1675. X  }
  1676. X
  1677. X/* This parser is a little different. It's normal to get here. Don't
  1678. X   crash'n'burn */
  1679. X
  1680. X  return;
  1681. X}
  1682. X
  1683. X/* this'll help \/  */
  1684. X
  1685. X#define INDEX_VALUE ((IY_FLAG)?IY+d:IX+d)
  1686. X
  1687. Xixy_ops(IY_FLAG)
  1688. Xchar IY_FLAG; /* true for IY */
  1689. X{
  1690. X  register BYTE op2;
  1691. X  register BYTE d;
  1692. X
  1693. X  op2=z80_mem(PC++);
  1694. X  d=z80_mem(PC++);    /* DANGER WILL ROBINSON!!! Better fix this
  1695. X             for PUSH, INC et all */
  1696. X
  1697. X/* And away they go!... */
  1698. X
  1699. X  if (op2==0xCB) /* CB ops */
  1700. X  {
  1701. X    cb_ops(INDEX_VALUE);
  1702. X    return;
  1703. X  }
  1704. X
  1705. X  if ((op2&0xC0)==0x40) /* LD (I?+d),reg or reg,(I?+d) */
  1706. X  {
  1707. X    register BYTE value;
  1708. X    switch((op2&0x38)>>3)
  1709. X    {
  1710. X      case 0:value=BC>>8;       break;
  1711. X      case 1:value=BC&0xff;     break;
  1712. X      case 2:value=DE>>8;       break;
  1713. X      case 3:value=DE&0xff;     break;
  1714. X      case 4:value=HL>>8;       break;
  1715. X      case 5:value=HL&0xff;     break;
  1716. X      case 6:value=z80_mem(INDEX_VALUE); break;
  1717. X      case 7:value=AF>>8;       break;
  1718. X    }
  1719. X    switch(op2&0x7)
  1720. X    {
  1721. X      case 0:BC=(BC&0xff)|(value<<8);  break;
  1722. X      case 1:BC=(BC&0xff00)|value;     break;
  1723. X      case 2:DE=(DE&0xff)|(value<<8);  break;
  1724. X      case 3:DE=(DE&0xff00)|value;     break;
  1725. X      case 4:HL=(HL&0xff)|(value<<8);  break;
  1726. X      case 5:HL=(HL&0xff00)|value;     break;
  1727. X      case 6:wr_z80_mem(INDEX_VALUE,value); break;
  1728. X      case 7:AF=(AF&0xff)|(value<<8);  break;
  1729. X    }
  1730. X
  1731. X    return;
  1732. X  }
  1733. X
  1734. X  if (op2==0x36) /* LD (I?+d),imm */
  1735. X  {
  1736. X    wr_z80_mem(INDEX_VALUE,z80_mem(PC++));
  1737. X    return;
  1738. X  }
  1739. X
  1740. X  if ((op2&0xFE)==0x34) /* INC/DEC (I?+d) */
  1741. X  {
  1742. X    switch (op2&1)
  1743. X    {
  1744. X      case 0:wr_z80_mem(INDEX_VALUE,alu_add(z80_mem(INDEX_VALUE),1));
  1745. X      break;
  1746. X      case 1:wr_z80_mem(INDEX_VALUE,alu_sub(z80_mem(INDEX_VALUE),1));
  1747. X      break;
  1748. X    }
  1749. X    return;
  1750. X  }
  1751. X
  1752. X  if ((op2&0xC7)==0x86) /* MATH OPS (I?+d) */
  1753. X  {
  1754. X    WORD t;
  1755. X    switch((op2&0x38)>>3)
  1756. X    {
  1757. X      case 0:t=alu_add(AF>>8,z80_mem(INDEX_VALUE))<<8; AF&=0xff; AF|=t; /* ADD */
  1758. X      break;
  1759. X      case 1:t=alu_adc(AF>>8,z80_mem(INDEX_VALUE))<<8; AF&=0xff; AF|=t;          /* ADC */
  1760. X      break;
  1761. X      case 2:t=alu_sub(AF>>8,z80_mem(INDEX_VALUE))<<8; AF&=0xff; AF|=t; /* SUB */
  1762. X      break;
  1763. X      case 3:t=alu_sbc(AF>>8,z80_mem(INDEX_VALUE))<<8; AF&=0xff; AF|=t;          /* SBC */
  1764. X      break;
  1765. X      case 4:AF=(AF&0xff)|(((AF>>8) & z80_mem(INDEX_VALUE))<<8);
  1766. X         log_flags(AF>>8);
  1767. X         /* AND */
  1768. X      break;
  1769. X      case 5:AF=(AF&0xff)|(((AF>>8) ^ z80_mem(INDEX_VALUE))<<8);
  1770. X         log_flags(AF>>8);
  1771. X         /* XOR */
  1772. X      break;
  1773. X      case 6:AF=(AF&0xff)|(((AF>>8) | z80_mem(INDEX_VALUE))<<8);
  1774. X         log_flags(AF>>8);
  1775. X         /* OR */
  1776. X      break;
  1777. X      case 7:alu_sub(AF>>8,z80_mem(INDEX_VALUE)); /* CMP */
  1778. X      break;
  1779. X    }
  1780. X
  1781. X    return;
  1782. X  }
  1783. X
  1784. X/* From here on are ops that don't involve d. For these, we
  1785. X   must decrement the PC to make up for the extra increment we did
  1786. X   to fetch d in the first place. d must be the opcode for the
  1787. X   next instruction. */
  1788. X
  1789. X  PC--;
  1790. X  d=0;  /* this makes our macro work. What a yucky hack! */
  1791. X
  1792. X  if (op2==0x21) /* LD I?,imm */
  1793. X  {
  1794. X    register WORD operand;
  1795. X
  1796. X    operand=z80_mem(PC++);
  1797. X    operand|=z80_mem(PC++)<<8;
  1798. X    if (IY_FLAG)
  1799. X      IY=operand;
  1800. X    else
  1801. X      IX=operand;
  1802. X
  1803. X    return;
  1804. X  }
  1805. X  if (op2==0x22) /* LD (imm),I? */
  1806. X  {
  1807. X    register WORD operand;
  1808. X
  1809. X    operand=z80_mem(PC++);
  1810. X    operand|=z80_mem(PC++)<<8;
  1811. X
  1812. X    wr_z80_mem(operand,INDEX_VALUE&0xff);
  1813. X    wr_z80_mem(operand+1,INDEX_VALUE>>8);
  1814. X
  1815. X    return;
  1816. X  }
  1817. X  if (op2==0x2A) /* LD I?,(imm) */
  1818. X  {
  1819. X    register WORD operand;
  1820. X
  1821. X    operand=z80_mem(PC++);
  1822. X    operand|=z80_mem(PC++)<<8;
  1823. X
  1824. X    if (IY_FLAG)
  1825. X      IY=z80_mem(operand)|(z80_mem(operand+1)<<8);
  1826. X    else
  1827. X      IX=z80_mem(operand)|(z80_mem(operand+1)<<8);
  1828. X
  1829. X    return;
  1830. X  }
  1831. X
  1832. X  if ((op2&0xCF)==0x09) /* ADD I?,rp */
  1833. X  {
  1834. X    register int temp;
  1835. X
  1836. X    switch ((op2&0x30)>>4)
  1837. X    {
  1838. X      case 0:temp=INDEX_VALUE+BC; break;
  1839. X      case 1:temp=INDEX_VALUE+DE; break;
  1840. X      case 2:temp=INDEX_VALUE+HL; break;
  1841. X      case 3:temp=INDEX_VALUE+SP; break;
  1842. X    }
  1843. X    if (IY_FLAG)
  1844. X      IY=(WORD) temp;
  1845. X    else
  1846. X      IX=(WORD) temp;
  1847. X    AF|=((temp>0xffff)?FLAG_C:0);
  1848. X    AF&=~FLAG_N;
  1849. X    return;
  1850. X  }
  1851. X
  1852. X  if (op2==0x23) /* INC I? */
  1853. X  {
  1854. X    if (IY_FLAG)
  1855. X      IY++;
  1856. X    else
  1857. X      IX++;
  1858. X
  1859. X    return;
  1860. X  }
  1861. X  if (op2==0x2B) /* DEC I? */
  1862. X  {
  1863. X    if (IY_FLAG)
  1864. X      IY--;
  1865. X    else
  1866. X      IX--;
  1867. X
  1868. X    return;
  1869. X  }
  1870. X  if (op2==0xE1) /* POP I? */
  1871. X  {
  1872. X    if (IY_FLAG)
  1873. X      IY=pop();
  1874. X    else
  1875. X      IX=pop();
  1876. X
  1877. X    return;
  1878. X  }
  1879. X  if (op2==0xE5) /* PUSH I? */
  1880. X  {
  1881. X    push(INDEX_VALUE);
  1882. X    return;
  1883. X  }
  1884. X  if (op2==0xE9) /* JP (I?) */
  1885. X  {
  1886. X    PC=INDEX_VALUE;
  1887. X    return;
  1888. X  }
  1889. X  if (op2==0xE3) /* EX (SP),I? */
  1890. X  {
  1891. X    register WORD temp;
  1892. X
  1893. X    temp=z80_mem(SP)|(z80_mem(SP+1)<<8);
  1894. X    wr_z80_mem(SP,INDEX_VALUE&0xff);
  1895. X    wr_z80_mem(SP+1,INDEX_VALUE>>8);
  1896. X    if (IY_FLAG)
  1897. X      IY=temp;
  1898. X    else
  1899. X      IX=temp;
  1900. X
  1901. X    return;
  1902. X  }
  1903. X  if (op2==0xF9) /* LD SP,I? */
  1904. X  {
  1905. X    SP=INDEX_VALUE;
  1906. X    return;
  1907. X  }
  1908. X
  1909. X/* There are undefined ED/FD ops. What do we do about it? Good
  1910. X   question. My theory says crash-n-burn. */
  1911. X
  1912. X  printf("OH NO!!!!! PARSE ERROR 2nd operand, Index ops\n");
  1913. X  printf("PC = %4x  (PC) = %2x\n\n",PC-1,op2);
  1914. X
  1915. X  exit(99);
  1916. X}
  1917. SHAR_EOF
  1918. $TOUCH -am 0928182190 z80_cbed.c &&
  1919. chmod 0644 z80_cbed.c ||
  1920. echo "restore of z80_cbed.c failed"
  1921. set `wc -c z80_cbed.c`;Wc_c=$1
  1922. if test "$Wc_c" != "16492"; then
  1923.     echo original size 16492, current size $Wc_c
  1924. fi
  1925. rm -f shar3_seq_.tmp
  1926. echo "You have unpacked the last part"
  1927. exit 0
  1928. -- 
  1929. Nick Sayer              | Disclaimer: "Don't try this at home, | RIP: Mel Blanc
  1930. mrapple@quack.sac.ca.us | kids. This should only be done by    |   1908-1989
  1931. N6QQQ  [44.2.1.17]      | trained, professional idiots."       |  May he never
  1932. 209-952-5347 (Telebit)  |                     --Plucky Duck    |  be silenced.
  1933.