diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 42e992347..af761fc24 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -43,9 +43,6 @@ class AsmGen(internal val program: Program, override fun compileToAssembly(): IAssemblyProgram? { - if(options.compTarget.name=="atari" && options.launcher==LauncherType.CBMBASIC) - throw AssemblyError("atari target cannot use CBM BASIC launcher type") - assemblyLines.clear() loopEndLabels.clear() diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt index b1613aa70..9cd821dbb 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AssemblyProgram.kt @@ -54,6 +54,7 @@ internal class AssemblyProgram( println("\nCreating raw binary for target ${compTarget.name}.") binFile } + else -> throw AssemblyError("invalid output type") } command.addAll(listOf("--output", outFile.toString(), assemblyFile.toString())) assemblerCommand = command @@ -75,7 +76,7 @@ internal class AssemblyProgram( command.add("--list=$listFile") val outFile = when (options.output) { - OutputType.PRG -> { + OutputType.XEX -> { command.add("--atari-xex") println("\nCreating xex for target ${compTarget.name}.") xexFile @@ -85,6 +86,7 @@ internal class AssemblyProgram( println("\nCreating raw binary for target ${compTarget.name}.") binFile } + else -> throw AssemblyError("invalid output type") } command.addAll(listOf("--output", outFile.toString(), assemblyFile.toString())) assemblerCommand = command diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index fc2228acd..640e25c69 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -71,12 +71,27 @@ internal class ProgramAndVarsGen( program.actualLoadAddress = program.definedLoadAddress if (program.actualLoadAddress == 0u) { - if (options.launcher == LauncherType.CBMBASIC) { - program.actualLoadAddress = compTarget.machine.BASIC_LOAD_ADDRESS - } - else { - errors.err("load address must be specified with %address when using launcher type ${options.launcher}", program.toplevelModule.position) - return + when(options.output) { + OutputType.RAW -> { + errors.err("load address must be specified with %address when using raw output type", program.toplevelModule.position) + return + } + OutputType.PRG -> { + when(options.launcher) { + CbmPrgLauncherType.BASIC -> { + program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS + } + CbmPrgLauncherType.NONE -> { + errors.err("load address must be specified with %address when not using basic launcher", program.toplevelModule.position) + return + } + } + } + OutputType.XEX -> { + if(options.launcher!=CbmPrgLauncherType.NONE) + throw AssemblyError("atari xex output can't contain BASIC launcher") + program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS + } } } @@ -89,33 +104,44 @@ internal class ProgramAndVarsGen( asmgen.out("P8ESTACK_LO = ${compTarget.machine.ESTACK_LO.toHex()}") asmgen.out("P8ESTACK_HI = ${compTarget.machine.ESTACK_HI.toHex()}") - when { - options.launcher == LauncherType.CBMBASIC -> { - if (program.actualLoadAddress != options.compTarget.machine.BASIC_LOAD_ADDRESS) { - errors.err("BASIC output must have load address ${options.compTarget.machine.BASIC_LOAD_ADDRESS.toHex()}", program.toplevelModule.position) - } - asmgen.out("; ---- basic program with sys call ----") - asmgen.out("* = ${program.actualLoadAddress.toHex()}") - val year = LocalDate.now().year - asmgen.out(" .word (+), $year") - asmgen.out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'") - asmgen.out("+\t.word 0") - asmgen.out("prog8_entrypoint\t; assembly code starts here\n") - if(!options.noSysInit) - asmgen.out(" jsr ${compTarget.name}.init_system") - asmgen.out(" jsr ${compTarget.name}.init_system_phase2") - } - options.output == OutputType.PRG -> { - asmgen.out("; ---- program without basic sys call ----") - asmgen.out("* = ${program.actualLoadAddress.toHex()}\n") - if(!options.noSysInit) - asmgen.out(" jsr ${compTarget.name}.init_system") - asmgen.out(" jsr ${compTarget.name}.init_system_phase2") - } - options.output == OutputType.RAW -> { + when(options.output) { + OutputType.RAW -> { asmgen.out("; ---- raw assembler program ----") asmgen.out("* = ${program.actualLoadAddress.toHex()}\n") } + OutputType.PRG -> { + when(options.launcher) { + CbmPrgLauncherType.BASIC -> { + if (program.actualLoadAddress != options.compTarget.machine.PROGRAM_LOAD_ADDRESS) { + errors.err("BASIC output must have load address ${options.compTarget.machine.PROGRAM_LOAD_ADDRESS.toHex()}", program.toplevelModule.position) + } + asmgen.out("; ---- basic program with sys call ----") + asmgen.out("* = ${program.actualLoadAddress.toHex()}") + val year = LocalDate.now().year + asmgen.out(" .word (+), $year") + asmgen.out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'") + asmgen.out("+\t.word 0") + asmgen.out("prog8_entrypoint\t; assembly code starts here\n") + if(!options.noSysInit) + asmgen.out(" jsr ${compTarget.name}.init_system") + asmgen.out(" jsr ${compTarget.name}.init_system_phase2") + } + CbmPrgLauncherType.NONE -> { + asmgen.out("; ---- program without basic sys call ----") + asmgen.out("* = ${program.actualLoadAddress.toHex()}\n") + if(!options.noSysInit) + asmgen.out(" jsr ${compTarget.name}.init_system") + asmgen.out(" jsr ${compTarget.name}.init_system_phase2") + } + } + } + OutputType.XEX -> { + asmgen.out("; ---- atari xex program ----") + asmgen.out("* = ${program.actualLoadAddress.toHex()}\n") + if(!options.noSysInit) + asmgen.out(" jsr ${compTarget.name}.init_system") + asmgen.out(" jsr ${compTarget.name}.init_system_phase2") + } } if(options.zeropage !in arrayOf(ZeropageType.BASICSAFE, ZeropageType.DONTUSE)) { diff --git a/codeGenTargets/src/prog8/codegen/target/AtariTarget.kt b/codeGenTargets/src/prog8/codegen/target/AtariTarget.kt index 793c48187..e7192c981 100644 --- a/codeGenTargets/src/prog8/codegen/target/AtariTarget.kt +++ b/codeGenTargets/src/prog8/codegen/target/AtariTarget.kt @@ -17,7 +17,6 @@ class AtariTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer { override val machine = AtariMachineDefinition() override val supportedEncodings = setOf(Encoding.ATASCII) override val defaultEncoding = Encoding.ATASCII - override val defaultLauncherType = LauncherType.NONE companion object { const val NAME = "atari" diff --git a/codeGenTargets/src/prog8/codegen/target/C128Target.kt b/codeGenTargets/src/prog8/codegen/target/C128Target.kt index a7cb06a86..af401e7b7 100644 --- a/codeGenTargets/src/prog8/codegen/target/C128Target.kt +++ b/codeGenTargets/src/prog8/codegen/target/C128Target.kt @@ -15,7 +15,6 @@ class C128Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by C override val machine = C128MachineDefinition() override val supportedEncodings = setOf(Encoding.PETSCII, Encoding.SCREENCODES) override val defaultEncoding = Encoding.PETSCII - override val defaultLauncherType = LauncherType.CBMBASIC companion object { const val NAME = "c128" diff --git a/codeGenTargets/src/prog8/codegen/target/C64Target.kt b/codeGenTargets/src/prog8/codegen/target/C64Target.kt index 429264d5b..f14785f69 100644 --- a/codeGenTargets/src/prog8/codegen/target/C64Target.kt +++ b/codeGenTargets/src/prog8/codegen/target/C64Target.kt @@ -15,7 +15,6 @@ class C64Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by Cb override val machine = C64MachineDefinition() override val supportedEncodings = setOf(Encoding.PETSCII, Encoding.SCREENCODES) override val defaultEncoding = Encoding.PETSCII - override val defaultLauncherType = LauncherType.CBMBASIC companion object { const val NAME = "c64" diff --git a/codeGenTargets/src/prog8/codegen/target/Cx16Target.kt b/codeGenTargets/src/prog8/codegen/target/Cx16Target.kt index d6bc1c98d..ab51cdd53 100644 --- a/codeGenTargets/src/prog8/codegen/target/Cx16Target.kt +++ b/codeGenTargets/src/prog8/codegen/target/Cx16Target.kt @@ -15,7 +15,6 @@ class Cx16Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by C override val machine = CX16MachineDefinition() override val supportedEncodings = setOf(Encoding.PETSCII, Encoding.SCREENCODES, Encoding.ISO) override val defaultEncoding = Encoding.PETSCII - override val defaultLauncherType = LauncherType.CBMBASIC companion object { const val NAME = "cx16" diff --git a/codeGenTargets/src/prog8/codegen/target/atari/AtariMachineDefinition.kt b/codeGenTargets/src/prog8/codegen/target/atari/AtariMachineDefinition.kt index 952f872e0..651493bc1 100644 --- a/codeGenTargets/src/prog8/codegen/target/atari/AtariMachineDefinition.kt +++ b/codeGenTargets/src/prog8/codegen/target/atari/AtariMachineDefinition.kt @@ -12,7 +12,7 @@ class AtariMachineDefinition: IMachineDefinition { override val FLOAT_MAX_POSITIVE = 9.999999999e97 override val FLOAT_MAX_NEGATIVE = -9.999999999e97 override val FLOAT_MEM_SIZE = 6 - override val BASIC_LOAD_ADDRESS = 0x2000u + override val PROGRAM_LOAD_ADDRESS = 0x2000u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override val ESTACK_LO = 0x1a00u // $1a00-$1aff inclusive // TODO @@ -23,7 +23,7 @@ class AtariMachineDefinition: IMachineDefinition { override fun getFloat(num: Number) = TODO("float from number") override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List { - return if (compilerOptions.launcher == LauncherType.CBMBASIC || compilerOptions.output == OutputType.PRG) + return if (compilerOptions.launcher == CbmPrgLauncherType.BASIC || compilerOptions.output == OutputType.PRG) listOf("syslib") else emptyList() diff --git a/codeGenTargets/src/prog8/codegen/target/c128/C128MachineDefinition.kt b/codeGenTargets/src/prog8/codegen/target/c128/C128MachineDefinition.kt index 47e273d5f..06971c770 100644 --- a/codeGenTargets/src/prog8/codegen/target/c128/C128MachineDefinition.kt +++ b/codeGenTargets/src/prog8/codegen/target/c128/C128MachineDefinition.kt @@ -13,7 +13,7 @@ class C128MachineDefinition: IMachineDefinition { override val FLOAT_MAX_POSITIVE = Mflpt5.FLOAT_MAX_POSITIVE override val FLOAT_MAX_NEGATIVE = Mflpt5.FLOAT_MAX_NEGATIVE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE - override val BASIC_LOAD_ADDRESS = 0x1c01u + override val PROGRAM_LOAD_ADDRESS = 0x1c01u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override val ESTACK_LO = 0x1a00u // $1a00-$1aff inclusive @@ -24,7 +24,7 @@ class C128MachineDefinition: IMachineDefinition { override fun getFloat(num: Number) = Mflpt5.fromNumber(num) override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List { - return if (compilerOptions.launcher == LauncherType.CBMBASIC || compilerOptions.output == OutputType.PRG) + return if (compilerOptions.launcher == CbmPrgLauncherType.BASIC || compilerOptions.output == OutputType.PRG) listOf("syslib") else emptyList() diff --git a/codeGenTargets/src/prog8/codegen/target/c64/C64MachineDefinition.kt b/codeGenTargets/src/prog8/codegen/target/c64/C64MachineDefinition.kt index bc9d050d3..2e736f311 100644 --- a/codeGenTargets/src/prog8/codegen/target/c64/C64MachineDefinition.kt +++ b/codeGenTargets/src/prog8/codegen/target/c64/C64MachineDefinition.kt @@ -13,7 +13,7 @@ class C64MachineDefinition: IMachineDefinition { override val FLOAT_MAX_POSITIVE = Mflpt5.FLOAT_MAX_POSITIVE override val FLOAT_MAX_NEGATIVE = Mflpt5.FLOAT_MAX_NEGATIVE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE - override val BASIC_LOAD_ADDRESS = 0x0801u + override val PROGRAM_LOAD_ADDRESS = 0x0801u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override val ESTACK_LO = 0xce00u // $ce00-$ceff inclusive @@ -24,7 +24,7 @@ class C64MachineDefinition: IMachineDefinition { override fun getFloat(num: Number) = Mflpt5.fromNumber(num) override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List { - return if (compilerOptions.launcher == LauncherType.CBMBASIC || compilerOptions.output == OutputType.PRG) + return if (compilerOptions.launcher == CbmPrgLauncherType.BASIC || compilerOptions.output == OutputType.PRG) listOf("syslib") else emptyList() diff --git a/codeGenTargets/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt b/codeGenTargets/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt index 46cedfc7e..693f1b66e 100644 --- a/codeGenTargets/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt +++ b/codeGenTargets/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt @@ -12,7 +12,7 @@ class CX16MachineDefinition: IMachineDefinition { override val FLOAT_MAX_POSITIVE = Mflpt5.FLOAT_MAX_POSITIVE override val FLOAT_MAX_NEGATIVE = Mflpt5.FLOAT_MAX_NEGATIVE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE - override val BASIC_LOAD_ADDRESS = 0x0801u + override val PROGRAM_LOAD_ADDRESS = 0x0801u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override val ESTACK_LO = 0x0400u // $0400-$04ff inclusive @@ -22,7 +22,7 @@ class CX16MachineDefinition: IMachineDefinition { override fun getFloat(num: Number) = Mflpt5.fromNumber(num) override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List { - return if (compilerOptions.launcher == LauncherType.CBMBASIC || compilerOptions.output == OutputType.PRG) + return if (compilerOptions.launcher == CbmPrgLauncherType.BASIC || compilerOptions.output == OutputType.PRG) listOf("syslib") else emptyList() diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index ae6d2e835..a98077266 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -9,7 +9,7 @@ import prog8.codegen.target.Cx16Target import prog8.compiler.CompilationResult import prog8.compiler.CompilerArguments import prog8.compiler.compileProgram -import prog8.compilerinterface.LauncherType +import prog8.compilerinterface.CbmPrgLauncherType import java.io.File import java.nio.file.FileSystems import java.nio.file.Path @@ -169,7 +169,7 @@ private fun compileMain(args: Array): Boolean { val programNameInPath = outputPath.resolve(compilationResult.programName) if(startEmulator1==true || startEmulator2==true) { - if (compilationResult.compilationOptions.launcher != LauncherType.NONE || compilationTarget=="atari") { + if (compilationResult.compilationOptions.launcher != CbmPrgLauncherType.NONE || compilationTarget=="atari") { if (startEmulator1 == true) compilationResult.compilationOptions.compTarget.machine.launchEmulator(1, programNameInPath) else if (startEmulator2 == true) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 424395c23..f4dbaa630 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -153,7 +153,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult { val failedProgram = Program("failed", BuiltinFunctionsFacade(BuiltinFunctions), compTarget, compTarget) val dummyoptions = CompilationOptions( - OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), + OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), floats = false, noSysInit = true, compTarget = compTarget @@ -215,9 +215,9 @@ fun parseImports(filepath: Path, importer.importLibraryModule("math") importer.importLibraryModule("prog8_lib") - if (compilerOptions.launcher == LauncherType.CBMBASIC && compilerOptions.output != OutputType.PRG) + if (compilerOptions.launcher == CbmPrgLauncherType.BASIC && compilerOptions.output != OutputType.PRG) errors.err("BASIC launcher requires output type PRG", program.toplevelModule.position) - if(compilerOptions.launcher == LauncherType.CBMBASIC && compTarget.name==AtariTarget.NAME) + if(compilerOptions.launcher == CbmPrgLauncherType.BASIC && compTarget.name==AtariTarget.NAME) errors.err("atari target cannot use CBM BASIC launcher, use NONE", program.toplevelModule.position) errors.report() @@ -261,7 +261,12 @@ fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget .map { it[0].int!!..it[1].int!! } .toList() - val outputType = if (outputTypeStr == null) OutputType.PRG else { + val outputType = if (outputTypeStr == null) { + if(compTarget is AtariTarget) + OutputType.XEX + else + OutputType.PRG + } else { try { OutputType.valueOf(outputTypeStr) } catch (x: IllegalArgumentException) { @@ -269,12 +274,17 @@ fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget OutputType.PRG } } - val launcherType = if (launcherTypeStr == null) compTarget.defaultLauncherType else { + val launcherType = if (launcherTypeStr == null) { + when(compTarget) { + is AtariTarget -> CbmPrgLauncherType.NONE + else -> CbmPrgLauncherType.BASIC + } + } else { try { - LauncherType.valueOf(launcherTypeStr) + CbmPrgLauncherType.valueOf(launcherTypeStr) } catch (x: IllegalArgumentException) { // set default value; actual check and error handling of invalid option is handled in the AstChecker later - LauncherType.CBMBASIC + CbmPrgLauncherType.BASIC } } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 4599171bf..a8b199cb8 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -20,7 +20,7 @@ import prog8.compiler.astprocessing.VariableExtractor import prog8.compiler.astprocessing.processAstBeforeAsmGeneration import prog8.compiler.printProgram import prog8.compilerinterface.CompilationOptions -import prog8.compilerinterface.LauncherType +import prog8.compilerinterface.CbmPrgLauncherType import prog8.compilerinterface.OutputType import prog8.compilerinterface.ZeropageType import prog8tests.helpers.* @@ -302,7 +302,7 @@ class TestOptimization: FunSpec({ expr.right.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UWORD expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE - val options = CompilationOptions(OutputType.RAW, LauncherType.CBMBASIC, ZeropageType.DONTUSE, emptyList(), false, true, C64Target(), outputDir= outputDir) + val options = CompilationOptions(OutputType.PRG, CbmPrgLauncherType.BASIC, ZeropageType.DONTUSE, emptyList(), false, true, C64Target(), outputDir= outputDir) result.program.processAstBeforeAsmGeneration(options, DummyVarsAndConsts, ErrorReporterForTests()) // assignment is now split into: diff --git a/compiler/test/ZeropageTests.kt b/compiler/test/ZeropageTests.kt index 370f94b13..f8264d98d 100644 --- a/compiler/test/ZeropageTests.kt +++ b/compiler/test/ZeropageTests.kt @@ -43,7 +43,7 @@ class TestAbstractZeropage: FunSpec({ val zp = DummyZeropage( CompilationOptions( OutputType.RAW, - LauncherType.NONE, + CbmPrgLauncherType.NONE, ZeropageType.FULL, listOf((0x50u..0x5fu)), false, @@ -64,7 +64,7 @@ class TestC64Zeropage: FunSpec({ val zpdummyscope = GlobalNamespace(emptyList()) test("testNames") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) var result = zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors) result.onFailure { fail(it.toString()) } @@ -78,33 +78,33 @@ class TestC64Zeropage: FunSpec({ } test("testZpFloatEnable") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) var result = zp.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) result.expectError { "should be allocation error due to disabled floats" } - val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target)) + val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target)) result = zp2.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) result.expectError { "should be allocation error due to disabled ZP use" } - val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target)) + val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target)) zp3.allocate(emptyList(), DataType.FLOAT, zpdummyscope, null, null, null, errors) } test("testZpModesWithFloats") { - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, c64target)) - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, c64target)) - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target)) shouldThrow { - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), true, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), true, false, c64target)) } shouldThrow { - C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), true, false, c64target)) + C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), true, false, c64target)) } } test("testZpDontuse") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target)) println(zp.free) zp.availableBytes() shouldBe 0 val result = zp.allocate(emptyList(), DataType.BYTE, zpdummyscope, null, null, null, errors) @@ -112,13 +112,13 @@ class TestC64Zeropage: FunSpec({ } test("testFreeSpacesBytes") { - val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) + val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) zp1.availableBytes() shouldBe 18 - val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, c64target)) + val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, c64target)) zp2.availableBytes() shouldBe 85 - val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, c64target)) + val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, c64target)) zp3.availableBytes() shouldBe 125 - val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) + val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) zp4.availableBytes() shouldBe 239 zp4.allocate(listOf("test"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp4.availableBytes() shouldBe 238 @@ -127,7 +127,7 @@ class TestC64Zeropage: FunSpec({ } test("testReservedSpace") { - val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) + val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) zp1.availableBytes() shouldBe 239 50u shouldBeIn zp1.free 100u shouldBeIn zp1.free @@ -136,7 +136,7 @@ class TestC64Zeropage: FunSpec({ 200u shouldBeIn zp1.free 255u shouldBeIn zp1.free 199u shouldBeIn zp1.free - val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, listOf(50u .. 100u, 200u..255u), false, false, c64target)) + val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, listOf(50u .. 100u, 200u..255u), false, false, c64target)) zp2.availableBytes() shouldBe 139 50u shouldNotBeIn zp2.free 100u shouldNotBeIn zp2.free @@ -148,7 +148,7 @@ class TestC64Zeropage: FunSpec({ } test("testBasicsafeAllocation") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) zp.availableBytes() shouldBe 18 zp.hasByteAvailable() shouldBe true zp.hasWordAvailable() shouldBe true @@ -170,7 +170,7 @@ class TestC64Zeropage: FunSpec({ } test("testFullAllocation") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target)) zp.availableBytes() shouldBe 239 zp.hasByteAvailable() shouldBe true zp.hasWordAvailable() shouldBe true @@ -201,7 +201,7 @@ class TestC64Zeropage: FunSpec({ } test("testEfficientAllocation") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target)) zp.availableBytes() shouldBe 18 zp.allocate(emptyList(), DataType.WORD, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x04u zp.allocate(emptyList(), DataType.UBYTE, zpdummyscope, null, null, null, errors).getOrElse{throw it}.first shouldBe 0x06u @@ -219,7 +219,7 @@ class TestC64Zeropage: FunSpec({ } test("testReservedLocations") { - val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) + val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, c64target)) withClue("zp _B1 and _REG must be next to each other to create a word") { zp.SCRATCH_B1 + 1u shouldBe zp.SCRATCH_REG } @@ -233,18 +233,18 @@ class TestCx16Zeropage: FunSpec({ val zpdummyscope = GlobalNamespace(emptyList()) test("testReservedLocations") { - val zp = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, cx16target)) + val zp = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, cx16target)) withClue("zp _B1 and _REG must be next to each other to create a word") { zp.SCRATCH_B1 + 1u shouldBe zp.SCRATCH_REG } } test("testFreeSpacesBytes") { - val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, cx16target)) + val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, cx16target)) zp1.availableBytes() shouldBe 88 - val zp2 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, cx16target)) + val zp2 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, cx16target)) zp2.availableBytes() shouldBe 175 - val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) + val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) zp3.availableBytes() shouldBe 216 zp3.allocate(listOf("test"), DataType.UBYTE, zpdummyscope, null, null, null, errors) zp3.availableBytes() shouldBe 215 @@ -253,7 +253,7 @@ class TestCx16Zeropage: FunSpec({ } test("testReservedSpace") { - val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) + val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) zp1.availableBytes() shouldBe 216 0x22u shouldBeIn zp1.free 0x80u shouldBeIn zp1.free @@ -263,7 +263,7 @@ class TestCx16Zeropage: FunSpec({ } test("preallocated zp vars") { - val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) + val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target)) zp1.allocatedVariables[listOf("test")] shouldBe null zp1.allocatedVariables[listOf("cx16", "r0")] shouldNotBe null zp1.allocatedVariables[listOf("cx16", "r15")] shouldNotBe null diff --git a/compiler/test/codegeneration/TestAsmGenSymbols.kt b/compiler/test/codegeneration/TestAsmGenSymbols.kt index 27c6dbcd1..b4e27cf45 100644 --- a/compiler/test/codegeneration/TestAsmGenSymbols.kt +++ b/compiler/test/codegeneration/TestAsmGenSymbols.kt @@ -100,7 +100,7 @@ class TestAsmGenSymbols: StringSpec({ fun createTestAsmGen(program: Program, allocation: IVariablesAndConsts): AsmGen { val errors = ErrorReporterForTests() - val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target()) + val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target()) options.compTarget.machine.zeropage = C64Zeropage(options) return AsmGen(program, errors, allocation, options) } diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt index 0104632e1..40a84997c 100644 --- a/compiler/test/helpers/Dummies.kt +++ b/compiler/test/helpers/Dummies.kt @@ -53,7 +53,6 @@ internal object DummyCompilationTarget : ICompilationTarget { get() = throw NotImplementedError("dummy") override val supportedEncodings = setOf(Encoding.PETSCII, Encoding.SCREENCODES, Encoding.ISO) override val defaultEncoding = Encoding.PETSCII - override val defaultLauncherType = LauncherType.NONE override fun encodeString(str: String, encoding: Encoding): List { throw NotImplementedError("dummy") diff --git a/compiler/test/helpers/compileXyz.kt b/compiler/test/helpers/compileXyz.kt index e7e7ea08b..c561596d4 100644 --- a/compiler/test/helpers/compileXyz.kt +++ b/compiler/test/helpers/compileXyz.kt @@ -86,7 +86,7 @@ internal fun generateAssembly( variables: IVariablesAndConsts, options: CompilationOptions? = null ): IAssemblyProgram? { - val coptions = options ?: CompilationOptions(OutputType.RAW, LauncherType.CBMBASIC, ZeropageType.DONTUSE, emptyList(), true, true, C64Target(), outputDir = outputDir) + val coptions = options ?: CompilationOptions(OutputType.RAW, CbmPrgLauncherType.BASIC, ZeropageType.DONTUSE, emptyList(), true, true, C64Target(), outputDir = outputDir) coptions.compTarget.machine.zeropage = C64Zeropage(coptions) val asmgen = AsmGen(program, ErrorReporterForTests(), variables, coptions) return asmgen.compileToAssembly() diff --git a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt index 8bfe6a745..443c63376 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt @@ -5,11 +5,12 @@ import kotlin.io.path.Path enum class OutputType { RAW, - PRG + PRG, + XEX } -enum class LauncherType { - CBMBASIC, +enum class CbmPrgLauncherType { + BASIC, NONE } @@ -22,7 +23,7 @@ enum class ZeropageType { } class CompilationOptions(val output: OutputType, - val launcher: LauncherType, + val launcher: CbmPrgLauncherType, val zeropage: ZeropageType, val zpReserved: List, val floats: Boolean, diff --git a/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt b/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt index de5bd6032..dba83a876 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt @@ -10,7 +10,6 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { val machine: IMachineDefinition val supportedEncodings: Set val defaultEncoding: Encoding - val defaultLauncherType: LauncherType override fun encodeString(str: String, encoding: Encoding): List override fun decodeString(bytes: List, encoding: Encoding): String diff --git a/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt b/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt index 75459eb99..ac0018340 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt @@ -19,7 +19,7 @@ interface IMachineDefinition { val FLOAT_MEM_SIZE: Int val ESTACK_LO: UInt val ESTACK_HI: UInt - val BASIC_LOAD_ADDRESS : UInt + val PROGRAM_LOAD_ADDRESS : UInt val opcodeNames: Set var zeropage: Zeropage diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 1a8e38e21..bd1368383 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -23,7 +23,6 @@ Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ Compiler: -- (due to the new atari target:) rework "launcher" option to a better name, include "XEX", and automatically set load address to $2000 in this case so %address can be omitted for atari programs too - writeAssembly(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there. - make everything an expression? (get rid of Statements. Statements are expressions with void return types?). - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type diff --git a/examples/atari/fibonacci.p8 b/examples/atari/fibonacci.p8 index 9131f9463..6dc9edaf4 100644 --- a/examples/atari/fibonacci.p8 +++ b/examples/atari/fibonacci.p8 @@ -1,6 +1,5 @@ %import textio %zeropage basicsafe -%address $2000 ; This example computes the first 20 values of the Fibonacci sequence. ; Note: this program is compatible with atari. diff --git a/examples/test.p8 b/examples/test.p8 index d9adbc58e..9a89082f0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,5 +1,4 @@ %import textio -%address $2000 main { sub start() {