zx_asmtest

view test.asm @ 2:f975431190f6

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