mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 01:49:22 +00:00
code check cleanups
This commit is contained in:
parent
5c6bd9c091
commit
2e35f3c3a3
@ -227,8 +227,8 @@ class PtContainmentCheck(position: Position): PtExpression(DataType.BOOL, positi
|
||||
get() = children[1] as? PtArray
|
||||
|
||||
companion object {
|
||||
val MAX_SIZE_FOR_INLINE_CHECKS_BYTE = 5
|
||||
val MAX_SIZE_FOR_INLINE_CHECKS_WORD = 4
|
||||
const val MAX_SIZE_FOR_INLINE_CHECKS_BYTE = 5
|
||||
const val MAX_SIZE_FOR_INLINE_CHECKS_WORD = 4
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ enum class DataType {
|
||||
WORD, // pass by value 16 bits signed
|
||||
LONG, // pass by value 32 bits signed
|
||||
FLOAT, // pass by value machine dependent
|
||||
BOOL, // pass by value bit 0 of a 8 bit byte
|
||||
BOOL, // pass by value bit 0 of an 8-bit byte
|
||||
STR, // pass by reference
|
||||
ARRAY_UB, // pass by reference
|
||||
ARRAY_B, // pass by reference
|
||||
|
@ -94,7 +94,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
|
||||
}
|
||||
|
||||
synchronized(this) {
|
||||
if(free.size > 0) {
|
||||
if(free.isNotEmpty()) {
|
||||
if(size==1) {
|
||||
for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) {
|
||||
if(oneSeparateByteFree(candidate))
|
||||
|
@ -6,7 +6,7 @@ import prog8.code.core.Zeropage
|
||||
import prog8.code.core.ZeropageType
|
||||
|
||||
|
||||
// reference: "Mapping the C128" zero page chapter.
|
||||
// reference: "Mapping the C128" zeropage chapter.
|
||||
|
||||
class C128Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
|
@ -81,7 +81,7 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override fun allocateCx16VirtualRegisters() {
|
||||
// Note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses.
|
||||
// However, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
|
||||
// However, to be able for the compiler to "see" them as zeropage variables, we have to register them here as well.
|
||||
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
|
||||
// The base addres is $04. Unfortunately it cannot be the same as on the Commander X16 ($02).
|
||||
for(reg in 0..15) {
|
||||
|
@ -54,7 +54,7 @@ class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override fun allocateCx16VirtualRegisters() {
|
||||
// Note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses.
|
||||
// However, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
|
||||
// However, to be able for the compiler to "see" them as zeropage variables, we have to register them here as well.
|
||||
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
|
||||
for(reg in 0..15) {
|
||||
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
|
||||
|
@ -7,7 +7,7 @@ import java.io.CharConversionException
|
||||
|
||||
object PetsciiEncoding {
|
||||
|
||||
// decoding: from Petscii/Screencodes (0-255) to unicode
|
||||
// decoding: from Petscii/Screencodes (0-255) to Unicode
|
||||
// character tables used from https://github.com/irmen/cbmcodecs2
|
||||
|
||||
private val decodingPetsciiLowercase = charArrayOf(
|
||||
@ -1157,16 +1157,16 @@ object PetsciiEncoding {
|
||||
}
|
||||
}
|
||||
|
||||
fun petscii2scr(petscii_code: UByte, inverseVideo: Boolean): Result<UByte, CharConversionException> {
|
||||
fun petscii2scr(petsciicode: UByte, inverseVideo: Boolean): Result<UByte, CharConversionException> {
|
||||
val code: UInt = when {
|
||||
petscii_code <= 0x1fu -> petscii_code + 128u
|
||||
petscii_code <= 0x3fu -> petscii_code.toUInt()
|
||||
petscii_code <= 0x5fu -> petscii_code - 64u
|
||||
petscii_code <= 0x7fu -> petscii_code - 32u
|
||||
petscii_code <= 0x9fu -> petscii_code + 64u
|
||||
petscii_code <= 0xbfu -> petscii_code - 64u
|
||||
petscii_code <= 0xfeu -> petscii_code - 128u
|
||||
petscii_code == 255.toUByte() -> 95u
|
||||
petsciicode <= 0x1fu -> petsciicode + 128u
|
||||
petsciicode <= 0x3fu -> petsciicode.toUInt()
|
||||
petsciicode <= 0x5fu -> petsciicode - 64u
|
||||
petsciicode <= 0x7fu -> petsciicode - 32u
|
||||
petsciicode <= 0x9fu -> petsciicode + 64u
|
||||
petsciicode <= 0xbfu -> petsciicode - 64u
|
||||
petsciicode <= 0xfeu -> petsciicode - 128u
|
||||
petsciicode == 255.toUByte() -> 95u
|
||||
else -> return Err(CharConversionException("petscii code out of range"))
|
||||
}
|
||||
if(inverseVideo) {
|
||||
|
@ -34,7 +34,7 @@ class Neo6502Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override fun allocateCx16VirtualRegisters() {
|
||||
// Note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses.
|
||||
// However, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
|
||||
// However, to be able for the compiler to "see" them as zeropage variables, we have to register them here as well.
|
||||
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
|
||||
for(reg in 0..15) {
|
||||
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
|
||||
|
@ -10,7 +10,7 @@ import java.nio.file.Path
|
||||
|
||||
internal class AssemblyProgram(
|
||||
override val name: String,
|
||||
private val outputDir: Path,
|
||||
outputDir: Path,
|
||||
private val compTarget: ICompilationTarget) : IAssemblyProgram {
|
||||
|
||||
private val assemblyFile = outputDir.resolve("$name.asm")
|
||||
|
@ -119,8 +119,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
private fun funcDivmodW(fcall: PtBuiltinFunctionCall) {
|
||||
asmgen.assignWordOperandsToAYAndVar(fcall.args[1], fcall.args[0], "P8ZP_SCRATCH_W1")
|
||||
// math.divmod_uw_asm: -- divide two unsigned words (16 bit each) into 16 bit results
|
||||
// input: P8ZP_SCRATCH_W1 in ZP: 16 bit number, A/Y: 16 bit divisor
|
||||
// output: P8ZP_SCRATCH_W2 in ZP: 16 bit remainder, A/Y: 16 bit division result
|
||||
// input: P8ZP_SCRATCH_W1 in ZP: 16-bit number, A/Y: 16 bit divisor
|
||||
// output: P8ZP_SCRATCH_W2 in ZP: 16-bit remainder, A/Y: 16 bit division result
|
||||
asmgen.out(" jsr prog8_math.divmod_uw_asm")
|
||||
val var2name = asmgen.asmVariableName(fcall.args[2] as PtIdentifier)
|
||||
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name)
|
||||
|
@ -151,7 +151,7 @@ class IRCodeGen(
|
||||
sub.chunks.removeAt(0)
|
||||
sub.chunks.add(0, replacement)
|
||||
} else if(first.label != sub.label) {
|
||||
val next = if(first is IRCodeChunk) first else null
|
||||
val next = first as? IRCodeChunk
|
||||
sub.chunks.add(0, IRCodeChunk(sub.label, next))
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||
/*
|
||||
Empty Code chunk with label ->
|
||||
If next chunk has no label -> move label to next chunk, remove original
|
||||
If next chunk has label -> label name should be the same, remove original. Otherwise merge both labels into 1.
|
||||
If next chunk has label -> label name should be the same, remove original, otherwise merge both labels into 1.
|
||||
If is last chunk -> keep chunk in place because of the label.
|
||||
Empty Code chunk without label ->
|
||||
should not have been generated! ERROR.
|
||||
@ -195,10 +195,10 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||
chunks += candidate
|
||||
else if(lastChunk.isEmpty()) {
|
||||
val label = lastChunk.label
|
||||
if(label!=null)
|
||||
chunks += IRInlineAsmChunk(label, candidate.assembly, candidate.isIR, candidate.next)
|
||||
chunks += if(label!=null)
|
||||
IRInlineAsmChunk(label, candidate.assembly, candidate.isIR, candidate.next)
|
||||
else
|
||||
chunks += candidate
|
||||
candidate
|
||||
}
|
||||
}
|
||||
is IRInlineBinaryChunk -> {
|
||||
@ -206,10 +206,10 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
|
||||
chunks += candidate
|
||||
else if(lastChunk.isEmpty()) {
|
||||
val label = lastChunk.label
|
||||
if(label!=null)
|
||||
chunks += IRInlineBinaryChunk(label, candidate.data, candidate.next)
|
||||
chunks += if(label!=null)
|
||||
IRInlineBinaryChunk(label, candidate.data, candidate.next)
|
||||
else
|
||||
chunks += candidate
|
||||
candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class VarConstantValueTypeAdjuster(
|
||||
IAstModification.Remove(singleAssignment, singleAssignment.parent as IStatementContainer)
|
||||
)
|
||||
}
|
||||
// variable only has a single write and it is the initialization value, so it can be replaced with a constant, IF the value is a constant
|
||||
// variable only has a single write, and it is the initialization value, so it can be replaced with a constant, IF the value is a constant
|
||||
errors.info("variable '${decl.name}' is never written to and was replaced by a constant", decl.position)
|
||||
val const = VarDecl(VarDeclType.CONST, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, decl.names, singleAssignment.value, decl.sharedWithAsm, decl.splitArray, decl.alignment, decl.dirty, decl.position)
|
||||
return listOf(
|
||||
|
@ -177,7 +177,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
||||
} catch (ac: ErrorsReportedException) {
|
||||
if(args.printAst1 && resultingProgram!=null) {
|
||||
println("\n*********** COMPILER AST *************")
|
||||
printProgram(resultingProgram!!)
|
||||
printProgram(resultingProgram)
|
||||
println("*********** COMPILER AST END *************\n")
|
||||
}
|
||||
if (args.printAst2) {
|
||||
@ -185,7 +185,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
||||
println("There is no intermediate AST available because of compilation errors.")
|
||||
else {
|
||||
println("\n*********** INTERMEDIATE AST *************")
|
||||
printAst(ast!!, true, ::println)
|
||||
printAst(ast, true, ::println)
|
||||
println("*********** INTERMEDIATE AST END *************\n")
|
||||
}
|
||||
}
|
||||
@ -449,7 +449,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
}
|
||||
|
||||
removeUnusedCode(program, errors,compilerOptions)
|
||||
for(num_cycles in 0..10000) {
|
||||
for(numCycles in 0..10000) {
|
||||
// keep optimizing expressions and statements until no more steps remain
|
||||
val optsDone1 = program.simplifyExpressions(errors)
|
||||
val optsDone2 = program.optimizeStatements(errors, functions, compilerOptions)
|
||||
@ -463,7 +463,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
if (numOpts == 0)
|
||||
break
|
||||
|
||||
if(num_cycles==10000) {
|
||||
if(numCycles==10000) {
|
||||
throw InternalCompilerException("optimizeAst() is looping endlessly, numOpts = $numOpts")
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ internal class AstChecker(private val program: Program,
|
||||
} else if(valueDt.isIterable && expectedReturnValues[0]==DataType.UWORD) {
|
||||
// you can return a string or array when an uword (pointer) is returned
|
||||
} else if(valueDt istype DataType.UWORD && expectedReturnValues[0]==DataType.STR) {
|
||||
// you can return a uword pointer when the return type is a string
|
||||
// you can return an uword pointer when the return type is a string
|
||||
} else {
|
||||
errors.err("type $valueDt of return value doesn't match subroutine's return type ${expectedReturnValues[0]}",returnStmt.value!!.position)
|
||||
}
|
||||
@ -340,7 +340,7 @@ internal class AstChecker(private val program: Program,
|
||||
val jumpTarget = jump.identifier?.targetStatement(program)
|
||||
if(jumpTarget!=null) {
|
||||
val sub = jump.definingSubroutine
|
||||
val targetSub = if(jumpTarget is Subroutine) jumpTarget else jumpTarget.definingSubroutine
|
||||
val targetSub = jumpTarget as? Subroutine ?: jumpTarget.definingSubroutine
|
||||
if(sub !== targetSub)
|
||||
count++
|
||||
}
|
||||
@ -1173,7 +1173,7 @@ internal class AstChecker(private val program: Program,
|
||||
val jumpTarget = jump.identifier?.targetStatement(program)
|
||||
if(jumpTarget!=null) {
|
||||
val sub = jump.definingSubroutine
|
||||
val targetSub = if(jumpTarget is Subroutine) jumpTarget else jumpTarget.definingSubroutine
|
||||
val targetSub = jumpTarget as? Subroutine ?: jumpTarget.definingSubroutine
|
||||
if(sub !== targetSub)
|
||||
count++
|
||||
}
|
||||
@ -1978,7 +1978,7 @@ internal class AstChecker(private val program: Program,
|
||||
// this is allowed: bitwise operation between different types as long as they're the same size.
|
||||
}
|
||||
else if(targetDatatype==DataType.UWORD && sourceDatatype in PassByReferenceDatatypes) {
|
||||
// this is allowed: a pass-by-reference datatype into a uword (pointer value).
|
||||
// this is allowed: a pass-by-reference datatype into an uword (pointer value).
|
||||
}
|
||||
else if(sourceDatatype in ArrayDatatypes && targetDatatype in ArrayDatatypes) {
|
||||
// this is allowed (assigning array to array)
|
||||
|
@ -2,7 +2,6 @@ package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.IfElse
|
||||
import prog8.ast.walk.AstWalker
|
||||
|
@ -1,7 +1,6 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.INameScope
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
|
@ -422,10 +422,10 @@ private fun AugassignmentContext.toAst(): Assignment {
|
||||
}
|
||||
|
||||
private fun DatatypeContext.toAst(): DataType {
|
||||
try {
|
||||
return DataType.valueOf(text.uppercase())
|
||||
return try {
|
||||
DataType.valueOf(text.uppercase())
|
||||
} catch (_: IllegalArgumentException) {
|
||||
return DataType.UNDEFINED
|
||||
DataType.UNDEFINED
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,10 +258,10 @@ class BinaryExpression(
|
||||
|
||||
return when (leftDt) {
|
||||
DataType.BOOL -> {
|
||||
if(rightDt==DataType.BOOL)
|
||||
return Pair(DataType.BOOL, null)
|
||||
return if(rightDt==DataType.BOOL)
|
||||
Pair(DataType.BOOL, null)
|
||||
else
|
||||
return Pair(DataType.BOOL, right)
|
||||
Pair(DataType.BOOL, right)
|
||||
}
|
||||
DataType.UBYTE -> {
|
||||
when (rightDt) {
|
||||
@ -518,19 +518,19 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
||||
fun optimalNumeric(origType1: DataType, origType2: DataType?, value: Number, position: Position) : NumericLiteral {
|
||||
val optimal = optimalNumeric(value, position)
|
||||
val largestOrig = if(origType2==null) origType1 else if(origType1.largerThan(origType2)) origType1 else origType2
|
||||
if(largestOrig.largerThan(optimal.type))
|
||||
return NumericLiteral(largestOrig, optimal.number, position)
|
||||
return if(largestOrig.largerThan(optimal.type))
|
||||
NumericLiteral(largestOrig, optimal.number, position)
|
||||
else
|
||||
return optimal
|
||||
optimal
|
||||
}
|
||||
|
||||
fun optimalInteger(origType1: DataType, origType2: DataType?, value: Int, position: Position): NumericLiteral {
|
||||
val optimal = optimalInteger(value, position)
|
||||
val largestOrig = if(origType2==null) origType1 else if(origType1.largerThan(origType2)) origType1 else origType2
|
||||
if(largestOrig.largerThan(optimal.type))
|
||||
return NumericLiteral(largestOrig, optimal.number, position)
|
||||
return if(largestOrig.largerThan(optimal.type))
|
||||
NumericLiteral(largestOrig, optimal.number, position)
|
||||
else
|
||||
return optimal
|
||||
optimal
|
||||
}
|
||||
|
||||
fun optimalNumeric(value: Number, position: Position): NumericLiteral {
|
||||
@ -805,14 +805,14 @@ class CharLiteral private constructor(val value: Char,
|
||||
|
||||
companion object {
|
||||
fun create(character: Char, encoding: Encoding, position: Position): CharLiteral {
|
||||
if(encoding==Encoding.KATAKANA) {
|
||||
return if(encoding==Encoding.KATAKANA) {
|
||||
val processed = JapaneseCharacterConverter.zenkakuKatakanaToHankakuKatakana(character.toString())
|
||||
if(processed.length==1)
|
||||
return CharLiteral(processed[0], encoding, position)
|
||||
CharLiteral(processed[0], encoding, position)
|
||||
else
|
||||
throw CharConversionException("character literal encodes into multiple bytes at $position")
|
||||
} else
|
||||
return CharLiteral(character, encoding, position)
|
||||
CharLiteral(character, encoding, position)
|
||||
}
|
||||
|
||||
fun fromEscaped(raw: String, encoding: Encoding, position: Position): CharLiteral {
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
Theoretical optimal chunk size is 512 bytes but actual size may be different. (In practice there seems to be no significant speed impact)
|
||||
|
||||
MCF files are meant to be be created using a tool on PC, and only being read on the X16.
|
||||
MCF files are meant to be created using a tool on PC, and only being read on the X16.
|
||||
A Python tool is provided to create a demo MCF file.
|
||||
A proof of concept Prog8 library module and example program is provided to consume that demo MCF file on the X16.
|
||||
|
||||
@ -96,4 +96,4 @@ The second routine has the following signature:
|
||||
|
||||
These routines are provided to the streaming routine as callback addresses (ram bank number + address to call).
|
||||
If any of these routines returns Carry set (error status) the streaming routine halts, otherwise it keeps on going.
|
||||
The streaming continues until a End of File chunk type is encountered in the loadlist.
|
||||
The streaming continues until an End of File chunk type is encountered in the loadlist.
|
||||
|
@ -1,3 +1,3 @@
|
||||
You'll need to put the titlescreen data files from the 'musicdemo' project into this directory.
|
||||
The musicdemo is on github: https://github.com/irmen/cx16musicdemo
|
||||
The musicdemo is on GitHub: https://github.com/irmen/cx16musicdemo
|
||||
The four files are the two ME- and the two DS- TITLESCREEN.BIN and .PAL files, and are generated by running the makefile in that project.
|
||||
|
@ -12,7 +12,7 @@ It then uses the streaming support in zsmkit to load the song from disk as it is
|
||||
It shows some other features such as callbacks and pausing as well.
|
||||
The way the zsmkit blob is embedded into the program is done by telling prog8 that
|
||||
the 'main' block of the program has to start at $0830, and the very first command
|
||||
in that block is not the usual 'start' subroutine but a %asmbinary command to load
|
||||
in that block is not the usual 'start' subroutine but an %asmbinary command to load
|
||||
and embed the zsmkit blob right there and then.
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ this one was configured without streaming support enabled.
|
||||
CUSTOMIZING ZSMKIT
|
||||
------------------
|
||||
|
||||
Read the README on the zsmkit github repo. It contains a lot of important information,
|
||||
Read the README on the zsmkit GitHub repo. It contains a lot of important information,
|
||||
about how zsmkit works, but also about the various things you have to configure to build a
|
||||
new library blob to your liking. The example here includes two recently built variants of the blob,
|
||||
so you don't immediately have to build something yourself, but if you want to enable or disable
|
||||
|
@ -408,10 +408,10 @@ class IRFileReader {
|
||||
|
||||
skipText(reader)
|
||||
while(reader.peek().isStartElement) {
|
||||
when(reader.peek().asStartElement().name.localPart) {
|
||||
"CODE" -> sub += parseCodeChunk(reader)
|
||||
"BYTES" -> sub += parseBinaryBytes(reader)
|
||||
"ASM" -> sub += parseInlineAssembly(reader)
|
||||
sub += when(reader.peek().asStartElement().name.localPart) {
|
||||
"CODE" -> parseCodeChunk(reader)
|
||||
"BYTES" -> parseBinaryBytes(reader)
|
||||
"ASM" -> parseInlineAssembly(reader)
|
||||
else -> throw IRParseException("invalid line in SUB: ${reader.peek()}")
|
||||
}
|
||||
skipText(reader)
|
||||
|
@ -236,7 +236,7 @@ class IRProgram(val name: String,
|
||||
i++
|
||||
instr2 = chunk.instructions[i]
|
||||
}
|
||||
// it could be that the actual call is only in another code chunk, so IF we find one, we can check. Otherwise just skip the check...
|
||||
// it could be that the actual call is only in another code chunk, so IF we find one, we can check, otherwise just skip the check...
|
||||
if(chunk.instructions[i].fcallArgs!=null) {
|
||||
val expectedRegisterLoads = chunk.instructions[i].fcallArgs!!.arguments.map { it.reg.registerNum }
|
||||
require(registers.containsAll(expectedRegisterLoads)) { "not all argument registers are given a value in the preparecall-call sequence" }
|
||||
|
@ -568,7 +568,7 @@ object SysCalls {
|
||||
return returnValue(callspec.returns.single(), height*256 + width, vm)
|
||||
}
|
||||
} catch (x: Exception) {
|
||||
// dunno what happened...
|
||||
// don't know what happened...
|
||||
}
|
||||
return returnValue(callspec.returns.single(), 30*256 + 80, vm) // just return some defaults in this case 80*30
|
||||
}
|
||||
@ -603,17 +603,17 @@ object SysCalls {
|
||||
}
|
||||
Syscall.READ_FILE_BYTE -> {
|
||||
val (success, byte) = vm.read_file_byte()
|
||||
if(success)
|
||||
return returnValue(callspec.returns.single(), 0x0100 or byte.toInt(), vm)
|
||||
return if(success)
|
||||
returnValue(callspec.returns.single(), 0x0100 or byte.toInt(), vm)
|
||||
else
|
||||
return returnValue(callspec.returns.single(), 0x0000, vm)
|
||||
returnValue(callspec.returns.single(), 0x0000, vm)
|
||||
}
|
||||
Syscall.WRITE_FILE_BYTE -> {
|
||||
val byte = getArgValues(callspec.arguments, vm).single() as UByte
|
||||
if(vm.write_file_byte(byte))
|
||||
return returnValue(callspec.returns.single(), 1, vm)
|
||||
return if(vm.write_file_byte(byte))
|
||||
returnValue(callspec.returns.single(), 1, vm)
|
||||
else
|
||||
return returnValue(callspec.returns.single(), 0, vm)
|
||||
returnValue(callspec.returns.single(), 0, vm)
|
||||
}
|
||||
Syscall.CLOSE_FILE -> vm.close_file_read()
|
||||
Syscall.CLOSE_FILE_WRITE -> vm.close_file_write()
|
||||
|
Loading…
Reference in New Issue
Block a user