yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
instructions.cc
Go to the documentation of this file.
2
3namespace yaze {
4namespace emu {
5
6// opcode functions
7
8void Spc700::MOVX(uint16_t adr) {
9 X = read(adr);
10 PSW.Z = (X == 0);
11 PSW.N = (X & 0x80);
12}
13
14void Spc700::MOVY(uint16_t adr) {
15 Y = read(adr);
16 PSW.Z = (Y == 0);
17 PSW.N = (Y & 0x80);
18}
19
20void Spc700::MOVS(uint16_t adr) {
21 switch (bstep) {
22 case 0: read(adr); break;
23 case 1: write(adr, A); bstep = 0; break;
24 }
25}
26
27void Spc700::MOVSX(uint16_t adr) {
28 switch (bstep) {
29 case 0: read(adr); break;
30 case 1: write(adr, X); bstep = 0; break;
31 }
32}
33
34void Spc700::MOVSY(uint16_t adr) {
35 switch (bstep) {
36 case 0: read(adr); break;
37 case 1: write(adr, Y); bstep = 0; break;
38 }
39}
40
41void Spc700::MOV(uint16_t adr) {
42 A = read(adr);
43 PSW.Z = (A == 0);
44 PSW.N = (A & 0x80);
45}
46
47void Spc700::MOV_ADDR(uint16_t address, uint8_t operand) {
48 write(address, operand);
49 PSW.Z = (operand == 0);
50 PSW.N = (operand & 0x80);
51}
52
53void Spc700::ADC(uint16_t adr) {
54 uint8_t value = read(adr);
55 uint16_t result = A + value + PSW.C;
56 PSW.V = ((A ^ result) & (adr ^ result) & 0x80);
57 PSW.C = (result > 0xFF);
58 PSW.H = ((A ^ adr ^ result) & 0x10);
59 A = result & 0xFF;
60 PSW.Z = ((A & 0xFF) == 0);
61 PSW.N = (A & 0x80);
62}
63
64void Spc700::ADCM(uint16_t& dest, uint8_t operand) {
65 uint8_t applyOn = read(dest);
66 int result = applyOn + operand + PSW.C;
67 PSW.V = (applyOn & 0x80) == (operand & 0x80) &&
68 (operand & 0x80) != (result & 0x80);
69 PSW.H = ((applyOn & 0xf) + (operand & 0xf) + PSW.C) > 0xf;
70 PSW.C = result > 0xff;
71 write(dest, result);
72 PSW.Z = ((result & 0xFF) == 0);
73 PSW.N = (result & 0x80);
74}
75
76void Spc700::SBC(uint16_t adr) {
77 uint8_t value = read(adr) ^ 0xff;
78 int result = A + value + PSW.C;
79 PSW.V = (A & 0x80) == (value & 0x80) && (value & 0x80) != (result & 0x80);
80 PSW.H = ((A & 0xf) + (value & 0xf) + PSW.C) > 0xf;
81 PSW.C = result > 0xff;
82 A = result;
83 PSW.Z = ((A & 0xFF) == 0);
84 PSW.N = (A & 0x80);
85}
86
87void Spc700::SBCM(uint16_t& dest, uint8_t operand) {
88 operand ^= 0xff;
89 uint8_t applyOn = read(dest);
90 int result = applyOn + operand + PSW.C;
91 PSW.V = (applyOn & 0x80) == (operand & 0x80) &&
92 (operand & 0x80) != (operand & 0x80);
93 PSW.H = ((applyOn & 0xF) + (operand & 0xF) + PSW.C) > 0xF;
94 PSW.C = result > 0xFF;
95 write(dest, result);
96 PSW.Z = ((A & 0xFF) == 0);
97 PSW.N = (A & 0x80);
98}
99
100void Spc700::CMPX(uint16_t adr) {
101 uint8_t value = read(adr) ^ 0xff;
102 int result = X + value + 1;
103 PSW.C = result > 0xff;
104 PSW.Z = (result == 0);
105 PSW.N = (result & 0x80);
106}
107
108void Spc700::CMPY(uint16_t adr) {
109 uint8_t value = read(adr) ^ 0xff;
110 int result = Y + value + 1;
111 PSW.C = result > 0xff;
112 PSW.Z = (result == 0);
113 PSW.N = (result & 0x80);
114}
115
116void Spc700::CMPM(uint16_t dst, uint8_t value) {
117 value ^= 0xff;
118 int result = read(dst) + value + 1;
119 PSW.C = result > 0xff;
120 callbacks_.idle(false);
121 PSW.Z = (result == 0);
122 PSW.N = (result & 0x80);
123}
124
125void Spc700::CMP(uint16_t adr) {
126 uint8_t value = read(adr) ^ 0xff;
127 int result = A + value + 1;
128 PSW.C = result > 0xff;
129 PSW.Z = ((result & 0xFF) == 0);
130 PSW.N = (result & 0x80);
131}
132
133void Spc700::AND(uint16_t adr) {
134 A &= read(adr);
135 PSW.Z = (A == 0);
136 PSW.N = (A & 0x80);
137}
138
139void Spc700::ANDM(uint16_t dest, uint8_t operand) {
140 uint8_t result = read(dest) & operand;
141 write(dest, result);
142 PSW.Z = (result == 0);
143 PSW.N = (result & 0x80);
144}
145
146void Spc700::OR(uint16_t adr) {
147 A |= read(adr);
148 PSW.Z = (A == 0);
149 PSW.N = (A & 0x80);
150}
151
152void Spc700::ORM(uint16_t dst, uint8_t value) {
153 uint8_t result = read(dst) | value;
154 write(dst, result);
155 PSW.Z = (result == 0);
156 PSW.N = (result & 0x80);
157}
158
159void Spc700::EOR(uint16_t adr) {
160 A ^= read(adr);
161 PSW.Z = (A == 0);
162 PSW.N = (A & 0x80);
163}
164
165void Spc700::EORM(uint16_t dest, uint8_t operand) {
166 uint8_t result = read(dest) ^ operand;
167 write(dest, result);
168 PSW.Z = (result == 0);
169 PSW.N = (result & 0x80);
170}
171
172void Spc700::ASL(uint16_t operand) {
173 uint8_t val = read(operand);
174 write(operand, val);
175 PSW.C = (val & 0x80);
176 val <<= 1;
177 PSW.Z = (val == 0);
178 PSW.N = (val & 0x80);
179}
180
181void Spc700::LSR(uint16_t adr) {
182 uint8_t val = read(adr);
183 PSW.C = (val & 0x01);
184 val >>= 1;
185 write(adr, val);
186 PSW.Z = (val == 0);
187 PSW.N = (val & 0x80);
188}
189
190void Spc700::ROR(uint16_t adr) {
191 uint8_t val = read(adr);
192 bool newC = val & 1;
193 val = (val >> 1) | (PSW.C << 7);
194 PSW.C = newC;
195 write(adr, val);
196 PSW.Z = (val == 0);
197 PSW.N = (val & 0x80);
198}
199
200void Spc700::ROL(uint16_t adr) {
201 uint8_t val = read(adr);
202 bool newC = val & 0x80;
203 val = (val << 1) | PSW.C;
204 PSW.C = newC;
205 write(adr, val);
206
207 PSW.Z = (val == 0);
208 PSW.N = (val & 0x80);
209}
210
211void Spc700::XCN(uint8_t operand, bool isImmediate) {
212 uint8_t value = isImmediate ? imm() : operand;
213 value = ((value & 0xF0) >> 4) | ((value & 0x0F) << 4);
214 PSW.Z = (value == 0);
215 PSW.N = (value & 0x80);
216 // operand = value;
217}
218
219void Spc700::INC(uint16_t adr) {
220 uint8_t val = read(adr) + 1;
221 write(adr, val);
222 PSW.Z = (val == 0);
223 PSW.N = (val & 0x80);
224}
225
226void Spc700::DEC(uint16_t operand) {
227 uint8_t val = read(operand) - 1;
228 write(operand, val);
229 PSW.Z = (operand == 0);
230 PSW.N = (operand & 0x80);
231}
232
233void Spc700::MOVW(uint16_t& dest, uint16_t operand) {
234 dest = operand;
235 PSW.Z = (operand == 0);
236 PSW.N = (operand & 0x8000);
237}
238
239void Spc700::INCW(uint16_t& operand) {
240 operand++;
241 PSW.Z = (operand == 0);
242 PSW.N = (operand & 0x8000);
243}
244
245void Spc700::DECW(uint16_t& operand) {
246 operand--;
247 PSW.Z = (operand == 0);
248 PSW.N = (operand & 0x8000);
249}
250
251void Spc700::ADDW(uint16_t& dest, uint16_t operand) {
252 uint32_t result = dest + operand;
253 PSW.C = (result > 0xFFFF);
254 PSW.Z = ((result & 0xFFFF) == 0);
255 PSW.N = (result & 0x8000);
256 PSW.V = ((dest ^ result) & (operand ^ result) & 0x8000);
257 dest = result & 0xFFFF;
258}
259
260void Spc700::SUBW(uint16_t& dest, uint16_t operand) {
261 uint32_t result = dest - operand;
262 PSW.C = (result < 0x10000);
263 PSW.Z = ((result & 0xFFFF) == 0);
264 PSW.N = (result & 0x8000);
265 PSW.V = ((dest ^ result) & (dest ^ operand) & 0x8000);
266 dest = result & 0xFFFF;
267}
268
269void Spc700::CMPW(uint16_t operand) {
270 uint32_t result = YA - operand;
271 PSW.C = (result < 0x10000);
272 PSW.Z = ((result & 0xFFFF) == 0);
273 PSW.N = (result & 0x8000);
274}
275
276void Spc700::MUL(uint8_t operand) {
277 uint16_t result = A * operand;
278 YA = result;
279 PSW.Z = (result == 0);
280 PSW.N = (result & 0x8000);
281}
282
283void Spc700::DIV(uint8_t operand) {
284 if (operand == 0) {
285 // Handle divide by zero error
286 return;
287 }
288 uint8_t quotient = A / operand;
289 uint8_t remainder = A % operand;
290 A = quotient;
291 Y = remainder;
292 PSW.Z = (quotient == 0);
293 PSW.N = (quotient & 0x80);
294}
295
296void Spc700::BRA(int8_t offset) { PC += offset; }
297
298void Spc700::BEQ(int8_t offset) {
299 if (PSW.Z) {
300 PC += offset;
301 }
302}
303
304void Spc700::BNE(int8_t offset) {
305 if (!PSW.Z) {
306 PC += offset;
307 }
308}
309
310void Spc700::BCS(int8_t offset) {
311 if (PSW.C) {
312 PC += offset;
313 }
314}
315
316void Spc700::BCC(int8_t offset) {
317 if (!PSW.C) {
318 PC += offset;
319 }
320}
321
322void Spc700::BVS(int8_t offset) {
323 if (PSW.V) {
324 PC += offset;
325 }
326}
327
328void Spc700::BVC(int8_t offset) {
329 if (!PSW.V) {
330 PC += offset;
331 }
332}
333
334void Spc700::BMI(int8_t offset) {
335 if (PSW.N) {
336 PC += offset;
337 }
338}
339
340void Spc700::BPL(int8_t offset) {
341 if (!PSW.N) {
342 PC += offset;
343 }
344}
345
346void Spc700::BBS(uint8_t bit, uint8_t operand) {
347 if (operand & (1 << bit)) {
348 PC += rel();
349 }
350}
351
352void Spc700::BBC(uint8_t bit, uint8_t operand) {
353 if (!(operand & (1 << bit))) {
354 PC += rel();
355 }
356}
357
358// CBNE DBNZ
359// JMP
360void Spc700::JMP(uint16_t address) { PC = address; }
361
362void Spc700::CALL(uint16_t address) {
363 uint16_t return_address = PC + 2;
364 write(SP, return_address & 0xFF);
365 write(SP - 1, (return_address >> 8) & 0xFF);
366 SP -= 2;
367 PC = address;
368}
369
370void Spc700::PCALL(uint8_t offset) {
371 uint16_t return_address = PC + 2;
372 write(SP, return_address & 0xFF);
373 write(SP - 1, (return_address >> 8) & 0xFF);
374 SP -= 2;
375 PC += offset;
376}
377
378void Spc700::TCALL(uint8_t offset) {
379 uint16_t return_address = PC + 2;
380 write(SP, return_address & 0xFF);
381 write(SP - 1, (return_address >> 8) & 0xFF);
382 SP -= 2;
383 PC = 0xFFDE + offset;
384}
385
387 uint16_t return_address = PC + 2;
388 write(SP, return_address & 0xFF);
389 write(SP - 1, (return_address >> 8) & 0xFF);
390 SP -= 2;
391 PC = 0xFFDE;
392}
393
395 uint16_t return_address = read(SP) | (read(SP + 1) << 8);
396 SP += 2;
397 PC = return_address;
398}
399
401 uint16_t return_address = read(SP) | (read(SP + 1) << 8);
402 SP += 2;
403 PC = return_address;
404 PSW.I = 1;
405}
406
407void Spc700::PUSH(uint8_t operand) {
408 write(SP, operand);
409 SP--;
410}
411
412void Spc700::POP(uint8_t& operand) {
413 SP++;
414 operand = read(SP);
415}
416
417void Spc700::SET1(uint8_t bit, uint8_t& operand) { operand |= (1 << bit); }
418
419void Spc700::CLR1(uint8_t bit, uint8_t& operand) { operand &= ~(1 << bit); }
420
421void Spc700::TSET1(uint8_t bit, uint8_t& operand) {
422 PSW.C = (operand & (1 << bit));
423 operand |= (1 << bit);
424}
425
426void Spc700::TCLR1(uint8_t bit, uint8_t& operand) {
427 PSW.C = (operand & (1 << bit));
428 operand &= ~(1 << bit);
429}
430
431void Spc700::AND1(uint8_t bit, uint8_t& operand) {
432 operand &= (1 << bit);
433 PSW.Z = (operand == 0);
434 PSW.N = (operand & 0x80);
435}
436
437void Spc700::OR1(uint8_t bit, uint8_t& operand) {
438 operand |= (1 << bit);
439 PSW.Z = (operand == 0);
440 PSW.N = (operand & 0x80);
441}
442
443void Spc700::EOR1(uint8_t bit, uint8_t& operand) {
444 operand ^= (1 << bit);
445 PSW.Z = (operand == 0);
446 PSW.N = (operand & 0x80);
447}
448
449void Spc700::NOT1(uint8_t bit, uint8_t& operand) {
450 operand ^= (1 << bit);
451 PSW.Z = (operand == 0);
452 PSW.N = (operand & 0x80);
453}
454
455void Spc700::MOV1(uint8_t bit, uint8_t& operand) {
456 PSW.C = (operand & (1 << bit));
457 operand |= (1 << bit);
458}
459
460void Spc700::CLRC() { PSW.C = 0; }
461
462void Spc700::SETC() { PSW.C = 1; }
463
464void Spc700::NOTC() { PSW.C = !PSW.C; }
465
466void Spc700::CLRV() { PSW.V = 0; }
467
468void Spc700::CLRP() { PSW.P = 0; }
469
470void Spc700::SETP() { PSW.P = 1; }
471
472void Spc700::EI() { PSW.I = 1; }
473
474void Spc700::DI() { PSW.I = 0; }
475
476void Spc700::NOP() { PC++; }
477
479
481
482} // namespace emu
483} // namespace yaze
void CMPM(uint16_t dst, uint8_t value)
void BEQ(int8_t offset)
void SUBW(uint16_t &dest, uint16_t operand)
void PCALL(uint8_t offset)
void JMP(uint16_t address)
void MOVS(uint16_t adr)
uint8_t read(uint16_t address)
Definition spc700.h:143
void MOVSX(uint16_t adr)
void NOT1(uint8_t bit, uint8_t &operand)
uint16_t adr
Definition spc700.h:80
void MOVX(uint16_t adr)
uint32_t bstep
Definition spc700.h:79
void AND1(uint8_t bit, uint8_t &operand)
void SBC(uint16_t adr)
void CMPY(uint16_t adr)
void ANDM(uint16_t dest, uint8_t operand)
void MOVW(uint16_t &dest, uint16_t operand)
void EORM(uint16_t dest, uint8_t operand)
void DEC(uint16_t operand)
void BCS(int8_t offset)
void DIV(uint8_t operand)
void MOV(uint16_t adr)
void EOR1(uint8_t bit, uint8_t &operand)
void BVS(int8_t offset)
void SBCM(uint16_t &dest, uint8_t operand)
void BVC(int8_t offset)
void LSR(uint16_t adr)
void SET1(uint8_t bit, uint8_t &operand)
void CMPX(uint16_t adr)
void TCLR1(uint8_t bit, uint8_t &operand)
void TCALL(uint8_t offset)
void CMP(uint16_t adr)
void ROL(uint16_t operand)
void MOV_ADDR(uint16_t address, uint8_t operand)
void write(uint16_t address, uint8_t value)
Definition spc700.h:173
void XCN(uint8_t operand, bool isImmediate=false)
void PUSH(uint8_t operand)
void INC(uint16_t adr)
void ADDW(uint16_t &dest, uint16_t operand)
void INCW(uint16_t &operand)
void BBC(uint8_t bit, uint8_t operand)
void BMI(int8_t offset)
void CALL(uint16_t address)
void BNE(int8_t offset)
void DECW(uint16_t &operand)
void ADC(uint16_t adr)
void EOR(uint16_t adr)
void ROR(uint16_t adr)
void BBS(uint8_t bit, uint8_t operand)
void POP(uint8_t &operand)
void ASL(uint16_t operand)
void BCC(int8_t offset)
void CLR1(uint8_t bit, uint8_t &operand)
uint16_t YA
Definition spc700.h:101
void OR(uint16_t adr)
void ADCM(uint16_t &dest, uint8_t operand)
void BRA(int8_t offset)
void BPL(int8_t offset)
void OR1(uint8_t bit, uint8_t &operand)
void CMPW(uint16_t operand)
uint16_t PC
Definition spc700.h:102
void AND(uint16_t adr)
void MOV1(uint8_t bit, uint8_t &operand)
void TSET1(uint8_t bit, uint8_t &operand)
ApuCallbacks callbacks_
Definition spc700.h:71
void MOVSY(uint16_t adr)
void MOVY(uint16_t adr)
void ORM(uint16_t dest, uint8_t operand)
void MUL(uint8_t operand)
SNES Emulation and debugging tools.
Definition apu.cc:13
Main namespace for the application.
Definition controller.cc:18