/
simple-asl.a65
165 lines (140 loc) · 5.11 KB
/
simple-asl.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
153
154
155
156
157
158
159
160
161
162
163
164
165
; Simple 6502 routines to test with Macro Assembler AS
cpu 6502
include "src/std.a65"
ident byt "simple-asl.a65" ; we use this to check that we've loaded
; the correct binary data and symbol table.
; Temporary symbol demonstrations
tempsyms nop ; tempsyms
.foo nop ; tempsyms.foo
$$named nop ; named8
.foo nop ; named8.foo
- nop ; __back0
/ nop ; __forw0
+ nop ; __forw1
.foo2 nop ; named8.foo (as of bld152 __back#/__forw# definitions
; no longer start a new scope for dotted vars)
rts
tempsyms_end
; Section demonstrations
foo nop ; global foo
section sec1 ; level 1 :sec1:
foo nop ; :sec1:foo
bar nop ; :sec1:bar
section sec2 ; level 2 :sec1:sec2:
foo nop ; :sec1:sec2:foo
public bar ; bar (not bar[2], bar[sec2])
bar nop
public baz:parent ; :sec1:baz (not baz[sec2])
baz nop
section sec2 ; level 3 :sec1:sec2:sec2:
foo nop ; :sec1:sec2:sec2:foo
endsection sec2
endsection sec2
quux nop ; :sec1:quux
endsection sec1
section sec2 ; level 1 :sec2
foo nop ; :sec2:foo
endsection sec2
;--------------------------------------------------------------------------
; BRK opcode generation and workarounds
; The standard BRK mnemonic assembles to $00 $EA (i.e., a NOP is added
; following the BRK). This is intentional behaviour, though there's just
; been some discussion about it on the list, as of 2020-01-10.
; It can be worked around by redefining BRK as a macro:
brk macro arg=-1,{NOEXPIF}
byt $00 ; BRK opcode
if arg >= 0
byt arg ; optional "argument" after BRK opcode
endif
endm
testbrk brk
byt $FF ; sentinel
testbrkarg brk $38
byt $FE ; sentinel
;--------------------------------------------------------------------------
; std.a65 test code
; DS/DB/DW
defalloctest
dstest0 ds 3
dstest1 ds 1
dbtest db $00,"abc",[2]$FF
dwtest dw $ABCD
; ZDS
zdstest0 db $F0 ; byte at current location
zdstest1 zds 3 ; zero page allocation
zdstest2 zds 2 ; zero page allocation
zdstest3 db $F3 ; byte at current location +1
; INCW
incwtest clv
bvs .incwtemp ; show that composed temps can cross macro
.nocarry incw incwdata ; show no collision w/macro-internal .nocarry
.incwtemp
rts
incwdata zds 2
;--------------------------------------------------------------------------
; Add X and Y, storing the result in xybuf and returning it in A
addxy txa
sty xybuf
clc
adc xybuf
sta xybuf
rts
xybuf ds 1
;--------------------------------------------------------------------------
; Clear an area. fillptr₁=startaddr-1, Y=length.
fill lda #0
/ sta (fillbase),y
dey
bne -
rts
fillbase zds 2
;--------------------------------------------------------------------------
; Demonstrate use of "negative offset" indexing
LSB function addr,(addr & $FF)
MSB function addr,((addr & $FF00) >> 8)
; negoff - calculate base address for use of index reg with negative offset
;
; This must be given the END address of the array. You can then load the
; index register with -(len(data)) and iterate forward across the data
; with INX/INY; when it reaches 0 you are done.
;
negoff function end,(end-$100)
negoffcalc ; store calculated address for test/debug
lda #LSB(negoff(no_data_end))
sta no_dbgaddr
lda #MSB(negoff(no_data_end))
sta no_dbgaddr+1
rts
negoffdemo
ldx #-6 ; length of no_data must be 6
.loop inc negoff(no_data_end),x
inx
bne .loop
rts
no_dbgaddr ds 2 ; read by unit test
db $E0 ; guard byte
no_data db "0a5g8s"
no_data_end
db $E1 ; guard byte
;--------------------------------------------------------------------------
; Chromatix' 65*02 family identification
; http://forum.6502.org/viewtopic.php?f=2&t=5931
; on exit, A will contain ASCII char:
; N - NMOS 6502
; S - 65SC02
; C - 65C02 or 65CE02
; 8 - 68C816 or 65C802
chromatix_id:
lda #0
sta $84
sta $85
lda #$1D ; 'N' EOR 'S'
sta $83
lda #$25 ; 'N' EOR 'S' EOR '8'
sta $1D
lda #$4E ; 'N'
cpu 65C02
rmb4 $83 ; magic $47 opcode
cpu 6502
eor $83
rts