home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 346_02 / m16mch.c < prev    next >
C/C++ Source or Header  |  1991-02-10  |  12KB  |  727 lines

  1. /* M16MCH:C */
  2.  
  3. /*
  4.  * (C) Copyright 1991
  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 "m6816.h"
  16.  
  17. #define    NB    256
  18.  
  19. int    *bp;
  20. int    bm;
  21. int    bb[NB];
  22.  
  23. /*
  24.  * Process a machine op.
  25.  */
  26. VOID
  27. machine(mp)
  28. struct mne *mp;
  29. {
  30.     register op, rf, cpg;
  31.     struct expr e1, e2, e3;
  32.     char id[NCPS];
  33.     struct area *espa;
  34.     int c, pc, t1, t2, vn;
  35.  
  36.     pc = dot.s_addr;
  37.     cpg = 0;
  38.     op = mp->m_valu;
  39.     switch (rf = mp->m_type) {
  40.  
  41.     case S_SDP:
  42.         e1.e_mode = 0;
  43.         e1.e_flag = 0;
  44.         e1.e_addr = 0;
  45.         e1.e_base.e_ap = NULL;
  46.         espa = NULL;
  47.         if (more()) {
  48.             expr(&e1, 0);
  49.             if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
  50.                 if (e1.e_addr) {
  51.                     err('b');
  52.                 }
  53.             }
  54.             if ((c = getnb()) == ',') {
  55.                 getid(id, -1);
  56.                 espa = alookup(id);
  57.                 if (espa == NULL) {
  58.                     err('u');
  59.                 }
  60.             } else {
  61.                 unget(c);
  62.             }
  63.         }
  64.         if (espa) {
  65.             outdp(espa, &e1);
  66.         } else {
  67.             outdp(dot.s_area, &e1);
  68.         }
  69.         lmode = SLIST;
  70.         break;
  71.  
  72.     case S_IMMA:
  73.         if (addr(&e1) == T_IMM) {
  74.             if (mchimm(&e1)) {
  75.                 outab(PAGE3);
  76.                 outab(op);
  77.                 outrw(&e1, R_NORM);
  78.             } else {
  79.                 outab(op);
  80.                 outrb(&e1, R_NORM);
  81.             }
  82.         } else {
  83.             dot.s_addr += 4;
  84.             aerr();
  85.         }
  86.         break;
  87.  
  88.     case S_IM16:
  89.         if (addr(&e1) == T_IMM) {
  90.             outab(PAGE3);
  91.             outab(op);
  92.             outrw(&e1, R_NORM);
  93.         } else {
  94.             dot.s_addr += 4;
  95.             aerr();
  96.         }
  97.         break;
  98.         
  99.     case S_BIT:
  100.         t1 = addr(&e1);
  101.         comma();
  102.         t2 = addr(&e2);
  103.         if ((t2 != T_IMM) && (t2 != T_EXT)) {
  104.             aerr();
  105.         }
  106.         if (t1 == T_EXT) {
  107.             outab(op|0x30);
  108.             mchubyt(&e2);
  109.             outrb(&e2, R_USGN);
  110.             outrw(&e1, R_NORM);
  111.         } else
  112.         if (t1 & T_INDX) {
  113.             if (mchindx(t1, &e1)) {
  114.                 outab(op|(t1 & 0x30));
  115.                 mchubyt(&e2);
  116.                 outrb(&e2, R_USGN);
  117.                 outrw(&e1, R_NORM);
  118.             } else {
  119.                 outab(PAGE1);
  120.                 outab(op|(t1 & 0x30));
  121.                 mchubyt(&e2);
  122.                 outrb(&e2, R_USGN);
  123.                 mchubyt(&e1);
  124.                 outrb(&e1, R_USGN);
  125.             }
  126.         } else {
  127.             dot.s_addr += 4;
  128.             aerr();
  129.         }
  130.         break;
  131.  
  132.     case S_BITW:
  133.         t1 = addr(&e1);
  134.         comma();
  135.         t2 = addr(&e2);
  136.         if ((t2 != T_IMM) && (t2 != T_EXT)) {
  137.             aerr();
  138.         }
  139.         if (t1 == T_EXT) {
  140.             t1 |= 0x30;
  141.         } else
  142.         if (t1 & T_INDX) {
  143.             if (t1 & T_IND8) {
  144.                 aerr();
  145.             }
  146.         } else {
  147.             aerr();
  148.         }
  149.         outab(PAGE2);
  150.         outab(op|(t1 & 0x30));
  151.         outrw(&e2, R_NORM);
  152.         outrw(&e1, R_NORM);
  153.         break;
  154.  
  155.     case S_BRBT:
  156.         t1 = addr(&e1);
  157.         comma();
  158.         t2 = addr(&e2);
  159.         comma();
  160.         addr(&e3);
  161.         if ((t2 != T_IMM) && (t2 != T_EXT)) {
  162.             aerr();
  163.         }
  164.         if (t1 == T_EXT) {
  165.             outab(op|0x30);
  166.             mchubyt(&e2);
  167.             outrb(&e2, R_USGN);
  168.             outrw(&e1, R_NORM);
  169.             if (mchabs(&e3)) {
  170.                 vn = e3.e_addr - dot.s_addr - 2;
  171.                 outaw(vn);
  172.             } else {
  173.                 outrw(&e3, R_PCR);
  174.             }
  175.         } else
  176.         if (t1 & T_INDX) {
  177.             if ((t1 & T_IND8) || (t1 & T_IND16)) {
  178.                 ;
  179.             } else
  180.             if (mchindx(t1, &e1)) {
  181.                 t1 |= T_IND16;
  182.             } else {
  183.                 if (mchabs(&e3)) {
  184.                     vn = e3.e_addr - dot.s_addr - 4;
  185.                     if ((vn < -128) || (vn > 127)) {
  186.                         t1 |= T_IND16;
  187.                     } else {
  188.                         t1 |= T_IND8;
  189.                     }
  190.                 } else {
  191.                     t1 |= T_IND16;
  192.                 }
  193.             }
  194.             if (t1 & T_IND8) {
  195.                 if (op == 0x0A)
  196.                     op = 0xCB;
  197.                 if (op == 0x0B)
  198.                     op = 0x8B;
  199.                 outab(op|(t1 & 0x30));
  200.                 mchubyt(&e2);
  201.                 outrb(&e2, R_USGN);
  202.                 mchubyt(&e1);
  203.                 outrb(&e1, R_USGN);
  204.                 if (mchabs(&e3)) {
  205.                     vn = e3.e_addr - dot.s_addr - 1;
  206.                     if ((vn < -128) || (vn > 127))
  207.                         aerr();
  208.                     outab(vn);
  209.                 } else {
  210.                     outrb(&e3, R_PCR);
  211.                 }
  212.             } else
  213.             if (t1 & T_IND16) {
  214.                 outab(op|(t1 & 0x30));
  215.                 mchubyt(&e2);
  216.                 outrb(&e2, R_USGN);
  217.                 outrw(&e1, R_NORM);
  218.                 if (mchabs(&e3)) {
  219.                     vn = e3.e_addr - dot.s_addr - 2;
  220.                     outaw(vn);
  221.                 } else {
  222.                     outrw(&e3, R_PCR);
  223.                 }
  224.             }
  225.         } else {
  226.             dot.s_addr += 6;
  227.             aerr();
  228.         }
  229.         break;
  230.  
  231.     case S_LDED:
  232.         t1 = addr(&e1);
  233.         if (t1 == T_EXT) {
  234.             outab(PAGE2);
  235.             outab(op);
  236.             outrw(&e1, R_NORM);
  237.         } else {
  238.             dot.s_addr += 4;
  239.             aerr();
  240.         }
  241.         break;
  242.  
  243.     case S_MAC:
  244.         t1 = addr(&e1);
  245.         if (more()) {
  246.             comma();
  247.             t2 = addr(&e2);
  248.             if ((t1 != T_IMM) || !mchabs(&e1) ||
  249.                 (t2 != T_IMM) || !mchabs(&e2))
  250.                 aerr();
  251.             outab(op);
  252.             outab(((e1.e_addr << 4) & 0xF0) | (e2.e_addr & 0x0F));
  253.         } else {
  254.             if (t1 != T_IMM)
  255.                 aerr();
  256.             outab(op);
  257.             outrb(&e1, R_NORM);
  258.         }
  259.         break;
  260.  
  261.     case S_PSHM:
  262.         vn = 0;
  263.         do {
  264.             if ((t1 = admode(pshm)) == 0 || vn & t1)
  265.                 aerr();
  266.             vn |= t1;
  267.         } while (more() && comma());
  268.         outab(op);
  269.         outab(vn);
  270.         break;
  271.  
  272.     case S_PULM:
  273.         vn = 0;
  274.         do {
  275.             if ((t1 = admode(pulm)) == 0 || vn & t1)
  276.                 aerr();
  277.             vn |= t1;
  278.         } while (more() && comma());
  279.         outab(op);
  280.         outab(vn);
  281.         break;
  282.  
  283.     case S_JXX:
  284.         t1 = addr(&e1);
  285.         comma();
  286.         t2 = addr(&e2);
  287.         if ((t1 != T_IMM) && (t1 != T_EXT)) {
  288.             aerr();
  289.         }
  290.         if (t2 == T_EXT) {
  291.             if (op == 0x4B)
  292.                 outab(0x70);
  293.             if (op == 0x89)
  294.                 outab(0xFA);
  295.             mchubyt(&e1);
  296.             outrb(&e1, R_USGN);
  297.             outrw(&e2, R_NORM);
  298.         } else
  299.         if ((t2 & T_INDX) && (t2 != (T_INDX|T_IND8))) {
  300.             outab(op|(t2 & 0x30));
  301.             mchubyt(&e1);
  302.             outrb(&e1, R_USGN);
  303.             outrw(&e2, R_NORM);
  304.         } else {
  305.             dot.s_addr += 4;
  306.             aerr();
  307.         }
  308.         break;
  309.  
  310.     case S_MOVB:
  311.     case S_MOVW:
  312.         t1 = addr(&e1);
  313.         comma();
  314.         t2 = addr(&e2);
  315.         if((t1 == T_EXT) && (t2 == T_EXT)) {
  316.             outab(PAGE3);
  317.             outab(op|0xFE);
  318.             outrw(&e1, R_NORM);
  319.             outrw(&e2, R_NORM);
  320.         } else
  321.         if((t1 & T_INDX) && (t2 == T_EXT)) {
  322.             outab(op|(t1 & 0x30));
  323.             mchubyt(&e1);
  324.             outrb(&e1, R_USGN);
  325.             outrw(&e2, R_NORM);
  326.         } else
  327.         if((t1 == T_EXT) && (t2 & T_INDX)) {
  328.             outab(op|0x02|(t2 & 0x30));
  329.             mchubyt(&e2);
  330.             outrb(&e2, R_USGN);
  331.             outrw(&e1, R_NORM);
  332.         } else {
  333.             dot.s_addr += 6;
  334.             aerr();
  335.         }
  336.         break;
  337.  
  338.     case S_CMP:
  339.     case S_LOAD:
  340.     case S_STOR:
  341.         t1 = addr(&e1);
  342.         if (t1 == T_EXT) {
  343.             outab(PAGE1);
  344.             outab(op|0x30);
  345.             outrw(&e1, R_NORM);
  346.         } else
  347.         if ((t1 == T_IMM) && (rf != S_STOR)) {
  348.             outab(PAGE3);
  349.             if (rf == S_CMP)
  350.                 outab(op|0x30);
  351.             if (rf == S_LOAD)
  352.                 outab((op|0x30) & 0xBF);
  353.             outrw(&e1, R_NORM);
  354.         } else
  355.         if (t1 & T_INDX) {
  356.             if (mchindx(t1, &e1)) {
  357.                 outab(PAGE1);
  358.                 outab(op|(t1 & 0x30));
  359.                 outrw(&e1, R_NORM);
  360.             } else {
  361.                 outab(op|(t1 & 0x30));
  362.                 mchubyt(&e1);
  363.                 outrb(&e1, R_USGN);
  364.             }
  365.         } else {
  366.             dot.s_addr += 4;
  367.             aerr();
  368.         }
  369.         break;
  370.  
  371.     case S_SOPW:
  372.         t1 = addr(&e1);
  373.         if (t1 == T_EXT) {
  374.             t1 |= 0x30;
  375.         } else
  376.         if (t1 & T_INDX) {
  377.             if (t1 & T_IND8) {
  378.                 aerr();
  379.             }
  380.         } else {
  381.             aerr();
  382.         }
  383.         outab(PAGE2);
  384.         outab(op|(t1 & 0x30));
  385.         outrw(&e1, R_NORM);
  386.         break;
  387.  
  388.     case S_SOP:
  389.         t1 = addr(&e1);
  390.         if (t1 == T_EXT) {
  391.             outab(PAGE1);
  392.             outab(op|0x30);
  393.             outrw(&e1, R_NORM);
  394.         } else
  395.         if (t1 & T_INDX) {
  396.             if (mchindx(t1, &e1)) {
  397.                 outab(PAGE1);
  398.                 outab(op|(t1 & 0x30));
  399.                 outrw(&e1, R_NORM);
  400.             } else {
  401.                 outab(op|(t1 & 0x30));
  402.                 mchubyt(&e1);
  403.                 outrb(&e1, R_USGN);
  404.             }
  405.         } else {
  406.             dot.s_addr += 4;
  407.             aerr();
  408.         }
  409.         break;
  410.  
  411.     case S_DOPE:
  412.         t1 = addr(&e1);
  413.         if (t1 == T_EXT) {
  414.             outab(PAGE3);
  415.             outab(op|0x30);
  416.             outrw(&e1, R_NORM);
  417.         } else
  418.         if (t1 == T_IMM) {
  419.             if (op == 0x41) {
  420.                 if (mchimm(&e1)) {
  421.                     outab(PAGE3);
  422.                     outab((op|0x30)&0x3F);
  423.                     outrw(&e1, R_NORM);
  424.                 } else {
  425.                     outab(0x7C);
  426.                     outrb(&e1, R_NORM);
  427.                 }
  428.             } else {
  429.                 outab(PAGE3);
  430.                 outab((op|0x30)&0x3F);
  431.                 outrw(&e1, R_NORM);
  432.             }
  433.         } else
  434.         if ((t1 & T_INDX) && (t1 != (T_INDX|T_IND8))) {
  435.             outab(PAGE3);
  436.             outab(op|(t1 & 0x30));
  437.             outrw(&e1, R_NORM);
  438.         } else {
  439.             dot.s_addr += 4;
  440.             aerr();
  441.         }
  442.         break;
  443.  
  444.     case S_DOPD:
  445.         t1 = addr(&e1);
  446.         if (t1 == T_EXT) {
  447.             outab(PAGE3);
  448.             outab(op|0x70);
  449.             outrw(&e1, R_NORM);
  450.         } else
  451.         if ((t1 == T_IMM) && (op != 0x8A)) {
  452.             if (op == 0x81) {
  453.                 if (mchimm(&e1)) {
  454.                     outab(PAGE3);
  455.                     outab(op|0x30);
  456.                     outrw(&e1, R_NORM);
  457.                 } else {
  458.                     outab(0xFC);
  459.                     outrb(&e1, R_NORM);
  460.                 }
  461.             } else {
  462.                 outab(PAGE3);
  463.                 outab(op|0x30);
  464.                 outrw(&e1, R_NORM);
  465.             }
  466.         } else
  467.         if (t1 & T_INDX) {
  468.             if (mchindx(t1, &e1)) {
  469.                 outab(PAGE3);
  470.                 outab(op|0x40|(t1 & 0x30));
  471.                 outrw(&e1, R_NORM);
  472.             } else {
  473.                 outab(op|(t1 & 0x30));
  474.                 mchubyt(&e1);
  475.                 outrb(&e1, R_USGN);
  476.             }
  477.         } else
  478.         if (t1 & T_E_I) {
  479.             outab(PAGE2);
  480.             outab(op|(t1 & 0x30));
  481.         } else {
  482.             dot.s_addr += 4;
  483.             aerr();
  484.         }
  485.         break;
  486.  
  487.     case S_DOP:
  488.         t1 = addr(&e1);
  489.         if (t1 == T_EXT) {
  490.             outab(PAGE1);
  491.             outab(op|0x30);
  492.             outrw(&e1, R_NORM);
  493.         } else
  494.         if ((t1 == T_IMM) && (op != 0x4A) && (op != 0xCA)) {
  495.             outab(op|0x30);
  496.             outrb(&e1, R_NORM);
  497.         } else
  498.         if (t1 & T_INDX) {
  499.             if (mchindx(t1, &e1)) {
  500.                 outab(PAGE1);
  501.                 outab(op|(t1 & 0x30));
  502.                 outrw(&e1, R_NORM);
  503.             } else {
  504.                 outab(op|(t1 & 0x30));
  505.                 mchubyt(&e1);
  506.                 outrb(&e1, R_USGN);
  507.             }
  508.         } else
  509.         if (t1 & T_E_I) {
  510.             outab(PAGE2);
  511.             outab(op|(t1 & 0x30));
  512.         } else {
  513.             dot.s_addr += 4;
  514.             aerr();
  515.         }
  516.         break;
  517.  
  518.     case S_INH37:
  519.         cpg += PAGE3-PAGE2;
  520.  
  521.     case S_INH27:
  522.         cpg += PAGE2;
  523.         outab(cpg);
  524.         outab(op);
  525.         break;
  526.  
  527.     case S_LBRA:
  528.         cpg += PAGE3-PAGE2;
  529.  
  530.     case S_LBSR:
  531.         cpg += PAGE2;
  532.         expr(&e1, 0);
  533.         outab(cpg);
  534.         outab(op);
  535.         if (mchabs(&e1)) {
  536.             vn = e1.e_addr - dot.s_addr - 2;
  537.             outaw(vn);
  538.         } else {
  539.             outrw(&e1, R_PCR);
  540.         }
  541.         if (e1.e_mode != S_USER)
  542.             aerr();
  543.         break;
  544.  
  545.     case S_BRA:
  546.     case S_BSR:
  547.         expr(&e1, 0);
  548.         outab(op);
  549.         if (mchabs(&e1)) {
  550.             vn = e1.e_addr - dot.s_addr - 1;
  551.             if ((vn < -128) || (vn > 127))
  552.                 rerr();
  553.             outab(vn);
  554.         } else {
  555.             outrb(&e1, R_PCR);
  556.         }
  557.         if (e1.e_mode != S_USER)
  558.             rerr();
  559.         break;
  560.  
  561.     default:
  562.         err('o');
  563.     }
  564.     if (pc & 0x0001) {
  565.         err('b');
  566.         dot.s_addr += 1;
  567.     }
  568. }
  569.  
  570. /*
  571.  * Check if argument is absolute
  572.  */
  573. int
  574. mchabs(e1)
  575. struct expr *e1;
  576. {
  577.     if (e1->e_base.e_ap == NULL || e1->e_base.e_ap == dot.s_area) {
  578.         return(-1);
  579.     }
  580.     return(0);
  581. }
  582.  
  583. /*
  584.  * Addressing error if argument is absolute
  585.  * and unsigned byte is greater than 0x00FF
  586.  */
  587. VOID
  588. mchubyt(e1)
  589. struct expr *e1;
  590. {
  591.     if (mchabs(e1) && (e1->e_addr & 0xFF00)) {
  592.         aerr();
  593.     }
  594. }
  595.  
  596. /*
  597.  * Check index mode
  598.  */
  599. int
  600. mchindx(t1,e1)
  601. int t1;
  602. struct expr *e1;
  603. {
  604.     int flag;
  605.  
  606.     if (t1 & T_IND8) {
  607.         flag = 0;
  608.     } else
  609.     if (t1 & T_IND16) {
  610.         flag = 1;
  611.     } else
  612.     if (pass == 0) {
  613.         flag = 1;
  614.     } else
  615.     if (pass == 1) {
  616.         if (e1->e_addr >= dot.s_addr)
  617.             e1->e_addr -= fuzz;
  618.         flag = 0;
  619.         if (e1->e_addr>255 || e1->e_flag || e1->e_base.e_ap)
  620.             flag = 1;
  621.         if (setbit(flag))
  622.             flag = 1;
  623.     } else {
  624.         if (getbit()) {
  625.             flag = 1;
  626.         } else {
  627.             flag = 0;
  628.         }
  629.     }
  630.     return(flag);
  631. }
  632.  
  633. /*
  634.  * Check immediate mode
  635.  */
  636. int
  637. mchimm(e1)
  638. struct expr *e1;
  639. {
  640.     int flag, vn;
  641.  
  642.     if (pass == 0) {
  643.         flag = 1;
  644.     } else
  645.     if (pass == 1) {
  646.         if (e1->e_addr >= dot.s_addr)
  647.             e1->e_addr -= fuzz;
  648.         vn = e1->e_addr;
  649.         flag = 0;
  650.         if ((vn<-128) || (vn>127) || e1->e_flag || e1->e_base.e_ap)
  651.             flag = 1;
  652.         if (setbit(flag)) {
  653.             flag = 1;
  654.         }
  655.     } else {
  656.         if (getbit()) {
  657.             flag = 1;
  658.         } else {
  659.             flag = 0;
  660.         }
  661.     }
  662.     return(flag);
  663. }
  664.  
  665. /*
  666.  * Machine specific initialization.
  667.  * Set up the bit table.
  668.  */
  669. VOID
  670. minit()
  671. {
  672.     bp = bb;
  673.     bm = 1;
  674. }
  675.  
  676. /*
  677.  * Store `b' in the next slot of the bit table.
  678.  * If no room, force the longer form of the offset.
  679.  */
  680. int
  681. setbit(b)
  682. {
  683.     if (bp >= &bb[NB])
  684.         return(1);
  685.     if (b)
  686.         *bp |= bm;
  687.     bm <<= 1;
  688.     if (bm == 0) {
  689.         bm = 1;
  690.         ++bp;
  691.     }
  692.     return(b);
  693. }
  694.  
  695. /*
  696.  * Get the next bit from the bit table.
  697.  * If none left, return a `1'.
  698.  * This will force the longer form of the offset.
  699.  */
  700. int
  701. getbit()
  702. {
  703.     register f;
  704.  
  705.     if (bp >= &bb[NB])
  706.         return (1);
  707.     f = *bp & bm;
  708.     bm <<= 1;
  709.     if (bm == 0) {
  710.         bm = 1;
  711.         ++bp;
  712.     }
  713.     return (f);
  714. }
  715.  
  716. /*
  717.  * The next character must be a
  718.  * comma.
  719.  */
  720. int
  721. comma()
  722. {
  723.     if (getnb() != ',')
  724.         qerr();
  725.     return(1);
  726. }
  727.