home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 292_04 / z80mch.c < prev    next >
C/C++ Source or Header  |  1990-07-17  |  10KB  |  602 lines

  1. /* z80mch.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15. #include "z80.h"
  16.  
  17. char    imtab[3] = { 0x46, 0x56, 0x5E };
  18. int    hd64;
  19.  
  20. /*
  21.  * Process a machine op.
  22.  */
  23. VOID
  24. machine(mp)
  25. struct mne *mp;
  26. {
  27.     register op, t1, t2;
  28.     struct expr e1, e2;
  29.     int rf, v1, v2;
  30.  
  31.     op = mp->m_valu;
  32.     rf = mp->m_type;
  33.     if (!hd64 && rf>X_HD64)
  34.         rf = 0;
  35.     switch (rf) {
  36.  
  37.     case S_INH1:
  38.         outab(op);
  39.         break;
  40.  
  41.     case S_INH2:
  42.         outab(0xED);
  43.         outab(op);
  44.         break;
  45.  
  46.     case S_RET:
  47.         if (more()) {
  48.             if ((v1 = admode(CND)) != 0) {
  49.                 outab(op | v1<<3);
  50.             } else {
  51.                 qerr();
  52.             }
  53.         } else {
  54.             outab(0xC9);
  55.         }
  56.         break;
  57.  
  58.     case S_PUSH:
  59.         if (admode(R16X)) {
  60.             outab(op+0x30);
  61.             break;
  62.         } else
  63.         if ((v1 = admode(R16)) != 0 && (v1 &= 0xFF) != SP) {
  64.             if (v1 != gixiy(v1)) {
  65.                 outab(op+0x20);
  66.                 break;
  67.             }
  68.             outab(op | v1<<4);
  69.             break;
  70.         }
  71.         aerr();
  72.         break;
  73.  
  74.     case S_RST:
  75.         v1 = absexpr();
  76.         if (v1 & ~0x38) {
  77.             aerr();
  78.             v1 = 0;
  79.         }
  80.         outab(op|v1);
  81.         break;
  82.  
  83.     case S_IM:
  84.         expr(&e1, 0);
  85.         abscheck(&e1);
  86.         if (e1.e_addr > 2) {
  87.             aerr();
  88.             e1.e_addr = 0;
  89.         }
  90.         outab(op);
  91.         outab(imtab[e1.e_addr]);
  92.         break;
  93.  
  94.     case S_BIT:
  95.         expr(&e1, 0);
  96.         t1 = 0;
  97.         v1 = e1.e_addr;
  98.         if (v1 > 7) {
  99.             ++t1;
  100.             v1 &= 0x07;
  101.         }
  102.         op |= (v1<<3);
  103.         comma();
  104.         addr(&e2);
  105.         abscheck(&e1);
  106.         if (genop(0xCB, op, &e2, 0) || t1)
  107.             aerr();
  108.         break;
  109.  
  110.     case S_RL:
  111.         t1 = 0;
  112.         t2 = addr(&e2);
  113.         if (more()) {
  114.             if ((t2 != S_R8) || (e2.e_addr != A))
  115.                 ++t1;
  116.             comma();
  117.             t2 = addr(&e2);
  118.         }
  119.         if (genop(0xCB, op, &e2, 0) || t1)
  120.             aerr();
  121.         break;
  122.  
  123.     case S_AND:
  124.     case S_SUB:
  125.         t1 = 0;
  126.         t2 = addr(&e2);
  127.         if (more()) {
  128.             if ((t2 != S_R8) || (e2.e_addr != A))
  129.                 ++t1;
  130.             comma();
  131.             t2 = addr(&e2);
  132.         }
  133.         if (rf==S_SUB && t2!=S_IMMED) {
  134.             if (genop(0xCB, op, &e2, 0) || t1)
  135.                 aerr();
  136.         } else {
  137.             if (genop(0, op, &e2, 1) || t1)
  138.                 aerr();
  139.         }
  140.         break;
  141.  
  142.     case S_ADD:
  143.     case S_ADC:
  144.     case S_SBC:
  145.         t1 = addr(&e1);
  146.         t2 = 0;
  147.         if (more()) {
  148.             comma();
  149.             t2 = addr(&e2);
  150.         }
  151.         if (t2 == 0) {
  152.             if (genop(0, op, &e1, 1))
  153.                 aerr();
  154.             break;
  155.         }
  156.         if ((t1 == S_R8) && (e1.e_addr == A)) {
  157.             if (genop(0, op, &e2, 1))
  158.                 aerr();
  159.             break;
  160.         }
  161.         if ((t1 == S_R16) && (t2 == S_R16)) {
  162.             if (rf == S_ADD)
  163.                 op = 0x09;
  164.             if (rf == S_ADC)
  165.                 op = 0x4A;
  166.             if (rf == S_SBC)
  167.                 op = 0x42;
  168.             v1 = e1.e_addr;
  169.             v2 = e2.e_addr;
  170.             if ((v1 == HL) && (v2 <= SP)) {
  171.                 if (rf != S_ADD)
  172.                     outab(0xED);
  173.                 outab(op | (v2<<4));
  174.                 break;
  175.             }
  176.             if (rf != S_ADD) {
  177.                 aerr();
  178.                 break;
  179.             }
  180.             if ((v1 == IX) && (v2 != HL) && (v2 != IY)) {
  181.                 if (v2 == IX)
  182.                     v2 = HL;
  183.                 outab(0xDD);
  184.                 outab(op | (v2<<4));
  185.                 break;
  186.             }
  187.             if ((v1 == IY) && (v2 != HL) && (v2 != IX)) {
  188.                 if (v2 == IY)
  189.                     v2 = HL;
  190.                 outab(0xFD);
  191.                 outab(op | (v2<<4));
  192.                 break;
  193.             }
  194.         }
  195.         aerr();
  196.         break;
  197.  
  198.     case S_LD:
  199.         t1 = addr(&e1);
  200.         comma();
  201.         t2 = addr(&e2);
  202.         if (t1 == S_R8) {
  203.             v1 = op | e1.e_addr<<3;
  204.             if (genop(0, v1, &e2, 0) == 0)
  205.                 break;
  206.             if (t2 == S_IMMED) {
  207.                 outab(e1.e_addr<<3 | 0x06);
  208.                 outrb(&e2,0);
  209.                 break;
  210.             }
  211.         }
  212.         v1 = e1.e_addr;
  213.         v2 = e2.e_addr;
  214.         if ((t1 == S_R16) && (t2 == S_IMMED)) {
  215.             v1 = gixiy(v1);
  216.             outab(0x01|v1<<4);
  217.             outrw(&e2, 0);
  218.             break;
  219.         }
  220.         if ((t1 == S_R16) && (t2 == S_INDM)) {
  221.             if (gixiy(v1) == HL) {
  222.                 outab(0x2A);
  223.             } else {
  224.                 outab(0xED);
  225.                 outab(0x4B | v1<<4);
  226.             }
  227.             outrw(&e2, 0);
  228.             break;
  229.         }
  230.         if ((t1 == S_INDM) && (t2 == S_R16)) {
  231.             if (gixiy(v2) == HL) {
  232.                 outab(0x22);
  233.             } else {
  234.                 outab(0xED);
  235.                 outab(0x43 | v2<<4);
  236.             }
  237.             outrw(&e1, 0);
  238.             break;
  239.         }
  240.         if ((t1 == S_R8) && (v1 == A) && (t2 == S_INDM)) {
  241.             outab(0x3A);
  242.             outrw(&e2, 0);
  243.             break;
  244.         }
  245.         if ((t1 == S_INDM) && (t2 == S_R8) && (v2 == A)) {
  246.             outab(0x32);
  247.             outrw(&e1, 0);
  248.             break;
  249.         }
  250.         if ((t2 == S_R8) && (gixiy(t1) == S_IDHL)) {
  251.             outab(0x70|v2);
  252.             if (t1 != S_IDHL)
  253.                 outrb(&e1, 0);
  254.             break;
  255.         }
  256.         if ((t2 == S_IMMED) && (gixiy(t1) == S_IDHL)) {
  257.             outab(0x36);
  258.             if (t1 != S_IDHL)
  259.                 outrb(&e1, 0);
  260.             outrb(&e2, 0);
  261.             break;
  262.         }
  263.         if ((t1 == S_R8X) && (t2 == S_R8) && (v2 == A)) {
  264.             outab(0xED);
  265.             outab(v1);
  266.             break;
  267.         }
  268.         if ((t1 == S_R8) && (v1 == A) && (t2 == S_R8X)) {
  269.             outab(0xED);
  270.             outab(v2|0x10);
  271.             break;
  272.         }
  273.         if ((t1 == S_R16) && (v1 == SP)) {
  274.             if ((t2 == S_R16) && (gixiy(v2) == HL)) {
  275.                 outab(0xF9);
  276.                 break;
  277.             }
  278.         }
  279.         if ((t1 == S_R8) && (v1 == A)) {
  280.             if ((t2 == S_IDBC) || (t2 == S_IDDE)) {
  281.                 outab(0x0A | (t2-S_INDR)<<4);
  282.                 break;
  283.             }
  284.         }
  285.         if ((t2 == S_R8) && (v2 == A)) {
  286.             if ((t1 == S_IDBC) || (t1 == S_IDDE)) {
  287.                 outab(0x02 | (t1-S_INDR)<<4);
  288.                 break;
  289.             }
  290.         }
  291.         aerr();
  292.         break;
  293.  
  294.  
  295.     case S_EX:
  296.         t1 = addr(&e1);
  297.         comma();
  298.         t2 = addr(&e2);
  299.         if (t2 == S_R16) {
  300.             v1 = e1.e_addr;
  301.             v2 = e2.e_addr;
  302.             if ((t1 == S_IDSP) && (v1 == 0)) {
  303.                 if (gixiy(v2) == HL) {
  304.                     outab(op);
  305.                     break;
  306.                 }
  307.             }
  308.             if (t1 == S_R16) {
  309.                 if ((v1 == DE) && (v2 == HL)) {
  310.                     outab(0xEB);
  311.                     break;
  312.                 }
  313.             }
  314.         }
  315.         if ((t1 == S_R16X) && (t2 == S_R16X)) {
  316.             outab(0x08);
  317.             break;
  318.         }
  319.         aerr();
  320.         break;
  321.  
  322.     case S_IN:
  323.     case S_OUT:
  324.         if (rf == S_IN) {
  325.             t1 = addr(&e1);
  326.             comma();
  327.             t2 = addr(&e2);
  328.         } else {
  329.             t2 = addr(&e2);
  330.             comma();
  331.             t1 = addr(&e1);
  332.         }
  333.         v1 = e1.e_addr;
  334.         v2 = e2.e_addr;
  335.         if (t1 == S_R8) {
  336.             if ((v1 == A) && (t2 == S_INDM)) {
  337.                 outab(op);
  338.                 outab(v2);
  339.                 break;
  340.             }
  341.             if (t2 == S_IDC) {
  342.                 outab(0xED);
  343.                 outab(((rf == S_IN) ? 0x40 : 0x41) + (v1<<3));
  344.                 break;
  345.             }
  346.         }
  347.         aerr();
  348.         break;
  349.  
  350.     case S_DEC:
  351.     case S_INC:
  352.         t1 = addr(&e1);
  353.         v1 = e1.e_addr;
  354.         if (t1 == S_R8) {
  355.             outab(op|(v1<<3));
  356.             break;
  357.         }
  358.         if (t1 == S_IDHL) {
  359.             outab(op|0x30);
  360.             break;
  361.         }
  362.         if (t1 != gixiy(t1)) {
  363.             outab(op|0x30);
  364.             outrb(&e1,0);
  365.             break;
  366.         }
  367.         if (t1 == S_R16) {
  368.             v1 = gixiy(v1);
  369.             if (rf == S_INC) {
  370.                 outab(0x03|(v1<<4));
  371.                 break;
  372.             }
  373.             if (rf == S_DEC) {
  374.                 outab(0x0B|(v1<<4));
  375.                 break;
  376.             }
  377.         }
  378.         aerr();
  379.         break;
  380.  
  381.     case S_DJNZ:
  382.     case S_JR:
  383.         if ((v1 = admode(CND)) != 0 && rf != S_DJNZ) {
  384.             if ((v1 &= 0xFF) <= 0x18) {
  385.                 op += (v1+1)<<3;
  386.             } else {
  387.                 aerr();
  388.             }
  389.             comma();
  390.         }
  391.         expr(&e2, 0);
  392.         outab(op);
  393.         if (e2.e_base.e_ap == NULL || e2.e_base.e_ap == dot.s_area) {
  394.             v2 = e2.e_addr - dot.s_addr - 1;
  395.             if ((v2 < -128) || (v2 > 127))
  396.                 aerr();
  397.             outab(v2);
  398.         } else {
  399.             outrb(&e2, R_PCR);
  400.         }
  401.         if (e2.e_mode != S_USER)
  402.             rerr();
  403.         break;
  404.  
  405.     case S_CALL:
  406.         if ((v1 = admode(CND)) != 0) {
  407.             op |= (v1&0xFF)<<3;
  408.             comma();
  409.         } else {
  410.             op = 0xCD;
  411.         }
  412.         expr(&e1, 0);
  413.         outab(op);
  414.         outrw(&e1, 0);
  415.         break;
  416.  
  417.     case S_JP:
  418.         if ((v1 = admode(CND)) != 0) {
  419.             op |= (v1&0xFF)<<3;
  420.             comma();
  421.             expr(&e1, 0);
  422.             outab(op);
  423.             outrw(&e1, 0);
  424.             break;
  425.         }
  426.         t1 = addr(&e1);
  427.         if (t1 == S_USER) {
  428.             outab(0xC3);
  429.             outrw(&e1, 0);
  430.             break;
  431.         }
  432.         if ((e1.e_addr == 0) && (gixiy(t1) == S_IDHL)) {
  433.             outab(0xE9);
  434.             break;
  435.         }
  436.         aerr();
  437.         break;
  438.  
  439.     case X_HD64:
  440.         ++hd64;
  441.         break;
  442.  
  443.     case X_INH2:
  444.         outab(0xED);
  445.         outab(op);
  446.         break;
  447.  
  448.     case X_IN:
  449.     case X_OUT:
  450.         if (rf == X_IN) {
  451.             t1 = addr(&e1);
  452.             comma();
  453.             t2 = addr(&e2);
  454.         } else {
  455.             t2 = addr(&e2);
  456.             comma();
  457.             t1 = addr(&e1);
  458.         }
  459.         if ((t1 == S_R8) && (t2 == S_INDM)) {
  460.             outab(0xED);
  461.             outab(op | e1.e_addr<<3);
  462.             outrb(&e2, 0);
  463.             break;
  464.         }
  465.         aerr();
  466.         break;
  467.  
  468.     case X_MLT:
  469.         t1 = addr(&e1);
  470.         if ((t1 == S_R16) && ((v1 = e1.e_addr) <= SP)) {
  471.             outab(0xED);
  472.             outab(op | v1<<4);
  473.             break;
  474.         }
  475.         aerr();
  476.         break;
  477.  
  478.     case X_TST:
  479.         t1 = addr(&e1);
  480.         if (t1 == S_R8) {
  481.             outab(0xED);
  482.             outab(op | e1.e_addr<<3);
  483.             break;
  484.         }
  485.         if (t1 == S_IDHL) {
  486.             outab(0xED);
  487.             outab(0x34);
  488.             break;
  489.         }
  490.         if (t1 == S_IMMED) {
  491.             outab(0xED);
  492.             outab(0x64);
  493.             outrb(&e1, 0);
  494.             break;
  495.         }
  496.         aerr();
  497.         break;
  498.  
  499.     case X_TSTIO:
  500.         t1 = addr(&e1);
  501.         if (t1 == S_IMMED) {
  502.             outab(0xED);
  503.             outab(op);
  504.             outrb(&e1, 0);
  505.             break;
  506.         }
  507.         aerr();
  508.         break;
  509.  
  510.     default:
  511.         err('o');
  512.     }
  513. }
  514.  
  515. /*
  516.  * general addressing evaluation
  517.  * return(0) if general addressing mode output, else
  518.  * return(esp->e_mode)
  519.  */
  520. int
  521. genop(pop, op, esp, f)
  522. register int pop, op;
  523. register struct expr *esp;
  524. int f;
  525. {
  526.     register int t1;
  527.     if ((t1 = esp->e_mode) == S_R8) {
  528.         if (pop)
  529.             outab(pop);
  530.         outab(op|esp->e_addr);
  531.         return(0);
  532.     }
  533.     if (t1 == S_IDHL) {
  534.         if (pop)
  535.             outab(pop);
  536.         outab(op|0x06);
  537.         return(0);
  538.     }
  539.     if (gixiy(t1) == S_IDHL) {
  540.         if (pop) {
  541.             outab(pop);
  542.             outrb(esp,0);
  543.             outab(op|0x06);
  544.         } else {
  545.             outab(op|0x06);
  546.             outrb(esp,0);
  547.         }
  548.         return(0);
  549.     }
  550.     if ((t1 == S_IMMED) && (f)) {
  551.         if (pop)
  552.             outab(pop);
  553.         outab(op|0x46);
  554.         outrb(esp,0);
  555.         return(0);
  556.     }
  557.     return(t1);
  558. }
  559.  
  560. /*
  561.  * IX and IY prebyte check
  562.  */
  563. int
  564. gixiy(v)
  565. int v;
  566. {
  567.     if (v == IX) {
  568.         v = HL;
  569.         outab(0xDD);
  570.     } else if (v == IY) {
  571.         v = HL;
  572.         outab(0xFD);
  573.     } else if (v == S_IDIX) {
  574.         v = S_IDHL;
  575.         outab(0xDD);
  576.     } else if (v == S_IDIY) {
  577.         v = S_IDHL;
  578.         outab(0xFD);
  579.     }
  580.     return(v);
  581. }
  582.  
  583. /*
  584.  * The next character must be a
  585.  * comma.
  586.  */
  587. VOID
  588. comma()
  589. {
  590.     if (getnb() != ',')
  591.         qerr();
  592. }
  593.  
  594. /*
  595.  * Machine dependent initialization
  596.  */
  597. VOID
  598. minit()
  599. {
  600.     hd64 = 0;
  601. }
  602.