Skip to content

Commit

Permalink
Implement some new text parsing related routines into str.so, start w…
Browse files Browse the repository at this point in the history
…orking on new assembler.
  • Loading branch information
beckadamtheinventor committed Mar 7, 2024
1 parent 0c84a61 commit 8613f48
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 2 deletions.
118 changes: 117 additions & 1 deletion src/data/adrive/src/fs/bin/bomasm.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,125 @@
jr _bomasm_main
db "FEX", 0
_bomasm_main:
ld hl,-30
ld (.savesp),sp
call ti._frameset0
ld a,(ix+6)
cp a,3
jr nc,.has_enough_args
ld hl,.str_info
or a,a
sbc hl,hl
pop ix
ret
.has_enough_args:
; zero temp space
ld hl,.bss
push hl
pop de
inc de
ld (hl),0
ld bc,.bss.len
ldir
call osrt.argv_1

.exit0:
or a,a
sbc hl,hl
.exithl:
ld sp,(.savesp)
pop ix
ret
.exit1:
ld hl,1
jr .exithl

; void assemble(char *src, size_t len)
.assemble:
ld hl,-6
call ti._frameset
; init local symtbl
or a,a
sbc hl,hl
ld (ix-3),hl
ld (ix-6),hl
ld (.srcoffset),hl
ld hl,(ix+6)
ld (.src),hl
ld hl,(ix+9)
ld (.srclen),hl
.assemble_loop:
call .peekchar
call .isidentifier
jr c,.not_identifier
call .readidentifier
.not_identifier:
jr .assemble_loop
ld sp,ix
pop ix
ret

; bool isidentifier(void)
; check if A is the start of an identifier
; return Cf set if A is *not* the start of an identifier
.isidentifier:
cp a,'_'
ret z
sub a,'A' ; check uppercase
cp a,26
ccf
ret c
sub a,$20 ; check lowercase
cp a,26
ccf
ret

; char peekchar(void)
.peekchar:
ld hl,(.src)
ld bc,(.srcoffset)
add hl,bc
ld a,(hl)
ret

; char *readidentifier(void)
.readidentifier:
ld hl,(.srclen)
push hl
ld hl,(.srcoffset)
push hl
ld hl,(.src)
push hl
call osrt.sreadidentifier
pop bc,bc,bc
add hl,bc
xor a,a
sbc hl,bc
jr z,.error_invalid_identifier ; fail if str == 0
or a,(hl)
ret nz
; also fail if str[0] == 0

.error_invalid_identifier:
ld hl,.str_error_invalid_identifier
.error_print_and_return:
call bos.gui_PrintLine
jq .exit1

.str_error_invalid_identifier:
db "Invalid identifier", 0

.str_info:
db "bomasm src.asm bin", 0

virtual at ti.pixelShadow
.savesp rb 3
.bss:
.globals rb 6
.src rb 3
.srclen rb 3
.srcoffset rb 3
.bss.len:
end virtual
136 changes: 135 additions & 1 deletion src/data/adrive/src/fs/bin/str.so.asm
Original file line number Diff line number Diff line change
@@ -1,21 +1,155 @@

; shared string code for os executables
; shared string related code

_osrt_str_so:
dd 1
jp osrt.substring
jp osrt.duplicate_string
jp osrt.subsection_mem
jp osrt.duplicate_mem
jp osrt.sreadline
jp osrt.sreadlineuntil
jp osrt.sreaduntil
jp osrt.sreadidentifier

virtual
db "osrt.substring rb 4",$A
db "osrt.duplicate_string rb 4",$A
db "osrt.subsection_mem rb 4",$A
db "osrt.duplicate_mem rb 4",$A
db "osrt.sreadline rb 4",$A
db "osrt.sreadlineuntil rb 4",$A
db "osrt.sreaduntil rb 4",$A
db "osrt.sreadidentifier rb 4",$A
load _routines_osrt_str_so: $-$$ from $$
end virtual

