-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.asm
227 lines (202 loc) · 4.65 KB
/
build.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
; PRESS START routine builder
;----------------------------------------------
@x_pos: db 0
@y_pos: db 0
@tally: db 0
push_start.print: equ 24576 ; Address to compile the routine at.
build.start:
; Make static graphic to print PRESS FIRE message
call @build ; Build the routine once
call @move ; Then move underneath both screens
ret
@build:
ld hl,push_start.print ; compile address
ld de,128 ; source data
@set_start_pos:
ld a,54
ld (@x_pos),a
ld a,154
ld (@y_pos),a
ld b,18 ; depth in pixels
@y_loop:
push bc
call @comp_start_lineXY ; find start of this line
@reset_tally: ; Tally in bytes to next position
xor a
ld (@tally),a
push de
ld b,150/2 ; width loop
@x_loop:
call house.pal_up
push bc
ld a,(de) ; Check each pixel
or a
call nz,@compile_printer ; If not empty, compile move-to this place and print it
@inc_tally: ; Increase the distance to next printed byte
ld a,(@tally)
inc a
ld (@tally),a
inc e ; move to next byte to check
pop bc
djnz @-x_loop
@down_line: ; Move to next source line down
pop de
ex de,hl
ld bc,128
add hl,bc
ex de,hl
pop bc ; Repeat for whole graphic
dec b
call nz,@line_down ; Only compile move down if another line is needed
jr nz,@-y_loop
@comp_ret:
ld (hl),ret_ ; Finish with a return after finished.
inc hl
@get_length:
ld de,push_start.print
and a
sbc hl,de
ret
@move:
; Copy the routine under the other screen
push hl
ld hl,build.move.src ; First move the copying code into the screen
ld de,build.move
ld bc,build.move.len
ldir
pop hl
ld (build.start.len+1),hl ; Populate the length of the routine into the code
call build.move ; Then call it
ret
build.move.src:
org 0
build.move:
@page_out: ; Page other page into upper memory
in a,(HMPR)
ld (@+rest_hi+1),a
ld a,ScreenPage2
out (HMPR),a
@copy: ; Copy the routine to the same address under the other screen
ld hl,push_start.print
ld de,push_start.print+32768
build.start.len: ld bc,0
ldir
@rest_hi: ld a,0 ; Restore upper page
out (HMPR),a
ret
build.move.end:
build.move.len: equ build.move.end-build.move
org build.move.src+build.move.len
;----------------------------------------------
@compile_printer:
; Print this byte
@move_to_tally: ; Move to position
push af
ld a,(@tally)
call @comp_moveA
pop af
@test_left: ; Test left nibble
ld c,a
and %11110000
or a
jr nz,@test_right ; If blank, print right nibble masked
ld a,c
call @comp_print_rpixA
ret
@test_right: ; If left contains data, test right
ld a,c
and %00001111
or a
ld a,c
call z,@comp_print_lpixA ; If blank, print left pixel masked
call nz,@comp_print_byteA ; Else print straight byte
ret
@line_down:
push af
ld a,(@y_pos)
inc a
ld (@y_pos),a
pop af
ret
@comp_start_lineXY:
; Set start of line
; compile LD (HL),[x*128]+[y]
ld a,(@y_pos)
ld b,a
ld a,(@x_pos)
ld c,a
srl b
rr c
ld (hl),ld_hl.nn
inc hl
ld (hl),c
inc hl
ld (hl),b
inc hl
ret
@comp_print_byteA:
; Print straight byte of data
; compile LD (HL),[A]
ld (hl),ld_.hl..n
inc hl
ld (hl),a
inc hl
ret
@comp_print_lpixA:
; print left pixel masked
; compile LD A,(HL); AND B; OR [A]; LD (HL),A
push af
ld (hl),ld_a..hl.
inc hl
ld (hl),and_b
inc hl
ld (hl),or_n
inc hl
ld (hl),a
inc hl
ld (hl),ld_.hl..a
inc hl
pop af
ret
@comp_print_rpixA:
; print right pixel masked
; compile LD A,(HL); AND C; OR [A]; LD (HL),A
ld (hl),ld_a..hl.
inc hl
ld (hl),and_c
inc hl
ld (hl),or_n
inc hl
ld (hl),a
inc hl
ld (hl),ld_.hl..a
inc hl
ret
@comp_moveA:
; compile INC L, A times, unless L>=3, then do LD A,[A]; ADD L; LD L,A
; NB I could have just done LD L,n, but I currently don't keep track of the actual x-byte position.
or a
ret z
cp 3
jr nc,@+comp_big
@comp_small:
ld b,a
@loop:
ld (hl),inc_l
inc hl
djnz @-loop
xor a
ld (@tally),a
ret
@comp_big:
ld (hl),ld_a.n
inc hl
ld (hl),a
inc hl
ld (hl),add_l
inc hl
ld (hl),ld_l.a
inc hl
xor a
ld (@tally),a
ret