-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmach_x16.s
255 lines (239 loc) · 3.92 KB
/
mach_x16.s
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
mach_init0:
rts
mach_init1:
rts
mach_reset:
ldx #$42
ldy #$02
lda #$00
jsr $FEC9
mach_dbg:
;; A has low order of new IP
rts
mach_hex_char:
tsx
lda $101,x
cmp #10
bcc _is_digit
clc
adc #55
bra _done
_is_digit:
clc
adc #$30
_done:
sta $101,x
jmp do_next
con_init:
jsr $ff81 ; CINT
lda #$0f ; ISO mode
jsr $FFD2
ldx #0
ldy #0
jsr gotoxy
rts ; Using C64-compatible kernal chrin/chrout
con_tx:
jsr $FFD2 ; C64 CHROUT
rts
con_rx:
jsr $FFCF ; C64 CHRIN
rts
raw_bs:
lda #20
rts
ll_mult:
tsx
lda $103,x
stz $103,x
sta mac
lda $104,x
stz $104,x
sta mac+1
ldy #16
again
;; Shift multiplier 1 bit right and check for carry
lda $102,x
lsr
sta $102,x
lda $101,x
ror
sta $101,x
bcc skip_add
;; Carry set. Add multiplicant to accumulator
clc
lda mac
adc $103,x
sta $103,x
lda mac+1
adc $104,x
sta $104,x
skip_add
lda mac
asl
sta mac
lda mac+1
rol
sta mac+1
dey
bne again
pla
pla
jmp do_next
ll_slash_mod:
tsx
lda $101,x
sta divisor
lda $102,x
sta divisor+1
lda $103,x
sta dividend
lda $104,x
sta dividend+1
;; Taken almost verbatim from the WDC 65816 6502 Programming Manual
lda #0
tax
pha
ldy #1
lda divisor
bmi div2
div1:
iny
asl divisor
rol divisor+1
bmi div2
cpy #17
bne div1
div2:
sec
lda dividend
sbc divisor
pha
lda dividend+1
sbc divisor+1
bcc div3
sta dividend+1
pla
sta dividend
pha
div3:
pla
pla
rol
pha
txa
rol
tax
lsr divisor+1
ror divisor
dey
bne div2
done:
pla
tay
txa
tsx
sta $102,x
tya
sta $101,x
lda dividend
sta $103,x
lda dividend+1
sta $104,x
jmp do_next
vera_addrx_l = $9f20
vera_addrx_m = $9f21
vera_addrx_h = $9f22
vera_data0 = $9f23
vera_data1 = $9f24
vera_ctrl = $9f25
vera_text_base = $1b000
vera_incr_1_h = $21 ; 1 for high-order addr bit
vera_addr0 = $00 ; for ADDRSEL in vera_ctrl
vera_addr1 = $01
screen_x: .byte ?
screen_y: .byte ?
scrptr: .addr ?
gotoxy:
clc
phx
tya
ply
tax
jsr $fff0
rts
;; A has the number of lines. >=60 is "clear screen"
;; mac0,1 == dest
;; mac2,3 == src
;; mac4 == scroll count
scroll_up:
cmp #60
bcc _in_bounds
lda #60
_in_bounds:
sta mac+4 ; Save line count
lda #vera_addr0 ; Init dest line address
sta vera_ctrl
stz vera_addrx_l
lda #>vera_text_base
sta vera_addrx_m
lda #vera_incr_1_h
sta vera_addrx_h
lda #vera_addr1 ; Init src line address
sta vera_ctrl
stz vera_addrx_l
clc
lda #>vera_text_base
adc mac+4
sta vera_addrx_m
lda #vera_incr_1_h
sta vera_addrx_h
sec
lda #60
sbc mac+4
tax ; Count of line moves
_line:
ldy #80
cpx #0
beq _do_blanks
_char:
lda vera_data1
sta vera_data0
dey
bne _char
lda #vera_addr0 ; Update dest
sta vera_ctrl
stz vera_addrx_l
inc vera_addrx_m
lda #vera_addr1 ; Update src
sta vera_ctrl
stz vera_addrx_l
inc vera_addrx_m
dex
bne _line
_do_blanks:
lda #vera_addr0
sta vera_ctrl
lda #vera_incr_1_h
sta vera_addrx_h
sec
lda #60
sbc mac+4
tax ; X now has current blanking line
_blank_line:
txa
clc
adc #>vera_text_base
sta vera_addrx_m
stz vera_addrx_l
ldy #80
lda #32
_blank_char:
sta vera_data0
dey
bne _blank_char
inx
cpx #60
bne _blank_line
rts
pagesize:
rts