mirror of
https://github.com/irmen/prog8.git
synced 2025-02-18 05:30:34 +00:00
added -varshigh
compiler option to move BSS section.
Documented BSS a bit in the manual.
This commit is contained in:
parent
fb9902c536
commit
ba9268a09e
@ -19,6 +19,7 @@ class CompilationOptions(val output: OutputType,
|
|||||||
var asmQuiet: Boolean = false,
|
var asmQuiet: Boolean = false,
|
||||||
var asmListfile: Boolean = false,
|
var asmListfile: Boolean = false,
|
||||||
var experimentalCodegen: Boolean = false,
|
var experimentalCodegen: Boolean = false,
|
||||||
|
var varsHigh: Boolean = false,
|
||||||
var evalStackBaseAddress: UInt? = null,
|
var evalStackBaseAddress: UInt? = null,
|
||||||
var outputDir: Path = Path(""),
|
var outputDir: Path = Path(""),
|
||||||
var symbolDefs: Map<String, String> = emptyMap()
|
var symbolDefs: Map<String, String> = emptyMap()
|
||||||
|
@ -16,6 +16,8 @@ interface IMachineDefinition {
|
|||||||
var ESTACK_LO: UInt
|
var ESTACK_LO: UInt
|
||||||
var ESTACK_HI: UInt
|
var ESTACK_HI: UInt
|
||||||
val PROGRAM_LOAD_ADDRESS : UInt
|
val PROGRAM_LOAD_ADDRESS : UInt
|
||||||
|
val BSSHIGHRAM_START: UInt
|
||||||
|
val BSSHIGHRAM_END: UInt
|
||||||
|
|
||||||
val cpu: CpuType
|
val cpu: CpuType
|
||||||
var zeropage: Zeropage
|
var zeropage: Zeropage
|
||||||
|
@ -17,6 +17,9 @@ class AtariMachineDefinition: IMachineDefinition {
|
|||||||
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive // TODO
|
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive // TODO
|
||||||
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive // TODO
|
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive // TODO
|
||||||
|
|
||||||
|
override val BSSHIGHRAM_START = 0u // TODO
|
||||||
|
override val BSSHIGHRAM_END = 0u // TODO
|
||||||
|
|
||||||
override lateinit var zeropage: Zeropage
|
override lateinit var zeropage: Zeropage
|
||||||
override lateinit var golden: GoldenRam
|
override lateinit var golden: GoldenRam
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ class C128MachineDefinition: IMachineDefinition {
|
|||||||
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
||||||
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive
|
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive
|
||||||
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive
|
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive
|
||||||
|
|
||||||
|
override val BSSHIGHRAM_START = 0u // TODO
|
||||||
|
override val BSSHIGHRAM_END = 0u // TODO
|
||||||
|
|
||||||
override lateinit var zeropage: Zeropage
|
override lateinit var zeropage: Zeropage
|
||||||
override lateinit var golden: GoldenRam
|
override lateinit var golden: GoldenRam
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ class C64MachineDefinition: IMachineDefinition {
|
|||||||
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
||||||
override var ESTACK_LO = 0xcf00u // $cf00-$cf7f inclusive
|
override var ESTACK_LO = 0xcf00u // $cf00-$cf7f inclusive
|
||||||
override var ESTACK_HI = 0xcf80u // $cf80-$cfff inclusive
|
override var ESTACK_HI = 0xcf80u // $cf80-$cfff inclusive
|
||||||
|
|
||||||
|
override val BSSHIGHRAM_START = 0xc000u
|
||||||
|
override val BSSHIGHRAM_END = ESTACK_LO
|
||||||
|
|
||||||
override lateinit var zeropage: Zeropage
|
override lateinit var zeropage: Zeropage
|
||||||
override lateinit var golden: GoldenRam
|
override lateinit var golden: GoldenRam
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@ class CX16MachineDefinition: IMachineDefinition {
|
|||||||
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
|
||||||
override var ESTACK_LO = 0x0700u // $0700-$077f inclusive
|
override var ESTACK_LO = 0x0700u // $0700-$077f inclusive
|
||||||
override var ESTACK_HI = 0x0780u // $0780-$07ff inclusive
|
override var ESTACK_HI = 0x0780u // $0780-$07ff inclusive
|
||||||
|
|
||||||
|
override val BSSHIGHRAM_START = 0xa000u // hiram bank 1, 8Kb, assumed to be active
|
||||||
|
override val BSSHIGHRAM_END = 0xc000u // rom starts here.
|
||||||
|
|
||||||
override lateinit var zeropage: Zeropage
|
override lateinit var zeropage: Zeropage
|
||||||
override lateinit var golden: GoldenRam
|
override lateinit var golden: GoldenRam
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ class VirtualMachineDefinition: IMachineDefinition {
|
|||||||
|
|
||||||
override var ESTACK_LO = 0u // not actually used
|
override var ESTACK_LO = 0u // not actually used
|
||||||
override var ESTACK_HI = 0u // not actually used
|
override var ESTACK_HI = 0u // not actually used
|
||||||
|
override val BSSHIGHRAM_START = 0u // not actually used
|
||||||
|
override val BSSHIGHRAM_END = 0u // not actually used
|
||||||
override lateinit var zeropage: Zeropage // not actually used
|
override lateinit var zeropage: Zeropage // not actually used
|
||||||
override lateinit var golden: GoldenRam // not actually used
|
override lateinit var golden: GoldenRam // not actually used
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun memorySlabs() {
|
private fun memorySlabs() {
|
||||||
|
if(symboltable.allMemorySlabs.isNotEmpty()) {
|
||||||
asmgen.out("; memory slabs\n .section slabs_BSS")
|
asmgen.out("; memory slabs\n .section slabs_BSS")
|
||||||
asmgen.out("prog8_slabs\t.block")
|
asmgen.out("prog8_slabs\t.block")
|
||||||
for (slab in symboltable.allMemorySlabs) {
|
for (slab in symboltable.allMemorySlabs) {
|
||||||
@ -171,15 +172,35 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
asmgen.out("\t.bend\n .send slabs_BSS")
|
asmgen.out("\t.bend\n .send slabs_BSS")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun footer() {
|
private fun footer() {
|
||||||
asmgen.out("; bss sections")
|
asmgen.out("; bss sections")
|
||||||
|
if(options.varsHigh) {
|
||||||
|
if(options.compTarget.machine.BSSHIGHRAM_START == 0u || options.compTarget.machine.BSSHIGHRAM_END==0u) {
|
||||||
|
throw AssemblyError("current compilation target hasn't got the high ram area properly defined")
|
||||||
|
}
|
||||||
|
// BSS vars in high ram area, memory() slabs just concatenated at the end of the program.
|
||||||
|
if(symboltable.allMemorySlabs.isNotEmpty()) {
|
||||||
|
asmgen.out(" .dsection slabs_BSS")
|
||||||
|
}
|
||||||
|
asmgen.out("prog8_program_end\t; end of program label for progend()")
|
||||||
|
asmgen.out(" * = ${options.compTarget.machine.BSSHIGHRAM_START.toHex()}")
|
||||||
|
asmgen.out("prog8_bss_section_start")
|
||||||
|
asmgen.out(" .dsection BSS")
|
||||||
|
asmgen.out(" .cerror * >= ${options.compTarget.machine.BSSHIGHRAM_END.toHex()}, \"too many variables for BSS section\"")
|
||||||
|
asmgen.out("prog8_bss_section_size = * - prog8_bss_section_start")
|
||||||
|
} else {
|
||||||
|
// BSS vars followed by memory() slabs, concatenated at the end of the program.
|
||||||
asmgen.out("prog8_bss_section_start")
|
asmgen.out("prog8_bss_section_start")
|
||||||
asmgen.out(" .dsection BSS")
|
asmgen.out(" .dsection BSS")
|
||||||
asmgen.out("prog8_bss_section_size = * - prog8_bss_section_start")
|
asmgen.out("prog8_bss_section_size = * - prog8_bss_section_start")
|
||||||
|
if(symboltable.allMemorySlabs.isNotEmpty()) {
|
||||||
asmgen.out(" .dsection slabs_BSS")
|
asmgen.out(" .dsection slabs_BSS")
|
||||||
|
}
|
||||||
asmgen.out("prog8_program_end\t; end of program label for progend()")
|
asmgen.out("prog8_program_end\t; end of program label for progend()")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun block2asm(block: PtBlock) {
|
private fun block2asm(block: PtBlock) {
|
||||||
asmgen.out("")
|
asmgen.out("")
|
||||||
|
@ -51,6 +51,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.NAME}')").default(C64Target.NAME)
|
val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.NAME}')").default(C64Target.NAME)
|
||||||
val startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a .p8ir IR source file in the VM")
|
val startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a .p8ir IR source file in the VM")
|
||||||
val watchMode by cli.option(ArgType.Boolean, fullName = "watch", description = "continuous compilation mode (watch for file changes)")
|
val watchMode by cli.option(ArgType.Boolean, fullName = "watch", description = "continuous compilation mode (watch for file changes)")
|
||||||
|
val varsHigh by cli.option(ArgType.Boolean, fullName = "varshigh", description = "put uninitialized variables in high memory area instead of at the end of the program")
|
||||||
val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999)
|
val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -124,6 +125,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
quietAssembler == true,
|
quietAssembler == true,
|
||||||
asmListfile == true,
|
asmListfile == true,
|
||||||
experimentalCodegen == true,
|
experimentalCodegen == true,
|
||||||
|
varsHigh == true,
|
||||||
compilationTarget,
|
compilationTarget,
|
||||||
evalStackAddr,
|
evalStackAddr,
|
||||||
processedSymbols,
|
processedSymbols,
|
||||||
@ -187,6 +189,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
quietAssembler == true,
|
quietAssembler == true,
|
||||||
asmListfile == true,
|
asmListfile == true,
|
||||||
experimentalCodegen == true,
|
experimentalCodegen == true,
|
||||||
|
varsHigh == true,
|
||||||
compilationTarget,
|
compilationTarget,
|
||||||
evalStackAddr,
|
evalStackAddr,
|
||||||
processedSymbols,
|
processedSymbols,
|
||||||
|
@ -35,6 +35,7 @@ class CompilerArguments(val filepath: Path,
|
|||||||
val quietAssembler: Boolean,
|
val quietAssembler: Boolean,
|
||||||
val asmListfile: Boolean,
|
val asmListfile: Boolean,
|
||||||
val experimentalCodegen: Boolean,
|
val experimentalCodegen: Boolean,
|
||||||
|
val varsHigh: Boolean,
|
||||||
val compilationTarget: String,
|
val compilationTarget: String,
|
||||||
val evalStackBaseAddress: UInt?,
|
val evalStackBaseAddress: UInt?,
|
||||||
val symbolDefs: Map<String, String>,
|
val symbolDefs: Map<String, String>,
|
||||||
@ -77,6 +78,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
asmQuiet = args.quietAssembler
|
asmQuiet = args.quietAssembler
|
||||||
asmListfile = args.asmListfile
|
asmListfile = args.asmListfile
|
||||||
experimentalCodegen = args.experimentalCodegen
|
experimentalCodegen = args.experimentalCodegen
|
||||||
|
varsHigh = args.varsHigh
|
||||||
evalStackBaseAddress = args.evalStackBaseAddress
|
evalStackBaseAddress = args.evalStackBaseAddress
|
||||||
outputDir = args.outputDir.normalize()
|
outputDir = args.outputDir.normalize()
|
||||||
symbolDefs = args.symbolDefs
|
symbolDefs = args.symbolDefs
|
||||||
|
@ -32,6 +32,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
|
|||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
asmListfile = false,
|
asmListfile = false,
|
||||||
experimentalCodegen = false,
|
experimentalCodegen = false,
|
||||||
|
varsHigh = false,
|
||||||
compilationTarget = target.name,
|
compilationTarget = target.name,
|
||||||
evalStackBaseAddress = null,
|
evalStackBaseAddress = null,
|
||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
|
@ -49,6 +49,7 @@ class TestCompilerOptionSourcedirs: FunSpec({
|
|||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
asmListfile = false,
|
asmListfile = false,
|
||||||
experimentalCodegen = false,
|
experimentalCodegen = false,
|
||||||
|
varsHigh = false,
|
||||||
compilationTarget = Cx16Target.NAME,
|
compilationTarget = Cx16Target.NAME,
|
||||||
evalStackBaseAddress = null,
|
evalStackBaseAddress = null,
|
||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
|
@ -30,6 +30,7 @@ internal fun compileFile(
|
|||||||
quietAssembler = true,
|
quietAssembler = true,
|
||||||
asmListfile = false,
|
asmListfile = false,
|
||||||
experimentalCodegen = false,
|
experimentalCodegen = false,
|
||||||
|
varsHigh = false,
|
||||||
platform.name,
|
platform.name,
|
||||||
evalStackBaseAddress = null,
|
evalStackBaseAddress = null,
|
||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
|
@ -175,6 +175,23 @@ One or more .p8 module files
|
|||||||
When not compiling for the Commander X16 target, the location of the 16 virtual registers cx16.r0..r15
|
When not compiling for the Commander X16 target, the location of the 16 virtual registers cx16.r0..r15
|
||||||
is changed accordingly (to keep them in the same memory space as the evaluation stack).
|
is changed accordingly (to keep them in the same memory space as the evaluation stack).
|
||||||
|
|
||||||
|
``-varshigh``
|
||||||
|
Places the uninitialized (and zero-initialized) variables in a separate high memory area, instead of
|
||||||
|
inside the program itself. This results in an increase of the amount of system ram available for the program
|
||||||
|
itself. The amount of ram saved depends on the amount and types of variables in the program, but can be
|
||||||
|
several hundreds of bytes or more.
|
||||||
|
The new memory location of the variables depends on the compilation target machine
|
||||||
|
|
||||||
|
c64: $C000 - $CEFF
|
||||||
|
|
||||||
|
cx16: $A000 - $BFFF (note: assumes that the correct HiRam bank #1 is mapped in at all times!)
|
||||||
|
|
||||||
|
If you use this option, you can no longer use the part of the above memory area that is
|
||||||
|
now alotted to the variables for your own purposes. The output of the 64tass assembler step at the
|
||||||
|
end of compilation shows precise details of where and how much memory is used by the variables
|
||||||
|
(it's called 'BSS' section or Gap). Compilation (or rather, assembling) will fail if there are too
|
||||||
|
many variables to fit in the high ram block.
|
||||||
|
|
||||||
|
|
||||||
Module source code files
|
Module source code files
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -12,6 +12,13 @@ but care should be taken of course to avoid unexpected side effects.
|
|||||||
Especially when you're dealing with interrupts or re-entrant routines: don't modify variables
|
Especially when you're dealing with interrupts or re-entrant routines: don't modify variables
|
||||||
that you not own or else you will break stuff.
|
that you not own or else you will break stuff.
|
||||||
|
|
||||||
|
Uninitialized and zero-initialized variables that are not put into zeropage, will be put into
|
||||||
|
a special 'BSS' section for the assembler. This section is usually placed at the end of the resulting program
|
||||||
|
but because it only contains empty space it won't actually increase the size of the resulting program binary.
|
||||||
|
Prog8 takes care of properly filling this memory area with zeros at program startup.
|
||||||
|
It is possible to relocate the BSS section using a compiler option
|
||||||
|
so that more system ram is available for the program code itself.
|
||||||
|
|
||||||
|
|
||||||
.. _three-letter-prefixing:
|
.. _three-letter-prefixing:
|
||||||
|
|
||||||
|
@ -3,21 +3,18 @@ TODO
|
|||||||
|
|
||||||
For next minor release
|
For next minor release
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- option to put BSS in specific upper memory block ($a000-$bfff on x16, $c000-$cdff on C64) add a .cerror check for overflow!
|
|
||||||
- document bss stuff in the manual
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
For 9.0 major changes
|
For 9.0 major changes
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
- duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything) + documentation
|
- duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything) + documentation
|
||||||
- get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m
|
- get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m
|
||||||
- SEGMENTS.
|
- Some support for (64tass) SEGMENTS ?
|
||||||
- Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class)
|
- Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class)
|
||||||
- block "golden" treated specially: every var in here will be allocated in the Golden ram area
|
- maybe treat block "golden" in a special way: can only contain vars, every var will be allocated in the Golden ram area?
|
||||||
- that block can only contain variables.
|
|
||||||
- the variables can NOT have initialization values, they will all be set to zero on startup (simple memset)
|
- the variables can NOT have initialization values, they will all be set to zero on startup (simple memset)
|
||||||
- just initialize them yourself in start() if you need a non-zero value
|
just initialize them yourself in start() if you need a non-zero value
|
||||||
- OR.... do all this automatically if 'golden' is enabled as a compiler option? So compiler allocates in ZP first, then Golden Ram, then regular ram
|
- OR.... do all this automatically if 'golden' is enabled as a compiler option? So compiler allocates in ZP first, then Golden Ram, then regular ram
|
||||||
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
|
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
|
||||||
- (need separate step in codegen and IR to write the "golden" variables)
|
- (need separate step in codegen and IR to write the "golden" variables)
|
||||||
|
@ -41,7 +41,8 @@ class RequestParser : Take {
|
|||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
quietAssembler = false,
|
quietAssembler = false,
|
||||||
asmListfile = false,
|
asmListfile = false,
|
||||||
experimentalCodegen = false
|
experimentalCodegen = false,
|
||||||
|
varsHigh = false
|
||||||
)
|
)
|
||||||
val compilationResult = compileProgram(args)
|
val compilationResult = compileProgram(args)
|
||||||
return RsJson(Jsonding())
|
return RsJson(Jsonding())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user