home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
c
/
library
/
xplatfrm
/
motxas
/
dohc5.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-23
|
5KB
|
231 lines
/*
* 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 */
{
char *skip_white();
int dist; /* relative branch distance */
int amode; /* indicated addressing mode */
char *peek;
/* guess at addressing mode */
peek = Optr;
amode = OTHER;
if( head(Operand,"X") || head(Operand,"x") ) {
if( delim(*(Operand+1)) )
amode = IND;
}
else while( !delim(*peek) ) { /* 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 */
if( eval() )
dist = Result - (Pc+2);
else dist = -2;
emit(opcode);
if( (dist >127 || dist <-128) && Pass==2){
error("Branch out of Range");
dist = -2;
}
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 += 1;
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("Missing comma");
Optr = skip_white(Optr);
eval();
emit(lobyte(Result));
if(class==SETCLR)
return;
/* else it's bit test and branch */
if(*Optr++ != ',') error("Missing comma");
Optr = skip_white(Optr);
if( eval() )
dist = Result - (Old_pc+3);
else dist = -3;
if( (dist >127 || dist <-128) && Pass==2){
error("Branch out of Range");
dist = -3;
}
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 += 2;
return;
}
if(Force_byte){
emit(op+0x10);
emit(lobyte(Result));
Cycles += 1;
return;
}
if(Result >= 0 && Result <= 0xFF){
emit(op+0x10);
emit(lobyte(Result));
Cycles += 1;
return;
}
else {
emit(op+0x20);
eword(Result);
Cycles += 2;
return;
}
}
else {
error("Unknown Addressing Mode");
return;
}
}
/*
* do_indexed --- handle all weird stuff for indexed addressing
*/
do_indexed(op)
int op;
{
if( *Optr != ',' && !head(Operand,"X") && !head(Operand,"x") ) {
eval();
if( !( *Optr++ == ',' && ( mapdn(*Optr) == 'x') ) )
warn("Indexed Addressing Assumed");
}
else { /* if no expression, fake it */
Force_word = NO;
Force_byte = NO;
Result = 0;
if( *Optr == ',' ) Optr++;
if( mapdn(*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 += 2;
return;
}
emit(op);
eword(Result);
Cycles += 3;
return;
}
Cycles += 2; /* 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("Address Offset Value Truncated");
emit(op+0x10);
emit(lobyte(Result));
return;
}
emit(op);
eword(Result);
Cycles++; /* 2 byte slightly slower */
return;
}