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