Add blockdev doc
This commit is contained in:
parent
21eb64f751
commit
6c4489d2a3
@ -8,3 +8,4 @@ properly running.
|
||||
|
||||
* [The shell](shell.md)
|
||||
* [Load code in RAM and run it](load-run-code.md)
|
||||
* [Using block devices](blockdev.md)
|
||||
|
91
doc/blockdev.md
Normal file
91
doc/blockdev.md
Normal file
@ -0,0 +1,91 @@
|
||||
# Using block devices
|
||||
|
||||
The `blockdev.asm` part manage what we call "block devices", an abstraction over
|
||||
something that we can read a byte to, write a byte to and seek into (select at
|
||||
which offset we will read/write to next).
|
||||
|
||||
A Collapse OS system can define up to `0xff` devices. Those definitions are made
|
||||
in the glue code, so they are static.
|
||||
|
||||
Definition of block devices happen at include time. It would look like:
|
||||
|
||||
[...]
|
||||
BLOCKDEV_COUNT .equ 1
|
||||
#include "blockdev.asm"
|
||||
; List of devices
|
||||
.dw aciaGetC, aciaPutC, 0
|
||||
[...]
|
||||
|
||||
That tells `blockdev` that we're going to set up one device, that its GetC and
|
||||
PutC are the ones defined by `acia.asm` and that it has no Seek.
|
||||
|
||||
blockdev routines defined as zero are dummies (we don't actually call `0x0000`).
|
||||
|
||||
## Routine definitions
|
||||
|
||||
Parts that implement GetC, PutC and Seek do so in a loosely-coupled manner, but
|
||||
they should try to adhere to the convention, that is:
|
||||
|
||||
**GetC**: Get a character at current position, advance the position by 1, then
|
||||
return the fetched character in register `A`. If no input is
|
||||
available, block until it is (in other words, we always get a valid
|
||||
character).
|
||||
|
||||
**PutC**: The opposite of GetC. Write the character in `A` at current position
|
||||
and advance. If it can't write, block until it can.
|
||||
|
||||
**Seek**: Set current position (word) to value in register `HL`.
|
||||
|
||||
## Shell usage
|
||||
|
||||
`blockdev.asm` supplies 2 shell commands that you can graft to your shell thus:
|
||||
|
||||
[...]
|
||||
SHELL_EXTRA_CMD_COUNT .equ 2
|
||||
#include "shell.asm"
|
||||
; extra commands
|
||||
.dw blkBselCmd, blkSeekCmd
|
||||
[...]
|
||||
|
||||
### bsel
|
||||
|
||||
`bsel` select the active block device. For now, this only affects `load`. It
|
||||
receives one argument, the device index. `bsel 0` selects the first defined
|
||||
device, `bsel 1`, the second, etc. Error `0x04` when argument is out of bounds.
|
||||
|
||||
### seek
|
||||
|
||||
`seek` receives one word argument and sets the pointer for the currently active
|
||||
device to the specified address. Example: `seek 1234`.
|
||||
|
||||
The device position is device-specific: if you seek on a device, then switch
|
||||
to another device and seek again, your previous position isn't lost. You will
|
||||
still be on the same position when you come back.
|
||||
|
||||
### Example
|
||||
|
||||
Let's try an example: You glue yourself a Collapse OS with ACIA as its first
|
||||
device and a mmap starting at `0xd000` as your second device. Here's what you
|
||||
could do to copy memory around:
|
||||
|
||||
> mptr d000
|
||||
D000
|
||||
> load 4 [device 0 is selected initially]
|
||||
[enter "abcd"]
|
||||
> peek 4
|
||||
61626364
|
||||
> mptr c000
|
||||
C000
|
||||
> peek 4
|
||||
[RAM garbage]
|
||||
> bsel 1
|
||||
> load 4
|
||||
[returns immediately]
|
||||
> peek 4
|
||||
61626364
|
||||
> seek 0002
|
||||
> load 2
|
||||
> peek 4
|
||||
63646364
|
||||
|
||||
Awesome, right?
|
Loading…
Reference in New Issue
Block a user