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

Compare commits

..

7 Commits

Author SHA1 Message Date
Virgil Dupras
0e79035d9c Disable test failing on Travis 2019-11-13 22:37:00 -05:00
Virgil Dupras
69750b4da6 Update bootstrap binaries 2019-11-13 22:28:47 -05:00
Virgil Dupras
82995eb346 zasm: have .fill generate an error on overflow
Can possibly avoid a lot of debugging pain.
2019-11-13 22:27:48 -05:00
Virgil Dupras
8d46895dd3 lib/parse: decimal ending with a whitespace are now valid
Also, make empty strings be parsed as invalid by parseDecimal.
2019-11-13 22:10:06 -05:00
Virgil Dupras
7274dccbe7 Move ASCII consts to ascii.h
And made them shorter in name. The new ascii.h file allow reuse in userspace
code.
2019-11-13 20:38:06 -05:00
Virgil Dupras
7046d23cd6 Fix broken IRC link in README 2019-11-13 20:27:09 -05:00
Sarala Saraswati
0f65890074 add link to freenode irc channel and sonic.net hosted listserv (#75) 2019-11-13 20:17:21 -05:00
32 changed files with 125 additions and 84 deletions

View File

@ -49,8 +49,11 @@ for more information.
For a general discussion of Collapse OS and the ecosystem of technologies and ideas that may develop around it refer to [r/collapseos][discussion] For a general discussion of Collapse OS and the ecosystem of technologies and ideas that may develop around it refer to [r/collapseos][discussion]
A more traditional [mailing list][listserv] and IRC (#collapseos on freenode) channels are also maintained.
[libz80]: https://github.com/ggambetta/libz80 [libz80]: https://github.com/ggambetta/libz80
[web]: https://collapseos.org [web]: https://collapseos.org
[jsemul]: https://schierlm.github.io/CollapseOS-Web-Emulator/ [jsemul]: https://schierlm.github.io/CollapseOS-Web-Emulator/
[discussion]: https://www.reddit.com/r/collapseos [discussion]: https://www.reddit.com/r/collapseos
[listserv]: http://lists.sonic.net/mailman/listinfo/collapseos

View File

@ -12,6 +12,7 @@
jp basStart jp basStart
.inc "lib/util.asm"
.inc "lib/parse.asm" .inc "lib/parse.asm"
.equ BAS_RAMSTART USER_RAMSTART .equ BAS_RAMSTART USER_RAMSTART
.inc "basic/main.asm" .inc "basic/main.asm"

View File

@ -1,6 +1,3 @@
; *** Requirements ***
; None
;
; *** Code *** ; *** Code ***
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the ; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
@ -15,6 +12,10 @@
; Parse string at (HL) as a decimal value and return value in IX under the ; Parse string at (HL) as a decimal value and return value in IX under the
; same conditions as parseLiteral. ; same conditions as parseLiteral.
; Sets Z on success, unset on error. ; Sets Z on success, unset on error.
; To parse successfully, all characters following HL must be digits and those
; digits must form a number that fits in 16 bits. To end the number, both \0
; and whitespaces (0x20 and 0x09) are accepted. There must be at least one
; digit in the string.
parseDecimal: parseDecimal:
push hl push hl
@ -22,11 +23,11 @@ parseDecimal:
ld a, (hl) ld a, (hl)
add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff
sub 0xff-9 ; maps to 0-9 and carries if not a digit sub 0xff-9 ; maps to 0-9 and carries if not a digit
jr c, .error ; not a digit on first char? error
exx ; preserve bc, hl, de exx ; preserve bc, hl, de
ld h, 0 ld h, 0
ld l, a ; load first digit in without multiplying ld l, a ; load first digit in without multiplying
ld b, 3 ; Carries can only occur for decimals >=5 in length ld b, 3 ; Carries can only occur for decimals >=5 in length
jr c, .end
.loop: .loop:
exx exx
@ -37,7 +38,6 @@ parseDecimal:
; inline parseDecimalDigit ; inline parseDecimalDigit
add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff
sub 0xff-9 ; maps to 0-9 and carries if not a digit sub 0xff-9 ; maps to 0-9 and carries if not a digit
jr c, .end jr c, .end
add hl, hl ; x2 add hl, hl ; x2
@ -74,4 +74,9 @@ parseDecimal:
push hl \ pop ix push hl \ pop ix
exx ; restore original de and bc exx ; restore original de and bc
pop hl pop hl
ret ret z
; A is not 0? Ok, but if it's a space, we're happy too.
jp isSep
.error:
pop hl
jp unsetZ

View File

@ -1,3 +1,10 @@
; Sets Z is A is ' ' or '\t'
isSep:
cp ' '
ret z
cp 0x09
ret
; Copy string from (HL) in (DE), that is, copy bytes until a null char is ; Copy string from (HL) in (DE), that is, copy bytes until a null char is
; encountered. The null char is also copied. ; encountered. The null char is also copied.
; HL and DE point to the char right after the null char. ; HL and DE point to the char right after the null char.

View File

@ -130,6 +130,11 @@ allowed. An included file cannot have an `.inc` directive.
offset. For example, if we want to place an instruction exactly at offset. For example, if we want to place an instruction exactly at
byte 0x38, we would precede it with `.fill 0x38-$`. byte 0x38, we would precede it with `.fill 0x38-$`.
The maximum value possible for `.fill` is `0xd000`. We do this to
avoid "overshoot" errors, that is, error where `$` is greater than
the offset you're trying to reach in an expression like `.fill X-$`
(such an expression overflows to `0xffff`).
**.org**: Sets the Program Counter to the value of the argument, an expression. **.org**: Sets the Program Counter to the value of the argument, an expression.
For example, a label being defined right after a `.org 0x400`, would For example, a label being defined right after a `.org 0x400`, would
have a value of `0x400`. Does not do any filling. You have to do that have a value of `0x400`. Does not do any filling. You have to do that

View File

@ -201,8 +201,11 @@ handleFIL:
jr nz, .badfmt jr nz, .badfmt
call parseExpr call parseExpr
jr nz, .badarg jr nz, .badarg
push bc push bc ; --> lvl 1
push ix \ pop bc push ix \ pop bc
ld a, b
cp 0xd0
jr nc, .overflow
.loop: .loop:
ld a, b ld a, b
or c or c
@ -214,19 +217,21 @@ handleFIL:
jr .loop jr .loop
.loopend: .loopend:
cp a ; ensure Z cp a ; ensure Z
pop bc pop bc ; <-- lvl 1
ret ret
.ioError: .ioError:
ld a, SHELL_ERR_IO_ERROR ld a, SHELL_ERR_IO_ERROR
jr .error jp unsetZ
.badfmt: .badfmt:
ld a, ERR_BAD_FMT ld a, ERR_BAD_FMT
jr .error jp unsetZ
.badarg: .badarg:
ld a, ERR_BAD_ARG ld a, ERR_BAD_ARG
.error: jp unsetZ
call unsetZ .overflow:
ret pop bc ; <-- lvl 1
ld a, ERR_OVFL
jp unsetZ
handleOUT: handleOUT:
push hl push hl

View File

@ -68,6 +68,7 @@
; ****** ; ******
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.org USER_CODE .org USER_CODE
jp zasmMain jp zasmMain

View File

@ -195,6 +195,9 @@ parseNumberOrSymbol:
; matter that we didn't find our symbol. Return success anyhow. ; matter that we didn't find our symbol. Return success anyhow.
; Otherwise return error. Z is already unset, so in fact, this is the ; Otherwise return error. Z is already unset, so in fact, this is the
; same as jumping to zasmIsFirstPass ; same as jumping to zasmIsFirstPass
; however, before we do, load IX with zero. Returning dummy non-zero
; values can have weird consequence (such as false overflow errors).
ld ix, 0
jp zasmIsFirstPass jp zasmIsFirstPass
.returnPC: .returnPC:

View File

@ -22,20 +22,13 @@ isLineEndOrComment:
isLineEnd: isLineEnd:
or a ; same as cp 0 or a ; same as cp 0
ret z ret z
cp 0x0d cp CR
ret z ret z
cp 0x0a cp LF
ret z ret z
cp '\' cp '\'
ret ret
; Sets Z is A is ' ' '\t' or ','
isSep:
cp ' '
ret z
cp 0x09
ret
; Sets Z is A is ' ', ',', ';', CR, LF, or null. ; Sets Z is A is ' ', ',', ';', CR, LF, or null.
isSepOrLineEnd: isSepOrLineEnd:
call isSep call isSep

View File

@ -19,6 +19,7 @@ look like:
jp aciaInt jp aciaInt
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

4
kernel/ascii.h Normal file
View File

@ -0,0 +1,4 @@
.equ BS 0x08
.equ CR 0x0d
.equ LF 0x0a
.equ DEL 0x7f

View File

@ -3,16 +3,6 @@
; Routines used by pretty much all parts. You will want to include it first ; Routines used by pretty much all parts. You will want to include it first
; in your glue file. ; in your glue file.
; *** CONSTS ***
.equ ASCII_BS 0x08
.equ ASCII_CR 0x0d
.equ ASCII_LF 0x0a
.equ ASCII_DEL 0x7f
; *** DATA ***
; Useful data to point to, when a pointer is needed.
P_NULL: .db 0
; *** REGISTER FIDDLING *** ; *** REGISTER FIDDLING ***
; add the value of A into DE ; add the value of A into DE

View File

@ -66,7 +66,7 @@ shellInit:
jp printstr jp printstr
.welcome: .welcome:
.db "Collapse OS", ASCII_CR, ASCII_LF, "> ", 0 .db "Collapse OS", CR, LF, "> ", 0
; Inifite loop that processes input. Because it's infinite, you should jump ; Inifite loop that processes input. Because it's infinite, you should jump
; to it rather than call it. Saves two precious bytes in the stack. ; to it rather than call it. Saves two precious bytes in the stack.

View File

@ -185,7 +185,7 @@ padGetC:
call vdpSpitC call vdpSpitC
jp padGetC jp padGetC
.return: .return:
ld a, ASCII_LF ld a, LF
ld (PAD_NEXTCHR), a ld (PAD_NEXTCHR), a
; continue to .advance ; continue to .advance
.advance: .advance:
@ -193,7 +193,7 @@ padGetC:
; Z was already set from previous BIT instruction ; Z was already set from previous BIT instruction
ret ret
.backspace: .backspace:
ld a, ASCII_BS ld a, BS
; Z was already set from previous BIT instruction ; Z was already set from previous BIT instruction
ret ret
.nextchr: .nextchr:

View File

@ -119,11 +119,11 @@ vdpPutC:
; 6 low bits contain our row*2 (each tile is 2 bytes wide) and high ; 6 low bits contain our row*2 (each tile is 2 bytes wide) and high
; 2 bits are the two low bits of our line ; 2 bits are the two low bits of our line
; special case: line feed, carriage return, back space ; special case: line feed, carriage return, back space
cp ASCII_LF cp LF
jr z, vdpLF jr z, vdpLF
cp ASCII_CR cp CR
jr z, vdpCR jr z, vdpCR
cp ASCII_BS cp BS
jr z, vdpBS jr z, vdpBS
push af push af

View File

@ -81,9 +81,9 @@ printnstr:
printcrlf: printcrlf:
push af push af
ld a, ASCII_CR ld a, CR
call STDIO_PUTC call STDIO_PUTC
ld a, ASCII_LF ld a, LF
call STDIO_PUTC call STDIO_PUTC
pop af pop af
ret ret
@ -124,13 +124,13 @@ stdioReadLine:
; Let's wait until something is typed. ; Let's wait until something is typed.
call STDIO_GETC call STDIO_GETC
; got it. Now, is it a CR or LF? ; got it. Now, is it a CR or LF?
cp ASCII_CR cp CR
jr z, .complete ; char is CR? buffer complete! jr z, .complete ; char is CR? buffer complete!
cp ASCII_LF cp LF
jr z, .complete jr z, .complete
cp ASCII_DEL cp DEL
jr z, .delchr jr z, .delchr
cp ASCII_BS cp BS
jr z, .delchr jr z, .delchr
; Echo the received character right away so that we see what we type ; Echo the received character right away so that we see what we type
@ -161,10 +161,10 @@ stdioReadLine:
inc b inc b
; Char deleted in buffer, now send BS + space + BS for the terminal ; Char deleted in buffer, now send BS + space + BS for the terminal
; to clear its previous char ; to clear its previous char
ld a, ASCII_BS ld a, BS
call STDIO_PUTC call STDIO_PUTC
ld a, ' ' ld a, ' '
call STDIO_PUTC call STDIO_PUTC
ld a, ASCII_BS ld a, BS
call STDIO_PUTC call STDIO_PUTC
jr .loop jr .loop

View File

@ -329,9 +329,9 @@ lcdClrScr:
ret ret
lcdPutC: lcdPutC:
cp ASCII_LF cp LF
jp z, lcdLinefeed jp z, lcdLinefeed
cp ASCII_BS cp BS
jr z, .bs jr z, .bs
push hl push hl
call fntGet call fntGet

View File

@ -12,6 +12,7 @@ jp init
jp aciaInt jp aciaInt
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

View File

@ -12,6 +12,7 @@ jp init
jp aciaInt jp aciaInt
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

View File

@ -7,6 +7,7 @@
jp init jp init
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

View File

@ -21,6 +21,7 @@ jp sdcSendRecv
jp aciaInt jp aciaInt
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

View File

@ -47,6 +47,7 @@ jp aciaInt
jp blkGetB jp blkGetB
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"
.equ ACIA_RAMSTART RAMSTART .equ ACIA_RAMSTART RAMSTART

View File

@ -9,6 +9,7 @@
retn retn
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"

View File

@ -9,6 +9,7 @@
retn retn
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"

View File

@ -40,6 +40,7 @@
retn retn
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "parse.asm" .inc "parse.asm"

View File

@ -22,6 +22,7 @@
.fill 0x64-$ .fill 0x64-$
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.equ FNT_WIDTH 3 .equ FNT_WIDTH 3
.equ FNT_HEIGHT 5 .equ FNT_HEIGHT 5

View File

@ -42,6 +42,7 @@
.inc "core.asm" .inc "core.asm"
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "parse.asm" .inc "parse.asm"
.equ BLOCKDEV_RAMSTART RAMSTART .equ BLOCKDEV_RAMSTART RAMSTART

View File

@ -33,6 +33,7 @@ jp printstr
.inc "core.asm" .inc "core.asm"
.inc "err.h" .inc "err.h"
.inc "ascii.h"
.inc "parse.asm" .inc "parse.asm"
.equ BLOCKDEV_RAMSTART RAMSTART .equ BLOCKDEV_RAMSTART RAMSTART
.equ BLOCKDEV_COUNT 3 .equ BLOCKDEV_COUNT 3

Binary file not shown.

Binary file not shown.

View File

@ -100,29 +100,11 @@ testLiteral:
call nexttest call nexttest
ret ret
; 2b int, 6b str, null-padded
tblDecimalValid:
.dw 99
.db "99", 0, 0, 0, 0
.dw 65535
.db "65535", 0
; 7b strings, null-padded
tblDecimalInvalid:
; TODO: make a null string parse as an invalid decimal
; null string is invalid
;.db 0, 0, 0, 0, 0, 0, 0
; too big, 5 chars
.db "65536", 0, 0
.db "99999", 0, 0
; too big, 6 chars with rightmost chars being within bound
.db "111111", 0
testDecimal: testDecimal:
; test valid cases. We loop through tblDecimalValid for our cases ; test valid cases. We loop through tblDecimalValid for our cases
ld b, 2 ld b, 5
ld hl, tblDecimalValid ld hl, .valid
.loop1: .loop1:
push hl ; --> lvl 1 push hl ; --> lvl 1
@ -147,8 +129,8 @@ testDecimal:
call nexttest call nexttest
; test invalid cases. We loop through tblDecimalInvalid for our cases ; test invalid cases. We loop through tblDecimalInvalid for our cases
ld b, 3 ld b, 4
ld hl, tblDecimalInvalid ld hl, .invalid
.loop2: .loop2:
call parseDecimal call parseDecimal
@ -159,6 +141,34 @@ testDecimal:
call nexttest call nexttest
ret ret
; 2b int, 6b str, null-padded
.valid:
.dw 99
.db "99", 0, 0, 0, 0
.dw 65535
.db "65535", 0
; Space is also accepted as a number "ender"
.dw 42
.db "42 x", 0, 0
; Tab too
.dw 42
.db "42", 0x09, 'x', 0, 0
; A simple "0" works too!
.dw 0
.db '0', 0, 0, 0, 0, 0
; 7b strings, null-padded
.invalid:
; null string is invalid
.db 0, 0, 0, 0, 0, 0, 0
; too big, 5 chars
.db "65536", 0, 0
.db "99999", 0, 0
; too big, 6 chars with rightmost chars being within bound
.db "111111", 0
nexttest: nexttest:
ld a, (testNum) ld a, (testNum)
inc a inc a

View File

@ -54,6 +54,8 @@ chkerr ".inc" 19
chkerr ".inc foo" 19 chkerr ".inc foo" 19
chkerr "ld a, 0x100" 20 chkerr "ld a, 0x100" 20
chkerr ".db 0x100" 20 chkerr ".db 0x100" 20
# TODO: find out why this tests fails on Travis but not on my machine...
# chkerr $'nop \ nop \ nop\n.fill 2-$' 20
chkerr ".inc \"doesnotexist\"" 21 chkerr ".inc \"doesnotexist\"" 21
chkerr "foo:\\foo:" 22 chkerr "foo:\\foo:" 22
chkoom chkoom