started changing libs to typed pointers

This commit is contained in:
Irmen de Jong
2025-07-20 11:47:35 +02:00
parent c3be7ab4b3
commit 23058b51a1
9 changed files with 204 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
compression {
sub decode_rle(uword @zp compressed, uword @zp target, uword maxsize) -> uword {
sub decode_rle(^^ubyte @zp compressed, ^^ubyte @zp target, uword maxsize) -> uword {
cx16.r0 = target ; original target
cx16.r1 = target+maxsize ; decompression limit
@@ -30,7 +30,7 @@ compression {
return target-cx16.r0
}
sub encode_rle(uword data, uword size, uword target, bool is_last_block) -> uword {
sub encode_rle(^^ubyte data, uword size, ^^ubyte target, bool is_last_block) -> uword {
; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding.
; Returns the size of the compressed RLE data. Worst case result storage size needed = (size + (size+126) / 127) + 1.
; is_last_block = usually true, but you can set it to false if you want to concatenate multiple
@@ -39,7 +39,7 @@ compression {
uword idx = 0
uword literals_start_idx = 0
ubyte literals_length = 0
uword orig_target = target
^^ubyte orig_target = target
sub next_same_span() {
; returns length in cx16.r1L, and the byte value in cx16.r1H
@@ -54,7 +54,7 @@ compression {
sub output_literals() {
@(target) = literals_length-1
target++
uword dataptr = data + literals_start_idx
^^ubyte dataptr = data + literals_start_idx
ubyte i
for i in 0 to literals_length-1 {
@(target) = @(dataptr)

View File

@@ -29,7 +29,7 @@ sub str_ub(ubyte value) -> str {
sub str_b(byte value) -> str {
; ---- convert the byte in A in decimal string form, without left padding 0s
uword out_ptr = &string_out
^^ubyte out_ptr = &string_out
if value<0 {
@(out_ptr) = '-'
out_ptr++
@@ -39,7 +39,7 @@ sub str_b(byte value) -> str {
return string_out
}
sub internal_str_ub(ubyte value, uword out_ptr) {
sub internal_str_ub(ubyte value, str out_ptr) {
ubyte hundreds = value / 100
value -= hundreds*100
ubyte tens = value / 10
@@ -73,7 +73,7 @@ sub str_ubhex (ubyte value) -> str {
sub str_ubbin (ubyte value) -> str {
; ---- convert the ubyte in A in binary string form
uword out_ptr = &string_out
^^ubyte out_ptr = &string_out
repeat 8 {
rol(value)
if_cc
@@ -88,7 +88,7 @@ sub str_ubbin (ubyte value) -> str {
sub str_uwbin (uword value) -> str {
; ---- convert the uword in A/Y in binary string form
uword out_ptr = &string_out
^^ubyte out_ptr = &string_out
repeat 16 {
rol(value)
if_cc
@@ -142,7 +142,7 @@ sub str_uw (uword value) -> str {
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
^^ubyte out_ptr = &string_out
if value<0 {
@(out_ptr) = '-'
out_ptr++
@@ -152,7 +152,7 @@ sub str_w (word value) -> str {
return string_out
}
sub internal_str_uw(uword value, uword out_ptr) {
sub internal_str_uw(uword value, str out_ptr) {
uword value2 = value/10
ubyte digits = value-value2*10 as ubyte
uword value3 = value2/10

View File

@@ -316,7 +316,7 @@ math {
return w2-w1
}
sub crc16(uword data, uword length) -> uword {
sub crc16(^^ubyte data, uword length) -> uword {
; calculates the CRC16 (XMODEM) checksum of the buffer.
; There are also "streaming" crc16_start/update/end routines below, that allow you to calculate crc32 for data that doesn't fit in a single memory block.
crc16_start()
@@ -353,7 +353,7 @@ math {
return cx16.r15
}
sub crc32(uword data, uword length) {
sub crc32(^^ubyte data, uword length) {
; Calculates the CRC-32 (ISO-HDLC/PKZIP) checksum of the buffer.
; because prog8 doesn't have 32 bits integers, we have to split up the calculation over 2 words.
; result stored in cx16.r14 (low word) and cx16.r15 (high word)

View File

@@ -5,7 +5,7 @@
sorting {
%option ignore_unused
sub shellsort_ub(uword @requirezp values, ubyte num_elements) {
sub shellsort_ub(^^ubyte @requirezp values, ubyte num_elements) {
num_elements--
ubyte @zp gap
for gap in [132, 57, 23, 10, 4, 1] {
@@ -27,29 +27,29 @@ sorting {
}
}
sub shellsort_uw(uword @requirezp values, ubyte num_elements) {
sub shellsort_uw(^^uword @requirezp values, ubyte num_elements) {
num_elements--
ubyte gap
for gap in [132, 57, 23, 10, 4, 1] {
ubyte i
for i in gap to num_elements {
uword @zp temp = peekw(values+i*$0002)
uword @zp temp = values[i]
ubyte @zp j = i
ubyte @zp k = j-gap
while j>=gap {
uword @zp v = peekw(values+k*2)
uword @zp v = values[k]
if v <= temp break
pokew(values+j*2, v)
values[j] = v
j = k
k -= gap
}
pokew(values+j*2, temp)
values[j] = temp
}
}
}
sub shellsort_by_ub(uword @requirezp ub_keys, uword @requirezp wordvalues, ubyte num_elements) {
sub shellsort_by_ub(^^ubyte @requirezp ub_keys, ^^uword @requirezp wordvalues, ubyte num_elements) {
; sorts the 'wordvalues' array (no-split array of words) according to the 'ub_keys' array (which also gets sorted ofcourse).
num_elements--
ubyte @zp gap
@@ -57,7 +57,7 @@ sorting {
ubyte i
for i in gap to num_elements {
ubyte @zp temp = ub_keys[i]
uword temp_wv = peekw(wordvalues + i*$0002)
uword temp_wv = wordvalues[i]
ubyte @zp j = i
ubyte @zp k = j-gap
repeat {
@@ -65,17 +65,17 @@ sorting {
if v <= temp break
if j < gap break
ub_keys[j] = v
pokew(wordvalues + j*$0002, peekw(wordvalues + k*$0002))
wordvalues[j] = wordvalues[k]
j = k
k -= gap
}
ub_keys[j] = temp
pokew(wordvalues + j*$0002, temp_wv)
wordvalues[j] = temp_wv
}
}
}
sub shellsort_by_uw(uword @requirezp uw_keys, uword @requirezp wordvalues, ubyte num_elements) {
sub shellsort_by_uw(^^uword @requirezp uw_keys, ^^uword @requirezp wordvalues, ubyte num_elements) {
; sorts the 'wordvalues' array according to the 'uw_keys' array (which also gets sorted ofcourse).
; both arrays should be no-split array of words. uw_keys are unsigned.
num_elements--
@@ -83,20 +83,20 @@ sorting {
for gap in [132, 57, 23, 10, 4, 1] {
ubyte i
for i in gap to num_elements {
uword @zp temp = peekw(uw_keys+i*$0002)
uword temp_wv = peekw(wordvalues + i*$0002)
uword @zp temp = uw_keys[i]
uword temp_wv = wordvalues[i]
ubyte @zp j = i
ubyte @zp k = j-gap
while j>=gap {
uword @zp v = peekw(uw_keys+k*2)
uword @zp v = uw_keys[k]
if v <= temp break
pokew(uw_keys+j*2, v)
pokew(wordvalues + j*$0002, peekw(wordvalues + k*$0002))
uw_keys[j] = v
wordvalues[j] = wordvalues[k]
j = k
k -= gap
}
pokew(uw_keys+j*2, temp)
pokew(wordvalues + j*$0002, temp_wv)
uw_keys[j] = temp
wordvalues[j] = temp_wv
}
}
}

View File

@@ -82,7 +82,7 @@ strings {
return 255, false
}
sub rfind(uword stringptr, ubyte character) -> ubyte, bool {
sub rfind(str stringptr, ubyte character) -> ubyte, bool {
; Locates the first position of the given character in the string, starting from the right.
; returns index in A, and boolean if found or not. (when false A will also be 255, an invalid index).
ubyte ix

View File

@@ -48,7 +48,7 @@ sys {
}}
}
sub internal_stringcopy(uword source, uword tgt) {
sub internal_stringcopy(str source, str tgt) {
; Called when the compiler wants to assign a string value to another string.
%ir {{
loadm.w r99000,sys.internal_stringcopy.source

View File

@@ -136,7 +136,7 @@ sub print_w (word value) {
print(conv.str_w(value))
}
sub input_chars (uword buffer) -> ubyte {
sub input_chars (str buffer) -> ubyte {
; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well)
; It assumes the keyboard is selected as I/O channel!
%ir {{

View File

@@ -61,7 +61,8 @@ STRUCTS and TYPED POINTERS
- DONE: fixed support for (expression) array index dereferencing "array[2]^^" where array contains pointers to primitives: replace with peek()
- DONE: fixed support for (assigntarget) array index dereferencing "array[2]^^" where array contains pointers to primitives: replace with poke()
- write docs in structpointers.rst
- scan through virtual library modules to change untyped uword pointers to typed pointers: compression, conv, diskio, math, sorting, strings, syslib, textio.
- scan through virtual library modules to change untyped uword pointers to typed pointers: diskio.
- virtual/sorting.p8 module generates slightly less efficient code than the old version with untyped uword pointers
- add support for array index dereferencing as assign target "array[2]^^.value = 99" where array is struct pointers (currently a 'no support' error)
- add support for array index dereferencing as assign target "array[2].value = 99" where array is struct pointers (currently a parser error)
- try to fix parse error l1^^.s[0] = 4242 (equivalent to l1.s[0]=4242 , which does parse correctly)

View File

@@ -1,19 +1,179 @@
%option no_sysinit
%zeropage basicsafe
%import textio
%import compression
%import math
%import sorting
%import strings
%import diskio
main {
sub start() {
^^word ptr
test_compression()
test_math()
test_sorting()
test_syslib()
test_strings()
test_conv()
test_diskio()
;test_textio()
}
if ptr!=0
cx16.r0++
if ptr==0
cx16.r0++
sub test_diskio() {
txt.print("--diskio--\n")
sys.memset(target, len(target), 0)
diskio.delete("derp.bin")
void diskio.f_open_w("derp.bin")
repeat 12
void diskio.f_write("derpderp123", 11)
diskio.f_close_w()
cx16.r0 = if ptr!=0 0 else ptr
cx16.r1 = if ptr==0 0 else ptr
cx16.r2 = if ptr!=0 ptr else 0
cx16.r3 = if ptr==0 ptr else 0
void diskio.f_open("derp.bin")
diskio.f_read(target, 60)
txt.print(target)
txt.nl()
}
ubyte[100] target
sub test_conv() {
txt.print("--conv--\n")
txt.print_b(-111)
txt.spc()
txt.print_ub(222)
txt.spc()
txt.print_uw(22222)
txt.spc()
txt.print_w(-22222)
txt.nl()
txt.print_ubbin(222, true)
txt.spc()
txt.print_ubhex(222, true)
txt.spc()
txt.print_uwbin(2222, true)
txt.spc()
txt.print_uwhex(2222, true)
txt.nl()
txt.print_ub0(1)
txt.spc()
txt.print_uw0(123)
txt.nl()
}
sub test_strings() {
txt.print("--strings--\n")
ubyte idx
bool found
idx, found = strings.rfind(source, '1')
txt.print_ub(idx)
txt.nl()
}
sub test_textio() {
txt.print("--textio--\n")
txt.print("enter some input: ")
void txt.input_chars(&target)
txt.print(target)
txt.nl()
}
sub test_syslib() {
txt.print("--syslib--\n")
sys.internal_stringcopy(source, target)
txt.print(target)
txt.nl()
sys.memset(target, sizeof(target), 0)
txt.print(target)
txt.nl()
sys.memcopy(source, target, len(source))
txt.print(target)
txt.nl()
sys.memsetw(&target as ^^uword, 20, $5051)
txt.print(target)
txt.nl()
txt.print_b(sys.memcmp(source, target, len(source)))
txt.nl()
}
sub test_sorting() {
txt.print("--sorting--\n")
ubyte[] bytes1 = [77,33,44,99,11,55]
ubyte[] bytes2 = [77,33,44,99,11,55]
uword[] @nosplit values1 = [1,2,3,4,5,6]
uword[] @nosplit words1 = [777,333,444,999,111,555]
uword[] @nosplit words2 = [777,333,444,999,111,555]
uword[] @nosplit values2 = [1,2,3,4,5,6]
sorting.shellsort_ub(&bytes1, len(bytes1))
sorting.shellsort_by_ub(&bytes2, &values1, len(bytes2))
sorting.shellsort_uw(&words1, len(words1))
sorting.shellsort_by_uw(&words2, &values2, len(words2))
for cx16.r0L in bytes1 {
txt.print_ub(cx16.r0L)
txt.spc()
}
txt.nl()
for cx16.r0L in bytes2 {
txt.print_ub(cx16.r0L)
txt.spc()
}
txt.nl()
for cx16.r0 in values1 {
txt.print_uw(cx16.r0)
txt.spc()
}
txt.nl()
for cx16.r0 in words1 {
txt.print_uw(cx16.r0)
txt.spc()
}
txt.nl()
for cx16.r0 in words2 {
txt.print_uw(cx16.r0)
txt.spc()
}
txt.nl()
for cx16.r0 in values2 {
txt.print_uw(cx16.r0)
txt.spc()
}
txt.nl()
}
sub test_math() {
txt.print("--math--\n")
txt.print("expected 15567: ")
txt.print_uw(math.crc16(source, len(source)))
txt.print("\nexpected 8747,54089: ")
math.crc32(source, len(source))
txt.print_uw(cx16.r14)
txt.chrout(',')
txt.print_uw(cx16.r15)
txt.nl()
}
str source = petscii:"Lorem ipsuuuuuuuuuuuum dollllllllllllllloooooooor sit ametttttttttttttttt, cccccccccccccccconsecteeeeetuuuuuur aaaaaaaaa111111222222333333444444"
sub test_compression() {
txt.print("--compression--\n")
ubyte[256] compressed
ubyte[256] decompressed
txt.print_uw(len(source))
txt.nl()
uword size = compression.encode_rle(source, len(source), compressed, true)
txt.print_uw(size)
txt.nl()
size = compression.decode_rle(compressed, decompressed, sizeof(decompressed))
txt.print_uw(size)
txt.nl()
txt.print(source)
txt.nl()
txt.print(decompressed)
txt.nl()
}
}