home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume15 / upm / part02 < prev    next >
Text File  |  1990-12-17  |  46KB  |  1,939 lines

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