zx_asmtest

view 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 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 drawloop:
13 call clear_scr
14 jp drawloop
16 clear_scr:
17 ld a, $ff
18 ld hl, fb_addr
19 ld b, 192
20 _LY: ld c, 32
21 _LX: ld (hl), a
22 inc hl
23 dec c
24 jr nz, _LX
25 dec b
26 jr nz, _LY
27 ret
29 ; ------ setup interrupt handler ------
30 ; ok this needs explaining or I will forget it later...
31 ; in interrupt mode 2:
32 ; - I register has the IVT base address (high byte for the jump)
33 ; - data bus has the vector index (low byte for the jump)
34 ; (1) IVT must be 256-byte aligned (addr: xx00h)
35 ; also the IVT should not be in ULA-contended memory
36 ; (2) IVT should be above 4000h
37 ; also it would be a good idea to avoid putting the IVT somewhere which can be
38 ; paged out on 128k models
39 ; (3) IVT shouldn't extend beyond c000h (?)
40 ; finally, and this is the awesome bit, the data bus of the spectrum is
41 ; floating during the interrupt request... which leads us to
42 ; (4) we must populate the entire IVT with the same interrupt address
43 ; (5) we must use an interrupt address with identical low and high bytes
44 ; (6) we need 257 bytes for the IVT
45 ;
46 ; with those facts in mind the code below:
47 ; - uses BE00h to BF01h (inclusive) for the IVT
48 ; - a trampoline jump opcode is placed at BDBDh to jump to intr
49 ; - the address BDBDh is then populated throughout the IVT (bd, 257 times)
50 ; -------------------------------------
52 ivt_addr equ $be00 ; c000 - 512 (we need 257 bytes headroom)
53 intr_tramp_addr equ $bdbd
54 jp_opcode equ $c3
56 setup_intr:
57 di
58 ld ix, ivt_addr
59 push ix
60 pop af ; a contains high byte of the ivt address
61 ld i, a
62 ld c, 0
63 ld hl, intr_tramp_addr
64 push hl
65 pop af ; a contains high byte of the trampoline address
66 _Livt: ld (ix), a
67 inc ix
68 dec c
69 jr nz, _Livt
70 ld (ix), a ; final odd high byte of the address
71 ; at $bdbd setup the jump to our interrupt routine
72 ld ix, $bdbd
73 ld (ix), jp_opcode
74 ld bc, intr
75 ld (ix+1), c
76 ld (ix+2), b
77 ; done
78 im 2
79 ei
80 ret
82 intr:
83 push af
84 ld a, (border)
85 inc a
86 out (254), a
87 ld (border), a
88 pop af
89 ei
90 reti
92 border defb 1
93 nframe defw 0
95 end prog_test