1 |
/** M6502: portable 6502 emulator ****************************/ |
2 |
/** **/ |
3 |
/** Codes.h **/ |
4 |
/** **/ |
5 |
/** This file contains implementation for the main table of **/ |
6 |
/** 6502 commands. It is included from 6502.c. **/ |
7 |
/** **/ |
8 |
/** Copyright (C) Marat Fayzullin 1996-2007 **/ |
9 |
/** Alex Krasivsky 1996 **/ |
10 |
/** You are not allowed to distribute this software **/ |
11 |
/** commercially. Please, notify me, if you make any **/ |
12 |
/** changes to this file. **/ |
13 |
/*************************************************************/ |
14 |
|
15 |
case 0x10: if(R->P&N_FLAG) R->PC.W++; else { M_JR; } break; /* BPL * REL */ |
16 |
case 0x30: if(R->P&N_FLAG) { M_JR; } else R->PC.W++; break; /* BMI * REL */ |
17 |
case 0xD0: if(R->P&Z_FLAG) R->PC.W++; else { M_JR; } break; /* BNE * REL */ |
18 |
case 0xF0: if(R->P&Z_FLAG) { M_JR; } else R->PC.W++; break; /* BEQ * REL */ |
19 |
case 0x90: if(R->P&C_FLAG) R->PC.W++; else { M_JR; } break; /* BCC * REL */ |
20 |
case 0xB0: if(R->P&C_FLAG) { M_JR; } else R->PC.W++; break; /* BCS * REL */ |
21 |
case 0x50: if(R->P&V_FLAG) R->PC.W++; else { M_JR; } break; /* BVC * REL */ |
22 |
case 0x70: if(R->P&V_FLAG) { M_JR; } else R->PC.W++; break; /* BVS * REL */ |
23 |
|
24 |
/* RTI */ |
25 |
case 0x40: |
26 |
M_POP(R->P);R->P|=R_FLAG;M_POP(R->PC.B.l);M_POP(R->PC.B.h); |
27 |
break; |
28 |
|
29 |
/* RTS */ |
30 |
case 0x60: |
31 |
M_POP(R->PC.B.l);M_POP(R->PC.B.h);R->PC.W++;break; |
32 |
|
33 |
/* JSR $ssss ABS */ |
34 |
case 0x20: |
35 |
K.B.l=Op6502(R->PC.W++); |
36 |
K.B.h=Op6502(R->PC.W); |
37 |
M_PUSH(R->PC.B.h); |
38 |
M_PUSH(R->PC.B.l); |
39 |
R->PC=K;break; |
40 |
|
41 |
/* JMP $ssss ABS */ |
42 |
case 0x4C: M_LDWORD(K);R->PC=K;break; |
43 |
|
44 |
/* JMP ($ssss) ABDINDIR */ |
45 |
case 0x6C: |
46 |
M_LDWORD(K); |
47 |
R->PC.B.l=Rd6502(K.W); |
48 |
K.B.l++; |
49 |
R->PC.B.h=Rd6502(K.W); |
50 |
break; |
51 |
|
52 |
/* BRK */ |
53 |
case 0x00: |
54 |
R->PC.W++; |
55 |
M_PUSH(R->PC.B.h);M_PUSH(R->PC.B.l); |
56 |
M_PUSH(R->P|B_FLAG); |
57 |
R->P=(R->P|I_FLAG)&~D_FLAG; |
58 |
R->PC.B.l=Rd6502(0xFFFE); |
59 |
R->PC.B.h=Rd6502(0xFFFF); |
60 |
break; |
61 |
|
62 |
/* CLI */ |
63 |
case 0x58: |
64 |
if((R->IRequest!=INT_NONE)&&(R->P&I_FLAG)) |
65 |
{ |
66 |
R->AfterCLI=1; |
67 |
R->IBackup=R->ICount; |
68 |
R->ICount=1; |
69 |
} |
70 |
R->P&=~I_FLAG; |
71 |
break; |
72 |
|
73 |
/* PLP */ |
74 |
case 0x28: |
75 |
M_POP(I); |
76 |
if((R->IRequest!=INT_NONE)&&((I^R->P)&~I&I_FLAG)) |
77 |
{ |
78 |
R->AfterCLI=1; |
79 |
R->IBackup=R->ICount; |
80 |
R->ICount=1; |
81 |
} |
82 |
R->P=I|R_FLAG|B_FLAG; |
83 |
break; |
84 |
|
85 |
case 0x08: M_PUSH(R->P);break; /* PHP */ |
86 |
case 0x18: R->P&=~C_FLAG;break; /* CLC */ |
87 |
case 0xB8: R->P&=~V_FLAG;break; /* CLV */ |
88 |
case 0xD8: R->P&=~D_FLAG;break; /* CLD */ |
89 |
case 0x38: R->P|=C_FLAG;break; /* SEC */ |
90 |
case 0xF8: R->P|=D_FLAG;break; /* SED */ |
91 |
case 0x78: R->P|=I_FLAG;break; /* SEI */ |
92 |
case 0x48: M_PUSH(R->A);break; /* PHA */ |
93 |
case 0x68: M_POP(R->A);M_FL(R->A);break; /* PLA */ |
94 |
case 0x98: R->A=R->Y;M_FL(R->A);break; /* TYA */ |
95 |
case 0xA8: R->Y=R->A;M_FL(R->Y);break; /* TAY */ |
96 |
case 0xC8: R->Y++;M_FL(R->Y);break; /* INY */ |
97 |
case 0x88: R->Y--;M_FL(R->Y);break; /* DEY */ |
98 |
case 0x8A: R->A=R->X;M_FL(R->A);break; /* TXA */ |
99 |
case 0xAA: R->X=R->A;M_FL(R->X);break; /* TAX */ |
100 |
case 0xE8: R->X++;M_FL(R->X);break; /* INX */ |
101 |
case 0xCA: R->X--;M_FL(R->X);break; /* DEX */ |
102 |
case 0xEA: break; /* NOP */ |
103 |
case 0x9A: R->S=R->X;break; /* TXS */ |
104 |
case 0xBA: R->X=R->S;M_FL(R->X);break; /* TSX */ |
105 |
|
106 |
case 0x24: MR_Zp(I);M_BIT(I);break; /* BIT $ss ZP */ |
107 |
case 0x2C: MR_Ab(I);M_BIT(I);break; /* BIT $ssss ABS */ |
108 |
|
109 |
case 0x05: MR_Zp(I);M_ORA(I);break; /* ORA $ss ZP */ |
110 |
case 0x06: MM_Zp(M_ASL);break; /* ASL $ss ZP */ |
111 |
case 0x25: MR_Zp(I);M_AND(I);break; /* AND $ss ZP */ |
112 |
case 0x26: MM_Zp(M_ROL);break; /* ROL $ss ZP */ |
113 |
case 0x45: MR_Zp(I);M_EOR(I);break; /* EOR $ss ZP */ |
114 |
case 0x46: MM_Zp(M_LSR);break; /* LSR $ss ZP */ |
115 |
case 0x65: MR_Zp(I);M_ADC(I);break; /* ADC $ss ZP */ |
116 |
case 0x66: MM_Zp(M_ROR);break; /* ROR $ss ZP */ |
117 |
case 0x84: MW_Zp(R->Y);break; /* STY $ss ZP */ |
118 |
case 0x85: MW_Zp(R->A);break; /* STA $ss ZP */ |
119 |
case 0x86: MW_Zp(R->X);break; /* STX $ss ZP */ |
120 |
case 0xA4: MR_Zp(R->Y);M_FL(R->Y);break; /* LDY $ss ZP */ |
121 |
case 0xA5: MR_Zp(R->A);M_FL(R->A);break; /* LDA $ss ZP */ |
122 |
case 0xA6: MR_Zp(R->X);M_FL(R->X);break; /* LDX $ss ZP */ |
123 |
case 0xC4: MR_Zp(I);M_CMP(R->Y,I);break; /* CPY $ss ZP */ |
124 |
case 0xC5: MR_Zp(I);M_CMP(R->A,I);break; /* CMP $ss ZP */ |
125 |
case 0xC6: MM_Zp(M_DEC);break; /* DEC $ss ZP */ |
126 |
case 0xE4: MR_Zp(I);M_CMP(R->X,I);break; /* CPX $ss ZP */ |
127 |
case 0xE5: MR_Zp(I);M_SBC(I);break; /* SBC $ss ZP */ |
128 |
case 0xE6: MM_Zp(M_INC);break; /* INC $ss ZP */ |
129 |
|
130 |
case 0x0D: MR_Ab(I);M_ORA(I);break; /* ORA $ssss ABS */ |
131 |
case 0x0E: MM_Ab(M_ASL);break; /* ASL $ssss ABS */ |
132 |
case 0x2D: MR_Ab(I);M_AND(I);break; /* AND $ssss ABS */ |
133 |
case 0x2E: MM_Ab(M_ROL);break; /* ROL $ssss ABS */ |
134 |
case 0x4D: MR_Ab(I);M_EOR(I);break; /* EOR $ssss ABS */ |
135 |
case 0x4E: MM_Ab(M_LSR);break; /* LSR $ssss ABS */ |
136 |
case 0x6D: MR_Ab(I);M_ADC(I);break; /* ADC $ssss ABS */ |
137 |
case 0x6E: MM_Ab(M_ROR);break; /* ROR $ssss ABS */ |
138 |
case 0x8C: MW_Ab(R->Y);break; /* STY $ssss ABS */ |
139 |
case 0x8D: MW_Ab(R->A);break; /* STA $ssss ABS */ |
140 |
case 0x8E: MW_Ab(R->X);break; /* STX $ssss ABS */ |
141 |
case 0xAC: MR_Ab(R->Y);M_FL(R->Y);break; /* LDY $ssss ABS */ |
142 |
case 0xAD: MR_Ab(R->A);M_FL(R->A);break; /* LDA $ssss ABS */ |
143 |
case 0xAE: MR_Ab(R->X);M_FL(R->X);break; /* LDX $ssss ABS */ |
144 |
case 0xCC: MR_Ab(I);M_CMP(R->Y,I);break; /* CPY $ssss ABS */ |
145 |
case 0xCD: MR_Ab(I);M_CMP(R->A,I);break; /* CMP $ssss ABS */ |
146 |
case 0xCE: MM_Ab(M_DEC);break; /* DEC $ssss ABS */ |
147 |
case 0xEC: MR_Ab(I);M_CMP(R->X,I);break; /* CPX $ssss ABS */ |
148 |
case 0xED: MR_Ab(I);M_SBC(I);break; /* SBC $ssss ABS */ |
149 |
case 0xEE: MM_Ab(M_INC);break; /* INC $ssss ABS */ |
150 |
|
151 |
case 0x09: MR_Im(I);M_ORA(I);break; /* ORA #$ss IMM */ |
152 |
case 0x29: MR_Im(I);M_AND(I);break; /* AND #$ss IMM */ |
153 |
case 0x49: MR_Im(I);M_EOR(I);break; /* EOR #$ss IMM */ |
154 |
case 0x69: MR_Im(I);M_ADC(I);break; /* ADC #$ss IMM */ |
155 |
case 0xA0: MR_Im(R->Y);M_FL(R->Y);break; /* LDY #$ss IMM */ |
156 |
case 0xA2: MR_Im(R->X);M_FL(R->X);break; /* LDX #$ss IMM */ |
157 |
case 0xA9: MR_Im(R->A);M_FL(R->A);break; /* LDA #$ss IMM */ |
158 |
case 0xC0: MR_Im(I);M_CMP(R->Y,I);break; /* CPY #$ss IMM */ |
159 |
case 0xC9: MR_Im(I);M_CMP(R->A,I);break; /* CMP #$ss IMM */ |
160 |
case 0xE0: MR_Im(I);M_CMP(R->X,I);break; /* CPX #$ss IMM */ |
161 |
case 0xE9: MR_Im(I);M_SBC(I);break; /* SBC #$ss IMM */ |
162 |
|
163 |
case 0x15: MR_Zx(I);M_ORA(I);break; /* ORA $ss,x ZP,x */ |
164 |
case 0x16: MM_Zx(M_ASL);break; /* ASL $ss,x ZP,x */ |
165 |
case 0x35: MR_Zx(I);M_AND(I);break; /* AND $ss,x ZP,x */ |
166 |
case 0x36: MM_Zx(M_ROL);break; /* ROL $ss,x ZP,x */ |
167 |
case 0x55: MR_Zx(I);M_EOR(I);break; /* EOR $ss,x ZP,x */ |
168 |
case 0x56: MM_Zx(M_LSR);break; /* LSR $ss,x ZP,x */ |
169 |
case 0x75: MR_Zx(I);M_ADC(I);break; /* ADC $ss,x ZP,x */ |
170 |
case 0x76: MM_Zx(M_ROR);break; /* ROR $ss,x ZP,x */ |
171 |
case 0x94: MW_Zx(R->Y);break; /* STY $ss,x ZP,x */ |
172 |
case 0x95: MW_Zx(R->A);break; /* STA $ss,x ZP,x */ |
173 |
case 0x96: MW_Zy(R->X);break; /* STX $ss,y ZP,y */ |
174 |
case 0xB4: MR_Zx(R->Y);M_FL(R->Y);break; /* LDY $ss,x ZP,x */ |
175 |
case 0xB5: MR_Zx(R->A);M_FL(R->A);break; /* LDA $ss,x ZP,x */ |
176 |
case 0xB6: MR_Zy(R->X);M_FL(R->X);break; /* LDX $ss,y ZP,y */ |
177 |
case 0xD5: MR_Zx(I);M_CMP(R->A,I);break; /* CMP $ss,x ZP,x */ |
178 |
case 0xD6: MM_Zx(M_DEC);break; /* DEC $ss,x ZP,x */ |
179 |
case 0xF5: MR_Zx(I);M_SBC(I);break; /* SBC $ss,x ZP,x */ |
180 |
case 0xF6: MM_Zx(M_INC);break; /* INC $ss,x ZP,x */ |
181 |
|
182 |
case 0x19: MR_Ay(I);M_ORA(I);break; /* ORA $ssss,y ABS,y */ |
183 |
case 0x1D: MR_Ax(I);M_ORA(I);break; /* ORA $ssss,x ABS,x */ |
184 |
case 0x1E: MM_Ax(M_ASL);break; /* ASL $ssss,x ABS,x */ |
185 |
case 0x39: MR_Ay(I);M_AND(I);break; /* AND $ssss,y ABS,y */ |
186 |
case 0x3D: MR_Ax(I);M_AND(I);break; /* AND $ssss,x ABS,x */ |
187 |
case 0x3E: MM_Ax(M_ROL);break; /* ROL $ssss,x ABS,x */ |
188 |
case 0x59: MR_Ay(I);M_EOR(I);break; /* EOR $ssss,y ABS,y */ |
189 |
case 0x5D: MR_Ax(I);M_EOR(I);break; /* EOR $ssss,x ABS,x */ |
190 |
case 0x5E: MM_Ax(M_LSR);break; /* LSR $ssss,x ABS,x */ |
191 |
case 0x79: MR_Ay(I);M_ADC(I);break; /* ADC $ssss,y ABS,y */ |
192 |
case 0x7D: MR_Ax(I);M_ADC(I);break; /* ADC $ssss,x ABS,x */ |
193 |
case 0x7E: MM_Ax(M_ROR);break; /* ROR $ssss,x ABS,x */ |
194 |
case 0x99: MW_Ay(R->A);break; /* STA $ssss,y ABS,y */ |
195 |
case 0x9D: MW_Ax(R->A);break; /* STA $ssss,x ABS,x */ |
196 |
case 0xB9: MR_Ay(R->A);M_FL(R->A);break; /* LDA $ssss,y ABS,y */ |
197 |
case 0xBC: MR_Ax(R->Y);M_FL(R->Y);break; /* LDY $ssss,x ABS,x */ |
198 |
case 0xBD: MR_Ax(R->A);M_FL(R->A);break; /* LDA $ssss,x ABS,x */ |
199 |
case 0xBE: MR_Ay(R->X);M_FL(R->X);break; /* LDX $ssss,y ABS,y */ |
200 |
case 0xD9: MR_Ay(I);M_CMP(R->A,I);break; /* CMP $ssss,y ABS,y */ |
201 |
case 0xDD: MR_Ax(I);M_CMP(R->A,I);break; /* CMP $ssss,x ABS,x */ |
202 |
case 0xDE: MM_Ax(M_DEC);break; /* DEC $ssss,x ABS,x */ |
203 |
case 0xF9: MR_Ay(I);M_SBC(I);break; /* SBC $ssss,y ABS,y */ |
204 |
case 0xFD: MR_Ax(I);M_SBC(I);break; /* SBC $ssss,x ABS,x */ |
205 |
case 0xFE: MM_Ax(M_INC);break; /* INC $ssss,x ABS,x */ |
206 |
|
207 |
case 0x01: MR_Ix(I);M_ORA(I);break; /* ORA ($ss,x) INDEXINDIR */ |
208 |
case 0x11: MR_Iy(I);M_ORA(I);break; /* ORA ($ss),y INDIRINDEX */ |
209 |
case 0x21: MR_Ix(I);M_AND(I);break; /* AND ($ss,x) INDEXINDIR */ |
210 |
case 0x31: MR_Iy(I);M_AND(I);break; /* AND ($ss),y INDIRINDEX */ |
211 |
case 0x41: MR_Ix(I);M_EOR(I);break; /* EOR ($ss,x) INDEXINDIR */ |
212 |
case 0x51: MR_Iy(I);M_EOR(I);break; /* EOR ($ss),y INDIRINDEX */ |
213 |
case 0x61: MR_Ix(I);M_ADC(I);break; /* ADC ($ss,x) INDEXINDIR */ |
214 |
case 0x71: MR_Iy(I);M_ADC(I);break; /* ADC ($ss),y INDIRINDEX */ |
215 |
case 0x81: MW_Ix(R->A);break; /* STA ($ss,x) INDEXINDIR */ |
216 |
case 0x91: MW_Iy(R->A);break; /* STA ($ss),y INDIRINDEX */ |
217 |
case 0xA1: MR_Ix(R->A);M_FL(R->A);break; /* LDA ($ss,x) INDEXINDIR */ |
218 |
case 0xB1: MR_Iy(R->A);M_FL(R->A);break; /* LDA ($ss),y INDIRINDEX */ |
219 |
case 0xC1: MR_Ix(I);M_CMP(R->A,I);break; /* CMP ($ss,x) INDEXINDIR */ |
220 |
case 0xD1: MR_Iy(I);M_CMP(R->A,I);break; /* CMP ($ss),y INDIRINDEX */ |
221 |
case 0xE1: MR_Ix(I);M_SBC(I);break; /* SBC ($ss,x) INDEXINDIR */ |
222 |
case 0xF1: MR_Iy(I);M_SBC(I);break; /* SBC ($ss),y INDIRINDEX */ |
223 |
|
224 |
case 0x0A: M_ASL(R->A);break; /* ASL a ACC */ |
225 |
case 0x2A: M_ROL(R->A);break; /* ROL a ACC */ |
226 |
case 0x4A: M_LSR(R->A);break; /* LSR a ACC */ |
227 |
case 0x6A: M_ROR(R->A);break; /* ROR a ACC */ |
228 |
|
229 |
default: |
230 |
/* Try to execute a patch function. If it fails, treat */ |
231 |
/* the opcode as undefined. */ |
232 |
if(!Patch6502(Op6502(R->PC.W-1),R)) |
233 |
if(R->TrapBadOps) |
234 |
printf |
235 |
( |
236 |
"[M6502 %lX] Unrecognized instruction: $%02X at PC=$%04X\n", |
237 |
(unsigned long)(R->User),Op6502(R->PC.W-1),(word)(R->PC.W-1) |
238 |
); |
239 |
break; |