Skip to content

Commit

Permalink
merge IMachineDefinition into ICompilationTarget
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Jan 13, 2025
1 parent 4f096a7 commit 09a1774
Show file tree
Hide file tree
Showing 56 changed files with 685 additions and 791 deletions.
8 changes: 4 additions & 4 deletions codeCore/src/prog8/code/SymbolTableMaker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp

if(options.compTarget.name != VMTarget.NAME) {
listOf(
PtMemMapped("P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE), options.compTarget.machine.zeropage.SCRATCH_B1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_REG", DataType.forDt(BaseDataType.UBYTE), options.compTarget.machine.zeropage.SCRATCH_REG, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UWORD), options.compTarget.machine.zeropage.SCRATCH_W1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD), options.compTarget.machine.zeropage.SCRATCH_W2, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE), options.compTarget.zeropage.SCRATCH_B1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_REG", DataType.forDt(BaseDataType.UBYTE), options.compTarget.zeropage.SCRATCH_REG, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UWORD), options.compTarget.zeropage.SCRATCH_W1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD), options.compTarget.zeropage.SCRATCH_W2, null, Position.DUMMY),
).forEach {
it.parent = program
st.add(StMemVar(it.name, it.type, it.address, it.arraySize?.toInt(), it))
Expand Down
2 changes: 1 addition & 1 deletion codeCore/src/prog8/code/core/CompilationOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CompilationOptions(val output: OutputType,
var symbolDefs: Map<String, String> = emptyMap()
) {
init {
compTarget.machine.initializeMemoryAreas(this)
compTarget.initializeMemoryAreas(this)
}

companion object {
Expand Down
33 changes: 32 additions & 1 deletion codeCore/src/prog8/code/core/ICompilationTarget.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
package prog8.code.core

import java.nio.file.Path

enum class CpuType {
CPU6502,
CPU65c02,
VIRTUAL
}

interface ICompilationTarget: IStringEncoding, IMemSizer {
val name: String
val machine: IMachineDefinition

val FLOAT_MAX_NEGATIVE: Double
val FLOAT_MAX_POSITIVE: Double
val FLOAT_MEM_SIZE: Int
val STARTUP_CODE_RESERVED_SIZE: UInt // this is here, so that certain compiler targets are able to tune this
val PROGRAM_LOAD_ADDRESS : UInt
val PROGRAM_MEMTOP_ADDRESS: UInt
val BSSHIGHRAM_START: UInt
val BSSHIGHRAM_END: UInt
val BSSGOLDENRAM_START: UInt
val BSSGOLDENRAM_END: UInt

val cpu: CpuType
var zeropage: Zeropage
var golden: GoldenRam

fun initializeMemoryAreas(compilerOptions: CompilationOptions)
fun getFloatAsmBytes(num: Number): String

fun convertFloatToBytes(num: Double): List<UByte>
fun convertBytesToFloat(bytes: List<UByte>): Double

fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path)
fun isIOAddress(address: UInt): Boolean

override fun encodeString(str: String, encoding: Encoding): List<UByte>
override fun decodeString(bytes: Iterable<UByte>, encoding: Encoding): String
Expand Down
36 changes: 0 additions & 36 deletions codeCore/src/prog8/code/core/IMachineDefinition.kt

This file was deleted.

78 changes: 55 additions & 23 deletions codeCore/src/prog8/code/target/AtariTarget.kt
Original file line number Diff line number Diff line change
@@ -1,40 +1,72 @@
package prog8.code.target

import prog8.code.core.*
import prog8.code.target.atari.AtariMachineDefinition
import prog8.code.target.encodings.Encoder
import prog8.code.target.zp.AtariZeropage
import java.nio.file.Path


class AtariTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer {

class AtariTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by NormalMemSizer(FLOAT_MEM_SIZE) {
override val name = NAME
override val machine = AtariMachineDefinition()
override val defaultEncoding = Encoding.ATASCII

companion object {
const val NAME = "atari"
const val FLOAT_MEM_SIZE = 6
}

override fun memorySize(dt: DataType, numElements: Int?): Int {
if(dt.isArray) {
if(numElements==null) return 2 // treat it as a pointer size
return when(dt.sub) {
BaseDataType.BOOL, BaseDataType.UBYTE, BaseDataType.BYTE -> numElements
BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.STR -> numElements * 2
BaseDataType.FLOAT-> numElements * machine.FLOAT_MEM_SIZE
BaseDataType.UNDEFINED -> throw IllegalArgumentException("undefined has no memory size")
else -> throw IllegalArgumentException("invalid sub type")
override val cpu = CpuType.CPU6502

override val FLOAT_MAX_POSITIVE = 9.999999999e97
override val FLOAT_MAX_NEGATIVE = -9.999999999e97
override val FLOAT_MEM_SIZE = AtariTarget.FLOAT_MEM_SIZE
override val STARTUP_CODE_RESERVED_SIZE = 20u
override val PROGRAM_LOAD_ADDRESS = 0x2000u
override val PROGRAM_MEMTOP_ADDRESS = 0xffffu // TODO what's memtop?

override val BSSHIGHRAM_START = 0u // TODO
override val BSSHIGHRAM_END = 0u // TODO
override val BSSGOLDENRAM_START = 0u // TODO
override val BSSGOLDENRAM_END = 0u // TODO

override lateinit var zeropage: Zeropage
override lateinit var golden: GoldenRam

override fun getFloatAsmBytes(num: Number) = TODO("atari float asm bytes from number")
override fun convertFloatToBytes(num: Double): List<UByte> = TODO("atari float to bytes")
override fun convertBytesToFloat(bytes: List<UByte>): Double = TODO("atari bytes to float")

override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
val emulatorName: String
val cmdline: List<String>
when(selectedEmulator) {
1 -> {
emulatorName = "atari800"
cmdline = listOf(emulatorName, "-xl", "-xl-rev", "2", "-nobasic", "-run", "${programNameWithPath}.xex")
}
2 -> {
emulatorName = "altirra"
cmdline = listOf("Altirra64.exe", "${programNameWithPath.normalize()}.xex")
}
else -> {
System.err.println("Atari target only supports atari800 and altirra emulators.")
return
}
}
else if (dt.isString) {
if(numElements!=null) return numElements // treat it as the size of the given string with the length
else return 2 // treat it as the size to store a string pointer
}

return when {
dt.isByteOrBool -> 1 * (numElements ?: 1)
dt.isFloat -> machine.FLOAT_MEM_SIZE * (numElements ?: 1)
dt.isLong -> throw IllegalArgumentException("long can not yet be put into memory")
dt.isUndefined -> throw IllegalArgumentException("undefined has no memory size")
else -> 2 * (numElements ?: 1)
}
// TODO monlist?

println("\nStarting Atari800XL emulator $emulatorName...")
val processb = ProcessBuilder(cmdline).inheritIO()
val process: Process = processb.start()
process.waitFor()
}

override fun isIOAddress(address: UInt): Boolean = address==0u || address==1u || address in 0xd000u..0xdfffu // TODO

override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
zeropage = AtariZeropage(compilerOptions)
golden = GoldenRam(compilerOptions, UIntRange.EMPTY)
}
}
66 changes: 62 additions & 4 deletions codeCore/src/prog8/code/target/C128Target.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,77 @@
package prog8.code.target

import prog8.code.core.CompilationOptions
import prog8.code.core.CpuType
import prog8.code.core.Encoding
import prog8.code.core.GoldenRam
import prog8.code.core.ICompilationTarget
import prog8.code.core.IMemSizer
import prog8.code.core.IStringEncoding
import prog8.code.target.c128.C128MachineDefinition
import prog8.code.target.cbm.CbmMemorySizer
import prog8.code.core.Zeropage
import prog8.code.target.zp.C128Zeropage
import prog8.code.target.encodings.Encoder
import java.nio.file.Path


class C128Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by CbmMemorySizer {
class C128Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by NormalMemSizer(Mflpt5.FLOAT_MEM_SIZE) {
override val name = NAME
override val machine = C128MachineDefinition()
override val defaultEncoding = Encoding.PETSCII

companion object {
const val NAME = "c128"
}


override val cpu = CpuType.CPU6502

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 STARTUP_CODE_RESERVED_SIZE = 20u
override val PROGRAM_LOAD_ADDRESS = 0x1c01u
override val PROGRAM_MEMTOP_ADDRESS = 0xc000u

override val BSSHIGHRAM_START = 0u // TODO
override val BSSHIGHRAM_END = 0u // TODO
override val BSSGOLDENRAM_START = 0u // TODO
override val BSSGOLDENRAM_END = 0u // TODO

override lateinit var zeropage: Zeropage
override lateinit var golden: GoldenRam

override fun getFloatAsmBytes(num: Number) = Mflpt5.fromNumber(num).makeFloatFillAsm()

override fun convertFloatToBytes(num: Double): List<UByte> {
val m5 = Mflpt5.fromNumber(num)
return listOf(m5.b0, m5.b1, m5.b2, m5.b3, m5.b4)
}

override fun convertBytesToFloat(bytes: List<UByte>): Double {
require(bytes.size==5) { "need 5 bytes" }
val m5 = Mflpt5(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4])
return m5.toDouble()
}

override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
if(selectedEmulator!=1) {
System.err.println("The c128 target only supports the main emulator (Vice).")
return
}

println("\nStarting C-128 emulator x128...")
val viceMonlist = C64Target.viceMonListName(programNameWithPath.toString())
val cmdline = listOf("x128", "-silent", "-moncommands", viceMonlist,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg")
val processb = ProcessBuilder(cmdline).inheritIO()
val process: Process = processb.start()
process.waitFor()
}

override fun isIOAddress(address: UInt): Boolean = address==0u || address==1u || address in 0xd000u..0xdfffu

override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
zeropage = C128Zeropage(compilerOptions)
golden = GoldenRam(compilerOptions, UIntRange.EMPTY) // TODO does the c128 have some of this somewhere?
}

}
76 changes: 72 additions & 4 deletions codeCore/src/prog8/code/target/C64Target.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,91 @@
package prog8.code.target

import prog8.code.core.CompilationOptions
import prog8.code.core.CpuType
import prog8.code.core.Encoding
import prog8.code.core.GoldenRam
import prog8.code.core.ICompilationTarget
import prog8.code.core.IMemSizer
import prog8.code.core.IStringEncoding
import prog8.code.target.c64.C64MachineDefinition
import prog8.code.target.cbm.CbmMemorySizer
import prog8.code.core.Zeropage
import prog8.code.target.zp.C64Zeropage
import prog8.code.target.encodings.Encoder
import java.io.IOException
import java.nio.file.Path


class C64Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by CbmMemorySizer {
class C64Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by NormalMemSizer(Mflpt5.Companion.FLOAT_MEM_SIZE) {
override val name = NAME
override val machine = C64MachineDefinition()
override val defaultEncoding = Encoding.PETSCII

companion object {
const val NAME = "c64"

fun viceMonListName(baseFilename: String) = "$baseFilename.vice-mon-list"
}


override val cpu = CpuType.CPU6502

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 STARTUP_CODE_RESERVED_SIZE = 20u
override val PROGRAM_LOAD_ADDRESS = 0x0801u
override val PROGRAM_MEMTOP_ADDRESS = 0xcfe0u // $a000 if floats are used
// note that at $cfe0-$cfff are the 16 'virtual registers' R0-R15

override val BSSHIGHRAM_START = 0xc000u
override val BSSHIGHRAM_END = 0xcfdfu
override val BSSGOLDENRAM_START = 0u
override val BSSGOLDENRAM_END = 0u

override lateinit var zeropage: Zeropage
override lateinit var golden: GoldenRam

override fun getFloatAsmBytes(num: Number) = Mflpt5.fromNumber(num).makeFloatFillAsm()

override fun convertFloatToBytes(num: Double): List<UByte> {
val m5 = Mflpt5.fromNumber(num)
return listOf(m5.b0, m5.b1, m5.b2, m5.b3, m5.b4)
}

override fun convertBytesToFloat(bytes: List<UByte>): Double {
require(bytes.size==5) { "need 5 bytes" }
val m5 = Mflpt5(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4])
return m5.toDouble()
}

override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
if(selectedEmulator!=1) {
System.err.println("The c64 target only supports the main emulator (Vice).")
return
}

for(emulator in listOf("x64sc", "x64")) {
println("\nStarting C-64 emulator $emulator...")
val viceMonlist = viceMonListName(programNameWithPath.toString())
val cmdline = listOf(emulator, "-silent", "-moncommands", viceMonlist,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg")
val processb = ProcessBuilder(cmdline).inheritIO()
val process: Process
try {
process=processb.start()
} catch(_: IOException) {
continue // try the next emulator executable
}
process.waitFor()
break
}
}

override fun isIOAddress(address: UInt): Boolean = address==0u || address==1u || address in 0xd000u..0xdfffu

override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
zeropage = C64Zeropage(compilerOptions)
golden = GoldenRam(compilerOptions, 0xc000u until 0xd000u)
}

}


Expand Down
Loading

0 comments on commit 09a1774

Please sign in to comment.