diff --git a/parts/blockdev.asm b/parts/blockdev.asm index 0f12147..84f21b7 100644 --- a/parts/blockdev.asm +++ b/parts/blockdev.asm @@ -17,15 +17,13 @@ BLOCKDEV_ERR_OUT_OF_BOUNDS .equ 0x03 ; *** VARIABLES *** ; A memory pointer to a device table. A device table is a list of addresses -; pointing to GetC and PutC routines. +; pointing to GetC, PutC and Seek routines. BLOCKDEV_TBL .equ BLOCKDEV_RAMSTART -; Index of the current blockdev selection -BLOCKDEV_SELIDX .equ BLOCKDEV_TBL+(BLOCKDEV_COUNT*4) -; Address of the current GetC routine -BLOCKDEV_GETC .equ BLOCKDEV_SELIDX+1 -; Address of the current PutC routine -BLOCKDEV_PUTC .equ BLOCKDEV_GETC+2 -BLOCKDEV_RAMEND .equ BLOCKDEV_PUTC+2 +; Pointer to the selected block device. A block device is a 6 bytes block of +; memory with pointers to GetC, PutC and Seek routines, in that order. 0 means +; unsupported. +BLOCKDEV_SEL .equ BLOCKDEV_TBL+(BLOCKDEV_COUNT*2) +BLOCKDEV_RAMEND .equ BLOCKDEV_SEL+2 ; *** CODE *** ; set DE to point to the table entry at index A. @@ -35,41 +33,29 @@ blkFind: ret z ; index is zero? don't loop push bc ld b, a - push af - ld a, 4 .loop: - call addDE + inc de + inc de djnz .loop - pop af pop bc ret -; Set the GetC pointer of device id A to the value in HL -blkSetGetC: - call blkFind - call writeHLinDE - ret - -; Set the GetC pointer of device id A to the value in HL -blkSetPutC: +; Set the pointer of device id A to the value in HL +blkSet: call blkFind - inc de - inc de call writeHLinDE ret ; Select block index specified in A blkSel: + push de + push hl call blkFind - ld (BLOCKDEV_SELIDX), a + ld hl, BLOCKDEV_SEL ex hl, de - ; now, HL points to the table entry - ld de, BLOCKDEV_GETC - ldi ; copy (HL) into (BLOCKDEV_GETC) - ldi ; .. and into +1 - ld de, BLOCKDEV_PUTC - ldi ; same thing for (BLOCKDEV_PUTC) ldi + pop hl + pop de ret blkBselCmd: @@ -85,12 +71,23 @@ blkBsel: ld a, BLOCKDEV_ERR_OUT_OF_BOUNDS ret -; Reads one character from blockdev ID specified at A and returns its value -; in A. Always returns a character and waits until read if it has to. -blkGetC: +; In those routines below, IY is destroyed (we don't push it to the stack). We +; seldom use it anyways... + +; call routine in BLOCKDEV_SEL with offset IYL. +_blkCall: push ix push de - ld de, (BLOCKDEV_GETC) + ld de, (BLOCKDEV_SEL) + ; DE now points to the *address table*, not the routine addresses + ; themselves. One layer of indirection left. + ; slide by offset + push af + ld a, iyl + call addDE ; slide by offset + pop af + call intoDE + ; Alright, now de points to what we want to call ld ixh, d ld ixl, e pop de @@ -98,13 +95,17 @@ blkGetC: pop ix ret +; Reads one character from blockdev ID specified at A and returns its value +; in A. Always returns a character and waits until read if it has to. +blkGetC: + ld iyl, 0 + jr _blkCall + blkPutC: - push ix - push de - ld de, (BLOCKDEV_PUTC) - ld ixh, d - ld ixl, e - pop de - call callIX - pop ix - ret + ld iyl, 2 + jr _blkCall + +blkSeek: + ld iyl, 4 + jr _blkCall +