blob: fffa3d282e779631fe86a04bd5fb363ddbf70a70 [file] [log] [blame]
;
; Startup code for Contiki (Apple2 version)
;
; This must be the *first* file on the linker command line
;
.export _exit
.import zerobss, initlib, callmain, donelib
.import __STARTUP_RUN__, __BOOT_SIZE__ ; Linker generated
.import __BSS_RUN__, __BSS_SIZE__ ; Linker generated
.import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
.import __CODE_RUN__, __CODE_SIZE__ ; Linker generated
.importzp sp
.linecont +
; ------------------------------------------------------------------------
; The executable header
.segment "EXEHDR"
.word __STARTUP_RUN__ ; Start address
.word __BSS_RUN__ + __BOOT_SIZE__ + \
__INIT_SIZE__ + __CODE_SIZE__ - \
__STARTUP_RUN__ ; Size
; ------------------------------------------------------------------------
; Place the startup code in a special segment.
.segment "STARTUP"
; Forward control to the code in the "BOOT" segment
jmp __BSS_RUN__
; Avoid re-entrance of donelib. This is also the _exit entry
_exit: ldx #$02
: lda rvsave,x
sta $03F2,x
dex
bpl :-
; Switch in LC bank 2 for R/O
bit $C080
; Call module destructors
jsr donelib
; Switch in ROM
bit $C082
; Back to DOS
jmp $03D0
; ------------------------------------------------------------------------
; The linker doesn't calculate where this code runs so it has to be PIC
.segment "BOOT"
; Switch to 80 column mode
.ifdef __APPLE2ENH__
lda #$0D
jsr $C300
.endif
; Setup the stack at HIMEM
lda $73
ldx $73+1
sta sp
stx sp+1
; Save the original RESET vector
ldx #$02
: lda $03F2,x
sta rvsave,x
dex
bpl :-
; ProDOS TechRefMan, chapter 5.3.5:
; "Your system program should place in the RESET vector the address of a
; routine that ... closes the files."
lda #<_exit
sta $03F2
lda #>_exit
sta $03F3
eor #$A5
sta $03F4
; Switch in LC bank 2 for W/O
bit $C081
bit $C081
; Set source start
lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
sta $3C
stx $3D
; Set source end
lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__)
ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__)
sta $3E
stx $3F
; Set destination
lda #<__CODE_RUN__
ldx #>__CODE_RUN__
sta $42
stx $43
; Reset index and call MOVE to relocate the "CODE" segment
ldy #$00
jsr $FE2C
; Set source start
lda #<(__BSS_RUN__ + __BOOT_SIZE__)
ldx #>(__BSS_RUN__ + __BOOT_SIZE__)
sta $3C
stx $3D
; Set source end
lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
sta $3E
stx $3F
; Set destination
lda #<__INIT_RUN__
ldx #>__INIT_RUN__
sta $42
stx $43
; Reset index and call MOVE to relocate the "INIT" segment
ldy #$00
jsr $FE2C
; Switch in LC bank 2 for R/O
bit $C080
; Forward control to code in the "INIT" segment
jmp init
; ------------------------------------------------------------------------
; The "INIT" segment will be overwritten by the heap
.segment "INIT"
; Clear the BSS data (and thus overwrite the "BOOT" segment)
init: jsr zerobss
; Call module constructors
jsr initlib
; Push arguments and call main()
jmp callmain
; ------------------------------------------------------------------------
; Data
.data
rvsave: .res 3