2 ; Start-up code for cc65 (PC-Engine version)
4 ; by Groepaz/Hitmen <groepaz@gmx.net>,
5 ; based on code by Ullrich von Bassewitz <uz@cc65.org>
7 ; 2018-02-24, Greg King
11 .export __STARTUP__ : absolute = 1 ; Mark as start-up
13 .import initlib, donelib
15 .import IRQStub, __nmi
20 .import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
21 .import __BSS_RUN__, __BSS_SIZE__
22 .import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__
27 ; ------------------------------------------------------------------------
28 ; Place the start-up code in a special segment.
35 csh ; Set high-speed CPU mode
38 ; Set up the stack and the memory mapping.
39 ldx #$FF ; Stack top ($21FF)
42 ; At power-on, most MPRs have random values; so, initiate them.
44 tam #%00000001 ; $0000-$1FFF = Hardware bank
46 tam #%00000010 ; $2000-$3FFF = Work RAM
48 ;tam #%00000100 ; $4000-$47FF = 2K Battery-backed RAM
50 ;tam #%00001000 ; $6000-$7FFF
56 tam #%00010000 ; $8000-$9FFF = ROM bank 1 (32K block of ROM)
58 tam #%00100000 ; $A000-$BFFF = ROM bank 2
60 @L1: tam #%01000000 ; $C000-$DFFF = ROM bank 3 (32K) or 1 (16K)
61 ;lda #$00 ; (The reset default)
62 ;tam #%10000000 ; $E000-$FFFF Hucard/Syscard bank 0
64 ; Initialize the hardware.
65 stz TIMER_CTRL ; Timer off
67 sta IRQ_MASK ; Interrupts off
69 ; FIXME; I don't know why the heck this one doesn't work when called from a constructor. -Groepaz :-/
70 .if 0 ; It now seems to work (at least, in Mednafen). -Greg King
75 ; Allow interrupts from the VDC.
77 sta IRQ_MASK ; IRQ1 = on
79 ; Copy the .data segment to RAM
80 tii __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
82 ; Clear the .bss segment
84 tii __BSS_RUN__, __BSS_RUN__ + 1, __BSS_SIZE__ - 1
87 lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
88 ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
92 ; Call the module constructors.
95 stz IRQ_STATUS ; Clear IRQs
96 cli ; Allow IRQ only after constructors have run
98 ; Pass an empty command line
102 ldy #4 ; Argument size
103 jsr _main ; Call the user's code
105 ; Call the module destructors. This is also the exit() entry.
108 ; Reset the PCEngine (start over).
115 ; ------------------------------------------------------------------------
117 ; ------------------------------------------------------------------------
120 .word IRQStub ; $FFF6 IRQ2 (External IRQ, BRK)
121 .word IRQStub ; $FFF8 IRQ1 (VDC)
122 .word IRQStub ; $FFFA Timer
123 .word __nmi ; $FFFC NMI
124 .word start ; $FFFE reset