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