mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
vm: implementing more fp instructions
This commit is contained in:
parent
fa357a450b
commit
86cc2f1075
@ -380,10 +380,22 @@ class CodeGen(internal val program: PtProgram,
|
||||
return code
|
||||
}
|
||||
|
||||
internal fun multiplyByConstFloat(fpReg: Int, factor: Float): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if(factor==1f)
|
||||
return code
|
||||
if(factor==0f) {
|
||||
code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f)
|
||||
} else {
|
||||
val factorReg = vmRegisters.nextFreeFloat()
|
||||
code += VmCodeInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpReg2 = fpReg, fpReg3 = factorReg)
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
internal val powersOfTwo = (0..16).map { 2.0.pow(it.toDouble()).toInt() }
|
||||
|
||||
internal fun multiplyByConst(dt: VmDataType, reg: Int, factor: Int): VmCodeChunk {
|
||||
// TODO support floating-point factors
|
||||
val code = VmCodeChunk()
|
||||
if(factor==1)
|
||||
return code
|
||||
|
@ -62,7 +62,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
is PtTypeCast -> code += translate(expr, resultRegister)
|
||||
is PtPrefix -> code += translate(expr, resultRegister)
|
||||
is PtArrayIndexer -> code += translate(expr, resultRegister)
|
||||
is PtBinaryExpression -> code += translate(expr, resultRegister)
|
||||
is PtBinaryExpression -> code += translate(expr, resultRegister, resultFpRegister)
|
||||
is PtBuiltinFunctionCall -> code += codeGen.translateBuiltinFunc(expr, resultRegister)
|
||||
is PtFunctionCall -> code += translate(expr, resultRegister, resultFpRegister)
|
||||
is PtContainmentCheck -> code += translate(expr, resultRegister, resultFpRegister)
|
||||
@ -269,13 +269,13 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
return code
|
||||
}
|
||||
|
||||
private fun translate(binExpr: PtBinaryExpression, resultRegister: Int): VmCodeChunk {
|
||||
private fun translate(binExpr: PtBinaryExpression, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
|
||||
val vmDt = codeGen.vmType(binExpr.left.type)
|
||||
val signed = binExpr.left.type in SignedDatatypes
|
||||
return when(binExpr.operator) {
|
||||
"+" -> operatorPlus(binExpr, vmDt, resultRegister)
|
||||
"-" -> operatorMinus(binExpr, vmDt, resultRegister)
|
||||
"*" -> operatorMultiply(binExpr, vmDt, resultRegister)
|
||||
"*" -> operatorMultiply(binExpr, vmDt, resultRegister, resultFpRegister )
|
||||
"/" -> operatorDivide(binExpr, vmDt, resultRegister)
|
||||
"%" -> operatorModulo(binExpr, vmDt, resultRegister)
|
||||
"|", "or" -> operatorOr(binExpr, vmDt, resultRegister)
|
||||
@ -398,6 +398,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
}
|
||||
|
||||
private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
if(vmDt==VmDataType.FLOAT)
|
||||
throw IllegalArgumentException("floating-point modulo not supported")
|
||||
val code = VmCodeChunk()
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
@ -410,74 +412,104 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val constFactorRight = binExpr.right as? PtNumber
|
||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
val factor = constFactorRight.number.toInt()
|
||||
code += codeGen.divideByConst(vmDt, resultRegister, factor)
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("div float")
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
val factor = constFactorRight.number.toInt()
|
||||
code += codeGen.divideByConst(vmDt, resultRegister, factor)
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
val constFactorLeft = binExpr.left as? PtNumber
|
||||
val constFactorRight = binExpr.right as? PtNumber
|
||||
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.right, resultRegister, -1)
|
||||
val factor = constFactorLeft.number.toInt()
|
||||
code += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||
} else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
val factor = constFactorRight.number.toInt()
|
||||
code += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
if(constFactorLeft!=null) {
|
||||
code += translateExpression(binExpr.right, -1, resultFpRegister)
|
||||
val factor = constFactorLeft.number.toFloat()
|
||||
code += codeGen.multiplyByConstFloat(resultFpRegister, factor)
|
||||
} else if(constFactorRight!=null) {
|
||||
code += translateExpression(binExpr.left, -1, resultFpRegister)
|
||||
val factor = constFactorRight.number.toFloat()
|
||||
code += codeGen.multiplyByConstFloat(resultFpRegister, factor)
|
||||
} else {
|
||||
val leftResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat()
|
||||
code += translateExpression(binExpr.left, -1, leftResultFpReg)
|
||||
code += translateExpression(binExpr.right, -1, rightResultFpReg)
|
||||
code += VmCodeInstruction(Opcode.MUL, vmDt, fpReg1 = resultFpRegister, reg2=leftResultFpReg, reg3=rightResultFpReg)
|
||||
}
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.right, resultRegister, -1)
|
||||
val factor = constFactorLeft.number.toInt()
|
||||
code += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||
} else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
val factor = constFactorRight.number.toInt()
|
||||
code += codeGen.multiplyByConst(vmDt, resultRegister, factor)
|
||||
} else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("minus float")
|
||||
} else {
|
||||
if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk {
|
||||
val code = VmCodeChunk()
|
||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.right, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
if(vmDt==VmDataType.FLOAT) {
|
||||
TODO("plus float")
|
||||
} else {
|
||||
if((binExpr.left as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.right, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else if((binExpr.right as? PtNumber)?.number==1.0) {
|
||||
code += translateExpression(binExpr.left, resultRegister, -1)
|
||||
code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister)
|
||||
}
|
||||
else {
|
||||
val leftResultReg = codeGen.vmRegisters.nextFree()
|
||||
val rightResultReg = codeGen.vmRegisters.nextFree()
|
||||
code += translateExpression(binExpr.left, leftResultReg, -1)
|
||||
code += translateExpression(binExpr.right, rightResultReg, -1)
|
||||
code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg)
|
||||
}
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
@ -184,47 +184,76 @@ sub str2ubyte(str string) -> ubyte {
|
||||
; -- returns in A the unsigned byte value of the string number argument in AY
|
||||
; the number may NOT be preceded by a + sign and may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
return str2uword(string) as ubyte
|
||||
}
|
||||
|
||||
sub str2byte(str string) -> byte {
|
||||
; -- returns in A the signed byte value of the string number argument in AY
|
||||
; the number may be preceded by a + or - sign but may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
return str2word(string) as byte
|
||||
}
|
||||
|
||||
sub str2uword(str string) -> uword {
|
||||
; -- returns the unsigned word value of the string number argument in AY
|
||||
; the number may NOT be preceded by a + sign and may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
%asm {{
|
||||
loadm.w r0, {conv.str2uword.string}
|
||||
syscall 11
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub str2word(str string) -> word {
|
||||
; -- returns the signed word value of the string number argument in AY
|
||||
; the number may be preceded by a + or - sign but may NOT contain spaces
|
||||
; (any non-digit character will terminate the number string that is parsed)
|
||||
; TODO
|
||||
return 0
|
||||
%asm {{
|
||||
loadm.w r0, {conv.str2word.string}
|
||||
syscall 12
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub hex2uword(str string) -> uword {
|
||||
; -- hexadecimal string (with or without '$') to uword.
|
||||
; string may be in petscii or c64-screencode encoding.
|
||||
; stops parsing at the first character that's not a hex digit (except leading $)
|
||||
; TODO
|
||||
return 0
|
||||
; TODO fix this result
|
||||
uword result
|
||||
ubyte char
|
||||
if @(string)=='$'
|
||||
string++
|
||||
repeat {
|
||||
char = @(string)
|
||||
if char==0
|
||||
return result
|
||||
result <<= 4
|
||||
if char>='0' and char<='9'
|
||||
result |= char-'0'
|
||||
else
|
||||
result |= char-'a'+10
|
||||
string++
|
||||
}
|
||||
}
|
||||
|
||||
sub bin2uword(str string) -> uword {
|
||||
; -- binary string (with or without '%') to uword.
|
||||
; stops parsing at the first character that's not a 0 or 1. (except leading %)
|
||||
; TODO
|
||||
return 0
|
||||
; TODO fix this result
|
||||
uword result
|
||||
ubyte char
|
||||
if @(string)=='%'
|
||||
string++
|
||||
repeat {
|
||||
char = @(string)
|
||||
if char==0
|
||||
return result
|
||||
result <<= 1
|
||||
if char=='1'
|
||||
result |= 1
|
||||
string++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,17 +19,15 @@ sub print_f(float value) {
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
; TODO fpow.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.pow.value}
|
||||
loadm.f fr1,{floats.pow.power}
|
||||
fpow.f fr0,fr0
|
||||
fpow.f fr0,fr0,fr1
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub fabs(float value) -> float {
|
||||
; TODO fabs.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.fabs.value}
|
||||
fabs.f fr0,fr0
|
||||
@ -38,7 +36,6 @@ sub fabs(float value) -> float {
|
||||
}
|
||||
|
||||
sub sin(float angle) -> float {
|
||||
; TODO fsin.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.sin.angle}
|
||||
fsin.f fr0,fr0
|
||||
@ -47,7 +44,6 @@ sub sin(float angle) -> float {
|
||||
}
|
||||
|
||||
sub cos(float angle) -> float {
|
||||
; TODO fcos.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.cos.angle}
|
||||
fcos.f fr0,fr0
|
||||
@ -56,7 +52,6 @@ sub cos(float angle) -> float {
|
||||
}
|
||||
|
||||
sub tan(float value) -> float {
|
||||
; TODO ftan.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.tan.value}
|
||||
ftan.f fr0,fr0
|
||||
@ -65,7 +60,6 @@ sub tan(float value) -> float {
|
||||
}
|
||||
|
||||
sub atan(float value) -> float {
|
||||
; TODO fatan.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.atan.value}
|
||||
fatan.f fr0,fr0
|
||||
@ -74,7 +68,6 @@ sub atan(float value) -> float {
|
||||
}
|
||||
|
||||
sub ln(float value) -> float {
|
||||
; TODO fln.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.ln.value}
|
||||
fln.f fr0,fr0
|
||||
@ -83,16 +76,14 @@ sub ln(float value) -> float {
|
||||
}
|
||||
|
||||
sub log2(float value) -> float {
|
||||
; TODO flog2.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.log2.value}
|
||||
flog2.f fr0,fr0
|
||||
flog.f fr0,fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub sqrt(float value) -> float {
|
||||
; TODO fsqrt.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.sqrt.value}
|
||||
fsqrt.f fr0,fr0
|
||||
@ -111,7 +102,6 @@ sub deg(float angle) -> float {
|
||||
}
|
||||
|
||||
sub round(float value) -> float {
|
||||
; TODO fround.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.round.value}
|
||||
fround.f fr0,fr0
|
||||
@ -120,7 +110,6 @@ sub round(float value) -> float {
|
||||
}
|
||||
|
||||
sub floor(float value) -> float {
|
||||
; TODO ffloor.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.floor.value}
|
||||
ffloor.f fr0,fr0
|
||||
@ -130,7 +119,6 @@ sub floor(float value) -> float {
|
||||
|
||||
sub ceil(float value) -> float {
|
||||
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
||||
; TODO fceil.f instruction
|
||||
%asm {{
|
||||
loadm.f fr0,{floats.ceil.value}
|
||||
fceil.f fr0,fr0
|
||||
@ -139,9 +127,8 @@ sub ceil(float value) -> float {
|
||||
}
|
||||
|
||||
sub rndf() -> float {
|
||||
; TODO frnd.f instruction
|
||||
%asm {{
|
||||
frnd.f fr0
|
||||
rnd.f fr0
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
@ -3,8 +3,12 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- vm: fix fp reg out of bounds
|
||||
- vm: implement missing floating point functions
|
||||
- vm: fix if @(string)=='$' string++ not working on ea31
|
||||
- vm: fix conv hex2uword and bin2uword
|
||||
- vm: implement float div, minus, plus
|
||||
- vm: implement float type casts to integer types
|
||||
- vm: implement float any, all, reverse, sort
|
||||
- vm: fix test fp calc result being 0
|
||||
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
|
||||
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
|
||||
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
|
||||
|
@ -8,15 +8,61 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
float fl = 500.0
|
||||
txt.print("rad 180 = ")
|
||||
floats.print_f(floats.rad(180.0))
|
||||
txt.print("rad 360 = ")
|
||||
floats.print_f(floats.rad(360.0))
|
||||
txt.print("deg 2 = ")
|
||||
floats.print_f(floats.deg(2.0))
|
||||
txt.print("deg pi = ")
|
||||
floats.print_f(floats.deg(floats.PI))
|
||||
|
||||
ubyte ub = conv.str2ubyte("234")
|
||||
txt.print_ub(ub)
|
||||
txt.nl()
|
||||
byte sb = conv.str2byte("-123")
|
||||
txt.print_b(sb)
|
||||
txt.nl()
|
||||
uword uw = conv.str2uword("54321")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
word sw = conv.str2word("-12345")
|
||||
txt.print_w(sw)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
; TODO fix hex2uword and bin2uword
|
||||
uw = conv.hex2uword("0")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("1")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("a")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("0")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("1")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
uw = conv.hex2uword("$ea31")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.hex2uword("ea31")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("%100000111011101")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
uw = conv.bin2uword("100000111011101")
|
||||
txt.print_uw(uw)
|
||||
txt.nl()
|
||||
|
||||
; float fl = 500.0
|
||||
; txt.print("rad 180 = ")
|
||||
; floats.print_f(floats.rad(180.0))
|
||||
; txt.print("rad 360 = ")
|
||||
; floats.print_f(floats.rad(360.0))
|
||||
; txt.print("deg 2 = ")
|
||||
; floats.print_f(floats.deg(2.0))
|
||||
; txt.print("deg pi = ")
|
||||
; floats.print_f(floats.deg(floats.PI))
|
||||
sys.exit(42)
|
||||
; floats.print_f(-42.42)
|
||||
; float f1 = 1.2345
|
||||
@ -58,21 +104,21 @@ main {
|
||||
; "deg", "round", "floor", "ceil", "rndf"
|
||||
|
||||
; a "pixelshader":
|
||||
sys.gfx_enable(0) ; enable lo res screen
|
||||
ubyte shifter
|
||||
|
||||
repeat {
|
||||
uword xx
|
||||
uword yy = 0
|
||||
repeat 240 {
|
||||
xx = 0
|
||||
repeat 320 {
|
||||
sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte)
|
||||
xx++
|
||||
}
|
||||
yy++
|
||||
}
|
||||
shifter+=4
|
||||
}
|
||||
; sys.gfx_enable(0) ; enable lo res screen
|
||||
; ubyte shifter
|
||||
;
|
||||
; repeat {
|
||||
; uword xx
|
||||
; uword yy = 0
|
||||
; repeat 240 {
|
||||
; xx = 0
|
||||
; repeat 320 {
|
||||
; sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte)
|
||||
; xx++
|
||||
; }
|
||||
; yy++
|
||||
; }
|
||||
; shifter+=4
|
||||
; }
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ a few fp conversion instructions to
|
||||
*only* LOAD AND STORE instructions have a possible memory operand, all other instructions use only registers or immediate value.
|
||||
|
||||
|
||||
TODO all floating point arithmethic functions as fp-instructions.
|
||||
|
||||
LOAD/STORE
|
||||
----------
|
||||
All have type b or w or f.
|
||||
@ -130,8 +128,8 @@ rol reg1 - rotate reg1 left by 1bits, not us
|
||||
roxl reg1 - rotate reg1 left by 1bits, using carry, + set Carry to shifted bit
|
||||
|
||||
|
||||
FLOATING POINT CONVERSIONS
|
||||
--------------------------
|
||||
FLOATING POINT CONVERSIONS AND FUNCTIONS
|
||||
----------------------------------------
|
||||
ffromub fpreg1, reg1 - fpreg1 = reg1 from usigned byte
|
||||
ffromsb fpreg1, reg1 - fpreg1 = reg1 from signed byte
|
||||
ffromuw fpreg1, reg1 - fpreg1 = reg1 from unsigned word
|
||||
@ -140,6 +138,8 @@ ftoub reg1, fpreg1 - reg1 = fpreg1 as unsigned byte
|
||||
ftosb reg1, fpreg1 - reg1 = fpreg1 as signed byte
|
||||
ftouw reg1, fpreg1 - reg1 = fpreg1 as unsigned word
|
||||
ftosw reg1, fpreg1 - reg1 = fpreg1 as signed word
|
||||
fpow fpreg1, fpreg2, fpreg3 - fpreg1 = fpreg2 to the power of fpreg3
|
||||
fabs fpreg1, fpreg2 - fpreg1 = abs(fpreg2)
|
||||
|
||||
|
||||
MISC
|
||||
@ -248,6 +248,18 @@ enum class Opcode {
|
||||
FTOSB,
|
||||
FTOUW,
|
||||
FTOSW,
|
||||
FPOW,
|
||||
FABS,
|
||||
FSIN,
|
||||
FCOS,
|
||||
FTAN,
|
||||
FATAN,
|
||||
FLN,
|
||||
FLOG,
|
||||
FSQRT,
|
||||
FROUND,
|
||||
FFLOOR,
|
||||
FCEIL,
|
||||
|
||||
CLC,
|
||||
SEC,
|
||||
@ -512,6 +524,18 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.FTOSB to InstructionFormat.from("F,r1,fr1"),
|
||||
Opcode.FTOUW to InstructionFormat.from("F,r1,fr1"),
|
||||
Opcode.FTOSW to InstructionFormat.from("F,r1,fr1"),
|
||||
Opcode.FPOW to InstructionFormat.from("F,fr1,fr2,fr3"),
|
||||
Opcode.FABS to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FSIN to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FCOS to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FTAN to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FATAN to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FLN to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FLOG to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FSQRT to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FROUND to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FFLOOR to InstructionFormat.from("F,fr1,fr2"),
|
||||
Opcode.FCEIL to InstructionFormat.from("F,fr1,fr2"),
|
||||
|
||||
Opcode.MSIG to InstructionFormat.from("BW,r1,r2"),
|
||||
Opcode.PUSH to InstructionFormat.from("BW,r1"),
|
||||
|
@ -16,8 +16,8 @@ SYSCALLS:
|
||||
8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
||||
9 = gfx_clear ; clear graphics window with shade in r0.b
|
||||
10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
||||
11 = <unused 1>
|
||||
12 = <unused 2>
|
||||
11 = decimal string to word (unsigned)
|
||||
12 = decimal string to word (signed)
|
||||
13 = wait ; wait certain amount of jiffies (1/60 sec)
|
||||
14 = waitvsync ; wait on vsync
|
||||
15 = sort_ubyte array
|
||||
@ -55,8 +55,8 @@ enum class Syscall {
|
||||
GFX_ENABLE,
|
||||
GFX_CLEAR,
|
||||
GFX_PLOT,
|
||||
UNUSED_1,
|
||||
UNUSED_2,
|
||||
STR_TO_UWORD,
|
||||
STR_TO_WORD,
|
||||
WAIT,
|
||||
WAITVSYNC,
|
||||
SORT_UBYTE,
|
||||
@ -301,6 +301,16 @@ object SysCalls {
|
||||
val value = vm.registers.getFloat(0)
|
||||
print(value)
|
||||
}
|
||||
Syscall.STR_TO_UWORD -> {
|
||||
val stringAddr = vm.registers.getUW(0)
|
||||
val string = vm.memory.getString(stringAddr.toInt())
|
||||
vm.registers.setUW(0, string.toUShort())
|
||||
}
|
||||
Syscall.STR_TO_WORD -> {
|
||||
val stringAddr = vm.registers.getUW(0)
|
||||
val string = vm.memory.getString(stringAddr.toInt())
|
||||
vm.registers.setSW(0, string.toShort())
|
||||
}
|
||||
else -> TODO("syscall ${call.name}")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user