Add blockdev part
Also, add the ability for parts to define extra shell commands.
This commit is contained in:
parent
4600b5299c
commit
12c23f52e0
108
parts/blockdev.asm
Normal file
108
parts/blockdev.asm
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
; blockdev
|
||||||
|
;
|
||||||
|
; A block device is an abstraction over something we can read from, write to.
|
||||||
|
;
|
||||||
|
; A device that fits this abstraction puts the properly hook into itself, and
|
||||||
|
; then the glue code assigns a blockdev ID to that device. It then becomes easy
|
||||||
|
; to access arbitrary devices in a convenient manner.
|
||||||
|
;
|
||||||
|
; This part exposes a new "bsel" command to select the currently active block
|
||||||
|
; device.
|
||||||
|
|
||||||
|
; *** DEFINES ***
|
||||||
|
; BLOCKDEV_COUNT: The number of devices we manage.
|
||||||
|
|
||||||
|
; *** CONSTS ***
|
||||||
|
; *** VARIABLES ***
|
||||||
|
; A memory pointer to a device table. A device table is a list of addresses
|
||||||
|
; pointing to GetC and PutC 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
|
||||||
|
|
||||||
|
; *** CODE ***
|
||||||
|
; set DE to point to the table entry at index A.
|
||||||
|
blkFind:
|
||||||
|
ld de, BLOCKDEV_TBL
|
||||||
|
cp 0
|
||||||
|
ret z ; index is zero? don't loop
|
||||||
|
push bc
|
||||||
|
ld b, a
|
||||||
|
push af
|
||||||
|
ld a, 4
|
||||||
|
.loop:
|
||||||
|
call addDE
|
||||||
|
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:
|
||||||
|
call blkFind
|
||||||
|
inc de
|
||||||
|
inc de
|
||||||
|
call writeHLinDE
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Select block index specified in A
|
||||||
|
blkSel:
|
||||||
|
call blkFind
|
||||||
|
ld (BLOCKDEV_SELIDX), a
|
||||||
|
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
|
||||||
|
ret
|
||||||
|
|
||||||
|
blkBselCmd:
|
||||||
|
.db "bsel", 0b001, 0, 0
|
||||||
|
blkBsel:
|
||||||
|
ret
|
||||||
|
push af
|
||||||
|
ld a, (hl) ; argument supplied
|
||||||
|
cp BLOCKDEV_COUNT
|
||||||
|
ret nz ; if selection >= device count, don't do anything
|
||||||
|
; (will devise a unified cmd error system later)
|
||||||
|
call blkSel
|
||||||
|
pop af
|
||||||
|
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:
|
||||||
|
push ix
|
||||||
|
push de
|
||||||
|
ld de, (BLOCKDEV_GETC)
|
||||||
|
ld ixh, d
|
||||||
|
ld ixl, e
|
||||||
|
pop de
|
||||||
|
call callIX
|
||||||
|
pop ix
|
||||||
|
ret
|
||||||
|
|
||||||
|
blkPutC:
|
||||||
|
push ix
|
||||||
|
push de
|
||||||
|
ld de, (BLOCKDEV_PUTC)
|
||||||
|
ld ixh, d
|
||||||
|
ld ixl, e
|
||||||
|
pop de
|
||||||
|
call callIX
|
||||||
|
pop ix
|
||||||
|
ret
|
@ -41,6 +41,18 @@ addHL:
|
|||||||
ld l, a
|
ld l, a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Write the contents of HL in (DE)
|
||||||
|
writeHLinDE:
|
||||||
|
push af
|
||||||
|
ld a, l
|
||||||
|
ld (de), a
|
||||||
|
inc de
|
||||||
|
ld a, h
|
||||||
|
ld (de), a
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
; jump to the location pointed to by IX. This allows us to call IX instead of
|
; jump to the location pointed to by IX. This allows us to call IX instead of
|
||||||
; just jumping it. We use IX because we never use this for arguments.
|
; just jumping it. We use IX because we never use this for arguments.
|
||||||
callIX:
|
callIX:
|
||||||
|
@ -14,14 +14,17 @@
|
|||||||
; hexadecimal form, without prefix or suffix.
|
; hexadecimal form, without prefix or suffix.
|
||||||
|
|
||||||
; *** DEFINES ***
|
; *** DEFINES ***
|
||||||
; SHELL_GETC: Macro that calls a GetC routine
|
; SHELL_GETC: Macro that calls a GetC routine for tty interface
|
||||||
; SHELL_PUTC: Macro that calls a PutC routine
|
; SHELL_PUTC: Macro that calls a PutC routine for tty interface
|
||||||
|
; SHELL_IO_GETC: Macro that calls a GetC routine for I/O ("load" cmd)
|
||||||
|
; SHELL_EXTRA_CMD_COUNT: Number of extra cmds to be expected after the regular
|
||||||
|
; ones. See comment in COMMANDS section for details.
|
||||||
; SHELL_RAMSTART
|
; SHELL_RAMSTART
|
||||||
|
|
||||||
; *** CONSTS ***
|
; *** CONSTS ***
|
||||||
|
|
||||||
; number of entries in shellCmdTbl
|
; number of entries in shellCmdTbl
|
||||||
SHELL_CMD_COUNT .equ 4
|
SHELL_CMD_COUNT .equ 4+SHELL_EXTRA_CMD_COUNT
|
||||||
|
|
||||||
; maximum number of bytes to receive as args in all commands. Determines the
|
; maximum number of bytes to receive as args in all commands. Determines the
|
||||||
; size of the args variable.
|
; size of the args variable.
|
||||||
@ -144,6 +147,7 @@ shellParse:
|
|||||||
pop de
|
pop de
|
||||||
jr z, .found
|
jr z, .found
|
||||||
inc de
|
inc de
|
||||||
|
inc de
|
||||||
djnz .loop
|
djnz .loop
|
||||||
|
|
||||||
; exhausted loop? not found
|
; exhausted loop? not found
|
||||||
@ -313,7 +317,12 @@ shellParseArgs:
|
|||||||
;
|
;
|
||||||
; When these commands are called, HL points to the first byte of the
|
; When these commands are called, HL points to the first byte of the
|
||||||
; parsed command args.
|
; parsed command args.
|
||||||
|
;
|
||||||
|
; Extra commands: Other parts might define new commands. You can add these
|
||||||
|
; commands to your shell. First, set SHELL_EXTRA_CMD_COUNT to
|
||||||
|
; the number of extra commands to add, then add a ".dw"
|
||||||
|
; directive *just* after your '#include "shell.asm"'. Voila!
|
||||||
|
;
|
||||||
|
|
||||||
; Set memory pointer to the specified address (word).
|
; Set memory pointer to the specified address (word).
|
||||||
; Example: seek 01fe
|
; Example: seek 01fe
|
||||||
@ -388,9 +397,9 @@ shellPeek:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Load the specified number of bytes (max 0xff) from IO and write them in the
|
; Load the specified number of bytes (max 0xff) from IO and write them in the
|
||||||
; current memory pointer (which doesn't change). For now, we can only load from
|
; current memory pointer (which doesn't change). This gets chars from
|
||||||
; SHELL_GETC, but a method of selecting IO sources is coming, making this
|
; SHELL_IO_GETC, which can be different from SHELL_GETC. Coupled with the
|
||||||
; command much more useful.
|
; "blockdev" part, this allows you to dynamically select your IO source.
|
||||||
; Control is returned to the shell only after all bytes are read.
|
; Control is returned to the shell only after all bytes are read.
|
||||||
;
|
;
|
||||||
; Example: load 42
|
; Example: load 42
|
||||||
@ -404,7 +413,7 @@ shellLoad:
|
|||||||
ld a, (hl)
|
ld a, (hl)
|
||||||
ld b, a
|
ld b, a
|
||||||
ld hl, (SHELL_MEM_PTR)
|
ld hl, (SHELL_MEM_PTR)
|
||||||
.loop: SHELL_GETC
|
.loop: SHELL_IO_GETC
|
||||||
ld (hl), a
|
ld (hl), a
|
||||||
inc hl
|
inc hl
|
||||||
djnz .loop
|
djnz .loop
|
||||||
@ -455,6 +464,8 @@ shellCall:
|
|||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; This table is at the very end of the file on purpose. The idea is to be able
|
||||||
|
; to graft extra commands easily after an include in the glue file.
|
||||||
shellCmdTbl:
|
shellCmdTbl:
|
||||||
.dw shellSeekCmd, shellPeekCmd, shellLoadCmd, shellCallCmd
|
.dw shellSeekCmd, shellPeekCmd, shellLoadCmd, shellCallCmd
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user