mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
removed the automatic system reset at program exit, this did't work with the new init code
This commit is contained in:
parent
14d091e60a
commit
d7ceda4d82
@ -251,8 +251,7 @@ asmsub init_system() {
|
||||
sta c64.COLOR
|
||||
lda #0
|
||||
sta c64.BGCOL0
|
||||
tax
|
||||
tay
|
||||
jsr disable_runstop_and_charsetswitch
|
||||
clc
|
||||
clv
|
||||
cli
|
||||
@ -272,7 +271,6 @@ asmsub reset_system() {
|
||||
|
||||
asmsub disable_runstop_and_charsetswitch() {
|
||||
%asm {{
|
||||
lda #$80
|
||||
lda #$80
|
||||
sta 657 ; disable charset switching
|
||||
lda #239
|
||||
|
@ -8,7 +8,6 @@ import prog8.ast.expressions.*
|
||||
import prog8.ast.processing.AstWalker
|
||||
import prog8.ast.processing.IAstModification
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compiler.target.c64.codegen.programInitializationRoutineName
|
||||
|
||||
|
||||
internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter) : AstWalker() {
|
||||
@ -107,16 +106,6 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E
|
||||
&& outerScope !is Block) {
|
||||
mods += IAstModification.InsertAfter(outerStatements[subroutineStmtIdx - 1], returnStmt, outerScope as Node)
|
||||
}
|
||||
|
||||
// if it's the program's start subroutine, insert a call to the initalization logic (if it's not there already)
|
||||
if(subroutine.name=="start" && subroutine.definingBlock().name=="main") {
|
||||
val first = subroutine.statements.firstOrNull() as? FunctionCallStatement
|
||||
if(first==null || first.target.nameInSource != listOf(programInitializationRoutineName)) {
|
||||
val call = FunctionCallStatement(IdentifierReference(listOf(programInitializationRoutineName), subroutine.position), mutableListOf(), true, subroutine.position)
|
||||
mods += IAstModification.InsertFirst(call, subroutine)
|
||||
}
|
||||
}
|
||||
|
||||
return mods
|
||||
}
|
||||
|
||||
|
@ -70,12 +70,4 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
||||
|
||||
private fun loneByte(address: Int) = address in free && address-1 !in free && address+1 !in free
|
||||
private fun sequentialFree(address: Int, size: Int) = free.containsAll((address until address+size).toList())
|
||||
|
||||
enum class ExitProgramStrategy {
|
||||
CLEAN_EXIT,
|
||||
SYSTEM_RESET
|
||||
}
|
||||
|
||||
abstract val exitProgramStrategy: ExitProgramStrategy
|
||||
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ internal interface CompilationTarget {
|
||||
fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
||||
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
||||
fun asmGenerator(program: Program, errors: ErrorReporter, zp: Zeropage, options: CompilationOptions, path: Path): IAssemblyGenerator
|
||||
val initProcName: String?
|
||||
val resetProcName: String?
|
||||
val disableRunStopProcName: String?
|
||||
|
||||
companion object {
|
||||
lateinit var instance: CompilationTarget
|
||||
@ -36,9 +33,6 @@ internal object C64Target: CompilationTarget {
|
||||
if(altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
||||
override fun asmGenerator(program: Program, errors: ErrorReporter, zp: Zeropage, options: CompilationOptions, path: Path) =
|
||||
AsmGen(program, errors, zp, options, path)
|
||||
override val initProcName = "c64.init_system"
|
||||
override val resetProcName = "c64.reset_system"
|
||||
override val disableRunStopProcName = "c64.disable_runstop_and_charsetswitch"
|
||||
}
|
||||
|
||||
internal object Cx16Target: CompilationTarget {
|
||||
@ -50,7 +44,4 @@ internal object Cx16Target: CompilationTarget {
|
||||
if(altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
||||
override fun asmGenerator(program: Program, errors: ErrorReporter, zp: Zeropage, options: CompilationOptions, path: Path) =
|
||||
AsmGen(program, errors, zp, options, path)
|
||||
override val initProcName = "cx16.init_system"
|
||||
override val resetProcName = "cx16.reset_system"
|
||||
override val disableRunStopProcName = null
|
||||
}
|
||||
|
@ -113,12 +113,6 @@ internal object C64MachineDefinition: IMachineDefinition {
|
||||
override val SCRATCH_W2 = 0xfd // temp storage 2 for a word $fb+$fc
|
||||
|
||||
|
||||
override val exitProgramStrategy: ExitProgramStrategy = when (options.zeropage) {
|
||||
ZeropageType.BASICSAFE, ZeropageType.DONTUSE -> ExitProgramStrategy.CLEAN_EXIT
|
||||
ZeropageType.FLOATSAFE, ZeropageType.KERNALSAFE, ZeropageType.FULL -> ExitProgramStrategy.SYSTEM_RESET
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
if (options.floats && options.zeropage !in setOf(ZeropageType.FLOATSAFE, ZeropageType.BASICSAFE, ZeropageType.DONTUSE ))
|
||||
throw CompilerException("when floats are enabled, zero page type should be 'floatsafe' or 'basicsafe' or 'dontuse'")
|
||||
|
@ -29,9 +29,6 @@ import java.util.*
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
|
||||
internal const val programInitializationRoutineName = "prog8_initialize_program"
|
||||
|
||||
|
||||
internal class AsmGen(private val program: Program,
|
||||
val errors: ErrorReporter,
|
||||
val zeropage: Zeropage,
|
||||
@ -54,12 +51,10 @@ internal class AsmGen(private val program: Program,
|
||||
private val expressionsAsmGen = ExpressionsAsmGen(program, this)
|
||||
internal val loopEndLabels = ArrayDeque<String>()
|
||||
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||
private val programInitLines = mutableListOf<String>()
|
||||
|
||||
override fun compileToAssembly(optimize: Boolean): IAssemblyProgram {
|
||||
assemblyLines.clear()
|
||||
loopEndLabels.clear()
|
||||
programInitLines.clear()
|
||||
|
||||
println("Generating assembly code... ")
|
||||
|
||||
@ -126,63 +121,25 @@ internal class AsmGen(private val program: Program,
|
||||
out(" .null $9e, format(' %d ', _prog8_entrypoint), $3a, $8f, ' prog8 by idj'")
|
||||
out("+\t.word 0")
|
||||
out("_prog8_entrypoint\t; assembly code starts here\n")
|
||||
if(!options.noSysInit && !CompilationTarget.instance.initProcName.isNullOrEmpty())
|
||||
out(" jsr ${CompilationTarget.instance.initProcName}")
|
||||
if(!options.noSysInit)
|
||||
out(" jsr ${CompilationTarget.instance.name}.init_system")
|
||||
}
|
||||
options.output == OutputType.PRG -> {
|
||||
out("; ---- program without basic sys call ----")
|
||||
out("* = ${program.actualLoadAddress.toHex()}\n")
|
||||
if(!options.noSysInit && !CompilationTarget.instance.initProcName.isNullOrEmpty())
|
||||
out(" jsr ${CompilationTarget.instance.initProcName}")
|
||||
if(!options.noSysInit)
|
||||
out(" jsr ${CompilationTarget.instance.name}.init_system")
|
||||
}
|
||||
options.output == OutputType.RAW -> {
|
||||
out("; ---- raw assembler program ----")
|
||||
out("* = ${program.actualLoadAddress.toHex()}\n")
|
||||
}
|
||||
}
|
||||
out(" jmp main.start ; start program / force start proc to be included")
|
||||
|
||||
if (zeropage.exitProgramStrategy != Zeropage.ExitProgramStrategy.CLEAN_EXIT) {
|
||||
if(!CompilationTarget.instance.disableRunStopProcName.isNullOrEmpty())
|
||||
programInitLines.add(" jsr ${CompilationTarget.instance.disableRunStopProcName}")
|
||||
}
|
||||
|
||||
programInitLines.add(" ; initialize the variables in each block that has globals")
|
||||
programInitLines.add(" cld")
|
||||
programInitLines.add(" clv")
|
||||
program.allBlocks().forEach {
|
||||
if(it.statements.filterIsInstance<VarDecl>().any { vd->vd.value!=null && vd.type==VarDeclType.VAR && vd.datatype in NumericDatatypes})
|
||||
programInitLines.add(" jsr ${it.name}.prog8_init_vars")
|
||||
}
|
||||
if (zeropage.exitProgramStrategy == Zeropage.ExitProgramStrategy.SYSTEM_RESET) {
|
||||
// push the reset routine onto the cpu stack so that it is executed when the program does an rts
|
||||
programInitLines.addAll(listOf(
|
||||
" tsx",
|
||||
" lda $0102,x",
|
||||
" pha",
|
||||
" lda $0103,x",
|
||||
" pha",
|
||||
" lda #>(${CompilationTarget.instance.resetProcName}-1)",
|
||||
" sta $0102,x",
|
||||
" lda #<(${CompilationTarget.instance.resetProcName}-1)",
|
||||
" sta $0103,x",
|
||||
))
|
||||
}
|
||||
programInitLines.add(" ldx #\$ff\t; init estack pointer")
|
||||
programInitLines.add(" rts")
|
||||
out(" jmp main.start ; start program / force start proc to be included")
|
||||
}
|
||||
|
||||
private fun footer() {
|
||||
// the program preamble or initialization code
|
||||
out("")
|
||||
out("; program initialization")
|
||||
out(programInitializationRoutineName)
|
||||
for(line in programInitLines) {
|
||||
out(line)
|
||||
}
|
||||
out("")
|
||||
|
||||
|
||||
// the global list of all floating point constants for the whole program
|
||||
out("; global float constants")
|
||||
for (flt in globalFloatConsts) {
|
||||
@ -632,25 +589,18 @@ $save .byte 0
|
||||
is InlineAssembly -> translate(stmt)
|
||||
is FunctionCallStatement -> {
|
||||
val functionName = stmt.target.nameInSource.last()
|
||||
if(functionName == programInitializationRoutineName) {
|
||||
out("""
|
||||
tsx
|
||||
stx prog8_lib.orig_stackpointer
|
||||
jsr $functionName""")
|
||||
val builtinFunc = BuiltinFunctions[functionName]
|
||||
if (builtinFunc != null) {
|
||||
builtinFunctionsAsmGen.translateFunctioncallStatement(stmt, builtinFunc)
|
||||
} else {
|
||||
val builtinFunc = BuiltinFunctions[functionName]
|
||||
if (builtinFunc != null) {
|
||||
builtinFunctionsAsmGen.translateFunctioncallStatement(stmt, builtinFunc)
|
||||
} else {
|
||||
functioncallAsmGen.translateFunctionCall(stmt)
|
||||
// discard any results from the stack:
|
||||
val sub = stmt.target.targetSubroutine(program.namespace)!!
|
||||
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
|
||||
for ((t, reg) in returns) {
|
||||
if (reg.stack) {
|
||||
if (t in IntegerDatatypes || t in PassByReferenceDatatypes) out(" inx")
|
||||
else if (t == DataType.FLOAT) out(" inx | inx | inx")
|
||||
}
|
||||
functioncallAsmGen.translateFunctionCall(stmt)
|
||||
// discard any results from the stack:
|
||||
val sub = stmt.target.targetSubroutine(program.namespace)!!
|
||||
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
|
||||
for ((t, reg) in returns) {
|
||||
if (reg.stack) {
|
||||
if (t in IntegerDatatypes || t in PassByReferenceDatatypes) out(" inx")
|
||||
else if (t == DataType.FLOAT) out(" inx | inx | inx")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -811,6 +761,23 @@ $save .byte 0
|
||||
out("${sub.name}\t.proc")
|
||||
zeropagevars2asm(sub.statements)
|
||||
memdefs2asm(sub.statements)
|
||||
|
||||
// the main.start subroutine is the program's entrypoint and should perform some initialization logic
|
||||
if(sub.name=="start" && sub.definingBlock().name=="main") {
|
||||
out("; program startup initialization")
|
||||
out(" cld")
|
||||
program.allBlocks().forEach {
|
||||
if(it.statements.filterIsInstance<VarDecl>().any { vd->vd.value!=null && vd.type==VarDeclType.VAR && vd.datatype in NumericDatatypes})
|
||||
out(" jsr ${it.name}.prog8_init_vars")
|
||||
}
|
||||
out("""
|
||||
tsx
|
||||
stx prog8_lib.orig_stackpointer ; required for func_exit
|
||||
ldx #255 ; init estack ptr
|
||||
clv
|
||||
clc""")
|
||||
}
|
||||
|
||||
out("; statements")
|
||||
sub.statements.forEach{ translate(it) }
|
||||
out("; variables")
|
||||
|
@ -78,13 +78,6 @@ internal object CX16MachineDefinition: IMachineDefinition {
|
||||
override val SCRATCH_W2 = 0x7e // temp storage 2 for a word $7e+$7f
|
||||
|
||||
|
||||
override val exitProgramStrategy: ExitProgramStrategy = when (options.zeropage) {
|
||||
ZeropageType.BASICSAFE, ZeropageType.DONTUSE -> ExitProgramStrategy.CLEAN_EXIT
|
||||
ZeropageType.KERNALSAFE, ZeropageType.FULL -> ExitProgramStrategy.SYSTEM_RESET
|
||||
else -> ExitProgramStrategy.SYSTEM_RESET
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
if (options.floats && options.zeropage !in setOf(ZeropageType.BASICSAFE, ZeropageType.DONTUSE ))
|
||||
throw CompilerException("when floats are enabled, zero page type should be 'basicsafe' or 'dontuse'")
|
||||
|
@ -67,7 +67,8 @@ Directives
|
||||
- style ``kernalsafe`` -- use the part of the ZP that is 'free' or only used by BASIC routines,
|
||||
and don't change anything else. This allows full use of KERNAL ROM routines (but not BASIC routines),
|
||||
including default IRQs during normal system operation.
|
||||
When the program exits, a system reset is performed (because BASIC will be in a corrupt state).
|
||||
It's not possible to return cleanly to BASIC when the program exits. The only choice is
|
||||
to perform a system reset. (A ``system_reset`` subroutine is available in the syslib to help you do this)
|
||||
- style ``floatsafe`` -- like the previous one but also reserves the addresses that
|
||||
are required to perform floating point operations (from the BASIC kernel). No clean exit is possible.
|
||||
- style ``basicsafe`` -- the most restricted mode; only use the handful 'free' addresses in the ZP, and don't
|
||||
@ -78,9 +79,10 @@ Directives
|
||||
except the few addresses mentioned above that are used by the system's IRQ routine.
|
||||
Even though the default IRQ routine is still active, it is impossible to use most BASIC and KERNAL ROM routines.
|
||||
This includes many floating point operations and several utility routines that do I/O, such as ``print_string``.
|
||||
As with ``kernalsafe``, it is not possible to cleanly exit the program, other than to reset the machine.
|
||||
This option makes programs smaller and faster because even more variables can
|
||||
be stored in the ZP (which allows for more efficient assembly code).
|
||||
It's not possible to return cleanly to BASIC when the program exits. The only choice is
|
||||
to perform a system reset. (A ``system_reset`` subroutine is available in the syslib to help you do this)
|
||||
- style ``dontuse`` -- don't use *any* location in the zeropage.
|
||||
|
||||
Also read :ref:`zeropage`.
|
||||
|
@ -2,8 +2,6 @@
|
||||
%import textio
|
||||
%import syslib
|
||||
|
||||
; TODO fix crash it's caused by commit 2b9316c4fff5ef33340676da96a9c7ef57237bc0 reworked program init logic
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO fix crash
|
||||
|
||||
main {
|
||||
|
||||
; vertices
|
||||
|
@ -2,8 +2,6 @@
|
||||
%import syslib
|
||||
%import textio
|
||||
|
||||
; TODO fix crash
|
||||
|
||||
spritedata $2000 {
|
||||
; this memory block contains the sprite data
|
||||
; it must start on an address aligned to 64 bytes.
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO fix crash
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
@ -8,9 +8,6 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO fix problem that it freezes or doesn't draw anything anymore
|
||||
|
||||
|
||||
main {
|
||||
const ubyte width = 255
|
||||
const ubyte height = 200
|
||||
|
@ -13,8 +13,6 @@
|
||||
;** **
|
||||
;\*****************************************************************************/
|
||||
|
||||
; TODO fix problem
|
||||
|
||||
|
||||
main {
|
||||
const uword SCREEN1 = $E000
|
||||
|
@ -7,8 +7,7 @@
|
||||
; staged speed increase
|
||||
; some simple sound effects
|
||||
|
||||
; TODO fix crash
|
||||
|
||||
; TODO fix auto dropping of blocks (first fix testarrays)
|
||||
|
||||
%target c64
|
||||
%import syslib
|
||||
@ -34,7 +33,8 @@ main {
|
||||
|
||||
|
||||
sub start() {
|
||||
@(650) = 128 ; set all keys to repeat
|
||||
c64.disable_runstop_and_charsetswitch()
|
||||
;@(650) = 128 ; set all keys to repeat
|
||||
sound.init()
|
||||
newGame()
|
||||
drawBoard()
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO fix byte var in arrayvar fail
|
||||
|
||||
|
||||
main {
|
||||
|
||||
; this is only a parser/compiler test, there's no actual working program
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO fix byte var in arrayvar fail
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
@ -3,8 +3,6 @@
|
||||
%import graphics
|
||||
%zeropage floatsafe
|
||||
|
||||
; TODO fix crash
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user