snd fix
[fceu.git] / ops.h
CommitLineData
c62d2810 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21case 0x00: /* BRK */
22 _PC++;
23 PUSH(_PC>>8);
24 PUSH(_PC);
8fa5eb33 25 _P|=B_FLAG;
26 PUSH(_P|U_FLAG);
c62d2810 27 _P|=I_FLAG;
28 _PC=RdMem(0xFFFE);
29 _PC|=RdMem(0xFFFF)<<8;
30 break;
31
32case 0x40: /* RTI */
33 _P=POP();
34 _PI=_P;
35 _PC=POP();
36 _PC|=POP()<<8;
37 break;
c0bf6f9f 38
c62d2810 39case 0x60: /* RTS */
40 _PC=POP();
41 _PC|=POP()<<8;
42 _PC++;
43 break;
44
45case 0x48: /* PHA */
46 PUSH(_A);
47 break;
48case 0x08: /* PHP */
49 PUSH(_P|U_FLAG|B_FLAG);
50 break;
51case 0x68: /* PLA */
52 _A=POP();
53 X_ZN(_A);
54 break;
55case 0x28: /* PLP */
56 _P=POP();
57 break;
58case 0x4C:
59 {
60 uint16 ptmp=_PC;
61 unsigned int npc;
62
63 npc=RdMem(ptmp);
64 ptmp++;
65 npc|=RdMem(ptmp)<<8;
66 _PC=npc;
67 }
68 break; /* JMP ABSOLUTE */
c0bf6f9f 69case 0x6C:
c62d2810 70 {
71 uint32 tmp;
72 GetAB(tmp);
73 _PC=RdMem(tmp);
74 _PC|=RdMem( ((tmp+1)&0x00FF) | (tmp&0xFF00))<<8;
75 }
76 break;
77case 0x20: /* JSR */
78 {
79 uint8 npc;
80 npc=RdMem(_PC++);
81 PUSH(_PC>>8);
82 PUSH(_PC);
83 _PC=RdMem(_PC)<<8;
84 _PC|=npc;
85 }
86 break;
87
88case 0xAA: /* TAX */
89 _X=_A;
90 X_ZN(_A);
91 break;
92
93case 0x8A: /* TXA */
94 _A=_X;
95 X_ZN(_A);
96 break;
97
98case 0xA8: /* TAY */
99 _Y=_A;
100 X_ZN(_A);
101 break;
102case 0x98: /* TYA */
103 _A=_Y;
104 X_ZN(_A);
105 break;
106
107case 0xBA: /* TSX */
108 _X=_S;
109 X_ZN(_X);
110 break;
111case 0x9A: /* TXS */
112 _S=_X;
113 break;
114
115case 0xCA: /* DEX */
116 _X--;
117 X_ZN(_X);
118 break;
119case 0x88: /* DEY */
120 _Y--;
121 X_ZN(_Y);
122 break;
123
124case 0xE8: /* INX */
125 _X++;
126 X_ZN(_X);
127 break;
128case 0xC8: /* INY */
129 _Y++;
130 X_ZN(_Y);
131 break;
132
133case 0x18: /* CLC */
134 _P&=~C_FLAG;
135 break;
136case 0xD8: /* CLD */
137 _P&=~D_FLAG;
138 break;
139case 0x58: /* CLI */
140 _P&=~I_FLAG;
141 break;
142case 0xB8: /* CLV */
143 _P&=~V_FLAG;
144 break;
145
146case 0x38: /* SEC */
147 _P|=C_FLAG;
148 break;
149case 0xF8: /* SED */
150 _P|=D_FLAG;
151 break;
152case 0x78: /* SEI */
153 _P|=I_FLAG;
154 break;
155
156case 0xEA: /* NOP */
157 break;
158
159case 0x0A: RMW_A(ASL);
160case 0x06: RMW_ZP(ASL);
161case 0x16: RMW_ZPX(ASL);
162case 0x0E: RMW_AB(ASL);
163case 0x1E: RMW_ABX(ASL);
164
165case 0xC6: RMW_ZP(DEC);
166case 0xD6: RMW_ZPX(DEC);
167case 0xCE: RMW_AB(DEC);
168case 0xDE: RMW_ABX(DEC);
169
170case 0xE6: RMW_ZP(INC);
171case 0xF6: RMW_ZPX(INC);
172case 0xEE: RMW_AB(INC);
173case 0xFE: RMW_ABX(INC);
174
175case 0x4A: RMW_A(LSR);
176case 0x46: RMW_ZP(LSR);
177case 0x56: RMW_ZPX(LSR);
178case 0x4E: RMW_AB(LSR);
179case 0x5E: RMW_ABX(LSR);
180
181case 0x2A: RMW_A(ROL);
182case 0x26: RMW_ZP(ROL);
183case 0x36: RMW_ZPX(ROL);
184case 0x2E: RMW_AB(ROL);
185case 0x3E: RMW_ABX(ROL);
186
187case 0x6A: RMW_A(ROR);
188case 0x66: RMW_ZP(ROR);
189case 0x76: RMW_ZPX(ROR);
190case 0x6E: RMW_AB(ROR);
191case 0x7E: RMW_ABX(ROR);
192
193case 0x69: LD_IM(ADC);
194case 0x65: LD_ZP(ADC);
195case 0x75: LD_ZPX(ADC);
196case 0x6D: LD_AB(ADC);
197case 0x7D: LD_ABX(ADC);
198case 0x79: LD_ABY(ADC);
199case 0x61: LD_IX(ADC);
200case 0x71: LD_IY(ADC);
201
202case 0x29: LD_IM(AND);
203case 0x25: LD_ZP(AND);
204case 0x35: LD_ZPX(AND);
205case 0x2D: LD_AB(AND);
206case 0x3D: LD_ABX(AND);
207case 0x39: LD_ABY(AND);
208case 0x21: LD_IX(AND);
209case 0x31: LD_IY(AND);
210
211case 0x24: LD_ZP(BIT);
212case 0x2C: LD_AB(BIT);
213
214case 0xC9: LD_IM(CMP);
215case 0xC5: LD_ZP(CMP);
216case 0xD5: LD_ZPX(CMP);
217case 0xCD: LD_AB(CMP);
218case 0xDD: LD_ABX(CMP);
219case 0xD9: LD_ABY(CMP);
220case 0xC1: LD_IX(CMP);
221case 0xD1: LD_IY(CMP);
222
223case 0xE0: LD_IM(CPX);
224case 0xE4: LD_ZP(CPX);
225case 0xEC: LD_AB(CPX);
226
227case 0xC0: LD_IM(CPY);
228case 0xC4: LD_ZP(CPY);
229case 0xCC: LD_AB(CPY);
230
231case 0x49: LD_IM(EOR);
232case 0x45: LD_ZP(EOR);
233case 0x55: LD_ZPX(EOR);
234case 0x4D: LD_AB(EOR);
235case 0x5D: LD_ABX(EOR);
236case 0x59: LD_ABY(EOR);
237case 0x41: LD_IX(EOR);
238case 0x51: LD_IY(EOR);
239
240case 0xA9: LD_IM(LDA);
241case 0xA5: LD_ZP(LDA);
242case 0xB5: LD_ZPX(LDA);
243case 0xAD: LD_AB(LDA);
244case 0xBD: LD_ABX(LDA);
245case 0xB9: LD_ABY(LDA);
246case 0xA1: LD_IX(LDA);
247case 0xB1: LD_IY(LDA);
248
249case 0xA2: LD_IM(LDX);
250case 0xA6: LD_ZP(LDX);
251case 0xB6: LD_ZPY(LDX);
252case 0xAE: LD_AB(LDX);
253case 0xBE: LD_ABY(LDX);
254
255case 0xA0: LD_IM(LDY);
256case 0xA4: LD_ZP(LDY);
257case 0xB4: LD_ZPX(LDY);
258case 0xAC: LD_AB(LDY);
259case 0xBC: LD_ABX(LDY);
260
261case 0x09: LD_IM(ORA);
262case 0x05: LD_ZP(ORA);
263case 0x15: LD_ZPX(ORA);
264case 0x0D: LD_AB(ORA);
265case 0x1D: LD_ABX(ORA);
266case 0x19: LD_ABY(ORA);
267case 0x01: LD_IX(ORA);
268case 0x11: LD_IY(ORA);
269
270case 0xEB: /* (undocumented) */
271case 0xE9: LD_IM(SBC);
272case 0xE5: LD_ZP(SBC);
273case 0xF5: LD_ZPX(SBC);
274case 0xED: LD_AB(SBC);
275case 0xFD: LD_ABX(SBC);
276case 0xF9: LD_ABY(SBC);
277case 0xE1: LD_IX(SBC);
278case 0xF1: LD_IY(SBC);
279
280case 0x85: ST_ZP(_A);
281case 0x95: ST_ZPX(_A);
282case 0x8D: ST_AB(_A);
283case 0x9D: ST_ABX(_A);
284case 0x99: ST_ABY(_A);
285case 0x81: ST_IX(_A);
286case 0x91: ST_IY(_A);
287
288case 0x86: ST_ZP(_X);
289case 0x96: ST_ZPY(_X);
290case 0x8E: ST_AB(_X);
291
292case 0x84: ST_ZP(_Y);
293case 0x94: ST_ZPX(_Y);
294case 0x8C: ST_AB(_Y);
295
296/* BCC */
297case 0x90: if(_P&C_FLAG) _PC++; else {JR();} break;
298
299/* BCS */
300case 0xB0: if(_P&C_FLAG) {JR();} else _PC++; break;
301
302/* BEQ */
303case 0xF0: if(_P&Z_FLAG) {JR();} else _PC++; break;
304
305/* BNE */
306case 0xD0: if(_P&Z_FLAG) _PC++; else {JR();} break;
307
308/* BMI */
309case 0x30: if(_P&N_FLAG) {JR();} else _PC++; break;
310
311/* BPL */
312case 0x10: if(_P&N_FLAG) _PC++; else {JR();} break;
313
314/* BVC */
315case 0x50: if(_P&V_FLAG) _PC++; else {JR();} break;
316
317/* BVS */
318case 0x70: if(_P&V_FLAG) {JR();} else _PC++; break;
319
320/* Here comes the undocumented instructions. Note that this implementation
321 may be "wrong". If so, please tell me.
322*/
323
324/* AAC */
325case 0x2B:
326case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7);
327
328/* AAX */
329case 0x87: ST_ZP(_A&_X);
330case 0x97: ST_ZPY(_A&_X);
331case 0x8F: ST_AB(_A&_X);
332case 0x83: ST_IX(_A&_X);
333
334/* ARR - ARGH, MATEY! */
c0bf6f9f 335case 0x6B: {
336 uint8 arrtmp;
c62d2810 337 LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A));
338 }
339/* ASR */
340case 0x4B: LD_IM(AND;LSRA);
341
342/* ATX(OAL) Is this(OR with $EE) correct? */
343case 0xAB: LD_IM(_A|=0xEE;AND;_X=_A);
344
c0bf6f9f 345/* AXS */
c62d2810 346case 0xCB: LD_IM(AXS);
347
348/* DCP */
4fdfab07 349case 0xC7: RMW_ZP(DEC;CMP);
350case 0xD7: RMW_ZPX(DEC;CMP);
351case 0xCF: RMW_AB(DEC;CMP);
352case 0xDF: RMW_ABX(DEC;CMP);
353case 0xDB: RMW_ABY(DEC;CMP);
354case 0xC3: RMW_IX(DEC;CMP);
355case 0xD3: RMW_IY(DEC;CMP);
c62d2810 356
357/* ISC */
4fdfab07 358case 0xE7: RMW_ZP(INC;SBC);
359case 0xF7: RMW_ZPX(INC;SBC);
360case 0xEF: RMW_AB(INC;SBC);
361case 0xFF: RMW_ABX(INC;SBC);
362case 0xFB: RMW_ABY(INC;SBC);
363case 0xE3: RMW_IX(INC;SBC);
364case 0xF3: RMW_IY(INC;SBC);
c62d2810 365
366/* DOP */
367
368case 0x04: _PC++;break;
369case 0x14: _PC++;break;
370case 0x34: _PC++;break;
371case 0x44: _PC++;break;
372case 0x54: _PC++;break;
373case 0x64: _PC++;break;
374case 0x74: _PC++;break;
375
376case 0x80: _PC++;break;
377case 0x82: _PC++;break;
378case 0x89: _PC++;break;
379case 0xC2: _PC++;break;
380case 0xD4: _PC++;break;
381case 0xE2: _PC++;break;
382case 0xF4: _PC++;break;
383
384/* KIL */
385
386case 0x02:
387case 0x12:
388case 0x22:
389case 0x32:
390case 0x42:
391case 0x52:
392case 0x62:
393case 0x72:
394case 0x92:
395case 0xB2:
396case 0xD2:
397case 0xF2:ADDCYC(0xFF);
398 _jammed=1;
399 _PC--;
400 break;
401
402/* LAR */
403case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X));
404
405/* LAX */
406case 0xA7: LD_ZP(LDA;LDX);
407case 0xB7: LD_ZPY(LDA;LDX);
408case 0xAF: LD_AB(LDA;LDX);
409case 0xBF: LD_ABY(LDA;LDX);
410case 0xA3: LD_IX(LDA;LDX);
411case 0xB3: LD_IY(LDA;LDX);
412
413/* NOP */
414case 0x1A:
415case 0x3A:
416case 0x5A:
417case 0x7A:
418case 0xDA:
419case 0xFA: break;
420
421/* RLA */
422case 0x27: RMW_ZP(ROL;AND);
423case 0x37: RMW_ZPX(ROL;AND);
424case 0x2F: RMW_AB(ROL;AND);
425case 0x3F: RMW_ABX(ROL;AND);
426case 0x3B: RMW_ABY(ROL;AND);
427case 0x23: RMW_IX(ROL;AND);
428case 0x33: RMW_IY(ROL;AND);
429
430/* RRA */
431case 0x67: RMW_ZP(ROR;ADC);
432case 0x77: RMW_ZPX(ROR;ADC);
433case 0x6F: RMW_AB(ROR;ADC);
434case 0x7F: RMW_ABX(ROR;ADC);
435case 0x7B: RMW_ABY(ROR;ADC);
436case 0x63: RMW_IX(ROR;ADC);
437case 0x73: RMW_IY(ROR;ADC);
438
439/* SLO */
440case 0x07: RMW_ZP(ASL;ORA);
441case 0x17: RMW_ZPX(ASL;ORA);
442case 0x0F: RMW_AB(ASL;ORA);
443case 0x1F: RMW_ABX(ASL;ORA);
444case 0x1B: RMW_ABY(ASL;ORA);
445case 0x03: RMW_IX(ASL;ORA);
446case 0x13: RMW_IY(ASL;ORA);
447
448/* SRE */
449case 0x47: RMW_ZP(LSR;EOR);
450case 0x57: RMW_ZPX(LSR;EOR);
451case 0x4F: RMW_AB(LSR;EOR);
452case 0x5F: RMW_ABX(LSR;EOR);
453case 0x5B: RMW_ABY(LSR;EOR);
454case 0x43: RMW_IX(LSR;EOR);
455case 0x53: RMW_IY(LSR;EOR);
456
457/* AXA - SHA */
458case 0x93: ST_IY(_A&_X&(((A-_Y)>>8)+1));
459case 0x9F: ST_ABY(_A&_X&(((A-_Y)>>8)+1));
460
461/* SYA */
462case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1));
463
464/* SXA */
465case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1));
466
467/* XAS */
468case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) );
469
470/* TOP */
471case 0x0C: LD_AB(;);
c0bf6f9f 472case 0x1C:
473case 0x3C:
474case 0x5C:
475case 0x7C:
476case 0xDC:
c62d2810 477case 0xFC: LD_ABX(;);
478
479/* XAA - BIG QUESTION MARK HERE */
480case 0x8B: _A|=0xEE; _A&=_X; LD_IM(AND);