1 // h6280.c - Execute CPU instructions
2 //
3
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "interupt.h"
8 #include "dis_runtime.h"
9 #include "pce.h"
10 #include "hard_pce.h"
11 #include "gfx.h"
12 #include "pce.h"
13 #include "utils.h"
14
15 #if defined(KERNEL_DEBUG)
16 static
one_bit_set(UChar arg)17 int one_bit_set(UChar arg)
18 {
19 return (arg != 0) && ((-arg & arg) == arg);
20 }
21 #endif
22
23 // flag-value table (for speed)
24
25 UChar flnz_list[256] = {
26 FL_Z,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00-0F
27 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
28 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
29 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
30 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40-4F
31 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
32 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
33 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 70-7F
34 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // 80-87
35 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
36 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // 90-97
37 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
38 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // A0-A7
39 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
40 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // B0-B7
41 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
42 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // C0-C7
43 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
44 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // D0-D7
45 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
46 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // E0-E7
47 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,
48 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N, // F0-F7
49 FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N,FL_N
50 };
51
52 // Elementary operations:
53 // - defined here for clarity, brevity,
54 // and reduced typographical errors
55
56 // This code ignores hardware-segment accesses; it should only be used
57 // to access immediate data (hardware segment does not run code):
58 //
59 // as a function:
60
imm_operand(UInt16 addr)61 inline UChar imm_operand(UInt16 addr) {
62 register unsigned short int memreg = addr>>13;
63 return( (UChar) (PageR[memreg][addr]));
64 }
65
66 #if !defined(INLINED_ACCESSORS)
67
68 #define get_8bit_addr(addr) Rd6502((addr))
69
70 #define put_8bit_addr(addr,byte) Wr6502((addr),(byte))
71
72 #define get_16bit_addr(addr) (Rd6502(addr) + (Rd6502((UInt16)(addr + 1)) << 8))
73
74 #else
75
76
77 // This is the more generalized access routine:
get_8bit_addr(UInt16 addr)78 inline UChar get_8bit_addr(UInt16 addr) {
79 register unsigned short int memreg = addr>>13;
80
81 if (PageR[memreg] == IOAREA)
82 return(IO_read(addr));
83 else
84 return((UChar) (PageR[memreg][addr]));
85 }
86
put_8bit_addr(UInt16 addr,UChar byte)87 inline void put_8bit_addr(UInt16 addr, UChar byte) {
88 register unsigned int memreg = addr>>13;
89
90 if (PageW[memreg] == IOAREA) {
91 IO_write(addr, byte);
92 } else {
93 PageW[memreg][addr] = byte;
94 }
95 }
96
get_16bit_addr(UInt16 addr)97 inline UInt16 get_16bit_addr(UInt16 addr) {
98 register unsigned int memreg = addr>>13;
99 UInt16 ret_16bit = (UChar) PageR[memreg][addr];
100 memreg = (++addr)>>13;
101 ret_16bit += (UInt16) ((UChar) PageR[memreg][addr] << 8);
102
103 return(ret_16bit);
104 }
105
106 #endif
107
108 //Addressing modes:
109
110 #define abs_operand(x) get_8bit_addr(get_16bit_addr(x))
111 #define absx_operand(x) get_8bit_addr(get_16bit_addr(x)+reg_x)
112 #define absy_operand(x) get_8bit_addr(get_16bit_addr(x)+reg_y)
113 #define zp_operand(x) get_8bit_zp(imm_operand(x))
114 #define zpx_operand(x) get_8bit_zp(imm_operand(x)+reg_x)
115 #define zpy_operand(x) get_8bit_zp(imm_operand(x)+reg_y)
116 #define zpind_operand(x) get_8bit_addr(get_16bit_zp(imm_operand(x)))
117 #define zpindx_operand(x) get_8bit_addr(get_16bit_zp(imm_operand(x)+reg_x))
118 #define zpindy_operand(x) get_8bit_addr(get_16bit_zp(imm_operand(x))+reg_y)
119
120 // Elementary flag check (flags 'N' and 'Z'):
121
122 #define chk_flnz_8bit(x) reg_p = ((reg_p & (~(FL_N|FL_T|FL_Z))) | flnz_list[x]);
123
get_8bit_zp(UChar zp_addr)124 inline UChar get_8bit_zp(UChar zp_addr) {
125 return((UChar) *(zp_base + zp_addr) );
126 }
127
get_16bit_zp(UChar zp_addr)128 inline UInt16 get_16bit_zp(UChar zp_addr) {
129 UInt16 n = *(zp_base + zp_addr);
130 n += (*(zp_base + (UChar)(zp_addr+1)) << 8);
131 return(n);
132 }
133
put_8bit_zp(UChar zp_addr,UChar byte)134 inline void put_8bit_zp(UChar zp_addr, UChar byte) {
135 *(zp_base + zp_addr) = byte;
136 }
137
push_8bit(UChar byte)138 inline void push_8bit(UChar byte) {
139 *(sp_base + reg_s--) = byte;
140 }
141
pull_8bit(void)142 inline UChar pull_8bit(void) {
143 return((UChar) *(sp_base + ++reg_s) );
144 }
145
push_16bit(UInt16 addr)146 inline void push_16bit(UInt16 addr) {
147 *(sp_base + reg_s--) = (UChar)(addr>>8);
148 *(sp_base + reg_s--) = (UChar)(addr&0xFF);
149 return;
150 }
151
pull_16bit(void)152 inline UInt16 pull_16bit(void) {
153 UInt16 n = (UChar) *(sp_base + ++reg_s);
154 n += (UInt16)(((UChar) *(sp_base + ++reg_s)) << 8);
155 return(n);
156 }
157
158 //
159 // Implementation of actual opcodes:
160 //
161
162 /*@ -type */
163
164 static
adc(UChar acc,UChar val)165 UChar adc(UChar acc, UChar val) {
166 Int16 sig = (Char)acc;
167 UInt16 usig = (UChar)acc;
168 UInt16 temp;
169
170 if (!(reg_p & FL_D)) { /* binary mode */
171 if (reg_p & FL_C) {
172 usig++;
173 sig++;
174 }
175 sig += (Char)val;
176 usig += (UChar)val;
177 acc = (UChar)(usig & 0xFF);
178
179 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z|FL_C))
180 | (((sig > 127) || (sig < -128)) ? FL_V:0)
181 | ((usig > 255) ? FL_C:0)
182 | flnz_list[acc];
183
184 } else { /* decimal mode */
185
186 // treatment of out-of-range accumulator
187 // and operand values (non-BCD) is not
188 // adequately defined. Nor is overflow
189 // flag treatment.
190
191 // Zeo : rewrote using bcdbin and binbcd arrays to boost code speed and fix
192 // residual bugs
193
194 temp = bcdbin[usig] + bcdbin[val];
195
196 if (reg_p & FL_C) { temp++; }
197
198 acc = binbcd[temp];
199
200 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
201 | ((temp > 99) ? FL_C:0)
202 | flnz_list[acc];
203
204 cycles++; /* decimal mode takes an extra cycle */
205
206 }
207 return(acc);
208 }
209
210 static
sbc(UChar val)211 void sbc(UChar val) {
212 Int16 sig = (Char)reg_a;
213 UInt16 usig = (UChar)reg_a;
214 Int16 temp;
215
216 if (!(reg_p & FL_D)) { /* binary mode */
217 if (!(reg_p & FL_C)) {
218 usig--;
219 sig--;
220 }
221 sig -= (Char)val;
222 usig -= (UChar)val;
223 reg_a = (UChar)(usig & 0xFF);
224 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z|FL_C))
225 | (((sig > 127) || (sig < -128)) ? FL_V:0)
226 | ((usig > 255) ? 0:FL_C)
227 | flnz_list[reg_a]; /* FL_N, FL_Z */
228
229 } else { /* decimal mode */
230
231 // treatment of out-of-range accumulator
232 // and operand values (non-bcd) is not
233 // adequately defined. Nor is overflow
234 // flag treatment.
235
236 temp = (Int16)(bcdbin[usig] - bcdbin[val]);
237
238 if (!(reg_p & FL_C)) { temp--; }
239
240 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
241 | ((temp < 0) ? 0:FL_C);
242
243 while (temp < 0) {
244 temp += 100;
245 }
246
247 chk_flnz_8bit(reg_a = binbcd[temp]);
248
249 cycles++; /* decimal mode takes an extra cycle */
250
251 }
252 }
253
adc_abs(void)254 int adc_abs(void) {
255 // if flag 'T' is set, use zero-page address specified by register 'X'
256 // as the accumulator...
257
258 if (reg_p & FL_T) {
259 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), abs_operand(reg_pc+1)));
260 cycles+=8;
261 } else {
262 reg_a = adc(reg_a, abs_operand(reg_pc+1));
263 cycles+=5;
264 }
265 reg_pc+=3;
266 return 0;
267 }
268
adc_absx(void)269 int adc_absx(void) {
270 if (reg_p & FL_T) {
271 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), absx_operand(reg_pc+1)));
272 cycles+=8;
273 } else {
274 reg_a = adc(reg_a, absx_operand(reg_pc+1));
275 cycles+=5;
276 }
277 reg_pc+=3;
278 return 0;
279 }
280
adc_absy(void)281 int adc_absy(void) {
282 if (reg_p & FL_T) {
283 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), absy_operand(reg_pc+1)));
284 cycles+=8;
285 } else {
286 reg_a = adc(reg_a, absy_operand(reg_pc+1));
287 cycles+=5;
288 }
289 reg_pc+=3;
290 return 0;
291 }
292
adc_imm(void)293 int adc_imm(void) {
294 if (reg_p & FL_T) {
295 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), imm_operand(reg_pc+1)));
296 cycles+=5;
297 } else {
298 reg_a = adc(reg_a, imm_operand(reg_pc+1));
299 cycles+=2;
300 }
301 reg_pc+=2;
302 return 0;
303 }
304
adc_zp(void)305 int adc_zp(void) {
306 if (reg_p & FL_T) {
307 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), zp_operand(reg_pc+1)));
308 cycles+=7;
309 } else {
310 reg_a = adc(reg_a, zp_operand(reg_pc+1));
311 cycles+=4;
312 }
313 reg_pc+=2;
314 return 0;
315 }
316
adc_zpx(void)317 int adc_zpx(void) {
318 if (reg_p & FL_T) {
319 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), zpx_operand(reg_pc+1)));
320 cycles+=7;
321 } else {
322 reg_a = adc(reg_a, zpx_operand(reg_pc+1));
323 cycles+=4;
324 }
325 reg_pc+=2;
326 return 0;
327 }
328
adc_zpind(void)329 int adc_zpind(void) {
330 if (reg_p & FL_T) {
331 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), zpind_operand(reg_pc+1)));
332 cycles+=10;
333 } else {
334 reg_a = adc(reg_a, zpind_operand(reg_pc+1));
335 cycles+=7;
336 }
337 reg_pc+=2;
338 return 0;
339 }
340
adc_zpindx(void)341 int adc_zpindx(void) {
342 if (reg_p & FL_T) {
343 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), zpindx_operand(reg_pc+1)));
344 cycles+=10;
345 } else {
346 reg_a = adc(reg_a, zpindx_operand(reg_pc+1));
347 cycles+=7;
348 }
349 reg_pc+=2;
350 return 0;
351 }
352
adc_zpindy(void)353 int adc_zpindy(void) {
354 if (reg_p & FL_T) {
355 put_8bit_zp(reg_x, adc(get_8bit_zp(reg_x), zpindy_operand(reg_pc+1)));
356 cycles+=10;
357 } else {
358 reg_a = adc(reg_a, zpindy_operand(reg_pc+1));
359 cycles+=7;
360 }
361 reg_pc+=2;
362 return 0;
363 }
364
and_abs(void)365 int and_abs(void) {
366 if (reg_p & FL_T) {
367 UChar temp = get_8bit_zp(reg_x);
368 chk_flnz_8bit(temp &= abs_operand(reg_pc+1));
369 put_8bit_zp(reg_x, temp);
370 cycles+=8;
371
372 } else {
373 chk_flnz_8bit(reg_a &= abs_operand(reg_pc+1));
374 cycles+=5;
375 }
376 reg_pc+=3;
377 return 0;
378 }
379
and_absx(void)380 int and_absx(void) {
381 if (reg_p & FL_T) {
382 UChar temp = get_8bit_zp(reg_x);
383 chk_flnz_8bit(temp &= absx_operand(reg_pc+1));
384 put_8bit_zp(reg_x, temp);
385 cycles+=8;
386
387 } else {
388 chk_flnz_8bit(reg_a &= absx_operand(reg_pc+1));
389 cycles+=5;
390 }
391 reg_pc+=3;
392 return 0;
393 }
394
and_absy(void)395 int and_absy(void) {
396 if (reg_p & FL_T) {
397 UChar temp = get_8bit_zp(reg_x);
398 chk_flnz_8bit(temp &= absy_operand(reg_pc+1));
399 put_8bit_zp(reg_x, temp);
400 cycles+=8;
401
402 } else {
403 chk_flnz_8bit(reg_a &= absy_operand(reg_pc+1));
404 cycles+=5;
405 }
406 reg_pc+=3;
407 return 0;
408 }
409
and_imm(void)410 int and_imm(void) {
411 if (reg_p & FL_T) {
412 UChar temp = get_8bit_zp(reg_x);
413 chk_flnz_8bit(temp &= imm_operand(reg_pc+1));
414 put_8bit_zp(reg_x, temp);
415 cycles+=5;
416
417 } else {
418 chk_flnz_8bit(reg_a &= imm_operand(reg_pc+1));
419 cycles+=2;
420 }
421 reg_pc+=2;
422 return 0;
423 }
424
and_zp(void)425 int and_zp(void) {
426 if (reg_p & FL_T) {
427 UChar temp = get_8bit_zp(reg_x);
428 chk_flnz_8bit(temp &= zp_operand(reg_pc+1));
429 put_8bit_zp(reg_x, temp);
430 cycles+=7;
431
432 } else {
433 chk_flnz_8bit(reg_a &= zp_operand(reg_pc+1));
434 cycles+=4;
435 }
436 reg_pc+=2;
437 return 0;
438 }
439
and_zpx(void)440 int and_zpx(void) {
441 if (reg_p & FL_T) {
442 UChar temp = get_8bit_zp(reg_x);
443 chk_flnz_8bit(temp &= zpx_operand(reg_pc+1));
444 put_8bit_zp(reg_x, temp);
445 cycles+=7;
446
447 } else {
448 chk_flnz_8bit(reg_a &= zpx_operand(reg_pc+1));
449 cycles+=4;
450 }
451 reg_pc+=2;
452 return 0;
453 }
454
and_zpind(void)455 int and_zpind(void) {
456 if (reg_p & FL_T) {
457 UChar temp = get_8bit_zp(reg_x);
458 chk_flnz_8bit(temp &= zpind_operand(reg_pc+1));
459 put_8bit_zp(reg_x, temp);
460 cycles+=10;
461
462 } else {
463 chk_flnz_8bit(reg_a &= zpind_operand(reg_pc+1));
464 cycles+=7;
465 }
466 reg_pc+=2;
467 return 0;
468 }
469
and_zpindx(void)470 int and_zpindx(void) {
471 if (reg_p & FL_T) {
472 UChar temp = get_8bit_zp(reg_x);
473 chk_flnz_8bit(temp &= zpindx_operand(reg_pc+1));
474 put_8bit_zp(reg_x, temp);
475 cycles+=10;
476
477 } else {
478 chk_flnz_8bit(reg_a &= zpindx_operand(reg_pc+1));
479 cycles+=7;
480 }
481 reg_pc+=2;
482 return 0;
483 }
484
and_zpindy(void)485 int and_zpindy(void) {
486 if (reg_p & FL_T) {
487 UChar temp = get_8bit_zp(reg_x);
488 chk_flnz_8bit(temp &= zpindy_operand(reg_pc+1));
489 put_8bit_zp(reg_x, temp);
490 cycles+=10;
491
492 } else {
493 chk_flnz_8bit(reg_a &= zpindy_operand(reg_pc+1));
494 cycles+=7;
495 }
496 reg_pc+=2;
497 return 0;
498 }
499
asl_a(void)500 int asl_a(void) {
501 UChar temp1 = reg_a;
502 reg_a<<=1;
503 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
504 | ((temp1 & 0x80) ? FL_C:0)
505 | flnz_list[reg_a];
506 cycles+=2;
507 reg_pc++;
508 return 0;
509 }
510
asl_abs(void)511 int asl_abs(void) {
512 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
513 UChar temp1 = get_8bit_addr(temp_addr);
514 UChar temp = temp1<<1;
515
516 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
517 | ((temp1 & 0x80) ? FL_C:0)
518 | flnz_list[temp];
519 cycles+=7;
520
521 put_8bit_addr(temp_addr,temp);
522 reg_pc+=3;
523 return 0;
524 }
525
asl_absx(void)526 int asl_absx(void) {
527 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
528 UChar temp1 = get_8bit_addr(temp_addr);
529 UChar temp = temp1<<1;
530
531 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
532 | ((temp1 & 0x80) ? FL_C:0)
533 | flnz_list[temp];
534 cycles+=7;
535 put_8bit_addr(temp_addr,temp);
536 reg_pc+=3;
537 return 0;
538 }
539
asl_zp(void)540 int asl_zp(void) {
541 UChar zp_addr = imm_operand(reg_pc+1);
542 UChar temp1 = get_8bit_zp(zp_addr);
543 UChar temp = temp1<<1;
544
545 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
546 | ((temp1 & 0x80) ? FL_C:0)
547 | flnz_list[temp];
548 cycles+=6;
549 put_8bit_zp(zp_addr, temp);
550 reg_pc+=2;
551 return 0;
552 }
553
asl_zpx(void)554 int asl_zpx(void) {
555 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
556 UChar temp1 = get_8bit_zp(zp_addr);
557 UChar temp = temp1<<1;
558
559 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
560 | ((temp1 & 0x80) ? FL_C:0)
561 | flnz_list[temp];
562 cycles+=6;
563 put_8bit_zp(zp_addr, temp);
564 reg_pc+=2;
565 return 0;
566 }
567
bbr0(void)568 int bbr0(void) {
569 reg_p &= ~FL_T;
570 if (zp_operand(reg_pc+1)&0x01) {
571 reg_pc+=3;
572 cycles+=6;
573 } else {
574 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
575 cycles+=8;
576 }
577 return 0;
578 }
579
bbr1(void)580 int bbr1(void) {
581 reg_p &= ~FL_T;
582 if (zp_operand(reg_pc+1)&0x02) {
583 reg_pc+=3;
584 cycles+=6;
585 } else {
586 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
587 cycles+=8;
588 }
589 return 0;
590 }
591
bbr2(void)592 int bbr2(void) {
593 reg_p &= ~FL_T;
594 if (zp_operand(reg_pc+1)&0x04) {
595 reg_pc+=3;
596 cycles+=6;
597 } else {
598 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
599 cycles+=8;
600 }
601 return 0;
602 }
603
bbr3(void)604 int bbr3(void) {
605 reg_p &= ~FL_T;
606 if (zp_operand(reg_pc+1)&0x08) {
607 reg_pc+=3;
608 cycles+=6;
609 } else {
610 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
611 cycles+=8;
612 }
613 return 0;
614 }
615
bbr4(void)616 int bbr4(void) {
617 reg_p &= ~FL_T;
618 if (zp_operand(reg_pc+1)&0x10) {
619 reg_pc+=3;
620 cycles+=6;
621 } else {
622 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
623 cycles+=8;
624 }
625 return 0;
626 }
627
bbr5(void)628 int bbr5(void) {
629 reg_p &= ~FL_T;
630 if (zp_operand(reg_pc+1)&0x20) {
631 reg_pc+=3;
632 cycles+=6;
633 } else {
634 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
635 cycles+=8;
636 }
637 return 0;
638 }
639
bbr6(void)640 int bbr6(void) {
641 reg_p &= ~FL_T;
642 if (zp_operand(reg_pc+1)&0x40) {
643 reg_pc+=3;
644 cycles+=6;
645 } else {
646 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
647 cycles+=8;
648 }
649 return 0;
650 }
651
bbr7(void)652 int bbr7(void) {
653 reg_p &= ~FL_T;
654 if (zp_operand(reg_pc+1)&0x80) {
655 reg_pc+=3;
656 cycles+=6;
657 } else {
658 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
659 cycles+=8;
660 }
661 return 0;
662 }
663
bbs0(void)664 int bbs0(void) {
665 reg_p &= ~FL_T;
666 if (zp_operand(reg_pc+1)&0x01) {
667 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
668 cycles+=8;
669 } else {
670 reg_pc+=3;
671 cycles+=6;
672 }
673 return 0;
674 }
675
bbs1(void)676 int bbs1(void) {
677 reg_p &= ~FL_T;
678 if (zp_operand(reg_pc+1)&0x02) {
679 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
680 cycles+=8;
681 } else {
682 reg_pc+=3;
683 cycles+=6;
684 }
685 return 0;
686 }
687
bbs2(void)688 int bbs2(void) {
689 reg_p &= ~FL_T;
690 if (zp_operand(reg_pc+1)&0x04) {
691 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
692 cycles+=8;
693 } else {
694 reg_pc+=3;
695 cycles+=6;
696 }
697 return 0;
698 }
699
bbs3(void)700 int bbs3(void) {
701 reg_p &= ~FL_T;
702 if (zp_operand(reg_pc+1)&0x08) {
703 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
704 cycles+=8;
705 } else {
706 reg_pc+=3;
707 cycles+=6;
708 }
709 return 0;
710 }
711
bbs4(void)712 int bbs4(void) {
713 reg_p &= ~FL_T;
714 if (zp_operand(reg_pc+1)&0x10) {
715 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
716 cycles+=8;
717 } else {
718 reg_pc+=3;
719 cycles+=6;
720 }
721 return 0;
722 }
723
bbs5(void)724 int bbs5(void) {
725 reg_p &= ~FL_T;
726 if (zp_operand(reg_pc+1)&0x20) {
727 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
728 cycles+=8;
729 } else {
730 reg_pc+=3;
731 cycles+=6;
732 }
733 return 0;
734 }
735
bbs6(void)736 int bbs6(void) {
737 reg_p &= ~FL_T;
738 if (zp_operand(reg_pc+1)&0x40) {
739 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
740 cycles+=8;
741 } else {
742 reg_pc+=3;
743 cycles+=6;
744 }
745 return 0;
746 }
747
bbs7(void)748 int bbs7(void) {
749 reg_p &= ~FL_T;
750 if (zp_operand(reg_pc+1)&0x80) {
751 reg_pc+=(Char)imm_operand(reg_pc+2)+3;
752 cycles+=8;
753 } else {
754 reg_pc+=3;
755 cycles+=6;
756 }
757 return 0;
758 }
759
bcc(void)760 int bcc(void) {
761 reg_p &= ~FL_T;
762 if (reg_p & FL_C) {
763 reg_pc+=2;
764 cycles+=2;
765 } else {
766 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
767 cycles+=4;
768 }
769 return 0;
770 }
771
bcs(void)772 int bcs(void) {
773 reg_p &= ~FL_T;
774 if (reg_p & FL_C) {
775 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
776 cycles+=4;
777 } else {
778 reg_pc+=2;
779 cycles+=2;
780 }
781 return 0;
782 }
783
beq(void)784 int beq(void) {
785 reg_p &= ~FL_T;
786 if (reg_p & FL_Z) {
787 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
788 cycles+=4;
789 } else {
790 reg_pc+=2;
791 cycles+=2;
792 }
793 return 0;
794 }
795
bit_abs(void)796 int bit_abs(void) {
797 UChar temp = abs_operand(reg_pc+1);
798 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
799 | ((temp&0x80) ? FL_N:0)
800 | ((temp&0x40) ? FL_V:0)
801 | ((reg_a&temp) ? 0:FL_Z);
802 reg_pc+=3;
803 cycles+=5;
804 return 0;
805 }
806
bit_absx(void)807 int bit_absx(void) {
808 UChar temp = absx_operand(reg_pc+1);
809 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
810 | ((temp&0x80) ? FL_N:0)
811 | ((temp&0x40) ? FL_V:0)
812 | ((reg_a&temp) ? 0:FL_Z);
813 reg_pc+=3;
814 cycles+=5;
815 return 0;
816 }
817
bit_imm(void)818 int bit_imm(void) {
819 // orig code (Eyes/Lichty said immediate mode did not affect
820 // 'N' and 'V' flags):
821 //reg_p = (reg_p & ~(FL_T|FL_Z))
822 // | ((reg_a & imm_operand(reg_pc+1)) ? 0:FL_Z);
823
824 UChar temp = imm_operand(reg_pc+1);
825 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
826 | ((temp&0x80) ? FL_N:0)
827 | ((temp&0x40) ? FL_V:0)
828 | ((reg_a&temp) ? 0:FL_Z);
829 reg_pc+=2;
830 cycles+=2;
831 return 0;
832 }
833
bit_zp(void)834 int bit_zp(void) {
835 UChar temp = zp_operand(reg_pc+1);
836 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
837 | ((temp&0x80) ? FL_N:0)
838 | ((temp&0x40) ? FL_V:0)
839 | ((reg_a&temp) ? 0:FL_Z);
840 reg_pc+=2;
841 cycles+=4;
842 return 0;
843 }
844
bit_zpx(void)845 int bit_zpx(void) {
846 UChar temp = zpx_operand(reg_pc+1);
847 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
848 | ((temp&0x80) ? FL_N:0)
849 | ((temp&0x40) ? FL_V:0)
850 | ((reg_a&temp) ? 0:FL_Z);
851 reg_pc+=2;
852 cycles+=4;
853 return 0;
854 }
855
bmi(void)856 int bmi(void) {
857 reg_p &= ~FL_T;
858 if (reg_p & FL_N) {
859 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
860 cycles+=4;
861 } else {
862 reg_pc+=2;
863 cycles+=2;
864 }
865 return 0;
866 }
867
bne(void)868 int bne(void) {
869 reg_p &= ~FL_T;
870 if (reg_p & FL_Z) {
871 reg_pc+=2;
872 cycles+=2;
873 } else {
874 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
875 cycles+=4;
876 }
877 return 0;
878 }
879
bpl(void)880 int bpl(void) {
881 reg_p &= ~FL_T;
882 if (reg_p & FL_N) {
883 reg_pc+=2;
884 cycles+=2;
885 } else {
886 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
887 cycles+=4;
888 }
889 return 0;
890 }
891
bra(void)892 int bra(void) {
893 reg_p &= ~FL_T;
894 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
895 cycles+=4;
896 return 0;
897 }
898
brek(void)899 int brek(void) {
900 #if defined(KERNEL_DEBUG)
901 fprintf(stderr, "BRK opcode has been hit [PC = 0x%04x] at %s(%d)\n", reg_pc, __FILE__, __LINE__);
902 #endif
903 push_16bit(reg_pc+2);
904 reg_p &= ~FL_T;
905 push_8bit(reg_p|FL_B);
906 reg_p =(reg_p & ~FL_D) | FL_I;
907 reg_pc=get_16bit_addr(0xFFF6);
908 cycles+=8;
909 return 0;
910 }
911
bsr(void)912 int bsr(void) {
913 reg_p &= ~FL_T;
914 push_16bit(reg_pc+1);
915 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
916 cycles+=8;
917 return 0;
918 }
919
bvc(void)920 int bvc(void) {
921 reg_p &= ~FL_T;
922 if (reg_p & FL_V) {
923 reg_pc+=2;
924 cycles+=2;
925 } else {
926 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
927 cycles+=4;
928 }
929 return 0;
930 }
931
bvs(void)932 int bvs(void) {
933 reg_p &= ~FL_T;
934 if (reg_p & FL_V) {
935 reg_pc+=(Char)imm_operand(reg_pc+1)+2;
936 cycles+=4;
937 } else {
938 reg_pc+=2;
939 cycles+=2;
940 }
941 return 0;
942 }
943
cla(void)944 int cla(void) {
945 reg_p &= ~FL_T;
946 reg_a = 0;
947 reg_pc++;
948 cycles+=2;
949 return 0;
950 }
951
clc(void)952 int clc(void) {
953 reg_p &= ~(FL_T|FL_C);
954 reg_pc++;
955 cycles+=2;
956 return 0;
957 }
958
cld(void)959 int cld(void) {
960 reg_p &= ~(FL_T|FL_D);
961 reg_pc++;
962 cycles+=2;
963 return 0;
964 }
965
cli(void)966 int cli(void) {
967 reg_p &= ~(FL_T|FL_I);
968 reg_pc++;
969 cycles+=2;
970 return 0;
971 }
972
clv(void)973 int clv(void) {
974 reg_p &= ~(FL_V|FL_T);
975 reg_pc++;
976 cycles+=2;
977 return 0;
978 }
979
clx(void)980 int clx(void) {
981 reg_p &= ~FL_T;
982 reg_x = 0;
983 reg_pc++;
984 cycles+=2;
985 return 0;
986 }
987
cly(void)988 int cly(void) {
989 reg_p &= ~FL_T;
990 reg_y = 0;
991 reg_pc++;
992 cycles+=2;
993 return 0;
994 }
995
cmp_abs(void)996 int cmp_abs(void) {
997 UChar temp = abs_operand(reg_pc+1);
998
999 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1000 | ((reg_a < temp) ? 0:FL_C)
1001 | flnz_list[(UChar)(reg_a-temp)];
1002 reg_pc+=3;
1003 cycles+=5;
1004 return 0;
1005 }
1006
cmp_absx(void)1007 int cmp_absx(void) {
1008 UChar temp = absx_operand(reg_pc+1);
1009
1010 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1011 | ((reg_a < temp) ? 0:FL_C)
1012 | flnz_list[(UChar)(reg_a-temp)];
1013 reg_pc+=3;
1014 cycles+=5;
1015 return 0;
1016 }
1017
cmp_absy(void)1018 int cmp_absy(void) {
1019 UChar temp = absy_operand(reg_pc+1);
1020
1021 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1022 | ((reg_a < temp) ? 0:FL_C)
1023 | flnz_list[(UChar)(reg_a-temp)];
1024 reg_pc+=3;
1025 cycles+=5;
1026 return 0;
1027 }
1028
cmp_imm(void)1029 int cmp_imm(void) {
1030 UChar temp = imm_operand(reg_pc+1);
1031
1032 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1033 | ((reg_a < temp) ? 0:FL_C)
1034 | flnz_list[(UChar)(reg_a-temp)];
1035 reg_pc+=2;
1036 cycles+=2;
1037 return 0;
1038 }
1039
cmp_zp(void)1040 int cmp_zp(void) {
1041 UChar temp = zp_operand(reg_pc+1);
1042
1043 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1044 | ((reg_a < temp) ? 0:FL_C)
1045 | flnz_list[(UChar)(reg_a-temp)];
1046 reg_pc+=2;
1047 cycles+=4;
1048 return 0;
1049 }
1050
cmp_zpx(void)1051 int cmp_zpx(void) {
1052 UChar temp = zpx_operand(reg_pc+1);
1053
1054 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1055 | ((reg_a < temp) ? 0:FL_C)
1056 | flnz_list[(UChar)(reg_a-temp)];
1057 reg_pc+=2;
1058 cycles+=4;
1059 return 0;
1060 }
1061
cmp_zpind(void)1062 int cmp_zpind(void) {
1063 UChar temp = zpind_operand(reg_pc+1);
1064
1065 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1066 | ((reg_a < temp) ? 0:FL_C)
1067 | flnz_list[(UChar)(reg_a-temp)];
1068 reg_pc+=2;
1069 cycles+=7;
1070 return 0;
1071 }
1072
cmp_zpindx(void)1073 int cmp_zpindx(void) {
1074 UChar temp = zpindx_operand(reg_pc+1);
1075
1076 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1077 | ((reg_a < temp) ? 0:FL_C)
1078 | flnz_list[(UChar)(reg_a-temp)];
1079 reg_pc+=2;
1080 cycles+=7;
1081 return 0;
1082 }
1083
cmp_zpindy(void)1084 int cmp_zpindy(void) {
1085 UChar temp = zpindy_operand(reg_pc+1);
1086
1087 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1088 | ((reg_a < temp) ? 0:FL_C)
1089 | flnz_list[(UChar)(reg_a-temp)];
1090 reg_pc+=2;
1091 cycles+=7;
1092 return 0;
1093 }
1094
cpx_abs(void)1095 int cpx_abs(void) {
1096 UChar temp = abs_operand(reg_pc+1);
1097
1098 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1099 | ((reg_x < temp) ? 0:FL_C)
1100 | flnz_list[(UChar)(reg_x-temp)];
1101 reg_pc+=3;
1102 cycles+=5;
1103 return 0;
1104 }
1105
cpx_imm(void)1106 int cpx_imm(void) {
1107 UChar temp = imm_operand(reg_pc+1);
1108
1109 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1110 | ((reg_x < temp) ? 0:FL_C)
1111 | flnz_list[(UChar)(reg_x-temp)];
1112 reg_pc+=2;
1113 cycles+=2;
1114 return 0;
1115 }
1116
cpx_zp(void)1117 int cpx_zp(void) {
1118 UChar temp = zp_operand(reg_pc+1);
1119
1120 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1121 | ((reg_x < temp) ? 0:FL_C)
1122 | flnz_list[(UChar)(reg_x-temp)];
1123 reg_pc+=2;
1124 cycles+=4;
1125 return 0;
1126 }
1127
cpy_abs(void)1128 int cpy_abs(void) {
1129 UChar temp = abs_operand(reg_pc+1);
1130
1131 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1132 | ((reg_y < temp) ? 0:FL_C)
1133 | flnz_list[(UChar)(reg_y-temp)];
1134 reg_pc+=3;
1135 cycles+=5;
1136 return 0;
1137 }
1138
cpy_imm(void)1139 int cpy_imm(void) {
1140 UChar temp = imm_operand(reg_pc+1);
1141
1142 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1143 | ((reg_y < temp) ? 0:FL_C)
1144 | flnz_list[(UChar)(reg_y-temp)];
1145 reg_pc+=2;
1146 cycles+=2;
1147 return 0;
1148 }
1149
cpy_zp(void)1150 int cpy_zp(void) {
1151 UChar temp = zp_operand(reg_pc+1);
1152
1153 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1154 | ((reg_y < temp) ? 0:FL_C)
1155 | flnz_list[(UChar)(reg_y-temp)];
1156 reg_pc+=2;
1157 cycles+=4;
1158 return 0;
1159 }
1160
dec_a(void)1161 int dec_a(void) {
1162 chk_flnz_8bit(--reg_a);
1163 reg_pc++;
1164 cycles+=2;
1165 return 0;
1166 }
1167
dec_abs(void)1168 int dec_abs(void) {
1169 UChar temp;
1170 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
1171 chk_flnz_8bit(temp = get_8bit_addr(temp_addr)-1);
1172 cycles+=7;
1173 put_8bit_addr(temp_addr, temp);
1174 reg_pc+=3;
1175 return 0;
1176 }
1177
dec_absx(void)1178 int dec_absx(void) {
1179 UChar temp;
1180 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
1181 chk_flnz_8bit(temp = get_8bit_addr(temp_addr)-1);
1182 cycles+=7;
1183 put_8bit_addr(temp_addr, temp);
1184 reg_pc+=3;
1185 return 0;
1186 }
1187
dec_zp(void)1188 int dec_zp(void) {
1189 UChar temp;
1190 UChar zp_addr = imm_operand(reg_pc+1);
1191 chk_flnz_8bit(temp = get_8bit_zp(zp_addr)-1);
1192 put_8bit_zp(zp_addr, temp);
1193 reg_pc+=2;
1194 cycles+=6;
1195 return 0;
1196 }
1197
dec_zpx(void)1198 int dec_zpx(void) {
1199 UChar temp;
1200 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
1201 chk_flnz_8bit(temp = get_8bit_zp(zp_addr)-1);
1202 put_8bit_zp(zp_addr, temp);
1203 reg_pc+=2;
1204 cycles+=6;
1205 return 0;
1206 }
1207
dex(void)1208 int dex(void) {
1209 chk_flnz_8bit(--reg_x);
1210 reg_pc++;
1211 cycles+=2;
1212 return 0;
1213 }
1214
dey(void)1215 int dey(void) {
1216 chk_flnz_8bit(--reg_y);
1217 reg_pc++;
1218 cycles+=2;
1219 return 0;
1220 }
1221
eor_abs(void)1222 int eor_abs(void) {
1223 if (reg_p & FL_T) {
1224 UChar temp = get_8bit_zp(reg_x);
1225 chk_flnz_8bit(temp ^= abs_operand(reg_pc+1));
1226 put_8bit_zp(reg_x, temp);
1227 cycles+=8;
1228
1229 } else {
1230 chk_flnz_8bit(reg_a ^= abs_operand(reg_pc+1));
1231 cycles+=5;
1232 }
1233 reg_pc+=3;
1234 return 0;
1235 }
1236
eor_absx(void)1237 int eor_absx(void) {
1238 if (reg_p & FL_T) {
1239 UChar temp = get_8bit_zp(reg_x);
1240 chk_flnz_8bit(temp ^= absx_operand(reg_pc+1));
1241 put_8bit_zp(reg_x, temp);
1242 cycles+=8;
1243
1244 } else {
1245 chk_flnz_8bit(reg_a ^= absx_operand(reg_pc+1));
1246 cycles+=5;
1247 }
1248 reg_pc+=3;
1249 return 0;
1250 }
1251
eor_absy(void)1252 int eor_absy(void) {
1253 if (reg_p & FL_T) {
1254 UChar temp = get_8bit_zp(reg_x);
1255 chk_flnz_8bit(temp ^= absy_operand(reg_pc+1));
1256 put_8bit_zp(reg_x, temp);
1257 cycles+=8;
1258
1259 } else {
1260 chk_flnz_8bit(reg_a ^= absy_operand(reg_pc+1));
1261 cycles+=5;
1262 }
1263 reg_pc+=3;
1264 return 0;
1265 }
1266
eor_imm(void)1267 int eor_imm(void) {
1268 if (reg_p & FL_T) {
1269 UChar temp = get_8bit_zp(reg_x);
1270 chk_flnz_8bit(temp ^= imm_operand(reg_pc+1));
1271 put_8bit_zp(reg_x, temp);
1272 cycles+=5;
1273
1274 } else {
1275 chk_flnz_8bit(reg_a ^= imm_operand(reg_pc+1));
1276 cycles+=2;
1277 }
1278 reg_pc+=2;
1279 return 0;
1280 }
1281
eor_zp(void)1282 int eor_zp(void) {
1283 if (reg_p & FL_T) {
1284 UChar temp = get_8bit_zp(reg_x);
1285 chk_flnz_8bit(temp ^= zp_operand(reg_pc+1));
1286 put_8bit_zp(reg_x, temp);
1287 cycles+=7;
1288
1289 } else {
1290 chk_flnz_8bit(reg_a ^= zp_operand(reg_pc+1));
1291 cycles+=4;
1292 }
1293 reg_pc+=2;
1294 return 0;
1295 }
1296
eor_zpx(void)1297 int eor_zpx(void) {
1298 if (reg_p & FL_T) {
1299 UChar temp = get_8bit_zp(reg_x);
1300 chk_flnz_8bit(temp ^= zpx_operand(reg_pc+1));
1301 put_8bit_zp(reg_x, temp);
1302 cycles+=7;
1303
1304 } else {
1305 chk_flnz_8bit(reg_a ^= zpx_operand(reg_pc+1));
1306 cycles+=4;
1307 }
1308 reg_pc+=2;
1309 return 0;
1310 }
1311
eor_zpind(void)1312 int eor_zpind(void) {
1313 if (reg_p & FL_T) {
1314 UChar temp = get_8bit_zp(reg_x);
1315 chk_flnz_8bit(temp ^= zpind_operand(reg_pc+1));
1316 put_8bit_zp(reg_x, temp);
1317 cycles+=10;
1318
1319 } else {
1320 chk_flnz_8bit(reg_a ^= zpind_operand(reg_pc+1));
1321 cycles+=7;
1322 }
1323 reg_pc+=2;
1324 return 0;
1325 }
1326
eor_zpindx(void)1327 int eor_zpindx(void) {
1328 if (reg_p & FL_T) {
1329 UChar temp = get_8bit_zp(reg_x);
1330 chk_flnz_8bit(temp ^= zpindx_operand(reg_pc+1));
1331 put_8bit_zp(reg_x, temp);
1332 cycles+=10;
1333
1334 } else {
1335 chk_flnz_8bit(reg_a ^= zpindx_operand(reg_pc+1));
1336 cycles+=7;
1337 }
1338 reg_pc+=2;
1339 return 0;
1340 }
1341
eor_zpindy(void)1342 int eor_zpindy(void) {
1343 if (reg_p & FL_T) {
1344 UChar temp = get_8bit_zp(reg_x);
1345 chk_flnz_8bit(temp ^= zpindy_operand(reg_pc+1));
1346 put_8bit_zp(reg_x, temp);
1347 cycles+=10;
1348
1349 } else {
1350 chk_flnz_8bit(reg_a ^= zpindy_operand(reg_pc+1));
1351 cycles+=7;
1352 }
1353 reg_pc+=2;
1354 return 0;
1355 }
1356
halt(void)1357 int halt(void) {
1358 return(1);
1359 }
1360
inc_a(void)1361 int inc_a(void) {
1362 chk_flnz_8bit(++reg_a);
1363 reg_pc++;
1364 cycles+=2;
1365 return 0;
1366 }
1367
inc_abs(void)1368 int inc_abs(void) {
1369 UChar temp;
1370 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
1371 chk_flnz_8bit(temp = get_8bit_addr(temp_addr)+1);
1372 cycles+=7;
1373 put_8bit_addr(temp_addr, temp);
1374 reg_pc+=3;
1375 return 0;
1376 }
1377
inc_absx(void)1378 int inc_absx(void) {
1379 UChar temp;
1380 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
1381 chk_flnz_8bit(temp = get_8bit_addr(temp_addr)+1);
1382 cycles+=7;
1383 put_8bit_addr(temp_addr, temp);
1384 reg_pc+=3;
1385 return 0;
1386 }
1387
inc_zp(void)1388 int inc_zp(void) {
1389 UChar temp;
1390 UChar zp_addr = imm_operand(reg_pc+1);
1391 chk_flnz_8bit(temp = get_8bit_zp(zp_addr)+1);
1392 put_8bit_zp(zp_addr, temp);
1393
1394 reg_pc+=2;
1395 cycles+=6;
1396 return 0;
1397 }
1398
inc_zpx(void)1399 int inc_zpx(void) {
1400 UChar temp;
1401 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
1402 chk_flnz_8bit(temp = get_8bit_zp(zp_addr)+1);
1403 put_8bit_zp(zp_addr, temp);
1404 reg_pc+=2;
1405 cycles+=6;
1406 return 0;
1407 }
1408
inx(void)1409 int inx(void) {
1410 chk_flnz_8bit(++reg_x);
1411 reg_pc++;
1412 cycles+=2;
1413 return 0;
1414 }
1415
iny(void)1416 int iny(void) {
1417 chk_flnz_8bit(++reg_y);
1418 reg_pc++;
1419 cycles+=2;
1420 return 0;
1421 }
1422
jmp(void)1423 int jmp(void) {
1424 reg_p &= ~FL_T;
1425 reg_pc = get_16bit_addr(reg_pc+1);
1426 cycles+=4;
1427 return 0;
1428 }
1429
jmp_absind(void)1430 int jmp_absind(void) {
1431 reg_p &= ~FL_T;
1432 reg_pc = get_16bit_addr(get_16bit_addr(reg_pc+1));
1433 cycles+=7;
1434 return 0;
1435 }
1436
jmp_absindx(void)1437 int jmp_absindx(void) {
1438 reg_p &= ~FL_T;
1439 reg_pc = get_16bit_addr(get_16bit_addr(reg_pc+1)+reg_x);
1440 cycles+=7;
1441 return 0;
1442 }
1443
jsr(void)1444 int jsr(void) {
1445 reg_p &= ~FL_T;
1446 push_16bit(reg_pc+2);
1447 reg_pc = get_16bit_addr(reg_pc+1);
1448 cycles+=7;
1449 return 0;
1450 }
1451
lda_abs(void)1452 int lda_abs(void) {
1453 chk_flnz_8bit(reg_a = abs_operand(reg_pc+1));
1454 reg_pc+=3;
1455 cycles+=5;
1456 return 0;
1457 }
1458
lda_absx(void)1459 int lda_absx(void) {
1460 chk_flnz_8bit(reg_a = absx_operand(reg_pc+1));
1461 reg_pc+=3;
1462 cycles+=5;
1463 return 0;
1464 }
1465
lda_absy(void)1466 int lda_absy(void) {
1467 chk_flnz_8bit(reg_a = absy_operand(reg_pc+1));
1468 reg_pc+=3;
1469 cycles+=5;
1470 return 0;
1471 }
1472
lda_imm(void)1473 int lda_imm(void) {
1474 chk_flnz_8bit(reg_a = imm_operand(reg_pc+1));
1475 reg_pc+=2;
1476 cycles+=2;
1477 return 0;
1478 }
1479
lda_zp(void)1480 int lda_zp(void) {
1481 chk_flnz_8bit(reg_a = zp_operand(reg_pc+1));
1482 reg_pc+=2;
1483 cycles+=4;
1484 return 0;
1485 }
1486
lda_zpx(void)1487 int lda_zpx(void) {
1488 chk_flnz_8bit(reg_a = zpx_operand(reg_pc+1));
1489 reg_pc+=2;
1490 cycles+=4;
1491 return 0;
1492 }
1493
lda_zpind(void)1494 int lda_zpind(void) {
1495 chk_flnz_8bit(reg_a = zpind_operand(reg_pc+1));
1496
1497 reg_pc+=2;
1498 cycles+=7;
1499 return 0;
1500 }
1501
lda_zpindx(void)1502 int lda_zpindx(void) {
1503 chk_flnz_8bit(reg_a = zpindx_operand(reg_pc+1));
1504 reg_pc+=2;
1505 cycles+=7;
1506 return 0;
1507 }
1508
lda_zpindy(void)1509 int lda_zpindy(void) {
1510 chk_flnz_8bit(reg_a = zpindy_operand(reg_pc+1));
1511 reg_pc+=2;
1512 cycles+=7;
1513 return 0;
1514 }
1515
ldx_abs(void)1516 int ldx_abs(void) {
1517 chk_flnz_8bit(reg_x = abs_operand(reg_pc+1));
1518 reg_pc+=3;
1519 cycles+=5;
1520 return 0;
1521 }
1522
ldx_absy(void)1523 int ldx_absy(void) {
1524 chk_flnz_8bit(reg_x = absy_operand(reg_pc+1));
1525 reg_pc+=3;
1526 cycles+=5;
1527 return 0;
1528 }
1529
ldx_imm(void)1530 int ldx_imm(void) {
1531 chk_flnz_8bit(reg_x = imm_operand(reg_pc+1));
1532 reg_pc+=2;
1533 cycles+=2;
1534 return 0;
1535 }
1536
ldx_zp(void)1537 int ldx_zp(void) {
1538 chk_flnz_8bit(reg_x = zp_operand(reg_pc+1));
1539 reg_pc+=2;
1540 cycles+=4;
1541 return 0;
1542 }
1543
ldx_zpy(void)1544 int ldx_zpy(void) {
1545 chk_flnz_8bit(reg_x = zpy_operand(reg_pc+1));
1546 reg_pc+=2;
1547 cycles+=4;
1548 return 0;
1549 }
1550
ldy_abs(void)1551 int ldy_abs(void) {
1552 chk_flnz_8bit(reg_y = abs_operand(reg_pc+1));
1553 reg_pc+=3;
1554 cycles+=5;
1555 return 0;
1556 }
1557
ldy_absx(void)1558 int ldy_absx(void) {
1559 chk_flnz_8bit(reg_y = absx_operand(reg_pc+1));
1560 reg_pc+=3;
1561 cycles+=5;
1562 return 0;
1563 }
1564
ldy_imm(void)1565 int ldy_imm(void) {
1566 chk_flnz_8bit(reg_y = imm_operand(reg_pc+1));
1567 reg_pc+=2;
1568 cycles+=2;
1569 return 0;
1570 }
1571
ldy_zp(void)1572 int ldy_zp(void) {
1573 chk_flnz_8bit(reg_y = zp_operand(reg_pc+1));
1574 reg_pc+=2;
1575 cycles+=4;
1576 return 0;
1577 }
1578
ldy_zpx(void)1579 int ldy_zpx(void) {
1580 chk_flnz_8bit(reg_y = zpx_operand(reg_pc+1));
1581 reg_pc+=2;
1582 cycles+=4;
1583 return 0;
1584 }
1585
lsr_a(void)1586 int lsr_a(void) {
1587 UChar temp = reg_a;
1588 reg_a/=2;
1589 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1590 | ((temp&1) ? FL_C:0)
1591 | flnz_list[reg_a];
1592 reg_pc++;
1593 cycles+=2;
1594 return 0;
1595 }
1596
lsr_abs(void)1597 int lsr_abs(void) {
1598 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
1599 UChar temp1 = get_8bit_addr(temp_addr);
1600 UChar temp = temp1/2;
1601
1602 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1603 | ((temp1&1) ? FL_C:0)
1604 | flnz_list[temp];
1605 cycles+=7;
1606 put_8bit_addr(temp_addr, temp);
1607 reg_pc+=3;
1608 return 0;
1609 }
1610
lsr_absx(void)1611 int lsr_absx(void) {
1612 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
1613 UChar temp1 = get_8bit_addr(temp_addr);
1614 UChar temp = temp1/2;
1615
1616 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1617 | ((temp1&1) ? FL_C:0)
1618 | flnz_list[temp];
1619 cycles+=7;
1620 put_8bit_addr(temp_addr, temp);
1621 reg_pc+=3;
1622 return 0;
1623 }
1624
lsr_zp(void)1625 int lsr_zp(void) {
1626 UChar zp_addr = imm_operand(reg_pc+1);
1627 UChar temp1 = get_8bit_zp(zp_addr);
1628 UChar temp = temp1/2;
1629
1630 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1631 | ((temp1&1) ? FL_C:0)
1632 | flnz_list[temp];
1633 put_8bit_zp(zp_addr, temp);
1634 reg_pc+=2;
1635 cycles+=6;
1636 return 0;
1637 }
1638
lsr_zpx(void)1639 int lsr_zpx(void) {
1640 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
1641 UChar temp1 = get_8bit_zp(zp_addr);
1642 UChar temp = temp1/2;
1643
1644 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1645 | ((temp1&1) ? FL_C:0)
1646 | flnz_list[temp];
1647 put_8bit_zp(zp_addr, temp);
1648 reg_pc+=2;
1649 cycles+=6;
1650 return 0;
1651 }
1652
nop(void)1653 int nop(void) {
1654 reg_p &= ~FL_T;
1655 reg_pc++;
1656 cycles+=2;
1657 return 0;
1658 }
1659
ora_abs(void)1660 int ora_abs(void) {
1661 if (reg_p & FL_T) {
1662 UChar temp = get_8bit_zp(reg_x);
1663 chk_flnz_8bit(temp |= abs_operand(reg_pc+1));
1664 put_8bit_zp(reg_x, temp);
1665 cycles+=8;
1666
1667 } else {
1668 chk_flnz_8bit(reg_a |= abs_operand(reg_pc+1));
1669 cycles+=5;
1670 }
1671 reg_pc+=3;
1672 return 0;
1673 }
1674
ora_absx(void)1675 int ora_absx(void) {
1676 if (reg_p & FL_T) {
1677 UChar temp = get_8bit_zp(reg_x);
1678 chk_flnz_8bit(temp |= absx_operand(reg_pc+1));
1679 put_8bit_zp(reg_x, temp);
1680 cycles+=8;
1681
1682 } else {
1683 chk_flnz_8bit(reg_a |= absx_operand(reg_pc+1));
1684 cycles+=5;
1685 }
1686 reg_pc+=3;
1687 return 0;
1688 }
1689
ora_absy(void)1690 int ora_absy(void) {
1691 if (reg_p & FL_T) {
1692 UChar temp = get_8bit_zp(reg_x);
1693 chk_flnz_8bit(temp |= absy_operand(reg_pc+1));
1694 put_8bit_zp(reg_x, temp);
1695 cycles+=8;
1696
1697 } else {
1698 chk_flnz_8bit(reg_a |= absy_operand(reg_pc+1));
1699 cycles+=5;
1700 }
1701 reg_pc+=3;
1702 return 0;
1703 }
1704
ora_imm(void)1705 int ora_imm(void) {
1706 if (reg_p & FL_T) {
1707 UChar temp = get_8bit_zp(reg_x);
1708 chk_flnz_8bit(temp |= imm_operand(reg_pc+1));
1709 put_8bit_zp(reg_x, temp);
1710 cycles+=5;
1711
1712 } else {
1713 chk_flnz_8bit(reg_a |= imm_operand(reg_pc+1));
1714 cycles+=2;
1715 }
1716 reg_pc+=2;
1717 return 0;
1718 }
1719
ora_zp(void)1720 int ora_zp(void) {
1721 if (reg_p & FL_T) {
1722 UChar temp = get_8bit_zp(reg_x);
1723 chk_flnz_8bit(temp |= zp_operand(reg_pc+1));
1724 put_8bit_zp(reg_x, temp);
1725 cycles+=7;
1726
1727 } else {
1728 chk_flnz_8bit(reg_a |= zp_operand(reg_pc+1));
1729 cycles+=4;
1730 }
1731 reg_pc+=2;
1732 return 0;
1733 }
1734
ora_zpx(void)1735 int ora_zpx(void) {
1736 if (reg_p & FL_T) {
1737 UChar temp = get_8bit_zp(reg_x);
1738 chk_flnz_8bit(temp |= zpx_operand(reg_pc+1));
1739 put_8bit_zp(reg_x, temp);
1740 cycles+=7;
1741
1742 } else {
1743 chk_flnz_8bit(reg_a |= zpx_operand(reg_pc+1));
1744 cycles+=4;
1745 }
1746 reg_pc+=2;
1747 return 0;
1748 }
1749
ora_zpind(void)1750 int ora_zpind(void) {
1751 if (reg_p & FL_T) {
1752 UChar temp = get_8bit_zp(reg_x);
1753 chk_flnz_8bit(temp |= zpind_operand(reg_pc+1));
1754 put_8bit_zp(reg_x, temp);
1755 cycles+=10;
1756
1757 } else {
1758 chk_flnz_8bit(reg_a |= zpind_operand(reg_pc+1));
1759 cycles+=7;
1760 }
1761 reg_pc+=2;
1762 return 0;
1763 }
1764
ora_zpindx(void)1765 int ora_zpindx(void) {
1766 if (reg_p & FL_T) {
1767 UChar temp = get_8bit_zp(reg_x);
1768 chk_flnz_8bit(temp |= zpindx_operand(reg_pc+1));
1769 put_8bit_zp(reg_x, temp);
1770 cycles+=10;
1771
1772 } else {
1773 chk_flnz_8bit(reg_a |= zpindx_operand(reg_pc+1));
1774 cycles+=7;
1775 }
1776 reg_pc+=2;
1777 return 0;
1778 }
1779
ora_zpindy(void)1780 int ora_zpindy(void) {
1781 if (reg_p & FL_T) {
1782 UChar temp = get_8bit_zp(reg_x);
1783 chk_flnz_8bit(temp |= zpindy_operand(reg_pc+1));
1784 put_8bit_zp(reg_x, temp);
1785 cycles+=10;
1786
1787 } else {
1788 chk_flnz_8bit(reg_a |= zpindy_operand(reg_pc+1));
1789 cycles+=7;
1790 }
1791 reg_pc+=2;
1792 return 0;
1793 }
1794
pha(void)1795 int pha(void) {
1796 reg_p &= ~FL_T;
1797 push_8bit(reg_a);
1798 reg_pc++;
1799 cycles+=3;
1800 return 0;
1801 }
1802
php(void)1803 int php(void) {
1804 reg_p &= ~FL_T;
1805 push_8bit(reg_p);
1806 reg_pc++;
1807 cycles+=3;
1808 return 0;
1809 }
1810
phx(void)1811 int phx(void) {
1812 reg_p &= ~FL_T;
1813 push_8bit(reg_x);
1814 reg_pc++;
1815 cycles+=3;
1816 return 0;
1817 }
1818
phy(void)1819 int phy(void) {
1820 reg_p &= ~FL_T;
1821 push_8bit(reg_y);
1822 reg_pc++;
1823 cycles+=3;
1824 return 0;
1825 }
1826
pla(void)1827 int pla(void) {
1828 chk_flnz_8bit(reg_a = pull_8bit());
1829 reg_pc++;
1830 cycles+=4;
1831 return 0;
1832 }
1833
plp(void)1834 int plp(void) {
1835 reg_p = pull_8bit();
1836 reg_pc++;
1837 cycles+=4;
1838 return 0;
1839 }
1840
plx(void)1841 int plx(void) {
1842 chk_flnz_8bit(reg_x = pull_8bit());
1843 reg_pc++;
1844 cycles+=4;
1845 return 0;
1846 }
1847
ply(void)1848 int ply(void) {
1849 chk_flnz_8bit(reg_y = pull_8bit());
1850 reg_pc++;
1851 cycles+=4;
1852 return 0;
1853 }
1854
rmb0(void)1855 int rmb0(void) {
1856 UChar temp = imm_operand(reg_pc+1);
1857 reg_p &= ~FL_T;
1858 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x01));
1859 reg_pc+=2;
1860 cycles+=7;
1861 return 0;
1862 }
1863
rmb1(void)1864 int rmb1(void) {
1865 UChar temp = imm_operand(reg_pc+1);
1866 reg_p &= ~FL_T;
1867 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x02));
1868 reg_pc+=2;
1869 cycles+=7;
1870 return 0;
1871 }
1872
rmb2(void)1873 int rmb2(void) {
1874 UChar temp = imm_operand(reg_pc+1);
1875 reg_p &= ~FL_T;
1876 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x04));
1877 reg_pc+=2;
1878 cycles+=7;
1879 return 0;
1880 }
1881
rmb3(void)1882 int rmb3(void) {
1883 UChar temp = imm_operand(reg_pc+1);
1884 reg_p &= ~FL_T;
1885 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x08));
1886 reg_pc+=2;
1887 cycles+=7;
1888 return 0;
1889 }
1890
rmb4(void)1891 int rmb4(void) {
1892 UChar temp = imm_operand(reg_pc+1);
1893 reg_p &= ~FL_T;
1894 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x10));
1895 reg_pc+=2;
1896 cycles+=7;
1897 return 0;
1898 }
1899
rmb5(void)1900 int rmb5(void) {
1901 UChar temp = imm_operand(reg_pc+1);
1902 reg_p &= ~FL_T;
1903 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x20));
1904 reg_pc+=2;
1905 cycles+=7;
1906 return 0;
1907 }
1908
rmb6(void)1909 int rmb6(void) {
1910 UChar temp = imm_operand(reg_pc+1);
1911 reg_p &= ~FL_T;
1912 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x40));
1913 reg_pc+=2;
1914 cycles+=7;
1915 return 0;
1916 }
1917
rmb7(void)1918 int rmb7(void) {
1919 UChar temp = imm_operand(reg_pc+1);
1920 reg_p &= ~FL_T;
1921 put_8bit_zp(temp, get_8bit_zp(temp) & (~0x80));
1922 reg_pc+=2;
1923 cycles+=7;
1924 return 0;
1925 }
1926
rol_a(void)1927 int rol_a(void) {
1928 UChar flg_tmp = (reg_p & FL_C) ? 1:0;
1929 UChar temp = reg_a;
1930
1931 reg_a = (reg_a<<1)+flg_tmp;
1932 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1933 | ((temp & 0x80) ? FL_C:0)
1934 | flnz_list[reg_a];
1935 reg_pc++;
1936 cycles+=2;
1937 return 0;
1938 }
1939
rol_abs(void)1940 int rol_abs(void) {
1941 UChar flg_tmp = (reg_p & FL_C) ? 1:0;
1942 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
1943 UChar temp1 = get_8bit_addr(temp_addr);
1944 UChar temp = (temp1<<1)+flg_tmp;
1945
1946 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1947 | ((temp1 & 0x80) ? FL_C:0)
1948 | flnz_list[temp];
1949 cycles+=7;
1950 put_8bit_addr(temp_addr, temp);
1951 reg_pc+=3;
1952 return 0;
1953 }
1954
rol_absx(void)1955 int rol_absx(void) {
1956 UChar flg_tmp = (reg_p & FL_C) ? 1:0;
1957 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
1958 UChar temp1 = get_8bit_addr(temp_addr);
1959 UChar temp = (temp1<<1)+flg_tmp;
1960
1961 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1962 | ((temp1 & 0x80) ? FL_C:0)
1963 | flnz_list[temp];
1964 cycles+=7;
1965 put_8bit_addr(temp_addr, temp);
1966 reg_pc+=3;
1967 return 0;
1968 }
1969
rol_zp(void)1970 int rol_zp(void) {
1971 UChar flg_tmp = (reg_p & FL_C) ? 1:0;
1972 UChar zp_addr = imm_operand(reg_pc+1);
1973 UChar temp1 = get_8bit_zp(zp_addr);
1974 UChar temp = (temp1<<1)+flg_tmp;
1975
1976 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1977 | ((temp1 & 0x80) ? FL_C:0)
1978 | flnz_list[temp];
1979 put_8bit_zp(zp_addr, temp);
1980 reg_pc+=2;
1981 cycles+=6;
1982 return 0;
1983 }
1984
rol_zpx(void)1985 int rol_zpx(void) {
1986 UChar flg_tmp = (reg_p & FL_C) ? 1:0;
1987 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
1988 UChar temp1 = get_8bit_zp(zp_addr);
1989 UChar temp = (temp1<<1)+flg_tmp;
1990
1991 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
1992 | ((temp1 & 0x80) ? FL_C:0)
1993 | flnz_list[temp];
1994 put_8bit_zp(zp_addr, temp);
1995 reg_pc+=2;
1996 cycles+=6;
1997 return 0;
1998 }
1999
ror_a(void)2000 int ror_a(void) {
2001 UChar flg_tmp = (reg_p & FL_C) ? 0x80:0;
2002 UChar temp = reg_a;
2003
2004 reg_a = (reg_a/2)+flg_tmp;
2005 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
2006 | ((temp & 0x01) ? FL_C:0)
2007 | flnz_list[reg_a];
2008 reg_pc++;
2009 cycles+=2;
2010 return 0;
2011 }
2012
ror_abs(void)2013 int ror_abs(void) {
2014 UChar flg_tmp = (reg_p & FL_C) ? 0x80:0;
2015 UInt16 temp_addr = get_16bit_addr(reg_pc+1);
2016 UChar temp1 = get_8bit_addr(temp_addr);
2017 UChar temp = (temp1/2)+flg_tmp;
2018
2019 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
2020 | ((temp1 & 0x01) ? FL_C:0)
2021 | flnz_list[temp];
2022 cycles+=7;
2023 put_8bit_addr(temp_addr, temp);
2024 reg_pc+=3;
2025 return 0;
2026 }
2027
ror_absx(void)2028 int ror_absx(void) {
2029 UChar flg_tmp = (reg_p & FL_C) ? 0x80:0;
2030 UInt16 temp_addr = get_16bit_addr(reg_pc+1)+reg_x;
2031 UChar temp1 = get_8bit_addr(temp_addr);
2032 UChar temp = (temp1/2)+flg_tmp;
2033
2034 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
2035 | ((temp1 & 0x01) ? FL_C:0)
2036 | flnz_list[temp];
2037 cycles+=7;
2038 put_8bit_addr(temp_addr, temp);
2039 reg_pc+=3;
2040 return 0;
2041 }
2042
ror_zp(void)2043 int ror_zp(void) {
2044 UChar flg_tmp = (reg_p & FL_C) ? 0x80:0;
2045 UChar zp_addr = imm_operand(reg_pc+1);
2046 UChar temp1 = get_8bit_zp(zp_addr);
2047 UChar temp = (temp1/2)+flg_tmp;
2048
2049 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
2050 | ((temp1 & 0x01) ? FL_C:0)
2051 | flnz_list[temp];
2052 put_8bit_zp(zp_addr, temp);
2053 reg_pc+=2;
2054 cycles+=6;
2055 return 0;
2056 }
2057
ror_zpx(void)2058 int ror_zpx(void) {
2059 UChar flg_tmp = (reg_p & FL_C) ? 0x80:0;
2060 UChar zp_addr = imm_operand(reg_pc+1)+reg_x;
2061 UChar temp1 = get_8bit_zp(zp_addr);
2062 UChar temp = (temp1/2)+flg_tmp;
2063
2064 reg_p = (reg_p & ~(FL_N|FL_T|FL_Z|FL_C))
2065 | ((temp1 & 0x01) ? FL_C:0)
2066 | flnz_list[temp];
2067 put_8bit_zp(zp_addr, temp);
2068 reg_pc+=2;
2069 cycles+=6;
2070 return 0;
2071 }
2072
rti(void)2073 int rti(void) {
2074 /* FL_B reset in RTI */
2075 reg_p = pull_8bit() & ~FL_B;
2076 reg_pc = pull_16bit();
2077 cycles+=7;
2078 return 0;
2079 }
2080
rts(void)2081 int rts(void) {
2082 reg_p &= ~FL_T;
2083 reg_pc = pull_16bit()+1;
2084 cycles+=7;
2085 return 0;
2086 }
2087
sax(void)2088 int sax(void) {
2089 UChar temp = reg_x;
2090 reg_p &= ~FL_T;
2091 reg_x = reg_a;
2092 reg_a = temp;
2093 reg_pc++;
2094 cycles+=3;
2095 return 0;
2096 }
2097
say(void)2098 int say(void) {
2099 UChar temp = reg_y;
2100 reg_p &= ~FL_T;
2101 reg_y = reg_a;
2102 reg_a = temp;
2103 reg_pc++;
2104 cycles+=3;
2105 return 0;
2106 }
2107
sbc_abs(void)2108 int sbc_abs(void) {
2109 sbc(abs_operand(reg_pc+1));
2110 reg_pc+=3;
2111 cycles+=5;
2112 return 0;
2113 }
2114
sbc_absx(void)2115 int sbc_absx(void) {
2116 sbc(absx_operand(reg_pc+1));
2117 reg_pc+=3;
2118 cycles+=5;
2119 return 0;
2120 }
2121
sbc_absy(void)2122 int sbc_absy(void) {
2123 sbc(absy_operand(reg_pc+1));
2124 reg_pc+=3;
2125 cycles+=5;
2126 return 0;
2127 }
2128
sbc_imm(void)2129 int sbc_imm(void) {
2130 sbc(imm_operand(reg_pc+1));
2131 reg_pc+=2;
2132 cycles+=2;
2133 return 0;
2134 }
2135
sbc_zp(void)2136 int sbc_zp(void) {
2137 sbc(zp_operand(reg_pc+1));
2138 reg_pc+=2;
2139 cycles+=4;
2140 return 0;
2141 }
2142
sbc_zpx(void)2143 int sbc_zpx(void) {
2144 sbc(zpx_operand(reg_pc+1));
2145 reg_pc+=2;
2146 cycles+=4;
2147 return 0;
2148 }
2149
sbc_zpind(void)2150 int sbc_zpind(void) {
2151 sbc(zpind_operand(reg_pc+1));
2152 reg_pc+=2;
2153 cycles+=7;
2154 return 0;
2155 }
2156
sbc_zpindx(void)2157 int sbc_zpindx(void) {
2158 sbc(zpindx_operand(reg_pc+1));
2159 reg_pc+=2;
2160 cycles+=7;
2161 return 0;
2162 }
2163
sbc_zpindy(void)2164 int sbc_zpindy(void) {
2165 sbc(zpindy_operand(reg_pc+1));
2166 reg_pc+=2;
2167 cycles+=7;
2168 return 0;
2169 }
2170
sec(void)2171 int sec(void) {
2172 reg_p = (reg_p|FL_C) & ~FL_T;
2173 reg_pc++;
2174 cycles+=2;
2175 return 0;
2176 }
2177
sed(void)2178 int sed(void) {
2179 reg_p = (reg_p|FL_D) & ~FL_T;
2180 reg_pc++;
2181 cycles+=2;
2182 return 0;
2183 }
2184
sei(void)2185 int sei(void) {
2186 #ifdef DUMP_ON_SEI
2187 int i;
2188 Log("MMR[7]\n");
2189 for (i = 0xE000; i < 0xE100; i++)
2190 {
2191 Log("%02X ", get_8bit_addr(i));
2192 }
2193 #endif
2194 reg_p = (reg_p|FL_I) & ~FL_T;
2195 reg_pc++;
2196 cycles+=2;
2197 return 0;
2198 }
2199
set(void)2200 int set(void) {
2201 reg_p |= FL_T;
2202 reg_pc++;
2203 cycles+=2;
2204 return 0;
2205 }
2206
smb0(void)2207 int smb0(void) {
2208 UChar temp = imm_operand(reg_pc+1);
2209 reg_p &= ~FL_T;
2210 put_8bit_zp(temp, get_8bit_zp(temp) | 0x01);
2211 reg_pc+=2;
2212 cycles+=7;
2213 return 0;
2214 }
2215
smb1(void)2216 int smb1(void) {
2217 UChar temp = imm_operand(reg_pc+1);
2218 reg_p &= ~FL_T;
2219 put_8bit_zp(temp, get_8bit_zp(temp) | 0x02);
2220 reg_pc+=2;
2221 cycles+=7;
2222 return 0;
2223 }
2224
smb2(void)2225 int smb2(void) {
2226 UChar temp = imm_operand(reg_pc+1);
2227 reg_p &= ~FL_T;
2228 put_8bit_zp(temp, get_8bit_zp(temp) | 0x04);
2229 reg_pc+=2;
2230 cycles+=7;
2231 return 0;
2232 }
2233
smb3(void)2234 int smb3(void) {
2235 UChar temp = imm_operand(reg_pc+1);
2236 reg_p &= ~FL_T;
2237 put_8bit_zp(temp, get_8bit_zp(temp) | 0x08);
2238 reg_pc+=2;
2239 cycles+=7;
2240 return 0;
2241 }
2242
smb4(void)2243 int smb4(void) {
2244 UChar temp = imm_operand(reg_pc+1);
2245 reg_p &= ~FL_T;
2246 put_8bit_zp(temp, get_8bit_zp(temp) | 0x10);
2247 reg_pc+=2;
2248 cycles+=7;
2249 return 0;
2250 }
2251
smb5(void)2252 int smb5(void) {
2253 UChar temp = imm_operand(reg_pc+1);
2254 reg_p &= ~FL_T;
2255 put_8bit_zp(temp, get_8bit_zp(temp) | 0x20);
2256 reg_pc+=2;
2257 cycles+=7;
2258 return 0;
2259 }
2260
smb6(void)2261 int smb6(void) {
2262 UChar temp = imm_operand(reg_pc+1);
2263 reg_p &= ~FL_T;
2264 put_8bit_zp(temp, get_8bit_zp(temp) | 0x40);
2265 reg_pc+=2;
2266 cycles+=7;
2267 return 0;
2268 }
2269
smb7(void)2270 int smb7(void) {
2271 UChar temp = imm_operand(reg_pc+1);
2272 reg_p &= ~FL_T;
2273 put_8bit_zp(temp, get_8bit_zp(temp) | 0x80);
2274 reg_pc+=2;
2275 cycles+=7;
2276 return 0;
2277 }
2278
st0(void)2279 int st0(void) {
2280 reg_p &= ~FL_T;
2281 IO_write(0,imm_operand(reg_pc+1));
2282 reg_pc+=2;
2283 cycles+=4;
2284 return 0;
2285 }
2286
st1(void)2287 int st1(void) {
2288 reg_p &= ~FL_T;
2289 IO_write(2,imm_operand(reg_pc+1));
2290 reg_pc+=2;
2291 cycles+=4;
2292 return 0;
2293 }
2294
st2(void)2295 int st2(void) {
2296 reg_p &= ~FL_T;
2297 IO_write(3,imm_operand(reg_pc+1));
2298 reg_pc+=2;
2299 cycles+=4;
2300 return 0;
2301 }
2302
sta_abs(void)2303 int sta_abs(void) {
2304 reg_p &= ~FL_T;
2305 cycles+=5;
2306 put_8bit_addr(get_16bit_addr(reg_pc+1), reg_a);
2307 reg_pc+=3;
2308 return 0;
2309 }
2310
sta_absx(void)2311 int sta_absx(void) {
2312 reg_p &= ~FL_T;
2313 cycles+=5;
2314 put_8bit_addr(get_16bit_addr(reg_pc+1)+reg_x, reg_a);
2315 reg_pc+=3;
2316 return 0;
2317 }
2318
sta_absy(void)2319 int sta_absy(void) {
2320 reg_p &= ~FL_T;
2321 cycles+=5;
2322 put_8bit_addr(get_16bit_addr(reg_pc+1)+reg_y, reg_a);
2323 reg_pc+=3;
2324 return 0;
2325 }
2326
sta_zp(void)2327 int sta_zp(void) {
2328 reg_p &= ~FL_T;
2329 put_8bit_zp(imm_operand(reg_pc+1), reg_a);
2330
2331 reg_pc+=2;
2332 cycles+=4;
2333 return 0;
2334 }
2335
sta_zpx(void)2336 int sta_zpx(void) {
2337 reg_p &= ~FL_T;
2338 put_8bit_zp(imm_operand(reg_pc+1)+reg_x, reg_a);
2339 reg_pc+=2;
2340 cycles+=4;
2341 return 0;
2342 }
2343
sta_zpind(void)2344 int sta_zpind(void) {
2345 reg_p &= ~FL_T;
2346 cycles+=7;
2347 put_8bit_addr(get_16bit_zp(imm_operand(reg_pc+1)), reg_a);
2348 reg_pc+=2;
2349 return 0;
2350 }
2351
sta_zpindx(void)2352 int sta_zpindx(void) {
2353 reg_p &= ~FL_T;
2354 cycles+=7;
2355 put_8bit_addr(get_16bit_zp(imm_operand(reg_pc+1)+reg_x), reg_a);
2356 reg_pc+=2;
2357 return 0;
2358 }
2359
sta_zpindy(void)2360 int sta_zpindy(void) {
2361 reg_p &= ~FL_T;
2362 cycles+=7;
2363 put_8bit_addr(get_16bit_zp(imm_operand(reg_pc+1))+reg_y, reg_a);
2364 reg_pc+=2;
2365 return 0;
2366 }
2367
stx_abs(void)2368 int stx_abs(void) {
2369 reg_p &= ~FL_T;
2370 cycles+=5;
2371 put_8bit_addr(get_16bit_addr(reg_pc+1), reg_x);
2372 reg_pc+=3;
2373 return 0;
2374 }
2375
stx_zp(void)2376 int stx_zp(void) {
2377 reg_p &= ~FL_T;
2378 put_8bit_zp(imm_operand(reg_pc+1), reg_x);
2379 reg_pc+=2;
2380 cycles+=4;
2381 return 0;
2382 }
2383
stx_zpy(void)2384 int stx_zpy(void) {
2385 reg_p &= ~FL_T;
2386 put_8bit_zp(imm_operand(reg_pc+1)+reg_y, reg_x);
2387 reg_pc+=2;
2388 cycles+=4;
2389 return 0;
2390 }
2391
sty_abs(void)2392 int sty_abs(void) {
2393 reg_p &= ~FL_T;
2394 cycles+=5;
2395 put_8bit_addr(get_16bit_addr(reg_pc+1), reg_y);
2396 reg_pc+=3;
2397 return 0;
2398 }
2399
sty_zp(void)2400 int sty_zp(void) {
2401 reg_p &= ~FL_T;
2402 put_8bit_zp(imm_operand(reg_pc+1), reg_y);
2403 reg_pc+=2;
2404 cycles+=4;
2405 return 0;
2406 }
2407
sty_zpx(void)2408 int sty_zpx(void) {
2409 reg_p &= ~FL_T;
2410 put_8bit_zp(imm_operand(reg_pc+1)+reg_x, reg_y);
2411 reg_pc+=2;
2412 cycles+=4;
2413 return 0;
2414 }
2415
stz_abs(void)2416 int stz_abs(void) {
2417 reg_p &= ~FL_T;
2418 cycles+=5;
2419 put_8bit_addr(get_16bit_addr(reg_pc+1), 0);
2420 reg_pc+=3;
2421 return 0;
2422 }
2423
stz_absx(void)2424 int stz_absx(void) {
2425 reg_p &= ~FL_T;
2426 cycles+=5;
2427 put_8bit_addr((get_16bit_addr(reg_pc+1)+reg_x), 0);
2428 reg_pc+=3;
2429 return 0;
2430 }
2431
stz_zp(void)2432 int stz_zp(void) {
2433 reg_p &= ~FL_T;
2434 put_8bit_zp(imm_operand(reg_pc+1), 0);
2435 reg_pc+=2;
2436 cycles+=4;
2437 return 0;
2438 }
2439
stz_zpx(void)2440 int stz_zpx(void) {
2441 reg_p &= ~FL_T;
2442 put_8bit_zp(imm_operand(reg_pc+1)+reg_x, 0);
2443 reg_pc+=2;
2444 cycles+=4;
2445 return 0;
2446 }
2447
sxy(void)2448 int sxy(void) {
2449 UChar temp = reg_y;
2450 reg_p &= ~FL_T;
2451 reg_y = reg_x;
2452 reg_x = temp;
2453 reg_pc++;
2454 cycles+=3;
2455 return 0;
2456 }
2457
tai(void)2458 int tai(void) {
2459 UInt16 from, to, len, alternate;
2460
2461 reg_p &= ~FL_T;
2462 from = get_16bit_addr(reg_pc+1);
2463 to = get_16bit_addr(reg_pc+3);
2464 len = get_16bit_addr(reg_pc+5);
2465 alternate = 0;
2466
2467 #if defined(CD_DEBUG) && defined(INLINED_ACCESSORS)
2468 fprintf(stderr, "Transfert from bank 0x%02x to bank 0x%02x\n", mmr[from >> 13], mmr[to >> 13]);
2469 #endif
2470
2471 cycles+=(6 * len) + 17;
2472 while (len-- != 0) {
2473 put_8bit_addr(to++, get_8bit_addr(from+alternate));
2474 alternate ^= 1;
2475 }
2476 reg_pc+=7;
2477 return 0;
2478 }
2479
tam(void)2480 int tam(void) {
2481 UInt16 i;
2482 UChar bitfld = imm_operand(reg_pc+1);
2483
2484 #if defined(KERNEL_DEBUG)
2485 if (bitfld == 0)
2486 {
2487 fprintf(stderr, "TAM with argument 0\n");
2488 Log("TAM with argument 0\n");
2489 }
2490 else if (!one_bit_set(bitfld))
2491 {
2492 fprintf(stderr, "TAM with unusual argument 0x%02x\n", bitfld);
2493 Log("TAM with unusual argument 0x%02x\n", bitfld);
2494 }
2495 #endif
2496
2497 for (i = 0; i < 8; i++) {
2498 if (bitfld & (1 << i)) {
2499 mmr[i] = reg_a;
2500 bank_set(i, reg_a);
2501 }
2502 }
2503
2504 reg_p &= ~FL_T;
2505 reg_pc+=2;
2506 cycles+=5;
2507 return 0;
2508 }
2509
tax(void)2510 int tax(void) {
2511 chk_flnz_8bit(reg_x = reg_a);
2512 reg_pc++;
2513 cycles+=2;
2514 return 0;
2515 }
2516
tay(void)2517 int tay(void) {
2518 chk_flnz_8bit(reg_y = reg_a);
2519 reg_pc++;
2520 cycles+=2;
2521 return 0;
2522 }
2523
tdd(void)2524 int tdd(void) {
2525 UInt16 from, to, len;
2526
2527 reg_p &= ~FL_T;
2528 from = get_16bit_addr(reg_pc+1);
2529 to = get_16bit_addr(reg_pc+3);
2530 len = get_16bit_addr(reg_pc+5);
2531
2532 #if defined(CD_DEBUG) && defined(INLINED_ACCESSORS)
2533 fprintf(stderr, "Transfert from bank 0x%02x to bank 0x%02x\n", mmr[from >> 13], mmr[to >> 13]);
2534 #endif
2535
2536 cycles+=(6 * len) + 17;
2537 while (len-- != 0) {
2538 put_8bit_addr(to--, get_8bit_addr(from--));
2539 }
2540 reg_pc+=7;
2541 return 0;
2542 }
2543
tia(void)2544 int tia(void) {
2545 UInt16 from, to, len, alternate;
2546
2547 reg_p &= ~FL_T;
2548 from = get_16bit_addr(reg_pc+1);
2549 to = get_16bit_addr(reg_pc+3);
2550 len = get_16bit_addr(reg_pc+5);
2551 alternate = 0;
2552
2553 #if defined(CD_DEBUG) && defined(INLINED_ACCESSORS)
2554 fprintf(stderr, "Transfert from bank 0x%02x to bank 0x%02x\n", mmr[from >> 13], mmr[to >> 13]);
2555 #endif
2556
2557 cycles+=(6 * len) + 17;
2558 while (len-- != 0) {
2559 put_8bit_addr(to+alternate, get_8bit_addr(from++));
2560 alternate ^= 1;
2561 }
2562 reg_pc+=7;
2563 return 0;
2564 }
2565
tii(void)2566 int tii(void) {
2567 UInt16 from, to, len;
2568
2569 reg_p &= ~FL_T;
2570 from = get_16bit_addr(reg_pc+1);
2571 to = get_16bit_addr(reg_pc+3);
2572 len = get_16bit_addr(reg_pc+5);
2573
2574 #if defined(CD_DEBUG) && defined(INLINED_ACCESSORS)
2575 fprintf(stderr, "Transfert from bank 0x%02x to bank 0x%02x\n", mmr[from >> 13], mmr[to >> 13]);
2576 #endif
2577
2578 cycles+=(6 * len) + 17;
2579 while (len-- != 0) {
2580 put_8bit_addr(to++, get_8bit_addr(from++));
2581 }
2582 reg_pc+=7;
2583 return 0;
2584 }
2585
tin(void)2586 int tin(void) {
2587 UInt16 from, to, len;
2588
2589 reg_p &= ~FL_T;
2590 from = get_16bit_addr(reg_pc+1);
2591 to = get_16bit_addr(reg_pc+3);
2592 len = get_16bit_addr(reg_pc+5);
2593
2594 #if defined(CD_DEBUG) && defined(INLINED_ACCESSORS)
2595 fprintf(stderr, "Transfert from bank 0x%02x to bank 0x%02x\n", mmr[from >> 13], mmr[to >> 13]);
2596 #endif
2597
2598 cycles+=(6 * len) + 17;
2599 while (len-- != 0) {
2600 put_8bit_addr(to, get_8bit_addr(from++));
2601 }
2602 reg_pc+=7;
2603 return 0;
2604 }
2605
tma(void)2606 int tma(void) {
2607 int i;
2608 UChar bitfld = imm_operand(reg_pc+1);
2609
2610 #if defined(KERNEL_DEBUG)
2611 if (bitfld == 0)
2612 {
2613 fprintf(stderr, "TMA with argument 0\n");
2614 Log("TMA with argument 0\n");
2615 }
2616 else if (!one_bit_set(bitfld))
2617 {
2618 fprintf(stderr, "TMA with unusual argument 0x%02x\n", bitfld);
2619 Log("TMA with unusual argument 0x%02x\n", bitfld);
2620 }
2621 #endif
2622
2623 for (i = 0; i < 8; i++) {
2624 if (bitfld & (1 << i)) {
2625 reg_a = mmr[i];
2626 }
2627 }
2628 reg_p &= ~FL_T;
2629 reg_pc+=2;
2630 cycles+=4;
2631 return 0;
2632 }
2633
trb_abs(void)2634 int trb_abs(void) {
2635 UInt16 abs_addr = get_16bit_addr(reg_pc+1);
2636 UChar temp = get_8bit_addr(abs_addr);
2637 UChar temp1 = (~reg_a) & temp;
2638
2639 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2640 | ((temp1&0x80) ? FL_N:0)
2641 | ((temp1&0x40) ? FL_V:0)
2642 | ((temp & reg_a) ? 0:FL_Z);
2643 cycles+=7;
2644 put_8bit_addr(abs_addr, temp1);
2645 reg_pc+=3;
2646 return 0;
2647 }
2648
trb_zp(void)2649 int trb_zp(void) {
2650 UChar zp_addr = imm_operand(reg_pc+1);
2651 UChar temp = get_8bit_zp(zp_addr);
2652 UChar temp1 = (~reg_a) & temp;
2653
2654 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2655 | ((temp1&0x80) ? FL_N:0)
2656 | ((temp1&0x40) ? FL_V:0)
2657 | ((temp & reg_a) ? 0:FL_Z);
2658 put_8bit_zp(zp_addr, temp1);
2659 reg_pc+=2;
2660 cycles+=6;
2661 return 0;
2662 }
2663
tsb_abs(void)2664 int tsb_abs(void) {
2665 UInt16 abs_addr = get_16bit_addr(reg_pc+1);
2666 UChar temp = get_8bit_addr(abs_addr);
2667 UChar temp1 = reg_a | temp;
2668
2669 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2670 | ((temp1&0x80) ? FL_N:0)
2671 | ((temp1&0x40) ? FL_V:0)
2672 | ((temp & reg_a) ? 0:FL_Z);
2673 cycles+=7;
2674 put_8bit_addr(abs_addr, temp1);
2675 reg_pc+=3;
2676 return 0;
2677 }
2678
tsb_zp(void)2679 int tsb_zp(void) {
2680 UChar zp_addr = imm_operand(reg_pc+1);
2681 UChar temp = get_8bit_zp(zp_addr);
2682 UChar temp1 = reg_a | temp;
2683
2684 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2685 | ((temp1&0x80) ? FL_N:0)
2686 | ((temp1&0x40) ? FL_V:0)
2687 | ((temp & reg_a) ? 0:FL_Z);
2688 put_8bit_zp(zp_addr, temp1);
2689 reg_pc+=2;
2690 cycles+=6;
2691 return 0;
2692 }
2693
tstins_abs(void)2694 int tstins_abs(void) {
2695 UChar imm = imm_operand(reg_pc+1);
2696 UChar temp = abs_operand(reg_pc+2);
2697
2698 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2699 | ((temp&0x80) ? FL_N:0)
2700 | ((temp&0x40) ? FL_V:0)
2701 | ((temp&imm) ? 0:FL_Z);
2702 cycles+=8;
2703 reg_pc+=4;
2704 return 0;
2705 }
2706
tstins_absx(void)2707 int tstins_absx(void) {
2708 UChar imm = imm_operand(reg_pc+1);
2709 UChar temp = absx_operand(reg_pc+2);
2710
2711 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2712 | ((temp&0x80) ? FL_N:0)
2713 | ((temp&0x40) ? FL_V:0)
2714 | ((temp&imm) ? 0:FL_Z);
2715 cycles+=8;
2716 reg_pc+=4;
2717 return 0;
2718 }
2719
tstins_zp(void)2720 int tstins_zp(void) {
2721 UChar imm = imm_operand(reg_pc+1);
2722 UChar temp = zp_operand(reg_pc+2);
2723
2724 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2725 | ((temp&0x80) ? FL_N:0)
2726 | ((temp&0x40) ? FL_V:0)
2727 | ((temp&imm) ? 0:FL_Z);
2728 cycles+=7;
2729 reg_pc+=3;
2730 return 0;
2731 }
2732
tstins_zpx(void)2733 int tstins_zpx(void) {
2734 UChar imm = imm_operand(reg_pc+1);
2735 UChar temp = zpx_operand(reg_pc+2);
2736
2737 reg_p = (reg_p & ~(FL_N|FL_V|FL_T|FL_Z))
2738 | ((temp&0x80) ? FL_N:0)
2739 | ((temp&0x40) ? FL_V:0)
2740 | ((temp&imm) ? 0:FL_Z);
2741 cycles+=7;
2742 reg_pc+=3;
2743 return 0;
2744 }
2745
2746
tsx(void)2747 int tsx(void) {
2748 chk_flnz_8bit(reg_x = reg_s);
2749 reg_pc++;
2750 cycles+=2;
2751 return 0;
2752 }
2753
txa(void)2754 int txa(void) {
2755 chk_flnz_8bit(reg_a = reg_x);
2756 reg_pc++;
2757 cycles+=2;
2758 return 0;
2759 }
2760
txs(void)2761 int txs(void) {
2762 reg_p &= ~FL_T;
2763 reg_s = reg_x;
2764 reg_pc++;
2765 cycles+=2;
2766 return 0;
2767 }
2768
tya(void)2769 int tya(void) {
2770 chk_flnz_8bit(reg_a = reg_y);
2771 reg_pc++;
2772 cycles+=2;
2773 return 0;
2774 }
2775
2776 // perform machine operations for IRQ2:
2777
int_irq2(void)2778 int int_irq2 (void) {
2779 if ((io.irq_mask & FL_IRQ2) != 0) { // interrupt disabled
2780 return 0;
2781 }
2782 //if ((irq_register & FL_IRQ2) == 0) { // interrupt disabled ?
2783 // return 0;
2784 //}
2785 cycles+=7;
2786 push_16bit(reg_pc);
2787 push_8bit(reg_p);
2788 reg_p = (reg_p & ~FL_D) | FL_I;
2789 reg_pc = get_16bit_addr(0xFFF6);
2790 return 0;
2791 }
2792
2793 // perform machine operations for IRQ1 (video interrupt):
2794
int_irq1(void)2795 int int_irq1 (void) {
2796 if ((io.irq_mask & FL_IRQ1) != 0) { // interrupt disabled
2797 return 0;
2798 }
2799 //if ((irq_register & FL_IRQ1) == 0) { // interrupt disabled ?
2800 // return 0;
2801 //}
2802 cycles+=7;
2803 push_16bit(reg_pc);
2804 push_8bit(reg_p);
2805 reg_p = (reg_p & ~FL_D) | FL_I;
2806 reg_pc = get_16bit_addr(0xFFF8);
2807 return 0;
2808 }
2809
2810 // perform machine operations for timer interrupt:
2811
int_tiq(void)2812 int int_tiq(void) {
2813 if ((io.irq_mask & FL_TIQ) != 0) { // interrupt disabled
2814 return 0;
2815 }
2816 //if ((irq_register & FL_TIQ) == 0) { // interrupt disabled ?
2817 // return 0;
2818 //}
2819 cycles+=7;
2820 push_16bit(reg_pc);
2821 push_8bit(reg_p);
2822 reg_p = (reg_p & ~FL_D) | FL_I;
2823 reg_pc = get_16bit_addr(0xFFFA);
2824 return 0;
2825 }
2826
2827 /*@ =type */
2828
2829 // Execute a single instruction :
2830
exe_instruct(void)2831 void exe_instruct(void) {
2832 (*optable_runtime[PageR[reg_pc>>13][reg_pc]].func_exe)();
2833 }
2834
2835 static void
Int6502(UChar Type)2836 Int6502 (UChar Type)
2837 {
2838 UInt16 J;
2839
2840 if ((Type == INT_NMI) || (!(reg_p & FL_I)))
2841 {
2842 cycles += 7;
2843 push_16bit(reg_pc);
2844 push_8bit(reg_p);
2845 reg_p = (reg_p & ~FL_D);
2846 /*
2847 WrRAM (SP + R->S,
2848 ((R->P & ~(B_FLAG | T_FLAG)) & ~(N_FLAG | V_FLAG | Z_FLAG)) |
2849 (R->NF & N_FLAG) | (R->VF & V_FLAG) | (R->ZF ? 0 : Z_FLAG));
2850 */
2851
2852 if (Type == INT_NMI)
2853 {
2854 J = VEC_NMI;
2855 }
2856 else
2857 {
2858 reg_p |= FL_I;
2859
2860 switch (Type)
2861 {
2862
2863 case INT_IRQ:
2864 J = VEC_IRQ;
2865 break;
2866
2867 case INT_IRQ2:
2868 J = VEC_IRQ2;
2869 break;
2870
2871 case INT_TIMER:
2872 J = VEC_TIMER;
2873 break;
2874
2875 }
2876
2877 }
2878 #ifdef KERNEL_DEBUG
2879 Log("Interruption : %04X\n", J);
2880 #endif
2881 reg_pc = get_16bit_addr((UInt16)J);
2882 } else {
2883 #ifdef KERNEL_DEBUG
2884 Log("Dropped interruption %02X\n", Type);
2885 #endif
2886 }
2887 }
2888
2889 //! Log all needed info to guess what went wrong in the cpu
dump_pce_core()2890 void dump_pce_core() {
2891
2892 int i;
2893
2894 fprintf(stderr, "Dumping PCE core\n");
2895
2896 Log("PC = 0x%04x\n", reg_pc);
2897 Log("A = 0x%02x\n", reg_a);
2898 Log("X = 0x%02x\n", reg_x);
2899 Log("Y = 0x%02x\n", reg_y);
2900 Log("P = 0x%02x\n", reg_p);
2901 Log("S = 0x%02x\n", reg_s);
2902
2903 for (i = 0; i < 8; i++)
2904 {
2905 Log("MMR[%d] = 0x%02x\n", i, mmr[i]);
2906 }
2907
2908 for (i = 0x2000; i < 0xFFFF; i++)
2909 {
2910
2911 if ((i & 0xF) == 0)
2912 {
2913 Log("%04X: ", i);
2914 }
2915
2916 Log("%02x ", get_8bit_addr((UInt16)i));
2917 if ((i & 0xF) == 0xF)
2918 {
2919 Log("\n");
2920 }
2921 if ((i & 0x1FFF) == 0x1FFF)
2922 {
2923 Log("\n-------------------------------------------------------------\n");
2924 }
2925 }
2926
2927 }
2928
2929
2930 #ifdef BENCHMARK
2931 /* code copied from utils.c */
2932 #include <sys/time.h>
osd_getTime(void)2933 static double osd_getTime(void)
2934 {
2935 #ifdef WIN32
2936 return (SDL_GetTicks() * 1e-3);
2937 #elif defined(DJGPP)
2938 return uclock() * (1.0 / UCLOCKS_PER_SEC);
2939 #else
2940 struct timeval tp;
2941
2942 gettimeofday(&tp, NULL);
2943 // printf("current microsec = %f\n",tp.tv_sec + 1e-6 * tp.tv_usec);
2944 return tp.tv_sec + 1e-6 * tp.tv_usec;
2945 #endif
2946 }
2947 #endif
2948
2949 // Execute instructions as a machine would, including all
2950 // important (known) interrupts, hardware functions, and
2951 // actual video display on the hardware
2952 //
2953 // Until the following happens:
2954 // (1) An unknown instruction is to be executed
2955 // (2) An unknown hardware access is performed
2956 // (3) <ESC> key is hit
2957
exe_go(void)2958 void exe_go(void) {
2959 int err = 0;
2960 UChar I;
2961
2962 #if defined(KERNEL_DEBUG)
2963 UInt16 old_reg_pc;
2964 #endif
2965
2966 #ifdef BENCHMARK
2967 static int countNb = 8; /* run for 8 * 65536 scan lines */
2968 static int countScan = 0; /* scan line counter */
2969 static double lastTime;
2970 lastTime = osd_getTime();
2971 #endif
2972
2973 // err is set on a 'trap':
2974 while (!err) {
2975
2976 // Log("Pc = %04x : %s\n", reg_pc, optable_runtime[Page[reg_pc>>13][reg_pc]].opname);
2977
2978 #ifdef DEBUG_KERNEL_DS
2979 /*
2980 if (reg_pc<0xE000)
2981 {
2982 Log("PC = %04X (%02X), A = %02X, X = %02X, Y = %02X, P = %02X\n",
2983 reg_pc,
2984 Page[reg_pc>>13][reg_pc],
2985 reg_a,
2986 reg_x,
2987 reg_y,
2988 reg_p);
2989
2990 {
2991 int i;
2992 for (i=0xF0; i<256; i++)
2993 Log("%02X",get_8bit_zp(i));
2994 Log("\n");
2995 }
2996
2997 }
2998 */
2999 #endif
3000
3001 /*
3002 {
3003 static char in_rom = 0;
3004 if (reg_pc == 0x3800) in_rom = 1;
3005
3006 if (in_rom)
3007 Log("PC = %04X\n",reg_pc, in_rom);
3008
3009 if (reg_pc == 0x3837)
3010 {
3011 int i;
3012 for (i = 0; i < 8; i++)
3013 Log("tmm[%d] = %d\n",i,mmr[i]);
3014 for (i = 0xE000; i < 0xFFFE; i++)
3015 Log("%02x%s",Page[i>>13][i],i & 0xf?"":"\n");
3016 }
3017
3018 if (reg_pc >= 0xE000)
3019 in_rom = 0;
3020
3021 if (reg_pc == 0x4000)
3022 {
3023 int i;
3024 for (i = 0; i < 8; i++)
3025 Log("tmm[%d] = %d\n",i,mmr[i]);
3026 for (i = 0x68; i < 0x7F; i++)
3027 {
3028 int x;
3029 Log("bank %d :",i);
3030 for (x = 0; x < 20; x++)
3031 Log("%02X",ROMMap[i][x]);
3032 Log("\n");
3033 }
3034 }
3035
3036 }
3037 */
3038
3039 #if defined(SHARED_MEMORY)
3040 if (external_control_cpu >= 0) {
3041 while (external_control_cpu == 0) {
3042 #if defined(WIN32)
3043 SDL_Delay(1);
3044 #else
3045 usleep(1);
3046 #endif
3047 }
3048 if (external_control_cpu > 0)
3049 external_control_cpu--;
3050 }
3051 #endif
3052
3053 #if defined(KERNEL_DEBUG)
3054 old_reg_pc = reg_pc;
3055 #endif
3056
3057 #undef OPCODE_LOGGING
3058 #if defined(OPCODE_LOGGING)
3059 #if defined(SDL)
3060 extern Uint8* key;
3061
3062 // if (!key[SDLK_F11])
3063 #endif
3064 if (0xC7A8 == reg_pc) {
3065 UChar offset = PageR[reg_pc >> 13][reg_pc + 1];
3066 Log("C7A8 !! %02X\n", offset);
3067 Log("zp[%02X] = %02X\n", offset, get_8bit_addr(get_16bit_zp(offset)));
3068 }
3069 Log("[%04X] (%02X) (%02X,%02X,%02X) (%02X,%02X) {%02X,%04X} {%02X}\n",
3070 reg_pc,
3071 PageR[reg_pc>>13][reg_pc],
3072 reg_a,
3073 reg_x,
3074 reg_y,
3075 reg_s,
3076 reg_p,
3077 get_8bit_addr(get_16bit_zp(0)),
3078 get_16bit_zp(0),
3079 get_8bit_zp(0x48));
3080 #endif
3081
3082 #ifdef USE_INSTR_SWITCH
3083 #include "instr-switch.c"
3084 #else
3085 err = (*optable_runtime[PageR[reg_pc>>13][reg_pc]].func_exe)();
3086 #endif
3087
3088 #if defined(KERNEL_DEBUG)
3089
3090 if (mmr[2] == 0x69)
3091 {
3092 static int old_4062 = -1;
3093 if (PageR[0x4062 >> 13][0x4062] != old_4062)
3094 {
3095 Log("[0x4062] changed from 0x%02x to 0x%02x\n", old_4062, PageR[0x4062 >> 13][0x4062]);
3096 old_4062 = PageR[0x4062 >> 13][0x4062];
3097 }
3098 }
3099
3100 if (reg_pc < 0x2000)
3101 {
3102 fprintf(stderr, "PC in I/O area [0x%04x] referer = 0x%04x\n", reg_pc, old_reg_pc);
3103 Log("PC in I/O area [0x%04x] referer = 0x%04x\n", reg_pc, old_reg_pc);
3104 }
3105 /*
3106 if ((reg_pc >= 0x2000) && (reg_pc < 0x4000))
3107 {
3108 fprintf(stderr, "PC in RAM [0x%04x] *PC = 0x%02x referer = 0x%04x\n", reg_pc, Page[reg_pc>>13][reg_pc], old_reg_pc);
3109 Log("PC in RAM [0x%04x] *PC = 0x%02x referer = 0x%04x\n", reg_pc, Page[reg_pc>>13][reg_pc], old_reg_pc);
3110 }
3111 */
3112 if (err)
3113 {
3114 dump_pce_core();
3115 /*
3116 int i;
3117 fprintf(stderr,"Err was set, PC = 0x04%x\n", reg_pc);
3118 for (i = -15; i < 15; i++)
3119 {
3120 fprintf(stderr,"%02x ", Page[(reg_pc+i)>>13][reg_pc+i]);
3121 }
3122 */
3123 }
3124 #endif
3125
3126 // err = (*optable[Page[reg_pc>>13][reg_pc]].func_exe)();
3127
3128 // TIMER stuff:
3129 // if (tiq_flag) {
3130 // tiq_flag = 0;
3131 // if (!(reg_p & FL_I)) int_tiq();
3132 // }
3133
3134 // HSYNC stuff - count cycles:
3135 if (cycles > 455)
3136 {
3137
3138 #ifdef BENCHMARK
3139 countScan++;
3140 if ((countScan & 0xFFFF) == 0) {
3141 double currentTime = osd_getTime();
3142 printf("%f\n", currentTime - lastTime);
3143 lastTime = currentTime;
3144 countNb--;
3145 if (countNb == 0) return;
3146 }
3147 #endif
3148
3149 /*
3150 Log("Horizontal sync, cycles = %d, cycleNew = %d\n",
3151 cycles,
3152 CycleNew);
3153 */
3154 CycleNew += cycles;
3155 cycles -= 455;
3156 // scanline++;
3157
3158 // Log("Calling periodic handler\n");
3159 I = Loop6502 (); /* Call the periodic handler */
3160 // _ICount += _IPeriod;
3161 /* Reset the cycle counter */
3162 cycles = 0;
3163
3164 // Log("Requested interrupt is %d\n",I);
3165
3166 if (I == INT_QUIT)
3167 {
3168 #if !defined(FINAL_RELEASE)
3169 fprintf(stderr,"Normal exit of the cpu loop (INT_QUIT interruption caught)\n");
3170 #endif
3171 return; /* Exit if INT_QUIT */
3172 }
3173 if (I)
3174 Int6502 (I); /* Interrupt if needed */
3175
3176 if ((unsigned int) (CycleNew - cyclecountold) >
3177 (unsigned int) TimerPeriod * 2)
3178
3179 cyclecountold = CycleNew;
3180
3181 }
3182 else
3183 {
3184
3185 if (CycleNew - cyclecountold >= TimerPeriod)
3186 {
3187 cyclecountold += TimerPeriod;
3188 I = TimerInt ();
3189 if (I)
3190 Int6502 (I);
3191 }
3192
3193 }
3194
3195 }
3196 #if !defined(FINAL_RELEASE)
3197 fprintf(stderr,"Abnormal exit from the cpu loop\n");
3198 #endif
3199 Log("Abnormal exit from the cpu loop\n");
3200 }
3201