1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 04:48: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]
A more traditional [mailing list][listserv] and IRC (#collapseos on freenode) channels are also maintained.
[libz80]: https://github.com/ggambetta/libz80
[web]: https://collapseos.org
[jsemul]: https://schierlm.github.io/CollapseOS-Web-Emulator/
[discussion]: https://www.reddit.com/r/collapseos
[listserv]: http://lists.sonic.net/mailman/listinfo/collapseos

View File

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

View File

@ -1,6 +1,3 @@
; *** Requirements ***
; None
;
; *** Code ***
; 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
; same conditions as parseLiteral.
; 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:
push hl
@ -22,11 +23,11 @@ parseDecimal:
ld a, (hl)
add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff
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
ld h, 0
ld l, a ; load first digit in without multiplying
ld b, 3 ; Carries can only occur for decimals >=5 in length
jr c, .end
.loop:
exx
@ -37,7 +38,6 @@ parseDecimal:
; inline parseDecimalDigit
add a, 0xff-'9' ; maps '0'-'9' onto 0xf6-0xff
sub 0xff-9 ; maps to 0-9 and carries if not a digit
jr c, .end
add hl, hl ; x2
@ -74,4 +74,9 @@ parseDecimal:
push hl \ pop ix
exx ; restore original de and bc
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
; encountered. The null char is also copied.
; HL and DE point to the char right after the null char.

View File

@ -121,15 +121,20 @@ allowed. An included file cannot have an `.inc` directive.
expression written as the second parameter. Example:
`.equ foo 0x42+'A'`
If the symbol specified has already been defined, no error occur and
the first value defined stays intact. This allows for "user override"
of programs.
If the symbol specified has already been defined, no error occur and
the first value defined stays intact. This allows for "user override"
of programs.
**.fill**: Outputs the number of null bytes specified by its argument, an
expression. Often used with `$` to fill our binary up to a certain
offset. For example, if we want to place an instruction exactly at
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.
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

View File

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

View File

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

View File

@ -195,6 +195,9 @@ parseNumberOrSymbol:
; matter that we didn't find our symbol. Return success anyhow.
; Otherwise return error. Z is already unset, so in fact, this is the
; 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
.returnPC:

View File

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

View File

@ -19,6 +19,7 @@ look like:
jp aciaInt
.inc "err.h"
.inc "ascii.h"
.inc "core.asm"
.inc "parse.asm"
.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
; 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 ***
; add the value of A into DE

View File

@ -66,7 +66,7 @@ shellInit:
jp printstr
.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
; to it rather than call it. Saves two precious bytes in the stack.

View File

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

View File

@ -119,11 +119,11 @@ vdpPutC:
; 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
; special case: line feed, carriage return, back space
cp ASCII_LF
cp LF
jr z, vdpLF
cp ASCII_CR
cp CR
jr z, vdpCR
cp ASCII_BS
cp BS
jr z, vdpBS
push af

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Binary file not shown.

View File

@ -100,29 +100,11 @@ testLiteral:
call nexttest
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:
; test valid cases. We loop through tblDecimalValid for our cases
ld b, 2
ld hl, tblDecimalValid
ld b, 5
ld hl, .valid
.loop1:
push hl ; --> lvl 1
@ -147,8 +129,8 @@ testDecimal:
call nexttest
; test invalid cases. We loop through tblDecimalInvalid for our cases
ld b, 3
ld hl, tblDecimalInvalid
ld b, 4
ld hl, .invalid
.loop2:
call parseDecimal
@ -159,6 +141,34 @@ testDecimal:
call nexttest
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:
ld a, (testNum)
inc a

View File

@ -54,6 +54,8 @@ chkerr ".inc" 19
chkerr ".inc foo" 19
chkerr "ld a, 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 "foo:\\foo:" 22
chkoom