This commit is contained in:
Irmen de Jong 2022-04-13 20:43:07 +02:00
parent ab1766a559
commit bf7f4bba7b
6 changed files with 112 additions and 57 deletions

View File

@ -1575,8 +1575,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
private fun outputAddressAndLenghtOfArray(arg: Expression) { private fun outputAddressAndLenghtOfArray(arg: Expression) {
// address in P8ZP_SCRATCH_W1, number of elements in A // address in P8ZP_SCRATCH_W1, number of elements in A
arg as IdentifierReference arg as IdentifierReference
val arrayVar = arg.targetVarDecl(program)!!
if(!arrayVar.isArray)
throw AssemblyError("length of non-array requested")
val size = arrayVar.arraysize!!.constIndex()!!
val identifierName = asmgen.asmVariableName(arg) val identifierName = asmgen.asmVariableName(arg)
val size = arg.targetVarDecl(program)!!.arraysize!!.constIndex()!!
asmgen.out(""" asmgen.out("""
lda #<$identifierName lda #<$identifierName
ldy #>$identifierName ldy #>$identifierName

View File

@ -12,11 +12,13 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
fun translate(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { fun translate(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
return when(call.name) { return when(call.name) {
"cmp" -> TODO("cmp() can't be used on vm because no processor status bits implemented") "max" -> funcMax(call, resultRegister)
"max" -> TODO()
"min" -> TODO() "min" -> TODO()
"sum" -> TODO() "sum" -> TODO()
"abs" -> TODO() "any" -> TODO()
"all" -> TODO()
"abs" -> TODO("abs once we can compare plus minus")
"cmp" -> TODO("cmp() can't be used on vm because no processor status bits implemented")
"sgn" -> funcSgn(call, resultRegister) "sgn" -> funcSgn(call, resultRegister)
"sin" -> TODO("floats not yet implemented") "sin" -> TODO("floats not yet implemented")
"cos" -> TODO("floats not yet implemented") "cos" -> TODO("floats not yet implemented")
@ -31,8 +33,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
"round" -> TODO("floats not yet implemented") "round" -> TODO("floats not yet implemented")
"floor" -> TODO("floats not yet implemented") "floor" -> TODO("floats not yet implemented")
"ceil" -> TODO("floats not yet implemented") "ceil" -> TODO("floats not yet implemented")
"any" -> TODO()
"all" -> TODO()
"pop" -> funcPop(call) "pop" -> funcPop(call)
"popw" -> funcPopw(call) "popw" -> funcPopw(call)
"push" -> funcPush(call) "push" -> funcPush(call)
@ -59,8 +59,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
"pokew" -> funcPokeW(call) "pokew" -> funcPokeW(call)
"pokemon" -> VmCodeChunk() "pokemon" -> VmCodeChunk()
"mkword" -> funcMkword(call, resultRegister) "mkword" -> funcMkword(call, resultRegister)
"sin8u" -> funcSin8u(call, resultRegister)
"cos8u" -> funcCos8u(call, resultRegister)
"sort" -> funcSort(call) "sort" -> funcSort(call)
"reverse" -> funcReverse(call) "reverse" -> funcReverse(call)
"swap" -> funcSwap(call) "swap" -> funcSwap(call)
@ -72,6 +70,25 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
} }
} }
private fun funcMax(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
val arrayName = (call.args.single() as PtIdentifier).targetName
val array = codeGen.symbolTable.flat.getValue(arrayName) as StStaticVariable
when (array.dt) {
DataType.ARRAY_UW, DataType.ARRAY_W -> {
TODO("max word array")
}
DataType.STR -> {
TODO("max string")
}
else -> {
TODO("max byte array")
}
}
return code
}
private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0) code += exprGen.translateExpression(call.args.single(), 0)
@ -164,24 +181,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
return code return code
} }
private fun funcCos8u(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
code += exprGen.translateExpression(call.args[0], 0)
code += VmCodeInstruction(Opcode.SYSCALL, value=Syscall.COS8U.ordinal)
if(resultRegister!=0)
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
return code
}
private fun funcSin8u(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
code += exprGen.translateExpression(call.args[0], 0)
code += VmCodeInstruction(Opcode.SYSCALL, value=Syscall.SIN8U.ordinal)
if(resultRegister!=0)
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
return code
}
private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val msbReg = codeGen.vmRegisters.nextFree() val msbReg = codeGen.vmRegisters.nextFree()
val lsbReg = codeGen.vmRegisters.nextFree() val lsbReg = codeGen.vmRegisters.nextFree()

View File

@ -214,6 +214,67 @@ math
Low level math routines. You should not normally have to bother with this directly. Low level math routines. You should not normally have to bother with this directly.
The compiler needs it to implement most of the math operations in your programs. The compiler needs it to implement most of the math operations in your programs.
However there's a bunch of integer trig functions in here too that use lookup tables
to quickly calculate sine and cosines. Usually a custom lookup table is the way to go if your
application needs this, but perhaps the provided ones can be of service too:
sin8u(x)
Fast 8-bit ubyte sine of angle 0..255, result is in range 0..255
sin8(x)
Fast 8-bit byte sine of angle 0..255, result is in range -127..127
sin16u(x)
Fast 16-bit uword sine of angle 0..255, result is in range 0..65535
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!
cos8u(x)
Fast 8-bit ubyte cosine of angle 0..255, result is in range 0..255
cos8(x)
Fast 8-bit byte cosine of angle 0..255, result is in range -127..127
cos16u(x)
Fast 16-bit uword cosine of angle 0..255, result is in range 0..65535
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!
cx16logo cx16logo
-------- --------

View File

@ -3,8 +3,9 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
- vm: add support for all builtin functions - min/max/any/all should give error when string arg is given instead of array
- can't use abs() etc in pipe expression because return type depends on argument type - can't use abs() etc in pipe expression because return type depends on argument type
- vm: add support for all builtin functions
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls. - pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
- createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there. - createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type

View File

@ -7,14 +7,21 @@
main { main {
sub start() { sub start() {
word zz = 0 word[] values = [1111, -222, -9999, 88, 20222, 0, 0, 1111]
txt.print_b(sgn(zz)) word[] values2 = [0,0,0,0,0,1,0,0,0]
txt.print_w(max("abcde"))
txt.nl() txt.nl()
zz = -100 txt.print_w(max(values))
txt.print_b(sgn(zz))
txt.nl() txt.nl()
zz = 9999 txt.print_w(min(values))
txt.print_b(sgn(zz)) txt.nl()
txt.print_w(sum(values))
txt.nl()
txt.print_ub(any(values))
txt.nl()
txt.print_ub(any(values2))
txt.nl()
txt.print_ub(all(values))
txt.nl() txt.nl()
; uword other = $fe4a ; uword other = $fe4a

View File

@ -21,14 +21,12 @@ SYSCALLS:
12 = rndw ; random WORD 12 = rndw ; random WORD
13 = wait ; wait certain amount of jiffies (1/60 sec) 13 = wait ; wait certain amount of jiffies (1/60 sec)
14 = waitvsync ; wait on vsync 14 = waitvsync ; wait on vsync
15 = sin8u 15 = sort_ubyte array
16 = cos8u 16 = sort_byte array
17 = sort_ubyte array 17 = sort_uword array
18 = sort_byte array 18 = sort_word array
19 = sort_uword array 19 = reverse_bytes array
20 = sort_word array 20 = reverse_words array
21 = reverse_bytes array
22 = reverse_words array
*/ */
enum class Syscall { enum class Syscall {
@ -47,14 +45,12 @@ enum class Syscall {
RNDW, RNDW,
WAIT, WAIT,
WAITVSYNC, WAITVSYNC,
SIN8U,
COS8U,
SORT_UBYTE, SORT_UBYTE,
SORT_BYTE, SORT_BYTE,
SORT_UWORD, SORT_UWORD,
SORT_WORD, SORT_WORD,
REVERSE_BYTES, REVERSE_BYTES, // TODO not as syscall
REVERSE_WORDS REVERSE_WORDS // TODO not as syscall
} }
object SysCalls { object SysCalls {
@ -112,18 +108,6 @@ object SysCalls {
Thread.sleep(millis) Thread.sleep(millis)
} }
Syscall.WAITVSYNC -> vm.waitvsync() Syscall.WAITVSYNC -> vm.waitvsync()
Syscall.SIN8U -> {
val arg = vm.registers.getUB(0).toDouble()
val rad = arg /256.0 * 2.0 * PI
val answer = truncate(128.0 + 127.5 * sin(rad))
vm.registers.setUB(0, answer.toUInt().toUByte())
}
Syscall.COS8U -> {
val arg = vm.registers.getUB(0).toDouble()
val rad = arg /256.0 * 2.0 * PI
val answer = truncate(128.0 + 127.5 * cos(rad))
vm.registers.setUB(0, answer.toUInt().toUByte())
}
Syscall.SORT_UBYTE -> { Syscall.SORT_UBYTE -> {
val address = vm.registers.getUW(0).toInt() val address = vm.registers.getUW(0).toInt()
val length = vm.registers.getUB(1).toInt() val length = vm.registers.getUB(1).toInt()