mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
min/max give proper error for string args
als implmented more vm builtin functions/syscalls
This commit is contained in:
parent
bf7f4bba7b
commit
349e5a15e9
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@ -22,4 +22,9 @@
|
|||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="SwUserDefinedSpecifications">
|
||||||
|
<option name="specTypeByUrl">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
@ -2,6 +2,7 @@ package prog8.codegen.virtual
|
|||||||
|
|
||||||
import prog8.code.StStaticVariable
|
import prog8.code.StStaticVariable
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
|
import prog8.code.core.ArrayToElementTypes
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.AssemblyError
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.vm.Opcode
|
import prog8.vm.Opcode
|
||||||
@ -13,10 +14,10 @@ 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) {
|
||||||
"max" -> funcMax(call, resultRegister)
|
"max" -> funcMax(call, resultRegister)
|
||||||
"min" -> TODO()
|
"min" -> funcMin(call, resultRegister)
|
||||||
"sum" -> TODO()
|
"sum" -> funcSum(call, resultRegister)
|
||||||
"any" -> TODO()
|
"any" -> funcAny(call, resultRegister)
|
||||||
"all" -> TODO()
|
"all" -> funcAll(call, resultRegister)
|
||||||
"abs" -> TODO("abs once we can compare plus minus")
|
"abs" -> TODO("abs once we can compare plus minus")
|
||||||
"cmp" -> TODO("cmp() can't be used on vm because no processor status bits implemented")
|
"cmp" -> TODO("cmp() can't be used on vm because no processor status bits implemented")
|
||||||
"sgn" -> funcSgn(call, resultRegister)
|
"sgn" -> funcSgn(call, resultRegister)
|
||||||
@ -70,22 +71,113 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMax(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcSum(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
|
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
|
||||||
|
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
|
||||||
|
val syscall =
|
||||||
|
when(array.dt) {
|
||||||
|
DataType.ARRAY_UB,
|
||||||
|
DataType.ARRAY_B -> Syscall.SUM_BYTE
|
||||||
|
DataType.ARRAY_UW,
|
||||||
|
DataType.ARRAY_W -> Syscall.SUM_WORD
|
||||||
|
DataType.ARRAY_F -> TODO("float sum")
|
||||||
|
else -> throw IllegalArgumentException("weird type")
|
||||||
|
}
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
val arrayName = (call.args.single() as PtIdentifier).targetName
|
code += exprGen.translateExpression(call.args[0], 0)
|
||||||
val array = codeGen.symbolTable.flat.getValue(arrayName) as StStaticVariable
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
|
||||||
when (array.dt) {
|
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
|
||||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
if(resultRegister!=0)
|
||||||
TODO("max word array")
|
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
|
||||||
}
|
return code
|
||||||
DataType.STR -> {
|
}
|
||||||
TODO("max string")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
TODO("max byte array")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun funcAny(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
|
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
|
||||||
|
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
|
||||||
|
val syscall =
|
||||||
|
when(array.dt) {
|
||||||
|
DataType.ARRAY_UB,
|
||||||
|
DataType.ARRAY_B -> Syscall.ANY_BYTE
|
||||||
|
DataType.ARRAY_UW,
|
||||||
|
DataType.ARRAY_W -> Syscall.ANY_WORD
|
||||||
|
DataType.ARRAY_F -> TODO("float any")
|
||||||
|
else -> throw IllegalArgumentException("weird type")
|
||||||
|
}
|
||||||
|
val code = VmCodeChunk()
|
||||||
|
code += exprGen.translateExpression(call.args[0], 0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
|
||||||
|
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
|
||||||
|
if(resultRegister!=0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcAll(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
|
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
|
||||||
|
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
|
||||||
|
val syscall =
|
||||||
|
when(array.dt) {
|
||||||
|
DataType.ARRAY_UB,
|
||||||
|
DataType.ARRAY_B -> Syscall.ALL_BYTE
|
||||||
|
DataType.ARRAY_UW,
|
||||||
|
DataType.ARRAY_W -> Syscall.ALL_WORD
|
||||||
|
DataType.ARRAY_F -> TODO("float all")
|
||||||
|
else -> throw IllegalArgumentException("weird type")
|
||||||
|
}
|
||||||
|
val code = VmCodeChunk()
|
||||||
|
code += exprGen.translateExpression(call.args[0], 0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
|
||||||
|
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
|
||||||
|
if(resultRegister!=0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcMax(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
|
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
|
||||||
|
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
|
||||||
|
val syscall =
|
||||||
|
when(array.dt) {
|
||||||
|
DataType.ARRAY_UB -> Syscall.MAX_UBYTE
|
||||||
|
DataType.ARRAY_B -> Syscall.MAX_BYTE
|
||||||
|
DataType.ARRAY_UW -> Syscall.MAX_UWORD
|
||||||
|
DataType.ARRAY_W -> Syscall.MAX_WORD
|
||||||
|
DataType.ARRAY_F -> TODO("float max")
|
||||||
|
else -> throw IllegalArgumentException("weird type")
|
||||||
|
}
|
||||||
|
val code = VmCodeChunk()
|
||||||
|
code += exprGen.translateExpression(call.args[0], 0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
|
||||||
|
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
|
||||||
|
if(resultRegister!=0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcMin(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
|
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
|
||||||
|
val elementDt: VmDataType = codeGen.vmType(ArrayToElementTypes.getValue(array.dt))
|
||||||
|
val syscall =
|
||||||
|
when(array.dt) {
|
||||||
|
DataType.ARRAY_UB -> Syscall.MIN_UBYTE
|
||||||
|
DataType.ARRAY_B -> Syscall.MIN_BYTE
|
||||||
|
DataType.ARRAY_UW -> Syscall.MIN_UWORD
|
||||||
|
DataType.ARRAY_W -> Syscall.MIN_WORD
|
||||||
|
DataType.ARRAY_F -> TODO("float min")
|
||||||
|
else -> throw IllegalArgumentException("weird type")
|
||||||
|
}
|
||||||
|
val code = VmCodeChunk()
|
||||||
|
code += exprGen.translateExpression(call.args[0], 0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
|
||||||
|
code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal)
|
||||||
|
if(resultRegister!=0)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADR, elementDt, reg1=resultRegister, reg2=0)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +243,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
when(array.dt) {
|
when(array.dt) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> Syscall.REVERSE_BYTES
|
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> Syscall.REVERSE_BYTES
|
||||||
DataType.ARRAY_UW, DataType.ARRAY_W -> Syscall.REVERSE_WORDS
|
DataType.ARRAY_UW, DataType.ARRAY_W -> Syscall.REVERSE_WORDS
|
||||||
DataType.FLOAT -> TODO("reverse floats")
|
DataType.ARRAY_F -> TODO("float reverse")
|
||||||
else -> throw IllegalArgumentException("weird type to reverse")
|
else -> throw IllegalArgumentException("weird type to reverse")
|
||||||
}
|
}
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
@ -170,7 +262,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
DataType.ARRAY_B -> Syscall.SORT_BYTE
|
DataType.ARRAY_B -> Syscall.SORT_BYTE
|
||||||
DataType.ARRAY_UW -> Syscall.SORT_UWORD
|
DataType.ARRAY_UW -> Syscall.SORT_UWORD
|
||||||
DataType.ARRAY_W -> Syscall.SORT_WORD
|
DataType.ARRAY_W -> Syscall.SORT_WORD
|
||||||
DataType.FLOAT -> TODO("float sort")
|
DataType.ARRAY_F -> TODO("float sort")
|
||||||
DataType.STR -> Syscall.SORT_UBYTE
|
DataType.STR -> Syscall.SORT_UBYTE
|
||||||
else -> throw IllegalArgumentException("weird type to sort")
|
else -> throw IllegalArgumentException("weird type to sort")
|
||||||
}
|
}
|
||||||
|
@ -1069,11 +1069,15 @@ internal class AstChecker(private val program: Program,
|
|||||||
errors.err("swap requires args of numerical type", position)
|
errors.err("swap requires args of numerical type", position)
|
||||||
}
|
}
|
||||||
else if(target.name=="all" || target.name=="any") {
|
else if(target.name=="all" || target.name=="any") {
|
||||||
if((args[0] as? AddressOf)?.identifier?.targetVarDecl(program)?.datatype == DataType.STR) {
|
if((args[0] as? AddressOf)?.identifier?.targetVarDecl(program)?.datatype == DataType.STR
|
||||||
|
|| args[0].inferType(program).getOr(DataType.STR) == DataType.STR) {
|
||||||
errors.err("any/all on a string is useless (is always true unless the string is empty)", position)
|
errors.err("any/all on a string is useless (is always true unless the string is empty)", position)
|
||||||
}
|
}
|
||||||
if(args[0].inferType(program).getOr(DataType.STR) == DataType.STR) {
|
}
|
||||||
errors.err("any/all on a string is useless (is always true unless the string is empty)", position)
|
else if(target.name=="min" || target.name=="max") {
|
||||||
|
if((args[0] as? AddressOf)?.identifier?.targetVarDecl(program)?.datatype == DataType.STR
|
||||||
|
|| args[0].inferType(program).getOr(DataType.STR) == DataType.STR) {
|
||||||
|
errors.err("min/max operate on arrays, not on strings", position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(target is Subroutine) {
|
} else if(target is Subroutine) {
|
||||||
|
@ -3,9 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- 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
|
||||||
@ -14,6 +12,7 @@ For next release
|
|||||||
If we can do that why not perhaps also able to inline multi-line subroutines? Why would it be limited to just 1 line? Maybe to protect against code size bloat.
|
If we can do that why not perhaps also able to inline multi-line subroutines? Why would it be limited to just 1 line? Maybe to protect against code size bloat.
|
||||||
Inlined subroutines cannot contain further nested subroutines!
|
Inlined subroutines cannot contain further nested subroutines!
|
||||||
Once this works, look for library subroutines that should be inlined.
|
Once this works, look for library subroutines that should be inlined.
|
||||||
|
- vm: add support for status bits, status-branch instructions, and cmp() and abs() functions.
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@ main {
|
|||||||
|
|
||||||
word[] values = [1111, -222, -9999, 88, 20222, 0, 0, 1111]
|
word[] values = [1111, -222, -9999, 88, 20222, 0, 0, 1111]
|
||||||
word[] values2 = [0,0,0,0,0,1,0,0,0]
|
word[] values2 = [0,0,0,0,0,1,0,0,0]
|
||||||
txt.print_w(max("abcde"))
|
|
||||||
txt.nl()
|
|
||||||
txt.print_w(max(values))
|
txt.print_w(max(values))
|
||||||
txt.nl()
|
txt.nl()
|
||||||
txt.print_w(min(values))
|
txt.print_w(min(values))
|
||||||
|
@ -25,8 +25,22 @@ SYSCALLS:
|
|||||||
16 = sort_byte array
|
16 = sort_byte array
|
||||||
17 = sort_uword array
|
17 = sort_uword array
|
||||||
18 = sort_word array
|
18 = sort_word array
|
||||||
19 = reverse_bytes array
|
19 = max_ubyte array
|
||||||
20 = reverse_words array
|
20 = max_byte array
|
||||||
|
21 = max_uword array
|
||||||
|
22 = max_word array
|
||||||
|
23 = min_ubyte array
|
||||||
|
24 = min_byte array
|
||||||
|
25 = min_uword array
|
||||||
|
26 = min_word array
|
||||||
|
27 = sum_byte array
|
||||||
|
28 = sum_word array
|
||||||
|
29 = any_byte array
|
||||||
|
30 = any_word array
|
||||||
|
31 = all_byte array
|
||||||
|
32 = all_word array
|
||||||
|
33 = reverse_bytes array
|
||||||
|
34 = reverse_words array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum class Syscall {
|
enum class Syscall {
|
||||||
@ -49,8 +63,22 @@ enum class Syscall {
|
|||||||
SORT_BYTE,
|
SORT_BYTE,
|
||||||
SORT_UWORD,
|
SORT_UWORD,
|
||||||
SORT_WORD,
|
SORT_WORD,
|
||||||
REVERSE_BYTES, // TODO not as syscall
|
MAX_UBYTE,
|
||||||
REVERSE_WORDS // TODO not as syscall
|
MAX_BYTE,
|
||||||
|
MAX_UWORD,
|
||||||
|
MAX_WORD,
|
||||||
|
MIN_UBYTE,
|
||||||
|
MIN_BYTE,
|
||||||
|
MIN_UWORD,
|
||||||
|
MIN_WORD,
|
||||||
|
SUM_BYTE,
|
||||||
|
SUM_WORD,
|
||||||
|
ANY_BYTE,
|
||||||
|
ANY_WORD,
|
||||||
|
ALL_BYTE,
|
||||||
|
ALL_WORD,
|
||||||
|
REVERSE_BYTES,
|
||||||
|
REVERSE_WORDS
|
||||||
}
|
}
|
||||||
|
|
||||||
object SysCalls {
|
object SysCalls {
|
||||||
@ -168,6 +196,112 @@ object SysCalls {
|
|||||||
vm.memory.setUW(address+index*2, value)
|
vm.memory.setUW(address+index*2, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Syscall.MAX_UBYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUB(it) }.maxOf { it }
|
||||||
|
vm.registers.setUB(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MAX_BYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getSB(it) }.maxOf { it }
|
||||||
|
vm.registers.setSB(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MAX_UWORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUW(it) }.maxOf { it }
|
||||||
|
vm.registers.setUW(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MAX_WORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getSW(it) }.maxOf { it }
|
||||||
|
vm.registers.setSW(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MIN_UBYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUB(it) }.minOf { it }
|
||||||
|
vm.registers.setUB(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MIN_BYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getSB(it) }.minOf { it }
|
||||||
|
vm.registers.setSB(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MIN_UWORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUW(it) }.minOf { it }
|
||||||
|
vm.registers.setUW(0, value)
|
||||||
|
}
|
||||||
|
Syscall.MIN_WORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getSW(it) }.minOf { it }
|
||||||
|
vm.registers.setSW(0, value)
|
||||||
|
}
|
||||||
|
Syscall.SUM_BYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUB(it) }.sum()
|
||||||
|
vm.registers.setUB(0, value.toUByte())
|
||||||
|
}
|
||||||
|
Syscall.SUM_WORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
val value = addresses.map { vm.memory.getUW(it) }.sum()
|
||||||
|
vm.registers.setUW(0, value.toUShort())
|
||||||
|
}
|
||||||
|
Syscall.ANY_BYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
if(addresses.any { vm.memory.getUB(it).toInt()!=0 })
|
||||||
|
vm.registers.setUB(0, 1u)
|
||||||
|
else
|
||||||
|
vm.registers.setUB(0, 0u)
|
||||||
|
}
|
||||||
|
Syscall.ANY_WORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
if(addresses.any { vm.memory.getUW(it).toInt()!=0 })
|
||||||
|
vm.registers.setUB(0, 1u)
|
||||||
|
else
|
||||||
|
vm.registers.setUB(0, 0u)
|
||||||
|
}
|
||||||
|
Syscall.ALL_BYTE -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
if(addresses.all { vm.memory.getUB(it).toInt()!=0 })
|
||||||
|
vm.registers.setUB(0, 1u)
|
||||||
|
else
|
||||||
|
vm.registers.setUB(0, 0u)
|
||||||
|
}
|
||||||
|
Syscall.ALL_WORD -> {
|
||||||
|
val address = vm.registers.getUW(0).toInt()
|
||||||
|
val length = vm.registers.getUB(1).toInt()
|
||||||
|
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2)
|
||||||
|
if(addresses.all { vm.memory.getUW(it).toInt()!=0 })
|
||||||
|
vm.registers.setUB(0, 1u)
|
||||||
|
else
|
||||||
|
vm.registers.setUB(0, 0u)
|
||||||
|
}
|
||||||
else -> TODO("syscall ${call.name}")
|
else -> TODO("syscall ${call.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user