mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
tweak
This commit is contained in:
parent
f7dd388954
commit
9ca6860ffa
@ -65,7 +65,7 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("; assembler syntax is for the 64tasm cross-assembler")
|
||||
asmgen.out("; output options: output=${options.output} launcher=${options.launcher} zp=${options.zeropage}")
|
||||
asmgen.out("")
|
||||
asmgen.out(".cpu '$cpu'\n.enc 'none'\n")
|
||||
asmgen.out(".cpu '$cpu'\n.enc 'none'")
|
||||
|
||||
// the global prog8 variables needed
|
||||
val zp = zeropage
|
||||
@ -88,7 +88,7 @@ internal class ProgramAndVarsGen(
|
||||
when(options.output) {
|
||||
OutputType.RAW -> {
|
||||
asmgen.out("; ---- raw assembler program ----")
|
||||
asmgen.out("* = ${options.loadAddress.toHex()}\n")
|
||||
asmgen.out("* = ${options.loadAddress.toHex()}")
|
||||
}
|
||||
OutputType.PRG -> {
|
||||
when(options.launcher) {
|
||||
@ -102,14 +102,14 @@ internal class ProgramAndVarsGen(
|
||||
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")
|
||||
asmgen.out("prog8_entrypoint\t; assembly code starts here")
|
||||
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("* = ${options.loadAddress.toHex()}\n")
|
||||
asmgen.out("* = ${options.loadAddress.toHex()}")
|
||||
if(!options.noSysInit)
|
||||
asmgen.out(" jsr ${compTarget.name}.init_system")
|
||||
asmgen.out(" jsr ${compTarget.name}.init_system_phase2")
|
||||
@ -118,7 +118,7 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
OutputType.XEX -> {
|
||||
asmgen.out("; ---- atari xex program ----")
|
||||
asmgen.out("* = ${options.loadAddress.toHex()}\n")
|
||||
asmgen.out("* = ${options.loadAddress.toHex()}")
|
||||
if(!options.noSysInit)
|
||||
asmgen.out(" jsr ${compTarget.name}.init_system")
|
||||
asmgen.out(" jsr ${compTarget.name}.init_system_phase2")
|
||||
@ -189,7 +189,7 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("\t.align $100")
|
||||
}
|
||||
|
||||
asmgen.out("${block.name}\t" + (if(block.forceOutput) ".block\n" else ".proc\n"))
|
||||
asmgen.out("${block.name}\t" + (if(block.forceOutput) ".block" else ".proc"))
|
||||
asmgen.outputSourceLine(block)
|
||||
|
||||
createBlockVariables(block)
|
||||
@ -204,13 +204,13 @@ internal class ProgramAndVarsGen(
|
||||
if(!options.dontReinitGlobals) {
|
||||
// generate subroutine to initialize block-level (global) variables
|
||||
if (initializers.isNotEmpty()) {
|
||||
asmgen.out("prog8_init_vars\t.block\n")
|
||||
asmgen.out("prog8_init_vars\t.block")
|
||||
initializers.forEach { assign -> asmgen.translate(assign) }
|
||||
asmgen.out(" rts\n .bend")
|
||||
}
|
||||
}
|
||||
|
||||
asmgen.out(if(block.forceOutput) "\n\t.bend\n" else "\n\t.pend\n")
|
||||
asmgen.out(if(block.forceOutput) "\n\t.bend" else "\n\t.pend")
|
||||
}
|
||||
|
||||
private fun getVars(scope: StNode): Map<String, StNode> =
|
||||
@ -266,7 +266,7 @@ internal class ProgramAndVarsGen(
|
||||
// asmsub with most likely just an inline asm in it
|
||||
asmgen.out("${sub.name}\t$asmStartScope")
|
||||
sub.children.forEach { asmgen.translate(it) }
|
||||
asmgen.out(" $asmEndScope\n")
|
||||
asmgen.out(" $asmEndScope")
|
||||
}
|
||||
|
||||
|
||||
@ -358,7 +358,7 @@ internal class ProgramAndVarsGen(
|
||||
.map { it.value as StStaticVariable }
|
||||
nonZpVariables2asm(variables)
|
||||
|
||||
asmgen.out(" $asmEndScope\n")
|
||||
asmgen.out(" $asmEndScope")
|
||||
}
|
||||
|
||||
private fun entrypointInitialization() {
|
||||
|
@ -19,10 +19,10 @@ class TestLaunchEmu: FunSpec({
|
||||
<ASMSYMBOLS>
|
||||
</ASMSYMBOLS>
|
||||
|
||||
<BSS>
|
||||
</BSS>
|
||||
<VARIABLES>
|
||||
</VARIABLES>
|
||||
<VARIABLESNOINIT>
|
||||
</VARIABLESNOINIT>
|
||||
<VARIABLESWITHINIT>
|
||||
</VARIABLESWITHINIT>
|
||||
|
||||
<MEMORYMAPPEDVARIABLES>
|
||||
</MEMORYMAPPEDVARIABLES>
|
||||
|
@ -14,7 +14,7 @@ import prog8.code.core.Position
|
||||
import prog8.code.target.C64Target
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
class TestVarious: FunSpec({
|
||||
class TestVariousCompilerAst: FunSpec({
|
||||
test("symbol names in inline assembly blocks") {
|
||||
val names1 = InlineAssembly("""
|
||||
|
@ -13,7 +13,7 @@ import prog8.code.core.DataType
|
||||
import prog8.code.target.C64Target
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
class TestVarious: FunSpec({
|
||||
class TestVariousCodeGen: FunSpec({
|
||||
test("bool to byte cast in expression is correct") {
|
||||
val text="""
|
||||
main {
|
@ -3,10 +3,17 @@ TODO
|
||||
|
||||
For next minor release
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
- fix hasInitValue() and isBssVar()
|
||||
- BSS.
|
||||
64tass can put variables into a section with .section BSS <variable> .send BSS
|
||||
and then putting .dsection BSS where it should output the BSS
|
||||
Define vars in BSS with .fill rather than .byte otherwise they STILL take up space!
|
||||
|
||||
- BSS in 6502 codegen: create BSS section in output assembly code and put StStaticVariables in there with bss=true.
|
||||
Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE if possible.
|
||||
Note that bss can still contain variables that have @zp tag and those are already dealt with differently
|
||||
- BSS: subroutine parameters don't have to be set to 0.
|
||||
Note that 'bss' can still be true for variables that were moved into zeropage, so have to check that!
|
||||
- BSS subroutine parameters don't have to be set to 0.
|
||||
- when putting BSS in specific memory block ($a000-$bfff, $c000-$cfff) add a .cerror check for overflow!
|
||||
|
||||
...
|
||||
|
||||
|
104
examples/test.p8
104
examples/test.p8
@ -1,13 +1,107 @@
|
||||
%import floats
|
||||
%import textio
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
|
||||
&ubyte[40] topline = $0400
|
||||
uword b_wordvar
|
||||
ubyte b_bb =123
|
||||
float b_fl
|
||||
ubyte[10] b_emptyarray
|
||||
ubyte[10] b_filledarray = [1,2,3,4,5,6,7,8,9,10]
|
||||
float[3] b_floatarray
|
||||
uword[3] b_wordarray
|
||||
|
||||
sub start() {
|
||||
topline[0] = 'a'
|
||||
topline[1] = 'b'
|
||||
topline[2] = 'd'
|
||||
topline[39] = '@'
|
||||
uword wordvar
|
||||
float fl
|
||||
ubyte bb =123
|
||||
ubyte[10] emptyarray
|
||||
ubyte[10] filledarray = [1,2,3,4,5,6,7,8,9,10]
|
||||
float[3] floatarray
|
||||
uword[3] wordarray
|
||||
|
||||
txt.print("**subroutine scope**\n")
|
||||
txt.print("uninit wordvar=")
|
||||
txt.print_uw(wordvar)
|
||||
txt.print("\nuninit float=")
|
||||
floats.print_f(fl)
|
||||
txt.print("\ninit bb=")
|
||||
txt.print_ub(bb)
|
||||
txt.print("\nuninit emptyarray[2]=")
|
||||
txt.print_ub(emptyarray[2])
|
||||
txt.print("\nuninit wordarray[2]=")
|
||||
txt.print_uw(wordarray[2])
|
||||
txt.print("\nuninit floatarray[2]=")
|
||||
floats.print_f(floatarray[2])
|
||||
txt.print("\ninit filledarray[2]=")
|
||||
txt.print_ub(filledarray[2])
|
||||
|
||||
txt.print("\n**block scope**\n")
|
||||
txt.print("uninit b_wordvar=")
|
||||
txt.print_uw(b_wordvar)
|
||||
txt.print("\nuninit b_float=")
|
||||
floats.print_f(b_fl)
|
||||
txt.print("\ninit b_bb=")
|
||||
txt.print_ub(b_bb)
|
||||
txt.print("\nuninit b_emptyarray[2]=")
|
||||
txt.print_ub(b_emptyarray[2])
|
||||
txt.print("\nuninit b_wordarray[2]=")
|
||||
txt.print_uw(b_wordarray[2])
|
||||
txt.print("\nuninit b_floatarray[2]=")
|
||||
floats.print_f(b_floatarray[2])
|
||||
txt.print("\ninit b_filledarray[2]=")
|
||||
txt.print_ub(b_filledarray[2])
|
||||
|
||||
txt.print("\n\nadding 42 to all values.\n")
|
||||
wordvar += 42
|
||||
bb += 42
|
||||
fl += 42.42
|
||||
floatarray[2] += 42.42
|
||||
wordarray[2] += 42
|
||||
emptyarray[2] += 42
|
||||
filledarray[2] += 42
|
||||
b_wordvar += 42
|
||||
b_bb += 42
|
||||
b_fl += 42.42
|
||||
b_floatarray[2] += 42.42
|
||||
b_wordarray[2] += 42
|
||||
b_emptyarray[2] += 42
|
||||
b_filledarray[2] += 42
|
||||
|
||||
txt.print("\n**subroutine scope**\n")
|
||||
txt.print("uninit wordvar=")
|
||||
txt.print_uw(wordvar)
|
||||
txt.print("\nuninit float=")
|
||||
floats.print_f(fl)
|
||||
txt.print("\ninit bb=")
|
||||
txt.print_ub(bb)
|
||||
txt.print("\nuninit emptyarray[2]=")
|
||||
txt.print_ub(emptyarray[2])
|
||||
txt.print("\nuninit wordarray[2]=")
|
||||
txt.print_uw(wordarray[2])
|
||||
txt.print("\nuninit floatarray[2]=")
|
||||
floats.print_f(floatarray[2])
|
||||
txt.print("\ninit filledarray[2]=")
|
||||
txt.print_ub(filledarray[2])
|
||||
|
||||
txt.print("\n**block scope**\n")
|
||||
txt.print("uninit b_wordvar=")
|
||||
txt.print_uw(b_wordvar)
|
||||
txt.print("\nuninit b_float=")
|
||||
floats.print_f(b_fl)
|
||||
txt.print("\ninit b_bb=")
|
||||
txt.print_ub(b_bb)
|
||||
txt.print("\nuninit b_emptyarray[2]=")
|
||||
txt.print_ub(b_emptyarray[2])
|
||||
txt.print("\nuninit b_wordarray[2]=")
|
||||
txt.print_uw(b_wordarray[2])
|
||||
txt.print("\nuninit b_floatarray[2]=")
|
||||
floats.print_f(b_floatarray[2])
|
||||
txt.print("\ninit b_filledarray[2]=")
|
||||
txt.print_ub(b_filledarray[2])
|
||||
|
||||
txt.print("\n\nrun again to see effect of re-init.\n")
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class IRFileReader {
|
||||
val programName = start.attributes.asSequence().single { it.name.localPart == "NAME" }.value
|
||||
val options = parseOptions(reader)
|
||||
val asmsymbols = parseAsmSymbols(reader)
|
||||
val bss = parseBss(reader)
|
||||
val varsWithoutInit = parseVarsWithoutInit(reader)
|
||||
val variables = parseVariables(reader, options.dontReinitGlobals)
|
||||
val memorymapped = parseMemMapped(reader)
|
||||
val slabs = parseSlabs(reader)
|
||||
@ -54,7 +54,7 @@ class IRFileReader {
|
||||
|
||||
val st = IRSymbolTable(null)
|
||||
asmsymbols.forEach { (name, value) -> st.addAsmSymbol(name, value)}
|
||||
bss.forEach { st.add(it) }
|
||||
varsWithoutInit.forEach { st.add(it) }
|
||||
variables.forEach { st.add(it) }
|
||||
memorymapped.forEach { st.add(it) }
|
||||
slabs.forEach { st.add(it) }
|
||||
@ -150,10 +150,10 @@ class IRFileReader {
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseBss(reader: XMLEventReader): List<StStaticVariable> {
|
||||
private fun parseVarsWithoutInit(reader: XMLEventReader): List<StStaticVariable> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="BSS") { "missing BSS" }
|
||||
require(start.name.localPart=="VARIABLESNOINIT") { "missing VARIABLESNOINIT" }
|
||||
val text = readText(reader).trim()
|
||||
require(reader.nextEvent().isEndElement)
|
||||
|
||||
@ -161,10 +161,10 @@ class IRFileReader {
|
||||
emptyList()
|
||||
else {
|
||||
val varPattern = Regex("(.+?)(\\[.+?\\])? (.+) (zp=(.+))?")
|
||||
val bssVariables = mutableListOf<StStaticVariable>()
|
||||
val variables = mutableListOf<StStaticVariable>()
|
||||
text.lineSequence().forEach { line ->
|
||||
// example: uword main.start.qq2 zp=DONTCARE
|
||||
val match = varPattern.matchEntire(line) ?: throw IRParseException("invalid BSS $line")
|
||||
val match = varPattern.matchEntire(line) ?: throw IRParseException("invalid VARIABLESNOINIT $line")
|
||||
val (type, arrayspec, name, _, zpwish) = match.destructured
|
||||
if('.' !in name)
|
||||
throw IRParseException("unscoped varname: $name")
|
||||
@ -173,16 +173,16 @@ class IRFileReader {
|
||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
|
||||
val newVar = StStaticVariable(name, dt, true, null, null, null, arraysize, zp, dummyNode)
|
||||
bssVariables.add(newVar)
|
||||
variables.add(newVar)
|
||||
}
|
||||
return bssVariables
|
||||
return variables
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseVariables(reader: XMLEventReader, dontReinitGlobals: Boolean): List<StStaticVariable> {
|
||||
skipText(reader)
|
||||
val start = reader.nextEvent().asStartElement()
|
||||
require(start.name.localPart=="VARIABLES") { "missing VARIABLES" }
|
||||
require(start.name.localPart=="VARIABLESWITHINIT") { "missing VARIABLESWITHINIT" }
|
||||
val text = readText(reader).trim()
|
||||
require(reader.nextEvent().isEndElement)
|
||||
|
||||
|
@ -139,14 +139,13 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
|
||||
private fun writeVariables() {
|
||||
|
||||
out.write("\n<BSS>\n")
|
||||
out.write("\n<VARIABLESNOINIT>\n")
|
||||
for (variable in irProgram.st.allVariables().filter { it.bss }) {
|
||||
val typeStr = getTypeString(variable)
|
||||
// bss variables have no initialization value
|
||||
out.write("$typeStr ${variable.name} zp=${variable.zpwish}\n")
|
||||
}
|
||||
|
||||
out.write("</BSS>\n<VARIABLES>\n")
|
||||
out.write("</VARIABLESNOINIT>\n<VARIABLESWITHINIT>\n")
|
||||
for (variable in irProgram.st.allVariables().filter { !it.bss }) {
|
||||
val typeStr = getTypeString(variable)
|
||||
val value: String = when(variable.dt) {
|
||||
@ -179,7 +178,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
}
|
||||
out.write("$typeStr ${variable.name}=$value zp=${variable.zpwish}\n")
|
||||
}
|
||||
out.write("</VARIABLES>\n")
|
||||
out.write("</VARIABLESWITHINIT>\n")
|
||||
|
||||
out.write("\n<MEMORYMAPPEDVARIABLES>\n")
|
||||
for (variable in irProgram.st.allMemMappedVariables()) {
|
||||
|
@ -55,12 +55,12 @@ evalStackBaseAddress=null
|
||||
<ASMSYMBOLS>
|
||||
</ASMSYMBOLS>
|
||||
|
||||
<BSS>
|
||||
<VARIABLESNOINIT>
|
||||
uword sys.bssvar zp=DONTCARE
|
||||
</BSS>
|
||||
<VARIABLES>
|
||||
</VARIABLESNOINIT>
|
||||
<VARIABLESWITHINIT>
|
||||
uword sys.wait.jiffies=10 zp=DONTCARE
|
||||
</VARIABLES>
|
||||
</VARIABLESWITHINIT>
|
||||
|
||||
<MEMORYMAPPEDVARIABLES>
|
||||
@uword cx16.r0=65282
|
||||
|
@ -176,7 +176,7 @@ class VmProgramLoader {
|
||||
program.st.allVariables().forEach { variable ->
|
||||
var addr = allocations.allocations.getValue(variable.name)
|
||||
|
||||
// zero out BSS variables.
|
||||
// zero out uninitialized variables.
|
||||
if(variable.bss) {
|
||||
if(variable.dt in ArrayDatatypes) {
|
||||
repeat(variable.length!!) {
|
||||
|
@ -115,10 +115,10 @@ class TestVm: FunSpec( {
|
||||
<ASMSYMBOLS>
|
||||
</ASMSYMBOLS>
|
||||
|
||||
<BSS>
|
||||
</BSS>
|
||||
<VARIABLES>
|
||||
</VARIABLES>
|
||||
<VARIABLESNOINIT>
|
||||
</VARIABLESNOINIT>
|
||||
<VARIABLESWITHINIT>
|
||||
</VARIABLESWITHINIT>
|
||||
|
||||
<MEMORYMAPPEDVARIABLES>
|
||||
</MEMORYMAPPEDVARIABLES>
|
||||
|
Loading…
Reference in New Issue
Block a user