-
Notifications
You must be signed in to change notification settings - Fork 0
/
trolldisplay.asm
360 lines (329 loc) · 6.57 KB
/
trolldisplay.asm
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
.module TROLLDISPLAY
setupdisplay:
push ix
pop hl
ld (previx),hl
ld ix,DRAW_MAP
ret
previx:
.word 0
restoredisplay:
ld hl,(previx)
push hl
pop ix
ret
waitvsync:
ld hl,FrameCounter
ld a,(hl)
-: cp (hl)
jr z,{-}
ret
; ----------------
; MapStart: where the drawing begins on the map, used to scroll per character
; ScrollXFine: 0-7, resolution is every second pixel
DRAW_MAP:
; waste time
ld b,7 ; 7
djnz $ ; 13/8
ld bc,$1234 ; 10
; prepare font pointer
ld a,$24 ; 7
ld i,a ; 9
; reset LINECNTR in ULA
in a,($fe) ; 11
out ($ff),a ; 11
; prepare to draw 8 lines of status text
ld b,8 ; 7
; draw the text
jp TOP_LINE + $8000 ; 10
TOP_LINE_DONE:
; waste time
ld b,12 ; 7
djnz $ ; 13/8
nop ; 4
nop ; 4
; prepare font pointer
ld a,$21 ; 7
ld i,a ; 9
; save shadow registers
exx ; 4
push bc ; 11
push de ; 11
push hl ; 11
; init shadow registers
ld hl,(MapStart) ; 16
ld de,DISPLAY_WIDTH ; 10
add hl,de ; 11
ld de,MAP_WIDTH ; 10
ld c,$c9 ; 7 $c9 = ret
; change dfile+32 to a ret
ld b,(hl) ; 7
ld (hl),c ; 7
exx ; 4
; save real stack
ld (StackSave),sp ; 20
; init line-stack
ld sp,LINE_STACK_START ; 10
MapStart = $ + 1
ld hl,MAP_DATA ; 10
set 7,h ; 8
ld de,MAP_WIDTH ; 10
ld b,DISPLAY_HEIGHT_RASTERS; 7
; waste time depending on ScrollXFine
ScrollXFine = $ + 1
ld a,0 ; 7
and 6 ; 7
sla a ; 8
add a,DELAY1 & 255 ; 7
ld (DelayTable1),a ; 13
; reset LINECNTR in ULA
in a,($fe) ; 11
out ($ff),a ; 11
; clear carry
xor a ; 4
DelayTable1 = $ + 1
jp DELAY1 ; 10
.align 16
DELAY1:
and (hl) ; 7
jp AFTER_DELAY1 ; 10
;.DELAY1:
dec bc ; 6
jp AFTER_DELAY1 ; 10
;.DELAY2:
ret c ; 5
jp AFTER_DELAY1 ; 10
;.DELAY3:
nop ; 4
jp AFTER_DELAY1 ; 10
AFTER_DELAY1:
; draw the picture as specified
jp (hl) ; 4
; ----------------
AFTER_LINE0:
; dec line counter
dec b ; 4
jp z,DRAW_MAP_DONE ; 10/10 previous line was last
; reinit line stack
ld sp,LINE_STACK ; 10
; waste time
.repeat 9
nop ; 4 * 9 = 36
.loop
ret z ; 5
; draw 1 raster of 32 chars
jp (hl) ; 4 + (32 * 4) + 10 = 142 (65 left)
; ----------------
AFTER_LINE1_6:
; dec line counter
dec b ; 4
jp z,DRAW_MAP_DONE ; 10/10 previous line was last
; waste time
.repeat 11
nop ; 4 * 11 = 44
.loop
xor 0 ; 7
; draw 1 raster of 32 chars
jp (hl) ; 4 + (32 * 4) + 10 = 142 (65 left)
; ----------------
AFTER_LINE7:
; dec line counter
dec b ; 4
jp z,DRAW_MAP_DONE ; 10/10 previous line was last
; point to next line of text
add hl,de ; 11
; restore old dfile-data
exx ; 4
ld (hl),b ; 7
; change dfile+32 to a ret
add hl,de ; 11
ld b,(hl) ; 7
ld (hl),c ; 7
exx ; 4
; draw 1 raster of 32 chars
jp (hl) ; 4 + (32 * 4) + 10 = 142 (65 left)
; ----------------
AFTER_TOP_LINE:
; dec line counter
dec b ; 4
jp z,TOP_LINE_DONE ; 10/10 previous line was last
; waste time
ld a,0 ; 7
inc de ; 6
; draw 1 raster of 40 chars
jp TOP_LINE + $8000 ; 10
; ----------------
AFTER_BOTTOM_LINE:
; dec line counter
dec b ; 4
jp z,BOTTOM_LINE_DONE ; 10/10 previous line was last
; waste time
ld a,0 ; 7
inc de ; 6
; draw 1 raster of 40 chars
jp BOTTOM_LINE + $8000 ; 10
; ----------------
DRAW_MAP_DONE:
; restore stack
ld sp,(StackSave) ; 20
; waste time depending on ScrollXFine
ld a,(ScrollXFine) ; 13
and 6 ; 7
sla a ; 8
add a,DELAY2 & 255 ; 7
ld (DelayTable2),a ; 13
xor a ; 4
DelayTable2 = $ + 1
jp DELAY2 ; 10
.align 16
DELAY2:
nop ; 4
jp AFTER_DELAY2 ; 10
;.DELAY1:
ret c ; 5
jp AFTER_DELAY2 ; 10
;.DELAY2:
dec hl ; 6
jp AFTER_DELAY2 ; 10
;.DELAY3:
and (hl) ; 7
jp AFTER_DELAY2 ; 10
AFTER_DELAY2:
; waste time
.repeat 5
nop ; 4 * 5 = 20
.loop
; prepare font pointer
ld a,$24 ; 7
ld i,a ; 9
; restore dfile+32
exx ; 4
ld (hl),b ; 7
exx ; 4
; increment FrameCounter
ld hl,FrameCounter ; 10
inc (hl) ; 11
; prepare for bottom margin and VSYNC
VCentreBot = $+1
ld a,BOTTOM_MARGIN ; 7
neg ; 8
inc a ; 4
ex af,af' ; 4
ld ix,GENERATE_VSYNC ; 14
; reset LINECNTR in ULA
in a,($fe) ; 11
out ($ff),a ; 11
; prepare to draw 8 lines of status text
ld b,8 ; 7
; draw the text
jp BOTTOM_LINE + $8000 ; 10
BOTTOM_LINE_DONE:
; NMI on
out ($fe),a ; 11
call vsynctask
; restore shadow registers
exx
pop hl ; 10
pop de ; 10
pop bc ; 10
exx
; restore registers
pop hl ; 10
pop de ; 10
pop bc ; 10
pop af ; 10
; return to application
ret ; 10
; jp vsynctask ; crashes :(
; ----------------
GENERATE_VSYNC:
; VSync start
in a,($fe) ; 11
;; read some keys
; ld bc,$effe ; 10 read keys 0-6
; in a,(c) ; 12
; ld (Keys0),a ; 13
; ld bc,$f7fe ; 10read keys 1-5
; in a,(c) ; 12
; ld (Keys1),a ; 13
; = 70
;
;; waste time, 4 rasters worth of VSync
; ld b,57 ; 7
; djnz $ ; 13/8
; = 756
;
; total T = 70 + 756 = 826
ld de,INPUT._kbin ; 10
ld bc,$fefe ; 10
; = 20
.repeat 8
in a,(c) ; 12
rlc b ; 8
ld (de),a ; 7
inc de ; 6 = 33
.loop
; = 8 * 33 = 264
;waste time
ld b,40 ; 7
djnz $ ; 13/8
; = (40*13)+8+7 = 535
; for timing only
ld a,TOP_MARGIN ; 7
; total T = 535 + 264 + 20 + 7 = 826
; prepare for top margin
VCentreTop = $+1
ld a,TOP_MARGIN ; 7
neg ; 8
inc a ; 4
; prepare a' for NMI-counter
ex af,af' ; 4
; reset the row counter at the correct raster to enable fine scrolling Y
ld ix,DRAW_MAP ; 14
; restore registers
pop hl ; 10
pop de ; 10
pop bc ; 10
pop af ; 10
; NMI on, VSync stop
out ($fe),a ; 11
; return to application
ret ; 10
; ----------------
; It would have been more logical to do have a stack 0-7, but there are
; no cycles left after line7.
; The solution is to rotate the line-stack so that line0 is the last,
; and deal with the arithmetic that entails.
.align 256
LINE_STACK:
.word AFTER_LINE1_6
.word AFTER_LINE1_6
.word AFTER_LINE1_6
.word AFTER_LINE1_6
.word AFTER_LINE1_6
.word AFTER_LINE1_6
.word AFTER_LINE7
LINE_STACK_START:
.word AFTER_LINE0
;----------------
MAP_WIDTH = 600
MAP_HEIGHT = 10
MAP_DATA = D_BUFFER
DISPLAY_WIDTH = 32
DISPLAY_HEIGHT_RASTERS = 80
DISPLAY_HEIGHT = DISPLAY_HEIGHT_RASTERS / 8
TOTAL_RASTERS = 312 ;PAL=312, NTSC=262
VSYNC_RASTERS = 4
VISIBLE_RASTERS = DISPLAY_HEIGHT_RASTERS + 8 + 8
WASTED_RASTERS = 5
TOTAL_MARGIN = TOTAL_RASTERS - VISIBLE_RASTERS - VSYNC_RASTERS - WASTED_RASTERS
TOP_MARGIN = (TOTAL_MARGIN / 2) - 16
BOTTOM_MARGIN = TOTAL_MARGIN - TOP_MARGIN
StackSave .word 0
FrameCounter .byte 0
TOP_LINE:
.fill 40,0
jp AFTER_TOP_LINE
BOTTOM_LINE:
.fill 40,0
jp AFTER_BOTTOM_LINE