|
|
@@ -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 |
|
|
|
|