-
Notifications
You must be signed in to change notification settings - Fork 0
/
proc_tst.a65
153 lines (130 loc) · 4.35 KB
/
proc_tst.a65
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
; This program looks at ways to determine which type of 6502-series
; processor you are using. This version runs on the 6502 Badge, but
; should be easily modified to other systems.
;
; By Jim McClanahan, W4JBM, January 2021
;
; Build with:
; $ 64tass --intel-hex proc_tst.a65 -o proc_test.hex -m --verbose-list -L proc_test.lst
; $ ./hex2bmon.py proc_tst.hex proc_tst.mon
;
;
; For whatever system we use, we need two routines defined:
;
; *** 6502 BADGE ***
;
; A routine to send a byte to the console...
xOutpt = $EAEC ; Send one byte to the output port
;
; ...and the reset vector to restart the system.
xReset = $FFC3 ; Cold start of the system
; (the Badge's monitor also allows us to return using RTS)
; Define any constants we want to use...
CR = $0D
LF = $0A
; Location isn't particularly important...
* = $0500
; Set up the stack
;
; This is not needed if called from a monitor
;STACK: LDX #$FF
; TXS
; First, let's see what happens to the Zero flag in
; the decimal mode
TEST1: SED ; Set Decimal (BCD) Mode
CLC ; Clear the Carry Flag
LDA #$99 ; Load a BCD 99 (which is also $99)
ADC #$01 ; ...and add 1
PHP ; Push processor status byte to stack
STA TSTR1 ; Store the result in memory
CLD ; Because we don't want to forget
; At this point, the Acc is $00 but the original 6502 did not
; set the Zero flag when this happened in the decimal mode
; while the later R6502 and 65C02 did.
BEQ TEST1B
TEST1A: LDA #MSG1&255 ; Point to Message 1
STA PRINT+1
LDA #MSG1/256
STA PRINT+2
JSR SHWMSG ; Display result (no Z flag)
JMP TEST2
TEST1B: LDA #MSG2&255 ; Point to Message 2
STA PRINT+1
LDA #MSG2/256
STA PRINT+2
JSR SHWMSG ; Display result (Z flag set)
; On the original 6502, undefined instructions could do various
; (and sometimes seemingly unpredictable) things. On later versions,
; some of the unused instructions were pressed into use while others
; were changed to be a "safe" NOP (no operation).
;
; $EA is NOP and on the original most of the $xA instructions also
; act as NOPs. $1A is one that seems to be a well-behaved NOP, but
; the R6502 and 65C02 used that previously undefined code to
; implement an INC A instruction.
;
; The following code checks to see what $3A does...
TEST2: PLA ; Before the test, let's story the processor
STA TSTR2 ; results from the last test.
LDA #$FF ; Load the accumulator
.BYTE $1A ; Either a NOP or INA (similar to INX and INY)
EOR #$0 ; Let's make sure the flags are set
PHP ; Save the processor status register
STA TSTR3 ; Store result in memory
BEQ TEST2B ; Does A == 0?
TEST2A: LDA #MSG3&255 ; If not, Point to Message 3
STA PRINT+1
LDA #MSG3/256
STA PRINT+2
JSR SHWMSG
JMP FINISH
TEST2B: LDA #MSG4&255 ; Point to Message 4
STA PRINT+1
LDA #MSG4/256
STA PRINT+2
JSR SHWMSG
FINISH: PLA ; Let's store the processor status
STA TSTR4 ; from the last test.
; JMP xReset ; We're done so jump back to the monitor
RTS ; ...depending on the system, RTS may work
; If you don't want to go to the monitor, you can loop instead...
;LOOP: JMP LOOP ; Now just loop endlessly...
; Display a null-terminated message...
SHWMSG: LDY #$0 ; Show Message Subroutine
PRINT: LDA MSG1,Y ; SELF MODIFYING Address and Offset
BEQ DONE ; Did we just load a $00 end-of-string?
JSR xOutpt ; If not, print it
INY ; Point to next character
BNE PRINT ; Branch to do it again...
DONE: RTS ; Jump here at end-of-string or 256 characters
;
; If we don't have console output, you can get information on
; what happened by looking at the results stored here.
;
; 7 4 3 0
; ---- ----
; NVbb DIZC
;
; N - Negative
; V - oVerflow
; D - Decimal mode
; I - Interrupt disable
; Z - Zero
; C - Carry
;
; bb should be %11 (usually a $3x in these tests) to show the
; status was pushed to the stack using PHP and not the result
; of an interupt.
TSTR1: .BYTE $FF ; Result in Decimal mode of $99 + $01
TSTR2: .BYTE $FF ; ...and process status register
TSTR3: .BYTE $FF ; Result of $FF and then executing NOP/INC A
TSTR4: .BYTE $FF ; ...and the process status register
; TSTR1, TSTR2, TSTR3, and TSTR4 should be:
; $00 $39 $FF $B0 for the original 6502
; $00 $3B $00 $32 for the 65C02
; Our messages follows...
MSG1: .NULL CR,LF,"Decimal Mode add does not set Zero Flag. (Original 6502)",CR,LF
MSG2: .NULL CR,LF,"Decimal Mode add did set Zero Flag. (65C02)",CR,LF
MSG3: .NULL "$1A acts as a NOP. (Original 6502)",CR,LF
MSG4: .NULL "$1A acts as INC A. (65C02)",CR,LF
.END