diff --git a/compiler/res/prog8lib/virtual/compression.p8 b/compiler/res/prog8lib/virtual/compression.p8 index af0dd9dbb..f6a98b416 100644 --- a/compiler/res/prog8lib/virtual/compression.p8 +++ b/compiler/res/prog8lib/virtual/compression.p8 @@ -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) diff --git a/compiler/res/prog8lib/virtual/conv.p8 b/compiler/res/prog8lib/virtual/conv.p8 index 2d63d1825..d42cf1b24 100644 --- a/compiler/res/prog8lib/virtual/conv.p8 +++ b/compiler/res/prog8lib/virtual/conv.p8 @@ -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 diff --git a/compiler/res/prog8lib/virtual/math.p8 b/compiler/res/prog8lib/virtual/math.p8 index 8de40afbf..cd33c442d 100644 --- a/compiler/res/prog8lib/virtual/math.p8 +++ b/compiler/res/prog8lib/virtual/math.p8 @@ -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) diff --git a/compiler/res/prog8lib/virtual/sorting.p8 b/compiler/res/prog8lib/virtual/sorting.p8 index 313af25bc..a45ed8261 100644 --- a/compiler/res/prog8lib/virtual/sorting.p8 +++ b/compiler/res/prog8lib/virtual/sorting.p8 @@ -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 } } } diff --git a/compiler/res/prog8lib/virtual/strings.p8 b/compiler/res/prog8lib/virtual/strings.p8 index 8a69dab54..5c24858f5 100644 --- a/compiler/res/prog8lib/virtual/strings.p8 +++ b/compiler/res/prog8lib/virtual/strings.p8 @@ -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 diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index 5f363e69e..0f2e9a8a5 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -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 diff --git a/compiler/res/prog8lib/virtual/textio.p8 b/compiler/res/prog8lib/virtual/textio.p8 index 790598bf3..28fa37f63 100644 --- a/compiler/res/prog8lib/virtual/textio.p8 +++ b/compiler/res/prog8lib/virtual/textio.p8 @@ -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 {{ diff --git a/docs/source/todo.rst b/docs/source/todo.rst index aad0f4f07..4a8e88d35 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -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) diff --git a/examples/test.p8 b/examples/test.p8 index a499dd02f..0fbd6a3f0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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() } }