mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
IR: support for multi-returnvalue function calls (asmsubs)
note: the VM can't execute these though as it has no CPU hardware registers
This commit is contained in:
parent
03e486c082
commit
2e37f5dee3
@ -23,13 +23,16 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
if(funcCall.multipleResultFpRegs.isNotEmpty())
|
if(funcCall.multipleResultFpRegs.isNotEmpty())
|
||||||
TODO("deal with (multiple?) FP return registers")
|
TODO("deal with (multiple?) FP return registers")
|
||||||
|
|
||||||
TODO("add to result multi return regs from expression")
|
// because we can only handle integer results right now we can just zip() it all up
|
||||||
// addToResult(result, funcCall, funcCall.resultReg, funcCall.resultFpReg)
|
addToResult(result, funcCall, funcCall.resultReg, funcCall.resultFpReg)
|
||||||
// sub.returns.zip(assignment.children).forEach { (returns, target) ->
|
sub.returns.zip(assignment.children).zip(funcCall.multipleResultRegs).forEach {
|
||||||
// result += assignCpuRegister(returns, funcCall, target as PtAssignTarget)
|
val regNumber = it.second
|
||||||
// }
|
val returns = it.first.first
|
||||||
// result.filterIsInstance<IRCodeChunk>().firstOrNull()?.appendSrcPosition(assignment.position)
|
val target = it.first.second as PtAssignTarget
|
||||||
// return result
|
result += assignCpuRegister(returns, regNumber, target)
|
||||||
|
}
|
||||||
|
result.filterIsInstance<IRCodeChunk>().firstOrNull()?.appendSrcPosition(assignment.position)
|
||||||
|
return result
|
||||||
} else {
|
} else {
|
||||||
if (assignment.target.children.single() is PtIrRegister)
|
if (assignment.target.children.single() is PtIrRegister)
|
||||||
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister")
|
||||||
@ -40,46 +43,31 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignCpuRegister(returns: StRomSubParameter, target: PtAssignTarget): IRCodeChunk {
|
private fun assignCpuRegister(returns: StRomSubParameter, regNum: Int, target: PtAssignTarget): IRCodeChunks {
|
||||||
val targetIdentifier = target.identifier
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val chunk = IRCodeChunk(null, null)
|
val loadCpuRegInstr = when(returns.register.registerOrPair) {
|
||||||
if(targetIdentifier!=null) {
|
RegisterOrPair.A -> IRInstruction(Opcode.LOADHA, IRDataType.BYTE, reg1=regNum)
|
||||||
TODO()
|
RegisterOrPair.X -> IRInstruction(Opcode.LOADHX, IRDataType.BYTE, reg1=regNum)
|
||||||
val regNum = 4242 // TODO??
|
RegisterOrPair.Y -> IRInstruction(Opcode.LOADHY, IRDataType.BYTE, reg1=regNum)
|
||||||
when(returns.register.registerOrPair) {
|
RegisterOrPair.AX -> IRInstruction(Opcode.LOADHAX, IRDataType.WORD, reg1=regNum)
|
||||||
RegisterOrPair.A -> chunk += IRInstruction(Opcode.LOADHA, IRDataType.BYTE, reg1=regNum)
|
RegisterOrPair.AY -> IRInstruction(Opcode.LOADHAY, IRDataType.WORD, reg1=regNum)
|
||||||
RegisterOrPair.X -> chunk += IRInstruction(Opcode.LOADHX, IRDataType.BYTE, reg1=regNum)
|
RegisterOrPair.XY -> IRInstruction(Opcode.LOADHXY, IRDataType.WORD, reg1=regNum)
|
||||||
RegisterOrPair.Y -> chunk += IRInstruction(Opcode.LOADHY, IRDataType.BYTE, reg1=regNum)
|
null -> {
|
||||||
RegisterOrPair.AX -> chunk += IRInstruction(Opcode.LOADHAX, IRDataType.WORD, reg1=regNum)
|
when(returns.register.statusflag) {
|
||||||
RegisterOrPair.AY -> chunk += IRInstruction(Opcode.LOADHAY, IRDataType.WORD, reg1=regNum)
|
Statusflag.Pc -> IRInstruction(Opcode.LOADHA, IRDataType.BYTE, reg1=regNum)
|
||||||
RegisterOrPair.XY -> chunk += IRInstruction(Opcode.LOADHXY, IRDataType.WORD, reg1=regNum)
|
else -> throw AssemblyError("weird statusflag as returnvalue")
|
||||||
null -> {
|
|
||||||
when(returns.register.statusflag) {
|
|
||||||
Statusflag.Pc -> chunk += IRInstruction(Opcode.LOADHA, IRDataType.BYTE, reg1=regNum)
|
|
||||||
else -> throw AssemblyError("weird statusflag as returnvalue")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("cannot load register")
|
|
||||||
}
|
}
|
||||||
chunk += IRInstruction(Opcode.STOREM, irType(target.type), reg1=regNum, labelSymbol = targetIdentifier.name)
|
else -> throw AssemblyError("cannot load register")
|
||||||
return chunk
|
|
||||||
}
|
}
|
||||||
val targetMem = target.memory
|
addInstr(result, loadCpuRegInstr, null)
|
||||||
if(targetMem!=null) {
|
|
||||||
TODO("assign $returns to $targetMem")
|
// build an assignment to store the value in the actual target.
|
||||||
return chunk
|
val assign = PtAssignment(target.position)
|
||||||
}
|
assign.add(target)
|
||||||
val targetArray = target.array
|
assign.add(PtIrRegister(regNum, target.type, target.position))
|
||||||
if(targetArray!=null) {
|
result += translate(assign)
|
||||||
TODO("assign $returns to $targetArray")
|
return result
|
||||||
return chunk
|
|
||||||
}
|
|
||||||
throw AssemblyError("weird target")
|
|
||||||
// val singleAssign = PtAssignment(target.position)
|
|
||||||
// singleAssign.children.add(target)
|
|
||||||
// TODO("use the new IR instructions to store machine regs STOREHxx ${target.position}")
|
|
||||||
// singleAssign.children.add(PtMachineRegister(4242, returns.type, assignment.position))
|
|
||||||
// result += translateRegularAssign(singleAssign)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translate(augAssign: PtAugmentedAssign): IRCodeChunks {
|
internal fun translate(augAssign: PtAugmentedAssign): IRCodeChunks {
|
||||||
|
@ -466,7 +466,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
argRegisters.add(FunctionCallArgs.ArgumentSpec(parameter.name, null, FunctionCallArgs.RegSpec(paramDt, tr.resultReg, null)))
|
argRegisters.add(FunctionCallArgs.ArgumentSpec(parameter.name, null, FunctionCallArgs.RegSpec(paramDt, tr.resultReg, null)))
|
||||||
result += tr.chunks
|
result += tr.chunks
|
||||||
}
|
}
|
||||||
// return value
|
// return value (always singular for normal Subs)
|
||||||
val returnRegSpec = if(fcall.void) null else {
|
val returnRegSpec = if(fcall.void) null else {
|
||||||
val returnIrType = irType(callTarget.returnType!!)
|
val returnIrType = irType(callTarget.returnType!!)
|
||||||
if(returnIrType==IRDataType.FLOAT)
|
if(returnIrType==IRDataType.FLOAT)
|
||||||
@ -475,7 +475,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFree(), null)
|
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFree(), null)
|
||||||
}
|
}
|
||||||
// create the call
|
// create the call
|
||||||
addInstr(result, IRInstruction(Opcode.CALL, labelSymbol = fcall.name, fcallArgs = FunctionCallArgs(argRegisters, returnRegSpec)), null)
|
addInstr(result, IRInstruction(Opcode.CALL, labelSymbol = fcall.name,
|
||||||
|
fcallArgs = FunctionCallArgs(argRegisters, if(returnRegSpec==null) emptyList() else listOf(returnRegSpec))), null)
|
||||||
return if(fcall.void)
|
return if(fcall.void)
|
||||||
ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||||
else if(fcall.type==DataType.FLOAT)
|
else if(fcall.type==DataType.FLOAT)
|
||||||
@ -516,34 +517,37 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(callTarget.returns.size>1)
|
if(callTarget.returns.size>1)
|
||||||
return callWithMultipleReturnValues()
|
return callRomSubWithMultipleReturnValues(callTarget, fcall, argRegisters, result)
|
||||||
|
|
||||||
// return a single value
|
// return a single value (or nothing)
|
||||||
var statusFlagResult: Statusflag? = null
|
|
||||||
val returnRegSpec = if(fcall.void) null else {
|
val returnRegSpec = if(fcall.void) null else {
|
||||||
if(callTarget.returns.isEmpty())
|
if(callTarget.returns.isEmpty())
|
||||||
null
|
null
|
||||||
val returns = callTarget.returns[0]
|
|
||||||
val returnIrType = irType(returns.type)
|
|
||||||
if(returnIrType==IRDataType.FLOAT)
|
|
||||||
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), returns.register)
|
|
||||||
else {
|
else {
|
||||||
val returnRegister = codeGen.registers.nextFree()
|
val returns = callTarget.returns[0]
|
||||||
FunctionCallArgs.RegSpec(returnIrType, returnRegister, returns.register)
|
val returnIrType = irType(returns.type)
|
||||||
|
if (returnIrType == IRDataType.FLOAT)
|
||||||
|
FunctionCallArgs.RegSpec(returnIrType, codeGen.registers.nextFreeFloat(), returns.register)
|
||||||
|
else {
|
||||||
|
val returnRegister = codeGen.registers.nextFree()
|
||||||
|
FunctionCallArgs.RegSpec(returnIrType, returnRegister, returns.register)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create the call
|
// create the call
|
||||||
|
val returnRegs = if(returnRegSpec==null) emptyList() else listOf(returnRegSpec)
|
||||||
val call =
|
val call =
|
||||||
if(callTarget.address==null)
|
if(callTarget.address==null)
|
||||||
IRInstruction(Opcode.CALL, labelSymbol = fcall.name, fcallArgs = FunctionCallArgs(argRegisters, returnRegSpec))
|
IRInstruction(Opcode.CALL, labelSymbol = fcall.name, fcallArgs = FunctionCallArgs(argRegisters, returnRegs))
|
||||||
else
|
else
|
||||||
IRInstruction(Opcode.CALL, address = callTarget.address!!.toInt(), fcallArgs = FunctionCallArgs(argRegisters, returnRegSpec))
|
IRInstruction(Opcode.CALL, address = callTarget.address!!.toInt(), fcallArgs = FunctionCallArgs(argRegisters, returnRegs))
|
||||||
addInstr(result, call, null)
|
addInstr(result, call, null)
|
||||||
var finalReturnRegister = returnRegSpec?.registerNum ?: -1
|
var finalReturnRegister = returnRegSpec?.registerNum ?: -1
|
||||||
|
|
||||||
if(fcall.parent is PtAssignment || fcall.parent is PtTypeCast) {
|
if(fcall.parent is PtAssignment || fcall.parent is PtTypeCast) {
|
||||||
// look if the status flag bit should actually be returned as a 0/1 byte value in a result register (so it can be assigned)
|
// look if the status flag bit should actually be returned as a 0/1 byte value in a result register (so it can be assigned)
|
||||||
if(statusFlagResult!=null && returnRegSpec!=null) {
|
val statusFlagResult = returnRegSpec?.cpuRegister?.statusflag
|
||||||
|
if(statusFlagResult!=null) {
|
||||||
// assign status flag bit to the return value register
|
// assign status flag bit to the return value register
|
||||||
finalReturnRegister = returnRegSpec.registerNum
|
finalReturnRegister = returnRegSpec.registerNum
|
||||||
if(finalReturnRegister<0)
|
if(finalReturnRegister<0)
|
||||||
@ -586,8 +590,27 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun callWithMultipleReturnValues(): ExpressionCodeResult {
|
private fun callRomSubWithMultipleReturnValues(
|
||||||
TODO("call with multiple return values")
|
callTarget: StRomSub,
|
||||||
|
fcall: PtFunctionCall,
|
||||||
|
argRegisters: MutableList<FunctionCallArgs.ArgumentSpec>,
|
||||||
|
result: MutableList<IRCodeChunkBase>
|
||||||
|
): ExpressionCodeResult {
|
||||||
|
// return multiple values
|
||||||
|
val returnRegisters = callTarget.returns.map {
|
||||||
|
val regnum = if(it.type==DataType.FLOAT) codeGen.registers.nextFreeFloat() else codeGen.registers.nextFree()
|
||||||
|
FunctionCallArgs.RegSpec(irType(it.type), regnum, it.register)
|
||||||
|
}
|
||||||
|
// create the call
|
||||||
|
val call =
|
||||||
|
if(callTarget.address==null)
|
||||||
|
IRInstruction(Opcode.CALL, labelSymbol = fcall.name, fcallArgs = FunctionCallArgs(argRegisters, returnRegisters))
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.CALL, address = callTarget.address!!.toInt(), fcallArgs = FunctionCallArgs(argRegisters, returnRegisters))
|
||||||
|
addInstr(result, call, null)
|
||||||
|
val resultRegs = returnRegisters.filter{it.dt!=IRDataType.FLOAT}.map{it.registerNum}
|
||||||
|
val resultFpRegs = returnRegisters.filter{it.dt==IRDataType.FLOAT}.map{it.registerNum}
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1, resultRegs, resultFpRegs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun operatorGreaterThan(
|
private fun operatorGreaterThan(
|
||||||
|
@ -1650,7 +1650,8 @@ class IRCodeGen(
|
|||||||
val args = params.map { (dt, reg)->
|
val args = params.map { (dt, reg)->
|
||||||
FunctionCallArgs.ArgumentSpec("", null, FunctionCallArgs.RegSpec(dt, reg, null))
|
FunctionCallArgs.ArgumentSpec("", null, FunctionCallArgs.RegSpec(dt, reg, null))
|
||||||
}
|
}
|
||||||
val returnSpec = if(returns==null) null else FunctionCallArgs.RegSpec(returns.first, returns.second, null)
|
// for now, syscalls have 0 or 1 return value
|
||||||
|
val returnSpec = if(returns==null) emptyList() else listOf(FunctionCallArgs.RegSpec(returns.first, returns.second, null))
|
||||||
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number, fcallArgs = FunctionCallArgs(args, returnSpec))
|
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number, fcallArgs = FunctionCallArgs(args, returnSpec))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
6502 codegen: make multi return value asmsub calls work.
|
||||||
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ val instructionFormats = mutableMapOf(
|
|||||||
|
|
||||||
class FunctionCallArgs(
|
class FunctionCallArgs(
|
||||||
var arguments: List<ArgumentSpec>,
|
var arguments: List<ArgumentSpec>,
|
||||||
val returns: RegSpec?
|
val returns: List<RegSpec>
|
||||||
) {
|
) {
|
||||||
class RegSpec(val dt: IRDataType, val registerNum: Int, val cpuRegister: RegisterOrStatusflag?)
|
class RegSpec(val dt: IRDataType, val registerNum: Int, val cpuRegister: RegisterOrStatusflag?)
|
||||||
class ArgumentSpec(val name: String, val address: Int?, val reg: RegSpec) {
|
class ArgumentSpec(val name: String, val address: Int?, val reg: RegSpec) {
|
||||||
@ -975,13 +975,13 @@ data class IRInstruction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(fcallArgs!=null) {
|
if(fcallArgs!=null) {
|
||||||
fcallArgs.returns?.let {
|
fcallArgs.returns.forEach {
|
||||||
if(it.dt==IRDataType.FLOAT)
|
if (it.dt == IRDataType.FLOAT)
|
||||||
writeFpRegsCounts[it.registerNum] = writeFpRegsCounts.getValue(it.registerNum)+1
|
writeFpRegsCounts[it.registerNum] = writeFpRegsCounts.getValue(it.registerNum) + 1
|
||||||
else {
|
else {
|
||||||
writeRegsCounts[it.registerNum] = writeRegsCounts.getValue(it.registerNum) + 1
|
writeRegsCounts[it.registerNum] = writeRegsCounts.getValue(it.registerNum) + 1
|
||||||
val types = regsTypes[it.registerNum]
|
val types = regsTypes[it.registerNum]
|
||||||
if(types==null) {
|
if (types == null) {
|
||||||
regsTypes[it.registerNum] = mutableSetOf(it.dt)
|
regsTypes[it.registerNum] = mutableSetOf(it.dt)
|
||||||
} else {
|
} else {
|
||||||
types += it.dt
|
types += it.dt
|
||||||
@ -1049,27 +1049,30 @@ data class IRInstruction(
|
|||||||
}
|
}
|
||||||
result.add(")")
|
result.add(")")
|
||||||
val returns = fcallArgs.returns
|
val returns = fcallArgs.returns
|
||||||
if(returns!=null) {
|
if(returns.isNotEmpty()) {
|
||||||
result.add(":")
|
result.add(":")
|
||||||
val cpuReg = if(returns.cpuRegister==null) "" else {
|
val resultParts = returns.map { returnspec ->
|
||||||
if(returns.cpuRegister.registerOrPair!=null)
|
val cpuReg = if (returnspec.cpuRegister == null) "" else {
|
||||||
returns.cpuRegister.registerOrPair.toString()
|
if (returnspec.cpuRegister.registerOrPair != null)
|
||||||
else
|
returnspec.cpuRegister.registerOrPair.toString()
|
||||||
returns.cpuRegister.statusflag.toString()
|
else
|
||||||
}
|
returnspec.cpuRegister.statusflag.toString()
|
||||||
if(cpuReg.isEmpty()) {
|
|
||||||
when (returns.dt) {
|
|
||||||
IRDataType.BYTE -> result.add("r${returns.registerNum}.b")
|
|
||||||
IRDataType.WORD -> result.add("r${returns.registerNum}.w")
|
|
||||||
IRDataType.FLOAT -> result.add("fr${returns.registerNum}.f")
|
|
||||||
}
|
}
|
||||||
} else {
|
if (cpuReg.isEmpty()) {
|
||||||
when(returns.dt) {
|
when (returnspec.dt) {
|
||||||
IRDataType.BYTE -> result.add("r${returns.registerNum}.b@" + cpuReg)
|
IRDataType.BYTE -> "r${returnspec.registerNum}.b"
|
||||||
IRDataType.WORD -> result.add("r${returns.registerNum}.w@" + cpuReg)
|
IRDataType.WORD -> "r${returnspec.registerNum}.w"
|
||||||
IRDataType.FLOAT -> result.add("r${returns.registerNum}.f@" + cpuReg)
|
IRDataType.FLOAT -> "fr${returnspec.registerNum}.f"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (returnspec.dt) {
|
||||||
|
IRDataType.BYTE -> "r${returnspec.registerNum}.b@" + cpuReg
|
||||||
|
IRDataType.WORD -> "r${returnspec.registerNum}.w@" + cpuReg
|
||||||
|
IRDataType.FLOAT -> "r${returnspec.registerNum}.f@" + cpuReg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result.add(resultParts.joinToString(","))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ private class ParsedCall(
|
|||||||
val target: String?,
|
val target: String?,
|
||||||
val address: Int?,
|
val address: Int?,
|
||||||
val args: List<FunctionCallArgs.ArgumentSpec>,
|
val args: List<FunctionCallArgs.ArgumentSpec>,
|
||||||
val returns: FunctionCallArgs.RegSpec?
|
val returns: List<FunctionCallArgs.RegSpec>
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun parseCall(rest: String): ParsedCall {
|
private fun parseCall(rest: String): ParsedCall {
|
||||||
@ -239,11 +239,15 @@ private fun parseCall(rest: String): ParsedCall {
|
|||||||
return FunctionCallArgs.RegSpec(type, num, cpuRegister)
|
return FunctionCallArgs.RegSpec(type, num, cpuRegister)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseReturnRegspec(reg: String): FunctionCallArgs.RegSpec {
|
fun parseReturnRegspec(regs: String?): List<FunctionCallArgs.RegSpec> {
|
||||||
return if(reg.startsWith('@')) {
|
if(regs==null)
|
||||||
FunctionCallArgs.RegSpec(IRDataType.BYTE, -1, parseRegisterOrStatusflag(reg.drop(1)))
|
return emptyList()
|
||||||
} else {
|
return regs.split(',').map { reg->
|
||||||
parseRegspec(reg)
|
if (reg.startsWith('@')) {
|
||||||
|
FunctionCallArgs.RegSpec(IRDataType.BYTE, -1, parseRegisterOrStatusflag(reg.drop(1)))
|
||||||
|
} else {
|
||||||
|
parseRegspec(reg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +282,7 @@ private fun parseCall(rest: String): ParsedCall {
|
|||||||
actualTarget,
|
actualTarget,
|
||||||
address,
|
address,
|
||||||
arguments,
|
arguments,
|
||||||
if(returns==null) null else parseReturnRegspec(returns)
|
parseReturnRegspec(returns)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ object SysCalls {
|
|||||||
if(maxlenvalue>0)
|
if(maxlenvalue>0)
|
||||||
input = input.substring(0, min(input.length, maxlenvalue))
|
input = input.substring(0, min(input.length, maxlenvalue))
|
||||||
vm.memory.setString((address as UShort).toInt(), input, true)
|
vm.memory.setString((address as UShort).toInt(), input, true)
|
||||||
returnValue(callspec.returns!!, input.length, vm)
|
returnValue(callspec.returns.single(), input.length, vm)
|
||||||
}
|
}
|
||||||
Syscall.SLEEP -> {
|
Syscall.SLEEP -> {
|
||||||
val duration = getArgValues(callspec.arguments, vm).single() as UShort
|
val duration = getArgValues(callspec.arguments, vm).single() as UShort
|
||||||
@ -237,7 +237,7 @@ object SysCalls {
|
|||||||
Syscall.GFX_GETPIXEL -> {
|
Syscall.GFX_GETPIXEL -> {
|
||||||
val (x,y) = getArgValues(callspec.arguments, vm)
|
val (x,y) = getArgValues(callspec.arguments, vm)
|
||||||
val color = vm.gfx_getpixel(x as UShort, y as UShort)
|
val color = vm.gfx_getpixel(x as UShort, y as UShort)
|
||||||
returnValue(callspec.returns!!, color, vm)
|
returnValue(callspec.returns.single(), color, vm)
|
||||||
}
|
}
|
||||||
Syscall.WAIT -> {
|
Syscall.WAIT -> {
|
||||||
val time = getArgValues(callspec.arguments, vm).single() as UShort
|
val time = getArgValues(callspec.arguments, vm).single() as UShort
|
||||||
@ -328,9 +328,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + if(length==0) 256 else length
|
val endAddressExcl = address + if(length==0) 256 else length
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-1, 1)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-1, 1)
|
||||||
if(addresses.any { vm.memory.getUB(it).toInt()!=0 })
|
if(addresses.any { vm.memory.getUB(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.ANY_WORD -> {
|
Syscall.ANY_WORD -> {
|
||||||
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -339,9 +339,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + if(length==0) 256*2 else length*2
|
val endAddressExcl = address + if(length==0) 256*2 else length*2
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-2, 2)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-2, 2)
|
||||||
if(addresses.any { vm.memory.getUW(it).toInt()!=0 })
|
if(addresses.any { vm.memory.getUW(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.ANY_FLOAT -> {
|
Syscall.ANY_FLOAT -> {
|
||||||
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -350,9 +350,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + (if(length==0) 256*vm.machinedef.FLOAT_MEM_SIZE else length*vm.machinedef.FLOAT_MEM_SIZE)
|
val endAddressExcl = address + (if(length==0) 256*vm.machinedef.FLOAT_MEM_SIZE else length*vm.machinedef.FLOAT_MEM_SIZE)
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-vm.machinedef.FLOAT_MEM_SIZE, 4)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-vm.machinedef.FLOAT_MEM_SIZE, 4)
|
||||||
if(addresses.any { vm.memory.getFloat(it).toInt()!=0 })
|
if(addresses.any { vm.memory.getFloat(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.ALL_BYTE -> {
|
Syscall.ALL_BYTE -> {
|
||||||
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -361,9 +361,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + if(length==0) 256 else length
|
val endAddressExcl = address + if(length==0) 256 else length
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-1, 1)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-1, 1)
|
||||||
if(addresses.all { vm.memory.getUB(it).toInt()!=0 })
|
if(addresses.all { vm.memory.getUB(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.ALL_WORD -> {
|
Syscall.ALL_WORD -> {
|
||||||
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -372,9 +372,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + if(length==0) 256*2 else length*2
|
val endAddressExcl = address + if(length==0) 256*2 else length*2
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-2, 2)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-2, 2)
|
||||||
if(addresses.all { vm.memory.getUW(it).toInt()!=0 })
|
if(addresses.all { vm.memory.getUW(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.ALL_FLOAT -> {
|
Syscall.ALL_FLOAT -> {
|
||||||
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -383,9 +383,9 @@ object SysCalls {
|
|||||||
val endAddressExcl = address + (if(length==0) 256*vm.machinedef.FLOAT_MEM_SIZE else length*vm.machinedef.FLOAT_MEM_SIZE)
|
val endAddressExcl = address + (if(length==0) 256*vm.machinedef.FLOAT_MEM_SIZE else length*vm.machinedef.FLOAT_MEM_SIZE)
|
||||||
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-vm.machinedef.FLOAT_MEM_SIZE, 4)
|
val addresses = IntProgression.fromClosedRange(address, endAddressExcl-vm.machinedef.FLOAT_MEM_SIZE, 4)
|
||||||
if(addresses.all { vm.memory.getFloat(it).toInt()!=0 })
|
if(addresses.all { vm.memory.getFloat(it).toInt()!=0 })
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
}
|
}
|
||||||
Syscall.PRINT_F -> {
|
Syscall.PRINT_F -> {
|
||||||
val value = getArgValues(callspec.arguments, vm).single() as Double
|
val value = getArgValues(callspec.arguments, vm).single() as Double
|
||||||
@ -402,18 +402,18 @@ object SysCalls {
|
|||||||
} catch(_: NumberFormatException) {
|
} catch(_: NumberFormatException) {
|
||||||
0u
|
0u
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, value, vm)
|
returnValue(callspec.returns.single(), value, vm)
|
||||||
}
|
}
|
||||||
Syscall.STR_TO_WORD -> {
|
Syscall.STR_TO_WORD -> {
|
||||||
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
||||||
val memstring = vm.memory.getString(stringAddr.toInt())
|
val memstring = vm.memory.getString(stringAddr.toInt())
|
||||||
val match = Regex("^[+-]?\\d+").find(memstring) ?: return returnValue(callspec.returns!!, 0, vm)
|
val match = Regex("^[+-]?\\d+").find(memstring) ?: return returnValue(callspec.returns.single(), 0, vm)
|
||||||
val value = try {
|
val value = try {
|
||||||
match.value.toShort()
|
match.value.toShort()
|
||||||
} catch(_: NumberFormatException) {
|
} catch(_: NumberFormatException) {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
return returnValue(callspec.returns!!, value, vm)
|
return returnValue(callspec.returns.single(), value, vm)
|
||||||
}
|
}
|
||||||
Syscall.STR_TO_FLOAT -> {
|
Syscall.STR_TO_FLOAT -> {
|
||||||
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
val stringAddr = getArgValues(callspec.arguments, vm).single() as UShort
|
||||||
@ -428,7 +428,7 @@ object SysCalls {
|
|||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.COMPARE_STRINGS -> {
|
Syscall.COMPARE_STRINGS -> {
|
||||||
val (firstV, secondV) = getArgValues(callspec.arguments, vm)
|
val (firstV, secondV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -438,11 +438,11 @@ object SysCalls {
|
|||||||
val second = vm.memory.getString(secondAddr.toInt())
|
val second = vm.memory.getString(secondAddr.toInt())
|
||||||
val comparison = first.compareTo(second)
|
val comparison = first.compareTo(second)
|
||||||
if(comparison==0)
|
if(comparison==0)
|
||||||
returnValue(callspec.returns!!, 0, vm)
|
returnValue(callspec.returns.single(), 0, vm)
|
||||||
else if(comparison<0)
|
else if(comparison<0)
|
||||||
returnValue(callspec.returns!!, -1, vm)
|
returnValue(callspec.returns.single(), -1, vm)
|
||||||
else
|
else
|
||||||
returnValue(callspec.returns!!, 1, vm)
|
returnValue(callspec.returns.single(), 1, vm)
|
||||||
}
|
}
|
||||||
Syscall.RNDFSEED -> {
|
Syscall.RNDFSEED -> {
|
||||||
val seed = getArgValues(callspec.arguments, vm).single() as Double
|
val seed = getArgValues(callspec.arguments, vm).single() as Double
|
||||||
@ -456,20 +456,20 @@ object SysCalls {
|
|||||||
vm.randomSeed(seed1 as UShort, seed2 as UShort)
|
vm.randomSeed(seed1 as UShort, seed2 as UShort)
|
||||||
}
|
}
|
||||||
Syscall.RND -> {
|
Syscall.RND -> {
|
||||||
returnValue(callspec.returns!!, vm.randomGenerator.nextInt().toUByte(), vm)
|
returnValue(callspec.returns.single(), vm.randomGenerator.nextInt().toUByte(), vm)
|
||||||
}
|
}
|
||||||
Syscall.RNDW -> {
|
Syscall.RNDW -> {
|
||||||
returnValue(callspec.returns!!, vm.randomGenerator.nextInt().toUShort(), vm)
|
returnValue(callspec.returns.single(), vm.randomGenerator.nextInt().toUShort(), vm)
|
||||||
}
|
}
|
||||||
Syscall.RNDF -> {
|
Syscall.RNDF -> {
|
||||||
returnValue(callspec.returns!!, vm.randomGeneratorFloats.nextFloat(), vm)
|
returnValue(callspec.returns.single(), vm.randomGeneratorFloats.nextFloat(), vm)
|
||||||
}
|
}
|
||||||
Syscall.STRING_CONTAINS -> {
|
Syscall.STRING_CONTAINS -> {
|
||||||
val (charV, addr) = getArgValues(callspec.arguments, vm)
|
val (charV, addr) = getArgValues(callspec.arguments, vm)
|
||||||
val stringAddr = addr as UShort
|
val stringAddr = addr as UShort
|
||||||
val char = (charV as UByte).toInt().toChar()
|
val char = (charV as UByte).toInt().toChar()
|
||||||
val string = vm.memory.getString(stringAddr.toInt())
|
val string = vm.memory.getString(stringAddr.toInt())
|
||||||
returnValue(callspec.returns!!, if(char in string) 1u else 0u, vm)
|
returnValue(callspec.returns.single(), if(char in string) 1u else 0u, vm)
|
||||||
}
|
}
|
||||||
Syscall.BYTEARRAY_CONTAINS -> {
|
Syscall.BYTEARRAY_CONTAINS -> {
|
||||||
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -477,11 +477,11 @@ object SysCalls {
|
|||||||
var array = (arrayV as UShort).toInt()
|
var array = (arrayV as UShort).toInt()
|
||||||
while(length>0u) {
|
while(length>0u) {
|
||||||
if(vm.memory.getUB(array)==value)
|
if(vm.memory.getUB(array)==value)
|
||||||
return returnValue(callspec.returns!!, 1u, vm)
|
return returnValue(callspec.returns.single(), 1u, vm)
|
||||||
array++
|
array++
|
||||||
length--
|
length--
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
}
|
}
|
||||||
Syscall.WORDARRAY_CONTAINS -> {
|
Syscall.WORDARRAY_CONTAINS -> {
|
||||||
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -489,11 +489,11 @@ object SysCalls {
|
|||||||
var array = (arrayV as UShort).toInt()
|
var array = (arrayV as UShort).toInt()
|
||||||
while(length>0u) {
|
while(length>0u) {
|
||||||
if(vm.memory.getUW(array)==value)
|
if(vm.memory.getUW(array)==value)
|
||||||
return returnValue(callspec.returns!!, 1u, vm)
|
return returnValue(callspec.returns.single(), 1u, vm)
|
||||||
array += 2
|
array += 2
|
||||||
length--
|
length--
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
}
|
}
|
||||||
Syscall.FLOATARRAY_CONTAINS -> {
|
Syscall.FLOATARRAY_CONTAINS -> {
|
||||||
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
val (value, arrayV, lengthV) = getArgValues(callspec.arguments, vm)
|
||||||
@ -501,11 +501,11 @@ object SysCalls {
|
|||||||
var array = (arrayV as UShort).toInt()
|
var array = (arrayV as UShort).toInt()
|
||||||
while(length>0u) {
|
while(length>0u) {
|
||||||
if(vm.memory.getFloat(array)==value)
|
if(vm.memory.getFloat(array)==value)
|
||||||
return returnValue(callspec.returns!!, 1u, vm)
|
return returnValue(callspec.returns.single(), 1u, vm)
|
||||||
array += vm.machinedef.FLOAT_MEM_SIZE
|
array += vm.machinedef.FLOAT_MEM_SIZE
|
||||||
length--
|
length--
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
}
|
}
|
||||||
Syscall.CLAMP_BYTE -> {
|
Syscall.CLAMP_BYTE -> {
|
||||||
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
||||||
@ -513,7 +513,7 @@ object SysCalls {
|
|||||||
val minimum = (minimumU as UByte).toByte().toInt()
|
val minimum = (minimumU as UByte).toByte().toInt()
|
||||||
val maximum = (maximumU as UByte).toByte().toInt()
|
val maximum = (maximumU as UByte).toByte().toInt()
|
||||||
val result = min(max(value, minimum), maximum)
|
val result = min(max(value, minimum), maximum)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.CLAMP_UBYTE -> {
|
Syscall.CLAMP_UBYTE -> {
|
||||||
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
||||||
@ -521,7 +521,7 @@ object SysCalls {
|
|||||||
val minimum = (minimumU as UByte).toInt()
|
val minimum = (minimumU as UByte).toInt()
|
||||||
val maximum = (maximumU as UByte).toInt()
|
val maximum = (maximumU as UByte).toInt()
|
||||||
val result = min(max(value, minimum), maximum)
|
val result = min(max(value, minimum), maximum)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.CLAMP_WORD -> {
|
Syscall.CLAMP_WORD -> {
|
||||||
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
||||||
@ -529,7 +529,7 @@ object SysCalls {
|
|||||||
val minimum = (minimumU as UShort).toShort().toInt()
|
val minimum = (minimumU as UShort).toShort().toInt()
|
||||||
val maximum = (maximumU as UShort).toShort().toInt()
|
val maximum = (maximumU as UShort).toShort().toInt()
|
||||||
val result = min(max(value, minimum), maximum)
|
val result = min(max(value, minimum), maximum)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.CLAMP_UWORD -> {
|
Syscall.CLAMP_UWORD -> {
|
||||||
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
||||||
@ -537,7 +537,7 @@ object SysCalls {
|
|||||||
val minimum = (minimumU as UShort).toInt()
|
val minimum = (minimumU as UShort).toInt()
|
||||||
val maximum = (maximumU as UShort).toInt()
|
val maximum = (maximumU as UShort).toInt()
|
||||||
val result = min(max(value, minimum), maximum)
|
val result = min(max(value, minimum), maximum)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.CLAMP_FLOAT -> {
|
Syscall.CLAMP_FLOAT -> {
|
||||||
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
val (valueU, minimumU, maximumU) = getArgValues(callspec.arguments, vm)
|
||||||
@ -545,7 +545,7 @@ object SysCalls {
|
|||||||
val minimum = minimumU as Double
|
val minimum = minimumU as Double
|
||||||
val maximum = maximumU as Double
|
val maximum = maximumU as Double
|
||||||
val result = min(max(value, minimum), maximum)
|
val result = min(max(value, minimum), maximum)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.ATAN -> {
|
Syscall.ATAN -> {
|
||||||
val (x1, y1, x2, y2) = getArgValues(callspec.arguments, vm)
|
val (x1, y1, x2, y2) = getArgValues(callspec.arguments, vm)
|
||||||
@ -557,10 +557,10 @@ object SysCalls {
|
|||||||
if(radians<0)
|
if(radians<0)
|
||||||
radians+=2*PI
|
radians+=2*PI
|
||||||
val result = floor(radians/2.0/PI*256.0)
|
val result = floor(radians/2.0/PI*256.0)
|
||||||
returnValue(callspec.returns!!, result, vm)
|
returnValue(callspec.returns.single(), result, vm)
|
||||||
}
|
}
|
||||||
Syscall.MUL16_LAST_UPPER -> {
|
Syscall.MUL16_LAST_UPPER -> {
|
||||||
returnValue(callspec.returns!!, vm.mul16_last_upper, vm)
|
returnValue(callspec.returns.single(), vm.mul16_last_upper, vm)
|
||||||
}
|
}
|
||||||
Syscall.FLOAT_TO_STR -> {
|
Syscall.FLOAT_TO_STR -> {
|
||||||
val (buffer, number) = getArgValues(callspec.arguments, vm)
|
val (buffer, number) = getArgValues(callspec.arguments, vm)
|
||||||
@ -612,7 +612,7 @@ object SysCalls {
|
|||||||
val target = (targetA as UShort).toInt()
|
val target = (targetA as UShort).toInt()
|
||||||
val string = vm.memory.getString(source)
|
val string = vm.memory.getString(source)
|
||||||
vm.memory.setString(target, string, true)
|
vm.memory.setString(target, string, true)
|
||||||
returnValue(callspec.returns!!, string.length, vm)
|
returnValue(callspec.returns.single(), string.length, vm)
|
||||||
}
|
}
|
||||||
Syscall.ARRAYCOPY_SPLITW_TO_NORMAL -> {
|
Syscall.ARRAYCOPY_SPLITW_TO_NORMAL -> {
|
||||||
val (fromLsbA, fromMsbA, targetA, bytecountA) = getArgValues(callspec.arguments, vm)
|
val (fromLsbA, fromMsbA, targetA, bytecountA) = getArgValues(callspec.arguments, vm)
|
||||||
@ -646,9 +646,9 @@ object SysCalls {
|
|||||||
for (i in 0..<data.size - 2) {
|
for (i in 0..<data.size - 2) {
|
||||||
vm.memory.setUB(addr + i, data[i + 2].toUByte())
|
vm.memory.setUB(addr + i, data[i + 2].toUByte())
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, (addr + data.size - 2).toUShort(), vm)
|
returnValue(callspec.returns.single(), (addr + data.size - 2).toUShort(), vm)
|
||||||
} else {
|
} else {
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Syscall.LOAD_RAW -> {
|
Syscall.LOAD_RAW -> {
|
||||||
@ -660,9 +660,9 @@ object SysCalls {
|
|||||||
for (i in 0..<data.size) {
|
for (i in 0..<data.size) {
|
||||||
vm.memory.setUB(addr + i, data[i].toUByte())
|
vm.memory.setUB(addr + i, data[i].toUByte())
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, (addr + data.size).toUShort(), vm)
|
returnValue(callspec.returns.single(), (addr + data.size).toUShort(), vm)
|
||||||
} else {
|
} else {
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Syscall.SAVE -> {
|
Syscall.SAVE -> {
|
||||||
@ -688,10 +688,10 @@ object SysCalls {
|
|||||||
}
|
}
|
||||||
val filename = vm.memory.getString((filenamePtr as UShort).toInt())
|
val filename = vm.memory.getString((filenamePtr as UShort).toInt())
|
||||||
if (File(filename).exists())
|
if (File(filename).exists())
|
||||||
returnValue(callspec.returns!!, 0u, vm)
|
returnValue(callspec.returns.single(), 0u, vm)
|
||||||
else {
|
else {
|
||||||
File(filename).writeBytes(data)
|
File(filename).writeBytes(data)
|
||||||
returnValue(callspec.returns!!, 1u, vm)
|
returnValue(callspec.returns.single(), 1u, vm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Syscall.DELETE -> {
|
Syscall.DELETE -> {
|
||||||
@ -712,12 +712,12 @@ object SysCalls {
|
|||||||
directory.listDirectoryEntries().sorted().forEach {
|
directory.listDirectoryEntries().sorted().forEach {
|
||||||
println("${it.toFile().length()}\t${it.normalize()}")
|
println("${it.toFile().length()}\t${it.normalize()}")
|
||||||
}
|
}
|
||||||
returnValue(callspec.returns!!, 1u, vm)
|
returnValue(callspec.returns.single(), 1u, vm)
|
||||||
}
|
}
|
||||||
Syscall.GETGONSOLESIZE -> {
|
Syscall.GETGONSOLESIZE -> {
|
||||||
// no arguments
|
// no arguments
|
||||||
if(System.console()==null) {
|
if(System.console()==null) {
|
||||||
return returnValue(callspec.returns!!, 30*256 + 80, vm) // just return some defaults in this case 80*30
|
return returnValue(callspec.returns.single(), 30*256 + 80, vm) // just return some defaults in this case 80*30
|
||||||
}
|
}
|
||||||
|
|
||||||
val linesS = System.getenv("LINES")
|
val linesS = System.getenv("LINES")
|
||||||
@ -725,7 +725,7 @@ object SysCalls {
|
|||||||
if(linesS!=null && columnsS!=null) {
|
if(linesS!=null && columnsS!=null) {
|
||||||
val lines = linesS.toInt()
|
val lines = linesS.toInt()
|
||||||
val columns = columnsS.toInt()
|
val columns = columnsS.toInt()
|
||||||
return returnValue(callspec.returns!!, lines*256 + columns, vm)
|
return returnValue(callspec.returns.single(), lines*256 + columns, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -735,12 +735,12 @@ object SysCalls {
|
|||||||
val response = process.inputStream.bufferedReader().lineSequence().iterator()
|
val response = process.inputStream.bufferedReader().lineSequence().iterator()
|
||||||
val width = response.next().toInt()
|
val width = response.next().toInt()
|
||||||
val height = response.next().toInt()
|
val height = response.next().toInt()
|
||||||
return returnValue(callspec.returns!!, height*256 + width, vm)
|
return returnValue(callspec.returns.single(), height*256 + width, vm)
|
||||||
}
|
}
|
||||||
} catch (x: Exception) {
|
} catch (x: Exception) {
|
||||||
// dunno what happened...
|
// dunno what happened...
|
||||||
}
|
}
|
||||||
return returnValue(callspec.returns!!, 30*256 + 80, vm) // just return some defaults in this case 80*30
|
return returnValue(callspec.returns.single(), 30*256 + 80, vm) // just return some defaults in this case 80*30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,8 +655,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
val returns = context.fcallSpec.returns
|
val returns = context.fcallSpec.returns
|
||||||
when (i.type!!) {
|
when (i.type!!) {
|
||||||
IRDataType.BYTE -> {
|
IRDataType.BYTE -> {
|
||||||
if(returns!=null)
|
if(returns.isNotEmpty())
|
||||||
registers.setUB(returns.registerNum, registers.getUB(i.reg1!!))
|
registers.setUB(returns.single().registerNum, registers.getUB(i.reg1!!))
|
||||||
else {
|
else {
|
||||||
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
||||||
if(callInstr.opcode!=Opcode.CALL)
|
if(callInstr.opcode!=Opcode.CALL)
|
||||||
@ -664,8 +664,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IRDataType.WORD -> {
|
IRDataType.WORD -> {
|
||||||
if(returns!=null)
|
if(returns.isNotEmpty())
|
||||||
registers.setUW(returns.registerNum, registers.getUW(i.reg1!!))
|
registers.setUW(returns.single().registerNum, registers.getUW(i.reg1!!))
|
||||||
else {
|
else {
|
||||||
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
||||||
if(callInstr.opcode!=Opcode.CALL)
|
if(callInstr.opcode!=Opcode.CALL)
|
||||||
@ -673,8 +673,8 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IRDataType.FLOAT -> {
|
IRDataType.FLOAT -> {
|
||||||
if(returns!=null)
|
if(returns.isNotEmpty())
|
||||||
registers.setFloat(returns.registerNum, registers.getFloat(i.fpReg1!!))
|
registers.setFloat(returns.single().registerNum, registers.getFloat(i.fpReg1!!))
|
||||||
else {
|
else {
|
||||||
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
val callInstr = context.returnChunk.instructions[context.returnIndex-1]
|
||||||
if(callInstr.opcode!=Opcode.CALL)
|
if(callInstr.opcode!=Opcode.CALL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user