mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
force_output option added
This commit is contained in:
parent
21136e8cad
commit
39a8b76534
@ -1,10 +1,10 @@
|
||||
%import c64lib
|
||||
%import c64utils
|
||||
%option force_output, enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
const uword SP0X = $d000
|
||||
const uword SP0Y = $d001
|
||||
~ spritedata $0a00 {
|
||||
%option force_output ; make sure the data appears in the program
|
||||
|
||||
ubyte[63] balloonsprite = [ %00000000,%01111111,%00000000,
|
||||
%00000001,%11111111,%11000000,
|
||||
@ -27,23 +27,26 @@
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00011100,%00000000 ]
|
||||
}
|
||||
|
||||
const uword sprite_data_address = 13*64 ; // safe area inside the tape buffer
|
||||
~ main {
|
||||
|
||||
const uword SP0X = $d000
|
||||
const uword SP0Y = $d001
|
||||
|
||||
sub start() {
|
||||
|
||||
c64.STROUT("balloon sprites!\n")
|
||||
c64.STROUT("...we are all floating...\n")
|
||||
|
||||
memcopy(balloonsprite, sprite_data_address, 63)
|
||||
c64.SPRPTR0 = sprite_data_address//64
|
||||
c64.SPRPTR1 = sprite_data_address//64
|
||||
c64.SPRPTR2 = sprite_data_address//64
|
||||
c64.SPRPTR3 = sprite_data_address//64
|
||||
c64.SPRPTR4 = sprite_data_address//64
|
||||
c64.SPRPTR5 = sprite_data_address//64
|
||||
c64.SPRPTR6 = sprite_data_address//64
|
||||
c64.SPRPTR7 = sprite_data_address//64
|
||||
c64.SPRPTR0 = $0a00//64
|
||||
c64.SPRPTR1 = $0a00//64
|
||||
c64.SPRPTR2 = $0a00//64
|
||||
c64.SPRPTR3 = $0a00//64
|
||||
c64.SPRPTR4 = $0a00//64
|
||||
c64.SPRPTR5 = $0a00//64
|
||||
c64.SPRPTR6 = $0a00//64
|
||||
c64.SPRPTR7 = $0a00//64
|
||||
|
||||
for ubyte i in 0 to 7 {
|
||||
@(SP0X+i*2) = 50+25*i
|
||||
|
@ -1,6 +1,8 @@
|
||||
%import c64utils
|
||||
%option enable_floats
|
||||
|
||||
~ main {
|
||||
|
||||
ubyte[3] balloonsprite = [ %00000000,%01111111,%00000000 ]
|
||||
|
||||
sub start() {
|
||||
@ -14,8 +16,5 @@
|
||||
@($d020) = @($d020+i) + 1
|
||||
@($d020+i) = @($d020+i) + 1
|
||||
c64scr.print_ub(X)
|
||||
|
||||
i = 2+balloonsprite
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -523,6 +523,8 @@ class Block(override val name: String,
|
||||
override fun toString(): String {
|
||||
return "Block(name=$name, address=$address, ${statements.size} statements)"
|
||||
}
|
||||
|
||||
val options = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.name!!}.toSet()
|
||||
}
|
||||
|
||||
|
||||
|
@ -617,17 +617,17 @@ class AstChecker(private val namespace: INameScope,
|
||||
err("invalid import directive, cannot import itself")
|
||||
}
|
||||
"%breakpoint" -> {
|
||||
if(directive.parent is Module) err("this directive may only occur in a block")
|
||||
if(directive.parent !is Block) err("this directive may only occur in a block")
|
||||
if(directive.args.isNotEmpty())
|
||||
err("invalid breakpoint directive, expected no arguments")
|
||||
}
|
||||
"%asminclude" -> {
|
||||
if(directive.parent is Module) err("this directive may only occur in a block")
|
||||
if(directive.parent !is Block) err("this directive may only occur in a block")
|
||||
if(directive.args.size!=2 || directive.args[0].str==null || directive.args[1].name==null)
|
||||
err("invalid asminclude directive, expected arguments: \"filename\", scopelabel")
|
||||
}
|
||||
"%asmbinary" -> {
|
||||
if(directive.parent is Module) err("this directive may only occur in a block")
|
||||
if(directive.parent !is Block) err("this directive may only occur in a block")
|
||||
val errormsg = "invalid asmbinary directive, expected arguments: \"filename\" [, offset [, length ] ]"
|
||||
if(directive.args.isEmpty()) err(errormsg)
|
||||
if(directive.args.isNotEmpty() && directive.args[0].str==null) err(errormsg)
|
||||
@ -636,8 +636,10 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(directive.args.size>3) err(errormsg)
|
||||
}
|
||||
"%option" -> {
|
||||
if(directive.parent !is Module) err("this directive may only occur at module level")
|
||||
if(directive.args.size!=1 || directive.args[0].name != "enable_floats")
|
||||
if(directive.parent !is Block && directive.parent !is Module) err("this directive may only occur in a block or at module level")
|
||||
if(directive.args.isEmpty())
|
||||
err("missing option directive argument(s)")
|
||||
else if(directive.args.map{it.name in setOf("enable_floats", "force_output")}.any { !it })
|
||||
err("invalid option directive argument(s)")
|
||||
}
|
||||
else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position)
|
||||
|
@ -151,7 +151,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
val continueStmtLabelStack : Stack<String> = Stack()
|
||||
|
||||
override fun process(block: Block): IStatement {
|
||||
prog.newBlock(block.scopedname, block.name, block.address)
|
||||
prog.newBlock(block.scopedname, block.name, block.address, block.options)
|
||||
processVariables(block) // @todo optimize initializations with same value: load the value only once (sort on initalization value, datatype ?)
|
||||
prog.label("block."+block.scopedname)
|
||||
prog.line(block.position)
|
||||
|
@ -14,7 +14,8 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
val instructions: MutableList<Instruction> = mutableListOf(),
|
||||
val variables: MutableMap<String, Value> = mutableMapOf(),
|
||||
val memoryPointers: MutableMap<String, Pair<Int, DataType>> = mutableMapOf(),
|
||||
val labels: MutableMap<String, Instruction> = mutableMapOf())
|
||||
val labels: MutableMap<String, Instruction> = mutableMapOf(),
|
||||
val force_output: Boolean)
|
||||
{
|
||||
val numVariables: Int
|
||||
get() { return variables.size }
|
||||
@ -368,8 +369,8 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap
|
||||
currentBlock.memoryPointers[name] = Pair(address, datatype)
|
||||
}
|
||||
|
||||
fun newBlock(scopedname: String, shortname: String, address: Int?) {
|
||||
currentBlock = ProgramBlock(scopedname, shortname, address)
|
||||
fun newBlock(scopedname: String, shortname: String, address: Int?, options: Set<String>) {
|
||||
currentBlock = ProgramBlock(scopedname, shortname, address, force_output="force_output" in options)
|
||||
blocks.add(currentBlock)
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
newinstructions,
|
||||
newvars,
|
||||
newConstants,
|
||||
newlabels))
|
||||
newlabels,
|
||||
force_output = block.force_output))
|
||||
}
|
||||
program.blocks.clear()
|
||||
program.blocks.addAll(newblocks)
|
||||
@ -196,7 +197,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'")
|
||||
out("* = ${block.address?.toHex()}")
|
||||
}
|
||||
out("${block.shortname}\t.proc\n")
|
||||
if(!blk.force_output)
|
||||
out("${block.shortname}\t.proc\n")
|
||||
out("\n; memdefs and kernel subroutines")
|
||||
memdefs2asm(block)
|
||||
out("\n; variables")
|
||||
@ -218,7 +220,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
processed--
|
||||
}
|
||||
if (trace) println("END BLOCK: ${block.scopedname}")
|
||||
out("\n\t.pend\n")
|
||||
if(!blk.force_output)
|
||||
out("\n\t.pend\n")
|
||||
}
|
||||
|
||||
private fun memdefs2asm(block: IntermediateProgram.ProgramBlock) {
|
||||
|
@ -103,11 +103,14 @@ Directives
|
||||
|
||||
.. data:: %option <option> [, <option> ...]
|
||||
|
||||
Level: module.
|
||||
Level: module, block.
|
||||
Sets special compiler options.
|
||||
For now, only the ``enable_floats`` option is recognised, which will tell the compiler
|
||||
For a module option, only the ``enable_floats`` option is recognised, which will tell the compiler
|
||||
to deal with floating point numbers (by using various subroutines from the Commodore-64 kernal).
|
||||
Otherwise, floating point support is not enabled.
|
||||
When used in a block with the ``force_output`` option, it will force the block to be outputted
|
||||
in the final program. Can be useful to make sure some
|
||||
data is generated that would otherwise be discarded because it's not referenced (such as sprite data).
|
||||
|
||||
|
||||
.. data:: %asmbinary "<filename>" [, <offset>[, <length>]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user