home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / motasm / src_c_do9 < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-23  |  11.2 KB  |  612 lines

  1. #define MICRO 6809
  2.  
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6.  
  7. #include "proto.h"
  8. #include "proto9.h"
  9. #include "as.h"
  10. #include "extvars.h"
  11. #include "structs.h"
  12.  
  13. /*
  14.  *      MC6809 specific processing
  15.  */
  16.  
  17. #define PAGE2 0x10
  18. #define PAGE3 0x11
  19. #define IPBYTE 0x9F /* extended indirect postbyte */
  20. #define SWI     0x3F
  21.  
  22. /* register names */
  23.  
  24. #define RD 0
  25. #define RX 1
  26. #define RY 2
  27. #define RU 3
  28. #define RS 4
  29. #define RPC 5
  30. #define RA 8
  31. #define RB 9
  32. #define RCC 10
  33. #define RDP 11
  34. #define RPCR 12
  35.  
  36. /* convert tfr/exg reg number into psh/pul format */
  37. int     regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
  38. int     rcycl[]= { 2,2, 2, 2, 2, 2,  0,0,1,1,1,1,0};
  39.  
  40. /* addressing modes */
  41. #define IMMED   0       /* immediate */
  42. #define IND     1       /* indexed */
  43. #define INDIR   2       /* indirect */
  44. #define OTHER   3       /* NOTA */
  45.  
  46. /*
  47.  *      localinit --- machine specific initialization
  48.  */
  49. void
  50. localinit(void)
  51. {
  52. }
  53.  
  54. /*
  55.  *      do_op --- process mnemonic
  56.  *
  57.  * Called with the base opcode and it's class. Optr points to
  58.  * the beginning of the operand field.
  59.  */
  60. void do_op(int opcode, int class)
  61. /*int opcode; *//* base opcode */
  62. /*int class; *//* mnemonic class */
  63. {
  64.  int     dist;   /* relative branch distance */
  65.  int     src,dst;/* source and destination registers */
  66.  int     pbyte;  /* postbyte value */
  67.  int     amode;  /* indicated addressing mode */
  68.  int j;
  69.  
  70.  amode = set_mode();     /* pickup indicated addressing mode */
  71.  
  72.  switch(class){
  73.   case INH:                       /* inherent addressing */
  74.    emit(opcode);
  75.    return;
  76.   case GEN:                       /* general addressing */
  77.    do_gen(opcode,amode);
  78.    return;
  79.   case IMM:                       /* immediate addressing */
  80.    if( amode != IMMED ){
  81.     error("Immediate Operand Required");
  82.     return;
  83.     }
  84.    Optr++;
  85.    eval();
  86.    emit(opcode);
  87.    emit(lobyte(Result));
  88.    return;
  89.   case REL:                       /* short relative branches */
  90.    eval();
  91.    dist = Result - (Pc+2);
  92.    emit(opcode);
  93.    if( (dist >127 || dist <-128) && Pass==2){
  94.     error("Branch out of Range");
  95.     emit(lobyte(-2));
  96.     return;
  97.     }
  98.    emit(lobyte(dist));
  99.    return;
  100.   case P2REL:                     /* long relative branches */
  101.    eval();
  102.    dist = Result - (Pc+4);
  103.    emit(PAGE2);
  104.    emit(opcode);
  105.    eword(dist);
  106.    return;
  107.   case P1REL:                     /* lbra and lbsr */
  108.    if( amode == IMMED)
  109.     Optr++; /* kludge for C compiler */
  110.    eval();
  111.    dist = Result - (Pc+3);
  112.    emit(opcode);
  113.    eword(dist);
  114.    return;
  115.   case NOIMM:
  116.    if( amode == IMMED ){
  117.     error("Immediate Addressing Illegal");
  118.     return;
  119.     }
  120.    do_gen(opcode,amode);
  121.    return;
  122.   case P2GEN:
  123.    emit(PAGE2);
  124.    if( amode == IMMED ){
  125.     emit(opcode);
  126.     Optr++;
  127.     eval();
  128.     eword(Result);
  129.     return;
  130.     }
  131.    do_gen(opcode,amode);
  132.    return;
  133.   case P3GEN:
  134.    emit(PAGE3);
  135.    if( amode == IMMED ){
  136.     emit(opcode);
  137.     Optr++;
  138.     eval();
  139.     eword(Result);
  140.     return;
  141.     }
  142.    do_gen(opcode,amode);
  143.    return;
  144.   case RTOR:                      /* tfr and exg */
  145.    emit(opcode);
  146.    src = regnum();
  147.    while(alpha(*Optr))Optr++;
  148.    if(src==ERR){
  149.     error("Register Name Required");
  150.     emit(0);
  151.     return;
  152.     }
  153.    if(*Optr++ != ','){
  154.     error("Missing ,");
  155.     emit(0);
  156.     return;
  157.     }
  158.    dst = regnum();
  159.    while(alpha(*Optr))Optr++;
  160.    if(dst==ERR){
  161.     error("Register Name Required");
  162.     emit(0);
  163.     return;
  164.     }
  165.    if( src==RPCR || dst==RPCR){
  166.     error("PCR illegal here");
  167.     emit(0);
  168.     return;
  169.     }
  170.    if( (src <=5 && dst >=8) ||
  171.        (src >=8 && dst <=5)){
  172.     error("Register Size Mismatch");
  173.     emit(0);
  174.     return;
  175.     }
  176.    emit( (src<<4)+dst );
  177.    return;
  178.   case INDEXED:                   /* indexed addressing only */
  179.    if( *Optr == '#'){
  180.     Optr++;         /* kludge city */
  181.     amode = IND;
  182.     }
  183.    if( amode != IND ){
  184.     error("Indexed Addressing Required");
  185.     return;
  186.     }
  187.    do_indexed(opcode);
  188.    return;
  189.   case RLIST:                     /* pushes and pulls */
  190.    if(*Operand == EOS){
  191.     error("Register List Required");
  192.     return;
  193.     }
  194.    emit(opcode);
  195.    pbyte = 0;
  196.    do{
  197.     j = regnum();
  198.     if( j == ERR || j==RPCR)
  199.      error("Illegal Register Name");
  200.     else if(j==RS && (opcode==52))
  201.      error("Can't Push S on S");
  202.     else if(j==RU && (opcode==54))
  203.      error("Can't Push U on U");
  204.     else if(j==RS && (opcode==53))
  205.      error("Can't Pull S from S");
  206.     else if(j==RU && (opcode==55))
  207.      error("Can't Pull U from U");
  208.     else{
  209.      pbyte |= regs[j];
  210.      Cycles += rcycl[j];
  211.      }
  212.     while(*Optr != EOS && alpha(*Optr))Optr++;
  213.    }while( *Optr++ == ',' );
  214.    emit(lobyte(pbyte));
  215.    return;
  216.   case P2NOIMM:
  217.    if( amode == IMMED )
  218.     error("Immediate Addressing Illegal");
  219.    else{
  220.     emit(PAGE2);
  221.     do_gen(opcode,amode);
  222.     }
  223.    return;
  224.   case P2INH:                     /* Page 2 inherent */
  225.    emit(PAGE2);
  226.    emit(opcode);
  227.    return;
  228.   case P3INH:                     /* Page 3 inherent */
  229.    emit(PAGE3);
  230.    emit(opcode);
  231.    return;
  232.   case LONGIMM:
  233.    if( amode == IMMED ){
  234.     emit(opcode);
  235.     Optr++;
  236.     eval();
  237.     eword(Result);
  238.     }
  239.    else
  240.     do_gen(opcode,amode);
  241.    return;
  242.   case GRP2:
  243.    if( amode == IND ){
  244.     do_indexed(opcode+0x60);
  245.     return;
  246.     }
  247.    else if( amode == INDIR){
  248.     Optr++;
  249.     emit(opcode + 0x60);
  250.     emit(IPBYTE);
  251.     eval();
  252.     eword(Result);
  253.     Cycles += 7;
  254.     if(*Optr == ']'){
  255.      Optr++;
  256.      return;
  257.      }
  258.     error("Missing ']'");
  259.     return;
  260.     }
  261.    eval();
  262.    if(Force_word){
  263.     emit(opcode+0x70);
  264.     eword(Result);
  265.     Cycles += 3;
  266.     return;
  267.     }
  268.    if(Force_byte){
  269.     emit(opcode);
  270.     emit(lobyte(Result));
  271.     Cycles += 2;
  272.     return;
  273.     }
  274.    if(Result>=0 && Result <=0xFF){
  275.     emit(opcode);
  276.     emit(lobyte(Result));
  277.     Cycles += 2;
  278.     return;
  279.     }
  280.    else {
  281.     emit(opcode+0x70);
  282.     eword(Result);
  283.     Cycles += 3;
  284.     return;
  285.     }
  286.   case SYS:                       /* system call */
  287.    emit(SWI);
  288.    eval();
  289.    emit(lobyte(Result));
  290.    return;
  291.   default:
  292.    fatal("Error in Mnemonic table");
  293.   }
  294. }
  295.  
  296.  
  297. /*
  298.  *      do_gen --- process general addressing mode stuff
  299.  */
  300. void do_gen(int op, int mode)
  301. {
  302.  if( mode == IMMED){
  303.   Optr++;
  304.   emit(op);
  305.   eval();
  306.   emit(lobyte(Result));
  307.   return;
  308.   }
  309.  else if( mode == IND ){
  310.   do_indexed(op+0x20);
  311.   return;
  312.   }
  313.  else if( mode == INDIR){
  314.   Optr++;
  315.   emit(op+0x20);
  316.   emit(IPBYTE);
  317.   eval();
  318.   eword(Result);
  319.   Cycles += 7;
  320.   if(*Optr == ']'){
  321.    Optr++;
  322.    return;
  323.    }
  324.   error("Missing ']'");
  325.   return;
  326.   }
  327.  else if( mode == OTHER){
  328.   eval();
  329.   if(Force_word){
  330.    emit(op+0x30);
  331.    eword(Result);
  332.    Cycles += 3;
  333.    return;
  334.    }
  335.   if(Force_byte){
  336.    emit(op+0x10);
  337.    emit(lobyte(Result));
  338.    Cycles += 2;
  339.    return;
  340.    }
  341.   if(Result>=0 && Result <=0xFF){
  342.    emit(op+0x10);
  343.    emit(lobyte(Result));
  344.    Cycles += 2;
  345.    return;
  346.    }
  347.   else {
  348.    emit(op+0x30);
  349.    eword(Result);
  350.    Cycles += 3;
  351.    return;
  352.    }
  353.   }
  354.  else {
  355.   error("Unknown Addressing Mode");
  356.   return;
  357.   }
  358. }
  359.  
  360. /*
  361.  *      do_indexed --- handle all wierd stuff for indexed addressing
  362.  */
  363. void do_indexed(int op)
  364. {
  365.  int     pbyte;
  366.  int     j,k;
  367.  int     predec,pstinc;
  368.  
  369.  Cycles += 2;    /* indexed is always 2+ base cycle count */
  370.  predec=0;
  371.  pstinc=0;
  372.  pbyte=128;
  373.  emit(op);
  374.  if(*Optr=='['){
  375.   pbyte |= 0x10;    /* set indirect bit */
  376.   Optr++;
  377.   if( !any((char)']',Optr))
  378.    error("Missing ']'");
  379.   Cycles += 3;    /* indirection takes this much longer */
  380.   }
  381.  j=regnum();
  382.  if(j==RA){
  383.   Cycles++;
  384.   abd_index(pbyte+6);
  385.   return;
  386.   }
  387.  if(j==RB){
  388.   Cycles++;
  389.   abd_index(pbyte+5);
  390.   return;
  391.   }
  392.  if(j==RD){
  393.   Cycles += 4;
  394.   abd_index(pbyte+11);
  395.   return;
  396.   }
  397.  eval();
  398.  Optr++;
  399.  while(*Optr=='-'){
  400.   predec++;
  401.   Optr++;
  402.   }
  403.  j=regnum();
  404.  while( alpha(*Optr) )Optr++;
  405.  while(*Optr=='+'){
  406.   pstinc++;
  407.   Optr++;
  408.   }
  409.  if(j==RPC || j==RPCR){
  410.   if( pstinc || predec ){
  411.    error("Auto Inc/Dec Illegal on PC");
  412.    return;
  413.    }
  414.   if(j==RPC){
  415.    if(Force_word){
  416.     emit(pbyte+13);
  417.     eword(Result);
  418.     Cycles += 5;
  419.     return;
  420.     }
  421.    if(Force_byte){
  422.     emit(pbyte+12);
  423.     emit(lobyte(Result));
  424.     Cycles++;
  425.     return;
  426.     }
  427.    if(Result>=-128 && Result <=127){
  428.     emit(pbyte+12);
  429.     emit(lobyte(Result));
  430.     Cycles++;
  431.     return;
  432.     }
  433.    else {
  434.     emit(pbyte+13);
  435.     eword(Result);
  436.     Cycles += 5;
  437.     return;
  438.     }
  439.    }
  440.   /* PCR addressing */
  441.   if(Force_word){
  442.    emit(pbyte+13);
  443.    eword(Result-(Pc+2));
  444.    Cycles += 5;
  445.    return;
  446.    }
  447.   if(Force_byte){
  448.    emit(pbyte+12);
  449.    emit(lobyte(Result-(Pc+1)));
  450.    Cycles++;
  451.    return;
  452.    }
  453.   k=Result-(Pc+2);
  454.   if( k >= -128 && k <= 127){
  455.    emit(pbyte+12);
  456.    emit(lobyte(Result-(Pc+1)));
  457.    Cycles++;
  458.    return;
  459.    }
  460.   else{
  461.    emit(pbyte+13);
  462.    eword(Result-(Pc+2));
  463.    Cycles += 5;
  464.    return;
  465.    }
  466.   }
  467.  if(predec || pstinc){
  468.   if(Result != 0){
  469.    error("Offset must be Zero");
  470.    return;
  471.    }
  472.   if(predec>2 || pstinc>2){
  473.    error("Auto Inc/Dec by 1 or 2 only");
  474.    return;
  475.    }
  476.   if((predec==1 && (pbyte&0x10) != 0) ||
  477.      (pstinc==1 && (pbyte&0x10) != 0)){
  478.    error("No Auto Inc/Dec by 1 for Indirect");
  479.    return;
  480.    }
  481.   if(predec && pstinc){
  482.    error("Can't do both!");
  483.    return;
  484.    }
  485.   if(predec)
  486.    pbyte += predec+1;
  487.   if(pstinc)
  488.    pbyte += pstinc-1;
  489.   pbyte += rtype(j);
  490.   emit(pbyte);
  491.   Cycles += 1 + predec + pstinc;
  492.   return;
  493.   }
  494.  pbyte += rtype(j);
  495.  if(Force_word){
  496.   emit(pbyte+0x09);
  497.   eword(Result);
  498.   Cycles += 4;
  499.   return;
  500.   }
  501.  if(Force_byte){
  502.   emit(pbyte+0x08);
  503.   emit(lobyte(Result));
  504.   Cycles++;
  505.   return;
  506.   }
  507.  if(Result==0){
  508.   emit(pbyte+0x04);
  509.   return;
  510.   }
  511.  if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
  512.   pbyte &= 127;
  513.   pbyte += Result&31;
  514.   emit(pbyte);
  515.   Cycles++;
  516.   return;
  517.   }
  518.  if(Result >= -128 && Result <= 127){
  519.   emit(pbyte+0x08);
  520.   emit(lobyte(Result));
  521.   Cycles++;
  522.   return;
  523.   }
  524.  emit(pbyte+0x09);
  525.  eword(Result);
  526.  Cycles += 4;
  527.  return;
  528. }
  529.  
  530.  
  531. /*
  532.  *      abd_index --- a,b or d indexed
  533.  */
  534.  
  535. void abd_index(int pbyte)
  536. {
  537.  int     k;
  538.  
  539.  Optr += 2;
  540.  k=regnum();
  541.  pbyte += rtype(k);
  542.  emit(pbyte);
  543.  return;
  544. }
  545.  
  546. /*
  547.  *      rtype --- return register type in post-byte format
  548.  */
  549. int rtype(int r)
  550. {
  551.  switch(r){
  552.  case RX:        return(0x00);
  553.  case RY:        return(0x20);
  554.  case RU:        return(0x40);
  555.  case RS:        return(0x60);
  556.   }
  557.  error("Illegal Register for Indexed");
  558.  return(0);
  559. }
  560.  
  561. /*
  562.  *      set_mode --- determine addressing mode from operand field
  563.  */
  564. int set_mode()
  565. {
  566.  register char *p;
  567.  
  568.  if( *Operand == '#' )
  569.   return(IMMED);          /* immediate addressing */
  570.  p = Operand;
  571.  while( *p != EOS && *p != BLANK && *p != TAB){/* any , before break */
  572.   if( *p == ',')
  573.    return(IND);    /* indexed addressing */
  574.   p++;
  575.   }
  576.  if( *Operand == '[')
  577.   return(INDIR);          /* indirect addressing */
  578.  return(OTHER);                  /* NOTA */
  579. }
  580.  
  581. /*
  582.  *      regnum --- return register number of *Optr
  583.  */
  584. int regnum()
  585. {
  586.  if( head(Optr,"D" ))return(RD);
  587.  if( head(Optr,"d" ))return(RD);
  588.  if( head(Optr,"X" ))return(RX);
  589.  if( head(Optr,"x" ))return(RX);
  590.  if( head(Optr,"Y" ))return(RY);
  591.  if( head(Optr,"y" ))return(RY);
  592.  if( head(Optr,"U" ))return(RU);
  593.  if( head(Optr,"u" ))return(RU);
  594.  if( head(Optr,"S" ))return(RS);
  595.  if( head(Optr,"s" ))return(RS);
  596.  if( head(Optr,"PC" ))return(RPC);
  597.  if( head(Optr,"pc" ))return(RPC);
  598.  if( head(Optr,"PCR" ))return(RPCR);
  599.  if( head(Optr,"pcr" ))return(RPCR);
  600.  if( head(Optr,"A" ))return(RA);
  601.  if( head(Optr,"a" ))return(RA);
  602.  if( head(Optr,"B" ))return(RB);
  603.  if( head(Optr,"b" ))return(RB);
  604.  if( head(Optr,"CC" ))return(RCC);
  605.  if( head(Optr,"cc" ))return(RCC);
  606.  if( head(Optr,"DP" ))return(RDP);
  607.  if( head(Optr,"dp" ))return(RDP);
  608.  return(ERR);
  609. }
  610.  
  611.  
  612.