+FEATURES {
+ STARTADDRESS: default = $0801;
+}
SYMBOLS {
__LOADADDR__: type = import;
__EXEHDR__: type = import;
__OVERLAYADDR__: type = import;
- __STACKSIZE__: type = weak, value = $0800; # 2k stack
- __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
+ __STACKSIZE__: type = weak, value = $0800; # 2k stack
+ __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
+ __HIMEM__: type = weak, value = $D000;
+ __HIMEM2__: type = export, value = __HIMEM__ - 2;
}
MEMORY {
- ZP: file = "", define = yes, start = $0002, size = $001A;
- LOADADDR: file = %O, start = $07FF, size = $0002;
- HEADER: file = %O, start = $0801, size = $000C;
- RAM: file = %O, define = yes, start = $080D, size = $C7F3 - __OVERLAYSIZE__ - __STACKSIZE__;
- OVL1ADDR: file = "%O.1", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL1: file = "%O.1", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL2ADDR: file = "%O.2", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL2: file = "%O.2", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL3ADDR: file = "%O.3", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL3: file = "%O.3", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL4ADDR: file = "%O.4", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL4: file = "%O.4", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL5ADDR: file = "%O.5", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL5: file = "%O.5", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL6ADDR: file = "%O.6", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL6: file = "%O.6", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL7ADDR: file = "%O.7", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL7: file = "%O.7", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL8ADDR: file = "%O.8", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL8: file = "%O.8", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
- OVL9ADDR: file = "%O.9", start = $CFFE - __OVERLAYSIZE__, size = $0002;
- OVL9: file = "%O.9", start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ ZP: file = "", define = yes, start = $0002, size = $001A;
+ LOADADDR: file = %O, start = %S - 2, size = $0002;
+ HEADER: file = %O, define = yes, start = %S, size = $000D;
+ RAM: file = %O, start = __HEADER_LAST__, size = __HIMEM__ - __OVERLAYSIZE__ - __STACKSIZE__ - __HEADER_LAST__;
+ MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
+ OVL1ADDR: file = "%O.1", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL1: file = "%O.1", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL2ADDR: file = "%O.2", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL2: file = "%O.2", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL3ADDR: file = "%O.3", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL3: file = "%O.3", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL4ADDR: file = "%O.4", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL4: file = "%O.4", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL5ADDR: file = "%O.5", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL5: file = "%O.5", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL6ADDR: file = "%O.6", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL6: file = "%O.6", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL7ADDR: file = "%O.7", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL7: file = "%O.7", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL8ADDR: file = "%O.8", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL8: file = "%O.8", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+ OVL9ADDR: file = "%O.9", start = __HIMEM2__ - __OVERLAYSIZE__, size = $0002;
+ OVL9: file = "%O.9", start = __HIMEM__ - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
}
SEGMENTS {
- LOADADDR: load = LOADADDR, type = ro;
- EXEHDR: load = HEADER, type = ro;
- STARTUP: load = RAM, type = ro;
- LOWCODE: load = RAM, type = ro, optional = yes;
- INIT: load = RAM, type = ro, define = yes, optional = yes;
- CODE: load = RAM, type = ro;
- RODATA: load = RAM, type = ro;
- DATA: load = RAM, type = rw;
- ZPSAVE: load = RAM, type = bss;
- BSS: load = RAM, type = bss, define = yes;
- ZEROPAGE: load = ZP, type = zp;
- OVL1ADDR: load = OVL1ADDR, type = ro;
- OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
- OVL2ADDR: load = OVL2ADDR, type = ro;
- OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
- OVL3ADDR: load = OVL3ADDR, type = ro;
- OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
- OVL4ADDR: load = OVL4ADDR, type = ro;
- OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
- OVL5ADDR: load = OVL5ADDR, type = ro;
- OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
- OVL6ADDR: load = OVL6ADDR, type = ro;
- OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
- OVL7ADDR: load = OVL7ADDR, type = ro;
- OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
- OVL8ADDR: load = OVL8ADDR, type = ro;
- OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
- OVL9ADDR: load = OVL9ADDR, type = ro;
- OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
+ ZEROPAGE: load = ZP, type = zp;
+ LOADADDR: load = LOADADDR, type = ro;
+ EXEHDR: load = HEADER, type = ro;
+ STARTUP: load = RAM, type = ro;
+ LOWCODE: load = RAM, type = ro, optional = yes;
+ CODE: load = RAM, type = ro;
+ RODATA: load = RAM, type = ro;
+ DATA: load = RAM, type = rw;
+ ZPSAVE: load = RAM, type = bss, define = yes;
+ BSS: load = RAM, type = bss, define = yes;
+ INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes;
+ OVL1ADDR: load = OVL1ADDR, type = ro;
+ OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
+ OVL2ADDR: load = OVL2ADDR, type = ro;
+ OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
+ OVL3ADDR: load = OVL3ADDR, type = ro;
+ OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
+ OVL4ADDR: load = OVL4ADDR, type = ro;
+ OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
+ OVL5ADDR: load = OVL5ADDR, type = ro;
+ OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
+ OVL6ADDR: load = OVL6ADDR, type = ro;
+ OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
+ OVL7ADDR: load = OVL7ADDR, type = ro;
+ OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
+ OVL8ADDR: load = OVL8ADDR, type = ro;
+ OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
+ OVL9ADDR: load = OVL9ADDR, type = ro;
+ OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
}
FEATURES {
CONDES: type = constructor,
+FEATURES {
+ STARTADDRESS: default = $0801;
+}
SYMBOLS {
__LOADADDR__: type = import;
__EXEHDR__: type = import;
__STACKSIZE__: type = weak, value = $0800; # 2k stack
+ __HIMEM__: type = weak, value = $D000;
}
MEMORY {
- ZP: file = "", define = yes, start = $0002, size = $001A;
- LOADADDR: file = %O, start = $07FF, size = $0002;
- HEADER: file = %O, start = $0801, size = $000C;
- RAM: file = %O, define = yes, start = $080D, size = $C7F3 - __STACKSIZE__;
+ ZP: file = "", define = yes, start = $0002, size = $001A;
+ LOADADDR: file = %O, start = %S - 2, size = $0002;
+ HEADER: file = %O, define = yes, start = %S, size = $000D;
+ RAM: file = %O, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
+ MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
}
SEGMENTS {
- LOADADDR: load = LOADADDR, type = ro;
- EXEHDR: load = HEADER, type = ro;
- STARTUP: load = RAM, type = ro;
- LOWCODE: load = RAM, type = ro, optional = yes;
- INIT: load = RAM, type = ro, define = yes, optional = yes;
- CODE: load = RAM, type = ro;
- RODATA: load = RAM, type = ro;
- DATA: load = RAM, type = rw;
- ZPSAVE: load = RAM, type = bss;
- BSS: load = RAM, type = bss, define = yes;
- ZEROPAGE: load = ZP, type = zp;
+ ZEROPAGE: load = ZP, type = zp;
+ LOADADDR: load = LOADADDR, type = ro;
+ EXEHDR: load = HEADER, type = ro;
+ STARTUP: load = RAM, type = ro;
+ LOWCODE: load = RAM, type = ro, optional = yes;
+ CODE: load = RAM, type = ro;
+ RODATA: load = RAM, type = ro;
+ DATA: load = RAM, type = rw;
+ ZPSAVE: load = RAM, type = bss, define = yes;
+ BSS: load = RAM, type = bss, define = yes;
+ INIT: load = MOVE, run = RAM, type = ro, define = yes, optional = yes;
}
FEATURES {
CONDES: type = constructor,
;
.export _exit
+ .exportzp init_load_, init_run_
.export __STARTUP__ : absolute = 1 ; Mark as startup
+
.import initlib, donelib
- .import zerobss
- .import callmain
+ .import move_init, zerobss, callmain
.import RESTOR, BSOUT, CLRCH
- .import __RAM_START__, __RAM_SIZE__ ; Linker generated
- .import __STACKSIZE__ ; Linker generated
+ .import __HIMEM__ ; from configure file
.importzp ST
.include "zeropage.inc"
; ------------------------------------------------------------------------
; Startup code
-.segment "STARTUP"
+; Two zero-page pointers are needed before any zero-page stuff is saved.
+; Choose locations that are not used by anything.
-Start:
+init_load_ := FREKZP
+init_run_ := FREKZP+2
-; Save the zero-page locations that we need.
- ldx #zpspace-1
-L1: lda sp,x
- sta zpsave,x
- dex
- bpl L1
+.segment "STARTUP"
+
+Start:
; Switch to the second charset.
; Switch off the BASIC ROM.
lda $01
- pha ; Remember the value
+ sta mmusave ; Save the memory configuration
and #$F8
ora #$06 ; Enable Kernal+I/O, disable BASIC
sta $01
-; Clear the BSS data.
-
- jsr zerobss
-
-; Save some system settings; and, set up the stack.
-
- pla
- sta mmusave ; Save the memory configuration
-
tsx
stx spsave ; Save the system stack ptr
- lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
- sta sp
- lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
- sta sp+1 ; Set argument stack ptr
+; Allow some re-entrancy by skipping the next task if it already was done.
+; This often can let us rerun the program without reloading it.
-; Call the module constructors.
+ ldx moveinit
+ beq L0
- jsr initlib
+; Move the INIT segment from where it was loaded (over ZPSAVE and BSS)
+; into where it must be run (in the heap).
-; Push the command-line arguments; and, call main().
+ jsr move_init
+ dec moveinit ; set to false
+
+; Save space by putting the rest of the start-up code in the INIT segment,
+; which can be re-used by the heap.
- jsr callmain
+L0: jsr initstart
; Back from main() [this is also the exit() entry]. Run the module destructors.
rts
+
; ------------------------------------------------------------------------
-; Data
-.segment "ZPSAVE"
+.segment "INIT"
-zpsave: .res zpspace
+initstart:
+
+; Save the zero-page locations that we need.
-.bss
+ ldx #zpspace-1
+L1: lda sp,x
+ sta zpsave,x
+ dex
+ bpl L1
+
+; Clear the BSS data.
+
+ jsr zerobss
+
+; Set up the stack.
+
+ lda #<__HIMEM__
+ ldx #>__HIMEM__
+ sta sp
+ stx sp+1 ; Set argument stack ptr
+
+; Call the module constructors.
+
+ jsr initlib
+
+; Push the command-line arguments; and, call main().
+
+ jmp callmain
+
+
+; ------------------------------------------------------------------------
+; Data
+
+.data
-spsave: .res 1
mmusave:.res 1
+spsave: .res 1
+moveinit:
+ .byte 1
+
+.segment "ZPSAVE"
+
+zpsave: .res zpspace