home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / emulate / x_comp / 68hc11 / do11.c < prev    next >
C/C++ Source or Header  |  1986-11-01  |  6KB  |  278 lines

  1. /*
  2.  *      MC68HC11 specific processing
  3.  */
  4.  
  5. #define PAGE1   0x00
  6. #define PAGE2   0x18
  7. #define PAGE3   0x1A
  8. #define PAGE4   0xCD
  9.  
  10. /* addressing modes */
  11. #define IMMED   0
  12. #define INDX    1
  13. #define INDY    2
  14. #define LIMMED  3       /* long immediate */
  15. #define OTHER   4
  16.  
  17. int     yflag = 0;      /* YNOIMM, YLIMM, and CPD flag */
  18.  
  19. /*
  20.  *      localinit --- machine specific initialization
  21.  */
  22. localinit()
  23. {
  24. }
  25.  
  26. /*
  27.  *      do_op --- process mnemonic
  28.  *
  29.  * Called with the base opcode and it's class. Optr points to
  30.  * the beginning of the operand field.
  31.  */
  32. do_op(opcode,class)
  33. int opcode; /* base opcode */
  34. int class; /* mnemonic class */
  35. {
  36.  int     dist;   /* relative branch distance */
  37.  int     amode;  /* indicated addressing mode */
  38.  char *peek;
  39.  
  40.  /* guess at addressing mode */
  41.  peek = Optr;
  42.  amode = OTHER;
  43.  while( !delim(*peek) && *peek != EOS)  /* check for comma in operand field */
  44.   if( *peek++ == ',' ){
  45.    if( mapdn(*peek) == 'y' )
  46.     amode = INDY;
  47.    else
  48.     amode = INDX;
  49.    break;
  50.    }
  51.  if( *Optr == '#' ) amode = IMMED;
  52.  
  53.  yflag = 0;
  54.  switch(class){
  55.   case P2INH:
  56.    emit(PAGE2);
  57.   case INH:                       /* inherent addressing */
  58.    emit(opcode);
  59.    return;
  60.   case REL:                       /* relative branches */
  61.    eval();
  62.    dist = Result - (Pc+2);
  63.    emit(opcode);
  64.    if( (dist >127 || dist <-128) && Pass==2){
  65.     error("Branch out of Range");
  66.     emit(lobyte(-2));
  67.     return;
  68.     }
  69.    emit(lobyte(dist));
  70.    return;
  71.   case LONGIMM:
  72.    if( amode == IMMED )
  73.     amode = LIMMED;
  74.   case NOIMM:
  75.    if( amode == IMMED ){
  76.     error("Immediate Addressing Illegal");
  77.     return;
  78.     }
  79.   case GEN:                       /* general addressing */
  80.    do_gen(opcode,amode,PAGE1,PAGE1,PAGE2);
  81.    return;
  82.   case GRP2:
  83.    if( amode == INDY ){
  84.     Cycles++;
  85.     emit(PAGE2);
  86.     amode = INDX;
  87.     }
  88.    if( amode == INDX )
  89.     do_indexed(opcode);
  90.    else{   /* extended addressing */
  91.     eval();
  92.     emit(opcode+0x10);
  93.     eword(Result);
  94.     }
  95.    return;
  96.   case CPD:               /* cmpd */
  97.    if( amode == IMMED )
  98.     amode = LIMMED;
  99.    if( amode == INDY )
  100.     yflag=1;
  101.    do_gen(opcode,amode,PAGE3,PAGE3,PAGE4);
  102.    return;
  103.   case XNOIMM:            /* stx */
  104.    if( amode == IMMED ){
  105.     error("Immediate Addressing Illegal");
  106.     return;
  107.     }
  108.   case XLIMM:             /* cpx, ldx */
  109.    if( amode == IMMED )
  110.     amode = LIMMED;
  111.    do_gen(opcode,amode,PAGE1,PAGE1,PAGE4);
  112.    return;
  113.   case YNOIMM:            /* sty */
  114.    if( amode == IMMED ){
  115.     error("Immediate Addressing Illegal");
  116.     return;
  117.     }
  118.   case YLIMM:             /* cpy, ldy */
  119.    if(amode == INDY)
  120.     yflag=1;
  121.    if( amode == IMMED )
  122.     amode = LIMMED;
  123.    do_gen(opcode,amode,PAGE2,PAGE3,PAGE2);
  124.    return;
  125.   case BTB:               /* bset, bclr */
  126.   case SETCLR:            /* brset, brclr */
  127.    opcode = bitop(opcode,amode,class);
  128.  
  129.    if (amode == INDX)
  130.     Cycles++;
  131.    if( amode == INDY ){
  132.     Cycles+=2;
  133.     emit(PAGE2);
  134.     amode = INDX;
  135.     }
  136.    emit(opcode);
  137.    eval();
  138.    emit(lobyte(Result));   /* address */
  139.    if( amode == INDX )
  140.     Optr += 2;      /* skip ,x or ,y */
  141.    Optr = skip_white(Optr);
  142.    eval();
  143.    emit(lobyte(Result));   /* mask */
  144.    if( class == SETCLR )
  145.     return;
  146.    Optr = skip_white(Optr);
  147.    eval();
  148.    dist = Result - (Pc+1);
  149.    if( (dist >127 || dist <-128) && Pass==2){
  150.     error("Branch out of Range");
  151.     dist = Old_pc - (Pc+1);
  152.     }
  153.    emit(lobyte(dist));
  154.    return;
  155.   default:
  156.    fatal("Error in Mnemonic table");
  157.   }
  158. }
  159.  
  160. /*
  161.  *      bitop --- adjust opcode on bit manipulation instructions
  162.  */
  163. bitop(op,mode,class)
  164. int op;
  165. int mode;
  166. int class;
  167. {
  168.  if( mode == INDX || mode == INDY )
  169.   return(op);
  170.  if( class == SETCLR )
  171.   return(op-8);
  172.  else if(class==BTB)
  173.   return(op-12);
  174.  else
  175.   fatal("bitop");
  176. }
  177.  
  178. /*
  179.  *      do_gen --- process general addressing modes
  180.  */
  181. do_gen(op,mode,pnorm,px,py)
  182. int     op;     /* base opcode */
  183. int     mode;   /* addressing mode */
  184. int     pnorm;  /* page for normal addressing modes: IMM,DIR,EXT */
  185. int     px;     /* page for INDX addressing */
  186. int     py;     /* page for INDY addressing */
  187. {
  188.  switch(mode){
  189.  case LIMMED:
  190.   Optr++;
  191.   epage(pnorm);
  192.   emit(op);
  193.   eval();
  194.   eword(Result);
  195.   break;
  196.  case IMMED:
  197.   Optr++;
  198.   epage(pnorm);
  199.   emit(op);
  200.   eval();
  201.   emit(lobyte(Result));
  202.   break;
  203.  case INDY:
  204.   if(yflag)
  205.    Cycles += 2;
  206.   else
  207.    Cycles += 3;
  208.   epage(py);
  209.   do_indexed(op+0x20);
  210.   break;
  211.  case INDX:
  212.   Cycles+=2;
  213.   epage(px);
  214.   do_indexed(op+0x20);
  215.   break;
  216.  case OTHER:
  217.   eval();
  218.   epage(pnorm);
  219.   if(Force_word){
  220.    emit(op+0x30);
  221.    eword(Result);
  222.    Cycles+=2;
  223.    break;
  224.    }
  225.   if(Force_byte){
  226.    emit(op+0x10);
  227.    emit(lobyte(Result));
  228.    Cycles++;
  229.    break;
  230.    }
  231.   if(Result>=0 && Result <=0xFF){
  232.    emit(op+0x10);
  233.    emit(lobyte(Result));
  234.    Cycles++;
  235.    break;
  236.    }
  237.   else {
  238.    emit(op+0x30);
  239.    eword(Result);
  240.    Cycles+=2;
  241.    break;
  242.    }
  243.   break;
  244.  default:
  245.   error("Unknown Addressing Mode");
  246.  }
  247. }
  248.  
  249. /*
  250.  *      do_indexed --- handle all wierd stuff for indexed addressing
  251.  */
  252. do_indexed(op)
  253. int op;
  254. {
  255.  char c;
  256.  
  257.  emit(op);
  258.  eval();
  259.  if( *Optr++ != ',' )
  260.   error("Syntax");
  261.  c = mapdn(*Optr++);
  262.  if( c != 'x' && c != 'y')
  263.   warn("Indexed Addressing Assumed");
  264.  if( Result < 0 || Result > 255)
  265.   warn("Value Truncated");
  266.  emit(lobyte(Result));
  267. }
  268.  
  269. /*
  270.  *      epage --- emit page prebyte
  271.  */
  272. epage(p)
  273. int p;
  274. {
  275.  if( p != PAGE1 )        /* PAGE1 means no prebyte */
  276.   emit(p);
  277. }
  278.