1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 05:38:05 +11:00

Compare commits

..

No commits in common. "1f26879cd33b8a9e3fd1ca424ccf50135c7bd303" and "38333e9e0764c10097aec93b85ad6a1c9e9393df" have entirely different histories.

36 changed files with 279 additions and 317 deletions

View File

@ -1,2 +0,0 @@
language: c
script: ./runtests.sh

View File

@ -1,15 +0,0 @@
This file describe tricks that are used throughout the code and might need
explanation.
or a: Equivalent to "cp 0", but results in a shorter opcode.
xor a: sets A to 0 more efficiently than ld a, 0
and 0xbf: Given a letter in the a-z range, changes it to its uppercase value
if it's already uppercased, then it stays that way.
Z if almost always used as a success indicator for routines. Set for success,
Reset for failure. "xor a" (destroys A) and "cp a" (preserves A) are used to
ensure Z is set. To ensure that it is reset, it's a bit more complicated and
"unsetZ" routine exists for that, although that in certain circumstances,
"inc a \ dec a" or "or a" can work.

View File

@ -9,7 +9,7 @@
; is reached on the block device.
; *** Requirements ***
; blkGetB
; blkGetC
; parseArgs
;
; *** Includes ***

View File

@ -7,7 +7,7 @@
; *** Variables ***
.equ AT28W_MAXBYTES AT28W_RAMSTART
.equ AT28W_RAMEND @+2
.equ AT28W_RAMEND AT28W_MAXBYTES+2
; *** Code ***
at28wMain:
@ -33,7 +33,7 @@ at28wInner:
; BC is zero, default to 0x2000 (8k, the size of the AT28)
ld bc, 0x2000
.loop:
call blkGetB
call blkGetC
jr nz, .loopend
ld (hl), a
ld e, a ; save expected data for verification

View File

@ -4,14 +4,14 @@
; Number of lines currently in the buffer
.equ BUF_LINECNT BUF_RAMSTART
; List of pointers to strings in scratchpad
.equ BUF_LINES @+2
.equ BUF_LINES BUF_LINECNT+2
; Points to the end of the scratchpad, that is, one byte after the last written
; char in it.
.equ BUF_PADEND @+ED_BUF_MAXLINES*2
.equ BUF_PADEND BUF_LINES+ED_BUF_MAXLINES*2
; The in-memory scratchpad
.equ BUF_PAD @+2
.equ BUF_PAD BUF_PADEND+2
.equ BUF_RAMEND @+ED_BUF_PADMAXLEN
.equ BUF_RAMEND BUF_PAD+ED_BUF_PADMAXLEN
; *** Code ***
@ -25,7 +25,7 @@ bufInit:
; init pad end in case we have an empty file.
ld (BUF_PADEND), hl
.loop:
call ioGetB
call ioGetC
jr nz, .loopend
or a ; null? hum, weird. same as LF
jr z, .lineend

View File

@ -13,9 +13,9 @@
; An address is a one byte type and a two bytes line number (0-indexed)
.equ CMD_ADDR1 CMD_RAMSTART
.equ CMD_ADDR2 @+3
.equ CMD_TYPE @+3
.equ CMD_RAMEND @+1
.equ CMD_ADDR2 CMD_ADDR1+3
.equ CMD_TYPE CMD_ADDR2+3
.equ CMD_RAMEND CMD_TYPE+1
; *** Code ***

View File

@ -9,10 +9,10 @@
; Handle of the target file
.equ IO_FILE_HDL IO_RAMSTART
; block device targeting IO_FILE_HDL
.equ IO_BLK @+FS_HANDLE_SIZE
.equ IO_BLK IO_FILE_HDL+FS_HANDLE_SIZE
; Buffer for lines read from I/O.
.equ IO_LINE @+BLOCKDEV_SIZE
.equ IO_RAMEND @+IO_MAXLEN+1 ; +1 for null
.equ IO_LINE IO_BLK+BLOCKDEV_SIZE
.equ IO_RAMEND IO_LINE+IO_MAXLEN+1 ; +1 for null
; *** Code ***
; Given a file name in (HL), open that file in (IO_FILE_HDL) and open a blkdev
@ -25,26 +25,26 @@ ioInit:
ld de, IO_BLK
ld hl, .blkdev
jp blkSet
.fsGetB:
.fsGetC:
ld ix, IO_FILE_HDL
jp fsGetB
.fsPutB:
jp fsGetC
.fsPutC:
ld ix, IO_FILE_HDL
jp fsPutB
jp fsPutC
.blkdev:
.dw .fsGetB, .fsPutB
.dw .fsGetC, .fsPutC
ioGetB:
ioGetC:
push ix
ld ix, IO_BLK
call _blkGetB
call _blkGetC
pop ix
ret
ioPutB:
ioPutC:
push ix
ld ix, IO_BLK
call _blkPutB
call _blkPutC
pop ix
ret
@ -76,14 +76,14 @@ ioPutLine:
ld a, (hl)
or a
jr z, .loopend ; null, we're finished
call ioPutB
call ioPutC
jr nz, .error
inc hl
jr .loop
.loopend:
; Wrote the whole line, write ending LF
ld a, 0x0a
call ioPutB
call ioPutC
jr z, .end ; success
; continue to error
.error:

View File

