OXYGENHUB
◆ riscv-1 x16-emulator / src / cpu / 65c02.h
7.9 KiB · Objective-C · last changed chore(): initial commit 15 days ago source blame history raw
03a3459e Andy McCall 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
    putvalue(0, memory_16bit());
46
}
47
48
// *******************************************************************************************
49
//
50
//								Unconditional Branch
51
//
52
// *******************************************************************************************
53
54
static void bra() {
55
    oldpc = regs.pc;
56
    regs.pc += reladdr;
57
    if (regs.e && (oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502++; //check if jump crossed a page boundary
58
}
59
60
// *******************************************************************************************
61
//
62
//									Push/Pull X and Y
63
//
64
// *******************************************************************************************
65
66
static void phx() {
67
    penaltym = 1;
68
69
    if (index_16bit()) {
70
        push16(regs.x);
71
    } else {
72
        push8(regs.xl);
73
    }
74
}
75
76
static void plx() {
77
    penaltym = 1;
78
79
    if (index_16bit()) {
80
        regs.x = pull16();
81
        zerocalc(regs.x, 1);
82
        signcalc(regs.x, 1);
83
    } else {
84
        regs.xl = pull8();
85
86
        zerocalc(regs.xl, 0);
87
        signcalc(regs.xl, 0);
88
    }
89
}
90
91
static void phy() {
92
    penaltym = 1;
93
94
    if (index_16bit()) {
95
        push16(regs.y);
96
    } else {
97
        push8(regs.yl);
98
    }
99
}
100
101
static void ply() {
102
    penaltym = 1;
103
104
    if (index_16bit()) {
105
        regs.y = pull16();
106
        zerocalc(regs.y, 1);
107
        signcalc(regs.y, 1);
108
    } else {
109
        regs.yl = pull8();
110
111
        zerocalc(regs.yl, 0);
112
        signcalc(regs.yl, 0);
113
    }
114
}
115
116
// *******************************************************************************************
117
//
118
//								TRB & TSB - Test and Change bits
119
//
120
// *******************************************************************************************
121
122
static void tsb() {
123
    value = getvalue(memory_16bit()); 							// Read memory
124
    result = acc_for_mode() & value;                // calculate A & memory
125
    zerocalc(result, memory_16bit()); 								// Set Z flag from this.
126
    result = value | acc_for_mode(); 				// Write back value read, A bits are set.
127
    putvalue(result, memory_16bit());
128
}
129
130
static void trb() {
131
    value = getvalue(memory_16bit()); 							// Read memory
132
    result = acc_for_mode() & value;  			// calculate A & memory
133
    zerocalc(result, memory_16bit()); 								// Set Z flag from this.
134
    result = value & (memory_16bit() ? regs.c ^ 0xFFFF : regs.a ^ 0xFF); 		    	// Write back value read, A bits are clear.
135
    putvalue(result, memory_16bit());
136
}
137
138
// *******************************************************************************************
139
//
140
//                                   Stop (Invoke Debugger)
141
//
142
// *******************************************************************************************
143
144
static void dbg() {
145
    stop6502(regs.pc - 1, regs.k);
146
}
147
148
// *******************************************************************************************
149
//
150
//                                     Wait for interrupt
151
//
152
// *******************************************************************************************
153
154
static void wai() {
155
	waiting = 1;
156
}
157
158
// *******************************************************************************************
159
//
160
//                                     BBR and BBS
161
//
162
// *******************************************************************************************
163
static void bbr(uint16_t bitmask)
164
{
165
    if (warn_rockwell) rockwell_warning("BBR");
166
	if ((getvalue(0) & bitmask) == 0) {
167
		oldpc = regs.pc;
168
		regs.pc += reladdr;
169
		if ((oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
170
		else clockticks6502++;
171
	}
172
}
173
174
static void bbr0() { bbr(0x01); }
175
static void bbr1() { bbr(0x02); }
176
static void bbr2() { bbr(0x04); }
177
static void bbr3() { bbr(0x08); }
178
static void bbr4() { bbr(0x10); }
179
static void bbr5() { bbr(0x20); }
180
static void bbr6() { bbr(0x40); }
181
static void bbr7() { bbr(0x80); }
182
183
static void bbs(uint16_t bitmask)
184
{
185
    if (warn_rockwell) rockwell_warning("BBS");
186
	if ((getvalue(0) & bitmask) != 0) {
187
		oldpc = regs.pc;
188
		regs.pc += reladdr;
189
		if ((oldpc & 0xFF00) != (regs.pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
190
		else clockticks6502++;
191
	}
192
}
193
194
static void bbs0() { bbs(0x01); }
195
static void bbs1() { bbs(0x02); }
196
static void bbs2() { bbs(0x04); }
197
static void bbs3() { bbs(0x08); }
198
static void bbs4() { bbs(0x10); }
199
static void bbs5() { bbs(0x20); }
200
static void bbs6() { bbs(0x40); }
201
static void bbs7() { bbs(0x80); }
202
203
// *******************************************************************************************
204
//
205
//                                     SMB and RMB
206
//
207
// *******************************************************************************************
208
209
static void smb0() { if (warn_rockwell) rockwell_warning("SMB0"); putvalue(getvalue(0) | 0x01, 0); }
210
static void smb1() { if (warn_rockwell) rockwell_warning("SMB1"); putvalue(getvalue(0) | 0x02, 0); }
211
static void smb2() { if (warn_rockwell) rockwell_warning("SMB2"); putvalue(getvalue(0) | 0x04, 0); }
212
static void smb3() { if (warn_rockwell) rockwell_warning("SMB3"); putvalue(getvalue(0) | 0x08, 0); }
213
static void smb4() { if (warn_rockwell) rockwell_warning("SMB4"); putvalue(getvalue(0) | 0x10, 0); }
214
static void smb5() { if (warn_rockwell) rockwell_warning("SMB5"); putvalue(getvalue(0) | 0x20, 0); }
215
static void smb6() { if (warn_rockwell) rockwell_warning("SMB6"); putvalue(getvalue(0) | 0x40, 0); }
216
static void smb7() { if (warn_rockwell) rockwell_warning("SMB7"); putvalue(getvalue(0) | 0x80, 0); }
217
218
static void rmb0() { if (warn_rockwell) rockwell_warning("RMB0"); putvalue(getvalue(0) & ~0x01, 0); }
219
static void rmb1() { if (warn_rockwell) rockwell_warning("RMB1"); putvalue(getvalue(0) & ~0x02, 0); }
220
static void rmb2() { if (warn_rockwell) rockwell_warning("RMB2"); putvalue(getvalue(0) & ~0x04, 0); }
221
static void rmb3() { if (warn_rockwell) rockwell_warning("RMB3"); putvalue(getvalue(0) & ~0x08, 0); }
222
static void rmb4() { if (warn_rockwell) rockwell_warning("RMB4"); putvalue(getvalue(0) & ~0x10, 0); }
223
static void rmb5() { if (warn_rockwell) rockwell_warning("RMB5"); putvalue(getvalue(0) & ~0x20, 0); }
224
static void rmb6() { if (warn_rockwell) rockwell_warning("RMB6"); putvalue(getvalue(0) & ~0x40, 0); }
225
static void rmb7() { if (warn_rockwell) rockwell_warning("RMB7"); putvalue(getvalue(0) & ~0x80, 0); }