conv routines now return the string buffer address.

This commit is contained in:
Irmen de Jong 2024-03-08 01:56:35 +01:00
parent bdfb01f6a0
commit 52649a8e4f
10 changed files with 171 additions and 147 deletions

View File

@ -8,27 +8,29 @@ conv {
str @shared string_out = "????????????????" ; result buffer for the string conversion routines
asmsub str_ub0 (ubyte value @ A) clobbers(A,X,Y) {
asmsub str_ub0 (ubyte value @ A) clobbers(X) -> str @AY {
; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total)
%asm {{
jsr conv.ubyte2decimal
sty string_out
sta string_out+1
stx string_out+2
lda #0
sta string_out+3
rts
jsr conv.ubyte2decimal
sty string_out
sta string_out+1
stx string_out+2
lda #0
sta string_out+3
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_ub (ubyte value @ A) clobbers(A,X,Y) {
asmsub str_ub (ubyte value @ A) clobbers(X) -> str @AY {
; ---- convert the ubyte in A in decimal string form, without left padding 0s
%asm {{
ldy #0
sty P8ZP_SCRATCH_B1
jsr conv.ubyte2decimal
_output_byte_digits
; hundreds?
; hundreds?
cpy #'0'
beq +
pha
@ -39,50 +41,54 @@ _output_byte_digits
inc P8ZP_SCRATCH_B1
; tens?
+ ldy P8ZP_SCRATCH_B1
cmp #'0'
cmp #'0'
beq +
sta string_out,y
iny
+ ; ones.
txa
sta string_out,y
iny
lda #0
sta string_out,y
rts
+ ; ones.
txa
sta string_out,y
iny
lda #0
sta string_out,y
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_b (byte value @ A) clobbers(A,X,Y) {
asmsub str_b (byte value @ A) clobbers(X) -> str @AY {
; ---- convert the byte in A in decimal string form, without left padding 0s
%asm {{
ldy #0
sty P8ZP_SCRATCH_B1
cmp #0
bpl +
pha
lda #'-'
sta string_out
inc P8ZP_SCRATCH_B1
pla
ldy #0
sty P8ZP_SCRATCH_B1
cmp #0
bpl +
pha
lda #'-'
sta string_out
inc P8ZP_SCRATCH_B1
pla
+ jsr conv.byte2decimal
bra str_ub._output_byte_digits
bra str_ub._output_byte_digits
}}
}
asmsub str_ubhex (ubyte value @ A) clobbers(A,X,Y) {
asmsub str_ubhex (ubyte value @ A) clobbers(X) -> str @AY {
; ---- convert the ubyte in A in hex string form
%asm {{
jsr conv.ubyte2hex
sta string_out
sty string_out+1
lda #0
sta string_out+2
rts
jsr conv.ubyte2hex
sta string_out
sty string_out+1
lda #0
sta string_out+2
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_ubbin (ubyte value @ A) clobbers(A,X,Y) {
asmsub str_ubbin (ubyte value @ A) clobbers(X) -> str @AY {
; ---- convert the ubyte in A in binary string form
%asm {{
sta P8ZP_SCRATCH_B1
@ -90,18 +96,20 @@ asmsub str_ubbin (ubyte value @ A) clobbers(A,X,Y) {
sty string_out+8
ldy #7
- lsr P8ZP_SCRATCH_B1
bcc +
lda #'1'
bne _digit
+ lda #'0'
_digit sta string_out,y
dey
bcc +
lda #'1'
bne _digit
+ lda #'0'
_digit sta string_out,y
dey
bpl -
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_uwbin (uword value @ AY) clobbers(A,X,Y) {
asmsub str_uwbin (uword value @ AY) clobbers(X) -> str @AY {
; ---- convert the uword in A/Y in binary string form
%asm {{
sta P8ZP_SCRATCH_REG
@ -111,79 +119,88 @@ asmsub str_uwbin (uword value @ AY) clobbers(A,X,Y) {
sty string_out+16
ldy #7
- lsr P8ZP_SCRATCH_REG
bcc +
lda #'1'
bne _digit
+ lda #'0'
_digit sta string_out+8,y
dey
bcc +
lda #'1'
bne _digit
+ lda #'0'
_digit sta string_out+8,y
dey
bpl -
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_uwhex (uword value @ AY) clobbers(A,Y) {
asmsub str_uwhex (uword value @ AY) -> str @AY {
; ---- convert the uword in A/Y in hexadecimal string form (4 digits)
%asm {{
pha
tya
jsr conv.ubyte2hex
sta string_out
sty string_out+1
pla
jsr conv.ubyte2hex
sta string_out+2
sty string_out+3
lda #0
sta string_out+4
rts
pha
tya
jsr conv.ubyte2hex
sta string_out
sty string_out+1
pla
jsr conv.ubyte2hex
sta string_out+2
sty string_out+3
lda #0
sta string_out+4
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_uw0 (uword value @ AY) clobbers(A,X,Y) {
asmsub str_uw0 (uword value @ AY) clobbers(X) -> str @AY {
; ---- convert the uword in A/Y in decimal string form, with left padding 0s (5 positions total)
%asm {{
jsr conv.uword2decimal
ldy #0
- lda conv.uword2decimal.decTenThousands,y
sta string_out,y
beq +
iny
bne -
+ rts
- lda conv.uword2decimal.decTenThousands,y
sta string_out,y
beq +
iny
bne -
+
lda #<string_out
ldy #>string_out
rts
}}
}
asmsub str_uw (uword value @ AY) clobbers(A,X,Y) {
asmsub str_uw (uword value @ AY) clobbers(X) -> str @AY {
; ---- convert the uword in A/Y in decimal string form, without left padding 0s
%asm {{
jsr conv.uword2decimal
ldx #0
_output_digits
ldy #0
- lda conv.uword2decimal.decTenThousands,y
beq _allzero
cmp #'0'
bne _gotdigit
iny
bne -
- lda conv.uword2decimal.decTenThousands,y
beq _allzero
cmp #'0'
bne _gotdigit
iny
bne -
_gotdigit sta string_out,x
inx
iny
lda conv.uword2decimal.decTenThousands,y
bne _gotdigit
_end lda #0
sta string_out,x
rts
inx
iny
lda conv.uword2decimal.decTenThousands,y
bne _gotdigit
_end lda #0
sta string_out,x
lda #<string_out
ldy #>string_out
rts
_allzero lda #'0'
sta string_out,x
inx
bne _end
sta string_out,x
inx
bne _end
}}
}
asmsub str_w (word value @ AY) clobbers(A,X,Y) {
asmsub str_w (word value @ AY) clobbers(X) -> str @AY {
; ---- convert the (signed) word in A/Y in decimal string form, without left padding 0's
%asm {{
cpy #0
@ -191,18 +208,19 @@ asmsub str_w (word value @ AY) clobbers(A,X,Y) {
pha
lda #'-'
sta string_out
tya
eor #255
tay
pla
eor #255
clc
adc #1
bcc +
iny
tya
eor #255
tay
pla
eor #255
clc
adc #1
bcc +
iny
+ jsr conv.uword2decimal
ldx #1
bne str_uw._output_digits
rts
}}
}

View File

@ -493,8 +493,7 @@ no_mciout:
str device_not_present_error = "device not present #xx"
if cbm.READST()==128 {
device_not_present_error[len(device_not_present_error)-2] = 0
conv.str_ub(drivenumber)
void string.copy(conv.string_out, &device_not_present_error+len(device_not_present_error)-2)
void string.copy(conv.str_ub(drivenumber), &device_not_present_error+len(device_not_present_error)-2)
return device_not_present_error
}

View File

@ -429,8 +429,7 @@ _end rts
str device_not_present_error = "device not present #xx"
if cbm.READST()==128 {
device_not_present_error[len(device_not_present_error)-2] = 0
conv.str_ub(drivenumber)
void string.copy(conv.string_out, &device_not_present_error+len(device_not_present_error)-2)
void string.copy(conv.str_ub(drivenumber), &device_not_present_error+len(device_not_present_error)-2)
return device_not_present_error
}
uword messageptr = &list_filename

View File

@ -8,7 +8,7 @@ conv {
str string_out = "????????????????" ; result buffer for the string conversion routines
sub str_ub0(ubyte value) {
sub str_ub0(ubyte value) -> str {
; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total)
ubyte hundreds = value / 100
value -= hundreds*100
@ -18,14 +18,16 @@ sub str_ub0(ubyte value) {
string_out[1] = tens+'0'
string_out[2] = value+'0'
string_out[3] = 0
return string_out
}
sub str_ub(ubyte value) {
sub str_ub(ubyte value) -> str {
; ---- convert the ubyte in A in decimal string form, without left padding 0s
internal_str_ub(value, string_out)
return string_out
}
sub str_b(byte value) {
sub str_b(byte value) -> str {
; ---- convert the byte in A in decimal string form, without left padding 0s
uword out_ptr = &string_out
if value<0 {
@ -34,6 +36,7 @@ sub str_b(byte value) {
value = -value
}
internal_str_ub(value as ubyte, out_ptr)
return string_out
}
sub internal_str_ub(ubyte value, uword out_ptr) {
@ -60,14 +63,15 @@ output_ones:
str hex_digits = "0123456789abcdef"
sub str_ubhex (ubyte value) {
sub str_ubhex (ubyte value) -> str {
; ---- convert the ubyte in A in hex string form
string_out[0] = hex_digits[value>>4]
string_out[1] = hex_digits[value&15]
string_out[2] = 0
return string_out
}
sub str_ubbin (ubyte value) {
sub str_ubbin (ubyte value) -> str {
; ---- convert the ubyte in A in binary string form
uword out_ptr = &string_out
repeat 8 {
@ -79,9 +83,10 @@ sub str_ubbin (ubyte value) {
out_ptr++
}
@(out_ptr) = 0
return string_out
}
sub str_uwbin (uword value) {
sub str_uwbin (uword value) -> str {
; ---- convert the uword in A/Y in binary string form
uword out_ptr = &string_out
repeat 16 {
@ -93,9 +98,10 @@ sub str_uwbin (uword value) {
out_ptr++
}
@(out_ptr) = 0
return string_out
}
sub str_uwhex (uword value) {
sub str_uwhex (uword value) -> str {
; ---- convert the uword in A/Y in hexadecimal string form (4 digits)
ubyte bits = msb(value)
string_out[0] = hex_digits[bits>>4]
@ -104,9 +110,10 @@ sub str_uwhex (uword value) {
string_out[2] = hex_digits[bits>>4]
string_out[3] = hex_digits[bits&15]
string_out[4] = 0
return string_out
}
sub str_uw0 (uword value) {
sub str_uw0 (uword value) -> str {
; ---- convert the uword in A/Y in decimal string form, with left padding 0s (5 positions total)
uword value2 = value/10
ubyte digits = value-value2*10 as ubyte
@ -124,14 +131,16 @@ sub str_uw0 (uword value) {
string_out[3] = tens+'0'
string_out[4] = digits+'0'
string_out[5] = 0
return string_out
}
sub str_uw (uword value) {
sub str_uw (uword value) -> str {
; ---- convert the uword in A/Y in decimal string form, without left padding 0s
internal_str_uw(value, string_out)
return string_out
}
sub str_w (word value) {
sub str_w (word value) -> str {
; ---- convert the (signed) word in A/Y in decimal string form, without left padding 0's
uword out_ptr = &string_out
if value<0 {
@ -140,6 +149,7 @@ sub str_w (word value) {
value = -value
}
internal_str_uw(value as uword, out_ptr)
return string_out
}
sub internal_str_uw(uword value, uword out_ptr) {

View File

@ -61,70 +61,60 @@ sub print (str text) {
sub print_ub0 (ubyte value) {
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
conv.str_ub0(value)
print(conv.string_out)
print(conv.str_ub0(value))
}
sub print_ub (ubyte value) {
; ---- print the ubyte in decimal form, without left padding 0s
conv.str_ub(value)
print(conv.string_out)
print(conv.str_ub(value))
}
sub print_b (byte value) {
; ---- print the byte in decimal form, without left padding 0s
conv.str_b(value)
print(conv.string_out)
print(conv.str_b(value))
}
sub print_ubhex (ubyte value, ubyte prefix) {
; ---- print the ubyte in hex form
if prefix
chrout('$')
conv.str_ubhex(value)
print(conv.string_out)
print(conv.str_ubhex(value))
}
sub print_ubbin (ubyte value, ubyte prefix) {
; ---- print the ubyte in binary form
if prefix
chrout('%')
conv.str_ubbin(value)
print(conv.string_out)
print(conv.str_ubbin(value))
}
sub print_uwbin (uword value, ubyte prefix) {
; ---- print the uword in binary form
if prefix
chrout('%')
conv.str_uwbin(value)
print(conv.string_out)
print(conv.str_uwbin(value))
}
sub print_uwhex (uword value, ubyte prefix) {
; ---- print the uword in hexadecimal form (4 digits)
if prefix
chrout('$')
conv.str_uwhex(value)
print(conv.string_out)
print(conv.str_uwhex(value))
}
sub print_uw0 (uword value) {
; ---- print the uword value in decimal form, with left padding 0s (5 positions total)
conv.str_uw0(value)
print(conv.string_out)
print(conv.str_uw0(value))
}
sub print_uw (uword value) {
; ---- print the uword in decimal form, without left padding 0s
conv.str_uw(value)
print(conv.string_out)
print(conv.str_uw(value))
}
sub print_w (word value) {
; ---- print the (signed) word in decimal form, without left padding 0's
conv.str_w(value)
print(conv.string_out)
print(conv.str_w(value))
}
sub input_chars (uword buffer) -> ubyte {

View File

@ -179,7 +179,9 @@ internal class AstChecker(private val program: Program,
}
val iterableDt = forLoop.iterable.inferType(program).getOr(DataType.BYTE)
if(iterableDt !in IterableDatatypes && forLoop.iterable !is RangeExpression) {
if(forLoop.iterable is IFunctionCall) {
errors.err("can not loop over function call return value", forLoop.position)
} else if(iterableDt !in IterableDatatypes && forLoop.iterable !is RangeExpression) {
errors.err("can only loop over an iterable type", forLoop.position)
} else {
val loopvar = forLoop.loopVar.targetVarDecl(program)

View File

@ -1,6 +1,10 @@
TODO
====
add a zsmkit example (next to zsound example)
fix compiler crash for for cx16.r9L in conv.str_ub(number) {...} : can't iterate over class prog8.code.ast.PtFunctionCall - should have been replaced by a variable
...
@ -26,14 +30,14 @@ Compiler:
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
- (need separate step in codegen and IR to write the "golden" variables)
- VM: implement more diskio support
- do we need (array)variable alignment tag instead of block alignment tag? You want to align the data, not the code in the block?
- VM: implement diskio support (let's start with the basics load, save, delete, rename, status?. no streaming, no directory listing)
- ir: related to the one above: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
- ir: fix call() return value handling
- ir: proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
global initialization values are simply a list of LOAD instructions.
Variables replaced include all subroutine parameters! So the only variables that remain as variables are arrays and strings.
- ir: fix call() return value handling
- ir: add more optimizations in IRPeepholeOptimizer
- ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
maybe another representation is needed once actual codegeneration is done from the IR...?
@ -51,7 +55,6 @@ Compiler:
Libraries:
- gfx2: add EOR mode support like in monogfx and see PAINT for inspiration. Self modifying code to keep it optimized?
- conv: the routines could return the address of conv.string_out, and/or there could be versions that take the address of a different buffer and use it instead.
- once kernal rom v47 is released, remove most of the workarounds in cx16 floats.parse_f() . Prototype parse routine in examples/cx16/floatparse.p8
- fix the problems in atari target, and flesh out its libraries.
- c128 target: make syslib more complete (missing kernal routines)?

View File

@ -55,10 +55,11 @@ main {
for cx16.r9L in "Cellular Automaton #" {
cx16.GRAPH_put_next_char(cx16.r9L)
}
conv.str_ub(number)
for cx16.r9L in conv.string_out {
cx16.GRAPH_put_next_char(cx16.r9L)
}
uword num_str = conv.str_ub(number)
do {
cx16.GRAPH_put_next_char(@(num_str))
num_str++
} until @(num_str)==0
}
bool[8] states

View File

@ -179,8 +179,8 @@ main {
uword vmem = vmembase * 2048 ; mkword(vmembase,0) * 8
ubyte bank = vmembase>=32
vmem += 35
conv.str_uw0(number)
uword pixelsptr = &numberpixels + (conv.string_out[1] & 15)*7
uword number_str = conv.str_uw0(number)
uword pixelsptr = &numberpixels + (number_str[1] & 15)*7
ubyte pix
cx16.VERA_CTRL = 0
cx16.VERA_ADDR_L = lsb(vmem)
@ -191,19 +191,19 @@ main {
vmem++
cx16.VERA_ADDR_L = lsb(vmem)
cx16.VERA_ADDR_M = msb(vmem)
pixelsptr = &numberpixels + (conv.string_out[2] & 15)*7
pixelsptr = &numberpixels + (number_str[2] & 15)*7
for pix in 0 to 6
cx16.VERA_DATA0 = pixelsptr[pix]
vmem++
cx16.VERA_ADDR_L = lsb(vmem)
cx16.VERA_ADDR_M = msb(vmem)
pixelsptr = &numberpixels + (conv.string_out[3] & 15)*7
pixelsptr = &numberpixels + (number_str[3] & 15)*7
for pix in 0 to 6
cx16.VERA_DATA0 = pixelsptr[pix]
vmem++
cx16.VERA_ADDR_L = lsb(vmem)
cx16.VERA_ADDR_M = msb(vmem)
pixelsptr = &numberpixels + (conv.string_out[4] & 15)*7
pixelsptr = &numberpixels + (number_str[4] & 15)*7
for pix in 0 to 6
cx16.VERA_DATA0 = pixelsptr[pix]
}

View File

@ -60,9 +60,11 @@ main {
}
sub print_number_gfx(ubyte num) {
conv.str_ub(num)
for cx16.r9L in conv.string_out
cx16.GRAPH_put_next_char(cx16.r9L)
uword num_str = conv.str_ub(num)
do {
cx16.GRAPH_put_next_char(@(num_str))
num_str++
} until @(num_str)==0
}
const uword screen_width = 320