fceux/drivers/win/asm.inc

211 lines
7.6 KiB
SourcePawn

if (!strlen(astr)) {
//Implied instructions
if (!strcmp(ins,"BRK")) opcode[0] = 0x00;
else if (!strcmp(ins,"PHP")) opcode[0] = 0x08;
else if (!strcmp(ins,"ASL")) opcode[0] = 0x0A;
else if (!strcmp(ins,"CLC")) opcode[0] = 0x18;
else if (!strcmp(ins,"PLP")) opcode[0] = 0x28;
else if (!strcmp(ins,"ROL")) opcode[0] = 0x2A;
else if (!strcmp(ins,"SEC")) opcode[0] = 0x38;
else if (!strcmp(ins,"RTI")) opcode[0] = 0x40;
else if (!strcmp(ins,"PHA")) opcode[0] = 0x48;
else if (!strcmp(ins,"LSR")) opcode[0] = 0x4A;
else if (!strcmp(ins,"CLI")) opcode[0] = 0x58;
else if (!strcmp(ins,"RTS")) opcode[0] = 0x60;
else if (!strcmp(ins,"PLA")) opcode[0] = 0x68;
else if (!strcmp(ins,"ROR")) opcode[0] = 0x6A;
else if (!strcmp(ins,"SEI")) opcode[0] = 0x78;
else if (!strcmp(ins,"DEY")) opcode[0] = 0x88;
else if (!strcmp(ins,"TXA")) opcode[0] = 0x8A;
else if (!strcmp(ins,"TYA")) opcode[0] = 0x98;
else if (!strcmp(ins,"TXS")) opcode[0] = 0x9A;
else if (!strcmp(ins,"TAY")) opcode[0] = 0xA8;
else if (!strcmp(ins,"TAX")) opcode[0] = 0xAA;
else if (!strcmp(ins,"CLV")) opcode[0] = 0xB8;
else if (!strcmp(ins,"TSX")) opcode[0] = 0xBA;
else if (!strcmp(ins,"INY")) opcode[0] = 0xC8;
else if (!strcmp(ins,"DEX")) opcode[0] = 0xCA;
else if (!strcmp(ins,"CLD")) opcode[0] = 0xD8;
else if (!strcmp(ins,"INX")) opcode[0] = 0xE8;
else if (!strcmp(ins,"NOP")) opcode[0] = 0xEA;
else if (!strcmp(ins,"SED")) opcode[0] = 0xF8;
else return 1;
}
else {
//Instructions with Operands
if (!strcmp(ins,"ORA")) opcode[0] = 0x01;
else if (!strcmp(ins,"ASL")) opcode[0] = 0x06;
else if (!strcmp(ins,"BPL")) opcode[0] = 0x10;
else if (!strcmp(ins,"JSR")) opcode[0] = 0x20;
else if (!strcmp(ins,"AND")) opcode[0] = 0x21;
else if (!strcmp(ins,"BIT")) opcode[0] = 0x24;
else if (!strcmp(ins,"ROL")) opcode[0] = 0x26;
else if (!strcmp(ins,"BMI")) opcode[0] = 0x30;
else if (!strcmp(ins,"EOR")) opcode[0] = 0x41;
else if (!strcmp(ins,"LSR")) opcode[0] = 0x46;
else if (!strcmp(ins,"JMP")) opcode[0] = 0x4C;
else if (!strcmp(ins,"BVC")) opcode[0] = 0x50;
else if (!strcmp(ins,"ADC")) opcode[0] = 0x61;
else if (!strcmp(ins,"ROR")) opcode[0] = 0x66;
else if (!strcmp(ins,"BVS")) opcode[0] = 0x70;
else if (!strcmp(ins,"STA")) opcode[0] = 0x81;
else if (!strcmp(ins,"STY")) opcode[0] = 0x84;
else if (!strcmp(ins,"STX")) opcode[0] = 0x86;
else if (!strcmp(ins,"BCC")) opcode[0] = 0x90;
else if (!strcmp(ins,"LDY")) opcode[0] = 0xA0;
else if (!strcmp(ins,"LDA")) opcode[0] = 0xA1;
else if (!strcmp(ins,"LDX")) opcode[0] = 0xA2;
else if (!strcmp(ins,"BCS")) opcode[0] = 0xB0;
else if (!strcmp(ins,"CPY")) opcode[0] = 0xC0;
else if (!strcmp(ins,"CMP")) opcode[0] = 0xC1;
else if (!strcmp(ins,"DEC")) opcode[0] = 0xC6;
else if (!strcmp(ins,"BNE")) opcode[0] = 0xD0;
else if (!strcmp(ins,"CPX")) opcode[0] = 0xE0;
else if (!strcmp(ins,"SBC")) opcode[0] = 0xE1;
else if (!strcmp(ins,"INC")) opcode[0] = 0xE6;
else if (!strcmp(ins,"BEQ")) opcode[0] = 0xF0;
else return 1;
{
//Parse Operands
// It's not the sexiest thing ever, but it works well enough!
//TODO:
// Add branches.
// Fix certain instructions. (Setting bits is not 100% perfect.)
// Fix instruction/operand matching. (Instructions like "jmp ($94),Y" are no good!)
// Optimizations?
int tmpint;
char tmpchr,tmpstr[20];
if (sscanf(astr,"#$%2X%c",&tmpint,&tmpchr) == 1) { //#Immediate
switch (opcode[0]) {
case 0x20: case 0x4C: //Jumps
case 0x10: case 0x30: case 0x50: case 0x70: //Branches
case 0x90: case 0xB0: case 0xD0: case 0xF0:
case 0x06: case 0x24: case 0x26: case 0x46: //Other instructions incapable of #Immediate
case 0x66: case 0x81: case 0x84: case 0x86:
case 0xC6: case 0xE6:
return 1;
default:
//cheap hack for certain instructions
switch (opcode[0]) {
case 0xA0: case 0xA2: case 0xC0: case 0xE0:
break;
default:
opcode[0] |= 0x08;
break;
}
opcode[1] = tmpint;
break;
}
}
else if (sscanf(astr,"$%4X%c",&tmpint,&tmpchr) == 1) { //Absolute, Zero Page, Branch, or Jump
switch (opcode[0]) {
case 0x20: case 0x4C: //Jumps
opcode[1] = (tmpint & 0xFF);
opcode[2] = (tmpint >> 8);
break;
case 0x10: case 0x30: case 0x50: case 0x70: //Branches
case 0x90: case 0xB0: case 0xD0: case 0xF0:
tmpint -= (addr+2);
if ((tmpint < -128) || (tmpint > 127)) return 1;
opcode[1] = (tmpint & 0xFF);
break;
//return 1; //FIX ME
default:
if (tmpint > 0xFF) { //Absolute
opcode[0] |= 0x0C;
opcode[1] = (tmpint & 0xFF);
opcode[2] = (tmpint >> 8);
}
else { //Zero Page
opcode[0] |= 0x04;
opcode[1] = (tmpint & 0xFF);
}
break;
}
}
else if (sscanf(astr,"$%4X%s",&tmpint,tmpstr) == 2) { //Absolute,X, Zero Page,X, Absolute,Y or Zero Page,Y
if (!strcmp(tmpstr,",X")) { //Absolute,X or Zero Page,X
switch (opcode[0]) {
case 0x20: case 0x4C: //Jumps
case 0x10: case 0x30: case 0x50: case 0x70: //Branches
case 0x90: case 0xB0: case 0xD0: case 0xF0:
case 0x24: case 0x86: case 0xA2: case 0xC0: //Other instructions incapable of Absolute,X or Zero Page,X
case 0xE0:
return 1;
default:
if (tmpint > 0xFF) { //Absolute
if (opcode[0] == 0x84) return 1; //No STY Absolute,X!
opcode[0] |= 0x1C;
opcode[1] = (tmpint & 0xFF);
opcode[2] = (tmpint >> 8);
}
else { //Zero Page
opcode[0] |= 0x14;
opcode[1] = (tmpint & 0xFF);
}
break;
}
}
else if (!strcmp(tmpstr,",Y")) { //Absolute,Y or Zero Page,Y
switch (opcode[0]) {
case 0x20: case 0x4C: //Jumps
case 0x10: case 0x30: case 0x50: case 0x70: //Branches
case 0x90: case 0xB0: case 0xD0: case 0xF0:
case 0x06: case 0x24: case 0x26: case 0x46: //Other instructions incapable of Absolute,Y or Zero Page,Y
case 0x66: case 0x84: case 0x86: case 0xA0:
case 0xC0: case 0xC6: case 0xE0: case 0xE6:
return 1;
case 0xA2: //cheap hack for LDX
opcode[0] |= 0x04;
default:
if (tmpint > 0xFF) { //Absolute
if (opcode[0] == 0x86) return 1; //No STX Absolute,Y!
opcode[0] |= 0x18;
opcode[1] = (tmpint & 0xFF);
opcode[2] = (tmpint >> 8);
}
else { //Zero Page
if ((opcode[0] != 0x86) || (opcode[0] != 0xA2)) return 1; //only STX and LDX Absolute,Y!
opcode[0] |= 0x10;
opcode[1] = (tmpint & 0xFF);
}
break;
}
}
else return 1;
}
else if (sscanf(astr,"($%4X%s",&tmpint,tmpstr) == 2) { //Jump (Indirect), (Indirect,X) or (Indirect),Y
switch (opcode[0]) {
case 0x20: //Jumps
case 0x10: case 0x30: case 0x50: case 0x70: //Branches
case 0x90: case 0xB0: case 0xD0: case 0xF0:
case 0x06: case 0x24: case 0x26: case 0x46: //Other instructions incapable of Jump (Indirect), (Indirect,X) or (Indirect),Y
case 0x66: case 0x84: case 0x86: case 0xA0:
case 0xA2: case 0xC0: case 0xC6: case 0xE0:
case 0xE6:
return 1;
default:
if ((!strcmp(tmpstr,")")) && (opcode[0] == 0x4C)) { //Jump (Indirect)
opcode[0] = 0x6C;
opcode[1] = (tmpint & 0xFF);
opcode[2] = (tmpint >> 8);
}
else if ((!strcmp(tmpstr,",X)")) && (tmpint <= 0xFF) && (opcode[0] != 0x4C)) { //(Indirect,X)
opcode[1] = (tmpint & 0xFF);
}
else if ((!strcmp(tmpstr,"),Y")) && (tmpint <= 0xFF) && (opcode[0] != 0x4C)) { //(Indirect),Y
opcode[0] |= 0x10;
opcode[1] = (tmpint & 0xFF);
}
else return 1;
break;
}
}
else return 1;
}
}