home *** CD-ROM | disk | FTP | other *** search
- /*
- * MC68HC11 specific processing
- */
-
- #define PAGE1 0x00
- #define PAGE2 0x18
- #define PAGE3 0x1A
- #define PAGE4 0xCD
-
- /* addressing modes */
- #define IMMED 0
- #define INDX 1
- #define INDY 2
- #define LIMMED 3 /* long immediate */
- #define OTHER 4
-
- int yflag = 0; /* YNOIMM, YLIMM, and CPD flag */
-
- /*
- * localinit --- machine specific initialization
- */
- localinit()
- {
- }
-
- /*
- * do_op --- process mnemonic
- *
- * Called with the base opcode and it's class. Optr points to
- * the beginning of the operand field.
- */
- do_op(opcode,class)
- int opcode; /* base opcode */
- int class; /* mnemonic class */
- {
- int dist; /* relative branch distance */
- int amode; /* indicated addressing mode */
- char *peek;
-
- /* guess at addressing mode */
- peek = Optr;
- amode = OTHER;
- while( !delim(*peek) && *peek != EOS) /* check for comma in operand field */
- if( *peek++ == ',' ){
- if( mapdn(*peek) == 'y' )
- amode = INDY;
- else
- amode = INDX;
- break;
- }
- if( *Optr == '#' ) amode = IMMED;
-
- yflag = 0;
- switch(class){
- case P2INH:
- emit(PAGE2);
- case INH: /* inherent addressing */
- emit(opcode);
- return;
- case REL: /* relative branches */
- eval();
- dist = Result - (Pc+2);
- emit(opcode);
- if( (dist >127 || dist <-128) && Pass==2){
- error("Branch out of Range");
- emit(lobyte(-2));
- return;
- }
- emit(lobyte(dist));
- return;
- case LONGIMM:
- if( amode == IMMED )
- amode = LIMMED;
- case NOIMM:
- if( amode == IMMED ){
- error("Immediate Addressing Illegal");
- return;
- }
- case GEN: /* general addressing */
- do_gen(opcode,amode,PAGE1,PAGE1,PAGE2);
- return;
- case GRP2:
- if( amode == INDY ){
- Cycles++;
- emit(PAGE2);
- amode = INDX;
- }
- if( amode == INDX )
- do_indexed(opcode);
- else{ /* extended addressing */
- eval();
- emit(opcode+0x10);
- eword(Result);
- }
- return;
- case CPD: /* cmpd */
- if( amode == IMMED )
- amode = LIMMED;
- if( amode == INDY )
- yflag=1;
- do_gen(opcode,amode,PAGE3,PAGE3,PAGE4);
- return;
- case XNOIMM: /* stx */
- if( amode == IMMED ){
- error("Immediate Addressing Illegal");
- return;
- }
- case XLIMM: /* cpx, ldx */
- if( amode == IMMED )
- amode = LIMMED;
- do_gen(opcode,amode,PAGE1,PAGE1,PAGE4);
- return;
- case YNOIMM: /* sty */
- if( amode == IMMED ){
- error("Immediate Addressing Illegal");
- return;
- }
- case YLIMM: /* cpy, ldy */
- if(amode == INDY)
- yflag=1;
- if( amode == IMMED )
- amode = LIMMED;
- do_gen(opcode,amode,PAGE2,PAGE3,PAGE2);
- return;
- case BTB: /* bset, bclr */
- case SETCLR: /* brset, brclr */
- opcode = bitop(opcode,amode,class);
-
- if (amode == INDX)
- Cycles++;
- if( amode == INDY ){
- Cycles+=2;
- emit(PAGE2);
- amode = INDX;
- }
- emit(opcode);
- eval();
- emit(lobyte(Result)); /* address */
- if( amode == INDX )
- Optr += 2; /* skip ,x or ,y */
- eval();
- emit(lobyte(Result)); /* mask */
- if( class == SETCLR )
- return;
- eval();
- dist = Result - (Pc+1);
- if( (dist >127 || dist <-128) && Pass==2){
- error("Branch out of Range");
- dist = Old_pc - (Pc+1);
- }
- emit(lobyte(dist));
- return;
- default:
- fatal("Error in Mnemonic table");
- }
- }
-
- /*
- * bitop --- adjust opcode on bit manipulation instructions
- */
- bitop(op,mode,class)
- int op;
- int mode;
- int class;
- {
- if( mode == INDX || mode == INDY )
- return(op);
- if( class == SETCLR )
- return(op-8);
- else if(class==BTB)
- return(op-12);
- else
- fatal("bitop");
- }
-
- /*
- * do_gen --- process general addressing modes
- */
- do_gen(op,mode,pnorm,px,py)
- int op; /* base opcode */
- int mode; /* addressing mode */
- int pnorm; /* page for normal addressing modes: IMM,DIR,EXT */
- int px; /* page for INDX addressing */
- int py; /* page for INDY addressing */
- {
- switch(mode){
- case LIMMED:
- Optr++;
- epage(pnorm);
- emit(op);
- eval();
- eword(Result);
- break;
- case IMMED:
- Optr++;
- epage(pnorm);
- emit(op);
- eval();
- emit(lobyte(Result));
- break;
- case INDY:
- if(yflag)
- Cycles += 2;
- else
- Cycles += 3;
- epage(py);
- do_indexed(op+0x20);
- break;
- case INDX:
- Cycles+=2;
- epage(px);
- do_indexed(op+0x20);
- break;
- case OTHER:
- eval();
- epage(pnorm);
- if(Force_word){
- emit(op+0x30);
- eword(Result);
- Cycles+=2;
- break;
- }
- if(Force_byte){
- emit(op+0x10);
- emit(lobyte(Result));
- Cycles++;
- break;
- }
- if(Result>=0 && Result <=0xFF){
- emit(op+0x10);
- emit(lobyte(Result));
- Cycles++;
- break;
- }
- else {
- emit(op+0x30);
- eword(Result);
- Cycles+=2;
- break;
- }
- break;
- default:
- error("Unknown Addressing Mode");
- }
- }
-
- /*
- * do_indexed --- handle all wierd stuff for indexed addressing
- */
- do_indexed(op)
- int op;
- {
- char c;
-
- emit(op);
- eval();
- if( *Optr++ != ',' )
- error("Syntax");
- c = mapdn(*Optr++);
- if( c != 'x' && c != 'y')
- warn("Indexed Addressing Assumed");
- if( Result < 0 || Result > 255)
- warn("Value Truncated");
- emit(lobyte(Result));
- }
-
- /*
- * epage --- emit page prebyte
- */
- epage(p)
- int p;
- {
- if( p != PAGE1 ) /* PAGE1 means no prebyte */
- emit(p);
- }
-