-
Notifications
You must be signed in to change notification settings - Fork 10
/
painting.s
286 lines (240 loc) · 5.96 KB
/
painting.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
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
;
; painting.s
; General rendering routines for 80 column text elements
;
; Created by Quinn Dunki on 8/15/14.
; Copyright (c) 2014 One Girl, One Laptop Productions. All rights reserved.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGDesktop
; Paints the desktop pattern (assumes 80 cols)
;
WGDesktop:
pha
lda #'W'
sta WGClearScreen_charPage1+1
lda #'V'
bra WGClearScreen_common
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGClearScreen
; Clears the text screen (assumes 80 cols)
;
WGClearScreen:
pha
lda #' ' + $80
sta WGClearScreen_charPage1+1
WGClearScreen_common:
sta WGClearScreen_charPage2+1
SAVE_XY
SETSWITCH PAGE2OFF
ldx #23
WGClearScreen_lineLoop:
lda TEXTLINES_L,x ; Compute video memory address of line
sta WGClearScreen_charLoop1+1
sta WGClearScreen_charLoop2+1
lda TEXTLINES_H,x
sta WGClearScreen_charLoop1+2
sta WGClearScreen_charLoop2+2
ldy #39
WGClearScreen_charPage1:
lda #$FF ; Self-modifying code!
WGClearScreen_charLoop1:
sta $FFFF,y ; Self-modifying code!
dey
bpl WGClearScreen_charLoop1
SETSWITCH PAGE2ON
ldy #39
WGClearScreen_charPage2:
lda #$FF ; Self-modifying code!
WGClearScreen_charLoop2:
sta $FFFF,y ; Self-modifying code!
dey
bpl WGClearScreen_charLoop2
SETSWITCH PAGE2OFF
dex
bpl WGClearScreen_lineLoop
RESTORE_XY
pla
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGPlot
; Plots a character at global cursor position (assumes 80 cols)
; A: Character to plot (Apple format)
; Side effects: Clobbers BASL,BASH
;
WGPlot:
SAVE_XY
pha
ldx WG_CURSORY
lda TEXTLINES_L,x ; Compute video memory address of point
sta BASL
lda TEXTLINES_H,x
sta BASH
lda WG_CURSORX
lsr
clc
adc BASL
sta BASL
bcc WGPlot_SkipInc
inc BASH
WGPlot_SkipInc:
lda WG_CURSORX ; X even?
ror
bcs WGPlot_xOdd
SETSWITCH PAGE2ON ; Plot the character
pla
sta (BASL)
jmp WGPlot_done
WGPlot_xOdd:
SETSWITCH PAGE2OFF ; Plot the character
pla
sta (BASL)
WGPlot_done:
SETSWITCH PAGE2OFF
RESTORE_XY
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WGPrint
; Prints a null-terminated ASCII string at the current view's
; cursor position. Clips to current view.
; PARAM0: String pointer, LSB
; PARAM1: String pointer, MSB
; V: If set, characters are printed raw with no high bit alterations
; Side effects: Clobbers SA,BASL,BASH
;
WGPrint:
SAVE_AXY
SAVE_ZPS
lda #%10000000
ldx #%00111111
bvc WGPrint_setupMask
lda #0
ldx #$ff
clv
WGPrint_setupMask:
sta WGPrint_specialMask
stx WGPrint_setupMaskInverse
; Start checking clipping boundaries
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+3
bcs WGPrint_leapDone ; Entire string is below the clip box
jsr WGStrLen ; We'll need the length of the string
sta SCRATCH1
LDX_ACTIVEVIEW ; Cache view width for later
lda WG_VIEWRECORDS+7,x
sta WG_SCRATCHA
ldy #0
WGPrint_lineLoopFirst: ; Calculating start of first line is slightly different
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+1
bcc WGPrint_skipToEndFirst ; This line is above the clip box
lda WG_LOCALCURSORX ; Find start of line within clip box
cmp WG_VIEWCLIP+0
bcs WGPrint_visibleChars
lda WG_VIEWCLIP+0 ; Line begins before left clip plane
sec ; Advance string index and advance cursor into clip box
sbc WG_LOCALCURSORX
tay
lda WG_VIEWCLIP+0
sta WG_LOCALCURSORX
bra WGPrint_visibleChars
WGPrint_leapDone:
bra WGPrint_done
WGPrint_skipToEndFirst:
lda WG_SCRATCHA ; Skip string index ahead by distance to EOL
sec
sbc WG_LOCALCURSORX
cmp SCRATCH1
bcs WGPrint_done ; EOL is past the end of the string, so we're done
tay
lda WG_SCRATCHA ; Skip cursor ahead to EOL
sta WG_LOCALCURSORX
bra WGPrint_nextLine
WGPrint_skipToEnd:
tya ; Skip string index ahead by distance to EOL
clc
adc WG_SCRATCHA
cmp SCRATCH1
bcs WGPrint_done ; EOL is past the end of the string, so we're done
tay
lda WG_SCRATCHA ; Skip cursor ahead to EOL
sta WG_LOCALCURSORX
bra WGPrint_nextLine
WGPrint_lineLoop:
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+1
bcc WGPrint_skipToEnd ; This line is above the clip box
lda WG_LOCALCURSORX ; Find start of line within clip box
cmp WG_VIEWCLIP+0
bcs WGPrint_visibleChars
tya
clc
adc WG_VIEWCLIP+0 ; Jump ahead by left span
tay
lda WG_VIEWCLIP+0 ; Set cursor to left edge of visible area
sta WG_LOCALCURSORX
WGPrint_visibleChars:
jsr WGSyncGlobalCursor
lda INVERSE
cmp #CHAR_INVERSE
beq WGPrint_charLoopInverse
WGPrint_charLoopNormal:
lda (PARAM0),y ; Draw current character
beq WGPrint_done
ora WGPrint_specialMask
jsr WGPlot
iny
inc WG_CURSORX ; Advance cursors
inc WG_LOCALCURSORX
lda WG_LOCALCURSORX
cmp WG_SCRATCHA ; Check for wrap boundary
beq WGPrint_nextLine
cmp WG_VIEWCLIP+2 ; Check for right clip plane
beq WGPrint_endVisible
bra WGPrint_charLoopNormal
WGPrint_done: ; This is in the middle here to keep local branches in range
RESTORE_ZPS
RESTORE_AXY
rts
WGPrint_endVisible:
tya
clc
adc WG_VIEWCLIP+4 ; Advance string index by right span
cmp SCRATCH1
bcs WGPrint_done
tay
WGPrint_nextLine:
inc WG_LOCALCURSORY ; Advance cursor
lda WG_LOCALCURSORY
cmp WG_VIEWCLIP+3 ; Check for bottom clip plane
beq WGPrint_done
cmp WG_VIEWRECORDS+8,x ; Check for bottom of view
beq WGPrint_done
lda (PARAM0),y ; Check for end string landing exactly at line end
beq WGPrint_done
stz WG_LOCALCURSORX
bra WGPrint_lineLoop
WGPrint_charLoopInverse:
lda (PARAM0),y ; Draw current character
beq WGPrint_done
cmp #$60
bcc WGPrint_charLoopInverseLow
and #%01111111 ; Inverse lowercase is in alternate character set
bra WGPrint_charLoopInversePlot
WGPrint_charLoopInverseLow:
and WGPrint_setupMaskInverse ; Normal inverse
WGPrint_charLoopInversePlot:
jsr WGPlot
iny
inc WG_CURSORX ; Advance cursors
inc WG_LOCALCURSORX
lda WG_LOCALCURSORX
cmp WG_SCRATCHA ; Check for wrap boundary
beq WGPrint_nextLine
cmp WG_VIEWCLIP+2 ; Check for right clip plane
beq WGPrint_endVisible
bra WGPrint_charLoopInverse
WGPrint_specialMask:
.byte 0
WGPrint_setupMaskInverse:
.byte 0