Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Cherry/Core/opcodes_ed.cpp
2 views
1
/*
2
* Gearcoleco - ColecoVision Emulator
3
* Copyright (C) 2021 Ignacio Sanchez
4
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see http://www.gnu.org/licenses/
17
*
18
*/
19
20
#include "Processor.h"
21
22
void Processor::OPCodeED0x40()
23
{
24
// IN B,(C)
25
OPCodes_IN_C(BC.GetHighRegister());
26
}
27
28
void Processor::OPCodeED0x41()
29
{
30
// OUT (C),B
31
OPCodes_OUT_C(BC.GetHighRegister());
32
}
33
34
void Processor::OPCodeED0x42()
35
{
36
// SBC HL,BC
37
OPCodes_SBC_HL(BC.GetValue());
38
}
39
40
void Processor::OPCodeED0x43()
41
{
42
// LD (nn),BC
43
OPCodes_LD_nn_dd(&BC);
44
}
45
46
void Processor::OPCodeED0x44()
47
{
48
// NEG
49
u8 value = AF.GetHigh();
50
AF.SetHigh(0x00);
51
OPCodes_SUB(value);
52
}
53
54
void Processor::OPCodeED0x45()
55
{
56
// RETN
57
OPCodes_RET();
58
m_bIFF1 = m_bIFF2;
59
}
60
61
void Processor::OPCodeED0x46()
62
{
63
// IM 0
64
SetInterruptMode(0);
65
}
66
67
void Processor::OPCodeED0x47()
68
{
69
// LD I,A
70
OPCodes_LD(&I, AF.GetHigh());
71
}
72
73
void Processor::OPCodeED0x48()
74
{
75
// IN C,(C)
76
OPCodes_IN_C(BC.GetLowRegister());
77
}
78
79
void Processor::OPCodeED0x49()
80
{
81
// OUT (C),C
82
OPCodes_OUT_C(BC.GetLowRegister());
83
}
84
85
void Processor::OPCodeED0x4A()
86
{
87
// ADC HL,BC
88
OPCodes_ADC_HL(BC.GetValue());
89
}
90
91
void Processor::OPCodeED0x4B()
92
{
93
// LD BC,(nn)
94
OPCodes_LD_dd_nn(&BC);
95
}
96
97
void Processor::OPCodeED0x4C()
98
{
99
// NEG*
100
UndocumentedOPCode();
101
OPCodeED0x44();
102
}
103
104
void Processor::OPCodeED0x4D()
105
{
106
// RETI
107
OPCodes_RET();
108
m_bIFF1 = m_bIFF2;
109
}
110
111
void Processor::OPCodeED0x4E()
112
{
113
// IM 0*
114
UndocumentedOPCode();
115
OPCodeED0x46();
116
}
117
118
void Processor::OPCodeED0x4F()
119
{
120
// LD R,A
121
OPCodes_LD(&R, AF.GetHigh());
122
}
123
124
void Processor::OPCodeED0x50()
125
{
126
// IN D,(C)
127
OPCodes_IN_C(DE.GetHighRegister());
128
}
129
130
void Processor::OPCodeED0x51()
131
{
132
// OUT (C),D
133
OPCodes_OUT_C(DE.GetHighRegister());
134
}
135
136
void Processor::OPCodeED0x52()
137
{
138
// SBC HL,DE
139
OPCodes_SBC_HL(DE.GetValue());
140
}
141
142
void Processor::OPCodeED0x53()
143
{
144
// LD (nn),DE
145
OPCodes_LD_nn_dd(&DE);
146
}
147
148
void Processor::OPCodeED0x54()
149
{
150
// NEG*
151
UndocumentedOPCode();
152
OPCodeED0x44();
153
}
154
155
void Processor::OPCodeED0x55()
156
{
157
// RETN*
158
UndocumentedOPCode();
159
OPCodeED0x45();
160
}
161
162
void Processor::OPCodeED0x56()
163
{
164
// IM 1
165
SetInterruptMode(1);
166
}
167
168
void Processor::OPCodeED0x57()
169
{
170
// LD A,I
171
u8 value = I;
172
OPCodes_LD(AF.GetHighRegister(), value);
173
ToggleSignFlagFromResult(value);
174
ToggleZeroFlagFromResult(value);
175
ToggleXYFlagsFromResult(value);
176
ClearFlag(FLAG_HALF);
177
ClearFlag(FLAG_NEGATIVE);
178
if (m_bIFF2)
179
ToggleFlag(FLAG_PARITY);
180
else
181
ClearFlag(FLAG_PARITY);
182
}
183
184
void Processor::OPCodeED0x58()
185
{
186
// IN E,(C)
187
OPCodes_IN_C(DE.GetLowRegister());
188
}
189
190
void Processor::OPCodeED0x59()
191
{
192
// OUT (C),E
193
OPCodes_OUT_C(DE.GetLowRegister());
194
}
195
196
void Processor::OPCodeED0x5A()
197
{
198
// ADC HL,DE
199
OPCodes_ADC_HL(DE.GetValue());
200
}
201
202
void Processor::OPCodeED0x5B()
203
{
204
// LD DE,(nn)
205
OPCodes_LD_dd_nn(&DE);
206
}
207
208
void Processor::OPCodeED0x5C()
209
{
210
// NEG*
211
UndocumentedOPCode();
212
OPCodeED0x44();
213
}
214
215
void Processor::OPCodeED0x5D()
216
{
217
// RETN*
218
UndocumentedOPCode();
219
OPCodeED0x45();
220
}
221
222
void Processor::OPCodeED0x5E()
223
{
224
// IM 2
225
SetInterruptMode(2);
226
}
227
228
void Processor::OPCodeED0x5F()
229
{
230
// LD A,R
231
u8 value = R;
232
OPCodes_LD(AF.GetHighRegister(), value);
233
ToggleSignFlagFromResult(value);
234
ToggleZeroFlagFromResult(value);
235
ToggleXYFlagsFromResult(value);
236
ClearFlag(FLAG_HALF);
237
ClearFlag(FLAG_NEGATIVE);
238
if (m_bIFF2)
239
ToggleFlag(FLAG_PARITY);
240
else
241
ClearFlag(FLAG_PARITY);
242
}
243
244
void Processor::OPCodeED0x60()
245
{
246
// IN H,(C)
247
OPCodes_IN_C(HL.GetHighRegister());
248
}
249
250
void Processor::OPCodeED0x61()
251
{
252
// OUT (C),H
253
OPCodes_OUT_C(HL.GetHighRegister());
254
}
255
256
void Processor::OPCodeED0x62()
257
{
258
// SBC HL,HL
259
OPCodes_SBC_HL(HL.GetValue());
260
}
261
262
void Processor::OPCodeED0x63()
263
{
264
// LD (nn),HL
265
OPCodes_LD_nn_dd(&HL);
266
}
267
268
void Processor::OPCodeED0x64()
269
{
270
// NEG*
271
UndocumentedOPCode();
272
OPCodeED0x44();
273
}
274
275
void Processor::OPCodeED0x65()
276
{
277
// RETN*
278
UndocumentedOPCode();
279
OPCodeED0x45();
280
}
281
282
void Processor::OPCodeED0x66()
283
{
284
// IM 0*
285
UndocumentedOPCode();
286
OPCodeED0x46();
287
}
288
289
void Processor::OPCodeED0x67()
290
{
291
// RRD
292
u16 address = HL.GetValue();
293
u8 value = m_pMemory->Read(address);
294
u8 result = (AF.GetHigh() & 0xF0) | (value & 0x0F);
295
m_pMemory->Write(address, ((AF.GetHigh() << 4) & 0xF0) | ((value >> 4) & 0x0F));
296
AF.SetHigh(result);
297
IsSetFlag(FLAG_CARRY) ? SetFlag(FLAG_CARRY) : ClearAllFlags();
298
ToggleZeroFlagFromResult(result);
299
ToggleSignFlagFromResult(result);
300
ToggleParityFlagFromResult(result);
301
ToggleXYFlagsFromResult(result);
302
WZ.SetValue(address + 1);
303
}
304
305
void Processor::OPCodeED0x68()
306
{
307
// IN L,(C)
308
OPCodes_IN_C(HL.GetLowRegister());
309
}
310
311
void Processor::OPCodeED0x69()
312
{
313
// OUT (C),L
314
OPCodes_OUT_C(HL.GetLowRegister());
315
}
316
317
void Processor::OPCodeED0x6A()
318
{
319
// ADC HL,HL
320
OPCodes_ADC_HL(HL.GetValue());
321
}
322
323
void Processor::OPCodeED0x6B()
324
{
325
// LD HL,(nn)
326
OPCodes_LD_dd_nn(&HL);
327
}
328
329
void Processor::OPCodeED0x6C()
330
{
331
// NEG*
332
UndocumentedOPCode();
333
OPCodeED0x44();
334
}
335
336
void Processor::OPCodeED0x6D()
337
{
338
// RETN*
339
UndocumentedOPCode();
340
OPCodeED0x45();
341
}
342
343
void Processor::OPCodeED0x6E()
344
{
345
// IM 0*
346
UndocumentedOPCode();
347
OPCodeED0x46();
348
}
349
350
void Processor::OPCodeED0x6F()
351
{
352
// RLD
353
u16 address = HL.GetValue();
354
u8 value = m_pMemory->Read(address);
355
u8 result = (AF.GetHigh() & 0xF0) | ((value >> 4) & 0x0F);
356
m_pMemory->Write(address, ((value << 4) & 0xF0) | (AF.GetHigh() & 0x0F));
357
AF.SetHigh(result);
358
IsSetFlag(FLAG_CARRY) ? SetFlag(FLAG_CARRY) : ClearAllFlags();
359
ToggleZeroFlagFromResult(result);
360
ToggleSignFlagFromResult(result);
361
ToggleParityFlagFromResult(result);
362
ToggleXYFlagsFromResult(result);
363
WZ.SetValue(address + 1);
364
}
365
366
void Processor::OPCodeED0x70()
367
{
368
// IN F,(C)*
369
UndocumentedOPCode();
370
OPCodes_IN_C(NULL);
371
}
372
373
void Processor::OPCodeED0x71()
374
{
375
// OUT (C),0*
376
UndocumentedOPCode();
377
m_pIOPorts->Out(BC.GetLow(), 0);
378
}
379
380
void Processor::OPCodeED0x72()
381
{
382
// SBC HL,SP
383
OPCodes_SBC_HL(SP.GetValue());
384
}
385
386
void Processor::OPCodeED0x73()
387
{
388
// LD (nn),SP
389
OPCodes_LD_nn_dd(&SP);
390
}
391
392
void Processor::OPCodeED0x74()
393
{
394
// NEG*
395
UndocumentedOPCode();
396
OPCodeED0x44();
397
}
398
399
void Processor::OPCodeED0x75()
400
{
401
// RETN*
402
UndocumentedOPCode();
403
OPCodeED0x45();
404
}
405
406
void Processor::OPCodeED0x76()
407
{
408
// IM 1*
409
UndocumentedOPCode();
410
OPCodeED0x56();
411
}
412
413
void Processor::OPCodeED0x78()
414
{
415
// IN A,(C)
416
OPCodes_IN_C(AF.GetHighRegister());
417
WZ.SetValue(BC.GetValue() + 1);
418
}
419
420
void Processor::OPCodeED0x79()
421
{
422
// OUT (C),A
423
OPCodes_OUT_C(AF.GetHighRegister());
424
WZ.SetValue(BC.GetValue() + 1);
425
}
426
427
void Processor::OPCodeED0x7A()
428
{
429
// ADC HL,SP
430
OPCodes_ADC_HL(SP.GetValue());
431
}
432
433
void Processor::OPCodeED0x7B()
434
{
435
// LD SP,(nn)
436
OPCodes_LD_dd_nn(&SP);
437
}
438
439
void Processor::OPCodeED0x7C()
440
{
441
// NEG*
442
UndocumentedOPCode();
443
OPCodeED0x44();
444
}
445
446
void Processor::OPCodeED0x7D()
447
{
448
// RETN*
449
UndocumentedOPCode();
450
OPCodeED0x45();
451
}
452
453
void Processor::OPCodeED0x7E()
454
{
455
// IM 2*
456
UndocumentedOPCode();
457
OPCodeED0x5E();
458
}
459
460
void Processor::OPCodeED0xA0()
461
{
462
// LDI
463
OPCodes_LDI();
464
}
465
466
void Processor::OPCodeED0xA1()
467
{
468
// CPI
469
OPCodes_CPI();
470
}
471
472
void Processor::OPCodeED0xA2()
473
{
474
// INI
475
OPCodes_INI();
476
}
477
478
void Processor::OPCodeED0xA3()
479
{
480
// OUTI
481
OPCodes_OUTI();
482
}
483
484
void Processor::OPCodeED0xA8()
485
{
486
// LDD
487
OPCodes_LDD();
488
}
489
490
void Processor::OPCodeED0xA9()
491
{
492
// CPD
493
OPCodes_CPD();
494
}
495
496
void Processor::OPCodeED0xAA()
497
{
498
// IND
499
OPCodes_IND();
500
}
501
502
void Processor::OPCodeED0xAB()
503
{
504
// OUTD
505
OPCodes_OUTD();
506
}
507
508
void Processor::OPCodeED0xB0()
509
{
510
// LDIR
511
OPCodes_LDI();
512
if (BC.GetValue() != 0)
513
{
514
PC.Decrement();
515
PC.Decrement();
516
WZ.SetValue(PC.GetValue() + 1);
517
m_iTStates += 5;
518
}
519
}
520
521
void Processor::OPCodeED0xB1()
522
{
523
// CPIR
524
OPCodes_CPI();
525
if ((BC.GetValue() != 0) && !IsSetFlag(FLAG_ZERO))
526
{
527
PC.Decrement();
528
PC.Decrement();
529
WZ.SetValue(PC.GetValue() + 1);
530
m_iTStates += 5;
531
}
532
}
533
534
void Processor::OPCodeED0xB2()
535
{
536
// INIR
537
OPCodes_INI();
538
if (BC.GetHigh() != 0)
539
{
540
PC.Decrement();
541
PC.Decrement();
542
m_iTStates += 5;
543
}
544
}
545
546
void Processor::OPCodeED0xB3()
547
{
548
// OTIR
549
OPCodes_OUTI();
550
if (BC.GetHigh() != 0)
551
{
552
PC.Decrement();
553
PC.Decrement();
554
m_iTStates += 5;
555
}
556
}
557
558
void Processor::OPCodeED0xB8()
559
{
560
// LDDR
561
OPCodes_LDD();
562
if (BC.GetValue() != 0)
563
{
564
PC.Decrement();
565
PC.Decrement();
566
WZ.SetValue(PC.GetValue() + 1);
567
m_iTStates += 5;
568
}
569
}
570
571
void Processor::OPCodeED0xB9()
572
{
573
// CPDR
574
OPCodes_CPD();
575
if ((BC.GetValue() != 0) && !IsSetFlag(FLAG_ZERO))
576
{
577
PC.Decrement();
578
PC.Decrement();
579
WZ.SetValue(PC.GetValue() + 1);
580
m_iTStates += 5;
581
}
582
}
583
584
void Processor::OPCodeED0xBA()
585
{
586
// INDR
587
OPCodes_IND();
588
if (BC.GetHigh() != 0)
589
{
590
PC.Decrement();
591
PC.Decrement();
592
m_iTStates += 5;
593
}
594
}
595
596
void Processor::OPCodeED0xBB()
597
{
598
// OTDR
599
OPCodes_OUTD();
600
if (BC.GetHigh() != 0)
601
{
602
PC.Decrement();
603
PC.Decrement();
604
m_iTStates += 5;
605
}
606
}
607
608