collapseos/doc/blockdev.md

2.7 KiB

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?