collapseos/doc/blockdev.md

113 lines
3.5 KiB
Markdown
Raw Normal View History

2019-04-17 00:37:29 +10:00
# Using block devices
The `blockdev.asm` part manage what we call "block devices", an abstraction over
2019-10-05 02:05:05 +10:00
something that we can read a byte to, write a byte to, optionally at arbitrary
offsets.
2019-04-17 00:37:29 +10:00
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 sdcGetB, sdcPutB
2019-04-17 00:37:29 +10:00
[...]
That tells `blockdev` that we're going to set up one device, that its GetB and
PutB are the ones defined by `sdc.asm`.
2019-04-17 00:37:29 +10:00
2019-10-05 02:05:05 +10:00
If your block device is read-only or write-only, use dummy routines. `unsetZ`
2019-10-05 03:52:14 +10:00
is a good choice since it will return with the `Z` flag unset, indicating an
2019-10-05 02:05:05 +10:00
error (dummy methods aren't supposed to be called).
Each defined block device, in addition to its routine definition, holds a
seek pointer. This seek pointer is used in shell commands described below.
2019-04-17 00:37:29 +10:00
## Routine definitions
Parts that implement GetB and PutB do so in a loosely-coupled manner, but
2019-04-17 00:37:29 +10:00
they should try to adhere to the convention, that is:
**GetB**: Get the byte at position specified by `HL`. If it supports 32-bit
2019-10-05 02:05:05 +10:00
addressing, `DE` contains the high-order bytes. Return the result in
2019-10-05 03:52:14 +10:00
`A`. If there's an error (for example, address out of range), unset
`Z`. This routine is not expected to block. We expect the result to be
2019-10-05 02:05:05 +10:00
immediate.
2019-04-17 00:37:29 +10:00
**PutB**: The opposite of GetB. Write the character in `A` at specified
2019-10-05 03:52:14 +10:00
position. `Z` unset on error.
2019-10-05 02:05:05 +10:00
2019-04-17 00:37:29 +10:00
## Shell usage
2019-06-03 01:23:24 +10:00
`blockdev.asm` supplies 4 shell commands that you can graft to your shell thus:
2019-04-17 00:37:29 +10:00
[...]
2019-06-03 01:23:24 +10:00
SHELL_EXTRA_CMD_COUNT .equ 4
2019-04-17 00:37:29 +10:00
#include "shell.asm"
; extra commands
2019-06-03 01:23:24 +10:00
.dw blkBselCmd, blkSeekCmd, blkLoadCmd, blkSaveCmd
2019-04-17 00:37:29 +10:00
[...]
### bsel
2019-10-05 02:05:05 +10:00
`bsel` select the active block device. This specify a target for `load` and
`save`. Some applications also use the active blockdev. 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.
2019-04-17 00:37:29 +10:00
### 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.
2019-06-03 01:23:24 +10:00
### load
`load` works a bit like `poke` except that it reads its data from the currently
active blockdev at its current position. If it hits the end of the blockdev
before it could load its specified number of bytes, it stops. It only raises an
error if it couldn't load any byte.
2019-10-05 02:05:05 +10:00
It moves the device's position to the byte after the last loaded byte.
2019-06-03 01:23:24 +10:00
### save
`save` is the opposite of `load`. It writes the specified number of bytes from
memory to the active blockdev at its current position.
2019-10-05 02:05:05 +10:00
It moves the device's position to the byte after the last written byte.
2019-04-17 00:37:29 +10:00
### 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
2019-06-03 01:23:24 +10:00
> poke 4
2019-04-17 00:37:29 +10:00
[enter "abcd"]
> peek 4
61626364
> mptr c000
C000
> peek 4
[RAM garbage]
> bsel 1
> load 4
[returns immediately]
> peek 4
61626364
2019-06-03 01:23:24 +10:00
> seek 00 0002
2019-04-17 00:37:29 +10:00
> load 2
> peek 4
63646364
Awesome, right?