/* * MC6805 specific processing */ /* addressing modes */ #define IMMED 0 /* immediate */ #define IND 1 /* indexed */ #define OTHER 2 /* NOTA */ /* * 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++ == ',' ){ amode = IND; break; } if( *Optr == '#' ) amode = IMMED; switch(class){ case INH: /* inherent addressing */ emit(opcode); return; case GEN: /* general addressing */ do_gen(opcode,amode); return; case REL: /* short 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 NOIMM: if( amode == IMMED ){ error("Immediate Addressing Illegal"); return; } do_gen(opcode,amode); return; case GRP2: if( amode == IND ){ do_indexed(opcode+0x20); return; } eval(); Cycles += 2; if(Force_byte){ emit(opcode); emit(lobyte(Result)); return; } if(Result>=0 && Result <=0xFF){ emit(opcode); emit(lobyte(Result)); return; } error("Extended Addressing not allowed"); return; case SETCLR: case BTB: eval(); if(Result <0 || Result >7){ error("Bit Number must be 0-7"); return; } emit( opcode | (Result << 1)); if(*Optr++ != ',')error("SYNTAX"); eval(); emit(lobyte(Result)); if(class==SETCLR) return; /* else it's bit test and branch */ if(*Optr++ != ',')error("SYNTAX"); eval(); dist = Result - (Old_pc+3); if( (dist >127 || dist <-128) && Pass==2){ error("Branch out of Range"); emit(lobyte(-3)); return; } emit(lobyte(dist)); return; default: fatal("Error in Mnemonic table"); } } /* * do_gen --- process general addressing */ do_gen(op,mode) int op; int mode; { if( mode == IMMED){ Optr++; emit(op); eval(); emit(lobyte(Result)); return; } else if( mode == IND ){ do_indexed(op+0x30); return; } else if( mode == OTHER){ /* direct or extended addressing */ eval(); if(Force_word){ emit(op+0x20); eword(Result); Cycles += 3; return; } if(Force_byte){ emit(op+0x10); emit(lobyte(Result)); Cycles += 2; return; } if(Result >= 0 && Result <= 0xFF){ emit(op+0x10); emit(lobyte(Result)); Cycles += 2; return; } else { emit(op+0x20); eword(Result); Cycles += 3; return; } } else { error("Unknown Addressing Mode"); return; } } /* * do_indexed --- handle all wierd stuff for indexed addressing */ do_indexed(op) int op; { eval(); if(!(*Optr++ == ',' && (*Optr == 'x' || *Optr == 'X'))) warn("Indexed Addressing Assumed"); if(Force_word){ if(op < 0x80 ){ /* group 2, no extended addressing */ emit(op+0x10); /* default to one byte indexed */ emit(lobyte(Result)); Cycles += 3; return; } emit(op); eword(Result); Cycles += 4; return; } Cycles += 3; /* assume 1 byte indexing */ if(Force_byte){ emit(op+0x10); emit(lobyte(Result)); return; } if(Result==0){ emit(op+0x20); Cycles--; /* ,x slightly faster */ return; } if(Result>0 && Result <=0xFF){ emit(op+0x10); emit(lobyte(Result)); return; } if( op < 0x80 ){ warn("Value Truncated"); emit(op+0x10); emit(lobyte(Result)); return; } emit(op); eword(Result); Cycles++; /* 2 byte slightly slower */ return; }