diff --git a/compiler/examples/comparison_ifs_byte.p8 b/compiler/examples/comparison_ifs_byte.p8 index 9d8e9e386..8c495a4df 100644 --- a/compiler/examples/comparison_ifs_byte.p8 +++ b/compiler/examples/comparison_ifs_byte.p8 @@ -10,7 +10,7 @@ byte v1 byte v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') v1 = 100 @@ -110,7 +110,7 @@ else c64.STROUT("error in 22>=22!\n") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') } diff --git a/compiler/examples/comparison_ifs_float.p8 b/compiler/examples/comparison_ifs_float.p8 index c338d9dd8..49d7acde2 100644 --- a/compiler/examples/comparison_ifs_float.p8 +++ b/compiler/examples/comparison_ifs_float.p8 @@ -10,7 +10,7 @@ float v1 float v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') v1 = 1.11 @@ -110,7 +110,7 @@ else c64.STROUT("error in -22.2>=-22.2!\n") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') } diff --git a/compiler/examples/comparison_ifs_uword.p8 b/compiler/examples/comparison_ifs_uword.p8 index d5a21e51c..9dd7fe07b 100644 --- a/compiler/examples/comparison_ifs_uword.p8 +++ b/compiler/examples/comparison_ifs_uword.p8 @@ -10,7 +10,7 @@ uword v1 uword v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') v1 = 100 @@ -110,7 +110,7 @@ else c64.STROUT("error in 322>=322!\n") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') } diff --git a/compiler/examples/comparisons_byte.p8 b/compiler/examples/comparisons_byte.p8 index 2676f7335..2a43c6bd7 100644 --- a/compiler/examples/comparisons_byte.p8 +++ b/compiler/examples/comparisons_byte.p8 @@ -11,7 +11,7 @@ ; check stack usage: c64.STROUT("signed byte ") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT(' ') cr=v1==v2 @@ -39,7 +39,7 @@ cr=v1>=v2 cr=v1>=v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') ; comparisons: @@ -58,7 +58,7 @@ c64.STROUT("v1=20, v2=-111\n") compare() - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') return diff --git a/compiler/examples/comparisons_float.p8 b/compiler/examples/comparisons_float.p8 index dd8a3e2a6..fd3c295e9 100644 --- a/compiler/examples/comparisons_float.p8 +++ b/compiler/examples/comparisons_float.p8 @@ -13,7 +13,7 @@ ; check stack usage: c64.STROUT("floating point ") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT(' ') cr=v1==v2 @@ -41,7 +41,7 @@ cr=v1>=v2 cr=v1>=v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') ; comparisons: @@ -75,7 +75,7 @@ c64.STROUT("v1 = v2 = 0\n") compare() - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') return diff --git a/compiler/examples/comparisons_ubyte.p8 b/compiler/examples/comparisons_ubyte.p8 index a6249e577..e6451dbe9 100644 --- a/compiler/examples/comparisons_ubyte.p8 +++ b/compiler/examples/comparisons_ubyte.p8 @@ -11,7 +11,7 @@ ; check stack usage: c64.STROUT("unsigned byte ") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT(' ') cr=v1==v2 @@ -39,7 +39,7 @@ cr=v1>=v2 cr=v1>=v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') ; comparisons: @@ -58,7 +58,7 @@ c64.STROUT("v1=220, v2=10\n") compare() - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') return diff --git a/compiler/examples/comparisons_uword.p8 b/compiler/examples/comparisons_uword.p8 index d054ec465..a886e2a65 100644 --- a/compiler/examples/comparisons_uword.p8 +++ b/compiler/examples/comparisons_uword.p8 @@ -11,7 +11,7 @@ ; check stack usage: c64.STROUT("unsigned word ") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT(' ') cr=v1==v2 @@ -39,7 +39,7 @@ cr=v1>=v2 cr=v1>=v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') ; comparisons: @@ -88,7 +88,7 @@ c64.STROUT("v1 = v2 = aa\n") compare() - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') return diff --git a/compiler/examples/comparisons_word.p8 b/compiler/examples/comparisons_word.p8 index 011f8685f..21723dae9 100644 --- a/compiler/examples/comparisons_word.p8 +++ b/compiler/examples/comparisons_word.p8 @@ -12,7 +12,7 @@ ; check stack usage: c64.STROUT("signed word ") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT(' ') cr=v1==v2 @@ -40,7 +40,7 @@ cr=v1>=v2 cr=v1>=v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') ; comparisons: @@ -125,7 +125,7 @@ c64.STROUT("v1 = v2 = aa\n") compare() - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') return diff --git a/compiler/examples/comparsion_ifs_ubyte.p8 b/compiler/examples/comparsion_ifs_ubyte.p8 index 3d440ec2a..2af1a22a9 100644 --- a/compiler/examples/comparsion_ifs_ubyte.p8 +++ b/compiler/examples/comparsion_ifs_ubyte.p8 @@ -10,7 +10,7 @@ ubyte v1 ubyte v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') v1 = 100 @@ -110,7 +110,7 @@ else c64.STROUT("error in 22>=22!\n") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') } diff --git a/compiler/examples/comparsion_ifs_word.p8 b/compiler/examples/comparsion_ifs_word.p8 index 747eca9e8..ca4d1a717 100644 --- a/compiler/examples/comparsion_ifs_word.p8 +++ b/compiler/examples/comparsion_ifs_word.p8 @@ -10,7 +10,7 @@ word v1 word v2 - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') v1 = 100 @@ -110,7 +110,7 @@ else c64.STROUT("error in -222>=-222!\n") - c64scr.print_byte_decimal(X) + c64scr.print_byte(X) c64.CHROUT('\n') } diff --git a/compiler/examples/numbergame-c64.p8 b/compiler/examples/numbergame-c64.p8 index 4b1f40181..053c89a37 100644 --- a/compiler/examples/numbergame-c64.p8 +++ b/compiler/examples/numbergame-c64.p8 @@ -39,7 +39,7 @@ ask_guess: c64.STROUT("\nYou have ") - c64scr.print_ubyte_decimal(attempts_left) + c64scr.print_ubyte(attempts_left) c64.STROUT(" guess") if(attempts_left>1) c64.STROUT("es") @@ -66,7 +66,7 @@ ask_guess: ; game over. c64.STROUT("\nToo bad! It was: ") - c64scr.print_ubyte_decimal(secretnumber) + c64scr.print_ubyte(secretnumber) c64.CHROUT('\n') goodbye: diff --git a/compiler/examples/numbergame-novm.p8 b/compiler/examples/numbergame-novm.p8 index aeccbd34f..a8cda640c 100644 --- a/compiler/examples/numbergame-novm.p8 +++ b/compiler/examples/numbergame-novm.p8 @@ -22,11 +22,11 @@ for ubyte attempts_left in 10 to 1 step -1 { ; stackptr debugging -; c64scr.print_byte_decimal(X) +; c64scr.print_byte(X) ; c64.CHROUT('\n') c64scr.print_string("\nYou have ") - c64scr.print_ubyte_decimal(attempts_left) + c64scr.print_ubyte(attempts_left) c64scr.print_string(" guess") if attempts_left>1 c64scr.print_string("es") @@ -36,15 +36,15 @@ ; debug info ; c64scr.print_string(" > attempts left=") -; c64scr.print_byte_decimal(attempts_left) +; c64scr.print_byte(attempts_left) ; c64scr.print_string("\n > secretnumber=") -; c64scr.print_byte_decimal(secretnumber) +; c64scr.print_byte(secretnumber) ; c64scr.print_string("\n > input=") ; c64scr.print_string(input) ; c64scr.print_string("\n > guess=") -; c64scr.print_byte_decimal(guess) +; c64scr.print_byte(guess) ; c64.CHROUT('\n') -; c64scr.print_byte_decimal(X) ; stackptr debugging +; c64scr.print_byte(X) ; stackptr debugging ; c64.CHROUT('\n') if guess==secretnumber { @@ -66,7 +66,7 @@ c64scr.print_string("\n\nYou guessed it, impressive!\n") else { c64scr.print_string("\nToo bad! My number was: ") - c64scr.print_ubyte_decimal(secretnumber) + c64scr.print_ubyte(secretnumber) c64scr.print_string(".\n") } c64scr.print_string("Thanks for playing, ") diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index d39094578..94b94ff51 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -3,24 +3,69 @@ ~ main { - memory ubyte[40] screen = $0400 - - poke() sub start() { - float t = 0.0 - while(true) { - ubyte x = lsb(round(sin(t)*15.0))+20 - ubyte y = lsb(round(cos(t)*10.0))+12 -; vm_gfx_text(x, y, 1, "*") - ;vm_gfx_pixel(x,y,1) -; c64scr.print_ubyte_decimal(x) -; c64.CHROUT(',') -; c64scr.print_ubyte_decimal(y) -; c64.CHROUT('\n') - screen[x] = '*' - t+=0.1 - } + uword uw1 + uword uw2 + word w1 + word w2 + ubyte ub1 + ubyte ub2 + byte b1 + byte b2 + float f1 + float f2 + + ub1 = 200 + c64scr.print_ubyte(abs(ub1)) ; ok + c64.CHROUT('\n') + b1 = 100 + c64scr.print_byte(abs(b1)) ; ok + c64.CHROUT('\n') + b1 = 0 + c64scr.print_byte(abs(b1)) ;ok + c64.CHROUT('\n') + b1 = -100 + c64scr.print_byte(abs(b1)) ;ok + c64.CHROUT('\n') + + uw1 = 1000 + c64scr.print_uword(abs(uw1)) ;ok + c64.CHROUT('\n') + w1 = 0 + c64scr.print_word(abs(w1)) ;ok + c64.CHROUT('\n') + w1 = -1000 + c64scr.print_word(abs(w1)) ;ok + c64.CHROUT('\n') + + f1 = 11.22 + c64flt.print_float(abs(f1)) ;ok + c64.CHROUT('\n') + f1 = 0 + c64flt.print_float(abs(f1)) ;ok + c64.CHROUT('\n') + f1 = -22.33 + c64flt.print_float(abs(f1)) ;@todo FAIL + c64.CHROUT('\n') + +; float t = 0.0 +; ubyte color=0 +; while(true) { +; ubyte x = lsb(round(sin(t)*17.0))+20 +; ubyte y = lsb(round(cos(t*1.3634567)*10.0))+12 +; +; c64scr.setchrclr(x,y,color,color) +; color++ +;; vm_gfx_text(x, y, 1, "*") +; ;vm_gfx_pixel(x,y,1) +;; c64scr.print_ubyte(x) +;; c64.CHROUT(',') +;; c64scr.print_ubyte(y) +;; c64.CHROUT('\n') +; ;screen[x] = '*' +; t+=0.1 +; } } } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index cc4de66f5..79a76ca06 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -711,6 +711,17 @@ private class StatementTranslator(private val prog: IntermediateProgram, } } + "abs" -> { + // 1 argument, type determines the exact opcode to use + val arg = args.single() + when (arg.resultingDatatype(namespace, heap)) { + DataType.UBYTE, DataType.UWORD -> {} + DataType.BYTE -> prog.instr(Opcode.ABS_B) + DataType.WORD -> prog.instr(Opcode.ABS_W) + DataType.FLOAT -> prog.instr(Opcode.ABS_F) + else -> throw CompilerException("wrong datatype for $funcname()") + } + } "flt" -> { // 1 argument, type determines the exact opcode to use val arg = args.single() diff --git a/compiler/src/prog8/compiler/intermediate/Opcode.kt b/compiler/src/prog8/compiler/intermediate/Opcode.kt index 882e49b6c..7d329053a 100644 --- a/compiler/src/prog8/compiler/intermediate/Opcode.kt +++ b/compiler/src/prog8/compiler/intermediate/Opcode.kt @@ -72,6 +72,9 @@ enum class Opcode { NEG_B, NEG_W, NEG_F, + ABS_B, + ABS_W, + ABS_F, // bit shifts and bitwise arithmetic SHL_BYTE, diff --git a/compiler/src/prog8/compiler/intermediate/Value.kt b/compiler/src/prog8/compiler/intermediate/Value.kt index 38002a3be..971d2b3f7 100644 --- a/compiler/src/prog8/compiler/intermediate/Value.kt +++ b/compiler/src/prog8/compiler/intermediate/Value.kt @@ -325,6 +325,15 @@ class Value(val type: DataType, numericvalueOrHeapId: Number) { } } + fun abs(): Value { + return when(type) { + DataType.BYTE -> Value(DataType.BYTE, abs(byteval!!.toInt())) + DataType.WORD -> Value(DataType.WORD, abs(wordval!!)) + DataType.FLOAT -> Value(DataType.FLOAT, abs(floatval!!)) + else -> throw VmExecutionException("abs can only work on byte/word/float") + } + } + fun bitand(other: Value): Value { val v1 = integerValue() val v2 = other.integerValue() diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 97ff64f83..0c0b65812 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -409,16 +409,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, Opcode.RSAVE -> { // save cpu status flag and all registers A, X, Y. // see http://6502.org/tutorials/register_preservation.html - """ - php - sta ${C64Zeropage.SCRATCH_REG} - pha - txa - pha - tya - pha - lda ${C64Zeropage.SCRATCH_REG} - """ + " php | sta ${C64Zeropage.SCRATCH_REG} | pha | txa | pha | tya | pha | lda ${C64Zeropage.SCRATCH_REG}" } Opcode.RRESTORE -> { // restore all registers and cpu status flag @@ -623,16 +614,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, jsr prog8_lib.dec_var_f """ } - Opcode.NEG_B -> { - """ - lda ${(ESTACK_LO+1).toHex()},x - eor #255 - sec - adc #0 - sta ${(ESTACK_LO+1).toHex()},x - """ - } + Opcode.NEG_B -> " jsr prog8_lib.neg_b" + Opcode.NEG_W -> " jsr prog8_lib.neg_w" Opcode.NEG_F -> " jsr prog8_lib.neg_f" + Opcode.ABS_B -> " jsr prog8_lib.abs_b" + Opcode.ABS_W -> " jsr prog8_lib.abs_w" + Opcode.ABS_F -> " jsr prog8_lib.abs_f" Opcode.INV_BYTE -> { """ lda ${(ESTACK_LO + 1).toHex()},x @@ -640,38 +627,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${(ESTACK_LO + 1).toHex()},x """ } - Opcode.INV_WORD -> { - """ - lda ${(ESTACK_LO+1).toHex()},x - eor #255 - sta ${(ESTACK_LO+1).toHex()},x - lda ${(ESTACK_HI+1).toHex()},x - eor #255 - sta ${(ESTACK_HI+1).toHex()},x - """ - } - Opcode.NOT_BYTE -> { - """ - lda ${(ESTACK_LO+1).toHex()},x - beq + - lda #0 - beq ++ -+ lda #1 -+ sta ${(ESTACK_LO+1).toHex()},x - """ - } - Opcode.NOT_WORD -> { - """ - lda ${(ESTACK_LO + 1).toHex()},x - ora ${(ESTACK_HI + 1).toHex()},x - beq + - lda #0 - beq ++ -+ lda #1 -+ sta ${(ESTACK_LO + 1).toHex()},x | sta ${(ESTACK_HI + 1).toHex()},x - """ - } - + Opcode.INV_WORD -> " jsr prog8_lib.inv_word" + Opcode.NOT_BYTE -> " jsr prog8_lib.not_byte" + Opcode.NOT_WORD -> " jsr prog8_lib.not_word" Opcode.BCS -> " bcs ${ins.callLabel}" Opcode.BCC -> " bcc ${ins.callLabel}" Opcode.BNEG -> " bmi ${ins.callLabel}" @@ -744,11 +702,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, sta ${(ESTACK_LO + 1).toHex()},x """ } - Opcode.ADD_W -> " jsr prog8_lib.add_w" // todo inline? - Opcode.ADD_UW -> " jsr prog8_lib.add_uw" // todo inline? + Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_w" Opcode.ADD_F -> " jsr prog8_lib.add_f" - Opcode.SUB_W -> " jsr prog8_lib.sub_w" // todo inline? - Opcode.SUB_UW -> " jsr prog8_lib.sub_uw" // todo inline? + Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_w" Opcode.SUB_F -> " jsr prog8_lib.sub_f" Opcode.MUL_B -> " jsr prog8_lib.mul_b" Opcode.MUL_UB -> " jsr prog8_lib.mul_ub" diff --git a/compiler/src/prog8/functions/BuiltinFunctions.kt b/compiler/src/prog8/functions/BuiltinFunctions.kt index 397b90df6..0f00ac894 100644 --- a/compiler/src/prog8/functions/BuiltinFunctions.kt +++ b/compiler/src/prog8/functions/BuiltinFunctions.kt @@ -22,10 +22,11 @@ val BuiltinFunctions = mapOf( "ror2" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null), "lsl" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null), "lsr" to FunctionSignature(false, listOf(BuiltinFunctionParam("item", setOf(DataType.UBYTE, DataType.UWORD))), null), - // these few have a return value depending on the argument list: + // these few have a return value depending on the argument(s): "max" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.max()!! }}, // type depends on args "min" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.min()!! }}, // type depends on args "sum" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), null) { a, p, n, h -> collectionArgOutputNumber(a, p, n, h) { it.sum() }}, // type depends on args + "abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", NumericDatatypes)), null, ::builtinAbs), // type depends on argument // normal functions follow: "sin" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::sin) }, "cos" to FunctionSignature(true, listOf(BuiltinFunctionParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::cos) }, @@ -38,7 +39,6 @@ val BuiltinFunctions = mapOf( "rad" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toRadians) }, "deg" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, n, h -> oneDoubleArg(a, p, n, h, Math::toDegrees) }, "avg" to FunctionSignature(true, listOf(BuiltinFunctionParam("values", ArrayDatatypes)), DataType.FLOAT, ::builtinAvg), - "abs" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.FLOAT, ::builtinAbs), "round" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::round) }, "floor" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::floor) }, "ceil" to FunctionSignature(true, listOf(BuiltinFunctionParam("value", setOf(DataType.FLOAT))), DataType.WORD) { a, p, n, h -> oneDoubleArgOutputWord(a, p, n, h, Math::ceil) }, @@ -128,7 +128,7 @@ fun builtinFunctionReturnType(function: String, args: List, namespa // function has return values, but the return type depends on the arguments return when (function) { - "max", "min" -> { + "max", "min", "abs" -> { val dt = datatypeFromListArg(args.single()) when(dt) { DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> dt diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index 4f4f766de..9109cb585 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -542,6 +542,21 @@ class StackVm(private var traceOutputFile: String?) { checkDt(v, DataType.FLOAT) evalstack.push(v.neg()) } + Opcode.ABS_B -> { + val v = evalstack.pop() + checkDt(v, DataType.BYTE) + evalstack.push(v.abs()) + } + Opcode.ABS_W -> { + val v = evalstack.pop() + checkDt(v, DataType.WORD) + evalstack.push(v.abs()) + } + Opcode.ABS_F -> { + val v = evalstack.pop() + checkDt(v, DataType.FLOAT) + evalstack.push(v.abs()) + } Opcode.SHL_BYTE -> { val v = evalstack.pop() checkDt(v, DataType.UBYTE) diff --git a/prog8lib/c64utils.p8 b/prog8lib/c64utils.p8 index d11ca8cbc..1957c91c3 100644 --- a/prog8lib/c64utils.p8 +++ b/prog8lib/c64utils.p8 @@ -11,6 +11,10 @@ ~ c64utils { + const uword ESTACK_LO = $ce00 + const uword ESTACK_HI = $cf00 + + ; ----- utility functions ---- asmsub init_system () -> clobbers(A,X,Y) -> () { @@ -613,7 +617,7 @@ asmsub print_pstring (text: str_p @ AY) -> clobbers(A,X) -> (ubyte @ Y) { } -asmsub print_ubyte_decimal0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () { +asmsub print_ubyte0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () { ; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total) %asm {{ jsr c64utils.ubyte2decimal @@ -628,7 +632,7 @@ asmsub print_ubyte_decimal0 (value: ubyte @ A) -> clobbers(A,X,Y) -> () { } -asmsub print_ubyte_decimal (value: ubyte @ A) -> clobbers(A,X,Y) -> () { +asmsub print_ubyte (value: ubyte @ A) -> clobbers(A,X,Y) -> () { ; ---- print the ubyte in A in decimal form, without left padding 0s %asm {{ jsr c64utils.ubyte2decimal @@ -649,7 +653,7 @@ _print_tens txa }} } -asmsub print_byte_decimal (value: byte @ A) -> clobbers(A,X,Y) -> () { +asmsub print_byte (value: byte @ A) -> clobbers(A,X,Y) -> () { ; ---- print the byte in A in decimal form, without left padding 0s %asm {{ pha @@ -659,7 +663,7 @@ asmsub print_byte_decimal (value: byte @ A) -> clobbers(A,X,Y) -> () { jsr c64.CHROUT + pla jsr c64utils.byte2decimal - jmp print_ubyte_decimal._print_byte_digits + jmp print_ubyte._print_byte_digits }} } @@ -694,7 +698,7 @@ asmsub print_uword_hex (prefix: ubyte @ Pc, value: uword @ AY) -> clobbers(A,X, } -asmsub print_uword_decimal0 (value: uword @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_uword0 (value: uword @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total) ; @todo shorter in loop form? %asm {{ @@ -713,7 +717,7 @@ asmsub print_uword_decimal0 (value: uword @ AY) -> clobbers(A,X,Y) -> () { } -asmsub print_uword_decimal (value: uword @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_uword (value: uword @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in decimal form, without left padding 0s %asm {{ jsr c64utils.uword2decimal @@ -745,7 +749,7 @@ _pr_decimal }} } -asmsub print_word_decimal (value: word @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_word (value: word @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the (signed) word in A/Y in decimal form, without left padding 0s %asm {{ cpy #0 @@ -762,7 +766,7 @@ asmsub print_word_decimal (value: word @ AY) -> clobbers(A,X,Y) -> () { adc #1 bcc + iny -+ jmp print_uword_decimal ++ jmp print_uword }} } @@ -787,4 +791,80 @@ asmsub input_chars (buffer: uword @ AY) -> clobbers(A, X) -> (ubyte @ Y) { }} } +asmsub setchr (col: ubyte @Y, row: ubyte @A) -> clobbers(A) -> () { + ; ---- set the character in SCRATCH_ZPB1 on the screen matrix at the given position + %asm {{ + sty c64.SCRATCH_ZPREG + asl a + tay + lda _screenrows+1,y + sta _mod+2 + lda _screenrows,y + clc + adc c64.SCRATCH_ZPREG + sta _mod+1 + bcc + + inc _mod+2 ++ lda c64.SCRATCH_ZPB1 +_mod sta $ffff ; modified + rts + +_screenrows .word $0400 + range(0, 1000, 40) + }} +} + +asmsub setclr (col: ubyte @Y, row: ubyte @A) -> clobbers(A) -> () { + ; ---- set the color in SCRATCH_ZPB1 on the screen matrix at the given position + %asm {{ + sty c64.SCRATCH_ZPREG + asl a + tay + lda _colorrows+1,y + sta _mod+2 + lda _colorrows,y + clc + adc c64.SCRATCH_ZPREG + sta _mod+1 + bcc + + inc _mod+2 ++ lda c64.SCRATCH_ZPB1 +_mod sta $ffff ; modified + rts + +_colorrows .word $d800 + range(0, 1000, 40) + }} +} + + +sub setchrclr (column: ubyte, row: ubyte, char: ubyte, color: ubyte) { + ; ---- set char+color at the given position on the screen + %asm {{ + lda setchrclr_row + asl a + tay + lda setchr._screenrows+1,y + sta _charmod+2 + adc #$d4 + sta _colormod+2 + lda setchr._screenrows,y + clc + adc setchrclr_column + sta _charmod+1 + sta _colormod+1 + bcc + + inc _charmod+2 + inc _colormod+2 ++ lda setchrclr_char +_charmod sta $ffff ; modified + lda setchrclr_color +_colormod sta $ffff ; modified + inx + inx + inx + inx + rts + }} +} + + } ; ---- end block c64scr diff --git a/prog8lib/prog8lib.p8 b/prog8lib/prog8lib.p8 index a2f60ea1e..86c7f772a 100644 --- a/prog8lib/prog8lib.p8 +++ b/prog8lib/prog8lib.p8 @@ -357,6 +357,26 @@ mul_f .proc jmp push_fac1_as_result .pend +neg_b .proc + lda ESTACK_LO+1,x + eor #255 + clc + adc #1 + sta ESTACK_LO+1,x + rts + .pend + +neg_w .proc + sec + lda #0 + sbc ESTACK_LO+1,x + sta ESTACK_LO+1,x + lda #0 + sbc ESTACK_HI+1,x + sta ESTACK_HI+1,x + rts + .pend + neg_f .proc ; -- push -flt back on stack jsr pop_float_fac1 @@ -364,24 +384,63 @@ neg_f .proc jsr c64.NEGOP jmp push_fac1_as_result .pend - -add_w .proc - ; -- push word+word - .warn "addw check correctness" - inx - clc - lda ESTACK_LO,x - adc ESTACK_LO+1,x +inv_word .proc + lda ESTACK_LO+1,x + eor #255 sta ESTACK_LO+1,x - lda ESTACK_HI,x - adc ESTACK_HI+1,x + lda ESTACK_HI+1,x + eor #255 sta ESTACK_HI+1,x rts .pend + +not_byte .proc + lda ESTACK_LO+1,x + beq + + lda #0 + beq ++ ++ lda #1 ++ sta ESTACK_LO+1,x + rts + .pend -add_uw .proc - .warn "add_uw check correctness" +not_word .proc + lda ESTACK_LO + 1,x + ora ESTACK_HI + 1,x + beq + + lda #0 + beq ++ ++ lda #1 ++ sta ESTACK_LO + 1,x + sta ESTACK_HI + 1,x + rts + .pend + +abs_b .proc + ; -- push abs(byte) on stack (as byte) + lda ESTACK_LO+1,x + bmi neg_b + rts + .pend + +abs_w .proc + ; -- push abs(word) on stack (as word) + lda ESTACK_HI+1,x + bmi neg_w + rts + .pend + +abs_f .proc + ; -- push abs(float) on stack (as float) + jsr pop_float_fac1 + stx SCRATCH_ZPREGX + jsr c64.ABS + jmp push_fac1_as_result + .pend + +add_w .proc + ; -- push word+word / uword+uword inx clc lda ESTACK_LO,x @@ -394,13 +453,16 @@ add_uw .proc .pend sub_w .proc - rts ; @todo inline? - .warn "sub_w not implemented" - .pend - -sub_uw .proc - rts ; @todo inline? - .warn "sub_uw not implemented" + ; -- push word-word + inx + sec + lda ESTACK_LO+1,x + sbc ESTACK_LO,x + sta ESTACK_LO+1,x + lda ESTACK_HI+1,x + sbc ESTACK_HI,x + sta ESTACK_HI+1,x + rts .pend mul_b .proc @@ -445,7 +507,7 @@ div_uw .proc remainder_b .proc rts - .warn "remainder_b not implemented" + .warn "remainder_b via div_b?" .pend remainder_ub .proc @@ -463,12 +525,12 @@ remainder_ub .proc remainder_w .proc rts - .warn "remainder_w not implemented" + .warn "remainder_w not implemented - via div_w" .pend remainder_uw .proc rts - .warn "remainder_uw not implemented" + .warn "remainder_uw not implemented - via div_uw" .pend equal_w .proc @@ -790,11 +852,6 @@ func_cos .proc jmp push_fac1_as_result .pend -func_abs .proc - rts - .warn "abs not implemented" - .pend - func_tan .proc ; -- push tan(f) back onto stack jsr pop_float_fac1