]> git.sur5r.net Git - cc65/blob - libsrc/pce/crt0.s
e67039d4320eadd66bd54aabfabeaf39512a57a6
[cc65] / libsrc / pce / crt0.s
1 ;
2 ; Startup code for cc65 (PCEngine version)
3 ;
4 ; by Groepaz/Hitmen <groepaz@gmx.net>
5 ; based on code by Ullrich von Bassewitz <uz@cc65.org>
6 ;
7 ; This must be the *first* file on the linker command line
8 ;
9
10         .export _exit
11         .export __STARTUP__ : absolute = 1      ; Mark as startup
12
13         .import initlib, donelib
14         .import push0, _main, zerobss
15         .import initheap
16         .import tmp1,tmp2,tmp3
17
18         ; Linker generated
19         .import __RAM_START__, __RAM_SIZE__
20         .import __ROM0_START__, __ROM0_SIZE__
21         .import __ROM_START__, __ROM_SIZE__
22         .import __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__
23         .import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__
24         .import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__
25         .import __DATA_LOAD__,__DATA_RUN__, __DATA_SIZE__
26         .import __BSS_SIZE__
27
28         .include "pce.inc"
29
30         .importzp sp
31         .importzp ptr1,ptr2
32
33 ; ------------------------------------------------------------------------
34 ; Create an empty LOWCODE segment to avoid linker warnings
35
36                 .segment "LOWCODE"
37
38 ; ------------------------------------------------------------------------
39 ; Place the startup code in a special segment.
40
41                 .segment "STARTUP"
42
43 start:
44
45 ; setup the CPU and System-IRQ
46
47                 ; Initialize CPU
48
49                 sei
50                 nop
51                 csh                     ; set high speed CPU mode
52                 nop
53                 cld
54                 nop
55
56                 ; Setup stack and memory mapping
57                 ldx     #$FF            ; Stack top ($21FF)
58                 txs
59
60                 ; at startup all MPRs are set to 0, so init them
61                 lda     #$ff
62                 tam     #%00000001      ; 0000-1FFF = Hardware page
63                 lda     #$F8
64                 tam     #%00000010      ; 2000-3FFF = Work RAM
65                 ;lda     #$F7
66                 ;tam     #%00000100      ; 4000-5FFF = Save RAM
67                 ;lda     #1
68                 ;tam     #%00001000      ; 6000-7FFF  Page 2
69                 ;lda     #2
70                 ;tam     #%00010000      ; 8000-9FFF  Page 3
71                 ;lda     #3
72                 ;tam     #%00100000      ; A000-BFFF  Page 4
73                 ;lda     #4
74                 ;tam     #%01000000      ; C000-DFFF  Page 5
75                 ;lda     #0
76                 ;tam     #%10000000      ; e000-fFFF  hucard/syscard bank 0
77
78                 ; Clear work RAM (2000-3FFF)
79                 stz     <$00
80                 tii     $2000, $2001, $1FFF
81
82                 ; Initialize hardware
83                 stz     TIMER_COUNT   ; Timer off
84                 lda     #$07
85                 sta     IRQ_MASK     ; Interrupts off
86                 stz     IRQ_STATUS   ; Acknowledge timer
87
88                 ;; FIXME; i dont know why the heck this one doesnt work when called from a constructor :/
89                 .import vdc_init
90                 jsr     vdc_init
91
92                 ; Turn on background and VD interrupt/IRQ1
93                 lda     #$05
94                 sta     IRQ_MASK           ; IRQ1=on
95
96                 cli
97
98                 ; Clear the BSS data
99                 jsr        zerobss
100
101                 ; Copy the .data segment to RAM
102                 lda #<(__DATA_LOAD__)
103                 sta ptr1
104                 lda #>(__DATA_LOAD__)
105                 sta ptr1+1
106                 lda #<(__DATA_RUN__)
107                 sta ptr2
108                 lda #>(__DATA_RUN__)
109                 sta ptr2+1
110
111                 ldx #>(__DATA_SIZE__)
112 @l2:
113                 beq @s1        ; no more full pages
114
115                 ; copy one page
116                 ldy #0
117 @l1:
118                 lda (ptr1),y
119                 sta (ptr2),y
120                 iny
121                 bne @l1
122
123                 inc ptr1+1
124                 inc ptr2+1
125
126                 dex
127                 bne @l2
128
129                 ; copy remaining bytes
130 @s1:
131                 ; copy one page
132                 ldy #0
133 @l3:
134                 lda (ptr1),y
135                 sta (ptr2),y
136                 iny
137                 cpy #<(__DATA_SIZE__)
138                 bne @l3
139
140                 ; setup the stack
141                 lda #<(__RAM_START__+__RAM_SIZE__)
142                 sta        sp
143                 lda #>(__RAM_START__+__RAM_SIZE__)
144                 sta        sp+1
145
146                 ; Init the Heap
147                 jsr initheap
148
149                 ; Call module constructors
150                 jsr        initlib
151
152                 ; Pass an empty command line
153                 jsr     push0                ; argc
154                 jsr     push0                ; argv
155
156                 ldy     #4                   ; Argument size
157                 jsr     _main                ; call the users code
158
159                 ; Call module destructors. This is also the _exit entry.
160 _exit:
161                 jsr        donelib                ; Run module destructors
162
163                 ; reset the PCEngine (start over)
164                 jmp start
165
166 ; ------------------------------------------------------------------------
167 ; System V-Blank Interupt
168 ; FIXME: hooks should be provided so the user can abuse the IRQ
169 ; ------------------------------------------------------------------------
170
171 _irq1:
172                 pha
173                 phx
174                 phy
175
176
177                 inc _tickcount
178                 bne @s1
179                 inc _tickcount+1
180                 bne @s1
181                 inc _tickcount+2
182                 bne @s1
183                 inc _tickcount+3
184 @s1:
185                 ; Acknowlege interrupt
186                 ldaio VDC_CTRL
187
188                 ply
189                 plx
190                 pla
191                 rti
192 _irq2:
193                 rti
194 _nmi:
195                 rti
196 _timer:
197                 stz     IRQ_STATUS
198                 rti
199
200                 .export initmainargs
201 initmainargs:
202                 rts
203
204 ; ------------------------------------------------------------------------
205 ; hardware vectors
206 ; ------------------------------------------------------------------------
207                 .segment "VECTORS"
208
209                 .word   _irq2           ; $fff6 IRQ2 (External IRQ, BRK)
210                 .word   _irq1           ; $fff8 IRQ1 (VDC)
211                 .word   _timer          ; $fffa Timer
212                 .word   _nmi            ; $fffc NMI
213                 .word   start           ; $fffe reset