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