diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index 7cf89c7e5..aa373d6fe 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -46,7 +46,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val "sum" -> funcSum(fcall, resultToStack, resultRegister, sscope) "any", "all" -> funcAnyAll(fcall, func, resultToStack, resultRegister, sscope) "sin8", "sin8u", "sin16", "sin16u", - "cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, resultRegister, sscope) + "sinr8", "sinr8u", "sinr16", "sinr16u", + "cos8", "cos8u", "cos16", "cos16u", + "cosr8", "cosr8u", "cosr16", "cosr16u" -> funcSinCosInt(fcall, func, resultToStack, resultRegister, sscope) "sgn" -> funcSgn(fcall, func, resultToStack, resultRegister, sscope) "sin", "cos", "tan", "atan", "ln", "log2", "sqrt", "rad", @@ -283,11 +285,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.out(" jsr prog8_lib.func_${func.name}_stack") else when(func.name) { - "sin8", "sin8u", "cos8", "cos8u" -> { + "sin8", "sin8u", "sinr8", "sinr8u", "cos8", "cos8u", "cosr8", "cosr8u" -> { asmgen.out(" jsr prog8_lib.func_${func.name}_into_A") assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, scope, program, asmgen), CpuRegister.A) } - "sin16", "sin16u", "cos16", "cos16u" -> { + "sin16", "sin16u", "sinr16", "sinr16u", "cos16", "cos16u", "cosr16", "cosr16u" -> { asmgen.out(" jsr prog8_lib.func_${func.name}_into_AY") assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, scope, program, asmgen), RegisterOrPair.AY) } diff --git a/compiler/res/prog8lib/prog8_funcs.asm b/compiler/res/prog8lib/prog8_funcs.asm index 67e093cb1..a9a4bad0d 100644 --- a/compiler/res/prog8lib/prog8_funcs.asm +++ b/compiler/res/prog8lib/prog8_funcs.asm @@ -91,6 +91,13 @@ func_sin8_into_A .proc _sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0))) .pend +func_sinr8_into_A .proc + tay + lda _sinecosR8,y + rts +_sinecosR8 .char trunc(127.0 * sin(range(180+45) * rad(360.0/180.0))) + .pend + func_sin8u_into_A .proc tay lda _sinecos8u,y @@ -98,6 +105,13 @@ func_sin8u_into_A .proc _sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0))) .pend +func_sinr8u_into_A .proc + tay + lda _sinecosR8u,y + rts +_sinecosR8u .byte trunc(128.0 + 127.5 * sin(range(180+45) * rad(360.0/180.0))) + .pend + func_sin8_stack .proc tay lda func_sin8_into_A._sinecos8,y @@ -106,6 +120,14 @@ func_sin8_stack .proc rts .pend +func_sinr8_stack .proc + tay + lda func_sinr8_into_A._sinecosR8,y + sta P8ESTACK_LO,x + dex + rts + .pend + func_sin8u_stack .proc tay lda func_sin8u_into_A._sinecos8u,y @@ -114,18 +136,38 @@ func_sin8u_stack .proc rts .pend +func_sinr8u_stack .proc + tay + lda func_sinr8u_into_A._sinecosR8u,y + sta P8ESTACK_LO,x + dex + rts + .pend + func_cos8_into_A .proc tay lda func_sin8_into_A._sinecos8+64,y rts .pend +func_cosr8_into_A .proc + tay + lda func_sinr8_into_A._sinecosR8+45,y + rts + .pend + func_cos8u_into_A .proc tay lda func_sin8u_into_A._sinecos8u+64,y rts .pend +func_cosr8u_into_A .proc + tay + lda func_sinr8u_into_A._sinecosR8u+45,y + rts + .pend + func_cos8_stack .proc tay lda func_sin8_into_A._sinecos8+64,y @@ -134,6 +176,14 @@ func_cos8_stack .proc rts .pend +func_cosr8_stack .proc + tay + lda func_sinr8_into_A._sinecosR8+45,y + sta P8ESTACK_LO,x + dex + rts + .pend + func_cos8u_stack .proc tay lda func_sin8u_into_A._sinecos8u+64,y @@ -142,6 +192,14 @@ func_cos8u_stack .proc rts .pend +func_cosr8u_stack .proc + tay + lda func_sinr8u_into_A._sinecosR8u+45,y + sta P8ESTACK_LO,x + dex + rts + .pend + func_sin16_into_AY .proc tay lda _sinecos8lo,y @@ -155,6 +213,19 @@ _sinecos8lo .byte <_ _sinecos8hi .byte >_ .pend +func_sinr16_into_AY .proc + tay + lda _sinecosR8lo,y + pha + lda _sinecosR8hi,y + tay + pla + rts +_ := trunc(32767.0 * sin(range(180+45) * rad(360.0/180.0))) +_sinecosR8lo .byte <_ +_sinecosR8hi .byte >_ + .pend + func_sin16u_into_AY .proc tay lda _sinecos8ulo,y @@ -168,6 +239,18 @@ _sinecos8ulo .byte <_ _sinecos8uhi .byte >_ .pend +func_sinr16u_into_AY .proc + tay + lda _sinecosR8ulo,y + pha + lda _sinecosR8uhi,y + tay + pla + rts +_ := trunc(32768.0 + 32767.5 * sin(range(180+45) * rad(360.0/180.0))) +_sinecosR8ulo .byte <_ +_sinecosR8uhi .byte >_ + .pend func_sin16_stack .proc tay @@ -179,6 +262,16 @@ func_sin16_stack .proc rts .pend +func_sinr16_stack .proc + tay + lda func_sinr16_into_AY._sinecosR8lo,y + sta P8ESTACK_LO,x + lda func_sinr16_into_AY._sinecosR8hi,y + sta P8ESTACK_HI,x + dex + rts + .pend + func_sin16u_stack .proc tay lda func_sin16u_into_AY._sinecos8ulo,y @@ -189,6 +282,16 @@ func_sin16u_stack .proc rts .pend +func_sinr16u_stack .proc + tay + lda func_sinr16u_into_AY._sinecosR8ulo,y + sta P8ESTACK_LO,x + lda func_sinr16u_into_AY._sinecosR8uhi,y + sta P8ESTACK_HI,x + dex + rts + .pend + func_cos16_into_AY .proc tay lda func_sin16_into_AY._sinecos8lo+64,y @@ -199,6 +302,16 @@ func_cos16_into_AY .proc rts .pend +func_cosr16_into_AY .proc + tay + lda func_sinr16_into_AY._sinecosR8lo+45,y + pha + lda func_sinr16_into_AY._sinecosR8hi+45,y + tay + pla + rts + .pend + func_cos16u_into_AY .proc tay lda func_sin16u_into_AY._sinecos8ulo+64,y @@ -209,6 +322,16 @@ func_cos16u_into_AY .proc rts .pend +func_cosr16u_into_AY .proc + tay + lda func_sinr16u_into_AY._sinecosR8ulo+45,y + pha + lda func_sinr16u_into_AY._sinecosR8uhi+45,y + tay + pla + rts + .pend + func_cos16_stack .proc tay lda func_sin16_into_AY._sinecos8lo+64,y @@ -219,6 +342,16 @@ func_cos16_stack .proc rts .pend +func_cosr16_stack .proc + tay + lda func_sinr16_into_AY._sinecosR8lo+45,y + sta P8ESTACK_LO,x + lda func_sinr16_into_AY._sinecosR8hi+45,y + sta P8ESTACK_HI,x + dex + rts + .pend + func_cos16u_stack .proc tay lda func_sin16u_into_AY._sinecos8ulo+64,y @@ -229,6 +362,16 @@ func_cos16u_stack .proc rts .pend +func_cosr16u_stack .proc + tay + lda func_sinr16u_into_AY._sinecosR8ulo+45,y + sta P8ESTACK_LO,x + lda func_sinr16u_into_AY._sinecosR8uhi+45,y + sta P8ESTACK_HI,x + dex + rts + .pend + abs_b_stack .proc ; -- push abs(A) on stack (as byte) jsr abs_b_into_A diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 80a30a5bf..c2b7e43c9 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -429,7 +429,7 @@ internal class AstChecker(private val program: Program, if(targetDt.isIterable) errors.err("cannot assign value to string or array", assignment.value.position) else if(!(valueDt istype DataType.STR && targetDt istype DataType.UWORD)) - errors.err("type of value doesn't match target", assignment.value.position) + errors.err("type of value $valueDt doesn't match target $targetDt", assignment.value.position) } if(assignment.value is TypecastExpression) { diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index 1b12432d9..4e5174f6f 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -87,6 +87,9 @@ class TestCompilerOnExamplesCx16: FunSpec({ "kefrenbars", "mandelbrot-gfx-colors", "multipalette", + "rasterbars", + "sincos", + "tehtriz", "testgfx2", ), listOf(false, true) diff --git a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt index 0ba762b10..1eb5b9b38 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt @@ -109,11 +109,19 @@ private val functionSignatures: List = listOf( FSignature("sin8u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UBYTE, ::builtinSin8u ), FSignature("sin16" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.WORD, ::builtinSin16 ), FSignature("sin16u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UWORD, ::builtinSin16u ), + FSignature("sinr8" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.BYTE, ::builtinSinR8 ), + FSignature("sinr8u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UBYTE, ::builtinSinR8u ), + FSignature("sinr16" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.WORD, ::builtinSinR16 ), + FSignature("sinr16u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UWORD, ::builtinSinR16u ), FSignature("cos" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::cos) }, FSignature("cos8" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.BYTE, ::builtinCos8 ), FSignature("cos8u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UBYTE, ::builtinCos8u ), FSignature("cos16" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.WORD, ::builtinCos16 ), FSignature("cos16u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UWORD, ::builtinCos16u ), + FSignature("cosr8" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.BYTE, ::builtinCosR8 ), + FSignature("cosr8u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UBYTE, ::builtinCosR8u ), + FSignature("cosr16" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.WORD, ::builtinCosR16 ), + FSignature("cosr16u" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.UWORD, ::builtinCosR16u ), FSignature("tan" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::tan) }, FSignature("atan" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::atan) }, FSignature("ln" , true, listOf(FParam("value", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::log) }, @@ -372,6 +380,24 @@ private fun builtinSin8u(args: List, position: Position, program: Pr return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * sin(rad)).toInt().toShort(), position) } +@Suppress("UNUSED_PARAMETER") +private fun builtinSinR8(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("sinr8 requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, (127.0 * sin(rad)).toInt().toShort(), position) +} + +@Suppress("UNUSED_PARAMETER") +private fun builtinSinR8u(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("sinr8u requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * sin(rad)).toInt().toShort(), position) +} + @Suppress("UNUSED_PARAMETER") private fun builtinCos8(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 1) @@ -390,6 +416,24 @@ private fun builtinCos8u(args: List, position: Position, program: Pr return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * cos(rad)).toInt().toShort(), position) } +@Suppress("UNUSED_PARAMETER") +private fun builtinCosR8(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("cosr8 requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.BYTE, (127.0 * cos(rad)).toInt().toShort(), position) +} + +@Suppress("UNUSED_PARAMETER") +private fun builtinCosR8u(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("cosr8u requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UBYTE, (128.0 + 127.5 * cos(rad)).toInt().toShort(), position) +} + @Suppress("UNUSED_PARAMETER") private fun builtinSin16(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 1) @@ -408,6 +452,24 @@ private fun builtinSin16u(args: List, position: Position, program: P return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * sin(rad)).toInt(), position) } +@Suppress("UNUSED_PARAMETER") +private fun builtinSinR16(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("sinr16 requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, (32767.0 * sin(rad)).toInt(), position) +} + +@Suppress("UNUSED_PARAMETER") +private fun builtinSinR16u(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("sinr16u requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * sin(rad)).toInt(), position) +} + @Suppress("UNUSED_PARAMETER") private fun builtinCos16(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 1) @@ -426,6 +488,24 @@ private fun builtinCos16u(args: List, position: Position, program: P return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * cos(rad)).toInt(), position) } +@Suppress("UNUSED_PARAMETER") +private fun builtinCosR16(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("cosr16 requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.WORD, (32767.0 * cos(rad)).toInt(), position) +} + +@Suppress("UNUSED_PARAMETER") +private fun builtinCosR16u(args: List, position: Position, program: Program): NumericLiteralValue { + if (args.size != 1) + throw SyntaxError("cosr16u requires one argument", position) + val constval = args[0].constValue(program) ?: throw NotConstArgumentException() + val rad = constval.number.toDouble() / 180.0 * 2.0 * PI + return NumericLiteralValue(DataType.UWORD, (32768.0 + 32767.5 * cos(rad)).toInt(), position) +} + @Suppress("UNUSED_PARAMETER") private fun builtinSgn(args: List, position: Position, program: Program): NumericLiteralValue { if (args.size != 1) diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 153789229..c66e06c91 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -704,6 +704,22 @@ cos16u(x) cos16(x) Fast 16-bit word cosine of angle 0..255, result is in range -32767..32767 +cosr8u(x) + Fast 8-bit ubyte cosine of angle 0..179 (each is a 2 degree step), result is in range 0..255 + Angles 180..255 will yield a garbage result! + +cosr8(x) + Fast 8-bit byte cosine of angle 0..179 (each is a 2 degree step), result is in range -127..127 + Angles 180..255 will yield a garbage result! + +cosr16u(x) + Fast 16-bit uword cosine of angle 0..179 (each is a 2 degree step), result is in range 0..65535 + Angles 180..255 will yield a garbage result! + +cosr16(x) + Fast 16-bit word cosine of angle 0..179 (each is a 2 degree step), result is in range -32767..32767 + Angles 180..255 will yield a garbage result! + deg(x) Radians to degrees. @@ -740,6 +756,22 @@ sin16u(x) sin16(x) Fast 16-bit word sine of angle 0..255, result is in range -32767..32767 +sinr8u(x) + Fast 8-bit ubyte sine of angle 0..179 (each is a 2 degree step), result is in range 0..255 + Angles 180..255 will yield a garbage result! + +sinr8(x) + Fast 8-bit byte sine of angle 0..179 (each is a 2 degree step), result is in range -127..127 + Angles 180..255 will yield a garbage result! + +sinr16u(x) + Fast 16-bit uword sine of angle 0..179 (each is a 2 degree step), result is in range 0..65535 + Angles 180..255 will yield a garbage result! + +sinr16(x) + Fast 16-bit word sine of angle 0..179 (each is a 2 degree step), result is in range -32767..32767 + Angles 180..255 will yield a garbage result! + sqrt16(w) 16 bit unsigned integer Square root. Result is unsigned byte. To do the reverse, squaring an integer, just write ``x*x``. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 05f253804..94f947e35 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,6 @@ TODO For next compiler release (7.3) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- add cosr8, sinr8, cosr16 and sinr16 that take a degree 0..179 (= 0..359 in 2 degree steps) - to more easily scale halves/quarters etc of a circle than possible with the ones that take 0..255 'degrees'. - - if-statement expression simplification sometimes increases code size (Petaxian) FIX THIS! - add expression simplification to while and until loops as well. - let typecasting code use expression.typecastTo() diff --git a/examples/cx16/sincos.p8 b/examples/cx16/sincos.p8 new file mode 100644 index 000000000..7bef8d169 --- /dev/null +++ b/examples/cx16/sincos.p8 @@ -0,0 +1,109 @@ +%import graphics + +; Note: this program is compatible with CX16 only. +; it doesn't work correctly on C64 because the bitmap screen data overlaps +; the program itself in memory $2000-... + + +main { + const uword width = 320 + const ubyte height = 200 + + sub start() { + graphics.enable_bitmap_mode() + + sincos255() + sys.wait(120) + + graphics.clear_screen(1, 0) + + sincos180() + sys.wait(120) + + graphics.clear_screen(1, 0) + circles() + + repeat { + } + } + + sub sincos255() { + graphics.line(256,0,256,height-1) + + ubyte pixelyb + uword pixelyw + ubyte pixelxb + + for pixelxb in 0 to 255 { + pixelyb = cos8u(pixelxb) / 2 + graphics.plot(pixelxb, pixelyb) + pixelyb = sin8u(pixelxb) / 2 + graphics.plot(pixelxb, pixelyb) + } + + for pixelxb in 0 to 255 { + pixelyw = cos16u(pixelxb) / 1024 + 120 + graphics.plot(pixelxb, lsb(pixelyw)) + pixelyw = sin16u(pixelxb) / 1024 + 120 + graphics.plot(pixelxb, lsb(pixelyw)) + } + } + + sub sincos180() { + graphics.line(180,0,180,height-1) + + ubyte pixelyb + uword pixelyw + ubyte pixelxb + + for pixelxb in 0 to 179 { + pixelyb = cosr8u(pixelxb) / 2 + graphics.plot(pixelxb, pixelyb) + pixelyb = sinr8u(pixelxb) / 2 + graphics.plot(pixelxb, pixelyb) + } + + for pixelxb in 0 to 179 { + pixelyw = cosr16u(pixelxb) / 1024 + 120 + graphics.plot(pixelxb, lsb(pixelyw)) + pixelyw = sinr16u(pixelxb) / 1024 + 120 + graphics.plot(pixelxb, lsb(pixelyw)) + } + } + + sub circles() { + ubyte pixelyb + uword pixelxw + ubyte r + + ; circles with "degrees" from 0 to 255 + +; TODO FIX WHEN USING NO-OPT! (CORRECT WHEN USING OPTIMIZATION..) + for r in 0 to 255 { + pixelxw = (sin8(r)/2 + 80) as uword + pixelyb = (cos8(r)/2 + height/2) as ubyte + graphics.plot(pixelxw, pixelyb) + } + + for r in 0 to 255 { + pixelxw = (sin16(r)/1024 + 80) as uword + pixelyb = (cos16(r)/1024 + height/2) as ubyte + graphics.plot(pixelxw, pixelyb) + } + + ; circles with half-degrees from 0 to 179 (=full degrees 0..358 with steps of 2 degrees) +; TODO FIX WHEN USING NO-OPT! (CORRECT WHEN USING OPTIMIZATION..) + for r in 0 to 179 { + pixelxw = (sinr8(r) as word /2 + 220) as uword + pixelyb = (cosr8(r)/2 + height/2) as ubyte + graphics.plot(pixelxw, pixelyb) + } + + for r in 0 to 179 { + pixelxw = (sinr16(r) as word /1024 + 220) as uword + pixelyb = (cosr16(r)/1024 + height/2) as ubyte + graphics.plot(pixelxw, pixelyb) + } + + } +}