From 9fb8526136ed62e689f2c1d7641876dcf269e5e6 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 15 Oct 2020 23:36:03 +0200 Subject: [PATCH] added conv.bin and hex string to number --- compiler/res/prog8lib/conv.p8 | 82 +++++++++++++++++-- .../codegen/assignment/AssignmentAsmGen.kt | 2 +- docs/source/libraries.rst | 4 +- docs/source/todo.rst | 2 +- examples/test.p8 | 56 ++----------- 5 files changed, 87 insertions(+), 59 deletions(-) diff --git a/compiler/res/prog8lib/conv.p8 b/compiler/res/prog8lib/conv.p8 index 081851ec3..e280db7dd 100644 --- a/compiler/res/prog8lib/conv.p8 +++ b/compiler/res/prog8lib/conv.p8 @@ -250,7 +250,7 @@ output .text "0000", $00 ; 0-terminated output buffer (to make printing ea } -asmsub str2ubyte(str string @ AY) clobbers(Y) -> ubyte @A { +asmsub str2ubyte(str string @ AY) clobbers(Y) -> ubyte @A { ; -- returns the unsigned byte value of the string number argument in AY ; the number may NOT be preceded by a + sign and may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) @@ -260,8 +260,7 @@ asmsub str2ubyte(str string @ AY) clobbers(Y) -> ubyte @A { }} } - -asmsub str2byte(str string @ AY) clobbers(Y) -> ubyte @A { +asmsub str2byte(str string @ AY) clobbers(Y) -> ubyte @A { ; -- returns the signed byte value of the string number argument in AY ; the number may be preceded by a + or - sign but may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) @@ -271,7 +270,7 @@ asmsub str2byte(str string @ AY) clobbers(Y) -> ubyte @A { }} } -asmsub str2uword(str string @ AY) -> uword @ AY { +asmsub str2uword(str string @ AY) -> uword @ AY { ; -- returns the unsigned word value of the string number argument in AY ; the number may NOT be preceded by a + sign and may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) @@ -325,7 +324,7 @@ _result_times_10 ; (W*4 + W)*2 }} } -asmsub str2word(str string @ AY) -> word @ AY { +asmsub str2word(str string @ AY) -> word @ AY { ; -- returns the signed word value of the string number argument in AY ; the number may be preceded by a + or - sign but may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) @@ -380,4 +379,77 @@ _negative .byte 0 }} } +asmsub hex2uword(str string @ AY) -> uword @AY { + ; -- hexadecimal string with or without '$' to uword. + ; string may be in petscii or c64-screencode encoding. + %asm {{ + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + sty P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 +_loop ldy #0 + sty P8ZP_SCRATCH_B1 + lda (P8ZP_SCRATCH_W2),y + beq _stop + cmp #'$' + beq _skip + cmp #7 + bcc _add_nine + cmp #'9' + beq _calc + bcs _add_nine +_calc asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + and #$0f + clc + adc P8ZP_SCRATCH_B1 + ora P8ZP_SCRATCH_W1 + sta P8ZP_SCRATCH_W1 +_skip inc P8ZP_SCRATCH_W2 + bne _loop + inc P8ZP_SCRATCH_W2+1 + bne _loop +_stop lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + rts +_add_nine ldy #9 + sty P8ZP_SCRATCH_B1 + bne _calc + }} +} + +asmsub bin2uword(str string @ AY) -> uword @AY { + ; -- binary string with or without '%' to uword. + %asm {{ + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + sty P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 +_loop lda (P8ZP_SCRATCH_W2),y + beq _stop + cmp #'%' + beq + + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + and #1 + ora P8ZP_SCRATCH_W1 + sta P8ZP_SCRATCH_W1 ++ inc P8ZP_SCRATCH_W2 + bne _loop + inc P8ZP_SCRATCH_W2+1 + bne _loop +_stop lda P8ZP_SCRATCH_W1 + ldy P8ZP_SCRATCH_W1+1 + rts + }} +} + } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index 52f0f9ce3..c764c55b3 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -43,7 +43,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } SourceStorageKind.VARIABLE -> { // simple case: assign from another variable - val variable = assign.source.asmVarname!! + val variable = assign.source.asmVarname when (assign.target.datatype) { DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable) DataType.UWORD, DataType.WORD -> assignVariableWord(assign.target, variable) diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index f9c6c6136..e31a380af 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -35,8 +35,8 @@ conv Routines to convert strings to numbers or vice versa. - numbers to strings, in various formats (binary, hex, decimal) -- strings in decimal format into numbers -- (TODO: strings in hex and binary format into numbers) +- strings in decimal, hex and binary format into numbers + textio (txt.*) -------------- diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 93be5a19e..a88b764ac 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -4,7 +4,7 @@ TODO - get rid of all other TODO's in the code ;-) - introduce strcmp() -- modify string comparsion expressions to use strcmp() automatically +- modify string comparison expressions to use strcmp() automatically - only allow array indexing via a number, a variable, or a typecast of one of those (eliminate complex expression calcs for array indexing, force explicit use of an index variable) - implement @stack for asmsub parameters - make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_' diff --git a/examples/test.p8 b/examples/test.p8 index 409ede72d..1ff6e0706 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -15,27 +15,27 @@ main { txt.print(hex1) txt.chrout('=') - txt.print_uwhex(conv2.hex2uword(hex1), true) + txt.print_uwhex(conv.hex2uword(hex1), true) txt.chrout('\n') txt.print(hex2) txt.chrout('=') - txt.print_uwhex(conv2.hex2uword(hex2), true) + txt.print_uwhex(conv.hex2uword(hex2), true) txt.chrout('\n') txt.print(hex3) txt.chrout('=') - txt.print_uwhex(conv2.hex2uword(hex3), true) + txt.print_uwhex(conv.hex2uword(hex3), true) txt.chrout('\n') txt.print(hex4) txt.chrout('=') - txt.print_uwhex(conv2.hex2uword(hex4), true) + txt.print_uwhex(conv.hex2uword(hex4), true) txt.chrout('\n') txt.print(bin1) txt.chrout('=') - txt.print_uwbin(conv2.bin2uword(bin1), true) + txt.print_uwbin(conv.bin2uword(bin1), true) txt.chrout('\n') txt.print(bin2) txt.chrout('=') - txt.print_uwbin(conv2.bin2uword(bin2), true) + txt.print_uwbin(conv.bin2uword(bin2), true) txt.chrout('\n') @@ -57,47 +57,3 @@ _saveX .byte 0 }} } } - - -conv2 { - - sub hex2uword(uword strptr) -> uword { - uword result = 0 - while @(strptr) { - if @(strptr)!='$' { - ubyte add = 0 - if @(strptr) <= 6 or @(strptr) > '9' - add = 9 - result = (result << 4) | (add + @(strptr) & $0f) - } - strptr++ - } - return result - } - - asmsub bin2uword(uword strptr @AY) -> uword @AY { - %asm {{ - sta P8ZP_SCRATCH_W2 - sty P8ZP_SCRATCH_W2+1 - ldy #0 - sty P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 -_loop lda (P8ZP_SCRATCH_W2),y - beq _stop - cmp #'%' - beq + - asl P8ZP_SCRATCH_W1 - rol P8ZP_SCRATCH_W1+1 - and #1 - ora P8ZP_SCRATCH_W1 - sta P8ZP_SCRATCH_W1 -+ inc P8ZP_SCRATCH_W2 - bne _loop - inc P8ZP_SCRATCH_W2+1 - bne _loop -_stop lda P8ZP_SCRATCH_W1 - ldy P8ZP_SCRATCH_W1+1 - rts - }} - } -}