mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
added new c64utils.str2(u)word that doesn't use kernel float routines
fixed processing of register pair return value of asmsub
This commit is contained in:
parent
223bab21aa
commit
191707cd37
@ -168,140 +168,117 @@ asmsub uword2decimal (uword value @ AY) -> clobbers(A,Y) -> () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub str2byte (str string @ AY) -> clobbers(Y) -> (byte @ A) {
|
|
||||||
%asm {{
|
|
||||||
; -- convert string (address in A/Y) to byte in A
|
|
||||||
; doesn't use any kernal routines
|
|
||||||
sta c64.SCRATCH_ZPWORD1
|
|
||||||
sty c64.SCRATCH_ZPWORD1+1
|
|
||||||
ldy #0
|
|
||||||
lda (c64.SCRATCH_ZPWORD1),y
|
|
||||||
cmp #'-'
|
|
||||||
beq +
|
|
||||||
jmp str2ubyte._enter
|
|
||||||
+ inc c64.SCRATCH_ZPWORD1
|
|
||||||
bne +
|
|
||||||
inc c64.SCRATCH_ZPWORD1+1
|
|
||||||
+ jsr str2ubyte._enter
|
|
||||||
eor #$ff
|
|
||||||
sec
|
|
||||||
adc #0
|
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub str2ubyte (str string @ AY) -> clobbers(Y) -> (ubyte @ A) {
|
|
||||||
%asm {{
|
|
||||||
; -- convert string (address in A/Y) to ubyte in A
|
|
||||||
; doesn't use any kernal routines
|
|
||||||
sta c64.SCRATCH_ZPWORD1
|
|
||||||
sty c64.SCRATCH_ZPWORD1+1
|
|
||||||
_enter jsr _numlen ; Y= slen
|
|
||||||
lda #0
|
|
||||||
dey
|
|
||||||
bpl +
|
|
||||||
rts
|
|
||||||
+ lda (c64.SCRATCH_ZPWORD1),y
|
|
||||||
sec
|
|
||||||
sbc #'0'
|
|
||||||
dey
|
|
||||||
bpl +
|
|
||||||
rts
|
|
||||||
+ sta c64.SCRATCH_ZPREG ;result
|
|
||||||
lda (c64.SCRATCH_ZPWORD1),y
|
|
||||||
sec
|
|
||||||
sbc #'0'
|
|
||||||
asl a
|
|
||||||
sta c64.SCRATCH_ZPB1
|
|
||||||
asl a
|
|
||||||
asl a
|
|
||||||
clc
|
|
||||||
adc c64.SCRATCH_ZPB1
|
|
||||||
clc
|
|
||||||
adc c64.SCRATCH_ZPREG
|
|
||||||
dey
|
|
||||||
bpl +
|
|
||||||
rts
|
|
||||||
+ sta c64.SCRATCH_ZPREG
|
|
||||||
lda (c64.SCRATCH_ZPWORD1),y
|
|
||||||
tay
|
|
||||||
lda _hundreds-'0',y
|
|
||||||
clc
|
|
||||||
adc c64.SCRATCH_ZPREG
|
|
||||||
rts
|
|
||||||
_hundreds .byte 0, 100, 200
|
|
||||||
|
|
||||||
_numlen
|
|
||||||
;-- return the length of the numeric string at ZPWORD1, in Y
|
|
||||||
ldy #0
|
|
||||||
- lda (c64.SCRATCH_ZPWORD1),y
|
|
||||||
cmp #'0'
|
|
||||||
bmi +
|
|
||||||
cmp #':' ; one after '9'
|
|
||||||
bpl +
|
|
||||||
iny
|
|
||||||
bne -
|
|
||||||
+ rts
|
|
||||||
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
asmsub c64flt_FREADSTR (ubyte length @ A) -> clobbers(A,X,Y) -> () = $b7b5 ; @todo needed for (slow) str conversion below
|
|
||||||
asmsub c64flt_GETADR () -> clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b7f7 ; @todo needed for (slow) str conversion below
|
|
||||||
asmsub c64flt_FTOSWORDYA () -> clobbers(X) -> (ubyte @ Y, ubyte @ A) = $b1aa ; @todo needed for (slow) str conversion below
|
|
||||||
|
|
||||||
asmsub str2uword(str string @ AY) -> clobbers() -> (uword @ AY) {
|
asmsub str2uword(str string @ AY) -> clobbers() -> (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)
|
||||||
%asm {{
|
%asm {{
|
||||||
;-- convert string (address in A/Y) to uword number in A/Y
|
_result = c64.SCRATCH_ZPWORD2
|
||||||
; @todo don't use the (slow) kernel floating point conversion
|
sta _mod+1
|
||||||
sta $22
|
sty _mod+2
|
||||||
sty $23
|
|
||||||
jsr _strlen2233
|
|
||||||
tya
|
|
||||||
stx c64.SCRATCH_ZPREGX
|
|
||||||
jsr c64flt_FREADSTR ; string to fac1
|
|
||||||
jsr c64flt_GETADR ; fac1 to unsigned word in Y/A
|
|
||||||
ldx c64.SCRATCH_ZPREGX
|
|
||||||
sta c64.SCRATCH_ZPREG
|
|
||||||
tya
|
|
||||||
ldy c64.SCRATCH_ZPREG
|
|
||||||
rts
|
|
||||||
|
|
||||||
_strlen2233
|
|
||||||
;-- return the length of the (zero-terminated) string at $22/$23, in Y
|
|
||||||
ldy #0
|
ldy #0
|
||||||
- lda ($22),y
|
sty _result
|
||||||
beq +
|
sty _result+1
|
||||||
iny
|
_mod lda $ffff,y ; modified
|
||||||
bne -
|
sec
|
||||||
+ rts
|
sbc #48
|
||||||
|
bpl +
|
||||||
|
_done ; return result
|
||||||
|
lda _result
|
||||||
|
ldy _result+1
|
||||||
|
rts
|
||||||
|
+ cmp #10
|
||||||
|
bcs _done
|
||||||
|
; add digit to result
|
||||||
|
pha
|
||||||
|
jsr _result_times_10
|
||||||
|
pla
|
||||||
|
clc
|
||||||
|
adc _result
|
||||||
|
sta _result
|
||||||
|
bcc +
|
||||||
|
inc _result+1
|
||||||
|
+ iny
|
||||||
|
bne _mod
|
||||||
|
; never reached
|
||||||
|
|
||||||
|
_result_times_10 ; (W*4 + W)*2
|
||||||
|
lda _result+1
|
||||||
|
sta c64.SCRATCH_ZPREG
|
||||||
|
lda _result
|
||||||
|
asl a
|
||||||
|
rol c64.SCRATCH_ZPREG
|
||||||
|
asl a
|
||||||
|
rol c64.SCRATCH_ZPREG
|
||||||
|
clc
|
||||||
|
adc _result
|
||||||
|
sta _result
|
||||||
|
lda c64.SCRATCH_ZPREG
|
||||||
|
adc _result+1
|
||||||
|
asl _result
|
||||||
|
rol a
|
||||||
|
sta _result+1
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub str2word(str string @ AY) -> clobbers() -> (word @ AY) {
|
asmsub str2word(str string @ AY) -> clobbers() -> (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)
|
||||||
%asm {{
|
%asm {{
|
||||||
;-- convert string (address in A/Y) to signed word number in A/Y
|
_result = c64.SCRATCH_ZPWORD2
|
||||||
; @todo don't use the (slow) kernel floating point conversion
|
sta c64.SCRATCH_ZPWORD1
|
||||||
sta $22
|
sty c64.SCRATCH_ZPWORD1+1
|
||||||
sty $23
|
ldy #0
|
||||||
jsr str2uword._strlen2233
|
sty _result
|
||||||
tya
|
sty _result+1
|
||||||
stx c64.SCRATCH_ZPREGX
|
sty _negative
|
||||||
jsr c64flt_FREADSTR ; string to fac1
|
lda (c64.SCRATCH_ZPWORD1),y
|
||||||
jsr c64flt_FTOSWORDYA ; fac1 to unsigned word in Y/A
|
cmp #'+'
|
||||||
ldx c64.SCRATCH_ZPREGX
|
bne +
|
||||||
sta c64.SCRATCH_ZPREG
|
iny
|
||||||
tya
|
+ cmp #'-'
|
||||||
ldy c64.SCRATCH_ZPREG
|
bne _parse
|
||||||
|
inc _negative
|
||||||
|
iny
|
||||||
|
_parse lda (c64.SCRATCH_ZPWORD1),y
|
||||||
|
sec
|
||||||
|
sbc #48
|
||||||
|
bpl _digit
|
||||||
|
_done ; return result
|
||||||
|
lda _negative
|
||||||
|
beq +
|
||||||
|
sec
|
||||||
|
lda #0
|
||||||
|
sbc _result
|
||||||
|
sta _result
|
||||||
|
lda #0
|
||||||
|
sbc _result+1
|
||||||
|
sta _result+1
|
||||||
|
+ lda _result
|
||||||
|
ldy _result+1
|
||||||
rts
|
rts
|
||||||
|
_digit cmp #10
|
||||||
|
bcs _done
|
||||||
|
; add digit to result
|
||||||
|
pha
|
||||||
|
jsr str2uword._result_times_10
|
||||||
|
pla
|
||||||
|
clc
|
||||||
|
adc _result
|
||||||
|
sta _result
|
||||||
|
bcc +
|
||||||
|
inc _result+1
|
||||||
|
+ iny
|
||||||
|
bne _parse
|
||||||
|
; never reached
|
||||||
|
_negative .byte 0
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; @todo string to 32 bit unsigned integer http://www.6502.org/source/strings/ascii-to-32bit.html
|
|
||||||
|
|
||||||
|
|
||||||
asmsub set_irqvec_excl() -> clobbers(A) -> () {
|
asmsub set_irqvec_excl() -> clobbers(A) -> () {
|
||||||
%asm {{
|
%asm {{
|
||||||
sei
|
sei
|
||||||
|
@ -727,12 +727,6 @@ private class AstChecker(private val namespace: INameScope,
|
|||||||
override fun process(typecast: TypecastExpression): IExpression {
|
override fun process(typecast: TypecastExpression): IExpression {
|
||||||
if(typecast.type in IterableDatatypes)
|
if(typecast.type in IterableDatatypes)
|
||||||
checkResult.add(ExpressionError("cannot type cast to string or array type", typecast.position))
|
checkResult.add(ExpressionError("cannot type cast to string or array type", typecast.position))
|
||||||
val funcTarget = (typecast.expression as? IFunctionCall)?.target?.targetStatement(namespace)
|
|
||||||
if(funcTarget is Subroutine &&
|
|
||||||
funcTarget.asmReturnvaluesRegisters.isNotEmpty() &&
|
|
||||||
funcTarget.asmReturnvaluesRegisters.all { it.stack!=true }) {
|
|
||||||
checkResult.add(ExpressionError("cannot type cast a call to an asmsub that returns value in register - use a variable to store it first", typecast.position))
|
|
||||||
}
|
|
||||||
return super.process(typecast)
|
return super.process(typecast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,7 +1016,9 @@ internal class Compiler(private val rootModule: Module,
|
|||||||
TODO("not yet supported: return values in cpu status flag $rv $subroutine")
|
TODO("not yet supported: return values in cpu status flag $rv $subroutine")
|
||||||
when(rv.registerOrPair) {
|
when(rv.registerOrPair) {
|
||||||
A,X,Y -> prog.instr(Opcode.PUSH_VAR_BYTE, callLabel = rv.registerOrPair.name)
|
A,X,Y -> prog.instr(Opcode.PUSH_VAR_BYTE, callLabel = rv.registerOrPair.name)
|
||||||
AX, AY, XY -> prog.instr(Opcode.PUSH_VAR_WORD, callLabel = rv.registerOrPair.name)
|
AX -> prog.instr(Opcode.PUSH_REGAX_WORD)
|
||||||
|
AY -> prog.instr(Opcode.PUSH_REGAY_WORD)
|
||||||
|
XY -> prog.instr(Opcode.PUSH_REGXY_WORD)
|
||||||
null -> {}
|
null -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2146,13 +2148,6 @@ internal class Compiler(private val rootModule: Module,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(expr: TypecastExpression) {
|
private fun translate(expr: TypecastExpression) {
|
||||||
val funcTarget = (expr.expression as? IFunctionCall)?.target?.targetStatement(namespace)
|
|
||||||
if(funcTarget is Subroutine &&
|
|
||||||
funcTarget.asmReturnvaluesRegisters.isNotEmpty() &&
|
|
||||||
funcTarget.asmReturnvaluesRegisters.all { it.stack!=true }) {
|
|
||||||
throw CompilerException("cannot type cast a call to an asmsub that returns value in register - use a variable to store it first")
|
|
||||||
}
|
|
||||||
|
|
||||||
translate(expr.expression)
|
translate(expr.expression)
|
||||||
val sourceDt = expr.expression.resultingDatatype(namespace, heap) ?: throw CompilerException("don't know what type to cast")
|
val sourceDt = expr.expression.resultingDatatype(namespace, heap) ?: throw CompilerException("don't know what type to cast")
|
||||||
if(sourceDt==expr.type)
|
if(sourceDt==expr.type)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
c64scr.print("es")
|
c64scr.print("es")
|
||||||
c64scr.print(" left.\nWhat is your next guess? ")
|
c64scr.print(" left.\nWhat is your next guess? ")
|
||||||
c64scr.input_chars(input)
|
c64scr.input_chars(input)
|
||||||
ubyte guess = c64utils.str2ubyte(input)
|
ubyte guess = lsb(c64utils.str2uword(input))
|
||||||
|
|
||||||
if guess==secretnumber {
|
if guess==secretnumber {
|
||||||
return ending(true)
|
return ending(true)
|
||||||
|
@ -7,9 +7,46 @@
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
ubyte ub
|
uword z = c64utils.str2uword(" 1 2 3 4 5 ")
|
||||||
A = 123 or 44
|
c64scr.print_uw(c64utils.str2uword(" "))
|
||||||
Y = A or 1
|
c64.CHROUT('\n')
|
||||||
ub = ub or 1
|
c64scr.print_uw(c64utils.str2uword(" 222 "))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_uw(c64utils.str2uword("1234 567"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_uw(c64utils.str2uword("1234x567"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_uw(c64utils.str2uword("+1234x567"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_uw(c64utils.str2uword("00065534"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_uw(c64utils.str2uword("0006553x4"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
word z2 = c64utils.str2word(" 1 2 3 4 5 ")
|
||||||
|
c64scr.print_w(c64utils.str2word(" "))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("0000000"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("12345"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("64444"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word(" 12345"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("-12345"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word(" - 123 45"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("+1234 567 "))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("-1234 567 "))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("-31999"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64scr.print_w(c64utils.str2word("31999"))
|
||||||
|
c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user