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