-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path65C02_extended_opcodes_test.lst
11504 lines (10854 loc) · 573 KB
/
65C02_extended_opcodes_test.lst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1
------------------------------------------------ 65C02_extended_opcodes_test.a65c ------------------------------------------------
2882 lines read, no errors in pass 1.
;
; 6 5 C 0 2 E X T E N D E D O P C O D E S T E S T
;
; Copyright (C) 2013-2017 Klaus Dormann
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
; This program is designed to test all additional 65C02 opcodes, addressing
; modes and functionality not available in the NMOS version of the 6502.
; The 6502_functional_test is a prerequisite to this test.
; NMI, IRQ, STP & WAI are covered in the 6502_interrupt_test.
;
; version 04-dec-2017
; contact info at http://2m5.de or email K@2m5.de
;
; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/
; command line switches: -l -m -s2 -w -x -h0
; | | | | | no page headers in listing
; | | | | 65C02 extensions
; | | | wide listing (133 char/col)
; | | write intel hex file instead of binary
; | expand macros in listing
; generate pass2 listing
;
; No IO - should be run from a monitor with access to registers.
; To run load intel hex image with a load command, than alter PC to 400 hex
; (code_segment) and enter a go command.
; Loop on program counter determines error or successful completion of test.
; Check listing for relevant traps (jump/branch *).
; Please note that in early tests some instructions will have to be used before
; they are actually tested!
;
; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled.
; Tests documented behavior of the original 65C02 only!
; Decimal ops will only be tested with valid BCD operands and the V flag will
; be ignored as it is absolutely useless in decimal mode.
;
; Debugging hints:
; Most of the code is written sequentially. if you hit a trap, check the
; immediately preceeding code for the instruction to be tested. Results are
; tested first, flags are checked second by pushing them onto the stack and
; pulling them to the accumulator after the result was checked. The "real"
; flags are no longer valid for the tested instruction at this time!
; If the tested instruction was indexed, the relevant index (X or Y) must
; also be checked. Opposed to the flags, X and Y registers are still valid.
;
; versions:
; 19-jul-2013 1st version distributed for testing
; 23-jul-2013 fixed BRA out of range due to larger trap macros
; added RAM integrity check
; 16-aug-2013 added error report to standard output option
; 23-aug-2015 change revoked
; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM
; 28-aug-2015 fixed decimal adc/sbc immediate only testing carry
; 09-feb-2017 fixed RMB/SMB tested when they shouldn't be tested
; 04-dec-2017 fixed BRK not tested for actually going through the IRQ vector
; added option to skip the remainder of a failing test
; in report.i65
; added skip override to undefined opcode as NOP test
; C O N F I G U R A T I O N
;ROM_vectors writable (0=no, 1=yes)
;if ROM vectors can not be used interrupts will not be trapped
;as a consequence BRK can not be tested but will be emulated to test RTI
0001 = ROM_vectors = 1
;load_data_direct (0=move from code segment, 1=load directly)
;loading directly is preferred but may not be supported by your platform
;0 produces only consecutive object code, 1 is not suitable for a binary image
0001 = load_data_direct = 1
;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow
;change) 2 requires extra code and is not recommended.
0003 = I_flag = 3
;configure memory - try to stay away from memory used by the system
;zero_page memory start address, $4e (78) consecutive Bytes required
; add 2 if I_flag = 2
000a = zero_page = $a
;data_segment memory start address, $63 (99) consecutive Bytes required
; + 12 Bytes at data_segment + $f9 (JMP indirect page cross test)
0200 = data_segment = $200
if (data_segment & $ff) != 0
ERROR ERROR ERROR low byte of data_segment MUST be $00 !!
endif
;code_segment memory start address, 10kB of consecutive space required
; add 1 kB if I_flag = 2
0400 = code_segment = $400
;added WDC only opcodes WAI & STP (0=test as NOPs, >0=no test)
0001 = wdc_op = 1
;added Rockwell & WDC opcodes BBR, BBS, RMB & SMB
;(0=test as NOPs, 1=full test, >1=no test)
0001 = rkwl_wdc_op = 1
;skip testing all undefined opcodes override
;0=test as NOP, >0=skip
0000 = skip_nop = 0
;report errors through I/O channel (0=use standard self trap loops, 1=include
;report.i65 as I/O channel, add 3 kB)
0000 = report = 0
;RAM integrity test option. Checks for undesired RAM writes.
;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k)
;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM
ffff = ram_top = -1
noopt ;do not take shortcuts
;macros for error & success traps to allow user modification
;example:
;trap macro
; jsr my_error_handler
; endm
;trap_eq macro
; bne skip\?
; trap ;failed equal (zero)
;skip\?
; endm
;
; my_error_handler should pop the calling address from the stack and report it.
; putting larger portions of code (more than 3 bytes) inside the trap macro
; may lead to branch range problems for some tests.
if report = 0
trap macro
jmp * ;failed anyway
endm
trap_eq macro
beq * ;failed equal (zero)
endm
trap_ne macro
bne * ;failed not equal (non zero)
endm
trap_cs macro
bcs * ;failed carry set
endm
trap_cc macro
bcc * ;failed carry clear
endm
trap_mi macro
bmi * ;failed minus (bit 7 set)
endm
trap_pl macro
bpl * ;failed plus (bit 7 clear)
endm
trap_vs macro
bvs * ;failed overflow set
endm
trap_vc macro
bvc * ;failed overflow clear
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jmp * ;test passed, no errors
endm
endif
if report = 1
trap macro
jsr report_error
endm
trap_eq macro
bne skip\?
trap ;failed equal (zero)
skip\?
endm
trap_ne macro
beq skip\?
trap ;failed not equal (non zero)
skip\?
endm
trap_cs macro
bcc skip\?
trap ;failed carry set
skip\?
endm
trap_cc macro
bcs skip\?
trap ;failed carry clear
skip\?
endm
trap_mi macro
bpl skip\?
trap ;failed minus (bit 7 set)
skip\?
endm
trap_pl macro
bmi skip\?
trap ;failed plus (bit 7 clear)
skip\?
endm
trap_vs macro
bvc skip\?
trap ;failed overflow set
skip\?
endm
trap_vc macro
bvs skip\?
trap ;failed overflow clear
skip\?
endm
; please observe that during the test the stack gets invalidated
; therefore a RTS inside the success macro is not possible
success macro
jsr report_success
endm
endif
0001 = carry equ %00000001 ;flag bits in status
0002 = zero equ %00000010
0004 = intdis equ %00000100
0008 = decmode equ %00001000
0010 = break equ %00010000
0020 = reserv equ %00100000
0040 = overfl equ %01000000
0080 = minus equ %10000000
0001 = fc equ carry
0002 = fz equ zero
0003 = fzc equ carry+zero
0040 = fv equ overfl
0042 = fvz equ overfl+zero
0080 = fn equ minus
0081 = fnc equ minus+carry
0082 = fnz equ minus+zero
0083 = fnzc equ minus+zero+carry
00c0 = fnv equ minus+overfl
0030 = fao equ break+reserv ;bits always on after PHP, BRK
0034 = fai equ fao+intdis ;+ forced interrupt disable
00ff = m8 equ $ff ;8 bit mask
00fb = m8i equ $ff&~intdis ;8 bit mask - interrupt disable
;macros to allow masking of status bits.
;masking of interrupt enable/disable on load and compare
;masking of always on bits after PHP or BRK (unused & break) on compare
if I_flag = 0
load_flag macro
lda #\1&m8i ;force enable interrupts (mask I)
endm
cmp_flag macro
cmp #(\1|fao)&m8i ;I_flag is always enabled + always on bits
endm
eor_flag macro
eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits
endm
endif
if I_flag = 1
load_flag macro
lda #\1|intdis ;force disable interrupts
endm
cmp_flag macro
cmp #(\1|fai)&m8 ;I_flag is always disabled + always on bits
endm
eor_flag macro
eor #(\1|fai) ;invert expected flags + always on bits + I
endm
endif
if I_flag = 2
load_flag macro
lda #\1
ora flag_I_on ;restore I-flag
and flag_I_off
endm
cmp_flag macro
eor flag_I_on ;I_flag is never changed
cmp #(\1|fao)&m8i ;expected flags + always on bits, mask I
endm
eor_flag macro
eor flag_I_on ;I_flag is never changed
eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits
endm
endif
if I_flag = 3
load_flag macro
lda #\1 ;allow test to change I-flag (no mask)
endm
cmp_flag macro
cmp #(\1|fao)&m8 ;expected flags + always on bits
endm
eor_flag macro
eor #\1|fao ;invert expected flags + always on bits
endm
endif
;macros to set (register|memory|zeropage) & status
set_stat macro ;setting flags in the processor status register
load_flag \1
pha ;use stack to load status
plp
endm
set_a macro ;precharging accu & status
load_flag \2
pha ;use stack to load status
lda #\1 ;precharge accu
plp
endm
set_x macro ;precharging index & status
load_flag \2
pha ;use stack to load status
ldx #\1 ;precharge index x
plp
endm
set_y macro ;precharging index & status
load_flag \2
pha ;use stack to load status
ldy #\1 ;precharge index y
plp
endm
set_ax macro ;precharging indexed accu & immediate status
load_flag \2
pha ;use stack to load status
lda \1,x ;precharge accu
plp
endm
set_ay macro ;precharging indexed accu & immediate status
load_flag \2
pha ;use stack to load status
lda \1,y ;precharge accu
plp
endm
set_z macro ;precharging indexed zp & immediate status
load_flag \2
pha ;use stack to load status
lda \1,x ;load to zeropage
sta zpt
plp
endm
set_zx macro ;precharging zp,x & immediate status
load_flag \2
pha ;use stack to load status
lda \1,x ;load to indexed zeropage
sta zpt,x
plp
endm
set_abs macro ;precharging indexed memory & immediate status
load_flag \2
pha ;use stack to load status
lda \1,x ;load to memory
sta abst
plp
endm
set_absx macro ;precharging abs,x & immediate status
load_flag \2
pha ;use stack to load status
lda \1,x ;load to indexed memory
sta abst,x
plp
endm
;macros to test (register|memory|zeropage) & status & (mask)
tst_stat macro ;testing flags in the processor status register
php ;save status
pla ;use stack to retrieve status
pha
cmp_flag \1
trap_ne
plp ;restore status
endm
tst_a macro ;testing result in accu & flags
php ;save flags
cmp #\1 ;test result
trap_ne
pla ;load status
pha
cmp_flag \2
trap_ne
plp ;restore status
endm
tst_as macro ;testing result in accu & flags, save accu
pha
php ;save flags
cmp #\1 ;test result
trap_ne
pla ;load status
pha
cmp_flag \2
trap_ne
plp ;restore status
pla
endm
tst_x macro ;testing result in x index & flags
php ;save flags
cpx #\1 ;test result
trap_ne
pla ;load status
pha
cmp_flag \2
trap_ne
plp ;restore status
endm
tst_y macro ;testing result in y index & flags
php ;save flags
cpy #\1 ;test result
trap_ne
pla ;load status
pha
cmp_flag \2
trap_ne
plp ;restore status
endm
tst_ax macro ;indexed testing result in accu & flags
php ;save flags
cmp \1,x ;test result
trap_ne
pla ;load status
eor_flag \3
cmp \2,x ;test flags
trap_ne ;
endm
tst_ay macro ;indexed testing result in accu & flags
php ;save flags
cmp \1,y ;test result
trap_ne ;
pla ;load status
eor_flag \3
cmp \2,y ;test flags
trap_ne
endm
tst_z macro ;indexed testing result in zp & flags
php ;save flags
lda zpt
cmp \1,x ;test result
trap_ne
pla ;load status
eor_flag \3
cmp \2,x ;test flags
trap_ne
endm
tst_zx macro ;testing result in zp,x & flags
php ;save flags
lda zpt,x
cmp \1,x ;test result
trap_ne
pla ;load status
eor_flag \3
cmp \2,x ;test flags
trap_ne
endm
tst_abs macro ;indexed testing result in memory & flags
php ;save flags
lda abst
cmp \1,x ;test result
trap_ne
pla ;load status
eor_flag \3
cmp \2,x ;test flags
trap_ne
endm
tst_absx macro ;testing result in abs,x & flags
php ;save flags
lda abst,x
cmp \1,x ;test result
trap_ne
pla ;load status
eor_flag \3
cmp \2,x ;test flags
trap_ne
endm
; RAM integrity test
; verifies that none of the previous tests has altered RAM outside of the
; designated write areas.
; uses zpt word as indirect pointer, zpt+2 word as checksum
if ram_top > -1
check_ram macro
cld
lda #0
sta zpt ;set low byte of indirect pointer
sta zpt+3 ;checksum high byte
ldx #11 ;reset modifiable RAM
ccs1\? sta jxi_tab,x ;JMP indirect page cross area
dex
bpl ccs1\?
clc
ldx #zp_bss-zero_page ;zeropage - write test area
ccs3\? adc zero_page,x
bcc ccs2\?
inc zpt+3 ;carry to high byte
clc
ccs2\? inx
bne ccs3\?
ldx #hi(abs1) ;set high byte of indirect pointer
stx zpt+1
ldy #lo(abs1) ;data after write & execute test area
ccs5\? adc (zpt),y
bcc ccs4\?
inc zpt+3 ;carry to high byte
clc
ccs4\? iny
bne ccs5\?
inx ;advance RAM high address
stx zpt+1
cpx #ram_top
bne ccs5\?
sta zpt+2 ;checksum low is
cmp ram_chksm ;checksum low expected
trap_ne ;checksum mismatch
lda zpt+3 ;checksum high is
cmp ram_chksm+1 ;checksum high expected
trap_ne ;checksum mismatch
endm
else
check_ram macro
;RAM check disabled - RAM size not set
endm
endif
next_test macro ;make sure, tests don't jump the fence
lda test_case ;previous test
cmp #test_num
trap_ne ;test is out of sequence
test_num = test_num + 1
lda #test_num ;*** next tests' number
sta test_case
;check_ram ;uncomment to find altered RAM after each test
endm
if load_data_direct = 1
data
else
bss ;uninitialized segment, copy of data at end of code!
endif
000a = org zero_page
;break test interrupt save
000a : 00 irq_a ds 1 ;a register
000b : 00 irq_x ds 1 ;x register
if I_flag = 2
;masking for I bit in status
flag_I_on ds 1 ;or mask to load flags
flag_I_off ds 1 ;and mask to load flags
endif
000c : zpt ;5 bytes store/modify test area
;add/subtract operand generation and result/flag prediction
000c : 00 adfc ds 1 ;carry flag before op
000d : 00 ad1 ds 1 ;operand 1 - accumulator
000e : 00 ad2 ds 1 ;operand 2 - memory / immediate
000f : 00 adrl ds 1 ;expected result bits 0-7
0010 : 00 adrh ds 1 ;expected result bit 8 (carry)
0011 : 00 adrf ds 1 ;expected flags NV0000ZC (-V in decimal mode)
0012 : 00 sb2 ds 1 ;operand 2 complemented for subtract
0013 : zp_bss
0013 : c3824100 zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
0017 : 7f zp7f db $7f ;test pattern for compare
;logical zeropage operands
0018 : 001f7180 zpOR db 0,$1f,$71,$80 ;test pattern for OR
001c : 0fff7f80 zpAN db $0f,$ff,$7f,$80 ;test pattern for AND
0020 : ff0f8f8f zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR
;indirect addressing pointers
0024 : 1002 ind1 dw abs1 ;indirect pointer to pattern in absolute memory
0026 : 1102 dw abs1+1
0028 : 1202 dw abs1+2
002a : 1302 dw abs1+3
002c : 1402 dw abs7f
002e : 1801 inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern
0030 : 0502 indt dw abst ;indirect pointer to store area in absolute memory
0032 : 0602 dw abst+1
0034 : 0702 dw abst+2
0036 : 0802 dw abst+3
0038 : 0d01 inwt dw abst-$f8 ;indirect pointer for wrap-test store
003a : 4702 indAN dw absAN ;indirect pointer to AND pattern in absolute memory
003c : 4802 dw absAN+1
003e : 4902 dw absAN+2
0040 : 4a02 dw absAN+3
0042 : 4b02 indEO dw absEO ;indirect pointer to EOR pattern in absolute memory
0044 : 4c02 dw absEO+1
0046 : 4d02 dw absEO+2
0048 : 4e02 dw absEO+3
004a : 4302 indOR dw absOR ;indirect pointer to OR pattern in absolute memory
004c : 4402 dw absOR+1
004e : 4502 dw absOR+2
0050 : 4602 dw absOR+3
;add/subtract indirect pointers
0052 : 0502 adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory
0054 : 0602 sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC)
0056 : 0601 adiy2 dw ada2-$ff ;with offset for indirect indexed
0058 : 0701 sbiy2 dw sba2-$ff
005a : zp_bss_end
0200 = org data_segment
0200 : 0000 pg_x ds 2 ;high JMP indirect address for page cross bug
0202 : 00 test_case ds 1 ;current test number
0203 : 0000 ram_chksm ds 2 ;checksum for RAM integrity test
;add/subtract operand copy - abs tests write area
0205 : abst ;5 bytes store/modify test area
0205 : 00 ada2 ds 1 ;operand 2
0206 : 00 sba2 ds 1 ;operand 2 complemented for subtract
0207 : 000000 ds 3 ;fill remaining bytes
020a : data_bss
if load_data_direct = 1
020a : 6900 ex_adci adc #0 ;execute immediate opcodes
020c : 60 rts
020d : e900 ex_sbci sbc #0 ;execute immediate opcodes
020f : 60 rts
else
ex_adci ds 3
ex_sbci ds 3
endif
0210 : c3824100 abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
0214 : 7f abs7f db $7f ;test pattern for compare
;loads
0215 : 80800002 fLDx db fn,fn,0,fz ;expected flags for load
;shifts
0219 : rASL ;expected result ASL & ROL -carry
0219 : 86048200 rROL db $86,$04,$82,0 ; "
021d : 87058301 rROLc db $87,$05,$83,1 ;expected result ROL +carry
0221 : rLSR ;expected result LSR & ROR -carry
0221 : 61412000 rROR db $61,$41,$20,0 ; "
0225 : e1c1a080 rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry
0229 : fASL ;expected flags for shifts
0229 : 81018002 fROL db fnc,fc,fn,fz ;no carry in
022d : 81018000 fROLc db fnc,fc,fn,0 ;carry in
0231 : fLSR
0231 : 01000102 fROR db fc,0,fc,fz ;no carry in
0235 : 81808180 fRORc db fnc,fn,fnc,fn ;carry in
;increments (decrements)
0239 : 7f80ff0001 rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC
023e : 0080800200 fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC
;logical memory operand
0243 : 001f7180 absOR db 0,$1f,$71,$80 ;test pattern for OR
0247 : 0fff7f80 absAN db $0f,$ff,$7f,$80 ;test pattern for AND
024b : ff0f8f8f absEO db $ff,$0f,$8f,$8f ;test pattern for EOR
;logical accu operand
024f : 00f11f00 absORa db 0,$f1,$1f,0 ;test pattern for OR
0253 : f0ffffff absANa db $f0,$ff,$ff,$ff ;test pattern for AND
0257 : fff0f00f absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR
;logical results
025b : 00ff7f80 absrlo db 0,$ff,$7f,$80
025f : 02800080 absflo db fz,fn,0,fn
0263 : data_bss_end
;define area for page crossing JMP (abs) & JMP (abs,x) test
02f9 = jxi_tab equ data_segment + $100 - 7 ;JMP (jxi_tab,x) x=6
02fd = ji_tab equ data_segment + $100 - 3 ;JMP (ji_tab+2)
0300 = jxp_tab equ data_segment + $100 ;JMP (jxp_tab-255) x=255
code
0400 = org code_segment
0400 : d8 start cld
0401 : a2ff ldx #$ff
0403 : 9a txs
0404 : a900 lda #0 ;*** test 0 = initialize
0406 : 8d0202 sta test_case
0000 = test_num = 0
;stop interrupts before initializing BSS
if I_flag = 1
sei
endif
;initialize I/O for report channel
if report = 1
jsr report_init
endif
;initialize BSS segment
if load_data_direct != 1
ldx #zp_end-zp_init-1
ld_zp lda zp_init,x
sta zp_bss,x
dex
bpl ld_zp
ldx #data_end-data_init-1
ld_data lda data_init,x
sta data_bss,x
dex
bpl ld_data
if ROM_vectors = 1
ldx #5
ld_vect lda vec_init,x
sta vec_bss,x
dex
bpl ld_vect
endif
endif
;retain status of interrupt flag
if I_flag = 2
php
pla
and #4 ;isolate flag
sta flag_I_on ;or mask
eor #lo(~4) ;reverse
sta flag_I_off ;and mask
endif
;generate checksum for RAM integrity test
if ram_top > -1
lda #0
sta zpt ;set low byte of indirect pointer
sta ram_chksm+1 ;checksum high byte
ldx #11 ;reset modifiable RAM
gcs1 sta jxi_tab,x ;JMP indirect page cross area
dex
bpl gcs1
clc
ldx #zp_bss-zero_page ;zeropage - write test area
gcs3 adc zero_page,x
bcc gcs2
inc ram_chksm+1 ;carry to high byte
clc
gcs2 inx
bne gcs3
ldx #hi(abs1) ;set high byte of indirect pointer
stx zpt+1
ldy #lo(abs1) ;data after write & execute test area
gcs5 adc (zpt),y
bcc gcs4
inc ram_chksm+1 ;carry to high byte
clc
gcs4 iny
bne gcs5
inx ;advance RAM high address
stx zpt+1
cpx #ram_top
bne gcs5
sta ram_chksm ;checksum complete
endif
next_test
0409 : ad0202 > lda test_case ;previous test
040c : c900 > cmp #test_num
> trap_ne ;test is out of sequence
040e : d0fe > bne * ;failed not equal (non zero)
>
0001 = >test_num = test_num + 1
0410 : a901 > lda #test_num ;*** next tests' number
0412 : 8d0202 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
;testing stack operations PHX PHY PLX PLY
0415 : a999 lda #$99 ;protect a
0417 : a2ff ldx #$ff ;initialize stack
0419 : 9a txs
041a : a255 ldx #$55
041c : da phx
041d : a2aa ldx #$aa
041f : da phx
0420 : ecfe01 cpx $1fe ;on stack ?
trap_ne
0423 : d0fe > bne * ;failed not equal (non zero)
0425 : ba tsx
0426 : e0fd cpx #$fd ;sp decremented?
trap_ne
0428 : d0fe > bne * ;failed not equal (non zero)
042a : 7a ply
042b : c0aa cpy #$aa ;successful retreived from stack?
trap_ne
042d : d0fe > bne * ;failed not equal (non zero)
042f : 7a ply
0430 : c055 cpy #$55
trap_ne
0432 : d0fe > bne * ;failed not equal (non zero)
0434 : ccff01 cpy $1ff ;remains on stack?
trap_ne
0437 : d0fe > bne * ;failed not equal (non zero)
0439 : ba tsx
043a : e0ff cpx #$ff ;sp incremented?
trap_ne
043c : d0fe > bne * ;failed not equal (non zero)
043e : a0a5 ldy #$a5
0440 : 5a phy
0441 : a05a ldy #$5a
0443 : 5a phy
0444 : ccfe01 cpy $1fe ;on stack ?
trap_ne
0447 : d0fe > bne * ;failed not equal (non zero)
0449 : ba tsx
044a : e0fd cpx #$fd ;sp decremented?
trap_ne
044c : d0fe > bne * ;failed not equal (non zero)
044e : fa plx
044f : e05a cpx #$5a ;successful retreived from stack?
trap_ne
0451 : d0fe > bne * ;failed not equal (non zero)
0453 : fa plx
0454 : e0a5 cpx #$a5
trap_ne
0456 : d0fe > bne * ;failed not equal (non zero)
0458 : ecff01 cpx $1ff ;remains on stack?
trap_ne
045b : d0fe > bne * ;failed not equal (non zero)
045d : ba tsx
045e : e0ff cpx #$ff ;sp incremented?
trap_ne
0460 : d0fe > bne * ;failed not equal (non zero)
0462 : c999 cmp #$99 ;unchanged?
trap_ne
0464 : d0fe > bne * ;failed not equal (non zero)
next_test
0466 : ad0202 > lda test_case ;previous test
0469 : c901 > cmp #test_num
> trap_ne ;test is out of sequence
046b : d0fe > bne * ;failed not equal (non zero)
>
0002 = >test_num = test_num + 1
046d : a902 > lda #test_num ;*** next tests' number
046f : 8d0202 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; test PHX does not alter flags or X but PLX does
0472 : a0aa ldy #$aa ;protect y
set_x 1,$ff ;push
> load_flag $ff
0474 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0476 : 48 > pha ;use stack to load status
0477 : a201 > ldx #1 ;precharge index x
0479 : 28 > plp
047a : da phx
tst_x 1,$ff
047b : 08 > php ;save flags
047c : e001 > cpx #1 ;test result
> trap_ne
047e : d0fe > bne * ;failed not equal (non zero)
>
0480 : 68 > pla ;load status
0481 : 48 > pha
> cmp_flag $ff
0482 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0484 : d0fe > bne * ;failed not equal (non zero)
>
0486 : 28 > plp ;restore status
set_x 0,0
> load_flag 0
0487 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0489 : 48 > pha ;use stack to load status
048a : a200 > ldx #0 ;precharge index x
048c : 28 > plp
048d : da phx
tst_x 0,0
048e : 08 > php ;save flags
048f : e000 > cpx #0 ;test result
> trap_ne
0491 : d0fe > bne * ;failed not equal (non zero)
>
0493 : 68 > pla ;load status
0494 : 48 > pha
> cmp_flag 0
0495 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0497 : d0fe > bne * ;failed not equal (non zero)
>
0499 : 28 > plp ;restore status
set_x $ff,$ff
> load_flag $ff
049a : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
049c : 48 > pha ;use stack to load status
049d : a2ff > ldx #$ff ;precharge index x
049f : 28 > plp
04a0 : da phx
tst_x $ff,$ff
04a1 : 08 > php ;save flags
04a2 : e0ff > cpx #$ff ;test result
> trap_ne
04a4 : d0fe > bne * ;failed not equal (non zero)
>
04a6 : 68 > pla ;load status
04a7 : 48 > pha
> cmp_flag $ff
04a8 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
04aa : d0fe > bne * ;failed not equal (non zero)
>
04ac : 28 > plp ;restore status
set_x 1,0
> load_flag 0
04ad : a900 > lda #0 ;allow test to change I-flag (no mask)
>
04af : 48 > pha ;use stack to load status
04b0 : a201 > ldx #1 ;precharge index x
04b2 : 28 > plp
04b3 : da phx
tst_x 1,0
04b4 : 08 > php ;save flags
04b5 : e001 > cpx #1 ;test result
> trap_ne
04b7 : d0fe > bne * ;failed not equal (non zero)
>
04b9 : 68 > pla ;load status
04ba : 48 > pha
> cmp_flag 0
04bb : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
04bd : d0fe > bne * ;failed not equal (non zero)
>
04bf : 28 > plp ;restore status
set_x 0,$ff
> load_flag $ff
04c0 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
04c2 : 48 > pha ;use stack to load status
04c3 : a200 > ldx #0 ;precharge index x
04c5 : 28 > plp
04c6 : da phx
tst_x 0,$ff
04c7 : 08 > php ;save flags
04c8 : e000 > cpx #0 ;test result
> trap_ne
04ca : d0fe > bne * ;failed not equal (non zero)
>
04cc : 68 > pla ;load status
04cd : 48 > pha
> cmp_flag $ff
04ce : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
04d0 : d0fe > bne * ;failed not equal (non zero)
>
04d2 : 28 > plp ;restore status
set_x $ff,0
> load_flag 0
04d3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
04d5 : 48 > pha ;use stack to load status
04d6 : a2ff > ldx #$ff ;precharge index x
04d8 : 28 > plp
04d9 : da phx
tst_x $ff,0
04da : 08 > php ;save flags
04db : e0ff > cpx #$ff ;test result
> trap_ne
04dd : d0fe > bne * ;failed not equal (non zero)
>
04df : 68 > pla ;load status