mirror of
https://github.com/irmen/prog8.git
synced 2025-02-04 02:30:19 +00:00
tweak program start initialization and fix cleanup at exit for atari and pet compiler targets
This commit is contained in:
parent
4c843571ea
commit
04cb684fd4
@ -103,6 +103,9 @@ internal class ProgramAndVarsGen(
|
|||||||
asmgen.out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'")
|
asmgen.out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'")
|
||||||
asmgen.out("+\t.word 0")
|
asmgen.out("+\t.word 0")
|
||||||
asmgen.out("prog8_entrypoint\t; assembly code starts here")
|
asmgen.out("prog8_entrypoint\t; assembly code starts here")
|
||||||
|
asmgen.out(" cld")
|
||||||
|
asmgen.out(" tsx ; save stackpointer for sys.exit()")
|
||||||
|
asmgen.out(" stx prog8_lib.orig_stackpointer")
|
||||||
if(!options.noSysInit)
|
if(!options.noSysInit)
|
||||||
asmgen.out(" jsr sys.init_system")
|
asmgen.out(" jsr sys.init_system")
|
||||||
asmgen.out(" jsr sys.init_system_phase2")
|
asmgen.out(" jsr sys.init_system_phase2")
|
||||||
@ -110,6 +113,9 @@ internal class ProgramAndVarsGen(
|
|||||||
CbmPrgLauncherType.NONE -> {
|
CbmPrgLauncherType.NONE -> {
|
||||||
asmgen.out("; ---- program without basic sys call ----")
|
asmgen.out("; ---- program without basic sys call ----")
|
||||||
asmgen.out("* = ${options.loadAddress.toHex()}")
|
asmgen.out("* = ${options.loadAddress.toHex()}")
|
||||||
|
asmgen.out(" cld")
|
||||||
|
asmgen.out(" tsx ; save stackpointer for sys.exit()")
|
||||||
|
asmgen.out(" stx prog8_lib.orig_stackpointer")
|
||||||
if(!options.noSysInit)
|
if(!options.noSysInit)
|
||||||
asmgen.out(" jsr sys.init_system")
|
asmgen.out(" jsr sys.init_system")
|
||||||
asmgen.out(" jsr sys.init_system_phase2")
|
asmgen.out(" jsr sys.init_system_phase2")
|
||||||
@ -119,6 +125,9 @@ internal class ProgramAndVarsGen(
|
|||||||
OutputType.XEX -> {
|
OutputType.XEX -> {
|
||||||
asmgen.out("; ---- atari xex program ----")
|
asmgen.out("; ---- atari xex program ----")
|
||||||
asmgen.out("* = ${options.loadAddress.toHex()}")
|
asmgen.out("* = ${options.loadAddress.toHex()}")
|
||||||
|
asmgen.out(" cld")
|
||||||
|
asmgen.out(" tsx ; save stackpointer for sys.exit()")
|
||||||
|
asmgen.out(" stx prog8_lib.orig_stackpointer")
|
||||||
if(!options.noSysInit)
|
if(!options.noSysInit)
|
||||||
asmgen.out(" jsr sys.init_system")
|
asmgen.out(" jsr sys.init_system")
|
||||||
asmgen.out(" jsr sys.init_system_phase2")
|
asmgen.out(" jsr sys.init_system_phase2")
|
||||||
@ -149,7 +158,10 @@ internal class ProgramAndVarsGen(
|
|||||||
asmgen.out(" jsr p8b_main.p8s_start | lda #0 | sta ${"$"}ff00")
|
asmgen.out(" jsr p8b_main.p8s_start | lda #0 | sta ${"$"}ff00")
|
||||||
asmgen.out(" jmp sys.cleanup_at_exit")
|
asmgen.out(" jmp sys.cleanup_at_exit")
|
||||||
}
|
}
|
||||||
else -> asmgen.jmp("p8b_main.p8s_start")
|
else -> {
|
||||||
|
asmgen.out(" jsr p8b_main.p8s_start")
|
||||||
|
asmgen.out(" jmp sys.cleanup_at_exit")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,22 +463,7 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun entrypointInitialization() {
|
private fun entrypointInitialization() {
|
||||||
asmgen.out("; program startup initialization")
|
// initialize block-level (global) variables at program start
|
||||||
asmgen.out(" cld | tsx | stx prog8_lib.orig_stackpointer ; required for sys.exit()")
|
|
||||||
// set full BSS area to zero
|
|
||||||
asmgen.out("""
|
|
||||||
.if prog8_bss_section_size>0
|
|
||||||
; reset all variables in BSS section to zero
|
|
||||||
lda #<prog8_bss_section_start
|
|
||||||
ldy #>prog8_bss_section_start
|
|
||||||
sta P8ZP_SCRATCH_W1
|
|
||||||
sty P8ZP_SCRATCH_W1+1
|
|
||||||
ldx #<prog8_bss_section_size
|
|
||||||
ldy #>prog8_bss_section_size
|
|
||||||
lda #0
|
|
||||||
jsr prog8_lib.memset
|
|
||||||
.endif""")
|
|
||||||
|
|
||||||
blockVariableInitializers.forEach {
|
blockVariableInitializers.forEach {
|
||||||
if (it.value.isNotEmpty())
|
if (it.value.isNotEmpty())
|
||||||
asmgen.out(" jsr ${it.key.name}.prog8_init_vars")
|
asmgen.out(" jsr ${it.key.name}.prog8_init_vars")
|
||||||
@ -517,9 +514,8 @@ internal class ProgramAndVarsGen(
|
|||||||
arrayVariable2asm(varname, it.alloc.dt, it.value, null)
|
arrayVariable2asm(varname, it.alloc.dt, it.value, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
asmgen.out("""+
|
// zero out the BSS area
|
||||||
clv
|
asmgen.out("+ jsr prog8_lib.program_startup_clear_bss")
|
||||||
clc""")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ZpStringWithInitial(
|
private class ZpStringWithInitial(
|
||||||
|
@ -44,6 +44,22 @@ sys {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmsub cleanup_at_exit() {
|
||||||
|
; executed when the main subroutine does rts
|
||||||
|
%asm {{
|
||||||
|
_exitcodeCarry = *+1
|
||||||
|
lda #0
|
||||||
|
lsr a
|
||||||
|
_exitcode = *+1
|
||||||
|
lda #0 ; exit code possibly modified in exit()
|
||||||
|
_exitcodeX = *+1
|
||||||
|
ldx #0
|
||||||
|
_exitcodeY = *+1
|
||||||
|
ldy #0
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
asmsub reset_system() {
|
asmsub reset_system() {
|
||||||
; Soft-reset the system back to initial power-on Basic prompt.
|
; Soft-reset the system back to initial power-on Basic prompt.
|
||||||
; TODO
|
; TODO
|
||||||
@ -248,27 +264,38 @@ save_SCRATCH_ZPWORD2 .word 0
|
|||||||
|
|
||||||
asmsub exit(ubyte returnvalue @A) {
|
asmsub exit(ubyte returnvalue @A) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
; TODO where to store A as exit code?
|
|
||||||
%asm {{
|
%asm {{
|
||||||
|
sta cleanup_at_exit._exitcode
|
||||||
ldx prog8_lib.orig_stackpointer
|
ldx prog8_lib.orig_stackpointer
|
||||||
txs
|
txs
|
||||||
rts ; return to original caller
|
jmp cleanup_at_exit
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub exit2(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y) {
|
asmsub exit2(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y) {
|
||||||
; -- immediately exit the program with result values in the A, X and Y registers.
|
; -- immediately exit the program with result values in the A, X and Y registers.
|
||||||
; TODO where to store A,X,Y as exit code?
|
|
||||||
%asm {{
|
%asm {{
|
||||||
jmp exit
|
sta cleanup_at_exit._exitcode
|
||||||
|
stx cleanup_at_exit._exitcodeX
|
||||||
|
sty cleanup_at_exit._exitcodeY
|
||||||
|
ldx prog8_lib.orig_stackpointer
|
||||||
|
txs
|
||||||
|
jmp cleanup_at_exit
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub exit3(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y, bool carry @Pc) {
|
asmsub exit3(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y, bool carry @Pc) {
|
||||||
; -- immediately exit the program with result values in the A, X and Y registers, and the Carry flag in the status register.
|
; -- immediately exit the program with result values in the A, X and Y registers, and the Carry flag in the status register.
|
||||||
; TODO where to store A,X,Y,Carry as exit code?
|
|
||||||
%asm {{
|
%asm {{
|
||||||
jmp exit
|
sta cleanup_at_exit._exitcode
|
||||||
|
lda #0
|
||||||
|
rol a
|
||||||
|
sta cleanup_at_exit._exitcodeCarry
|
||||||
|
stx cleanup_at_exit._exitcodeX
|
||||||
|
sty cleanup_at_exit._exitcodeY
|
||||||
|
ldx prog8_lib.orig_stackpointer
|
||||||
|
txs
|
||||||
|
jmp cleanup_at_exit
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,26 @@
|
|||||||
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
|
orig_stackpointer .byte 0 ; stores the Stack pointer register at program start
|
||||||
|
|
||||||
|
|
||||||
|
program_startup_clear_bss .proc
|
||||||
|
; this is always ran first thing from the start routine to clear out the BSS area
|
||||||
|
.if prog8_bss_section_size>0
|
||||||
|
; reset all variables in BSS section to zero
|
||||||
|
lda #<prog8_bss_section_start
|
||||||
|
ldy #>prog8_bss_section_start
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
ldx #<prog8_bss_section_size
|
||||||
|
ldy #>prog8_bss_section_size
|
||||||
|
lda #0
|
||||||
|
jsr prog8_lib.memset
|
||||||
|
.endif
|
||||||
|
clv
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
read_byte_from_address_in_AY_into_A .proc
|
read_byte_from_address_in_AY_into_A .proc
|
||||||
sta P8ZP_SCRATCH_W2
|
sta P8ZP_SCRATCH_W2
|
||||||
sty P8ZP_SCRATCH_W2+1
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
Can we move the asm init code that is injected into the start() subroutine, to init_system_phase2 instead?
|
Shouldn't RAW output target have some initialization logic too? Does it even clear the variables/bss etc?
|
||||||
|
|
||||||
Doc improvements: some short overview for people coming from other programming languages like C:
|
Doc improvements: some short overview for people coming from other programming languages like C:
|
||||||
tell something about prog8 not having function overloading, max 16 bit (u)word integer as native type (and floats sometimes),
|
tell something about prog8 not having function overloading, max 16 bit (u)word integer as native type (and floats sometimes),
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import floats
|
%zeropage dontuse
|
||||||
%zeropage basicsafe
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
uword @shared variable
|
||||||
sub start() {
|
sub start() {
|
||||||
float fl = 5.23
|
txt.print("hello!\n")
|
||||||
fl = floats.ceil(fl)
|
txt.print_uw(variable)
|
||||||
floats.print(fl)
|
|
||||||
txt.nl()
|
|
||||||
fl = 5.23
|
|
||||||
fl = floats.floor(fl)
|
|
||||||
floats.print(fl)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
sys.exit3(1,2,3,false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user