mirror of
https://github.com/irmen/prog8.git
synced 2024-09-10 09:54:32 +00:00
doc
This commit is contained in:
parent
ab1766a559
commit
bf7f4bba7b
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
--------
|
--------
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user