# 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, optionally at arbitrary offsets. 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 [...] That tells `blockdev` that we're going to set up one device, that its GetB and PutB are the ones defined by `sdc.asm`. If your block device is read-only or write-only, use dummy routines. `unsetZ` is a good choice since it will return with the `Z` flag unset, indicating an 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. ## Routine definitions Parts that implement GetB and PutB do so in a loosely-coupled manner, but they should try to adhere to the convention, that is: **GetB**: Get the byte at position specified by `HL`. If it supports 32-bit addressing, `DE` contains the high-order bytes. Return the result in `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 immediate. **PutB**: The opposite of GetB. Write the character in `A` at specified position. `Z` unset on error. ## Shell usage `apps/basic/blk.asm` supplies 4 shell commands that you can add to your shell. See "Optional Modules/blk" in [the shell doc](../apps/basic/README.md). ### Example Let's try an example: You glue yourself a Collapse OS with a mmap starting at `0xe000` as your 4th device (like it is in the shell emulator). Here's what you could do to copy memory around: > m=0xe000 > while m<0xe004 getc:poke m a:m=m+1 [enter "abcd"] > bsel 3 > i=0 > while i<4 getb:puth a:i=i+1 61626364> bseek 2 > getb:puth a 63> getb:puth a 64>