; char *sreadidentifier(const char *src, const size_t offset, const size_t len);
osrt.sreadidentifier:
call ti._frameset0
ld de,(ix+9)
ld hl,(ix+12)
or a,a
sbc hl,de ; len - offset
jr c,osrt.sreadline.fail
push hl
pop bc
ld hl,(ix+6)
add hl,de ; src + offset
push hl
jr osrt.sreadidentifier.loop.entry
osrt.sreadidentifier.loop:
ld a,(hl)
sub a,'0'
cp a,10
jr nc,osrt.sreadidentifier.done
osrt.sreadidentifier.loop.entry:
ld a,(hl)
cp a,'_'
jr z,osrt.sreadidentifier.loop.next
sub a,'A'
cp a,26
jr c,osrt.sreadidentifier.loop.next
sub a,$20
cp a,26
jr nc,osrt.sreadidentifier.done
osrt.sreadidentifier.loop.next:
cpi
jp pe,osrt.sreadidentifier.loop
osrt.sreadidentifier.done:
pop de
or a,a
sbc hl,de ; end - start
jr z,osrt.sreadline.line_len_0
inc hl ; +1 for null terminator
push de
jr osrt.malloc_and_return_ldir_string

; char *readlineuntil(const char *src, const size_t offset, const size_t len, char end);
osrt.sreadlineuntil:
call ti._frameset0
ld a,(ix+15)
jr osrt.sreadline.entry_a

; char *readuntil(const char *src, const size_t offset, const size_t len, char end);
osrt.sreaduntil:
call ti._frameset0
ld a,(ix+15)
scf
jr osrt.sreadline.entry_af

; char *readline(const char *src, const size_t offset, const size_t len);
osrt.sreadline:
ld a,$A ; newline
osrt.sreadline.entry_a:
or a,a
osrt.sreadline.entry_af:
push af
ld de,(ix+9)
ld hl,(ix+12)
or a,a
sbc hl,de ; len - offset
jr c,osrt.sreadline.fail
push hl
pop bc
ld hl,(ix+6)
add hl,de ; src + offset
pop af
push hl
; or a,a
call osrt.sreadline.entry
add hl,bc
or a,a
sbc hl,bc
jr z,osrt.sreadline.line_len_0
osrt.malloc_and_return_ldir_string:
push hl
call bos.sys_Malloc
ex hl,de
pop bc ; length of line
pop hl ; pointer to start of line
jr c,osrt.sreadline.fail
osrt.return_ldir_string:
push de
ldir
xor a,a
ld (de),a
pop hl
pop ix
ret

osrt.sreadline.line_len_0:
ld hl,$FF0000
db $01 ; ld bc,... dummify or a / sbc hl
osrt.sreadline.fail:
or a,a
sbc hl,hl
ld sp,ix
pop ix
ret

; if Cf set as input this will check for character in a and newline, otherwise just a
; input hl pointer to data, bc length of data
; returns length of line in hl
osrt.sreadline.entry:
jr c,osrt.sreadline.entry.check_two
cpir
jr osrt.sreadline.entry.exit
osrt.sreadline.entry.check_two:
ld e,a
cp a,(hl)
jr z,osrt.sreadline.entry.exit
ld a,(hl)
cp a,e
jr z,osrt.sreadline.entry.exit
ld a,e
cpi
jp pe,osrt.sreadline.entry.check_two
osrt.sreadline.entry.exit:
push bc
pop hl
ret

; char *substring(const char *str, const size_t start, const size_t length);
; output copied substring or 0 if start+length > strlen(str) or if malloc failed.
osrt.substring:
Expand Down
4 changes: 4 additions & 0 deletions src/include/osrt.inc
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ osrt.substring rb 4
osrt.duplicate_string rb 4
osrt.subsection_mem rb 4
osrt.duplicate_mem rb 4
osrt.sreadline rb 4
osrt.sreadlineuntil rb 4
osrt.sreaduntil rb 4
osrt.sreadidentifier rb 4
end virtual

0 comments on commit 8613f48

Please sign in to comment.