OXYGENHUB
◆ rrdc-perf enhanced-x16-emulator / src / cpu / 65c02.h
8.0 KiB · Objective-C · last changed chore(): initial commit 25 days ago source blame history raw
1
// *******************************************************************************************
2
// *******************************************************************************************
3
//
4
//		File:		65C02.H
5
//		Date:		3rd September 2019
6
//		Purpose:	Additional functions for new 65C02 Opcodes.
7
//		Author:		Paul Robson ([email protected])
8
//
9
// *******************************************************************************************
10
// *******************************************************************************************
11
12
// *******************************************************************************************
13
//
14
//					Indirect without indexation.  (copied from indy)
15
//
16
// *******************************************************************************************
17
18
19
// *******************************************************************************************
20
//
21
//						(Absolute,Indexed) address mode for JMP
22
//
23
// *******************************************************************************************
24
25
static void ainx() { 		// absolute indexed branch
26
    uint16_t eahelp, eahelp2;
27
    eahelp = (uint16_t)read6502(regs.pc, regs.k) | (uint16_t)((uint16_t)read6502(regs.pc+1, regs.k) << 8);
28
    eahelp = (eahelp + regs.x) & 0xFFFF;
29
#if 0
30
    eahelp2 = (eahelp & 0xFF00) | ((eahelp + 1) & 0x00FF); //replicate 6502 page-boundary wraparound bug
31
#else
32
    eahelp2 = eahelp + 1; // the 65c02 doesn't have the bug
33
#endif
34
    ea = (uint16_t)read6502(eahelp, regs.k) | ((uint16_t)read6502(eahelp2, regs.k) << 8);
35
    regs.pc += 2;
36
}
37
38
// *******************************************************************************************
39
//
40
//								Store zero to memory.
41
//
42
// *******************************************************************************************
43
44
static void stz() {
45
    pay_for_wide_memory(1);
46
    putvalue(0, memory_16bit());
47
}
48
49
// *******************************************************************************************
50
//
51
//								Unconditional Branch
52
//
53
// *******************************************************************************************
54
55
static void bra() {
56
    oldpc = regs.pc;
57
    regs.pc += reladdr;
58
    if (regs.e && (oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502++; //check if jump crossed a page boundary
59
}
60
61
// *******************************************************************************************
62
//
63
//									Push/Pull X and Y
64
//
65
// *******************************************************************************************
66
67
static void phx() {
68
    penaltyx = 1;
69
70
    if (index_16bit()) {
71
        push16(regs.x);
72
    } else {
73
        push8(regs.xl);
74
    }
75
}
76
77
static void plx() {
78
    penaltyx = 1;
79
80
    if (index_16bit()) {
81
        regs.x = pull16();
82
        zerocalc(regs.x, 1);
83
        signcalc(regs.x, 1);
84
    } else {
85
        regs.xl = pull8();
86
87
        zerocalc(regs.xl, 0);
88
        signcalc(regs.xl, 0);
89
    }
90
}
91
92
static void phy() {
93
    penaltyx = 1;
94
95
    if (index_16bit()) {
96
        push16(regs.y);
97
    } else {
98
        push8(regs.yl);
99
    }
100
}
101
102
static void ply() {
103
    penaltyx = 1;
104
105
    if (index_16bit()) {
106
        regs.y = pull16();
107
        zerocalc(regs.y, 1);
108
        signcalc(regs.y, 1);
109
    } else {
110
        regs.yl = pull8();
111
112
        zerocalc(regs.yl, 0);
113
        signcalc(regs.yl, 0);
114
    }
115
}
116
117
// *******************************************************************************************
118
//
119
//								TRB & TSB - Test and Change bits
120
//
121
// *******************************************************************************************
122
123
static void tsb() {
124
    pay_for_wide_memory(2);
125
    value = getvalue(memory_16bit()); 							// Read memory
126
    result = acc_for_mode() & value;                // calculate A & memory
127
    zerocalc(result, memory_16bit()); 								// Set Z flag from this.
128
    result = value | acc_for_mode(); 				// Write back value read, A bits are set.
129
    putvalue(result, memory_16bit());
130
}
131
132
static void trb() {
133
    pay_for_wide_memory(2);
134
    value = getvalue(memory_16bit()); 							// Read memory
135
    result = acc_for_mode() & value;  			// calculate A & memory
136
    zerocalc(result, memory_16bit()); 								// Set Z flag from this.
137
    result = value & (memory_16bit() ? regs.c ^ 0xFFFF : regs.a ^ 0xFF); 		    	// Write back value read, A bits are clear.
138
    putvalue(result, memory_16bit());
139
}
140
141
// *******************************************************************************************
142
//
143
//                                   Stop (Invoke Debugger)
144
//
145
// *******************************************************************************************
146
147
static void dbg() {
148
    stop6502(regs.pc - 1, regs.k);
149
}
150
151
// *******************************************************************************************
152
//
153
//                                     Wait for interrupt
154
//
155
// *******************************************************************************************
156
157
static void wai() {
158
	waiting = 1;
159
}
160
161
// *******************************************************************************************
162
//
163
//                                     BBR and BBS
164
//
165
// *******************************************************************************************
166
static void bbr(uint16_t bitmask)
167
{
168
    if (warn_rockwell) rockwell_warning("BBR");
169
	if ((getvalue(0) & bitmask) == 0) {
170
		oldpc = regs.pc;
171
		regs.pc += reladdr;
172
		if ((oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
173
		else clockticks6502++;
174
	}
175
}
176
177
static void bbr0() { bbr(0x01); }
178
static void bbr1() { bbr(0x02); }
179
static void bbr2() { bbr(0x04); }
180
static void bbr3() { bbr(0x08); }
181
static void bbr4() { bbr(0x10); }
182
static void bbr5() { bbr(0x20); }
183
static void bbr6() { bbr(0x40); }
184
static void bbr7() { bbr(0x80); }
185
186
static void bbs(uint16_t bitmask)
187
{
188
    if (warn_rockwell) rockwell_warning("BBS");
189
	if ((getvalue(0) & bitmask) != 0) {
190
		oldpc = regs.pc;
191
		regs.pc += reladdr;
192
		if ((oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
193
		else clockticks6502++;
194
	}
195
}
196
197
static void bbs0() { bbs(0x01); }
198
static void bbs1() { bbs(0x02); }
199
static void bbs2() { bbs(0x04); }
200
static void bbs3() { bbs(0x08); }
201
static void bbs4() { bbs(0x10); }
202
static void bbs5() { bbs(0x20); }
203
static void bbs6() { bbs(0x40); }
204
static void bbs7() { bbs(0x80); }
205
206
// *******************************************************************************************
207
//
208
//                                     SMB and RMB
209
//
210
// *******************************************************************************************
211
212
static void smb0() { if (warn_rockwell) rockwell_warning("SMB0"); putvalue(getvalue(0) | 0x01, 0); }
213
static void smb1() { if (warn_rockwell) rockwell_warning("SMB1"); putvalue(getvalue(0) | 0x02, 0); }
214
static void smb2() { if (warn_rockwell) rockwell_warning("SMB2"); putvalue(getvalue(0) | 0x04, 0); }
215
static void smb3() { if (warn_rockwell) rockwell_warning("SMB3"); putvalue(getvalue(0) | 0x08, 0); }
216
static void smb4() { if (warn_rockwell) rockwell_warning("SMB4"); putvalue(getvalue(0) | 0x10, 0); }
217
static void smb5() { if (warn_rockwell) rockwell_warning("SMB5"); putvalue(getvalue(0) | 0x20, 0); }
218
static void smb6() { if (warn_rockwell) rockwell_warning("SMB6"); putvalue(getvalue(0) | 0x40, 0); }
219
static void smb7() { if (warn_rockwell) rockwell_warning("SMB7"); putvalue(getvalue(0) | 0x80, 0); }
220
221
static void rmb0() { if (warn_rockwell) rockwell_warning("RMB0"); putvalue(getvalue(0) & ~0x01, 0); }
222
static void rmb1() { if (warn_rockwell) rockwell_warning("RMB1"); putvalue(getvalue(0) & ~0x02, 0); }
223
static void rmb2() { if (warn_rockwell) rockwell_warning("RMB2"); putvalue(getvalue(0) & ~0x04, 0); }
224
static void rmb3() { if (warn_rockwell) rockwell_warning("RMB3"); putvalue(getvalue(0) & ~0x08, 0); }
225
static void rmb4() { if (warn_rockwell) rockwell_warning("RMB4"); putvalue(getvalue(0) & ~0x10, 0); }
226
static void rmb5() { if (warn_rockwell) rockwell_warning("RMB5"); putvalue(getvalue(0) & ~0x20, 0); }
227
static void rmb6() { if (warn_rockwell) rockwell_warning("RMB6"); putvalue(getvalue(0) & ~0x40, 0); }
228
static void rmb7() { if (warn_rockwell) rockwell_warning("RMB7"); putvalue(getvalue(0) & ~0x80, 0); }