home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / asxsrc / m09mch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-25  |  6.8 KB  |  460 lines

  1. /* m09mch.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  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 "6809.h"
  16.  
  17. #define    NB    256
  18.  
  19. int    *bp;
  20. int    bm;
  21. int    bb[NB];
  22.  
  23. struct    sdp    sdp[] = {
  24.     0,    NULL
  25. };
  26.  
  27. /*
  28.  * Process a machine op.
  29.  */
  30. VOID
  31. machine(mp)
  32. struct mne *mp;
  33. {
  34.     register op, rf, cpg, c;
  35.     struct expr e1;
  36.     int t1, v1, v2;
  37.     struct area *amp;
  38.     char id[NCPS];
  39.     cpg = 0;
  40.     op = mp->m_valu;
  41.     switch (rf = mp->m_type) {
  42.  
  43.     case S_INH2:
  44.         cpg += 0x01;
  45.  
  46.     case S_INH1:
  47.         cpg += 0x10;
  48.  
  49.     case S_INH:
  50.         if (cpg)
  51.             outab(cpg);
  52.         outab(op);
  53.         break;
  54.  
  55.     case S_BRA:
  56.         expr(&e1, 0);
  57.         v1 = e1.e_addr - dot->s_addr - 2;
  58.         if ((v1 < -128) || (v1 > 127))
  59.             aerr();
  60.         if (e1.e_base.e_ap != dot->s_area)
  61.             rerr();
  62.         outab(op);
  63.         outab(v1);
  64.         break;
  65.  
  66.     case S_LBRA:
  67.         cpg += 0x10;
  68.  
  69.     case S_LBSR:
  70.         expr(&e1, 0);
  71.         if (cpg)
  72.             outab(cpg);
  73.         outab(op);
  74.         if (e1.e_base.e_ap != dot->s_area) {
  75.             outrw(&e1, 1);
  76.         } else {
  77.             v1 = e1.e_addr - dot->s_addr - 2;
  78.             outaw(v1);
  79.         }
  80.         if (e1.e_mode != S_USER)
  81.             aerr();
  82.         break;
  83.  
  84.     case S_PULS:
  85.         v1 = 0;
  86.         do {
  87.             if ((t1 = admode(stks)) == 0 || v1 & t1)
  88.                 aerr();
  89.             v1 |= t1;
  90.         } while (more() && comma());
  91.         outab(op);
  92.         outab(v1);
  93.         break;
  94.  
  95.     case S_PULU:
  96.         v1 = 0;
  97.         do {
  98.             if ((t1 = admode(stku)) == 0 || v1 & t1)
  99.                 aerr();
  100.             v1 |= t1;
  101.         } while (more() && comma());
  102.         outab(op);
  103.         outab(v1);
  104.         break;
  105.  
  106.     case S_EXG:
  107.         v1 = admode(regs);
  108.         comma();
  109.         v2 = admode(regs);
  110.         if ((v1 & 0x08) != (v2 & 0x08))
  111.             aerr();
  112.         outab(op);
  113.         outab((v1<<4)|v2);
  114.         break;
  115.  
  116.     case S_ACC:
  117.         t1 = addr(&e1);
  118.         if (t1 == S_IMMED)
  119.             e1.e_mode = S_IMB;
  120.         genout(cpg, op, rf, &e1);
  121.         break;
  122.  
  123.     case S_STR1:
  124.         cpg += 0x10;
  125.  
  126.     case S_SOP:
  127.     case S_STR:
  128.         t1 = addr(&e1);
  129.         if (t1 == S_IMMED)
  130.             e1.e_mode = S_IMER;
  131.         genout(cpg, op, rf, &e1);
  132.         break;
  133.  
  134.     case S_LR2:
  135.         cpg += 0x01;
  136.  
  137.     case S_LR1:
  138.         cpg += 0x10;
  139.  
  140.     case S_LR:
  141.         t1 = addr(&e1);
  142.         if (t1 == S_IMMED)
  143.             e1.e_mode = S_IMW;
  144.         genout(cpg, op, rf, &e1);
  145.         break;
  146.  
  147.     case S_LEA:
  148.         t1 = addr(&e1);
  149.         if (index) {
  150.             genout(cpg, op, rf, &e1);
  151.             break;
  152.         }
  153.         aerr();
  154.         break;
  155.  
  156.     case S_CC:
  157.         t1 = addr(&e1);
  158.         if (t1 == S_IMMED) {
  159.             e1.e_mode = S_IMB;
  160.             genout(cpg, op, rf, &e1);
  161.             break;
  162.         }
  163.         aerr();
  164.         break;
  165.  
  166.     case S_6800:
  167.         m68out(op);
  168.         break;        
  169.  
  170.     case S_SDP:
  171.         expr(&e1, 0);
  172.         amp = NULL;
  173.         if ((c = getnb()) == ',') {
  174.             getid(id, -1);
  175.             amp = alookup(id);
  176.             if ( amp == NULL) {
  177.                 err('u');
  178.             }
  179.         } else {
  180.             unget(c);
  181.         }
  182.         if (amp) {
  183.             sdp->s_area = amp;
  184.         } else {
  185.             sdp->s_area = dot->s_area;
  186.         }
  187.         sdp->s_addr = e1.e_addr & ~0xFF;
  188.         lmode = SLIST;
  189.         break;
  190.  
  191.     default:
  192.         err('o');
  193.     }
  194. }
  195.  
  196. /*
  197.  * General Output Routine
  198.  */
  199. VOID
  200. genout(cpg, op, rf, esp)
  201. register int cpg, op, rf;
  202. register struct expr *esp;
  203. {
  204.     int espv;
  205.     struct area *espa;
  206.     int disp, flag;
  207.  
  208.     espv = esp->e_addr;
  209.     espa = esp->e_base.e_ap;
  210.     switch (esp->e_mode) {
  211.  
  212.     case S_IMB:
  213.         if (cpg)
  214.             outab(cpg);
  215.         outab(op);
  216.         outrb(esp, 0);
  217.         break;
  218.  
  219.     case S_IMW:
  220.         if (cpg)
  221.             outab(cpg);
  222.         outab(op);
  223.         outrw(esp, 0);
  224.         break;
  225.  
  226.     case S_DIR:
  227.         if (cpg)
  228.             outab(cpg);
  229.         if (rf == S_SOP) {
  230.             outab(op&0x0F);
  231.         } else {
  232.             outab(op|0x10);
  233.         }
  234.         if (espa && espa != sdp->s_area)
  235.             rerr();
  236.         espv = espv - sdp->s_addr;
  237.         if (espv & ~0xFF)
  238.             aerr();
  239.         outab(espv);
  240.         break;
  241.  
  242.     case S_EXT:
  243.         if (cpg)
  244.             outab(cpg);
  245.         if (index) {
  246.             outab(op|0x20);
  247.             outab(index|0x0F);
  248.             outrw(esp, 0);
  249.             break;
  250.         }
  251.         outab(op|0x30);
  252.         outrw(esp, 0);
  253.         break;
  254.  
  255.     case S_IND:
  256.         if (cpg)
  257.             outab(cpg);
  258.         outab(op|0x20);
  259.         outab(index);
  260.         break;
  261.  
  262.     case S_PC:
  263.         if (espa) {
  264.             aerr();
  265.             break;
  266.         }
  267.         if (cpg)
  268.             outab(cpg);
  269.         outab(op|0x20);
  270.         if (pass == 0) {
  271.             dot->s_addr += 3;
  272.         } else
  273.         if (pass == 1) {
  274.             if (esp->e_addr >= dot->s_addr)
  275.                 esp->e_addr -= fuzz;
  276.             dot->s_addr += 2;
  277.             disp = esp->e_addr;
  278.             flag = 0;
  279.             if (disp<-128 || disp>127)
  280.                 ++flag;
  281.             if (setbit(flag))
  282.                 ++dot->s_addr;
  283.         } else {
  284.             if (getbit()) {
  285.                 outab(index|0x01);
  286.                 outaw(espv);
  287.             } else {
  288.                 outab(index);
  289.                 outab(espv);
  290.             }
  291.         }
  292.         break;
  293.  
  294.     case S_PCR:
  295.         if (cpg)
  296.             outab(cpg);
  297.         outab(op|0x20);
  298.         if (pass == 0) {
  299.             dot->s_addr += 3;
  300.         } else
  301.         if (espa && espa != dot->s_area) {
  302.             outab(index|0x01);
  303.             outrw(esp, 1);
  304.         } else
  305.         if (pass == 1) {
  306.             if (esp->e_addr >= dot->s_addr)
  307.                 esp->e_addr -= fuzz;
  308.             dot->s_addr += 2;
  309.             disp = esp->e_addr - dot->s_addr;
  310.             flag = 0;
  311.             if (disp<-128 || disp>127)
  312.                 ++flag;
  313.             if (setbit(flag))
  314.                 ++dot->s_addr;
  315.         } else {
  316.             if (getbit()) {
  317.                 outab(index|0x01);
  318.                 disp = espv - dot->s_addr - 2;
  319.                 outaw(disp);
  320.             } else {
  321.                 outab(index);
  322.                 disp = espv - dot->s_addr - 1;
  323.                 outab(disp);
  324.             }
  325.         }
  326.         break;
  327.  
  328.     case S_OFST:
  329.         if (cpg)
  330.             outab(cpg);
  331.         outab(op|0x20);
  332.         if (pass == 0) {
  333.             dot->s_addr += 3;
  334.         } else
  335.         if (espa) {
  336.             outab(index|0x09);
  337.             outrw(esp, 0);
  338.         } else
  339.         if (pass == 1) {
  340.             if (esp->e_addr >= dot->s_addr)
  341.                 esp->e_addr -= fuzz;
  342.             dot->s_addr += 1;
  343.             flag = 0;
  344.             if (espv <- 128 || espv > 127)
  345.                 ++flag;
  346.             if (setbit(flag)) {
  347.                 dot->s_addr += 2;
  348.             } else {
  349.                 flag = index & 0x10;
  350.                 if (espv <- 16 || espv > 15)
  351.                     ++flag;
  352.                 if (setbit(flag))
  353.                     ++dot->s_addr;
  354.             }
  355.         } else {
  356.             if (getbit()) {
  357.                 outab(index|0x09);
  358.                 outaw(espv);
  359.             } else {
  360.                 if (getbit()) {
  361.                     outab(index|0x08);
  362.                     outab(espv);
  363.                 } else {
  364.                     outab((index & 0x60) | (espv & 0x1F));
  365.                 }
  366.             }
  367.         }
  368.         break;
  369.  
  370.     case S_IMER:
  371.     default:
  372.         aerr();
  373.     }
  374. }
  375.  
  376. /*
  377.  * mc6800 compatibility output routine
  378.  */
  379. VOID
  380. m68out(i)
  381. int i;
  382. {
  383.     register char *ptr;
  384.     register int j;
  385.     ptr = (char *) &mc6800[i].opcode;
  386.     for (j=0; j<4 ; j++) {
  387.         if (i = *ptr++) {
  388.             outab(i);
  389.         } else {
  390.             break;
  391.         }
  392.     }
  393. }
  394.  
  395. /*
  396.  * Machine specific initialization.
  397.  * Set up the bit table.
  398.  * Reset direct page.
  399.  */
  400. VOID
  401. minit()
  402. {
  403.     bp = bb;
  404.     bm = 1;
  405.     sdp->s_addr = 0;
  406.     sdp->s_area = dot->s_area;
  407. }
  408.  
  409. /*
  410.  * Store `b' in the next slot of the bit table.
  411.  * If no room, force the longer form of the offset.
  412.  */
  413. int
  414. setbit(b)
  415. {
  416.     if (bp >= &bb[NB])
  417.         return(1);
  418.     if (b)
  419.         *bp |= bm;
  420.     bm <<= 1;
  421.     if (bm == 0) {
  422.         bm = 1;
  423.         ++bp;
  424.     }
  425.     return(b);
  426. }
  427.  
  428. /*
  429.  * Get the next bit from the bit table.
  430.  * If none left, return a `1'.
  431.  * This will force the longer form of the offset.
  432.  */
  433. int
  434. getbit()
  435. {
  436.     register f;
  437.  
  438.     if (bp >= &bb[NB])
  439.         return (1);
  440.     f = *bp & bm;
  441.     bm <<= 1;
  442.     if (bm == 0) {
  443.         bm = 1;
  444.         ++bp;
  445.     }
  446.     return (f);
  447. }
  448.  
  449. /*
  450.  * The next character must be a
  451.  * comma.
  452.  */
  453. int
  454. comma()
  455. {
  456.     if (getnb() != ',')
  457.         qerr();
  458.     return(1);
  459. }
  460.