mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
removed all string related builtin functions and moved them to separate routines in new 'string' library module
This commit is contained in:
parent
ee7f9d457d
commit
58f37513e7
@ -7,16 +7,14 @@ indent_size = 4
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
max_line_length = 120
|
max_line_length = 120
|
||||||
tab_width = 4
|
tab_width = 8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
|
||||||
[*.p8]
|
[*.p8]
|
||||||
tab_width = 4
|
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[*.asm]
|
[*.asm]
|
||||||
tab_width = 8
|
|
||||||
indent_size = 8
|
indent_size = 8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||||
|
|
||||||
%import textio
|
%import textio
|
||||||
|
%import string
|
||||||
%import syslib
|
%import syslib
|
||||||
|
|
||||||
diskio {
|
diskio {
|
||||||
@ -84,7 +85,7 @@ io_error:
|
|||||||
name_ptrs++
|
name_ptrs++
|
||||||
@(name_ptrs) = msb(names_buffer)
|
@(name_ptrs) = msb(names_buffer)
|
||||||
name_ptrs++
|
name_ptrs++
|
||||||
names_buffer += strcopy(diskio.list_filename, names_buffer) + 1
|
names_buffer += string.copy(diskio.list_filename, names_buffer) + 1
|
||||||
files_found++
|
files_found++
|
||||||
if names_buffer - buffer_start > 512-18
|
if names_buffer - buffer_start > 512-18
|
||||||
break
|
break
|
||||||
@ -204,7 +205,7 @@ close_end:
|
|||||||
; note: only a single iteration loop can be active at a time!
|
; note: only a single iteration loop can be active at a time!
|
||||||
f_close()
|
f_close()
|
||||||
|
|
||||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||||
c64.SETLFS(11, drivenumber, 3)
|
c64.SETLFS(11, drivenumber, 3)
|
||||||
void c64.OPEN() ; open 11,8,0,"filename"
|
void c64.OPEN() ; open 11,8,0,"filename"
|
||||||
if_cc {
|
if_cc {
|
||||||
@ -373,7 +374,7 @@ io_error:
|
|||||||
|
|
||||||
|
|
||||||
sub save(ubyte drivenumber, uword filenameptr, uword address, uword size) -> ubyte {
|
sub save(ubyte drivenumber, uword filenameptr, uword address, uword size) -> ubyte {
|
||||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||||
c64.SETLFS(1, drivenumber, 0)
|
c64.SETLFS(1, drivenumber, 0)
|
||||||
uword end_address = address + size
|
uword end_address = address + size
|
||||||
|
|
||||||
@ -403,7 +404,7 @@ io_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub load(ubyte drivenumber, uword filenameptr, uword address_override) -> uword {
|
sub load(ubyte drivenumber, uword filenameptr, uword address_override) -> uword {
|
||||||
c64.SETNAM(strlen(filenameptr), filenameptr)
|
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||||
ubyte secondary = 1
|
ubyte secondary = 1
|
||||||
uword end_of_load = 0
|
uword end_of_load = 0
|
||||||
if address_override
|
if address_override
|
||||||
@ -435,7 +436,7 @@ io_error:
|
|||||||
|
|
||||||
sub delete(ubyte drivenumber, uword filenameptr) {
|
sub delete(ubyte drivenumber, uword filenameptr) {
|
||||||
; -- delete a file on the drive
|
; -- delete a file on the drive
|
||||||
ubyte flen = strlen(filenameptr)
|
ubyte flen = string.length(filenameptr)
|
||||||
filename[0] = 's'
|
filename[0] = 's'
|
||||||
filename[1] = ':'
|
filename[1] = ':'
|
||||||
memcopy(filenameptr, &filename+2, flen+1)
|
memcopy(filenameptr, &filename+2, flen+1)
|
||||||
@ -448,8 +449,8 @@ io_error:
|
|||||||
|
|
||||||
sub rename(ubyte drivenumber, uword oldfileptr, uword newfileptr) {
|
sub rename(ubyte drivenumber, uword oldfileptr, uword newfileptr) {
|
||||||
; -- rename a file on the drive
|
; -- rename a file on the drive
|
||||||
ubyte flen_old = strlen(oldfileptr)
|
ubyte flen_old = string.length(oldfileptr)
|
||||||
ubyte flen_new = strlen(newfileptr)
|
ubyte flen_new = string.length(newfileptr)
|
||||||
filename[0] = 'r'
|
filename[0] = 'r'
|
||||||
filename[1] = ':'
|
filename[1] = ':'
|
||||||
memcopy(newfileptr, &filename+2, flen_new)
|
memcopy(newfileptr, &filename+2, flen_new)
|
||||||
|
@ -1204,205 +1204,3 @@ func_memcopy255 .proc
|
|||||||
ldx P8ZP_SCRATCH_REG
|
ldx P8ZP_SCRATCH_REG
|
||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
func_leftstr .proc
|
|
||||||
; leftstr(source, target, length)
|
|
||||||
lda _arg_source
|
|
||||||
ldy _arg_source+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
lda _arg_target
|
|
||||||
ldy _arg_target+1
|
|
||||||
sta P8ZP_SCRATCH_W2
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
ldy _arg_length
|
|
||||||
lda #0
|
|
||||||
sta (P8ZP_SCRATCH_W2),y
|
|
||||||
cpy #0
|
|
||||||
bne _loop
|
|
||||||
rts
|
|
||||||
_loop dey
|
|
||||||
lda (P8ZP_SCRATCH_W1),y
|
|
||||||
sta (P8ZP_SCRATCH_W2),y
|
|
||||||
cpy #0
|
|
||||||
bne _loop
|
|
||||||
+ rts
|
|
||||||
|
|
||||||
_arg_source .word 0
|
|
||||||
_arg_target .word 0
|
|
||||||
_arg_length .byte 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
|
|
||||||
func_rightstr .proc
|
|
||||||
; rightstr(source, target, length)
|
|
||||||
lda _arg_source
|
|
||||||
ldy _arg_source+1
|
|
||||||
jsr func_strlen_into_A
|
|
||||||
sec
|
|
||||||
sbc _arg_length
|
|
||||||
sta P8ZP_SCRATCH_B1
|
|
||||||
lda _arg_source
|
|
||||||
ldy _arg_source+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
lda _arg_target
|
|
||||||
ldy _arg_target+1
|
|
||||||
sta P8ZP_SCRATCH_W2
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
ldy #0
|
|
||||||
sty P8ZP_SCRATCH_REG
|
|
||||||
- ldy P8ZP_SCRATCH_B1
|
|
||||||
lda (P8ZP_SCRATCH_W1),y
|
|
||||||
inc P8ZP_SCRATCH_B1
|
|
||||||
ldy P8ZP_SCRATCH_REG
|
|
||||||
sta (P8ZP_SCRATCH_W2),y
|
|
||||||
inc P8ZP_SCRATCH_REG
|
|
||||||
cmp #0
|
|
||||||
bne -
|
|
||||||
rts
|
|
||||||
|
|
||||||
_arg_source .word 0
|
|
||||||
_arg_target .word 0
|
|
||||||
_arg_length .byte 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
|
|
||||||
func_strlen_into_A .proc
|
|
||||||
; -- put length of 0-terminated string in A/Y into A
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
ldy #0
|
|
||||||
- lda (P8ZP_SCRATCH_W1),y
|
|
||||||
beq +
|
|
||||||
iny
|
|
||||||
bne -
|
|
||||||
+ tya
|
|
||||||
rts
|
|
||||||
.pend
|
|
||||||
|
|
||||||
func_strlen_stack .proc
|
|
||||||
jsr func_strlen_into_A
|
|
||||||
sta P8ESTACK_LO,x
|
|
||||||
dex
|
|
||||||
rts
|
|
||||||
.pend
|
|
||||||
|
|
||||||
|
|
||||||
func_substr .proc
|
|
||||||
; substr(source, target, start, length)
|
|
||||||
lda _arg_source
|
|
||||||
ldy _arg_source+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
lda _arg_target
|
|
||||||
ldy _arg_target+1
|
|
||||||
sta P8ZP_SCRATCH_W2
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
ldy _arg_length
|
|
||||||
lda _arg_start
|
|
||||||
sta P8ZP_SCRATCH_B1
|
|
||||||
|
|
||||||
; adjust src location
|
|
||||||
clc
|
|
||||||
lda P8ZP_SCRATCH_W1
|
|
||||||
adc P8ZP_SCRATCH_B1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
bcc +
|
|
||||||
inc P8ZP_SCRATCH_W1+1
|
|
||||||
+ lda #0
|
|
||||||
sta (P8ZP_SCRATCH_W2),y
|
|
||||||
jmp _startloop
|
|
||||||
- lda (P8ZP_SCRATCH_W1),y
|
|
||||||
sta (P8ZP_SCRATCH_W2),y
|
|
||||||
_startloop dey
|
|
||||||
cpy #$ff
|
|
||||||
bne -
|
|
||||||
rts
|
|
||||||
|
|
||||||
_arg_source .word 0
|
|
||||||
_arg_target .word 0
|
|
||||||
_arg_start .byte 0
|
|
||||||
_arg_length .byte 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
|
|
||||||
func_strcmp .proc
|
|
||||||
; -- compare 2 strings -> A
|
|
||||||
lda _arg_s2
|
|
||||||
ldy _arg_s2+1
|
|
||||||
sta P8ZP_SCRATCH_W2
|
|
||||||
sty P8ZP_SCRATCH_W2+1
|
|
||||||
lda _arg_s1
|
|
||||||
ldy _arg_s1+1
|
|
||||||
jmp strcmp_mem
|
|
||||||
_arg_s1 .word 0
|
|
||||||
_arg_s2 .word 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
func_strcmp_stack .proc
|
|
||||||
jsr func_strcmp
|
|
||||||
sta P8ESTACK_LO,x
|
|
||||||
dex
|
|
||||||
rts
|
|
||||||
.pend
|
|
||||||
|
|
||||||
func_strcopy .proc
|
|
||||||
lda _arg_to
|
|
||||||
ldy _arg_to+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
lda _arg_from
|
|
||||||
ldy _arg_from+1
|
|
||||||
jsr strcpy
|
|
||||||
tya
|
|
||||||
rts
|
|
||||||
_arg_from .word 0
|
|
||||||
_arg_to .word 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
func_strcopy_to_stack .proc
|
|
||||||
jsr func_strcopy
|
|
||||||
sta P8ESTACK_LO,x
|
|
||||||
dex
|
|
||||||
rts
|
|
||||||
.pend
|
|
||||||
|
|
||||||
|
|
||||||
func_strfind .proc
|
|
||||||
lda _arg_string
|
|
||||||
ldy _arg_string+1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
ldy #0
|
|
||||||
- lda (P8ZP_SCRATCH_W1),y
|
|
||||||
beq _notfound
|
|
||||||
cmp _arg_char
|
|
||||||
beq _found
|
|
||||||
iny
|
|
||||||
bne -
|
|
||||||
_notfound lda #0
|
|
||||||
ldy #0
|
|
||||||
rts
|
|
||||||
_found sty P8ZP_SCRATCH_B1
|
|
||||||
lda P8ZP_SCRATCH_W1
|
|
||||||
clc
|
|
||||||
adc P8ZP_SCRATCH_B1
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
bcc +
|
|
||||||
inc P8ZP_SCRATCH_W1+1
|
|
||||||
+ ldy P8ZP_SCRATCH_W1+1
|
|
||||||
rts
|
|
||||||
|
|
||||||
_arg_string .word 0
|
|
||||||
_arg_char .byte 0
|
|
||||||
.pend
|
|
||||||
|
|
||||||
func_strfind_stack .proc
|
|
||||||
jsr func_strfind
|
|
||||||
sta P8ESTACK_LO,x
|
|
||||||
sty P8ESTACK_HI,x
|
|
||||||
dex
|
|
||||||
rts
|
|
||||||
.pend
|
|
||||||
|
@ -5,5 +5,189 @@
|
|||||||
|
|
||||||
string {
|
string {
|
||||||
|
|
||||||
|
asmsub length(uword string @AY) clobbers(A) -> ubyte @Y {
|
||||||
|
; Returns the number of bytes in the string.
|
||||||
|
; This value is determined during runtime and counts upto the first terminating 0 byte in the string,
|
||||||
|
; regardless of the size of the string during compilation time. Don’t confuse this with len and sizeof!
|
||||||
|
|
||||||
|
%asm {{
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
ldy #0
|
||||||
|
- lda (P8ZP_SCRATCH_W1),y
|
||||||
|
beq +
|
||||||
|
iny
|
||||||
|
bne -
|
||||||
|
+ rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub left(uword source @R0, ubyte length @A, uword target @R1) clobbers(A, Y) {
|
||||||
|
; Copies the left side of the source string of the given length to target string.
|
||||||
|
; It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
; Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||||
|
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||||
|
%asm {{
|
||||||
|
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||||
|
ldy cx16.r0
|
||||||
|
sty P8ZP_SCRATCH_W1
|
||||||
|
ldy cx16.r0+1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
ldy cx16.r1
|
||||||
|
sty P8ZP_SCRATCH_W2
|
||||||
|
ldy cx16.r1+1
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
tay
|
||||||
|
lda #0
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
cpy #0
|
||||||
|
bne _loop
|
||||||
|
rts
|
||||||
|
_loop dey
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
cpy #0
|
||||||
|
bne _loop
|
||||||
|
+ rts
|
||||||
|
}}
|
||||||
|
; asmgen.out(" jsr prog8_lib.func_leftstr")
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub right(uword source @R0, ubyte length @A, uword target @R1) clobbers(A,Y) {
|
||||||
|
; Copies the right side of the source string of the given length to target string.
|
||||||
|
; It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
; Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||||
|
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||||
|
%asm {{
|
||||||
|
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||||
|
sta P8ZP_SCRATCH_B1
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jsr string.length
|
||||||
|
tya
|
||||||
|
sec
|
||||||
|
sbc P8ZP_SCRATCH_B1
|
||||||
|
clc
|
||||||
|
adc cx16.r0
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
lda cx16.r0+1
|
||||||
|
adc #0
|
||||||
|
sta P8ZP_SCRATCH_W1+1
|
||||||
|
ldy cx16.r1
|
||||||
|
sty P8ZP_SCRATCH_W2
|
||||||
|
ldy cx16.r1+1
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
ldy P8ZP_SCRATCH_B1
|
||||||
|
lda #0
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
cpy #0
|
||||||
|
bne _loop
|
||||||
|
rts
|
||||||
|
_loop dey
|
||||||
|
lda (P8ZP_SCRATCH_W1),y
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
cpy #0
|
||||||
|
bne _loop
|
||||||
|
+ rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub slice(uword source @R0, ubyte start @A, ubyte length @Y, uword target @R1) clobbers(A, Y) {
|
||||||
|
; Copies a segment from the source string, starting at the given index,
|
||||||
|
; and of the given length to target string.
|
||||||
|
; It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
; Also, you have to make sure yourself that start and length are within bounds of the strings.
|
||||||
|
; Modifies in-place, doesn’t return a value (so can’t be used in an expression).
|
||||||
|
%asm {{
|
||||||
|
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||||
|
; substr(source, target, start, length)
|
||||||
|
sta P8ZP_SCRATCH_B1
|
||||||
|
lda cx16.r0
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
lda cx16.r0+1
|
||||||
|
sta P8ZP_SCRATCH_W1+1
|
||||||
|
lda cx16.r1
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
lda cx16.r1+1
|
||||||
|
sta P8ZP_SCRATCH_W2+1
|
||||||
|
|
||||||
|
; adjust src location
|
||||||
|
clc
|
||||||
|
lda P8ZP_SCRATCH_W1
|
||||||
|
adc P8ZP_SCRATCH_B1
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
bcc +
|
||||||
|
inc P8ZP_SCRATCH_W1+1
|
||||||
|
+ lda #0
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
beq _startloop
|
||||||
|
- lda (P8ZP_SCRATCH_W1),y
|
||||||
|
sta (P8ZP_SCRATCH_W2),y
|
||||||
|
_startloop dey
|
||||||
|
cpy #$ff
|
||||||
|
bne -
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub find(uword string @R0, ubyte character @A) -> uword @AY {
|
||||||
|
; Locates the first position of the given character in the string,
|
||||||
|
; returns the string starting with this character or $0000 if the character is not found.
|
||||||
|
%asm {{
|
||||||
|
; need to copy the the cx16 virtual registers to zeropage to be compatible with C64...
|
||||||
|
sta P8ZP_SCRATCH_B1
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
ldy #0
|
||||||
|
- lda (P8ZP_SCRATCH_W1),y
|
||||||
|
beq _notfound
|
||||||
|
cmp P8ZP_SCRATCH_B1
|
||||||
|
beq _found
|
||||||
|
iny
|
||||||
|
bne -
|
||||||
|
_notfound lda #0
|
||||||
|
ldy #0
|
||||||
|
rts
|
||||||
|
_found sty P8ZP_SCRATCH_B1
|
||||||
|
ldy P8ZP_SCRATCH_W1+1
|
||||||
|
lda P8ZP_SCRATCH_W1
|
||||||
|
clc
|
||||||
|
adc P8ZP_SCRATCH_B1
|
||||||
|
bcc +
|
||||||
|
iny
|
||||||
|
+ rts
|
||||||
|
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub copy(uword source @R0, uword target @AY) clobbers(A) -> ubyte @Y {
|
||||||
|
; Copy a string to another, overwriting that one.
|
||||||
|
; Returns the length of the string that was copied.
|
||||||
|
; Often you don’t have to call this explicitly and can just write string1 = string2
|
||||||
|
; but this function is useful if you’re dealing with addresses for instance.
|
||||||
|
%asm {{
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jmp prog8_lib.strcpy
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub compare(uword string1 @R0, uword string2 @AY) clobbers(Y) -> ubyte @A {
|
||||||
|
; Compares two strings for sorting.
|
||||||
|
; Returns -1 (255), 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
||||||
|
; Note that you can also directly compare strings and string values with eachother using
|
||||||
|
; comparison operators ==, < etcetera (it will use strcmp for you under water automatically).
|
||||||
|
%asm {{
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jmp prog8_lib.strcmp_mem
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,21 +79,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
"set_carry" -> asmgen.out(" sec")
|
"set_carry" -> asmgen.out(" sec")
|
||||||
"clear_irqd" -> asmgen.out(" cli")
|
"clear_irqd" -> asmgen.out(" cli")
|
||||||
"set_irqd" -> asmgen.out(" sei")
|
"set_irqd" -> asmgen.out(" sei")
|
||||||
"strlen" -> funcStrlen(fcall, resultToStack)
|
|
||||||
"strfind" -> funcStrfind(fcall, func, resultToStack, sscope)
|
|
||||||
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
|
|
||||||
"strcopy" -> {
|
|
||||||
translateArguments(fcall.args, func, sscope)
|
|
||||||
if(resultToStack)
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strcopy_to_stack")
|
|
||||||
else
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strcopy")
|
|
||||||
}
|
|
||||||
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope)
|
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope)
|
||||||
"substr", "leftstr", "rightstr" -> {
|
|
||||||
translateArguments(fcall.args, func, sscope)
|
|
||||||
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
|
||||||
}
|
|
||||||
"exit" -> {
|
"exit" -> {
|
||||||
translateArguments(fcall.args, func, sscope)
|
translateArguments(fcall.args, func, sscope)
|
||||||
asmgen.out(" jmp prog8_lib.func_exit")
|
asmgen.out(" jmp prog8_lib.func_exit")
|
||||||
@ -198,22 +184,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcStrfind(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
|
||||||
translateArguments(fcall.args, func, scope)
|
|
||||||
if(resultToStack)
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strfind_stack")
|
|
||||||
else
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strfind")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
|
||||||
translateArguments(fcall.args, func, scope)
|
|
||||||
if(resultToStack)
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strcmp_stack")
|
|
||||||
else
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strcmp")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||||
translateArguments(fcall.args, func, scope)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
@ -588,27 +558,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcStrlen(fcall: IFunctionCall, resultToStack: Boolean) {
|
|
||||||
if (fcall.args[0] is IdentifierReference) {
|
|
||||||
// use the address of the variable
|
|
||||||
val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference)
|
|
||||||
val type = fcall.args[0].inferType(program)
|
|
||||||
when {
|
|
||||||
type.istype(DataType.STR) -> asmgen.out(" lda #<$name | ldy #>$name")
|
|
||||||
type.istype(DataType.UWORD) -> asmgen.out(" lda $name | ldy $name+1")
|
|
||||||
else -> throw AssemblyError("strlen requires str or uword arg")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// use the expression value as address of the string
|
|
||||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
|
||||||
}
|
|
||||||
if (resultToStack)
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strlen_stack")
|
|
||||||
else
|
|
||||||
asmgen.out(" jsr prog8_lib.func_strlen_into_A")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSwap(fcall: IFunctionCall) {
|
private fun funcSwap(fcall: IFunctionCall) {
|
||||||
val first = fcall.args[0]
|
val first = fcall.args[0]
|
||||||
val second = fcall.args[1]
|
val second = fcall.args[1]
|
||||||
|
@ -159,24 +159,7 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FSignature("memsetw" , false, listOf(
|
FSignature("memsetw" , false, listOf(
|
||||||
FParam("address", IterableDatatypes + DataType.UWORD),
|
FParam("address", IterableDatatypes + DataType.UWORD),
|
||||||
FParam("numwords", setOf(DataType.UWORD)),
|
FParam("numwords", setOf(DataType.UWORD)),
|
||||||
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null),
|
FParam("wordvalue", setOf(DataType.UWORD, DataType.WORD))), null)
|
||||||
FSignature("strlen" , true, listOf(FParam("string", StringlyDatatypes)), DataType.UBYTE, ::builtinStrlen),
|
|
||||||
FSignature("strcopy" , false, listOf(FParam("from", StringlyDatatypes), FParam("to", StringlyDatatypes)), DataType.UBYTE),
|
|
||||||
FSignature("substr" , false, listOf(
|
|
||||||
FParam("source", StringlyDatatypes),
|
|
||||||
FParam("target", StringlyDatatypes),
|
|
||||||
FParam("start", setOf(DataType.UBYTE)),
|
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
|
||||||
FSignature("leftstr" , false, listOf(
|
|
||||||
FParam("source", StringlyDatatypes),
|
|
||||||
FParam("target", StringlyDatatypes),
|
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
|
||||||
FSignature("rightstr" , false, listOf(
|
|
||||||
FParam("source", StringlyDatatypes),
|
|
||||||
FParam("target", StringlyDatatypes),
|
|
||||||
FParam("length", setOf(DataType.UBYTE))), null),
|
|
||||||
FSignature("strcmp" , true, listOf(FParam("s1", StringlyDatatypes), FParam("s2", StringlyDatatypes)), DataType.BYTE, null),
|
|
||||||
FSignature("strfind" , true, listOf(FParam("string", StringlyDatatypes), FParam("char", setOf(DataType.UBYTE))), DataType.STR, null)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||||
@ -355,23 +338,6 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun builtinStrlen(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
|
||||||
if (args.size != 1)
|
|
||||||
throw SyntaxError("strlen requires one argument", position)
|
|
||||||
val argument=args[0]
|
|
||||||
if(argument is StringLiteralValue)
|
|
||||||
return NumericLiteralValue.optimalInteger(argument.value.length, argument.position)
|
|
||||||
val vardecl = (argument as? IdentifierReference)?.targetVarDecl(program.namespace)
|
|
||||||
if(vardecl!=null) {
|
|
||||||
if(vardecl.datatype!=DataType.STR && vardecl.datatype!=DataType.UWORD)
|
|
||||||
throw SyntaxError("strlen must have string argument", position)
|
|
||||||
if(vardecl.autogeneratedDontRemove && vardecl.value!=null) {
|
|
||||||
return NumericLiteralValue.optimalInteger((vardecl.value as StringLiteralValue).value.length, argument.position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw NotConstArgumentException()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun builtinLen(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
private fun builtinLen(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
||||||
// note: in some cases the length is > 255 and then we have to return a UWORD type instead of a UBYTE.
|
// note: in some cases the length is > 255 and then we have to return a UWORD type instead of a UBYTE.
|
||||||
if(args.size!=1)
|
if(args.size!=1)
|
||||||
|
@ -65,6 +65,49 @@ Provides several routines that deal with disk drive I/O, such as:
|
|||||||
- delete and rename files on the disk
|
- delete and rename files on the disk
|
||||||
|
|
||||||
|
|
||||||
|
string
|
||||||
|
------
|
||||||
|
Provides string manipulation routines.
|
||||||
|
|
||||||
|
length(str) -> ubyte length
|
||||||
|
Number of bytes in the string. This value is determined during runtime and counts upto
|
||||||
|
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
|
||||||
|
Don't confuse this with ``len`` and ``sizeof``
|
||||||
|
|
||||||
|
left(source, length, target)
|
||||||
|
Copies the left side of the source string of the given length to target string.
|
||||||
|
It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||||
|
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||||
|
|
||||||
|
right(source, length, target)
|
||||||
|
Copies the right side of the source string of the given length to target string.
|
||||||
|
It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
||||||
|
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||||
|
|
||||||
|
slice(source, start, length, target)
|
||||||
|
Copies a segment from the source string, starting at the given index,
|
||||||
|
and of the given length to target string.
|
||||||
|
It is assumed the target string buffer is large enough to contain the result.
|
||||||
|
Also, you have to make sure yourself that start and length are within bounds of the strings.
|
||||||
|
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
||||||
|
|
||||||
|
find(string, char) -> uword address
|
||||||
|
Locates the first position of the given character in the string, returns the string starting
|
||||||
|
with this character or $0000 if the character is not found.
|
||||||
|
|
||||||
|
compare(string1, string2) -> ubyte result
|
||||||
|
Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
||||||
|
Note that you can also directly compare strings and string values with eachother
|
||||||
|
using ``==``, ``<`` etcetera (it will use string.compare for you under water automatically).
|
||||||
|
|
||||||
|
copy(from, to) -> ubyte length
|
||||||
|
Copy a string to another, overwriting that one. Returns the length of the string that was copied.
|
||||||
|
Often you don't have to call this explicitly and can just write ``string1 = string2``
|
||||||
|
but this function is useful if you're dealing with addresses for instance.
|
||||||
|
|
||||||
|
|
||||||
floats
|
floats
|
||||||
------
|
------
|
||||||
Provides definitions for the ROM/kernel subroutines and utility routines dealing with floating
|
Provides definitions for the ROM/kernel subroutines and utility routines dealing with floating
|
||||||
|
@ -799,44 +799,6 @@ memsetw(address, numwords, wordvalue)
|
|||||||
Efficiently set a part of memory to the given (u)word value.
|
Efficiently set a part of memory to the given (u)word value.
|
||||||
But the most efficient will always be to write a specialized fill routine in assembly yourself!
|
But the most efficient will always be to write a specialized fill routine in assembly yourself!
|
||||||
|
|
||||||
leftstr(source, target, length)
|
|
||||||
Copies the left side of the source string of the given length to target string.
|
|
||||||
It is assumed the target string buffer is large enough to contain the result.
|
|
||||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
|
||||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
|
||||||
|
|
||||||
rightstr(source, target, length)
|
|
||||||
Copies the right side of the source string of the given length to target string.
|
|
||||||
It is assumed the target string buffer is large enough to contain the result.
|
|
||||||
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
|
|
||||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
|
||||||
|
|
||||||
strlen(str)
|
|
||||||
Number of bytes in the string. This value is determined during runtime and counts upto
|
|
||||||
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
|
|
||||||
Don't confuse this with ``len`` and ``sizeof``
|
|
||||||
|
|
||||||
strcmp(string1, string2)
|
|
||||||
Returns -1, 0 or 1 depeding on wether string1 sorts before, equal or after string2.
|
|
||||||
Note that you can also directly compare strings and string values with eachother
|
|
||||||
using ``==``, ``<`` etcetera (it will use strcmp for you under water automatically).
|
|
||||||
|
|
||||||
substr(source, target, start, length)
|
|
||||||
Copies a segment from the source string, starting at the given index,
|
|
||||||
and of the given length to target string.
|
|
||||||
It is assumed the target string buffer is large enough to contain the result.
|
|
||||||
Also, you have to make sure yourself that start and length are within bounds of the strings.
|
|
||||||
Modifies in-place, doesn't return a value (so can't be used in an expression).
|
|
||||||
|
|
||||||
strcopy(from, to)
|
|
||||||
Copy a string to another, overwriting that one. Returns the length of the string that was copied.
|
|
||||||
Often you don't have to call this explicitly and can just write ``string1 = string2``
|
|
||||||
but this function is useful if you're dealing with addresses for instance.
|
|
||||||
|
|
||||||
strfind(string, char)
|
|
||||||
Locates the first position of the given character in the string, returns the string starting
|
|
||||||
with this character or $0000 if the character is not found.
|
|
||||||
|
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
@ -3,8 +3,10 @@ TODO
|
|||||||
====
|
====
|
||||||
|
|
||||||
- move all str* builtin functions to a strings library module, mem* to the sys module. update docs.
|
- move all str* builtin functions to a strings library module, mem* to the sys module. update docs.
|
||||||
|
- move target() builtin to sys.target constant
|
||||||
- use (zp) addressing mode on 65c02 specific code rather than ldy#0 / lda (zp),y
|
- use (zp) addressing mode on 65c02 specific code rather than ldy#0 / lda (zp),y
|
||||||
- optimize pointer access code @(pointer)? use a subroutine? macro? 65c02 vs 6502?
|
- optimize pointer access code @(pointer)? use a subroutine? macro? 65c02 vs 6502?
|
||||||
|
- allow byte return type with single register for asmsubs, for instance string.compare
|
||||||
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
|
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
|
||||||
- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
|
- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
|
||||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||||
|
@ -7,16 +7,14 @@ indent_size = 4
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
max_line_length = 120
|
max_line_length = 120
|
||||||
tab_width = 4
|
tab_width = 8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
ij_smart_tabs = true
|
ij_smart_tabs = true
|
||||||
|
|
||||||
[*.p8]
|
[*.p8]
|
||||||
tab_width = 4
|
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[*.asm]
|
[*.asm]
|
||||||
tab_width = 8
|
|
||||||
indent_size = 8
|
indent_size = 8
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
%import floats
|
%import floats
|
||||||
%import textio
|
%import textio
|
||||||
|
%import string
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
@ -22,10 +23,10 @@ main {
|
|||||||
if length!=5 txt.print("error len1\n")
|
if length!=5 txt.print("error len1\n")
|
||||||
length = len(uwarr)
|
length = len(uwarr)
|
||||||
if length!=5 txt.print("error len2\n")
|
if length!=5 txt.print("error len2\n")
|
||||||
length=strlen(name)
|
length=string.length(name)
|
||||||
if length!=5 txt.print("error strlen1\n")
|
if length!=5 txt.print("error strlen1\n")
|
||||||
name[3] = 0
|
name[3] = 0
|
||||||
length=strlen(name)
|
length=string.length(name)
|
||||||
if length!=3 txt.print("error strlen2\n")
|
if length!=3 txt.print("error strlen2\n")
|
||||||
|
|
||||||
; MAX
|
; MAX
|
||||||
|
@ -477,6 +477,7 @@ main {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; @TODO fix type errors
|
||||||
|
|
||||||
sub shiftrsw0() -> word {
|
sub shiftrsw0() -> word {
|
||||||
word q = -12345
|
word q = -12345
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import floats
|
%import floats
|
||||||
|
%import string
|
||||||
%import syslib
|
%import syslib
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -8,7 +9,6 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
rotations()
|
rotations()
|
||||||
strings()
|
|
||||||
integers()
|
integers()
|
||||||
floatingpoint()
|
floatingpoint()
|
||||||
|
|
||||||
@ -256,82 +256,6 @@ main {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub strings() {
|
|
||||||
const uword ADDR = $8400
|
|
||||||
const uword ADDR2 = $8000
|
|
||||||
|
|
||||||
memset(ADDR2, 40*25, '*')
|
|
||||||
memset(ADDR2, 40, '1')
|
|
||||||
memset(ADDR2+24*40, 39, '2')
|
|
||||||
memsetw(ADDR2, 40*25/2, $3132)
|
|
||||||
memsetw(ADDR2, 20, $4142)
|
|
||||||
memsetw(ADDR2+24*40, 19, $4241)
|
|
||||||
memcopy(ADDR2, ADDR, 200)
|
|
||||||
|
|
||||||
str result = "?" *10
|
|
||||||
str s1 = "irmen"
|
|
||||||
str s2 = "hello"
|
|
||||||
str dots = "....."
|
|
||||||
|
|
||||||
ubyte ub
|
|
||||||
byte bb
|
|
||||||
ubyte zero=0
|
|
||||||
|
|
||||||
bb = strcmp(s1, s2)
|
|
||||||
txt.print_b(bb)
|
|
||||||
txt.chrout('\n')
|
|
||||||
bb = strcmp(s2, s1)
|
|
||||||
txt.print_b(bb)
|
|
||||||
txt.chrout('\n')
|
|
||||||
txt.print_ub(s1==s2)
|
|
||||||
txt.chrout('\n')
|
|
||||||
txt.print_ub(s1<s2)
|
|
||||||
txt.chrout('\n')
|
|
||||||
txt.print_ub(s1>s2)
|
|
||||||
txt.chrout('\n')
|
|
||||||
bb = zero+strcmp(s1,s2)*1+zero
|
|
||||||
txt.print_b(bb)
|
|
||||||
txt.chrout('\n')
|
|
||||||
bb = zero+strcmp(s2,s1)*1+zero
|
|
||||||
txt.print_b(bb)
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
ub = strlen(s1)
|
|
||||||
txt.print_ub(ub)
|
|
||||||
txt.chrout('\n')
|
|
||||||
ub = zero+strlen(s1)*1+zero
|
|
||||||
txt.print_ub(ub)
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
leftstr(s1, result, 3)
|
|
||||||
txt.print(result)
|
|
||||||
txt.chrout('\n')
|
|
||||||
leftstr(s1, result, len(s1))
|
|
||||||
txt.print(result)
|
|
||||||
txt.chrout('\n')
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
result = "x"*8
|
|
||||||
rightstr(s2, result, 3)
|
|
||||||
txt.print(result)
|
|
||||||
txt.chrout('\n')
|
|
||||||
rightstr(s2, result, len(s1))
|
|
||||||
txt.print(result)
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
result = "y"*10
|
|
||||||
substr(s2, result, 1, 3)
|
|
||||||
txt.print(result)
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
void strcopy(s2, s1)
|
|
||||||
txt.print_ub(99+strcopy(s2,s1))
|
|
||||||
txt.chrout('\n')
|
|
||||||
|
|
||||||
test_stack.test()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sub integers() {
|
sub integers() {
|
||||||
ubyte[] ubarr = [1,2,3,4,5,0,4,3,2,1, 255, 255, 255]
|
ubyte[] ubarr = [1,2,3,4,5,0,4,3,2,1, 255, 255, 255]
|
||||||
byte[] barr = [1,2,3,4,5,-4,0,-3,2,1, -128, -128, -127]
|
byte[] barr = [1,2,3,4,5,-4,0,-3,2,1, -128, -128, -127]
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%import perf2
|
%import perf2
|
||||||
%import perf3
|
%import perf3
|
||||||
@ -954,7 +955,7 @@ util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util10 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util7 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -944,7 +945,7 @@ util9 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword string) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(string) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(string)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%target cx16
|
%target cx16
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%import textio
|
%import textio
|
||||||
|
%import string
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ textparse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uword value = conv.any2uword(word_addrs[2])
|
uword value = conv.any2uword(word_addrs[2])
|
||||||
if strcmp("*", word_addrs[0])==0 {
|
if word_addrs[0] == "*" { ; TODO does this string compare work?
|
||||||
program_counter = value
|
program_counter = value
|
||||||
} else {
|
} else {
|
||||||
set_symbol(word_addrs[0], value)
|
set_symbol(word_addrs[0], value)
|
||||||
@ -96,7 +97,7 @@ textparse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if label_ptr {
|
if label_ptr {
|
||||||
uword lastlabelchar = label_ptr + strlen(label_ptr)-1
|
uword lastlabelchar = label_ptr + string.length(label_ptr)-1
|
||||||
if @(lastlabelchar) == ':'
|
if @(lastlabelchar) == ':'
|
||||||
@(lastlabelchar) = 0
|
@(lastlabelchar) = 0
|
||||||
if instructions.match(label_ptr) {
|
if instructions.match(label_ptr) {
|
||||||
@ -346,7 +347,7 @@ textparse {
|
|||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
@(dest)=0
|
@(dest)=0
|
||||||
void strcopy(input_line2, src)
|
string.copy(input_line2, src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
%import gfx2
|
%import gfx2
|
||||||
%import textio
|
%import textio
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import koala_module
|
%import koala_module
|
||||||
%import iff_module
|
%import iff_module
|
||||||
%import pcx_module
|
%import pcx_module
|
||||||
@ -14,7 +15,7 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
; trick to check if we're running on sdcard or host system shared folder
|
; trick to check if we're running on sdcard or host system shared folder
|
||||||
txt.print("\nimage viewer for commander x16\nformats supported: .iff, .pcx, .bmp, .koa (c64 koala)\n\n")
|
txt.print("\nimage viewer for commander x16\nformats supported: .iff, .pcx, .bmp, .koa (c64 koala)\n\n")
|
||||||
if strlen(diskio.status(8)) {
|
if string.length(diskio.status(8)) {
|
||||||
txt.print("enter image file name or just enter for all on disk: ")
|
txt.print("enter image file name or just enter for all on disk: ")
|
||||||
ubyte i = txt.input_chars(diskio.filename)
|
ubyte i = txt.input_chars(diskio.filename)
|
||||||
gfx2.screen_mode(1) ; 320*240, 256c
|
gfx2.screen_mode(1) ; 320*240, 256c
|
||||||
@ -54,7 +55,7 @@ main {
|
|||||||
;txt.print(filenameptr)
|
;txt.print(filenameptr)
|
||||||
;txt.chrout('\n')
|
;txt.chrout('\n')
|
||||||
uword extension = filenameptr + rfind(filenameptr, '.')
|
uword extension = filenameptr + rfind(filenameptr, '.')
|
||||||
if strcmp(extension, ".iff")==0 {
|
if extension == ".iff" { ; TODO does this compare work?
|
||||||
;txt.print("loading ")
|
;txt.print("loading ")
|
||||||
;txt.print("iff\n")
|
;txt.print("iff\n")
|
||||||
if iff_module.show_image(filenameptr) {
|
if iff_module.show_image(filenameptr) {
|
||||||
@ -70,7 +71,7 @@ main {
|
|||||||
load_error(filenameptr)
|
load_error(filenameptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if strcmp(extension, ".pcx")==0 {
|
else if extension == ".pcx" { ; TODO works?
|
||||||
;txt.print("loading ")
|
;txt.print("loading ")
|
||||||
;txt.print("pcx\n")
|
;txt.print("pcx\n")
|
||||||
if pcx_module.show_image(filenameptr) {
|
if pcx_module.show_image(filenameptr) {
|
||||||
@ -79,7 +80,7 @@ main {
|
|||||||
load_error(filenameptr)
|
load_error(filenameptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if strcmp(extension, ".koa")==0 {
|
else if extension == ".koa" { ; TODO works?
|
||||||
;txt.print("loading ")
|
;txt.print("loading ")
|
||||||
;txt.print("koala\n")
|
;txt.print("koala\n")
|
||||||
if koala_module.show_image(filenameptr) {
|
if koala_module.show_image(filenameptr) {
|
||||||
@ -88,7 +89,7 @@ main {
|
|||||||
load_error(filenameptr)
|
load_error(filenameptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if strcmp(extension, ".bmp")==0 {
|
else if extension == ".bmp" { ; TODO works?
|
||||||
;txt.print("loading ")
|
;txt.print("loading ")
|
||||||
;txt.print("bmp\n")
|
;txt.print("bmp\n")
|
||||||
if bmp_module.show_image(filenameptr) {
|
if bmp_module.show_image(filenameptr) {
|
||||||
@ -97,7 +98,7 @@ main {
|
|||||||
load_error(filenameptr)
|
load_error(filenameptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
; else if strcmp(extension, ".ci")==0 {
|
; else if extension == ".ci" {
|
||||||
;; txt.print("loading ")
|
;; txt.print("loading ")
|
||||||
;; txt.print("ci\n")
|
;; txt.print("ci\n")
|
||||||
; if ci_module.show_image(filenameptr) {
|
; if ci_module.show_image(filenameptr) {
|
||||||
@ -117,12 +118,12 @@ main {
|
|||||||
|
|
||||||
sub extension_equals(uword stringptr, uword extensionptr) -> ubyte {
|
sub extension_equals(uword stringptr, uword extensionptr) -> ubyte {
|
||||||
ubyte ix = rfind(stringptr, '.')
|
ubyte ix = rfind(stringptr, '.')
|
||||||
return ix<255 and strcmp(stringptr+ix, extensionptr)==0
|
return ix<255 and string.compare(stringptr+ix, extensionptr)==0
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rfind(uword stringptr, ubyte char) -> ubyte {
|
sub rfind(uword stringptr, ubyte char) -> ubyte {
|
||||||
ubyte i
|
ubyte i
|
||||||
for i in strlen(stringptr)-1 downto 0 {
|
for i in string.length(stringptr)-1 downto 0 {
|
||||||
if @(stringptr+i)==char
|
if @(stringptr+i)==char
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,99 @@
|
|||||||
%import test_stack
|
%import test_stack
|
||||||
%import textio
|
%import textio
|
||||||
|
%import string
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
|
; TODO: error when a parameter has the same name as an existing module/block/subroutine: sub print_right(ubyte width, uword string) {
|
||||||
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
str s1 = "irmen"
|
||||||
|
str s2 = "what"
|
||||||
|
str s3 = "irmen2"
|
||||||
|
|
||||||
|
s3[5] = 0
|
||||||
|
|
||||||
|
txt.print("length:\n")
|
||||||
|
txt.print_ub(len(s1))
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(string.length(s1))
|
||||||
|
|
||||||
|
txt.print("\n\ncopy:\n")
|
||||||
|
txt.print(s3)
|
||||||
|
txt.chrout('\n')
|
||||||
|
s3 = s2
|
||||||
|
txt.print(s3)
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(string.copy("new", s3))
|
||||||
|
txt.print(s3)
|
||||||
|
|
||||||
|
txt.print("\n\ncompare:\n")
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(string.compare(s1, s2))
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(string.compare(s2, s1))
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(string.compare(s1, s3))
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(s1==s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(s1<s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print_ub(s1>s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
txt.print("\n\nleft:")
|
||||||
|
string.left(s2,2,s3)
|
||||||
|
txt.print(s3)
|
||||||
|
txt.chrout('\n')
|
||||||
|
txt.print("\n\nright:\n")
|
||||||
|
txt.print(s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
string.right(s2,2,s3)
|
||||||
|
txt.print(s3)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
txt.print("\n\nfind:\n")
|
||||||
|
txt.print(s1)
|
||||||
|
txt.chrout('\n')
|
||||||
|
uword found = string.find(s1, 'e')
|
||||||
|
txt.print_uwhex(found, 1)
|
||||||
|
if found
|
||||||
|
txt.print(found)
|
||||||
|
txt.chrout('\n')
|
||||||
|
found = string.find(s1, 'i')
|
||||||
|
txt.print_uwhex(found, 1)
|
||||||
|
if found
|
||||||
|
txt.print(found)
|
||||||
|
txt.chrout('\n')
|
||||||
|
found = string.find(s1, 'x')
|
||||||
|
txt.print_uwhex(found, 1)
|
||||||
|
if found
|
||||||
|
txt.print(found)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
txt.print("\n\nslice:\n")
|
||||||
|
string.slice(s1, 0, 5, s2)
|
||||||
|
txt.print(s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
string.slice(s1, 1, 4, s2)
|
||||||
|
txt.print(s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
string.slice(s1, 2, 2, s2)
|
||||||
|
txt.print(s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
string.slice(s1, 3, 2, s2)
|
||||||
|
txt.print(s2)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
test_stack.test()
|
||||||
|
}
|
||||||
|
|
||||||
|
sub start2 () {
|
||||||
str[] binstrings = [
|
str[] binstrings = [
|
||||||
"",
|
"",
|
||||||
"%",
|
"%",
|
||||||
@ -151,16 +239,16 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; found = strfind("irmen de jong", ' ')
|
; found = string.find("irmen de jong", ' ')
|
||||||
; txt.print_uwhex(found, 1)
|
; txt.print_uwhex(found, 1)
|
||||||
; txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
; found = strfind(" irmen-de-jong", ' ')
|
; found = string.find(" irmen-de-jong", ' ')
|
||||||
; txt.print_uwhex(found, 1)
|
; txt.print_uwhex(found, 1)
|
||||||
; txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
; found = strfind("irmen-de-jong ", ' ')
|
; found = string.find("irmen-de-jong ", ' ')
|
||||||
; txt.print_uwhex(found, 1)
|
; txt.print_uwhex(found, 1)
|
||||||
; txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
; found = strfind("irmen-de-jong", ' ')
|
; found = string.find("irmen-de-jong", ' ')
|
||||||
; txt.print_uwhex(found, 1)
|
; txt.print_uwhex(found, 1)
|
||||||
; txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import conv
|
%import conv
|
||||||
%import diskio
|
%import diskio
|
||||||
|
%import string
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
@ -943,11 +944,11 @@ util {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
sub print_right(ubyte width, uword string) {
|
sub print_right(ubyte width, uword s) {
|
||||||
repeat width - strlen(string) {
|
repeat width - string.length(s) {
|
||||||
txt.chrout(' ')
|
txt.chrout(' ')
|
||||||
}
|
}
|
||||||
txt.print(string)
|
txt.print(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub print_10s(uword value @AY) clobbers(A, X, Y) {
|
asmsub print_10s(uword value @AY) clobbers(A, X, Y) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user