mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
more asm, constants now also outputted in asm source
This commit is contained in:
parent
08224d5367
commit
0c64d7ffe5
@ -1,7 +1,6 @@
|
||||
%output prg
|
||||
%import c64lib
|
||||
%import c64utils
|
||||
%import mathlib
|
||||
|
||||
~ main {
|
||||
sub start() {
|
||||
@ -28,7 +27,7 @@
|
||||
c64.MUL10() ; .. and now *100
|
||||
c64.FADDH() ; add 0.5..
|
||||
c64.FADDH() ; and again, so +1 total
|
||||
A, Y = c64flt.GETADRAY() ; @todo fix return value type check "cannot assign word to byte, use msb() or lsb()"
|
||||
A, Y = c64flt.GETADRAY()
|
||||
secretnumber = A
|
||||
|
||||
c64scr.print_string("I am thinking of a number from 1 to 100!You'll have to guess it!\n")
|
||||
@ -44,7 +43,7 @@ ask_guess:
|
||||
c64.CHROUT('\n')
|
||||
freadstr_arg = guess
|
||||
c64.FREADSTR(A)
|
||||
A, Y = c64flt.GETADRAY() ; @todo fix return value type check "cannot assign word to byte, use msb() or lsb()"
|
||||
A, Y = c64flt.GETADRAY()
|
||||
if(A==secretnumber) {
|
||||
c64scr.print_string("\nThat's my number, impressive!\n")
|
||||
goto goodbye
|
||||
|
@ -8,18 +8,18 @@
|
||||
|
||||
c64scr.print_string("Let's play a number guessing game!\n")
|
||||
c64scr.print_string("Enter your name: ")
|
||||
vm_input_str(name)
|
||||
Y=c64scr.input_chars(name)
|
||||
c64scr.print_string("\nHello, ")
|
||||
c64scr.print_string(name)
|
||||
c64scr.print_string(".\nI am thinking of a number from 1 to 100! You'll have to guess it!\n")
|
||||
|
||||
for ubyte attempts_left in 10 to 1 step -1 {
|
||||
c64scr.print_string("\nYou have ")
|
||||
vm_write_num(attempts_left)
|
||||
c64scr.print_byte_decimal(attempts_left)
|
||||
c64scr.print_string(" guess")
|
||||
if attempts_left>1 c64scr.print_string("es")
|
||||
c64scr.print_string(" left. What is your next guess? ")
|
||||
vm_input_str(guess)
|
||||
Y=c64scr.input_chars(guess)
|
||||
ubyte guessednumber = str2ubyte(guess)
|
||||
if guessednumber==secretnumber {
|
||||
c64scr.print_string("\nYou guessed it, impressive!\n")
|
||||
@ -35,7 +35,7 @@
|
||||
}
|
||||
|
||||
c64scr.print_string("\nToo bad! My number was: ")
|
||||
vm_write_num(secretnumber)
|
||||
c64scr.print_byte_decimal(secretnumber)
|
||||
c64scr.print_string(".\n")
|
||||
return
|
||||
}
|
||||
|
@ -1,63 +1,11 @@
|
||||
%output raw
|
||||
%launcher none
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
; memory ubyte[40] firstScreenLine = $0400
|
||||
; word ww=333
|
||||
;
|
||||
; Y=33
|
||||
;
|
||||
; if(Y>3) {
|
||||
; A=99
|
||||
; } else {
|
||||
; A=100
|
||||
; }
|
||||
;
|
||||
; if(ww>33) {
|
||||
; A=99
|
||||
; } else {
|
||||
; A=100
|
||||
; }
|
||||
;
|
||||
; for ubyte c in 10 to 30 {
|
||||
; firstScreenLine[c] = c
|
||||
; }
|
||||
|
||||
|
||||
ubyte bv = 99
|
||||
word wv = 14443
|
||||
float fv = 3.14
|
||||
memory ubyte mb = $c000
|
||||
memory word mw = $c100
|
||||
memory float mf = $c200
|
||||
memory ubyte[10] mba = $d000
|
||||
memory word[10] mwa = $d100
|
||||
memory float[10] mfa = $d200
|
||||
memory str mstr = $d300
|
||||
memory str_p mstrp = $d300
|
||||
memory str_s mstrs = $d300
|
||||
memory str_ps mstrps = $d300
|
||||
|
||||
mb = 5
|
||||
mb = Y
|
||||
mb = bv
|
||||
mw = 22334
|
||||
mw = wv
|
||||
mf = 4.45
|
||||
mf = fv
|
||||
mba[9] = 5
|
||||
mba[9] = Y
|
||||
mba[9] = bv
|
||||
mwa[9] = 22334
|
||||
mwa[9] = wv
|
||||
mfa[9] = 5.667
|
||||
mfa[9] = fv
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
~ main {
|
||||
memory ubyte[40*25] Screen = $0400
|
||||
|
||||
sub start() {
|
||||
A, Y = c64flt.GETADRAY()
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
}
|
||||
else
|
||||
checkAssignmentCompatible(targetDatatype, sourceDatatype, assignment.value, assignment.position)
|
||||
checkAssignmentCompatible(targetDatatype, sourceDatatype, assignment.value, assignment.targets, assignment.position)
|
||||
}
|
||||
}
|
||||
return assignment
|
||||
@ -482,13 +482,13 @@ class AstChecker(private val namespace: INameScope,
|
||||
when(decl.datatype) {
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB ->
|
||||
if(arraySize > 256)
|
||||
err("byte arrayspec length must be 1-256")
|
||||
err("byte array length must be 1-256")
|
||||
DataType.ARRAY_W, DataType.ARRAY_UW ->
|
||||
if(arraySize > 128)
|
||||
err("word arrayspec length must be 1-128")
|
||||
err("word array length must be 1-128")
|
||||
DataType.ARRAY_F ->
|
||||
if(arraySize > 51)
|
||||
err("float arrayspec length must be 1-51")
|
||||
err("float array length must be 1-51")
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@ -891,13 +891,13 @@ class AstChecker(private val namespace: INameScope,
|
||||
val arraySize = value.arrayvalue?.size ?: heap.get(value.heapId!!).arraysize
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
if(arraySpecSize<1 || arraySpecSize>256)
|
||||
return err("byte arrayspec length must be 1-256")
|
||||
return err("byte array length must be 1-256")
|
||||
val constX = arrayspec.x.constValue(namespace, heap)
|
||||
if(constX?.asIntegerValue==null)
|
||||
return err("arrayspec size specifier must be constant integer value")
|
||||
return err("array size specifier must be constant integer value")
|
||||
val expectedSize = constX.asIntegerValue
|
||||
if (arraySize != expectedSize)
|
||||
return err("initializer arrayspec size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
return err("initializer array size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
return true
|
||||
}
|
||||
return err("invalid byte array size, must be 1-256")
|
||||
@ -911,18 +911,18 @@ class AstChecker(private val namespace: INameScope,
|
||||
val arraySize = value.arrayvalue?.size ?: heap.get(value.heapId!!).arraysize
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
if(arraySpecSize<1 || arraySpecSize>128)
|
||||
return err("word arrayspec length must be 1-128")
|
||||
return err("word array length must be 1-128")
|
||||
val constX = arrayspec.x.constValue(namespace, heap)
|
||||
if(constX?.asIntegerValue==null)
|
||||
return err("arrayspec size specifier must be constant integer value")
|
||||
return err("array size specifier must be constant integer value")
|
||||
val expectedSize = constX.asIntegerValue
|
||||
if (arraySize != expectedSize)
|
||||
return err("initializer arrayspec size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
return err("initializer array size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
return true
|
||||
}
|
||||
return err("invalid word arrayspec size, must be 1-128")
|
||||
return err("invalid word array size, must be 1-128")
|
||||
}
|
||||
return err("invalid word arrayspec initialization value ${value.type}, expected $targetDt")
|
||||
return err("invalid word array initialization value ${value.type}, expected $targetDt")
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
// value may be either a single float, or a float arrayspec
|
||||
@ -931,15 +931,15 @@ class AstChecker(private val namespace: INameScope,
|
||||
val arraySpecSize = arrayspec.size()
|
||||
if(arraySpecSize!=null && arraySpecSize>0) {
|
||||
if(arraySpecSize < 1 || arraySpecSize>51)
|
||||
return err("float arrayspec length must be 1-51")
|
||||
return err("float array length must be 1-51")
|
||||
val constX = arrayspec.x.constValue(namespace, heap)
|
||||
if(constX?.asIntegerValue==null)
|
||||
return err("arrayspec size specifier must be constant integer value")
|
||||
return err("array size specifier must be constant integer value")
|
||||
val expectedSize = constX.asIntegerValue
|
||||
if (arraySize != expectedSize)
|
||||
return err("initializer arrayspec size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
return err("initializer array size mismatch (expecting $expectedSize, got $arraySize)")
|
||||
} else
|
||||
return err("invalid float arrayspec size, must be 1-51")
|
||||
return err("invalid float array size, must be 1-51")
|
||||
|
||||
// check if the floating point values are all within range
|
||||
val doubles = if(value.arrayvalue!=null)
|
||||
@ -950,7 +950,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
return err("floating point value overflow")
|
||||
return true
|
||||
}
|
||||
return err("invalid float arrayspec initialization value ${value.type}, expected $targetDt")
|
||||
return err("invalid float array initialization value ${value.type}, expected $targetDt")
|
||||
}
|
||||
}
|
||||
return true
|
||||
@ -959,6 +959,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
private fun checkAssignmentCompatible(targetDatatype: DataType,
|
||||
sourceDatatype: DataType,
|
||||
sourceValue: IExpression,
|
||||
assignTargets: List<AssignTarget>,
|
||||
position: Position) : Boolean {
|
||||
|
||||
if(sourceValue is RangeExpr)
|
||||
@ -980,8 +981,12 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(result)
|
||||
return true
|
||||
|
||||
if((sourceDatatype==DataType.UWORD || sourceDatatype==DataType.WORD) && (targetDatatype==DataType.UBYTE || targetDatatype==DataType.BYTE))
|
||||
checkResult.add(ExpressionError("cannot assign word to byte, use msb() or lsb()?", position))
|
||||
if((sourceDatatype==DataType.UWORD || sourceDatatype==DataType.WORD) && (targetDatatype==DataType.UBYTE || targetDatatype==DataType.BYTE)) {
|
||||
if(assignTargets.size==2 && assignTargets[0].register!=null && assignTargets[1].register!=null)
|
||||
return true // for asm subroutine calls that return a (U)WORD that's going to be stored into two BYTES (registers), we make an exception.
|
||||
else
|
||||
checkResult.add(ExpressionError("cannot assign word to byte, use msb() or lsb()?", position))
|
||||
}
|
||||
else if(sourceDatatype==DataType.FLOAT && targetDatatype in IntegerDatatypes)
|
||||
checkResult.add(ExpressionError("cannot assign float to ${targetDatatype.toString().toLowerCase()}; possible loss of precision. Suggestion: round the value or revert to integer arithmetic", position))
|
||||
else
|
||||
|
@ -21,7 +21,7 @@ abstract class Zeropage(private val options: CompilationOptions) {
|
||||
DataType.UBYTE -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!!
|
||||
DataType.UWORD -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 2
|
||||
DataType.FLOAT -> (vardecl.arrayspec.x as LiteralValue).asIntegerValue!! * 5
|
||||
else -> throw CompilerException("arrayspec can only be of byte, word, float")
|
||||
else -> throw CompilerException("array can only be of byte, word, float")
|
||||
}
|
||||
} else {
|
||||
when (vardecl.datatype) {
|
||||
|
@ -274,8 +274,8 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
}
|
||||
currentBlock.variables[scopedname] = value
|
||||
}
|
||||
VarDeclType.CONST -> {} // constants are all folded away
|
||||
VarDeclType.MEMORY -> {
|
||||
VarDeclType.MEMORY, VarDeclType.CONST -> {
|
||||
// note that constants are all folded away, but assembly code may still refer to them
|
||||
val lv = decl.value as LiteralValue
|
||||
if(lv.type!=DataType.UWORD && lv.type!=DataType.UBYTE)
|
||||
throw CompilerException("expected integer memory address $lv")
|
||||
|
@ -619,10 +619,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
Opcode.INV_WORD -> {
|
||||
"""
|
||||
lda ${(ESTACK_LO + 1).toHex()},x
|
||||
lda ${(ESTACK_LO+1).toHex()},x
|
||||
eor #255
|
||||
sta ${(ESTACK_LO+1).toHex()},x
|
||||
lda ${(ESTACK_HI + 1).toHex()},x
|
||||
lda ${(ESTACK_HI+1).toHex()},x
|
||||
eor #255
|
||||
sta ${(ESTACK_HI+1).toHex()},x
|
||||
"""
|
||||
@ -732,11 +732,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.MUL_W -> " jsr prog8_lib.mul_w"
|
||||
Opcode.MUL_UW -> " jsr prog8_lib.mul_uw"
|
||||
Opcode.MUL_F -> " jsr prog8_lib.mul_f"
|
||||
Opcode.LESS_UB -> " jsr prog8_lib.less_ub"
|
||||
Opcode.LESS_B -> " jsr prog8_lib.less_b"
|
||||
Opcode.LESS_UW -> " jsr prog8_lib.less_uw"
|
||||
Opcode.LESS_W -> " jsr prog8_lib.less_w"
|
||||
Opcode.LESS_F -> " jsr prog8_lib.less_f"
|
||||
|
||||
Opcode.AND_BYTE -> {
|
||||
"""
|
||||
@ -754,6 +749,39 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
sta ${(ESTACK_LO + 1).toHex()},x
|
||||
"""
|
||||
}
|
||||
Opcode.REMAINDER_B -> " jsr prog8_lib.remainder_b"
|
||||
Opcode.REMAINDER_UB -> " jsr prog8_lib.remainder_ub"
|
||||
Opcode.REMAINDER_W -> " jsr prog8_lib.remainder_w"
|
||||
Opcode.REMAINDER_UW -> " jsr prog8_lib.remainder_uw"
|
||||
Opcode.REMAINDER_F -> " jsr prog8_lib.remainder_f"
|
||||
|
||||
Opcode.GREATER_B -> " jsr prog8_lib.greater_b"
|
||||
Opcode.GREATER_UB -> " jsr prog8_lib.greater_ub"
|
||||
Opcode.GREATER_W -> " jsr prog8_lib.greater_w"
|
||||
Opcode.GREATER_UW -> " jsr prog8_lib.greater_uw"
|
||||
Opcode.GREATER_F -> " jsr prog8_lib.greater_f"
|
||||
|
||||
Opcode.GREATEREQ_B -> " jsr prog8_lib.greatereq_b"
|
||||
Opcode.GREATEREQ_UB -> " jsr prog8_lib.greatereq_ub"
|
||||
Opcode.GREATEREQ_W -> " jsr prog8_lib.greatereq_w"
|
||||
Opcode.GREATEREQ_UW -> " jsr prog8_lib.greatereq_uw"
|
||||
Opcode.GREATEREQ_F -> " jsr prog8_lib.greatereq_f"
|
||||
|
||||
Opcode.EQUAL_BYTE -> " jsr prog8_lib.equal_b"
|
||||
Opcode.EQUAL_WORD -> " jsr prog8_lib.equal_w"
|
||||
Opcode.EQUAL_F -> " jsr prog8_lib.equal_f"
|
||||
|
||||
Opcode.LESS_UB -> " jsr prog8_lib.less_ub"
|
||||
Opcode.LESS_B -> " jsr prog8_lib.less_b"
|
||||
Opcode.LESS_UW -> " jsr prog8_lib.less_uw"
|
||||
Opcode.LESS_W -> " jsr prog8_lib.less_w"
|
||||
Opcode.LESS_F -> " jsr prog8_lib.less_f"
|
||||
|
||||
Opcode.LESSEQ_UB -> " jsr prog8_lib.lesseq_ub"
|
||||
Opcode.LESSEQ_B -> " jsr prog8_lib.lesseq_b"
|
||||
Opcode.LESSEQ_UW -> " jsr prog8_lib.lesseq_uw"
|
||||
Opcode.LESSEQ_W -> " jsr prog8_lib.lesseq_w"
|
||||
Opcode.LESSEQ_F -> " jsr prog8_lib.lesseq_f"
|
||||
|
||||
else -> null
|
||||
}
|
||||
@ -830,6 +858,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun sameConstantIndexedVarOperation(variable: String, index: Int, ins: Instruction): AsmFragment? {
|
||||
// an in place operation that consists of a push-value / op / push-index-value / pop-into-indexed-var
|
||||
return when(ins.opcode) {
|
||||
Opcode.SHL_BYTE -> AsmFragment(" asl $variable+$index", 8)
|
||||
Opcode.SHR_BYTE -> AsmFragment(" lsr $variable+$index", 8)
|
||||
@ -848,6 +877,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun sameIndexedVarOperation(variable: String, indexVar: String, ins: Instruction): AsmFragment? {
|
||||
// an in place operation that consists of a push-value / op / push-index-var / pop-into-indexed-var
|
||||
val saveX = " stx ${C64Zeropage.SCRATCH_B1} |"
|
||||
val restoreX = " | ldx ${C64Zeropage.SCRATCH_B1}"
|
||||
val loadXWord: String
|
||||
@ -891,6 +921,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun sameMemOperation(address: Int, ins: Instruction): AsmFragment? {
|
||||
// an in place operation that consists of a push-mem / op / pop-mem sequence
|
||||
val addr = address.toHex()
|
||||
val addrHi = (address+1).toHex()
|
||||
return when(ins.opcode) {
|
||||
@ -911,6 +942,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
}
|
||||
|
||||
private fun sameVarOperation(variable: String, ins: Instruction): AsmFragment? {
|
||||
// an in place operation that consists of a push-var / op / pop-var
|
||||
return when(ins.opcode) {
|
||||
Opcode.SHL_BYTE -> {
|
||||
when (variable) {
|
||||
@ -2705,9 +2737,28 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
// push msb(word var)
|
||||
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB)) { segment ->
|
||||
" lda #>${segment[0].callLabel} | sta ${ESTACK_LO.toHex()},x | dex "
|
||||
},
|
||||
|
||||
// set a register pair to a certain memory address (of a variable)
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGAX_WORD)) { segment ->
|
||||
" lda #<${segment[0].callLabel} | ldx #>${segment[0].callLabel} "
|
||||
},
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGAY_WORD)) { segment ->
|
||||
" lda #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} "
|
||||
},
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGXY_WORD)) { segment ->
|
||||
" ldx #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} "
|
||||
},
|
||||
// set a register pair to a certain memory address (of a literal string value)
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_STR, Opcode.POP_REGAX_WORD)) { segment ->
|
||||
TODO("$segment")
|
||||
},
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_STR, Opcode.POP_REGAY_WORD)) { segment ->
|
||||
TODO("$segment")
|
||||
},
|
||||
AsmPattern(listOf(Opcode.PUSH_ADDR_STR, Opcode.POP_REGXY_WORD)) { segment ->
|
||||
TODO("$segment")
|
||||
}
|
||||
|
||||
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ asmsub print_pstring (text: str_p @ XY) -> clobbers(A,X) -> (ubyte @ Y) {
|
||||
asmsub print_byte_decimal0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
|
||||
; ---- print the byte in A in decimal form, with left padding 0s (3 positions total)
|
||||
%asm {{
|
||||
jsr byte2decimal
|
||||
jsr c64utils.byte2decimal
|
||||
pha
|
||||
tya
|
||||
jsr c64.CHROUT
|
||||
@ -663,7 +663,7 @@ asmsub print_byte_decimal0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
|
||||
asmsub print_byte_decimal (value: ubyte @ A) -> clobbers(A,X,Y) -> () {
|
||||
; ---- print the byte in A in decimal form, without left padding 0s
|
||||
%asm {{
|
||||
jsr byte2decimal
|
||||
jsr c64utils.byte2decimal
|
||||
pha
|
||||
cpy #'0'
|
||||
bne _print_hundreds
|
||||
@ -689,7 +689,7 @@ asmsub print_byte_hex (prefix: ubyte @ Pc, value: ubyte @ A) -> clobbers(A,X,Y
|
||||
lda #'$'
|
||||
jsr c64.CHROUT
|
||||
pla
|
||||
+ jsr byte2hex
|
||||
+ jsr c64utils.byte2hex
|
||||
txa
|
||||
jsr c64.CHROUT
|
||||
tya
|
||||
@ -716,16 +716,16 @@ asmsub print_word_decimal0 (dataword: uword @ XY) -> clobbers(A,X,Y) -> () {
|
||||
; ---- print the (unsigned) word in X/Y in decimal form, with left padding 0s (5 positions total)
|
||||
; @todo shorter in loop form?
|
||||
%asm {{
|
||||
jsr word2decimal
|
||||
lda word2decimal_output
|
||||
jsr c64utils.word2decimal
|
||||
lda c64utils.word2decimal_output
|
||||
jsr c64.CHROUT
|
||||
lda word2decimal_output+1
|
||||
lda c64utils.word2decimal_output+1
|
||||
jsr c64.CHROUT
|
||||
lda word2decimal_output+2
|
||||
lda c64utils.word2decimal_output+2
|
||||
jsr c64.CHROUT
|
||||
lda word2decimal_output+3
|
||||
lda c64utils.word2decimal_output+3
|
||||
jsr c64.CHROUT
|
||||
lda word2decimal_output+4
|
||||
lda c64utils.word2decimal_output+4
|
||||
jmp c64.CHROUT
|
||||
}}
|
||||
}
|
||||
@ -734,27 +734,27 @@ asmsub print_word_decimal0 (dataword: uword @ XY) -> clobbers(A,X,Y) -> () {
|
||||
asmsub print_word_decimal (dataword: uword @ XY) -> clobbers(A,X,Y) -> () {
|
||||
; ---- print the word in X/Y in decimal form, without left padding 0s
|
||||
%asm {{
|
||||
jsr word2decimal
|
||||
jsr c64utils.word2decimal
|
||||
ldy #0
|
||||
lda word2decimal_output
|
||||
lda c64utils.word2decimal_output
|
||||
cmp #'0'
|
||||
bne _pr_decimal
|
||||
iny
|
||||
lda word2decimal_output+1
|
||||
lda c64utils.word2decimal_output+1
|
||||
cmp #'0'
|
||||
bne _pr_decimal
|
||||
iny
|
||||
lda word2decimal_output+2
|
||||
lda c64utils.word2decimal_output+2
|
||||
cmp #'0'
|
||||
bne _pr_decimal
|
||||
iny
|
||||
lda word2decimal_output+3
|
||||
lda c64utils.word2decimal_output+3
|
||||
cmp #'0'
|
||||
bne _pr_decimal
|
||||
iny
|
||||
|
||||
_pr_decimal
|
||||
lda word2decimal_output,y
|
||||
lda c64utils.word2decimal_output,y
|
||||
jsr c64.CHROUT
|
||||
iny
|
||||
cpy #5
|
||||
|
@ -82,15 +82,6 @@ mul_f
|
||||
neg_f
|
||||
rts
|
||||
|
||||
less_ub
|
||||
rts
|
||||
|
||||
less_b
|
||||
rts
|
||||
|
||||
less_f
|
||||
rts
|
||||
|
||||
|
||||
add_w
|
||||
rts ; @todo inline?
|
||||
@ -120,7 +111,92 @@ div_w
|
||||
div_uw
|
||||
rts
|
||||
|
||||
remainder_b
|
||||
rts
|
||||
remainder_ub
|
||||
rts
|
||||
remainder_w
|
||||
rts
|
||||
remainder_uw
|
||||
rts
|
||||
remainder_f
|
||||
rts
|
||||
|
||||
equal_ub
|
||||
rts
|
||||
|
||||
equal_b
|
||||
rts
|
||||
|
||||
equal_w
|
||||
rts
|
||||
|
||||
equal_uw
|
||||
rts
|
||||
|
||||
equal_f
|
||||
rts
|
||||
|
||||
less_ub
|
||||
rts
|
||||
|
||||
less_b
|
||||
rts
|
||||
|
||||
less_w
|
||||
rts
|
||||
|
||||
less_uw
|
||||
rts
|
||||
|
||||
less_f
|
||||
rts
|
||||
|
||||
lesseq_ub
|
||||
rts
|
||||
|
||||
lesseq_b
|
||||
rts
|
||||
|
||||
lesseq_w
|
||||
rts
|
||||
|
||||
lesseq_uw
|
||||
rts
|
||||
|
||||
lesseq_f
|
||||
rts
|
||||
|
||||
greater_ub
|
||||
rts
|
||||
|
||||
greater_b
|
||||
rts
|
||||
|
||||
greater_w
|
||||
rts
|
||||
|
||||
greater_uw
|
||||
rts
|
||||
|
||||
greater_f
|
||||
rts
|
||||
|
||||
greatereq_ub
|
||||
rts
|
||||
|
||||
greatereq_b
|
||||
rts
|
||||
|
||||
greatereq_w
|
||||
rts
|
||||
|
||||
greatereq_uw
|
||||
rts
|
||||
|
||||
greatereq_f
|
||||
rts
|
||||
|
||||
func_sin
|
||||
rts
|
||||
func_cos
|
||||
|
Loading…
Reference in New Issue
Block a user