git.haldean.org x6502 / 999c02b
Clean up build system and code layout. This uses real, big-boy makefiles instead of a shell script and moves all of the opcode-handling weird .h files all into one directory. Will Haldean Brown 8 years ago
28 changed file(s) with 942 addition(s) and 908 deletion(s). Raw diff Collapse all Expand all
0 CC=clang
1 PYTHON=python
2 COPTS=-o x6502 -O3 -lpthread -Wall
3 DEBUGOPTS=-DDEBUG -O0 -g
4
5 all: release
6
7 debug-names.h: generate_debug_names.py opcodes.h
8 $(PYTHON) generate_debug_names.py > debug-names.h
9
10 release: debug-names.h *.c *.h
11 $(CC) $(COPTS) *.c
12
13 debug: debug-names.h *.c *.h
14 $(CC) $(COPTS) $(DEBUGOPTS) *.c
88 It currently supports the full instruction set of the
99 6502 (plus a few extensions) and has an extremely
1010 rudimentary simulated I/O bus. It should be able to run
11 arbitrary x6502 bytecode with "correct" results,
11 arbitrary x6502 bytecode with ``correct'' results,
1212 although most binaries for common 6502 systems (Amiga,
1313 C64, Apple II, etc) won't function as expected, since
1414 they expect I/O devices to be mapped into memory where
1616
1717 Building and running x6502
1818
19 To build x6502, just run ./make.sh. You will need clang
20 and Python installed. No libraries beyond POSIX libc are
21 used. This will produce the x6502 binary.
19 To build x6502, just run `make' in the project root. You
20 will need clang and Python installed. To use gcc, change
21 the $(CC) var in the Makefile. No libraries beyond POSIX
22 libc are used. This will produce the x6502 binary.
2223
2324 x6502 takes the compiled 6502 object file as an
2425 argument, and runs it until it encounters an EXT
3031 either tell your assembler that that's the base address
3132 for the text section of your binary or override the
3233 default load address using the `-b' flag of x6502.
34
35 If you want to compile a version of x6502 that dumps
36 machine state after every instruction, run `make debug'
37 instead of `make'. This will also disable compiler
38 optimizations.
3339
3440 Extensions to the 6502 instruction set
3541
5864 character is available on standard in, an interrupt is
5965 raised and FF01 is set to the character that was
6066 received. Note that one character is delivered per
61 interrupt; if the user types "abc", they will get three
62 interrupts one after the other.
67 interrupt; if the user types ``abc'', they will get
68 three interrupts one after the other.
6369
6470 A commented example of how to use the I/O capabilities
6571 of x6502 is provided in test-programs/echo.s.
72
73 Source code formatting
74
75 The code for opcode handling is a little strange; there
76 are lots of ``header'' files in the opcode_handlers
77 directory that are not really header files at all. These
78 files all contain code for handling opcode parsing and
79 interpretation; with over 150 opcodes, having all of the
80 code to handle these in one file would be excessive and
81 difficult to navigate, and dispatching out to functions
82 to handle each opcode carries unnecessary overhead in
83 what should be the tightest loop in the project. Thus,
84 each of these header files is #included in emu.c in the
85 middle of a select statement, and gets access to the
86 local scope within the main_loop function. It's weird
87 but it gets the job done, and is the least bad of all
88 considered options.
6689
6790 TODO:
6891 - switch to Makefiles like a real person
+0
-75
arithmetic.h less more
0 case ADC_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 add(m, m->mem[mem_abs(arg1, arg2, 0)]);
4 break;
5
6 case ADC_ABX:
7 arg1 = NEXT_BYTE(m);
8 arg2 = NEXT_BYTE(m);
9 add(m, m->mem[mem_abs(arg1, arg2, m->x)]);
10 break;
11
12 case ADC_ABY:
13 arg1 = NEXT_BYTE(m);
14 arg2 = NEXT_BYTE(m);
15 add(m, m->mem[mem_abs(arg1, arg2, m->y)]);
16 break;
17
18 case ADC_IMM:
19 add(m, NEXT_BYTE(m));
20 break;
21
22 case ADC_INX:
23 add(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)]);
24 break;
25
26 case ADC_INY:
27 add(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)]);
28 break;
29
30 case ADC_ZP:
31 add(m, m->mem[NEXT_BYTE(m)]);
32 break;
33
34 case ADC_ZPX:
35 add(m, m->mem[ZP(NEXT_BYTE(m) + m->x)]);
36 break;
37
38 case SBC_AB:
39 arg1 = NEXT_BYTE(m);
40 arg2 = NEXT_BYTE(m);
41 sub(m, m->mem[mem_abs(arg1, arg2, 0)]);
42 break;
43
44 case SBC_ABX:
45 arg1 = NEXT_BYTE(m);
46 arg2 = NEXT_BYTE(m);
47 sub(m, m->mem[mem_abs(arg1, arg2, m->x)]);
48 break;
49
50 case SBC_ABY:
51 arg1 = NEXT_BYTE(m);
52 arg2 = NEXT_BYTE(m);
53 sub(m, m->mem[mem_abs(arg1, arg2, m->y)]);
54 break;
55
56 case SBC_IMM:
57 sub(m, NEXT_BYTE(m));
58 break;
59
60 case SBC_INX:
61 sub(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)]);
62 break;
63
64 case SBC_INY:
65 sub(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)]);
66 break;
67
68 case SBC_ZP:
69 sub(m, m->mem[NEXT_BYTE(m)]);
70 break;
71
72 case SBC_ZPX:
73 sub(m, m->mem[ZP(NEXT_BYTE(m) + m->x)]);
74 break;
+0
-55
branch.h less more
0 case BCC_REL:
1 s1 = NEXT_BYTE(m);
2 if (!get_flag(m, FLAG_CARRY)) {
3 branch_offset = s1;
4 }
5 break;
6
7 case BCS_REL:
8 s1 = NEXT_BYTE(m);
9 if (get_flag(m, FLAG_CARRY)) {
10 branch_offset = s1;
11 }
12 break;
13
14 case BEQ_REL:
15 s1 = NEXT_BYTE(m);
16 if (get_flag(m, FLAG_ZERO)) {
17 branch_offset = s1;
18 }
19 break;
20
21 case BMI_REL:
22 s1 = NEXT_BYTE(m);
23 if (get_flag(m, FLAG_NEGATIVE)) {
24 branch_offset = s1;
25 }
26 break;
27
28 case BNE_REL:
29 s1 = NEXT_BYTE(m);
30 if (!get_flag(m, FLAG_ZERO)) {
31 branch_offset = s1;
32 }
33 break;
34
35 case BPL_REL:
36 s1 = NEXT_BYTE(m);
37 if (!get_flag(m, FLAG_NEGATIVE)) {
38 branch_offset = s1;
39 }
40 break;
41
42 case BVC_REL:
43 s1 = NEXT_BYTE(m);
44 if (!get_flag(m, FLAG_OVERFLOW)) {
45 branch_offset = s1;
46 }
47 break;
48
49 case BVS_REL:
50 s1 = NEXT_BYTE(m);
51 if (get_flag(m, FLAG_OVERFLOW)) {
52 branch_offset = s1;
53 }
54 break;
+0
-65
compare.h less more
0 case CMP_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->ac);
4 break;
5
6 case CMP_ABX:
7 arg1 = NEXT_BYTE(m);
8 arg2 = NEXT_BYTE(m);
9 cmp(m, m->mem[mem_abs(arg1, arg2, m->x)], m->ac);
10 break;
11
12 case CMP_ABY:
13 arg1 = NEXT_BYTE(m);
14 arg2 = NEXT_BYTE(m);
15 cmp(m, m->mem[mem_abs(arg1, arg2, m->y)], m->ac);
16 break;
17
18 case CMP_IMM:
19 cmp(m, NEXT_BYTE(m), m->ac);
20 break;
21
22 case CMP_INX:
23 cmp(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)], m->ac);
24 break;
25
26 case CMP_INY:
27 cmp(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)], m->ac);
28 break;
29
30 case CMP_ZP:
31 cmp(m, m->mem[NEXT_BYTE(m)], m->ac);
32 break;
33
34 case CMP_ZPX:
35 cmp(m, m->mem[ZP(NEXT_BYTE(m) + m->x)], m->ac);
36 break;
37
38 case CPX_AB:
39 arg1 = NEXT_BYTE(m);
40 arg2 = NEXT_BYTE(m);
41 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->x);
42 break;
43
44 case CPX_IMM:
45 cmp(m, NEXT_BYTE(m), m->x);
46 break;
47
48 case CPX_ZP:
49 cmp(m, m->mem[NEXT_BYTE(m)], m->x);
50 break;
51
52 case CPY_AB:
53 arg1 = NEXT_BYTE(m);
54 arg2 = NEXT_BYTE(m);
55 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->y);
56 break;
57
58 case CPY_IMM:
59 cmp(m, NEXT_BYTE(m), m->y);
60 break;
61
62 case CPY_ZP:
63 cmp(m, m->mem[NEXT_BYTE(m)], m->y);
64 break;
+12
-12
emu.c less more
5050 break;
5151 #endif
5252
53 #include "arithmetic.h"
54 #include "branch.h"
55 #include "compare.h"
56 #include "flags.h"
57 #include "incdec.h"
58 #include "jump.h"
59 #include "load.h"
60 #include "logical.h"
61 #include "shift.h"
62 #include "stack.h"
63 #include "store.h"
64 #include "transfer.h"
53 #include "opcode_handlers/arithmetic.h"
54 #include "opcode_handlers/branch.h"
55 #include "opcode_handlers/compare.h"
56 #include "opcode_handlers/flags.h"
57 #include "opcode_handlers/incdec.h"
58 #include "opcode_handlers/jump.h"
59 #include "opcode_handlers/load.h"
60 #include "opcode_handlers/logical.h"
61 #include "opcode_handlers/shift.h"
62 #include "opcode_handlers/stack.h"
63 #include "opcode_handlers/store.h"
64 #include "opcode_handlers/transfer.h"
6565
6666 default:
6767 printf("ERROR: got unknown opcode %02x\n", opcode);
+0
-27
flags.h less more
0 case CLC:
1 set_flag(m, FLAG_CARRY, 0);
2 break;
3
4 case CLD:
5 set_flag(m, FLAG_DECIMAL, 0);
6 break;
7
8 case CLI:
9 set_flag(m, FLAG_INTERRUPT, 0);
10 break;
11
12 case CLV:
13 set_flag(m, FLAG_OVERFLOW, 0);
14 break;
15
16 case SEC:
17 set_flag(m, FLAG_CARRY, 1);
18 break;
19
20 case SED:
21 set_flag(m, FLAG_DECIMAL, 1);
22 break;
23
24 case SEI:
25 set_flag(m, FLAG_INTERRUPT, 1);
26 break;
+0
-72
incdec.h less more
0 // CALL MARK_DIRTY IN HERE!
1 case INC_AB:
2 arg1 = NEXT_BYTE(m);
3 arg2 = NEXT_BYTE(m);
4 r1 = mem_abs(arg1, arg2, 0);
5 set_flags(m, ++m->mem[r1]);
6 mark_dirty(m, r1);
7 break;
8
9 case INC_ABX:
10 arg1 = NEXT_BYTE(m);
11 arg2 = NEXT_BYTE(m);
12 r1 = mem_abs(arg1, arg2, m->x);
13 set_flags(m, ++m->mem[r1]);
14 mark_dirty(m, r1);
15 break;
16
17 case INC_ZP:
18 r1 = NEXT_BYTE(m);
19 set_flags(m, ++m->mem[r1]);
20 mark_dirty(m, r1);
21 break;
22
23 case INC_ZPX:
24 r1 = ZP(NEXT_BYTE(m) + m->x);
25 set_flags(m, ++m->mem[r1]);
26 mark_dirty(m, r1);
27 break;
28
29 case INX:
30 set_flags(m, ++m->x);
31 break;
32
33 case INY:
34 set_flags(m, ++m->y);
35 break;
36
37 case DEC_AB:
38 arg1 = NEXT_BYTE(m);
39 arg2 = NEXT_BYTE(m);
40 r1 = mem_abs(arg1, arg2, 0);
41 set_flags(m, --m->mem[r1]);
42 mark_dirty(m, r1);
43 break;
44
45 case DEC_ABX:
46 arg1 = NEXT_BYTE(m);
47 arg2 = NEXT_BYTE(m);
48 r1 = mem_abs(arg1, arg2, m->x);
49 set_flags(m, --m->mem[r1]);
50 mark_dirty(m, r1);
51 break;
52
53 case DEC_ZP:
54 r1 = NEXT_BYTE(m);
55 set_flags(m, --m->mem[r1]);
56 mark_dirty(m, r1);
57 break;
58
59 case DEC_ZPX:
60 r1 = ZP(NEXT_BYTE(m) + m->x);
61 set_flags(m, --m->mem[r1]);
62 mark_dirty(m, r1);
63 break;
64
65 case DEX:
66 set_flags(m, --m->x);
67 break;
68
69 case DEY:
70 set_flags(m, --m->y);
71 break;
+0
-37
jump.h less more
0 case JMP_AB:
1 arg1 = NEXT_BYTE(m);
2 m->pc = mem_abs(arg1, NEXT_BYTE(m), 0);
3 break;
4
5 case JMP_IN:
6 arg1 = NEXT_BYTE(m);
7 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
8 m->pc = mem_abs(m->mem[r1], m->mem[r1+1], 0);
9 break;
10
11 case JSR_AB:
12 arg1 = NEXT_BYTE(m);
13 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
14 // we push the address of the byte immediately before where we want to
15 // return to because reasons:
16 r2 = m->pc + pc_offset - 1;
17 STACK_PUSH(m) = (r2 & 0xFF00) >> 8;
18 STACK_PUSH(m) = r2 & 0xFF;
19 m->pc = r1;
20 break;
21
22 case RTS:
23 arg1 = STACK_POP(m);
24 m->pc = mem_abs(arg1, STACK_POP(m), 0) + 1;
25 break;
26
27 case BRK:
28 set_flag(m, FLAG_BREAK, 1);
29 m->interrupt_waiting = 1;
30 break;
31
32 case RTI:
33 m->sr = STACK_POP(m);
34 arg1 = STACK_POP(m);
35 m->pc = mem_abs(arg1, STACK_POP(m), 0);
36 break;
+0
-103
load.h less more
0 case LDA_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 m->ac = m->mem[mem_abs(arg1, arg2, 0)];
4 set_flags(m, m->ac);
5 break;
6
7 case LDA_ABX:
8 arg1 = NEXT_BYTE(m);
9 arg2 = NEXT_BYTE(m);
10 m->ac = m->mem[mem_abs(arg1, arg2, m->x)];
11 set_flags(m, m->ac);
12 break;
13
14 case LDA_ABY:
15 arg1 = NEXT_BYTE(m);
16 arg2 = NEXT_BYTE(m);
17 m->ac = m->mem[mem_abs(arg1, arg2, m->y)];
18 set_flags(m, m->ac);
19 break;
20
21 case LDA_IMM:
22 m->ac = NEXT_BYTE(m);
23 set_flags(m, m->ac);
24 break;
25
26 case LDA_INX:
27 m->ac = m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
28 set_flags(m, m->ac);
29 break;
30
31 case LDA_INY:
32 m->ac = m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
33 set_flags(m, m->ac);
34 break;
35
36 case LDA_ZP:
37 m->ac = m->mem[NEXT_BYTE(m)];
38 set_flags(m, m->ac);
39 break;
40
41 case LDA_ZPX:
42 m->ac = m->mem[NEXT_BYTE(m) + m->x];
43 set_flags(m, m->ac);
44 break;
45
46 case LDX_AB:
47 arg1 = NEXT_BYTE(m);
48 arg2 = NEXT_BYTE(m);
49 m->x = m->mem[mem_abs(arg1, arg2, 0)];
50 set_flags(m, m->x);
51 break;
52
53 case LDX_ABY:
54 arg1 = NEXT_BYTE(m);
55 arg2 = NEXT_BYTE(m);
56 m->x = m->mem[mem_abs(arg1, arg2, m->y)];
57 set_flags(m, m->x);
58 break;
59
60 case LDX_IMM:
61 m->x = NEXT_BYTE(m);
62 set_flags(m, m->x);
63 break;
64
65 case LDX_ZP:
66 m->x = m->mem[NEXT_BYTE(m)];
67 set_flags(m, m->x);
68 break;
69
70 case LDX_ZPY:
71 m->x = m->mem[NEXT_BYTE(m) + m->y];
72 set_flags(m, m->x);
73 break;
74
75 case LDY_AB:
76 arg1 = NEXT_BYTE(m);
77 arg2 = NEXT_BYTE(m);
78 m->y = m->mem[mem_abs(arg1, arg2, 0)];
79 set_flags(m, m->y);
80 break;
81
82 case LDY_ABX:
83 arg1 = NEXT_BYTE(m);
84 arg2 = NEXT_BYTE(m);
85 m->y = m->mem[mem_abs(arg1, arg2, m->x)];
86 set_flags(m, m->y);
87 break;
88
89 case LDY_IMM:
90 m->y = NEXT_BYTE(m);
91 set_flags(m, m->y);
92 break;
93
94 case LDY_ZP:
95 m->y = m->mem[NEXT_BYTE(m)];
96 set_flags(m, m->y);
97 break;
98
99 case LDY_ZPX:
100 m->y = m->mem[NEXT_BYTE(m) + m->x];
101 set_flags(m, m->y);
102 break;
+0
-153
logical.h less more
0 case AND_IMM:
1 m->ac &= NEXT_BYTE(m);
2 set_flags(m, m->ac);
3 break;
4
5 case AND_ZP:
6 m->ac &= m->mem[NEXT_BYTE(m)];
7 set_flags(m, m->ac);
8 break;
9
10 case AND_ZPX:
11 m->ac &= m->mem[ZP(NEXT_BYTE(m) + m->x)];
12 set_flags(m, m->ac);
13 break;
14
15 case AND_AB:
16 arg1 = NEXT_BYTE(m);
17 arg2 = NEXT_BYTE(m);
18 m->ac &= m->mem[mem_abs(arg1, arg2, 0)];
19 set_flags(m, m->ac);
20 break;
21
22 case AND_ABX:
23 arg1 = NEXT_BYTE(m);
24 arg2 = NEXT_BYTE(m);
25 m->ac &= m->mem[mem_abs(arg1, arg2, m->x)];
26 set_flags(m, m->ac);
27 break;
28
29 case AND_ABY:
30 arg1 = NEXT_BYTE(m);
31 arg2 = NEXT_BYTE(m);
32 m->ac &= m->mem[mem_abs(arg1, arg2, m->y)];
33 set_flags(m, m->ac);
34 break;
35
36 case AND_INX:
37 m->ac &= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
38 set_flags(m, m->ac);
39 break;
40
41 case AND_INY:
42 m->ac &= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
43 set_flags(m, m->ac);
44 break;
45
46 case EOR_IMM:
47 m->ac ^= NEXT_BYTE(m);
48 set_flags(m, m->ac);
49 break;
50
51 case EOR_ZP:
52 m->ac ^= m->mem[NEXT_BYTE(m)];
53 set_flags(m, m->ac);
54 break;
55
56 case EOR_ZPX:
57 m->ac ^= m->mem[ZP(NEXT_BYTE(m) + m->x)];
58 set_flags(m, m->ac);
59 break;
60
61 case EOR_AB:
62 arg1 = NEXT_BYTE(m);
63 arg2 = NEXT_BYTE(m);
64 m->ac ^= m->mem[mem_abs(arg1, arg2, 0)];
65 set_flags(m, m->ac);
66 break;
67
68 case EOR_ABX:
69 arg1 = NEXT_BYTE(m);
70 arg2 = NEXT_BYTE(m);
71 m->ac ^= m->mem[mem_abs(arg1, arg2, m->x)];
72 set_flags(m, m->ac);
73 break;
74
75 case EOR_ABY:
76 arg1 = NEXT_BYTE(m);
77 arg2 = NEXT_BYTE(m);
78 m->ac ^= m->mem[mem_abs(arg1, arg2, m->y)];
79 set_flags(m, m->ac);
80 break;
81
82 case EOR_INX:
83 m->ac ^= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
84 set_flags(m, m->ac);
85 break;
86
87 case EOR_INY:
88 m->ac ^= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
89 set_flags(m, m->ac);
90 break;
91
92 case ORA_IMM:
93 m->ac |= NEXT_BYTE(m);
94 set_flags(m, m->ac);
95 break;
96
97 case ORA_ZP:
98 m->ac |= m->mem[NEXT_BYTE(m)];
99 set_flags(m, m->ac);
100 break;
101
102 case ORA_ZPX:
103 m->ac |= m->mem[ZP(NEXT_BYTE(m) + m->x)];
104 set_flags(m, m->ac);
105 break;
106
107 case ORA_AB:
108 arg1 = NEXT_BYTE(m);
109 arg2 = NEXT_BYTE(m);
110 m->ac |= m->mem[mem_abs(arg1, arg2, 0)];
111 set_flags(m, m->ac);
112 break;
113
114 case ORA_ABX:
115 arg1 = NEXT_BYTE(m);
116 arg2 = NEXT_BYTE(m);
117 m->ac |= m->mem[mem_abs(arg1, arg2, m->x)];
118 set_flags(m, m->ac);
119 break;
120
121 case ORA_ABY:
122 arg1 = NEXT_BYTE(m);
123 arg2 = NEXT_BYTE(m);
124 m->ac |= m->mem[mem_abs(arg1, arg2, m->y)];
125 set_flags(m, m->ac);
126 break;
127
128 case ORA_INX:
129 m->ac |= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
130 set_flags(m, m->ac);
131 break;
132
133 case ORA_INY:
134 m->ac |= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
135 set_flags(m, m->ac);
136 break;
137
138 case BIT_AB:
139 arg1 = NEXT_BYTE(m);
140 arg2 = NEXT_BYTE(m);
141 t1 = m->mem[mem_abs(arg1, arg2, 0)];
142 set_flag(m, FLAG_ZERO, !(t1 & m->ac));
143 set_flag(m, FLAG_OVERFLOW, t1 & 0x40);
144 set_flag(m, FLAG_NEGATIVE, t1 & 0x80);
145 break;
146
147 case BIT_ZP:
148 t1 = m->mem[NEXT_BYTE(m)];
149 set_flag(m, FLAG_ZERO, !(t1 & m->ac));
150 set_flag(m, FLAG_OVERFLOW, t1 & 0x40);
151 set_flag(m, FLAG_NEGATIVE, t1 & 0x80);
152 break;
+0
-4
make.sh less more
0 #!/bin/bash
1
2 python generate_debug_names.py > debug-names.h
3 clang *.c -o x6502 -O3 -lpthread -Wall
0 case ADC_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 add(m, m->mem[mem_abs(arg1, arg2, 0)]);
4 break;
5
6 case ADC_ABX:
7 arg1 = NEXT_BYTE(m);
8 arg2 = NEXT_BYTE(m);
9 add(m, m->mem[mem_abs(arg1, arg2, m->x)]);
10 break;
11
12 case ADC_ABY:
13 arg1 = NEXT_BYTE(m);
14 arg2 = NEXT_BYTE(m);
15 add(m, m->mem[mem_abs(arg1, arg2, m->y)]);
16 break;
17
18 case ADC_IMM:
19 add(m, NEXT_BYTE(m));
20 break;
21
22 case ADC_INX:
23 add(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)]);
24 break;
25
26 case ADC_INY:
27 add(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)]);
28 break;
29
30 case ADC_ZP:
31 add(m, m->mem[NEXT_BYTE(m)]);
32 break;
33
34 case ADC_ZPX:
35 add(m, m->mem[ZP(NEXT_BYTE(m) + m->x)]);
36 break;
37
38 case SBC_AB:
39 arg1 = NEXT_BYTE(m);
40 arg2 = NEXT_BYTE(m);
41 sub(m, m->mem[mem_abs(arg1, arg2, 0)]);
42 break;
43
44 case SBC_ABX:
45 arg1 = NEXT_BYTE(m);
46 arg2 = NEXT_BYTE(m);
47 sub(m, m->mem[mem_abs(arg1, arg2, m->x)]);
48 break;
49
50 case SBC_ABY:
51 arg1 = NEXT_BYTE(m);
52 arg2 = NEXT_BYTE(m);
53 sub(m, m->mem[mem_abs(arg1, arg2, m->y)]);
54 break;
55
56 case SBC_IMM:
57 sub(m, NEXT_BYTE(m));
58 break;
59
60 case SBC_INX:
61 sub(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)]);
62 break;
63
64 case SBC_INY:
65 sub(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)]);
66 break;
67
68 case SBC_ZP:
69 sub(m, m->mem[NEXT_BYTE(m)]);
70 break;
71
72 case SBC_ZPX:
73 sub(m, m->mem[ZP(NEXT_BYTE(m) + m->x)]);
74 break;
0 case BCC_REL:
1 s1 = NEXT_BYTE(m);
2 if (!get_flag(m, FLAG_CARRY)) {
3 branch_offset = s1;
4 }
5 break;
6
7 case BCS_REL:
8 s1 = NEXT_BYTE(m);
9 if (get_flag(m, FLAG_CARRY)) {
10 branch_offset = s1;
11 }
12 break;
13
14 case BEQ_REL:
15 s1 = NEXT_BYTE(m);
16 if (get_flag(m, FLAG_ZERO)) {
17 branch_offset = s1;
18 }
19 break;
20
21 case BMI_REL:
22 s1 = NEXT_BYTE(m);
23 if (get_flag(m, FLAG_NEGATIVE)) {
24 branch_offset = s1;
25 }
26 break;
27
28 case BNE_REL:
29 s1 = NEXT_BYTE(m);
30 if (!get_flag(m, FLAG_ZERO)) {
31 branch_offset = s1;
32 }
33 break;
34
35 case BPL_REL:
36 s1 = NEXT_BYTE(m);
37 if (!get_flag(m, FLAG_NEGATIVE)) {
38 branch_offset = s1;
39 }
40 break;
41
42 case BVC_REL:
43 s1 = NEXT_BYTE(m);
44 if (!get_flag(m, FLAG_OVERFLOW)) {
45 branch_offset = s1;
46 }
47 break;
48
49 case BVS_REL:
50 s1 = NEXT_BYTE(m);
51 if (get_flag(m, FLAG_OVERFLOW)) {
52 branch_offset = s1;
53 }
54 break;
0 case CMP_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->ac);
4 break;
5
6 case CMP_ABX:
7 arg1 = NEXT_BYTE(m);
8 arg2 = NEXT_BYTE(m);
9 cmp(m, m->mem[mem_abs(arg1, arg2, m->x)], m->ac);
10 break;
11
12 case CMP_ABY:
13 arg1 = NEXT_BYTE(m);
14 arg2 = NEXT_BYTE(m);
15 cmp(m, m->mem[mem_abs(arg1, arg2, m->y)], m->ac);
16 break;
17
18 case CMP_IMM:
19 cmp(m, NEXT_BYTE(m), m->ac);
20 break;
21
22 case CMP_INX:
23 cmp(m, m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)], m->ac);
24 break;
25
26 case CMP_INY:
27 cmp(m, m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)], m->ac);
28 break;
29
30 case CMP_ZP:
31 cmp(m, m->mem[NEXT_BYTE(m)], m->ac);
32 break;
33
34 case CMP_ZPX:
35 cmp(m, m->mem[ZP(NEXT_BYTE(m) + m->x)], m->ac);
36 break;
37
38 case CPX_AB:
39 arg1 = NEXT_BYTE(m);
40 arg2 = NEXT_BYTE(m);
41 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->x);
42 break;
43
44 case CPX_IMM:
45 cmp(m, NEXT_BYTE(m), m->x);
46 break;
47
48 case CPX_ZP:
49 cmp(m, m->mem[NEXT_BYTE(m)], m->x);
50 break;
51
52 case CPY_AB:
53 arg1 = NEXT_BYTE(m);
54 arg2 = NEXT_BYTE(m);
55 cmp(m, m->mem[mem_abs(arg1, arg2, 0)], m->y);
56 break;
57
58 case CPY_IMM:
59 cmp(m, NEXT_BYTE(m), m->y);
60 break;
61
62 case CPY_ZP:
63 cmp(m, m->mem[NEXT_BYTE(m)], m->y);
64 break;
0 case CLC:
1 set_flag(m, FLAG_CARRY, 0);
2 break;
3
4 case CLD:
5 set_flag(m, FLAG_DECIMAL, 0);
6 break;
7
8 case CLI:
9 set_flag(m, FLAG_INTERRUPT, 0);
10 break;
11
12 case CLV:
13 set_flag(m, FLAG_OVERFLOW, 0);
14 break;
15
16 case SEC:
17 set_flag(m, FLAG_CARRY, 1);
18 break;
19
20 case SED:
21 set_flag(m, FLAG_DECIMAL, 1);
22 break;
23
24 case SEI:
25 set_flag(m, FLAG_INTERRUPT, 1);
26 break;
0 // CALL MARK_DIRTY IN HERE!
1 case INC_AB:
2 arg1 = NEXT_BYTE(m);
3 arg2 = NEXT_BYTE(m);
4 r1 = mem_abs(arg1, arg2, 0);
5 set_flags(m, ++m->mem[r1]);
6 mark_dirty(m, r1);
7 break;
8
9 case INC_ABX:
10 arg1 = NEXT_BYTE(m);
11 arg2 = NEXT_BYTE(m);
12 r1 = mem_abs(arg1, arg2, m->x);
13 set_flags(m, ++m->mem[r1]);
14 mark_dirty(m, r1);
15 break;
16
17 case INC_ZP:
18 r1 = NEXT_BYTE(m);
19 set_flags(m, ++m->mem[r1]);
20 mark_dirty(m, r1);
21 break;
22
23 case INC_ZPX:
24 r1 = ZP(NEXT_BYTE(m) + m->x);
25 set_flags(m, ++m->mem[r1]);
26 mark_dirty(m, r1);
27 break;
28
29 case INX:
30 set_flags(m, ++m->x);
31 break;
32
33 case INY:
34 set_flags(m, ++m->y);
35 break;
36
37 case DEC_AB:
38 arg1 = NEXT_BYTE(m);
39 arg2 = NEXT_BYTE(m);
40 r1 = mem_abs(arg1, arg2, 0);
41 set_flags(m, --m->mem[r1]);
42 mark_dirty(m, r1);
43 break;
44
45 case DEC_ABX:
46 arg1 = NEXT_BYTE(m);
47 arg2 = NEXT_BYTE(m);
48 r1 = mem_abs(arg1, arg2, m->x);
49 set_flags(m, --m->mem[r1]);
50 mark_dirty(m, r1);
51 break;
52
53 case DEC_ZP:
54 r1 = NEXT_BYTE(m);
55 set_flags(m, --m->mem[r1]);
56 mark_dirty(m, r1);
57 break;
58
59 case DEC_ZPX:
60 r1 = ZP(NEXT_BYTE(m) + m->x);
61 set_flags(m, --m->mem[r1]);
62 mark_dirty(m, r1);
63 break;
64
65 case DEX:
66 set_flags(m, --m->x);
67 break;
68
69 case DEY:
70 set_flags(m, --m->y);
71 break;
0 case JMP_AB:
1 arg1 = NEXT_BYTE(m);
2 m->pc = mem_abs(arg1, NEXT_BYTE(m), 0);
3 break;
4
5 case JMP_IN:
6 arg1 = NEXT_BYTE(m);
7 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
8 m->pc = mem_abs(m->mem[r1], m->mem[r1+1], 0);
9 break;
10
11 case JSR_AB:
12 arg1 = NEXT_BYTE(m);
13 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
14 // we push the address of the byte immediately before where we want to
15 // return to because reasons:
16 r2 = m->pc + pc_offset - 1;
17 STACK_PUSH(m) = (r2 & 0xFF00) >> 8;
18 STACK_PUSH(m) = r2 & 0xFF;
19 m->pc = r1;
20 break;
21
22 case RTS:
23 arg1 = STACK_POP(m);
24 m->pc = mem_abs(arg1, STACK_POP(m), 0) + 1;
25 break;
26
27 case BRK:
28 set_flag(m, FLAG_BREAK, 1);
29 m->interrupt_waiting = 1;
30 break;
31
32 case RTI:
33 m->sr = STACK_POP(m);
34 arg1 = STACK_POP(m);
35 m->pc = mem_abs(arg1, STACK_POP(m), 0);
36 break;
0 case LDA_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 m->ac = m->mem[mem_abs(arg1, arg2, 0)];
4 set_flags(m, m->ac);
5 break;
6
7 case LDA_ABX:
8 arg1 = NEXT_BYTE(m);
9 arg2 = NEXT_BYTE(m);
10 m->ac = m->mem[mem_abs(arg1, arg2, m->x)];
11 set_flags(m, m->ac);
12 break;
13
14 case LDA_ABY:
15 arg1 = NEXT_BYTE(m);
16 arg2 = NEXT_BYTE(m);
17 m->ac = m->mem[mem_abs(arg1, arg2, m->y)];
18 set_flags(m, m->ac);
19 break;
20
21 case LDA_IMM:
22 m->ac = NEXT_BYTE(m);
23 set_flags(m, m->ac);
24 break;
25
26 case LDA_INX:
27 m->ac = m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
28 set_flags(m, m->ac);
29 break;
30
31 case LDA_INY:
32 m->ac = m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
33 set_flags(m, m->ac);
34 break;
35
36 case LDA_ZP:
37 m->ac = m->mem[NEXT_BYTE(m)];
38 set_flags(m, m->ac);
39 break;
40
41 case LDA_ZPX:
42 m->ac = m->mem[NEXT_BYTE(m) + m->x];
43 set_flags(m, m->ac);
44 break;
45
46 case LDX_AB:
47 arg1 = NEXT_BYTE(m);
48 arg2 = NEXT_BYTE(m);
49 m->x = m->mem[mem_abs(arg1, arg2, 0)];
50 set_flags(m, m->x);
51 break;
52
53 case LDX_ABY:
54 arg1 = NEXT_BYTE(m);
55 arg2 = NEXT_BYTE(m);
56 m->x = m->mem[mem_abs(arg1, arg2, m->y)];
57 set_flags(m, m->x);
58 break;
59
60 case LDX_IMM:
61 m->x = NEXT_BYTE(m);
62 set_flags(m, m->x);
63 break;
64
65 case LDX_ZP:
66 m->x = m->mem[NEXT_BYTE(m)];
67 set_flags(m, m->x);
68 break;
69
70 case LDX_ZPY:
71 m->x = m->mem[NEXT_BYTE(m) + m->y];
72 set_flags(m, m->x);
73 break;
74
75 case LDY_AB:
76 arg1 = NEXT_BYTE(m);
77 arg2 = NEXT_BYTE(m);
78 m->y = m->mem[mem_abs(arg1, arg2, 0)];
79 set_flags(m, m->y);
80 break;
81
82 case LDY_ABX:
83 arg1 = NEXT_BYTE(m);
84 arg2 = NEXT_BYTE(m);
85 m->y = m->mem[mem_abs(arg1, arg2, m->x)];
86 set_flags(m, m->y);
87 break;
88
89 case LDY_IMM:
90 m->y = NEXT_BYTE(m);
91 set_flags(m, m->y);
92 break;
93
94 case LDY_ZP:
95 m->y = m->mem[NEXT_BYTE(m)];
96 set_flags(m, m->y);
97 break;
98
99 case LDY_ZPX:
100 m->y = m->mem[NEXT_BYTE(m) + m->x];
101 set_flags(m, m->y);
102 break;
0 case AND_IMM:
1 m->ac &= NEXT_BYTE(m);
2 set_flags(m, m->ac);
3 break;
4
5 case AND_ZP:
6 m->ac &= m->mem[NEXT_BYTE(m)];
7 set_flags(m, m->ac);
8 break;
9
10 case AND_ZPX:
11 m->ac &= m->mem[ZP(NEXT_BYTE(m) + m->x)];
12 set_flags(m, m->ac);
13 break;
14
15 case AND_AB:
16 arg1 = NEXT_BYTE(m);
17 arg2 = NEXT_BYTE(m);
18 m->ac &= m->mem[mem_abs(arg1, arg2, 0)];
19 set_flags(m, m->ac);
20 break;
21
22 case AND_ABX:
23 arg1 = NEXT_BYTE(m);
24 arg2 = NEXT_BYTE(m);
25 m->ac &= m->mem[mem_abs(arg1, arg2, m->x)];
26 set_flags(m, m->ac);
27 break;
28
29 case AND_ABY:
30 arg1 = NEXT_BYTE(m);
31 arg2 = NEXT_BYTE(m);
32 m->ac &= m->mem[mem_abs(arg1, arg2, m->y)];
33 set_flags(m, m->ac);
34 break;
35
36 case AND_INX:
37 m->ac &= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
38 set_flags(m, m->ac);
39 break;
40
41 case AND_INY:
42 m->ac &= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
43 set_flags(m, m->ac);
44 break;
45
46 case EOR_IMM:
47 m->ac ^= NEXT_BYTE(m);
48 set_flags(m, m->ac);
49 break;
50
51 case EOR_ZP:
52 m->ac ^= m->mem[NEXT_BYTE(m)];
53 set_flags(m, m->ac);
54 break;
55
56 case EOR_ZPX:
57 m->ac ^= m->mem[ZP(NEXT_BYTE(m) + m->x)];
58 set_flags(m, m->ac);
59 break;
60
61 case EOR_AB:
62 arg1 = NEXT_BYTE(m);
63 arg2 = NEXT_BYTE(m);
64 m->ac ^= m->mem[mem_abs(arg1, arg2, 0)];
65 set_flags(m, m->ac);
66 break;
67
68 case EOR_ABX:
69 arg1 = NEXT_BYTE(m);
70 arg2 = NEXT_BYTE(m);
71 m->ac ^= m->mem[mem_abs(arg1, arg2, m->x)];
72 set_flags(m, m->ac);
73 break;
74
75 case EOR_ABY:
76 arg1 = NEXT_BYTE(m);
77 arg2 = NEXT_BYTE(m);
78 m->ac ^= m->mem[mem_abs(arg1, arg2, m->y)];
79 set_flags(m, m->ac);
80 break;
81
82 case EOR_INX:
83 m->ac ^= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
84 set_flags(m, m->ac);
85 break;
86
87 case EOR_INY:
88 m->ac ^= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
89 set_flags(m, m->ac);
90 break;
91
92 case ORA_IMM:
93 m->ac |= NEXT_BYTE(m);
94 set_flags(m, m->ac);
95 break;
96
97 case ORA_ZP:
98 m->ac |= m->mem[NEXT_BYTE(m)];
99 set_flags(m, m->ac);
100 break;
101
102 case ORA_ZPX:
103 m->ac |= m->mem[ZP(NEXT_BYTE(m) + m->x)];
104 set_flags(m, m->ac);
105 break;
106
107 case ORA_AB:
108 arg1 = NEXT_BYTE(m);
109 arg2 = NEXT_BYTE(m);
110 m->ac |= m->mem[mem_abs(arg1, arg2, 0)];
111 set_flags(m, m->ac);
112 break;
113
114 case ORA_ABX:
115 arg1 = NEXT_BYTE(m);
116 arg2 = NEXT_BYTE(m);
117 m->ac |= m->mem[mem_abs(arg1, arg2, m->x)];
118 set_flags(m, m->ac);
119 break;
120
121 case ORA_ABY:
122 arg1 = NEXT_BYTE(m);
123 arg2 = NEXT_BYTE(m);
124 m->ac |= m->mem[mem_abs(arg1, arg2, m->y)];
125 set_flags(m, m->ac);
126 break;
127
128 case ORA_INX:
129 m->ac |= m->mem[mem_indexed_indirect(m, NEXT_BYTE(m), m->x)];
130 set_flags(m, m->ac);
131 break;
132
133 case ORA_INY:
134 m->ac |= m->mem[mem_indirect_index(m, NEXT_BYTE(m), m->y)];
135 set_flags(m, m->ac);
136 break;
137
138 case BIT_AB:
139 arg1 = NEXT_BYTE(m);
140 arg2 = NEXT_BYTE(m);
141 t1 = m->mem[mem_abs(arg1, arg2, 0)];
142 set_flag(m, FLAG_ZERO, !(t1 & m->ac));
143 set_flag(m, FLAG_OVERFLOW, t1 & 0x40);
144 set_flag(m, FLAG_NEGATIVE, t1 & 0x80);
145 break;
146
147 case BIT_ZP:
148 t1 = m->mem[NEXT_BYTE(m)];
149 set_flag(m, FLAG_ZERO, !(t1 & m->ac));
150 set_flag(m, FLAG_OVERFLOW, t1 & 0x40);
151 set_flag(m, FLAG_NEGATIVE, t1 & 0x80);
152 break;
0 case ASL_AB:
1 arg1 = NEXT_BYTE(m);
2 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
3 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x80);
4 m->mem[r1] = (m->mem[r1] << 1) & 0xFE;
5 set_flags(m, m->mem[r1]);
6 mark_dirty(m, r1);
7 break;
8
9 case ASL_ABX:
10 arg1 = NEXT_BYTE(m);
11 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
12 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x80);
13 m->mem[r1] = (m->mem[r1] << 1) & 0xFE;
14 set_flags(m, m->mem[r1]);
15 mark_dirty(m, r1);
16 break;
17
18 case ASL_ACC:
19 set_flag(m, FLAG_CARRY, m->ac & 0x80);
20 m->ac = (m->ac << 1) & 0xFE;
21 set_flags(m, m->ac);
22 break;
23
24 case ASL_ZP:
25 arg1 = NEXT_BYTE(m);
26 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x80);
27 m->mem[arg1] = (m->mem[arg1] << 1) & 0xFE;
28 set_flags(m, m->mem[arg1]);
29 mark_dirty(m, arg1);
30 break;
31
32 case ASL_ZPX:
33 arg1 = ZP(NEXT_BYTE(m) + m->x);
34 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x80);
35 m->mem[arg1] = (m->mem[arg1] << 1) & 0xFE;
36 set_flags(m, m->mem[arg1]);
37 mark_dirty(m, arg1);
38 break;
39
40 case LSR_AB:
41 arg1 = NEXT_BYTE(m);
42 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
43 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x01);
44 m->mem[r1] = (m->mem[r1] >> 1) & 0x7F;
45 set_flags(m, m->mem[r1]);
46 mark_dirty(m, r1);
47 break;
48
49 case LSR_ABX:
50 arg1 = NEXT_BYTE(m);
51 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
52 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x01);
53 m->mem[r1] = (m->mem[r1] >> 1) & 0x7F;
54 set_flags(m, m->mem[r1]);
55 mark_dirty(m, r1);
56 break;
57
58 case LSR_ACC:
59 set_flag(m, FLAG_CARRY, m->ac & 0x01);
60 m->ac = (m->ac >> 1) & 0x7F;
61 set_flags(m, m->ac);
62 break;
63
64 case LSR_ZP:
65 arg1 = NEXT_BYTE(m);
66 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x01);
67 m->mem[arg1] = (m->mem[arg1] >> 1) & 0x7F;
68 set_flags(m, m->mem[arg1]);
69 mark_dirty(m, arg1);
70 break;
71
72 case LSR_ZPX:
73 arg1 = ZP(NEXT_BYTE(m) + m->x);
74 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x01);
75 m->mem[arg1] = (m->mem[arg1] >> 1) & 0x7F;
76 set_flags(m, m->mem[arg1]);
77 mark_dirty(m, arg1);
78 break;
79
80 case ROL_AB:
81 arg1 = NEXT_BYTE(m);
82 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
83 t1 = m->mem[r1] & 0x80;
84 m->mem[r1] = ((m->mem[r1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
85 set_flag(m, FLAG_CARRY, t1);
86 set_flags(m, m->mem[r1]);
87 mark_dirty(m, r1);
88 break;
89
90 case ROL_ABX:
91 arg1 = NEXT_BYTE(m);
92 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
93 t1 = m->mem[r1] & 0x80;
94 m->mem[r1] = ((m->mem[r1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
95 set_flag(m, FLAG_CARRY, t1);
96 set_flags(m, m->mem[r1]);
97 mark_dirty(m, r1);
98 break;
99
100 case ROL_ACC:
101 t1 = m->ac & 0x80;
102 m->ac = ((m->ac << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
103 set_flag(m, FLAG_CARRY, t1);
104 set_flags(m, m->ac);
105 break;
106
107 case ROL_ZP:
108 arg1 = NEXT_BYTE(m);
109 t1 = m->mem[arg1] & 0x80;
110 m->mem[arg1] = ((m->mem[arg1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
111 set_flag(m, FLAG_CARRY, t1);
112 set_flags(m, m->mem[arg1]);
113 mark_dirty(m, arg1);
114 break;
115
116 case ROL_ZPX:
117 arg1 = ZP(NEXT_BYTE(m) + m->x);
118 t1 = m->mem[arg1] & 0x80;
119 m->mem[arg1] = ((m->mem[arg1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
120 set_flag(m, FLAG_CARRY, t1);
121 set_flags(m, m->mem[arg1]);
122 mark_dirty(m, arg1);
123 break;
124
125 case ROR_AB:
126 arg1 = NEXT_BYTE(m);
127 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
128 t1 = m->mem[r1] & 0x01;
129 m->mem[r1] = ((m->mem[r1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
130 set_flag(m, FLAG_CARRY, t1);
131 set_flags(m, m->mem[r1]);
132 mark_dirty(m, r1);
133 break;
134
135 case ROR_ABX:
136 arg1 = NEXT_BYTE(m);
137 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
138 t1 = m->mem[r1] & 0x01;
139 m->mem[r1] = ((m->mem[r1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
140 set_flag(m, FLAG_CARRY, t1);
141 set_flags(m, m->mem[r1]);
142 mark_dirty(m, r1);
143 break;
144
145 case ROR_ACC:
146 t1 = m->ac & 0x01;
147 m->ac = ((m->ac >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
148 set_flag(m, FLAG_CARRY, t1);
149 set_flags(m, m->ac);
150 break;
151
152 case ROR_ZP:
153 arg1 = NEXT_BYTE(m);
154 t1 = m->mem[arg1] & 0x01;
155 m->mem[arg1] = ((m->mem[arg1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
156 set_flag(m, FLAG_CARRY, t1);
157 set_flags(m, m->mem[arg1]);
158 mark_dirty(m, arg1);
159 break;
160
161 case ROR_ZPX:
162 arg1 = ZP(NEXT_BYTE(m) + m->x);
163 t1 = m->mem[arg1] & 0x01;
164 m->mem[arg1] = ((m->mem[arg1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
165 set_flag(m, FLAG_CARRY, t1);
166 set_flags(m, m->mem[arg1]);
167 mark_dirty(m, arg1);
168 break;
0 case PHA:
1 STACK_PUSH(m) = m->ac;
2 break;
3
4 case PHP:
5 STACK_PUSH(m) = m->sr;
6 break;
7
8 case PLA:
9 m->ac = STACK_POP(m);
10 break;
11
12 case PLP:
13 m->sr = STACK_POP(m);
14 break;
0 case STA_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 r1 = mem_abs(arg1, arg2, 0);
4 m->mem[r1] = m->ac;
5 mark_dirty(m, r1);
6 break;
7
8 case STA_ABX:
9 arg1 = NEXT_BYTE(m);
10 arg2 = NEXT_BYTE(m);
11 r1 = mem_abs(arg1, arg2, m->x);
12 m->mem[r1] = m->ac;
13 mark_dirty(m, r1);
14 break;
15
16 case STA_ABY:
17 arg1 = NEXT_BYTE(m);
18 arg2 = NEXT_BYTE(m);
19 r1 = mem_abs(arg1, arg2, m->y);
20 m->mem[r1] = m->ac;
21 mark_dirty(m, r1);
22 break;
23
24 case STA_INX:
25 r1 = mem_indexed_indirect(m, NEXT_BYTE(m), m->x);
26 m->mem[r1] = m->ac;
27 mark_dirty(m, r1);
28 break;
29
30 case STA_INY:
31 r1 = mem_indirect_index(m, NEXT_BYTE(m), m->y);
32 m->mem[r1] = m->ac;
33 mark_dirty(m, r1);
34 break;
35
36 case STA_ZP:
37 r1 = ZP(NEXT_BYTE(m));
38 m->mem[r1] = m->ac;
39 mark_dirty(m, r1);
40 break;
41
42 case STA_ZPX:
43 r1 = ZP(NEXT_BYTE(m) + m->x);
44 m->mem[r1] = m->ac;
45 mark_dirty(m, r1);
46 break;
47
48 case STX_ZP:
49 r1 = ZP(NEXT_BYTE(m));
50 m->mem[r1] = m->x;
51 mark_dirty(m, r1);
52 break;
53
54 case STX_ZPY:
55 r1 = ZP(NEXT_BYTE(m) + m->y);
56 m->mem[r1] = m->x;
57 mark_dirty(m, r1);
58 break;
59
60 case STX_AB:
61 arg1 = NEXT_BYTE(m);
62 arg2 = NEXT_BYTE(m);
63 r1 = mem_abs(arg1, arg2, 0);
64 m->mem[r1] = m->x;
65 mark_dirty(m, r1);
66 break;
67
68 case STY_ZP:
69 r1 = ZP(NEXT_BYTE(m));
70 m->mem[r1] = m->y;
71 mark_dirty(m, r1);
72 break;
73
74 case STY_ZPX:
75 r1 = ZP(NEXT_BYTE(m) + m->x);
76 m->mem[r1] = m->y;
77 mark_dirty(m, r1);
78 break;
79
80 case STY_AB:
81 arg1 = NEXT_BYTE(m);
82 arg2 = NEXT_BYTE(m);
83 r1 = mem_abs(arg1, arg2, 0);
84 m->mem[r1] = m->y;
85 mark_dirty(m, r1);
86 break;
0 case TAX:
1 m->x = m->ac;
2 set_flags(m, m->x);
3 break;
4
5 case TAY:
6 m->y = m->ac;
7 set_flags(m, m->y);
8 break;
9
10 case TSX:
11 m->x = m->sp;
12 set_flags(m, m->x);
13 break;
14
15 case TXA:
16 m->ac = m->x;
17 set_flags(m, m->ac);
18 break;
19
20 case TXS:
21 m->sp = m->x;
22 break;
23
24 case TYA:
25 m->ac = m->y;
26 set_flags(m, m->ac);
27 break;
+0
-169
shift.h less more
0 case ASL_AB:
1 arg1 = NEXT_BYTE(m);
2 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
3 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x80);
4 m->mem[r1] = (m->mem[r1] << 1) & 0xFE;
5 set_flags(m, m->mem[r1]);
6 mark_dirty(m, r1);
7 break;
8
9 case ASL_ABX:
10 arg1 = NEXT_BYTE(m);
11 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
12 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x80);
13 m->mem[r1] = (m->mem[r1] << 1) & 0xFE;
14 set_flags(m, m->mem[r1]);
15 mark_dirty(m, r1);
16 break;
17
18 case ASL_ACC:
19 set_flag(m, FLAG_CARRY, m->ac & 0x80);
20 m->ac = (m->ac << 1) & 0xFE;
21 set_flags(m, m->ac);
22 break;
23
24 case ASL_ZP:
25 arg1 = NEXT_BYTE(m);
26 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x80);
27 m->mem[arg1] = (m->mem[arg1] << 1) & 0xFE;
28 set_flags(m, m->mem[arg1]);
29 mark_dirty(m, arg1);
30 break;
31
32 case ASL_ZPX:
33 arg1 = ZP(NEXT_BYTE(m) + m->x);
34 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x80);
35 m->mem[arg1] = (m->mem[arg1] << 1) & 0xFE;
36 set_flags(m, m->mem[arg1]);
37 mark_dirty(m, arg1);
38 break;
39
40 case LSR_AB:
41 arg1 = NEXT_BYTE(m);
42 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
43 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x01);
44 m->mem[r1] = (m->mem[r1] >> 1) & 0x7F;
45 set_flags(m, m->mem[r1]);
46 mark_dirty(m, r1);
47 break;
48
49 case LSR_ABX:
50 arg1 = NEXT_BYTE(m);
51 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
52 set_flag(m, FLAG_CARRY, m->mem[r1] & 0x01);
53 m->mem[r1] = (m->mem[r1] >> 1) & 0x7F;
54 set_flags(m, m->mem[r1]);
55 mark_dirty(m, r1);
56 break;
57
58 case LSR_ACC:
59 set_flag(m, FLAG_CARRY, m->ac & 0x01);
60 m->ac = (m->ac >> 1) & 0x7F;
61 set_flags(m, m->ac);
62 break;
63
64 case LSR_ZP:
65 arg1 = NEXT_BYTE(m);
66 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x01);
67 m->mem[arg1] = (m->mem[arg1] >> 1) & 0x7F;
68 set_flags(m, m->mem[arg1]);
69 mark_dirty(m, arg1);
70 break;
71
72 case LSR_ZPX:
73 arg1 = ZP(NEXT_BYTE(m) + m->x);
74 set_flag(m, FLAG_CARRY, m->mem[arg1] & 0x01);
75 m->mem[arg1] = (m->mem[arg1] >> 1) & 0x7F;
76 set_flags(m, m->mem[arg1]);
77 mark_dirty(m, arg1);
78 break;
79
80 case ROL_AB:
81 arg1 = NEXT_BYTE(m);
82 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
83 t1 = m->mem[r1] & 0x80;
84 m->mem[r1] = ((m->mem[r1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
85 set_flag(m, FLAG_CARRY, t1);
86 set_flags(m, m->mem[r1]);
87 mark_dirty(m, r1);
88 break;
89
90 case ROL_ABX:
91 arg1 = NEXT_BYTE(m);
92 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
93 t1 = m->mem[r1] & 0x80;
94 m->mem[r1] = ((m->mem[r1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
95 set_flag(m, FLAG_CARRY, t1);
96 set_flags(m, m->mem[r1]);
97 mark_dirty(m, r1);
98 break;
99
100 case ROL_ACC:
101 t1 = m->ac & 0x80;
102 m->ac = ((m->ac << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
103 set_flag(m, FLAG_CARRY, t1);
104 set_flags(m, m->ac);
105 break;
106
107 case ROL_ZP:
108 arg1 = NEXT_BYTE(m);
109 t1 = m->mem[arg1] & 0x80;
110 m->mem[arg1] = ((m->mem[arg1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
111 set_flag(m, FLAG_CARRY, t1);
112 set_flags(m, m->mem[arg1]);
113 mark_dirty(m, arg1);
114 break;
115
116 case ROL_ZPX:
117 arg1 = ZP(NEXT_BYTE(m) + m->x);
118 t1 = m->mem[arg1] & 0x80;
119 m->mem[arg1] = ((m->mem[arg1] << 1) & 0xFE) | get_flag(m, FLAG_CARRY);
120 set_flag(m, FLAG_CARRY, t1);
121 set_flags(m, m->mem[arg1]);
122 mark_dirty(m, arg1);
123 break;
124
125 case ROR_AB:
126 arg1 = NEXT_BYTE(m);
127 r1 = mem_abs(arg1, NEXT_BYTE(m), 0);
128 t1 = m->mem[r1] & 0x01;
129 m->mem[r1] = ((m->mem[r1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
130 set_flag(m, FLAG_CARRY, t1);
131 set_flags(m, m->mem[r1]);
132 mark_dirty(m, r1);
133 break;
134
135 case ROR_ABX:
136 arg1 = NEXT_BYTE(m);
137 r1 = mem_abs(arg1, NEXT_BYTE(m), m->x);
138 t1 = m->mem[r1] & 0x01;
139 m->mem[r1] = ((m->mem[r1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
140 set_flag(m, FLAG_CARRY, t1);
141 set_flags(m, m->mem[r1]);
142 mark_dirty(m, r1);
143 break;
144
145 case ROR_ACC:
146 t1 = m->ac & 0x01;
147 m->ac = ((m->ac >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
148 set_flag(m, FLAG_CARRY, t1);
149 set_flags(m, m->ac);
150 break;
151
152 case ROR_ZP:
153 arg1 = NEXT_BYTE(m);
154 t1 = m->mem[arg1] & 0x01;
155 m->mem[arg1] = ((m->mem[arg1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
156 set_flag(m, FLAG_CARRY, t1);
157 set_flags(m, m->mem[arg1]);
158 mark_dirty(m, arg1);
159 break;
160
161 case ROR_ZPX:
162 arg1 = ZP(NEXT_BYTE(m) + m->x);
163 t1 = m->mem[arg1] & 0x01;
164 m->mem[arg1] = ((m->mem[arg1] >> 1) & 0x7F) | (get_flag(m, FLAG_CARRY) << 7);
165 set_flag(m, FLAG_CARRY, t1);
166 set_flags(m, m->mem[arg1]);
167 mark_dirty(m, arg1);
168 break;
+0
-15
stack.h less more
0 case PHA:
1 STACK_PUSH(m) = m->ac;
2 break;
3
4 case PHP:
5 STACK_PUSH(m) = m->sr;
6 break;
7
8 case PLA:
9 m->ac = STACK_POP(m);
10 break;
11
12 case PLP:
13 m->sr = STACK_POP(m);
14 break;
+0
-87
store.h less more
0 case STA_AB:
1 arg1 = NEXT_BYTE(m);
2 arg2 = NEXT_BYTE(m);
3 r1 = mem_abs(arg1, arg2, 0);
4 m->mem[r1] = m->ac;
5 mark_dirty(m, r1);
6 break;
7
8 case STA_ABX:
9 arg1 = NEXT_BYTE(m);
10 arg2 = NEXT_BYTE(m);
11 r1 = mem_abs(arg1, arg2, m->x);
12 m->mem[r1] = m->ac;
13 mark_dirty(m, r1);
14 break;
15
16 case STA_ABY:
17 arg1 = NEXT_BYTE(m);
18 arg2 = NEXT_BYTE(m);
19 r1 = mem_abs(arg1, arg2, m->y);
20 m->mem[r1] = m->ac;
21 mark_dirty(m, r1);
22 break;
23
24 case STA_INX:
25 r1 = mem_indexed_indirect(m, NEXT_BYTE(m), m->x);
26 m->mem[r1] = m->ac;
27 mark_dirty(m, r1);
28 break;
29
30 case STA_INY:
31 r1 = mem_indirect_index(m, NEXT_BYTE(m), m->y);
32 m->mem[r1] = m->ac;
33 mark_dirty(m, r1);
34 break;
35
36 case STA_ZP:
37 r1 = ZP(NEXT_BYTE(m));
38 m->mem[r1] = m->ac;
39 mark_dirty(m, r1);
40 break;
41
42 case STA_ZPX:
43 r1 = ZP(NEXT_BYTE(m) + m->x);
44 m->mem[r1] = m->ac;
45 mark_dirty(m, r1);
46 break;
47
48 case STX_ZP:
49 r1 = ZP(NEXT_BYTE(m));
50 m->mem[r1] = m->x;
51 mark_dirty(m, r1);
52 break;
53
54 case STX_ZPY:
55 r1 = ZP(NEXT_BYTE(m) + m->y);
56 m->mem[r1] = m->x;
57 mark_dirty(m, r1);
58 break;
59
60 case STX_AB:
61 arg1 = NEXT_BYTE(m);
62 arg2 = NEXT_BYTE(m);
63 r1 = mem_abs(arg1, arg2, 0);
64 m->mem[r1] = m->x;
65 mark_dirty(m, r1);
66 break;
67
68 case STY_ZP:
69 r1 = ZP(NEXT_BYTE(m));
70 m->mem[r1] = m->y;
71 mark_dirty(m, r1);
72 break;
73
74 case STY_ZPX:
75 r1 = ZP(NEXT_BYTE(m) + m->x);
76 m->mem[r1] = m->y;
77 mark_dirty(m, r1);
78 break;
79
80 case STY_AB:
81 arg1 = NEXT_BYTE(m);
82 arg2 = NEXT_BYTE(m);
83 r1 = mem_abs(arg1, arg2, 0);
84 m->mem[r1] = m->y;
85 mark_dirty(m, r1);
86 break;
+0
-28
transfer.h less more
0 case TAX:
1 m->x = m->ac;
2 set_flags(m, m->x);
3 break;
4
5 case TAY:
6 m->y = m->ac;
7 set_flags(m, m->y);
8 break;
9
10 case TSX:
11 m->x = m->sp;
12 set_flags(m, m->x);
13 break;
14
15 case TXA:
16 m->ac = m->x;
17 set_flags(m, m->ac);
18 break;
19
20 case TXS:
21 m->sp = m->x;
22 break;
23
24 case TYA:
25 m->ac = m->y;
26 set_flags(m, m->ac);
27 break;