Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/lynx/c6502mak.h
2 views
1
//
2
// Copyright (c) 2004 K. Wilkins
3
//
4
// This software is provided 'as-is', without any express or implied warranty.
5
// In no event will the authors be held liable for any damages arising from
6
// the use of this software.
7
//
8
// Permission is granted to anyone to use this software for any purpose,
9
// including commercial applications, and to alter it and redistribute it
10
// freely, subject to the following restrictions:
11
//
12
// 1. The origin of this software must not be misrepresented; you must not
13
// claim that you wrote the original software. If you use this software
14
// in a product, an acknowledgment in the product documentation would be
15
// appreciated but is not required.
16
//
17
// 2. Altered source versions must be plainly marked as such, and must not
18
// be misrepresented as being the original software.
19
//
20
// 3. This notice may not be removed or altered from any source distribution.
21
//
22
23
//////////////////////////////////////////////////////////////////////////////
24
// Handy - An Atari Lynx Emulator //
25
// Copyright (c) 1996,1997 //
26
// K. Wilkins //
27
//////////////////////////////////////////////////////////////////////////////
28
// 65C02 Macro definitions //
29
//////////////////////////////////////////////////////////////////////////////
30
// //
31
// This file contains all of the required address mode and operand //
32
// macro definitions for the 65C02 emulation //
33
// //
34
// K. Wilkins //
35
// August 1997 //
36
// //
37
//////////////////////////////////////////////////////////////////////////////
38
// Revision History: //
39
// ----------------- //
40
// //
41
// 01Aug1997 KW Document header added & class documented. //
42
// //
43
//////////////////////////////////////////////////////////////////////////////
44
45
//
46
// Addressing mode decoding
47
//
48
49
#define xIMMEDIATE() {mOperand=mPC;mPC++;}
50
#define xABSOLUTE() {mOperand=CPU_PEEKW(mPC);mPC+=2;}
51
#define xZEROPAGE() {mOperand=CPU_PEEK(mPC);mPC++;}
52
#define xZEROPAGE_X() {mOperand=CPU_PEEK(mPC)+mX;mPC++;mOperand&=0xff;}
53
#define xZEROPAGE_Y() {mOperand=CPU_PEEK(mPC)+mY;mPC++;mOperand&=0xff;}
54
#define xABSOLUTE_X() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;}
55
#define xABSOLUTE_Y() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mY;mOperand&=0xffff;}
56
#define xINDIRECT_ABSOLUTE_X() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand+=mX;mOperand&=0xffff;mOperand=CPU_PEEKW(mOperand);}
57
#define xRELATIVE() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=(mPC+mOperand)&0xffff;}
58
#define xINDIRECT_X() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=mOperand+mX;mOperand&=0x00ff;mOperand=CPU_PEEKW(mOperand);}
59
#define xINDIRECT_Y() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);mOperand=mOperand+mY;mOperand&=0xffff;}
60
#define xINDIRECT_ABSOLUTE() {mOperand=CPU_PEEKW(mPC);mPC+=2;mOperand=CPU_PEEKW(mOperand);}
61
#define xINDIRECT() {mOperand=CPU_PEEK(mPC);mPC++;mOperand=CPU_PEEKW(mOperand);}
62
63
//
64
// Helper Macros
65
//
66
//#define SET_Z(m) { mZ=(m)?false:true; }
67
//#define SET_N(m) { mN=(m&0x80)?true:false; }
68
//#define SET_NZ(m) SET_Z(m) SET_N(m)
69
#define SET_Z(m) { mZ=!(m); }
70
#define SET_N(m) { mN=(m)&0x80; }
71
#define SET_NZ(m) { mZ=!(m); mN=(m)&0x80; }
72
#define PULL(m) { mSP++; mSP&=0xff; m=CPU_PEEK(mSP+0x0100); }
73
#define PUSH(m) { CPU_POKE(0x0100+mSP,m); mSP--; mSP&=0xff; }
74
//
75
// Opcode execution
76
//
77
78
#define xADC()\
79
{\
80
int value=CPU_PEEK(mOperand);\
81
if(mD)\
82
{\
83
int c = mC?1:0;\
84
int lo = (mA & 0x0f) + (value & 0x0f) + c;\
85
int hi = (mA & 0xf0) + (value & 0xf0);\
86
mV=0;\
87
mC=0;\
88
if (lo > 0x09)\
89
{\
90
hi += 0x10;\
91
lo += 0x06;\
92
}\
93
if (~(mA^value) & (mA^hi) & 0x80) mV=1;\
94
if (hi > 0x90) hi += 0x60;\
95
if (hi & 0xff00) mC=1;\
96
mA = (lo & 0x0f) + (hi & 0xf0);\
97
}\
98
else\
99
{\
100
int c = mC?1:0;\
101
int sum = mA + value + c;\
102
mV=0;\
103
mC=0;\
104
if (~(mA^value) & (mA^sum) & 0x80) mV=1;\
105
if (sum & 0xff00) mC=1;\
106
mA = (uint8) sum;\
107
}\
108
SET_NZ(mA)\
109
}
110
111
#define xAND()\
112
{\
113
mA&=CPU_PEEK(mOperand);\
114
SET_NZ(mA);\
115
}
116
117
#define xASL()\
118
{\
119
int value=CPU_PEEK(mOperand);\
120
mC=value&0x80;\
121
value<<=1;\
122
value&=0xff;\
123
SET_NZ(value);\
124
CPU_POKE(mOperand,value);\
125
}
126
127
#define xASLA()\
128
{\
129
mC=mA&0x80;\
130
mA<<=1;\
131
mA&=0xff;\
132
SET_NZ(mA);\
133
}
134
135
#define xBCC()\
136
{\
137
if(!mC)\
138
{\
139
int offset=(signed char)CPU_PEEK(mPC);\
140
mPC++;\
141
mPC+=offset;\
142
mPC&=0xffff;\
143
}\
144
else\
145
{\
146
mPC++;\
147
mPC&=0xffff;\
148
}\
149
}
150
151
#define xBCS()\
152
{\
153
if(mC)\
154
{\
155
int offset=(signed char)CPU_PEEK(mPC);\
156
mPC++;\
157
mPC+=offset;\
158
mPC&=0xffff;\
159
}\
160
else\
161
{\
162
mPC++;\
163
mPC&=0xffff;\
164
}\
165
}
166
167
#define xBEQ()\
168
{\
169
if(mZ)\
170
{\
171
int offset=(signed char)CPU_PEEK(mPC);\
172
mPC++;\
173
mPC+=offset;\
174
mPC&=0xffff;\
175
}\
176
else\
177
{\
178
mPC++;\
179
mPC&=0xffff;\
180
}\
181
}
182
183
// This version of bit, not setting N and V status flags in immediate, seems to be correct.
184
// The same behaviour is reported on the 65C02 used in old Apple computers, at least.
185
// (From a pragmatic sense, using the normal version of bit for immediate
186
// mode breaks the title screen of "California Games" in a subtle way.)
187
#define xBIT()\
188
{\
189
int value=CPU_PEEK(mOperand);\
190
SET_Z(mA&value);\
191
\
192
if(mOpcode!=0x89)\
193
{\
194
mN=value&0x80;\
195
mV=value&0x40;\
196
}\
197
}
198
#define xBMI()\
199
{\
200
if(mN)\
201
{\
202
int offset=(signed char)CPU_PEEK(mPC);\
203
mPC++;\
204
mPC+=offset;\
205
mPC&=0xffff;\
206
}\
207
else\
208
{\
209
mPC++;\
210
mPC&=0xffff;\
211
}\
212
}
213
214
#define xBNE()\
215
{\
216
if(!mZ)\
217
{\
218
int offset=(signed char)CPU_PEEK(mPC);\
219
mPC++;\
220
mPC+=offset;\
221
mPC&=0xffff;\
222
}\
223
else\
224
{\
225
mPC++;\
226
mPC&=0xffff;\
227
}\
228
}
229
230
#define xBPL()\
231
{\
232
if(!mN)\
233
{\
234
int offset=(signed char)CPU_PEEK(mPC);\
235
mPC++;\
236
mPC+=offset;\
237
mPC&=0xffff;\
238
}\
239
else\
240
{\
241
mPC++;\
242
mPC&=0xffff;\
243
}\
244
}
245
246
#define xBRA()\
247
{\
248
int offset=(signed char)CPU_PEEK(mPC);\
249
mPC++;\
250
mPC+=offset;\
251
mPC&=0xffff;\
252
}
253
254
#define xBRK()\
255
{\
256
mPC++;\
257
PUSH(mPC>>8);\
258
PUSH(mPC&0xff);\
259
PUSH(PS()|0x10);\
260
\
261
mD=FALSE;\
262
mI=TRUE;\
263
\
264
mPC=CPU_PEEKW(IRQ_VECTOR);\
265
}
266
// KW 4/11/98 B flag needed to be set IN the stack status word = 0x10.
267
268
#define xBVC()\
269
{\
270
if(!mV)\
271
{\
272
int offset=(signed char)CPU_PEEK(mPC);\
273
mPC++;\
274
mPC+=offset;\
275
mPC&=0xffff;\
276
}\
277
else\
278
{\
279
mPC++;\
280
mPC&=0xffff;\
281
}\
282
}
283
284
#define xBVS()\
285
{\
286
if(mV)\
287
{\
288
int offset=(signed char)CPU_PEEK(mPC);\
289
mPC++;\
290
mPC+=offset;\
291
mPC&=0xffff;\
292
}\
293
else\
294
{\
295
mPC++;\
296
mPC&=0xffff;\
297
}\
298
}
299
300
#define xCLC()\
301
{\
302
mC=FALSE;\
303
}
304
305
#define xCLD()\
306
{\
307
mD=FALSE;\
308
}
309
310
#define xCLI()\
311
{\
312
mI=FALSE;\
313
}
314
315
#define xCLV()\
316
{\
317
mV=FALSE;\
318
}
319
320
#define xCMP()\
321
{\
322
int value=CPU_PEEK(mOperand);\
323
mC=0;\
324
if (mA >= value) mC=1;\
325
SET_NZ((uint8)(mA - value))\
326
}
327
328
#define xCPX()\
329
{\
330
int value=CPU_PEEK(mOperand);\
331
mC=0;\
332
if (mX >= value) mC=1;\
333
SET_NZ((uint8)(mX - value))\
334
}
335
336
#define xCPY()\
337
{\
338
int value=CPU_PEEK(mOperand);\
339
mC=0;\
340
if (mY >= value) mC=1;\
341
SET_NZ((uint8)(mY - value))\
342
}
343
344
#define xDEC()\
345
{\
346
int value=CPU_PEEK(mOperand)-1;\
347
value&=0xff;\
348
CPU_POKE(mOperand,value);\
349
SET_NZ(value);\
350
}
351
352
#define xDECA()\
353
{\
354
mA--;\
355
mA&=0xff;\
356
SET_NZ(mA);\
357
}
358
359
#define xDEX()\
360
{\
361
mX--;\
362
mX&=0xff;\
363
SET_NZ(mX);\
364
}
365
366
#define xDEY()\
367
{\
368
mY--;\
369
mY&=0xff;\
370
SET_NZ(mY);\
371
}
372
373
#define xEOR()\
374
{\
375
mA^=CPU_PEEK(mOperand);\
376
SET_NZ(mA);\
377
}
378
379
#define xINC()\
380
{\
381
int value=CPU_PEEK(mOperand)+1;\
382
value&=0xff;\
383
CPU_POKE(mOperand,value);\
384
SET_NZ(value);\
385
}
386
387
#define xINCA()\
388
{\
389
mA++;\
390
mA&=0xff;\
391
SET_NZ(mA);\
392
}
393
394
#define xINX()\
395
{\
396
mX++;\
397
mX&=0xff;\
398
SET_NZ(mX);\
399
}
400
401
#define xINY()\
402
{\
403
mY++;\
404
mY&=0xff;\
405
SET_NZ(mY);\
406
}
407
408
#define xJMP()\
409
{\
410
mPC=mOperand;\
411
}
412
413
#define xJSR()\
414
{\
415
PUSH((mPC-1)>>8);\
416
PUSH((mPC-1)&0xff);\
417
mPC=mOperand;\
418
}
419
420
#define xLDA()\
421
{\
422
mA=CPU_PEEK(mOperand);\
423
SET_NZ(mA);\
424
}
425
426
#define xLDX()\
427
{\
428
mX=CPU_PEEK(mOperand);\
429
SET_NZ(mX);\
430
}
431
432
#define xLDY()\
433
{\
434
mY=CPU_PEEK(mOperand);\
435
SET_NZ(mY);\
436
}
437
438
#define xLSR()\
439
{\
440
int value=CPU_PEEK(mOperand);\
441
mC=value&0x01;\
442
value=(value>>1)&0x7f;\
443
CPU_POKE(mOperand,value);\
444
SET_NZ(value);\
445
}
446
447
#define xLSRA()\
448
{\
449
mC=mA&0x01;\
450
mA=(mA>>1)&0x7f;\
451
SET_NZ(mA);\
452
}
453
454
#define xNOP()\
455
{\
456
}
457
458
#define xORA()\
459
{\
460
mA|=CPU_PEEK(mOperand);\
461
SET_NZ(mA);\
462
}
463
464
#define xPHA()\
465
{\
466
PUSH(mA);\
467
}
468
469
#define xPHP()\
470
{\
471
PUSH(PS());\
472
}
473
474
#define xPHX()\
475
{\
476
PUSH(mX);\
477
}
478
479
#define xPHY()\
480
{\
481
PUSH(mY);\
482
}
483
484
#define xPLA()\
485
{\
486
PULL(mA);\
487
SET_NZ(mA);\
488
}
489
490
#define xPLP()\
491
{\
492
int P;\
493
PULL(P);\
494
PS(P);\
495
}
496
497
#define xPLX()\
498
{\
499
PULL(mX);\
500
SET_NZ(mX);\
501
}
502
503
#define xPLY()\
504
{\
505
PULL(mY);\
506
SET_NZ(mY);\
507
}
508
509
#define xROL()\
510
{\
511
int value=CPU_PEEK(mOperand);\
512
int oldC=mC;\
513
mC=value&0x80;\
514
value=(value<<1)|(oldC?1:0);\
515
value&=0xff;\
516
CPU_POKE(mOperand,value);\
517
SET_NZ(value);\
518
}
519
520
#define xROLA()\
521
{\
522
int oldC=mC;\
523
mC=mA&0x80;\
524
mA=(mA<<1)|(oldC?1:0);\
525
mA&=0xff;\
526
SET_NZ(mA);\
527
}
528
529
#define xROR()\
530
{\
531
int value=CPU_PEEK(mOperand);\
532
int oldC=mC;\
533
mC=value&0x01;\
534
value=((value>>1)&0x7f)|(oldC?0x80:0x00);\
535
value&=0xff;\
536
CPU_POKE(mOperand,value);\
537
SET_NZ(value);\
538
}
539
540
#define xRORA()\
541
{\
542
int oldC=mC;\
543
mC=mA&0x01;\
544
mA=((mA>>1)&0x7f)|(oldC?0x80:0x00);\
545
mA&=0xff;\
546
SET_NZ(mA);\
547
}
548
549
#define xRTI()\
550
{\
551
int tmp;\
552
PULL(tmp);\
553
PS(tmp);\
554
PULL(mPC);\
555
PULL(tmp);\
556
mPC|=tmp<<8;\
557
}
558
559
#define xRTS()\
560
{\
561
int tmp;\
562
PULL(mPC);\
563
PULL(tmp);\
564
mPC|=tmp<<8;\
565
mPC++;\
566
}
567
568
#define xSBC()\
569
{\
570
int value=CPU_PEEK(mOperand);\
571
if (mD)\
572
{\
573
int c = mC?0:1;\
574
int sum = mA - value - c;\
575
int lo = (mA & 0x0f) - (value & 0x0f) - c;\
576
int hi = (mA & 0xf0) - (value & 0xf0);\
577
mV=0;\
578
mC=0;\
579
if ((mA^value) & (mA^sum) & 0x80) mV=1;\
580
if (lo & 0xf0) lo -= 6;\
581
if (lo & 0x80) hi -= 0x10;\
582
if (hi & 0x0f00) hi -= 0x60;\
583
if ((sum & 0xff00) == 0) mC=1;\
584
mA = (lo & 0x0f) + (hi & 0xf0);\
585
}\
586
else\
587
{\
588
int c = mC?0:1;\
589
int sum = mA - value - c;\
590
mV=0;\
591
mC=0;\
592
if ((mA^value) & (mA^sum) & 0x80) mV=1;\
593
if ((sum & 0xff00) == 0) mC=1;\
594
mA = (uint8) sum;\
595
}\
596
SET_NZ(mA)\
597
}
598
599
#define xSEC()\
600
{\
601
mC=true;\
602
}
603
604
#define xSED()\
605
{\
606
mD=true;\
607
}
608
609
#define xSEI()\
610
{\
611
mI=true;\
612
}
613
614
#define xSTA()\
615
{\
616
CPU_POKE(mOperand,mA);\
617
}
618
619
#define xSTP()\
620
{\
621
mSystem.gSystemCPUSleep=TRUE;\
622
}
623
624
#define xSTX()\
625
{\
626
CPU_POKE(mOperand,mX);\
627
}
628
629
#define xSTY()\
630
{\
631
CPU_POKE(mOperand,mY);\
632
}
633
634
#define xSTZ()\
635
{\
636
CPU_POKE(mOperand,0);\
637
}
638
639
#define xTAX()\
640
{\
641
mX=mA;\
642
SET_NZ(mX);\
643
}
644
645
#define xTAY()\
646
{\
647
mY=mA;\
648
SET_NZ(mY);\
649
}
650
651
#define xTRB()\
652
{\
653
int value=CPU_PEEK(mOperand);\
654
SET_Z(mA&value);\
655
value=value&(mA^0xff);\
656
CPU_POKE(mOperand,value);\
657
}
658
659
#define xTSB()\
660
{\
661
int value=CPU_PEEK(mOperand);\
662
SET_Z(mA&value);\
663
value=value|mA;\
664
CPU_POKE(mOperand,value);\
665
}
666
667
#define xTSX()\
668
{\
669
mX=mSP;\
670
SET_NZ(mX);\
671
}
672
673
#define xTXA()\
674
{\
675
mA=mX;\
676
SET_NZ(mA);\
677
}
678
679
#define xTXS()\
680
{\
681
mSP=mX;\
682
}
683
684
#define xTYA()\
685
{\
686
mA=mY;\
687
SET_NZ(mA);\
688
}
689
690
#define xWAI()\
691
{\
692
mSystem.gSystemCPUSleep=TRUE;\
693
}
694
695
696