Skip to content

Commit

Permalink
Merge branch 'master' into next_compositetypes
Browse files Browse the repository at this point in the history
# Conflicts:
#	codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt
#	compilerAst/src/prog8/ast/expressions/AstExpressions.kt
  • Loading branch information
irmen committed Nov 6, 2024
2 parents b14012c + 77e376f commit 4152f7e
Show file tree
Hide file tree
Showing 62 changed files with 1,638 additions and 1,349 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ What does Prog8 provide?
- inline assembly allows you to have full control when every cycle or byte matters
- supports the sixteen 'virtual' 16-bit registers R0 - R15 from the Commander X16 (also available on other targets)
- encode strings and characters into petscii or screencodes or even other encodings
- Automatic ROM/RAM bank switching on certain compiler targets when calling routines in other banks
- 50 Kb of available program RAM size on the C64 by default; because Basic ROM is banked out altogether

*Rapid edit-compile-run-debug cycle:*

Expand Down
3 changes: 2 additions & 1 deletion codeCore/src/prog8/code/SymbolTable.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package prog8.code

import prog8.code.ast.PtAsmSub
import prog8.code.ast.PtNode
import prog8.code.ast.PtProgram
import prog8.code.core.*
Expand Down Expand Up @@ -257,7 +258,7 @@ class StSub(name: String, val parameters: List<StSubroutineParameter>, val retur


class StRomSub(name: String,
val address: UInt?, // null in case of asmsub, specified in case of romsub
val address: PtAsmSub.Address?, // null in case of asmsub, specified in case of romsub.
val parameters: List<StRomSubParameter>,
val returns: List<StRomSubParameter>,
astNode: PtNode) :
Expand Down
7 changes: 5 additions & 2 deletions codeCore/src/prog8/code/ast/AstPrinter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,13 @@ fun printAst(root: PtNode, skipLibraries: Boolean, output: (text: String) -> Uni
}"
}
val str = if (node.inline) "inline " else ""
if(node.address==null) {
if(node.address == null) {
str + "asmsub ${node.name}($params) $clobbers $returns"
} else {
str + "romsub ${node.address.toHex()} = ${node.name}($params) $clobbers $returns"
val bank = if(node.address.constbank!=null) "@bank ${node.address.constbank}"
else if(node.address.varbank!=null) "@bank ${node.address.varbank?.name}"
else ""
str + "romsub $bank ${node.address.address.toHex()} = ${node.name}($params) $clobbers $returns"
}
}
is PtBlock -> {
Expand Down
7 changes: 5 additions & 2 deletions codeCore/src/prog8/code/ast/AstStatements.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ sealed interface IPtSubroutine {

class PtAsmSub(
name: String,
val address: UInt?,
val address: Address?,
val clobbers: Set<CpuRegister>,
val parameters: List<Pair<RegisterOrStatusflag, PtSubroutineParameter>>,
val returns: List<Pair<RegisterOrStatusflag, DataType>>,
val inline: Boolean,
position: Position
) : PtNamedNode(name, position), IPtSubroutine
) : PtNamedNode(name, position), IPtSubroutine {

class Address(val constbank: UByte?, var varbank: PtIdentifier?, val address: UInt)
}


class PtSub(
Expand Down
3 changes: 2 additions & 1 deletion codeCore/src/prog8/code/target/c64/C64MachineDefinition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class C64MachineDefinition: IMachineDefinition {
override val FLOAT_MAX_NEGATIVE = Mflpt5.FLOAT_MAX_NEGATIVE
override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE
override val PROGRAM_LOAD_ADDRESS = 0x0801u
override val PROGRAM_TOP_ADDRESS = 0xbfffu
override val PROGRAM_TOP_ADDRESS = 0xcfe0u // $9fff 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 = 0xcfffu
Expand Down
3 changes: 3 additions & 0 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
is PtAsmSub -> {
prefixNamedNode(node)
node.parameters.forEach { (_, param) -> prefixNamedNode(param) }
if(node.address?.varbank!=null) {
node.address!!.varbank = node.address!!.varbank!!.prefix(node, st)
}
}
is PtSub -> {
prefixNamedNode(node)
Expand Down
30 changes: 22 additions & 8 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,22 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}

private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
if(asmgen.options.compTarget.name != "cx16")
throw AssemblyError("callfar only works on cx16 target at this time")
val targetName = asmgen.options.compTarget.name
if(targetName !in arrayOf("cx16", "c64", "c128"))
throw AssemblyError("callfar only works on cx16, c64 and c128 targets at this time")

val jsrfar = when(targetName) {
"cx16" -> "cx16.JSRFAR"
"c64" -> "c64.x16jsrfar"
"c128" -> "c128.x16jsrfar"
else -> TODO("jsrfar routine")
}
val constBank = fcall.args[0].asConstInteger()
val constAddress = fcall.args[1].asConstInteger()
if(constBank!=null && constAddress!=null) {
asmgen.assignExpressionToRegister(fcall.args[2], RegisterOrPair.AY) // uword argument
asmgen.out("""
jsr cx16.JSRFAR
jsr $jsrfar
.word ${constAddress.toHex()}
.byte $constBank""")
} else {
Expand All @@ -226,7 +233,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.out(" sta (+)+0 | sty (+)+1")
asmgen.assignExpressionToRegister(fcall.args[2], RegisterOrPair.AY) // uword argument
asmgen.out("""
jsr cx16.JSRFAR
jsr $jsrfar
+ .word 0
+ .byte 0""")
}
Expand All @@ -238,8 +245,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}

private fun funcCallFar2(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
if(asmgen.options.compTarget.name != "cx16")
throw AssemblyError("callfar2 only works on cx16 target at this time")
val targetName = asmgen.options.compTarget.name
if(targetName !in arrayOf("cx16", "c64", "c128"))
throw AssemblyError("callfar2 only works on cx16, c64 and c128 targets at this time")

fun assignArgs() {
fun assign(value: PtExpression, register: Char) {
Expand All @@ -260,12 +268,18 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
TODO("callfar2: support non-const argument values")
}

val jsrfar = when(targetName) {
"cx16" -> "cx16.JSRFAR"
"c64" -> "c64.x16jsrfar"
"c128" -> "c128.x16jsrfar"
else -> TODO("jsrfar routine")
}
val constBank = fcall.args[0].asConstInteger()
val constAddress = fcall.args[1].asConstInteger()
if(constBank!=null && constAddress!=null) {
assignArgs()
asmgen.out("""
jsr cx16.JSRFAR
jsr $jsrfar
.word ${constAddress.toHex()}
.byte $constBank""")
} else {
Expand All @@ -275,7 +289,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.out(" sta (+)+0 | sty (+)+1")
assignArgs()
asmgen.out("""
jsr cx16.JSRFAR
jsr $jsrfar
+ .word 0
+ .byte 0""")
}
Expand Down
79 changes: 78 additions & 1 deletion codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,84 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
sub.children.forEach { asmgen.translate(it as PtInlineAssembly) }
asmgen.out(" \t; inlined routine end: ${sub.name}")
} else {
asmgen.out(" jsr $subAsmName")
val bank = sub.address?.constbank?.toString()
if(bank==null) {
val varbank = if(sub.address?.varbank==null) null else asmgen.asmVariableName(sub.address!!.varbank!!)
if(varbank!=null) {
when(asmgen.options.compTarget.name) {
"cx16" -> {
// JSRFAR can jump to a banked RAM address as well!
asmgen.out("""
php
pha
lda $varbank
sta +
pla
plp
jsr cx16.JSRFAR
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
}
"c64" -> {
asmgen.out("""
php
pha
lda $varbank
sta +
pla
plp
jsr c64.x16jsrfar
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
}
"c128" -> {
asmgen.out("""
php
pha
lda $varbank
sta +
pla
plp
jsr c128.x16jsrfar
.word $subAsmName ; ${sub.address!!.address.toHex()}
+ .byte 0 ; modified"""
)
}
else -> throw AssemblyError("callfar is not supported on the selected compilation target")
}
} else {
asmgen.out(" jsr $subAsmName")
}
}
else {
when(asmgen.options.compTarget.name) {
"cx16" -> {
// JSRFAR can jump to a banked RAM address as well!
asmgen.out("""
jsr cx16.JSRFAR
.word $subAsmName ; ${sub.address!!.address.toHex()}
.byte $bank"""
)
}
"c64" -> {
asmgen.out("""
jsr c64.x16jsrfar
.word $subAsmName ; ${sub.address!!.address.toHex()}
.byte $bank"""
)
}
"c128" -> {
asmgen.out("""
jsr c128.x16jsrfar
.word $subAsmName ; ${sub.address!!.address.toHex()}
.byte $bank"""
)
}
else -> throw AssemblyError("callfar is not supported on the selected compilation target")
}
}
}
}
else if(sub is PtSub) {
Expand Down
Loading

0 comments on commit 4152f7e

Please sign in to comment.