@ -25,16 +25,16 @@
; *** Requirements ***
; BLOCKDEV_SIZE
; FS_HANDLE_SIZE
; _blkGetB
; _blkPutB
; _blkGetC
; _blkPutC
; _blkSeek
; _blkTell
; addHL
; cpHLDE
; fsFindFN
; fsOpen
; fsGetB
; fsPutB
; fsGetC
; fsPutC
; fsSetSize
; intoHL
; printstr
@ -46,7 +46,7 @@
; *** Variables ***
;
.equ ED_CURLINE ED_RAMSTART
.equ ED_RAMEND @+2
.equ ED_RAMEND ED_CURLINE+2
edMain:
; because ed only takes a single string arg, we can use HL directly

View File

@ -4,15 +4,15 @@
; sectors. Collapse OS doesn't have a random number generator, so we'll simply
; rely on initial SRAM value, which tend is random enough for our purpose.
;
; How it works is simple. From its designated RAMSTART, it calls PutB until it
; How it works is simple. From its designated RAMSTART, it calls PutC until it
; reaches the end of RAM (0xffff). Then, it starts over and this time it reads
; every byte and compares.
;
; If there's an error, prints out where.
;
; *** Requirements ***
; sdcPutB
; sdcGetB
; sdcPutC
; sdcGetC
; printstr
; printHexPair
;

View File

@ -9,7 +9,7 @@ sdctMain:
; we set DE to 12 instead of zero
push de ; <|
ld de, 12 ; |
call sdcPutB ; |
call sdcPutC ; |
pop de ; <|
jr nz, .error
inc hl
@ -30,7 +30,7 @@ sdctMain:
.rLoop:
push de ; <|
ld de, 12 ; |
call sdcGetB ; |
call sdcGetC ; |
pop de ; <|
jr nz, .error
ex de, hl

View File

@ -54,7 +54,7 @@ handleDB:
or a ; cp 0
jr nz, .overflow ; not zero? overflow
ld a, l
call ioPutB
call ioPutC
jr nz, .ioError
.stopStrLit:
call readComma
@ -84,7 +84,7 @@ handleDB:
or a ; when we encounter 0, that was what used to
jr z, .stopStrLit ; be our closing quote. Stop.
; Normal character, output
call ioPutB
call ioPutC
jr nz, .ioError
jr .stringLiteral
@ -98,10 +98,10 @@ handleDW:
jr nz, .badarg
push ix \ pop hl
ld a, l
call ioPutB
call ioPutC
jr nz, .ioError
ld a, h
call ioPutB
call ioPutC
jr nz, .ioError
call readComma
jr z, .loop
@ -208,7 +208,7 @@ handleFIL:
or c
jr z, .loopend
xor a
call ioPutB
call ioPutC
jr nz, .ioError
dec bc
jr .loop
@ -314,7 +314,7 @@ getDirectiveID:
; Parse directive specified in A (D_* const) with args in I/O and act in
; an appropriate manner. If the directive results in writing data at its
; current location, that data is directly written through ioPutB.
; current location, that data is directly written through ioPutC.
; Each directive has the same return value pattern: Z on success, not-Z on
; error, A contains the error number (ERR_*).
parseDirective:

View File

