mirror of
https://github.com/irmen/prog8.git
synced 2024-07-10 23:29:02 +00:00
conv.bin2uword, conv.hex2uword, conv.str2uword, conv.str2word more robust and return parsed length in cx16.r15
This commit is contained in:
parent
76101d7f8d
commit
07dd64958f
@ -7,9 +7,9 @@
|
||||
|
||||
conv {
|
||||
|
||||
; ----- number conversions to decimal strings
|
||||
; ----- number conversions to decimal strings ----
|
||||
|
||||
asmsub ubyte2decimal (ubyte value @ A) -> ubyte @ Y, ubyte @ A, ubyte @ X {
|
||||
asmsub ubyte2decimal (ubyte value @A) -> ubyte @Y, ubyte @A, ubyte @X {
|
||||
; ---- A to decimal string in Y/A/X (100s in Y, 10s in A, 1s in X)
|
||||
%asm {{
|
||||
ldy #uword2decimal.ASCII_0_OFFSET
|
||||
@ -18,7 +18,7 @@ asmsub ubyte2decimal (ubyte value @ A) -> ubyte @ Y, ubyte @ A, ubyte @ X {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub uword2decimal (uword value @ AY) -> ubyte @Y, ubyte @A, ubyte @X {
|
||||
asmsub uword2decimal (uword value @AY) -> ubyte @Y, ubyte @A, ubyte @X {
|
||||
; ---- convert 16 bit uword in A/Y to decimal
|
||||
; output in uword2decimal.decTenThousands, decThousands, decHundreds, decTens, decOnes
|
||||
; (these are terminated by a zero byte so they can be easily printed)
|
||||
@ -193,11 +193,7 @@ decOnes .byte 0
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
; ----- utility functions ----
|
||||
|
||||
|
||||
asmsub byte2decimal (byte value @ A) -> ubyte @ Y, ubyte @ A, ubyte @ X {
|
||||
asmsub byte2decimal (byte value @A) -> ubyte @Y, ubyte @A, ubyte @X {
|
||||
; ---- A (signed byte) to decimal string in Y/A/X (100s in Y, 10s in A, 1s in X)
|
||||
; note: if the number is negative, you have to deal with the '-' yourself!
|
||||
%asm {{
|
||||
@ -210,7 +206,7 @@ asmsub byte2decimal (byte value @ A) -> ubyte @ Y, ubyte @ A, ubyte @ X {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub ubyte2hex (ubyte value @ A) -> ubyte @ A, ubyte @ Y {
|
||||
asmsub ubyte2hex (ubyte value @A) -> ubyte @A, ubyte @Y {
|
||||
; ---- A to hex petscii string in AY (first hex char in A, second hex char in Y)
|
||||
%asm {{
|
||||
stx P8ZP_SCRATCH_REG
|
||||
@ -232,7 +228,7 @@ _hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub uword2hex (uword value @ AY) clobbers(A,Y) {
|
||||
asmsub uword2hex (uword value @AY) clobbers(A,Y) {
|
||||
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string 'uword2hex.output' (0-terminated)
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_REG
|
||||
@ -250,10 +246,14 @@ output .text "0000", $00 ; 0-terminated output buffer (to make printing ea
|
||||
}
|
||||
|
||||
|
||||
; ---- string conversion to numbers -----
|
||||
|
||||
asmsub any2uword(str string @AY) -> uword @AY {
|
||||
; -- returns the number value of the given string
|
||||
; the string may be in decimal, hex or binary format
|
||||
; (the latter two require a $ or % prefix to be recognised)
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; result in AY, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%asm {{
|
||||
pha
|
||||
sta P8ZP_SCRATCH_W1
|
||||
@ -274,45 +274,51 @@ _bin pla
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
inline asmsub str2ubyte(str string @ AY) clobbers(Y) -> ubyte @A {
|
||||
; -- returns the unsigned byte value of the string number argument in AY
|
||||
inline asmsub str2ubyte(str string @AY) clobbers(Y) -> ubyte @A {
|
||||
; -- returns in A 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)
|
||||
; result in A, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%asm {{
|
||||
jsr conv.str2uword
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub str2byte(str string @ AY) clobbers(Y) -> ubyte @A {
|
||||
; -- returns the signed byte value of the string number argument in AY
|
||||
inline asmsub str2byte(str string @AY) clobbers(Y) -> ubyte @A {
|
||||
; -- returns in A 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)
|
||||
; result in A, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%asm {{
|
||||
jsr conv.str2word
|
||||
}}
|
||||
}
|
||||
|
||||
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)
|
||||
; result in AY, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%asm {{
|
||||
_result = P8ZP_SCRATCH_W2
|
||||
sta _mod+1
|
||||
sty _mod+2
|
||||
_result = P8ZP_SCRATCH_W1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy #0
|
||||
sty _result
|
||||
sty _result+1
|
||||
_mod lda $ffff,y ; modified
|
||||
sty cx16.r15+1
|
||||
_loop
|
||||
lda (P8ZP_SCRATCH_W2),y
|
||||
sec
|
||||
sbc #48
|
||||
bpl +
|
||||
_done ; return result
|
||||
bpl _digit
|
||||
_done
|
||||
sty cx16.r15
|
||||
lda _result
|
||||
ldy _result+1
|
||||
rts
|
||||
+ cmp #10
|
||||
_digit
|
||||
cmp #10
|
||||
bcs _done
|
||||
; add digit to result
|
||||
pha
|
||||
@ -324,7 +330,7 @@ _done ; return result
|
||||
bcc +
|
||||
inc _result+1
|
||||
+ iny
|
||||
bne _mod
|
||||
bne _loop
|
||||
; never reached
|
||||
|
||||
_result_times_10 ; (W*4 + W)*2
|
||||
@ -347,19 +353,21 @@ _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)
|
||||
; result in AY, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%asm {{
|
||||
_result = P8ZP_SCRATCH_W2
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
_result = P8ZP_SCRATCH_W1
|
||||
sta P8ZP_SCRATCH_W2
|
||||
sty P8ZP_SCRATCH_W2+1
|
||||
ldy #0
|
||||
sty _result
|
||||
sty _result+1
|
||||
sty _negative
|
||||
lda (P8ZP_SCRATCH_W1),y
|
||||
sty cx16.r15+1
|
||||
lda (P8ZP_SCRATCH_W2),y
|
||||
cmp #'+'
|
||||
bne +
|
||||
iny
|
||||
@ -367,11 +375,12 @@ _result = P8ZP_SCRATCH_W2
|
||||
bne _parse
|
||||
inc _negative
|
||||
iny
|
||||
_parse lda (P8ZP_SCRATCH_W1),y
|
||||
_parse lda (P8ZP_SCRATCH_W2),y
|
||||
sec
|
||||
sbc #48
|
||||
bpl _digit
|
||||
_done ; return result
|
||||
_done
|
||||
sty cx16.r15
|
||||
lda _negative
|
||||
beq +
|
||||
sec
|
||||
@ -384,7 +393,8 @@ _done ; return result
|
||||
+ lda _result
|
||||
ldy _result+1
|
||||
rts
|
||||
_digit cmp #10
|
||||
_digit
|
||||
cmp #10
|
||||
bcs _done
|
||||
; add digit to result
|
||||
pha
|
||||
@ -402,27 +412,40 @@ _negative .byte 0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub hex2uword(str string @ AY) -> uword @AY {
|
||||
; -- hexadecimal string with or without '$' to uword.
|
||||
asmsub hex2uword(str string @AY) -> uword @AY {
|
||||
; -- hexadecimal string (with or without '$') to uword.
|
||||
; string may be in petscii or c64-screencode encoding.
|
||||
; stops parsing at the first character that's not a hex digit (except leading $)
|
||||
; result in AY, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%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
|
||||
sty cx16.r15+1
|
||||
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
|
||||
bne _loop
|
||||
iny
|
||||
_loop
|
||||
lda #0
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda (P8ZP_SCRATCH_W2),y
|
||||
beq _stop
|
||||
cmp #7 ; screencode letters A-F are 1-6
|
||||
bcc _add_letter
|
||||
cmp #'g'
|
||||
bcs _stop
|
||||
cmp #'a'
|
||||
bcs _add_letter
|
||||
cmp #'0'
|
||||
bcc _stop
|
||||
cmp #'9'+1
|
||||
bcs _stop
|
||||
_calc
|
||||
asl P8ZP_SCRATCH_W1
|
||||
rol P8ZP_SCRATCH_W1+1
|
||||
asl P8ZP_SCRATCH_W1
|
||||
rol P8ZP_SCRATCH_W1+1
|
||||
@ -435,41 +458,54 @@ _calc asl P8ZP_SCRATCH_W1
|
||||
adc P8ZP_SCRATCH_B1
|
||||
ora P8ZP_SCRATCH_W1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
_skip inc P8ZP_SCRATCH_W2
|
||||
iny
|
||||
bne _loop
|
||||
inc P8ZP_SCRATCH_W2+1
|
||||
bne _loop
|
||||
_stop lda P8ZP_SCRATCH_W1
|
||||
_stop
|
||||
sty cx16.r15
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
rts
|
||||
_add_nine ldy #9
|
||||
sty P8ZP_SCRATCH_B1
|
||||
bne _calc
|
||||
_add_letter
|
||||
pha
|
||||
lda #9
|
||||
sta P8ZP_SCRATCH_B1
|
||||
pla
|
||||
jmp _calc
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub bin2uword(str string @ AY) -> uword @AY {
|
||||
; -- binary string with or without '%' to uword.
|
||||
asmsub bin2uword(str string @AY) -> uword @AY {
|
||||
; -- binary string (with or without '%') to uword.
|
||||
; stops parsing at the first character that's not a 0 or 1. (except leading %)
|
||||
; result in AY, number of characters processed also remains in cx16.r15 if you want to use it!! (0 = error)
|
||||
%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
|
||||
sty cx16.r15+1
|
||||
lda (P8ZP_SCRATCH_W2),y
|
||||
beq _stop
|
||||
cmp #'%'
|
||||
beq +
|
||||
asl P8ZP_SCRATCH_W1
|
||||
bne _loop
|
||||
iny
|
||||
_loop
|
||||
lda (P8ZP_SCRATCH_W2),y
|
||||
cmp #'0'
|
||||
bcc _stop
|
||||
cmp #'2'
|
||||
bcs _stop
|
||||
_first asl P8ZP_SCRATCH_W1
|
||||
rol P8ZP_SCRATCH_W1+1
|
||||
and #1
|
||||
ora P8ZP_SCRATCH_W1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
+ inc P8ZP_SCRATCH_W2
|
||||
iny
|
||||
bne _loop
|
||||
inc P8ZP_SCRATCH_W2+1
|
||||
bne _loop
|
||||
_stop lda P8ZP_SCRATCH_W1
|
||||
_stop
|
||||
sty cx16.r15
|
||||
lda P8ZP_SCRATCH_W1
|
||||
ldy P8ZP_SCRATCH_W1+1
|
||||
rts
|
||||
}}
|
||||
|
150
examples/test.p8
150
examples/test.p8
@ -5,16 +5,150 @@
|
||||
|
||||
main {
|
||||
|
||||
asmsub opcode(uword instr_info_ptr @AY, ubyte addr_mode @X) clobbers(X) -> ubyte @A, ubyte @Pc {
|
||||
%asm {{
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
sub start () {
|
||||
ubyte xx = opcode(0, 1)
|
||||
test_stack.test()
|
||||
str[] binstrings = [
|
||||
"",
|
||||
"%",
|
||||
"%0",
|
||||
"$0",
|
||||
"%1",
|
||||
"101",
|
||||
"%11111111",
|
||||
"%1111 ",
|
||||
"% 1111 ",
|
||||
"%1111%",
|
||||
"%1111)",
|
||||
"%1111,",
|
||||
"%1111.",
|
||||
"%1111foo",
|
||||
"%1111000010101010",
|
||||
"%1111000010101010111"
|
||||
]
|
||||
str[] hexstrings = [
|
||||
"",
|
||||
"$",
|
||||
"$0",
|
||||
"%0",
|
||||
"$1",
|
||||
"$9",
|
||||
"9934",
|
||||
"$91",
|
||||
"$91 ",
|
||||
"$ 91 ",
|
||||
"$12ae$",
|
||||
"$12ae)",
|
||||
"$12ae,",
|
||||
"$12ae.",
|
||||
"$12aez00",
|
||||
"$12345"
|
||||
]
|
||||
str[] posdecstrings = [
|
||||
"",
|
||||
"0",
|
||||
"1",
|
||||
"9",
|
||||
"$9",
|
||||
"10",
|
||||
"11",
|
||||
"123",
|
||||
"255",
|
||||
"62221",
|
||||
"42 ",
|
||||
" 42 ",
|
||||
"42$",
|
||||
"42)",
|
||||
"42,",
|
||||
"42.",
|
||||
"42aaaa"
|
||||
]
|
||||
str[] worddecstrings = [
|
||||
"",
|
||||
"0",
|
||||
"1",
|
||||
"9",
|
||||
"$9",
|
||||
"10",
|
||||
"11",
|
||||
"123",
|
||||
"255",
|
||||
"62221",
|
||||
"42 ",
|
||||
" 42 ",
|
||||
"42$",
|
||||
"42)",
|
||||
"42,",
|
||||
"42.",
|
||||
"42aaaa",
|
||||
"-",
|
||||
"-0",
|
||||
"-1",
|
||||
"-9",
|
||||
"$9",
|
||||
"-10",
|
||||
"-11",
|
||||
"-123",
|
||||
"-255",
|
||||
"-62221",
|
||||
"-32221",
|
||||
"-42 ",
|
||||
"- 42 ",
|
||||
"-42-",
|
||||
"-42$",
|
||||
"-42)",
|
||||
"-42,",
|
||||
"-42.",
|
||||
"-42aaaa"
|
||||
]
|
||||
|
||||
uword value
|
||||
word wvalue
|
||||
uword strptr
|
||||
for strptr in binstrings {
|
||||
value = conv.bin2uword(strptr)
|
||||
txt.print(strptr)
|
||||
txt.print(" = ")
|
||||
txt.print_uw(value)
|
||||
txt.print(" = ")
|
||||
txt.print_uwbin(value, true)
|
||||
txt.print(" #")
|
||||
txt.print_uw(cx16.r15) ; number of chars processedc
|
||||
txt.chrout('\n')
|
||||
}
|
||||
|
||||
txt.chrout('\n')
|
||||
for strptr in hexstrings {
|
||||
value = conv.hex2uword(strptr)
|
||||
txt.print(strptr)
|
||||
txt.print(" = ")
|
||||
txt.print_uw(value)
|
||||
txt.print(" = ")
|
||||
txt.print_uwhex(value, true)
|
||||
txt.print(" #")
|
||||
txt.print_uw(cx16.r15) ; number of chars processedc
|
||||
txt.chrout('\n')
|
||||
}
|
||||
|
||||
txt.chrout('\n')
|
||||
for strptr in posdecstrings {
|
||||
value = conv.str2uword(strptr)
|
||||
txt.print(strptr)
|
||||
txt.print(" = ")
|
||||
txt.print_uw(value)
|
||||
txt.print(" #")
|
||||
txt.print_uw(cx16.r15) ; number of chars processedc
|
||||
txt.chrout('\n')
|
||||
}
|
||||
|
||||
txt.chrout('\n')
|
||||
for strptr in worddecstrings {
|
||||
wvalue = conv.str2word(strptr)
|
||||
txt.print(strptr)
|
||||
txt.print(" = ")
|
||||
txt.print_w(wvalue)
|
||||
txt.print(" #")
|
||||
txt.print_uw(cx16.r15) ; number of chars processedc
|
||||
txt.chrout('\n')
|
||||
}
|
||||
|
||||
|
||||
; found = strfind("irmen de jong", ' ')
|
||||
|
Loading…
Reference in New Issue
Block a user