zx_asmtest
diff test.asm @ 0:34ec0f897aa3
interrupt handler works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 19 Jan 2016 03:25:08 +0200 |
parents | |
children | f975431190f6 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test.asm Tue Jan 19 03:25:08 2016 +0200 1.3 @@ -0,0 +1,95 @@ 1.4 +org $8000 1.5 + 1.6 +fb_addr equ $4000 1.7 +attr_addr equ $5800 1.8 + 1.9 +prog_test: 1.10 + call setup_intr 1.11 + 1.12 + ld a, 2 1.13 + out (254), a 1.14 + 1.15 +drawloop: 1.16 + call clear_scr 1.17 + jp drawloop 1.18 + 1.19 +clear_scr: 1.20 + ld a, $ff 1.21 + ld hl, fb_addr 1.22 + ld b, 192 1.23 +_LY: ld c, 32 1.24 +_LX: ld (hl), a 1.25 + inc hl 1.26 + dec c 1.27 + jr nz, _LX 1.28 + dec b 1.29 + jr nz, _LY 1.30 + ret 1.31 + 1.32 +; ------ setup interrupt handler ------ 1.33 +; ok this needs explaining or I will forget it later... 1.34 +; in interrupt mode 2: 1.35 +; - I register has the IVT base address (high byte for the jump) 1.36 +; - data bus has the vector index (low byte for the jump) 1.37 +; (1) IVT must be 256-byte aligned (addr: xx00h) 1.38 +; also the IVT should not be in ULA-contended memory 1.39 +; (2) IVT should be above 4000h 1.40 +; also it would be a good idea to avoid putting the IVT somewhere which can be 1.41 +; paged out on 128k models 1.42 +; (3) IVT shouldn't extend beyond c000h (?) 1.43 +; finally, and this is the awesome bit, the data bus of the spectrum is 1.44 +; floating during the interrupt request... which leads us to 1.45 +; (4) we must populate the entire IVT with the same interrupt address 1.46 +; (5) we must use an interrupt address with identical low and high bytes 1.47 +; (6) we need 257 bytes for the IVT 1.48 +; 1.49 +; with those facts in mind the code below: 1.50 +; - uses BE00h to BF01h (inclusive) for the IVT 1.51 +; - a trampoline jump opcode is placed at BDBDh to jump to intr 1.52 +; - the address BDBDh is then populated throughout the IVT (bd, 257 times) 1.53 +; ------------------------------------- 1.54 + 1.55 +ivt_addr equ $be00 ; c000 - 512 (we need 257 bytes headroom) 1.56 +intr_tramp_addr equ $bdbd 1.57 +jp_opcode equ $c3 1.58 + 1.59 +setup_intr: 1.60 + di 1.61 + ld ix, ivt_addr 1.62 + push ix 1.63 + pop af ; a contains high byte of the ivt address 1.64 + ld i, a 1.65 + ld c, 0 1.66 + ld hl, intr_tramp_addr 1.67 + push hl 1.68 + pop af ; a contains high byte of the trampoline address 1.69 +_Livt: ld (ix), a 1.70 + inc ix 1.71 + dec c 1.72 + jr nz, _Livt 1.73 + ld (ix), a ; final odd high byte of the address 1.74 + ; at $bdbd setup the jump to our interrupt routine 1.75 + ld ix, $bdbd 1.76 + ld (ix), jp_opcode 1.77 + ld bc, intr 1.78 + ld (ix+1), c 1.79 + ld (ix+2), b 1.80 + ; done 1.81 + im 2 1.82 + ei 1.83 + ret 1.84 + 1.85 +intr: 1.86 + push af 1.87 + ld a, (border) 1.88 + inc a 1.89 + out (254), a 1.90 + ld (border), a 1.91 + pop af 1.92 + ei 1.93 + reti 1.94 + 1.95 +border defb 1 1.96 +nframe defw 0 1.97 + 1.98 +end prog_test