@ -5,9 +5,9 @@
;
; We don't buffer the whole source in memory, so we need our input blkdev to
; support Seek so we can read the file a second time. So, for input, we need
; GetB and Seek.
; GetC and Seek.
;
; For output, we only need PutB. Output doesn't start until the second pass.
; For output, we only need PutC. Output doesn't start until the second pass.
;
; The goal of the second pass is to assign values to all symbols so that we
; can have forward references (instructions referencing a label that happens
@ -33,11 +33,11 @@
; blkSet
; fsFindFN
; fsOpen
; fsGetB
; fsGetC
; cpHLDE
; parseArgs
; _blkGetB
; _blkPutB
; _blkGetC
; _blkPutC
; _blkSeek
; _blkTell
; printstr

View File

@ -888,7 +888,7 @@ parseInstruction:
ld hl, INS_UPCODE
.loopWrite:
ld a, (hl)
call ioPutB
call ioPutC
jr nz, .ioError
inc hl
djnz .loopWrite

View File

@ -8,7 +8,7 @@
; maintaining IO_PC and of properly disabling output on first pass.
;
; On top of that, this unit has the responsibility of keeping track of the
; current lineno. Whenever GetB is called, we check if the fetched byte is a
; current lineno. Whenever GetC is called, we check if the fetched char is a
; newline. If it is, we increase our lineno. This unit is the best place to
; keep track of this because we have to handle ioRecallPos.
;
@ -17,7 +17,7 @@
; mechanism, that is, a way to say "you see that character I've just read? that
; was out of my bounds. Could you make it as if I had never read it?". That
; buffer is one character big and is made with the expectation that ioPutBack
; is always called right after a ioGetB (when it's called).
; is always called right after a ioGetC (when it's called).
;
; ioPutBack will mess up seek and tell offsets, so thath "put back" should be
; consumed before having to seek and tell.
@ -25,7 +25,7 @@
; That's for the general rules.
;
; Now, let's enter includes. To simplify processing, we make include mostly
; transparent to all other units. They always read from ioGetB and a include
; transparent to all other units. They always read from ioGetC and a include
; directive should have the exact same effect as copy/pasting the contents of
; the included file in the caller.
;
@ -33,7 +33,7 @@
; can include.
;
; When we include, all we do here is open the file with fsOpen and set a flag
; indicating that we're inside an include. When that flag is on, GetB, Seek and
; indicating that we're inside an include. When that flag is on, GetC, Seek and
; Tell are transparently redirected to their fs* counterpart.
;
; When we reach EOF in an included file, we transparently unset the "in include"
@ -73,7 +73,7 @@ ioInit:
call blkSet
jp ioResetCounters
ioGetB:
ioGetC:
ld a, (IO_PUTBACK_BUF)
or a ; cp 0
jr nz, .getback
@ -81,7 +81,7 @@ ioGetB:
jr z, .normalmode
; We're in "include mode", read from FS
ld ix, IO_INCLUDE_BLK
call _blkGetB
call _blkGetC
jr nz, .includeEOF
cp 0x0a ; newline
ret nz ; not newline? nothing to do
@ -111,7 +111,7 @@ ioGetB:
.normalmode:
; normal mode, read from IN stream
ld ix, IO_IN_BLK
call _blkGetB
call _blkGetC
cp 0x0a ; newline
ret nz ; not newline? return
; inc current lineno
@ -133,14 +133,14 @@ _callIX:
jp (ix)
ret
; Put back non-zero character A into the "ioGetB stack". The next ioGetB call,
; Put back non-zero character A into the "ioGetC stack". The next ioGetC call,
; instead of reading from IO_IN_BLK, will return that character. That's the
; easiest way I found to handle the readWord/gotoNextLine problem.
ioPutBack:
ld (IO_PUTBACK_BUF), a
ret
ioPutB:
ioPutC:
push hl
ld hl, (IO_PC)
inc hl
@ -151,7 +151,7 @@ ioPutB:
jr z, .skip
pop af
ld ix, IO_OUT_BLK
jp _blkPutB
jp _blkPutC
.skip:
pop af
cp a ; ensure Z
@ -240,7 +240,7 @@ ioOpenInclude:
cp a ; ensure Z
ret
; Open file specified in (HL) and spit its contents through ioPutB
; Open file specified in (HL) and spit its contents through ioPutC
; Sets Z on success.
ioSpitBin:
call fsFindFN
@ -251,9 +251,9 @@ ioSpitBin:
ld hl, 0
.loop:
ld ix, IO_BIN_HDL
call fsGetB
call fsGetC
jr nz, .loopend
call ioPutB
call ioPutC
inc hl
jr .loop
.loopend:
@ -274,12 +274,12 @@ ioLineNo:
pop af
ret
_ioIncGetB:
_ioIncGetC:
ld ix, IO_INCLUDE_HDL
jp fsGetB
jp fsGetC
_ioIncBlk:
.dw _ioIncGetB, unsetZ
.dw _ioIncGetC, unsetZ
; call printstr followed by newline
ioPrintLN:

View File

@ -128,7 +128,7 @@ zasmParseFile:
ret
; Parse next token and accompanying args (when relevant) in I/O, write the
; resulting opcode(s) through ioPutB and increases (IO_PC) by the number of
; resulting opcode(s) through ioPutC and increases (IO_PC) by the number of
; bytes written. BC is set to the result of the call to tokenize.
; Sets Z if parse was successful, unset if there was an error. EOF is not an
; error. If there is an error, A is set to the corresponding error code (ERR_*).

View File

@ -74,12 +74,12 @@ isLabel:
; Read I/O as long as it's whitespace. When it's not, stop and return the last
; read char in A
_eatWhitespace:
call ioGetB
call ioGetC
call isSep
ret nz
jr _eatWhitespace
; Read ioGetB until a word starts, then read ioGetB as long as there is no
; Read ioGetC until a word starts, then read ioGetC as long as there is no
; separator and put that contents in (scratchpad), null terminated, for a
; maximum of SCRATCHPAD_SIZE-1 characters.
; If EOL (\n, \r or comment) or EOF is hit before we could read a word, we stop
@ -104,7 +104,7 @@ readWord:
.loop:
ld (hl), a
inc hl
call ioGetB
call ioGetC
call isSepOrLineEnd
jr z, .success
cp ','
@ -130,7 +130,7 @@ readWord:
; inside quotes, we accept literal whitespaces, but not line ends.
ld (hl), a
inc hl
call ioGetB
call ioGetC
cp '"'
jr z, .loop ; ending the quote ends the word
call isLineEnd
@ -143,12 +143,12 @@ readWord:
; single quote is more straightforward: we have 3 chars and we put them
; right in scratchpad
ld (hl), a
call ioGetB
call ioGetC
or a
jr z, .error
inc hl
ld (hl), a
call ioGetB
call ioGetC
cp 0x27 ; '
jr nz, .error
inc hl
@ -165,7 +165,7 @@ readComma:
call unsetZ
ret
; Read ioGetB until we reach the beginning of next line, skipping comments if
; Read ioGetC until we reach the beginning of next line, skipping comments if
; necessary. This skips all whitespace, \n, \r, comments until we reach the
; first non-comment character. Then, we put it back (ioPutBack) and return.
;
@ -176,7 +176,7 @@ readComma:
gotoNextLine:
.loop1:
; first loop is "strict", that is: we error out on non-whitespace.
call ioGetB
call ioGetC
call isSepOrLineEnd
ret nz ; error
or a ; cp 0
@ -189,7 +189,7 @@ gotoNextLine:
.loop2:
; second loop is the "comment loop": anything is valid and we just run
; until EOL.
call ioGetB
call ioGetC
or a ; cp 0
jr z, .eof
cp '\' ; special case: '\' doesn't count as a line end
@ -201,7 +201,7 @@ gotoNextLine:
.loop3:
; Loop 3 happens after we reach our first line sep. This means that we
; wade through whitespace until we reach a non-whitespace character.
call ioGetB
call ioGetC
or a ; cp 0
jr z, .eof
cp 0x3b ; ';'

View File

@ -13,11 +13,11 @@ 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
.dw aciaGetC, aciaPutC
[...]
That tells `blockdev` that we're going to set up one device, that its GetB and
PutB are the ones defined by `sdc.asm`.
That tells `blockdev` that we're going to set up one device, that its GetC and
PutC are the ones defined by `acia.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
@ -28,16 +28,16 @@ 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
Parts that implement GetC and PutC 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
**GetC**: Get the character 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
**PutC**: The opposite of GetC. Write the character in `A` at specified
position. `Z` unset on error.
## Shell usage

View File

@ -2,34 +2,34 @@
;
; A block device is an abstraction over something we can read from, write to.
;
; A device that fits this abstraction puts the proper 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.
; 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 module exposes a seek/tell/getb/putb API that is then re-routed to
; This module exposes a seek/tell/getc/putc API that is then re-routed to
; underlying drivers. There will eventually be more than one driver type, but
; for now we sit on only one type of driver: random access driver.
;
; *** Random access drivers ***
;
; Random access drivers are expected to supply two routines: GetB and PutB.
; Random access drivers are expected to supply two routines: GetC and PutC.
;
; GetB:
; Reads one byte at address specified in DE/HL and returns its value in A.
; GetC:
; Reads one character at address specified in DE/HL and returns its value in A.
; Sets Z according to whether read was successful: Set if successful, unset
; if not.
;
; Unsuccessful reads generally mean that requested addr is out of bounds (we
; reached EOF).
;
; PutB:
; Writes byte in A at address specified in DE/HL. Sets Z according to whether
; the operation was successful.
; PutC:
; Writes character in A at address specified in DE/HL. Sets Z according to
; whether the operation was successful.
;
; Unsuccessful writes generally mean that we're out of bounds for writing.
;
; All routines are expected to preserve unused registers except IX which is
; explicitly protected during GetB/PutB calls. This makes quick "handle+jump"
; explicitly protected during GetC/PutC calls. This makes quick "handle+jump"
; definitions possible.
@ -46,9 +46,9 @@
.equ BLOCKDEV_SIZE 8
; *** VARIABLES ***
; Pointer to the selected block device. A block device is a 8 bytes block of
; memory with pointers to GetB, PutB, and a 32-bit counter, in that order.
; memory with pointers to GetC, PutC, and a 32-bit counter, in that order.
.equ BLOCKDEV_SEL BLOCKDEV_RAMSTART
.equ BLOCKDEV_RAMEND @+BLOCKDEV_SIZE
.equ BLOCKDEV_RAMEND BLOCKDEV_SEL+BLOCKDEV_SIZE
; *** CODE ***
; Select block index specified in A and place them in routine pointers at (DE).
@ -121,16 +121,16 @@ _blkInc:
pop af
ret
; Reads one byte from selected device and returns its value in A.
; Reads one character from selected device and returns its value in A.
; Sets Z according to whether read was successful: Set if successful, unset
; if not.
blkGetB:
blkGetC:
push ix
ld ix, BLOCKDEV_SEL
call _blkGetB
call _blkGetC
pop ix
ret
_blkGetB:
_blkGetC:
push hl
push de
call _blkTell
@ -139,20 +139,20 @@ _blkGetB:
pop hl
jr _blkInc ; advance and return
; Writes byte in A in current position in the selected device. Sets Z according
; to whether the operation was successful.
blkPutB:
; Writes character in A in current position in the selected device. Sets Z
; according to whether the operation was successful.
blkPutC:
push ix
ld ix, BLOCKDEV_SEL
call _blkPutB
call _blkPutC
pop ix
ret
_blkPutB:
_blkPutC:
push ix
push hl
push de
call _blkTell
inc ix ; make IX point to PutB
inc ix ; make IX point to PutC
inc ix
call callIXI
pop de
@ -160,7 +160,7 @@ _blkPutB:
pop ix
jr _blkInc ; advance and return
; Reads B chars from blkGetB and copy them in (HL).
; Reads B chars from blkGetC and copy them in (HL).
; Sets Z if successful, unset Z if there was an error.
blkRead:
push ix
@ -172,7 +172,7 @@ _blkRead:
push hl
push bc
.loop:
call _blkGetB
call _blkGetC
jr nz, .end ; Z already unset
ld (hl), a
inc hl
@ -183,7 +183,7 @@ _blkRead:
pop hl
ret
; Writes B chars to blkPutB from (HL).
; Writes B chars to blkPutC from (HL).
; Sets Z if successful, unset Z if there was an error.
blkWrite:
push ix
@ -196,7 +196,7 @@ _blkWrite:
push bc
.loop:
ld a, (hl)
call _blkPutB
call _blkPutC
jr nz, .end ; Z already unset
inc hl
djnz .loop
@ -217,11 +217,11 @@ _blkWrite:
; (high). DE is only used for mode 0.
;
; When seeking to an out-of-bounds position, the resulting position will be
; one position ahead of the last valid position. Therefore, GetB after a seek
; one position ahead of the last valid position. Therefore, GetC after a seek
; to end would always fail.
;
; If the device is "growable", it's possible that seeking to end when calling
; PutB doesn't necessarily result in a failure.
; PutC doesn't necessarily result in a failure.
blkSeek:
push ix
ld ix, BLOCKDEV_SEL
@ -309,6 +309,6 @@ _blkTell:
; This label is at the end of the file on purpose: the glue file should include
; a list of device routine table entries just after the include. Each line
; has 2 word addresses: GetB and PutB. An entry could look like:
; .dw mmapGetB, mmapPutB
; has 4 word addresses: GetC, PutC and Seek, Tell. An entry could look like:
; .dw mmapGetC, mmapPutC, mmapSeek, mmapTell
blkDevTbl:

View File

@ -50,7 +50,7 @@ blkSeekCmd:
; stop loading.
;
; Returns a SHELL_ERR_IO_ERROR only if we couldn't read any byte (if the first
; call to GetB failed)
; call to GetC failed)
;
; Example: load 42
blkLoadCmd:
@ -62,12 +62,12 @@ blkLoad:
ld a, (hl)
ld b, a
ld hl, (SHELL_MEM_PTR)
call blkGetB
call blkGetC
jr nz, .ioError
jr .intoLoop ; we'v already called blkGetB. don't call it
jr .intoLoop ; we'v already called blkGetC. don't call it
; again.
.loop:
call blkGetB
call blkGetC
.intoLoop:
ld (hl), a
inc hl
@ -86,7 +86,7 @@ blkLoad:
; Load the specified number of bytes (max 0x100, 0 means 0x100) from the current
; memory pointer and write them to I/O. Memory pointer doesn't move. This puts
; chars to blkPutB. Raises error if not all bytes could be written.
; chars to blkPutC. Raises error if not all bytes could be written.
;
; Example: save 42
blkSaveCmd:
@ -101,7 +101,7 @@ blkSave:
.loop:
ld a, (hl)
inc hl
call blkPutB
call blkPutC
jr nz, .ioError
djnz .loop
.loopend:

View File

@ -9,6 +9,6 @@
.equ BLOCKDEV_ERR_OUT_OF_BOUNDS 0x03
.equ BLOCKDEV_ERR_UNSUPPORTED 0x04
; IO routines (GetB, PutB) returned an error in a load/save command
; IO routines (GetC, PutC) returned an error in a load/save command
.equ SHELL_ERR_IO_ERROR 0x05

View File

@ -3,7 +3,7 @@
; Collapse OS filesystem (CFS) is not made to be convenient, but to be simple.
; This is little more than "named storage blocks". Characteristics:
;
; * a filesystem sits upon a blockdev. It needs GetB, PutB, Seek.
; * a filesystem sits upon a blockdev. It needs GetC, PutC, Seek.
; * No directory. Use filename prefix to group.
; * First block of each file has metadata. Others are raw data.
; * No FAT. Files are a chain of blocks of a predefined size. To enumerate
@ -98,12 +98,12 @@
; This pointer is 32 bits. 32 bits pointers are a bit awkward: first two bytes
; are high bytes *low byte first*, and then the low two bytes, same order.
; When loaded in HL/DE, the four bytes are loaded in this order: E, D, L, H
.equ FS_START @+BLOCKDEV_SIZE
.equ FS_START FS_BLK+BLOCKDEV_SIZE
; This variable below contain the metadata of the last block we moved
; to. We read this data in memory to avoid constant seek+read operations.
.equ FS_META @+4
.equ FS_HANDLES @+FS_METASIZE
.equ FS_RAMEND @+FS_HANDLE_COUNT*FS_HANDLE_SIZE
.equ FS_META FS_START+4
.equ FS_HANDLES FS_META+FS_METASIZE
.equ FS_RAMEND FS_HANDLES+FS_HANDLE_COUNT*FS_HANDLE_SIZE
; *** DATA ***
P_FS_MAGIC:
@ -333,10 +333,10 @@ fsIsDeleted:
; we can still access the FS even if blkdev selection changes. These routines
; below mimic blkdev's methods, but for our private mount.
fsblkGetB:
fsblkGetC:
push ix
ld ix, FS_BLK
call _blkGetB
call _blkGetC
pop ix
ret
@ -347,10 +347,10 @@ fsblkRead:
pop ix
ret
fsblkPutB:
fsblkPutC:
push ix
ld ix, FS_BLK
call _blkPutB
call _blkPutC
pop ix
ret
@ -458,27 +458,27 @@ fsSetSize:
; cache.
ld a, l
ld (ix+4), a
call fsblkPutB
call fsblkPutC
ld a, h
ld (ix+5), a
call fsblkPutB
call fsblkPutC
pop hl ; <-- lvl 1
xor a ; ensure Z
ret
; Read a byte in handle at (IX) at position HL and put it into A.
; Z is set on success, unset if handle is at the end of the file.
fsGetB:
fsGetC:
call fsWithinBounds
jr z, .proceed
; We want to unset Z, but also return 0 to ensure that a GetB that
; We want to unset Z, but also return 0 to ensure that a GetC that
; doesn't check Z doesn't end up with false data.
xor a
jp unsetZ ; returns
.proceed:
push hl
call fsPlaceH
call fsblkGetB
call fsblkGetC
cp a ; ensure Z
pop hl
ret
@ -486,10 +486,10 @@ fsGetB:
; Write byte A in handle (IX) at position HL.
; Z is set on success, unset if handle is at the end of the file.
; TODO: detect end of block alloc
fsPutB:
fsPutC:
push hl
call fsPlaceH
call fsblkPutB
call fsblkPutC
pop hl
; if HL is out of bounds, increase bounds
call fsWithinBounds

View File

@ -24,7 +24,7 @@ _mmapAddr:
pop de
jp unsetZ
mmapGetB:
mmapGetC:
push hl
call _mmapAddr
jr nz, .end
@ -35,7 +35,7 @@ mmapGetB:
ret
mmapPutB:
mmapPutC:
push hl
call _mmapAddr
jr nz, .end

View File

@ -16,7 +16,7 @@
;
; *** Variables ***
.equ PGM_HANDLE PGM_RAMSTART
.equ PGM_RAMEND @+FS_HANDLE_SIZE
.equ PGM_RAMEND PGM_HANDLE+FS_HANDLE_SIZE
; Routine suitable to plug into SHELL_CMDHOOK. HL points to the full cmdline.
; which has been processed to replace the first ' ' with a null char.
@ -48,7 +48,7 @@ pgmRun:
ld hl, 0 ; addr that we read in file handle
ld de, PGM_CODEADDR ; addr in mem we write to
.loop:
call fsGetB ; we use Z at end of loop
call fsGetC ; we use Z at end of loop
ld (de), a ; Z preserved
inc hl ; Z preserved in 16-bit
inc de ; Z preserved in 16-bit

View File

@ -20,14 +20,14 @@
;
; SD card's lowest common denominator in terms of block size is 512 bytes, so
; that's what we deal with. To avoid wastefully reading entire blocks from the
; card for one byte read ops, we buffer the last read block. If a GetB or PutB
; card for one byte read ops, we buffer the last read block. If a GetC or PutC
; operation is within that buffer, then no interaction with the SD card is
; necessary.
;
; As soon as a GetB or PutB operation is made that is outside the current
; As soon as a GetC or PutC operation is made that is outside the current
; buffer, we load a new block.
;
; When we PutB, we flag the buffer as "dirty". On the next buffer change (during
; When we PutC, we flag the buffer as "dirty". On the next buffer change (during
; an out-of-buffer request or during an explicit "flush" operation), bytes
; currently in the buffer will be written to the SD card.
;
@ -37,10 +37,10 @@
; right away, in another file on the same card (zasm), on a different sector.
;
; If we only have one buffer in this scenario, we'll end up loading a new sector
; at each GetB/PutB operation and, more importantly, writing a whole block for
; at each GetC/PutC operation and, more importantly, writing a whole block for
; a few bytes each time. This will wear the card prematurely (and be very slow).
;
; With 2 buffers, we solve the problem. Whenever GetB/PutB is called, we first
; With 2 buffers, we solve the problem. Whenever GetC/PutC is called, we first
; look if one of the buffer holds our sector. If not, we see if one of the
; buffer is clean (not dirty). If yes, we use this one. If both are dirty or
; clean, we use any. This way, as long as writing isn't made to random
@ -721,7 +721,7 @@ _sdcPlaceBuf:
xor a ; ensure Z
ret
sdcGetB:
sdcGetC:
push hl
call _sdcPlaceBuf
jr nz, .error
@ -736,7 +736,7 @@ sdcGetB:
pop hl
ret
sdcPutB:
sdcPutC:
push hl
push af ; let's remember the char we put, _sdcPlaceBuf
; destroys A.

View File

@ -24,7 +24,7 @@ jp aciaInt
.equ BLOCKDEV_COUNT 1
.inc "blockdev.asm"
; List of devices
.dw mmapGetB, mmapPutB
.dw mmapGetC, mmapPutC
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
.inc "stdio.asm"

View File

@ -29,8 +29,8 @@ jp aciaInt
.equ BLOCKDEV_COUNT 2
.inc "blockdev.asm"
; List of devices
.dw sdcGetB, sdcPutB
.dw blk2GetB, blk2PutB
.dw sdcGetC, sdcPutC
.dw blk2GetC, blk2PutC
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
@ -83,10 +83,10 @@ init:
; *** blkdev 2: file handle 0 ***
blk2GetB:
blk2GetC:
ld ix, FS_HANDLES
jp fsGetB
jp fsGetC
blk2PutB:
blk2PutC:
ld ix, FS_HANDLES
jp fsPutB
jp fsPutC

View File

@ -27,7 +27,7 @@
jp blkSet
jp fsFindFN
jp fsOpen
jp fsGetB
jp fsGetC
jp cpHLDE ; approaching 0x38...
; interrupt hook
@ -37,14 +37,14 @@ jp aciaInt
; *** Jump Table (cont.) ***
jp parseArgs
jp printstr
jp _blkGetB
jp _blkPutB
jp _blkGetC
jp _blkPutC
jp _blkSeek
jp _blkTell
jp printHexPair
jp sdcGetB
jp sdcPutB
jp blkGetB
jp sdcGetC
jp sdcPutC
jp blkGetC
.inc "err.h"
.inc "core.asm"
@ -55,10 +55,10 @@ jp aciaInt
.equ BLOCKDEV_COUNT 4
.inc "blockdev.asm"
; List of devices
.dw sdcGetB, sdcPutB
.dw blk1GetB, blk1PutB
.dw blk2GetB, blk2PutB
.dw mmapGetB, mmapPutB
.dw sdcGetC, sdcPutC
.dw blk1GetC, blk1PutC
.dw blk2GetC, blk2PutC
.dw mmapGetC, mmapPutC
.equ MMAP_START 0xe000
@ -116,20 +116,20 @@ init:
; *** blkdev 1: file handle 0 ***
blk1GetB:
blk1GetC:
ld ix, FS_HANDLES
jp fsGetB
jp fsGetC
blk1PutB:
blk1PutC:
ld ix, FS_HANDLES
jp fsPutB
jp fsPutC
; *** blkdev 2: file handle 1 ***
blk2GetB:
blk2GetC:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsGetB
jp fsGetC
blk2PutB:
blk2PutC:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsPutB
jp fsPutC

View File

@ -5,31 +5,30 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE @+3
.equ addHL @+3
.equ upcase @+3
.equ unsetZ @+3
.equ intoDE @+3
.equ intoHL @+3
.equ writeHLinDE @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3
.equ blkSel @+3
.equ blkSet @+3
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ cpHLDE @+3
; now at 0x36
.equ addDE 0x06
.equ addHL 0x09
.equ upcase 0x0c
.equ unsetZ 0x0f
.equ intoDE 0x12
.equ intoHL 0x15
.equ writeHLinDE 0x18
.equ findchar 0x1b
.equ parseHex 0x1e
.equ parseHexPair 0x21
.equ blkSel 0x24
.equ blkSet 0x27
.equ fsFindFN 0x2a
.equ fsOpen 0x2d
.equ fsGetC 0x30
.equ cpHLDE 0x33
.equ parseArgs 0x3b
.equ printstr @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ printHexPair @+3
.equ sdcGetB @+3
.equ sdcPutB @+3
.equ blkGetB @+3
.equ printstr 0x3e
.equ _blkGetC 0x41
.equ _blkPutC 0x44
.equ _blkSeek 0x47
.equ _blkTell 0x4a
.equ printHexPair 0x4d
.equ sdcGetC 0x50
.equ sdcPutC 0x53
.equ blkGetC 0x56

View File

@ -22,14 +22,14 @@
jp blkSet
jp fsFindFN
jp fsOpen
jp fsGetB
jp fsPutB
jp fsGetC
jp fsPutC
jp fsSetSize
jp cpHLDE
jp parseArgs
jp printstr
jp _blkGetB
jp _blkPutB
jp _blkGetC
jp _blkPutC
jp _blkSeek
jp _blkTell
jp printcrlf
@ -63,9 +63,9 @@
.equ BLOCKDEV_COUNT 3
.inc "blockdev.asm"
; List of devices
.dw mmapGetB, mmapPutB
.dw f0GetB, f0PutB
.dw f1GetB, f1PutB
.dw mmapGetC, mmapPutC
.dw f0GetC, f0PutC
.dw f1GetC, f1PutC
.equ FS_RAMSTART BLOCKDEV_RAMEND
@ -121,21 +121,21 @@ init:
ld (SHELL_CMDHOOK), hl
jp shellLoop
f0GetB:
f0GetC:
ld ix, FS_HANDLES
jp fsGetB
jp fsGetC
f0PutB:
f0PutC:
ld ix, FS_HANDLES
jp fsPutB
jp fsPutC
f1GetB:
f1GetC:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsGetB
jp fsGetC
f1PutB:
f1PutC:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsPutB
jp fsPutC
edCmd:
.db "ed", 0, 0, 0b1001, 0, 0

View File

@ -30,14 +30,14 @@
.equ blkSet 0x27
.equ fsFindFN 0x2a
.equ fsOpen 0x2d
.equ fsGetB 0x30
.equ fsPutB 0x33
.equ fsGetC 0x30
.equ fsPutC 0x33
.equ fsSetSize 0x36
.equ cpHLDE 0x39
.equ parseArgs 0x3c
.equ printstr 0x3f
.equ _blkGetB 0x42
.equ _blkPutB 0x45
.equ _blkGetC 0x42
.equ _blkPutC 0x45
.equ _blkSeek 0x48
.equ _blkTell 0x4b
.equ printcrlf 0x4e

View File

@ -1,20 +0,0 @@
#/usr/bin/env bash
set -e
git submodule init
git submodule update
git clean -fxd
cd tools/emul
make
cd ../tests
make
# let's try again with an updated zasm
cd ../emul
make updatebootstrap all
cd ../tests
make

View File

@ -26,14 +26,14 @@
jp blkSet
jp fsFindFN
jp fsOpen
jp fsGetB
jp fsPutB
jp fsGetC
jp fsPutC
jp fsSetSize
jp cpHLDE
jp parseArgs
jp printstr
jp _blkGetB
jp _blkPutB
jp _blkGetC
jp _blkPutC
jp _blkSeek
jp _blkTell
jp printcrlf
@ -48,10 +48,10 @@
.equ BLOCKDEV_COUNT 4
.inc "blockdev.asm"
; List of devices
.dw fsdevGetB, fsdevPutB
.dw stdoutGetB, stdoutPutB
.dw stdinGetB, stdinPutB
.dw mmapGetB, mmapPutB
.dw fsdevGetC, fsdevPutC
.dw stdoutGetC, stdoutPutC
.dw stdinGetC, stdinPutC
.dw mmapGetC, mmapPutC
.equ MMAP_START 0xe000
@ -84,8 +84,8 @@ init:
; setup stack
ld hl, KERNEL_RAMEND
ld sp, hl
ld hl, emulGetB
ld de, emulPutB
ld hl, emulGetC
ld de, emulPutC
call stdioInit
call fsInit
ld a, 0 ; select fsdev
@ -97,17 +97,17 @@ init:
ld (SHELL_CMDHOOK), hl
jp shellLoop
emulGetB:
emulGetC:
; Blocks until a char is returned
in a, (STDIO_PORT)
cp a ; ensure Z
ret
emulPutB:
emulPutC:
out (STDIO_PORT), a
ret
fsdevGetB:
fsdevGetC:
ld a, e
out (FS_ADDR_PORT), a
ld a, h
@ -121,7 +121,7 @@ fsdevGetB:
cp a ; ensure Z
ret
fsdevPutB:
fsdevPutC:
push af
ld a, e
out (FS_ADDR_PORT), a
@ -142,21 +142,21 @@ fsdevPutB:
.equ STDOUT_HANDLE FS_HANDLES
stdoutGetB:
stdoutGetC:
ld ix, STDOUT_HANDLE
jp fsGetB
jp fsGetC
stdoutPutB:
stdoutPutC:
ld ix, STDOUT_HANDLE
jp fsPutB
jp fsPutC
.equ STDIN_HANDLE FS_HANDLES+FS_HANDLE_SIZE
stdinGetB:
stdinGetC:
ld ix, STDIN_HANDLE
jp fsGetB
jp fsGetC
stdinPutB:
stdinPutC:
ld ix, STDIN_HANDLE
jp fsPutB
jp fsPutC

View File

@ -19,14 +19,14 @@
.equ blkSet @+3
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ fsPutB @+3
.equ fsGetC @+3
.equ fsPutC @+3
.equ fsSetSize @+3
.equ cpHLDE @+3
.equ parseArgs @+3
.equ printstr @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkGetC @+3
.equ _blkPutC @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ printcrlf @+3

View File

@ -24,11 +24,11 @@ jp blkSel
jp blkSet
jp fsFindFN
jp fsOpen
jp fsGetB
jp fsGetC
jp cpHLDE
jp parseArgs
jp _blkGetB
jp _blkPutB
jp _blkGetC
jp _blkPutC
jp _blkSeek
jp _blkTell
jp printstr
@ -40,9 +40,9 @@ jp printstr
.equ BLOCKDEV_COUNT 3
.inc "blockdev.asm"
; List of devices
.dw emulGetB, unsetZ
.dw unsetZ, emulPutB
.dw fsdevGetB, fsdevPutB
.dw emulGetC, unsetZ
.dw unsetZ, emulPutC
.dw fsdevGetC, fsdevPutC
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
.inc "stdio.asm"
@ -71,7 +71,7 @@ init:
.db "0 1", 0
; *** I/O ***
emulGetB:
emulGetC:
; the STDIN_SEEK port works by poking it twice. First poke is for high
; byte, second poke is for low one.
ld a, h
@ -87,7 +87,7 @@ emulGetB:
call unsetZ
ret
emulPutB:
emulPutC:
out (STDIO_PORT), a
cp a ; ensure Z
ret
@ -97,7 +97,7 @@ stderrPutC:
cp a ; ensure Z
ret
fsdevGetB:
fsdevGetC:
ld a, e
out (FS_SEEK_PORT), a
ld a, h
@ -111,7 +111,7 @@ fsdevGetB:
cp a ; ensure Z
ret
fsdevPutB:
fsdevPutC:
push af
ld a, e
out (FS_SEEK_PORT), a

View File

@ -5,25 +5,25 @@
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE @+3
.equ addHL @+3
.equ upcase @+3
.equ unsetZ @+3
.equ intoDE @+3
.equ intoHL @+3
.equ writeHLinDE @+3
.equ findchar @+3
.equ parseHex @+3
.equ parseHexPair @+3
.equ blkSel @+3
.equ blkSet @+3
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ cpHLDE @+3
.equ parseArgs @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ printstr @+3
.equ addDE 0x06
.equ addHL 0x09
.equ upcase 0x0c
.equ unsetZ 0x0f
.equ intoDE 0x12
.equ intoHL 0x15
.equ writeHLinDE 0x18
.equ findchar 0x1b
.equ parseHex 0x1e
.equ parseHexPair 0x21
.equ blkSel 0x24
.equ blkSet 0x27
.equ fsFindFN 0x2a
.equ fsOpen 0x2d
.equ fsGetC 0x30
.equ cpHLDE 0x33
.equ parseArgs 0x36
.equ _blkGetC 0x39
.equ _blkPutC 0x3c
.equ _blkSeek 0x3f
.equ _blkTell 0x42
.equ printstr 0x45

View File

@ -9,7 +9,7 @@
.equ BLOCKDEV_ERR_OUT_OF_BOUNDS 0x03
.equ BLOCKDEV_ERR_UNSUPPORTED 0x04
; IO routines (GetB, PutB) returned an error in a load/save command
; IO routines (GetC, PutC) returned an error in a load/save command
.equ SHELL_ERR_IO_ERROR 0x05