zx_asmtest
changeset 0:34ec0f897aa3
interrupt handler works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 19 Jan 2016 03:25:08 +0200 |
parents | |
children | 04fc17db12e6 |
files | Makefile test.asm |
diffstat | 2 files changed, 105 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Makefile Tue Jan 19 03:25:08 2016 +0200 1.3 @@ -0,0 +1,10 @@ 1.4 +tap = test.tap 1.5 + 1.6 +ASFLAGS = --alocal 1.7 + 1.8 +$(tap): test.asm 1.9 + pasmo $(ASFLAGS) --tapbas $< $@ 1.10 + 1.11 +.PHONY: run 1.12 +run: $(tap) 1.13 + fuse-sdl $(tap)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test.asm Tue Jan 19 03:25:08 2016 +0200 2.3 @@ -0,0 +1,95 @@ 2.4 +org $8000 2.5 + 2.6 +fb_addr equ $4000 2.7 +attr_addr equ $5800 2.8 + 2.9 +prog_test: 2.10 + call setup_intr 2.11 + 2.12 + ld a, 2 2.13 + out (254), a 2.14 + 2.15 +drawloop: 2.16 + call clear_scr 2.17 + jp drawloop 2.18 + 2.19 +clear_scr: 2.20 + ld a, $ff 2.21 + ld hl, fb_addr 2.22 + ld b, 192 2.23 +_LY: ld c, 32 2.24 +_LX: ld (hl), a 2.25 + inc hl 2.26 + dec c 2.27 + jr nz, _LX 2.28 + dec b 2.29 + jr nz, _LY 2.30 + ret 2.31 + 2.32 +; ------ setup interrupt handler ------ 2.33 +; ok this needs explaining or I will forget it later... 2.34 +; in interrupt mode 2: 2.35 +; - I register has the IVT base address (high byte for the jump) 2.36 +; - data bus has the vector index (low byte for the jump) 2.37 +; (1) IVT must be 256-byte aligned (addr: xx00h) 2.38 +; also the IVT should not be in ULA-contended memory 2.39 +; (2) IVT should be above 4000h 2.40 +; also it would be a good idea to avoid putting the IVT somewhere which can be 2.41 +; paged out on 128k models 2.42 +; (3) IVT shouldn't extend beyond c000h (?) 2.43 +; finally, and this is the awesome bit, the data bus of the spectrum is 2.44 +; floating during the interrupt request... which leads us to 2.45 +; (4) we must populate the entire IVT with the same interrupt address 2.46 +; (5) we must use an interrupt address with identical low and high bytes 2.47 +; (6) we need 257 bytes for the IVT 2.48 +; 2.49 +; with those facts in mind the code below: 2.50 +; - uses BE00h to BF01h (inclusive) for the IVT 2.51 +; - a trampoline jump opcode is placed at BDBDh to jump to intr 2.52 +; - the address BDBDh is then populated throughout the IVT (bd, 257 times) 2.53 +; ------------------------------------- 2.54 + 2.55 +ivt_addr equ $be00 ; c000 - 512 (we need 257 bytes headroom) 2.56 +intr_tramp_addr equ $bdbd 2.57 +jp_opcode equ $c3 2.58 + 2.59 +setup_intr: 2.60 + di 2.61 + ld ix, ivt_addr 2.62 + push ix 2.63 + pop af ; a contains high byte of the ivt address 2.64 + ld i, a 2.65 + ld c, 0 2.66 + ld hl, intr_tramp_addr 2.67 + push hl 2.68 + pop af ; a contains high byte of the trampoline address 2.69 +_Livt: ld (ix), a 2.70 + inc ix 2.71 + dec c 2.72 + jr nz, _Livt 2.73 + ld (ix), a ; final odd high byte of the address 2.74 + ; at $bdbd setup the jump to our interrupt routine 2.75 + ld ix, $bdbd 2.76 + ld (ix), jp_opcode 2.77 + ld bc, intr 2.78 + ld (ix+1), c 2.79 + ld (ix+2), b 2.80 + ; done 2.81 + im 2 2.82 + ei 2.83 + ret 2.84 + 2.85 +intr: 2.86 + push af 2.87 + ld a, (border) 2.88 + inc a 2.89 + out (254), a 2.90 + ld (border), a 2.91 + pop af 2.92 + ei 2.93 + reti 2.94 + 2.95 +border defb 1 2.96 +nframe defw 0 2.97 + 2.98 +end prog_test