rev |
line source |
nuclear@0
|
1 org $8000
|
nuclear@0
|
2
|
nuclear@0
|
3 fb_addr equ $4000
|
nuclear@0
|
4 attr_addr equ $5800
|
nuclear@0
|
5
|
nuclear@0
|
6 prog_test:
|
nuclear@0
|
7 call setup_intr
|
nuclear@0
|
8
|
nuclear@0
|
9 ld a, 2
|
nuclear@0
|
10 out (254), a
|
nuclear@0
|
11
|
nuclear@2
|
12 call clear_scr
|
nuclear@2
|
13
|
nuclear@0
|
14 drawloop:
|
nuclear@2
|
15 ld b, 0
|
nuclear@2
|
16 ld a, (py)
|
nuclear@2
|
17 ld c, a
|
nuclear@2
|
18 push bc
|
nuclear@2
|
19 ld a, (px)
|
nuclear@2
|
20 ld c, a
|
nuclear@2
|
21 push bc
|
nuclear@2
|
22 call erase_blk
|
nuclear@2
|
23 pop bc
|
nuclear@2
|
24 pop bc
|
nuclear@2
|
25
|
nuclear@2
|
26 ld hl, sprite
|
nuclear@2
|
27 push hl
|
nuclear@2
|
28 ld b, 0
|
nuclear@2
|
29 ld a, (ny)
|
nuclear@2
|
30 ld (py), a
|
nuclear@2
|
31 ld c, a
|
nuclear@2
|
32 push bc
|
nuclear@2
|
33 ld a, (nx)
|
nuclear@2
|
34 ld (px), a
|
nuclear@2
|
35 ld c, a
|
nuclear@2
|
36 push bc
|
nuclear@2
|
37 call draw_sprite
|
nuclear@2
|
38 pop bc
|
nuclear@2
|
39 pop bc
|
nuclear@2
|
40 pop bc
|
nuclear@2
|
41
|
nuclear@2
|
42 _endfrm:
|
nuclear@2
|
43 ld a, 2
|
nuclear@2
|
44 out (254), a
|
nuclear@2
|
45
|
nuclear@2
|
46 halt
|
nuclear@0
|
47 jp drawloop
|
nuclear@0
|
48
|
nuclear@2
|
49 px defb 16
|
nuclear@2
|
50 py defb 12
|
nuclear@2
|
51 nx defb 16
|
nuclear@2
|
52 ny defb 12
|
nuclear@2
|
53
|
nuclear@2
|
54 inp_left:
|
nuclear@2
|
55 ld a, (px)
|
nuclear@2
|
56 cp 0
|
nuclear@2
|
57 ret z
|
nuclear@2
|
58 dec a
|
nuclear@2
|
59 ld (nx), a
|
nuclear@2
|
60 ret
|
nuclear@2
|
61
|
nuclear@2
|
62 inp_right:
|
nuclear@2
|
63 ld a, (px)
|
nuclear@2
|
64 cp 31
|
nuclear@2
|
65 ret z
|
nuclear@2
|
66 inc a
|
nuclear@2
|
67 ld (nx), a
|
nuclear@2
|
68 ret
|
nuclear@2
|
69
|
nuclear@2
|
70 inp_up:
|
nuclear@2
|
71 ld a, (py)
|
nuclear@2
|
72 cp 0
|
nuclear@2
|
73 ret z
|
nuclear@2
|
74 dec a
|
nuclear@2
|
75 ld (ny), a
|
nuclear@2
|
76 ret
|
nuclear@2
|
77
|
nuclear@2
|
78 inp_down:
|
nuclear@2
|
79 ld a, (py)
|
nuclear@2
|
80 cp 23
|
nuclear@2
|
81 ret z
|
nuclear@2
|
82 inc a
|
nuclear@2
|
83 ld (ny), a
|
nuclear@2
|
84 ret
|
nuclear@2
|
85
|
nuclear@2
|
86 inp_fire: ; TODO
|
nuclear@2
|
87 ret
|
nuclear@2
|
88
|
nuclear@0
|
89 clear_scr:
|
nuclear@0
|
90 ld a, $ff
|
nuclear@0
|
91 ld hl, fb_addr
|
nuclear@0
|
92 ld b, 192
|
nuclear@2
|
93 _ly: ld c, 32
|
nuclear@2
|
94 _lx: ld (hl), a
|
nuclear@0
|
95 inc hl
|
nuclear@0
|
96 dec c
|
nuclear@2
|
97 jr nz, _lx
|
nuclear@0
|
98 dec b
|
nuclear@2
|
99 jr nz, _ly
|
nuclear@2
|
100 ret
|
nuclear@2
|
101
|
nuclear@2
|
102 erase_blk:
|
nuclear@2
|
103 ld ix, 2
|
nuclear@2
|
104 add ix, sp
|
nuclear@2
|
105 ld c, (ix)
|
nuclear@2
|
106 ld b, (ix + 2)
|
nuclear@2
|
107
|
nuclear@2
|
108 call calc_blk_addr
|
nuclear@2
|
109
|
nuclear@2
|
110 ld c, 8
|
nuclear@2
|
111 ld a, $ff
|
nuclear@2
|
112 _loop: ld (de), a
|
nuclear@2
|
113 inc d
|
nuclear@2
|
114 dec c
|
nuclear@2
|
115 jr nz, _loop
|
nuclear@2
|
116 ret
|
nuclear@2
|
117
|
nuclear@2
|
118
|
nuclear@2
|
119 draw_sprite:
|
nuclear@2
|
120 ld ix, 2
|
nuclear@2
|
121 add ix, sp ; skip ret addr
|
nuclear@2
|
122 ld c, (ix) ; c <- x
|
nuclear@2
|
123 ld b, (ix + 2) ; b <- y
|
nuclear@2
|
124 ld l, (ix + 4) ; hl <- sprite address
|
nuclear@2
|
125 ld h, (ix + 5)
|
nuclear@2
|
126
|
nuclear@2
|
127 call calc_blk_addr
|
nuclear@2
|
128
|
nuclear@2
|
129 ld c, 8
|
nuclear@2
|
130 _loop: ld a, (hl)
|
nuclear@2
|
131 ld (de), a
|
nuclear@2
|
132 inc hl
|
nuclear@2
|
133 inc d
|
nuclear@2
|
134 dec c
|
nuclear@2
|
135 jr nz, _loop
|
nuclear@2
|
136 ret
|
nuclear@2
|
137
|
nuclear@2
|
138 ; expects X -> c, Y -> b, returns in de
|
nuclear@2
|
139 calc_blk_addr:
|
nuclear@2
|
140 push af
|
nuclear@2
|
141 sla b
|
nuclear@2
|
142 sla b ; change from blocks to pixels
|
nuclear@2
|
143 sla b
|
nuclear@2
|
144 ; construct low address byte -> e
|
nuclear@2
|
145 ld a, b ; start with Y
|
nuclear@2
|
146 sla a
|
nuclear@2
|
147 sla a
|
nuclear@2
|
148 and $e0 ; keep top 3 bits
|
nuclear@2
|
149 ld e, a ; move into e
|
nuclear@2
|
150 ld a, c ; a <- X
|
nuclear@2
|
151 and $1f ; keep low 5 bits
|
nuclear@2
|
152 or e ; combine with Y bits
|
nuclear@2
|
153 ld e, a ; move the result back to e
|
nuclear@2
|
154 ; construct high address byte -> d
|
nuclear@2
|
155 ld a, b ; start with Y again
|
nuclear@2
|
156 sra a
|
nuclear@2
|
157 sra a
|
nuclear@2
|
158 sra a
|
nuclear@2
|
159 and $18 ; keep bits 3 and 4
|
nuclear@2
|
160 ld d, a ; keep it in d
|
nuclear@2
|
161 ld a, b ; grap Y one more time
|
nuclear@2
|
162 and $7 ; keep low 3 bits of Y in a
|
nuclear@2
|
163 or d ; combine with Y6-Y7
|
nuclear@2
|
164 ld bc, fb_addr
|
nuclear@2
|
165 or b ; combine with high byte of fb address
|
nuclear@2
|
166 ld d, a ; move result back to d
|
nuclear@2
|
167 pop af
|
nuclear@2
|
168 ret
|
nuclear@2
|
169
|
nuclear@2
|
170
|
nuclear@2
|
171 ; port | keys
|
nuclear@2
|
172 ; ------+--------------------------
|
nuclear@2
|
173 ; 32766 | B, N, M, SymbShift, Space
|
nuclear@2
|
174 ; 64510 | T, R, E, W, Q
|
nuclear@2
|
175 ; 65022 | G, F, D, S, A
|
nuclear@2
|
176 scan_keys:
|
nuclear@2
|
177 ld bc, 65022 ; check ASD
|
nuclear@2
|
178 in a, (c)
|
nuclear@2
|
179 rra
|
nuclear@2
|
180 push af
|
nuclear@2
|
181 call nc, inp_left
|
nuclear@2
|
182 pop af
|
nuclear@2
|
183 rra
|
nuclear@2
|
184 push af
|
nuclear@2
|
185 call nc, inp_down
|
nuclear@2
|
186 pop af
|
nuclear@2
|
187 rra
|
nuclear@2
|
188 call nc, inp_right
|
nuclear@2
|
189
|
nuclear@2
|
190 ld bc, 64510 ; check W
|
nuclear@2
|
191 in a, (c)
|
nuclear@2
|
192 rra ; skip Q
|
nuclear@2
|
193 rra
|
nuclear@2
|
194 call nc, inp_up
|
nuclear@2
|
195
|
nuclear@2
|
196 ld bc, 32766 ; check space
|
nuclear@2
|
197 in a, (c)
|
nuclear@2
|
198 rra
|
nuclear@2
|
199 call nc, inp_fire
|
nuclear@0
|
200 ret
|
nuclear@0
|
201
|
nuclear@0
|
202 ; ------ setup interrupt handler ------
|
nuclear@0
|
203 ; ok this needs explaining or I will forget it later...
|
nuclear@0
|
204 ; in interrupt mode 2:
|
nuclear@0
|
205 ; - I register has the IVT base address (high byte for the jump)
|
nuclear@0
|
206 ; - data bus has the vector index (low byte for the jump)
|
nuclear@0
|
207 ; (1) IVT must be 256-byte aligned (addr: xx00h)
|
nuclear@0
|
208 ; also the IVT should not be in ULA-contended memory
|
nuclear@2
|
209 ; (2) IVT should be above 8000h
|
nuclear@0
|
210 ; also it would be a good idea to avoid putting the IVT somewhere which can be
|
nuclear@0
|
211 ; paged out on 128k models
|
nuclear@0
|
212 ; (3) IVT shouldn't extend beyond c000h (?)
|
nuclear@2
|
213 ; finally, and this is the awesome bit, the data bus of the spectrum contains
|
nuclear@2
|
214 ; garbage during the interrupt request... which leads us to
|
nuclear@0
|
215 ; (4) we must populate the entire IVT with the same interrupt address
|
nuclear@0
|
216 ; (5) we must use an interrupt address with identical low and high bytes
|
nuclear@0
|
217 ; (6) we need 257 bytes for the IVT
|
nuclear@0
|
218 ;
|
nuclear@0
|
219 ; with those facts in mind the code below:
|
nuclear@0
|
220 ; - uses BE00h to BF01h (inclusive) for the IVT
|
nuclear@0
|
221 ; - a trampoline jump opcode is placed at BDBDh to jump to intr
|
nuclear@0
|
222 ; - the address BDBDh is then populated throughout the IVT (bd, 257 times)
|
nuclear@0
|
223 ; -------------------------------------
|
nuclear@0
|
224
|
nuclear@0
|
225 ivt_addr equ $be00 ; c000 - 512 (we need 257 bytes headroom)
|
nuclear@0
|
226 intr_tramp_addr equ $bdbd
|
nuclear@0
|
227 jp_opcode equ $c3
|
nuclear@0
|
228
|
nuclear@0
|
229 setup_intr:
|
nuclear@0
|
230 di
|
nuclear@0
|
231 ld ix, ivt_addr
|
nuclear@0
|
232 push ix
|
nuclear@0
|
233 pop af ; a contains high byte of the ivt address
|
nuclear@0
|
234 ld i, a
|
nuclear@0
|
235 ld c, 0
|
nuclear@0
|
236 ld hl, intr_tramp_addr
|
nuclear@0
|
237 push hl
|
nuclear@0
|
238 pop af ; a contains high byte of the trampoline address
|
nuclear@2
|
239 _livt: ld (ix), a
|
nuclear@0
|
240 inc ix
|
nuclear@0
|
241 dec c
|
nuclear@2
|
242 jr nz, _livt
|
nuclear@0
|
243 ld (ix), a ; final odd high byte of the address
|
nuclear@0
|
244 ; at $bdbd setup the jump to our interrupt routine
|
nuclear@0
|
245 ld ix, $bdbd
|
nuclear@0
|
246 ld (ix), jp_opcode
|
nuclear@0
|
247 ld bc, intr
|
nuclear@0
|
248 ld (ix+1), c
|
nuclear@0
|
249 ld (ix+2), b
|
nuclear@0
|
250 ; done
|
nuclear@0
|
251 im 2
|
nuclear@0
|
252 ei
|
nuclear@0
|
253 ret
|
nuclear@0
|
254
|
nuclear@0
|
255 intr:
|
nuclear@2
|
256 exx
|
nuclear@2
|
257 ex af, af'
|
nuclear@2
|
258
|
nuclear@2
|
259 ld a, 1
|
nuclear@0
|
260 out (254), a
|
nuclear@2
|
261
|
nuclear@2
|
262 call scan_keys
|
nuclear@2
|
263 ex af, af'
|
nuclear@2
|
264 exx
|
nuclear@0
|
265 ei
|
nuclear@0
|
266 reti
|
nuclear@0
|
267
|
nuclear@0
|
268 border defb 1
|
nuclear@0
|
269 nframe defw 0
|
nuclear@0
|
270
|
nuclear@2
|
271 sprite defb %11100111
|
nuclear@2
|
272 defb %10000001
|
nuclear@2
|
273 defb %11000011
|
nuclear@2
|
274 defb %10000001
|
nuclear@2
|
275 defb %00000000
|
nuclear@2
|
276 defb %00011000
|
nuclear@2
|
277 defb %00111100
|
nuclear@2
|
278 defb %01111110
|
nuclear@2
|
279
|
nuclear@0
|
280 end prog_test
|