]> git.sur5r.net Git - cc65/blob - libsrc/pce/crt0.s
f89119c467491564b127498d1d0fa215148f2744
[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 ; Place the startup code in a special segment.
35
36         .segment "STARTUP"
37
38 start:
39
40         ; setup the CPU and System-IRQ
41
42         ; Initialize CPU
43
44         sei
45         nop
46         csh                     ; set high speed CPU mode
47         nop
48         cld
49         nop
50
51         ; Setup stack and memory mapping
52         ldx     #$FF            ; Stack top ($21FF)
53         txs
54
55         ; at startup all MPRs are set to 0, so init them
56         lda     #$ff
57         tam     #%00000001      ; 0000-1FFF = Hardware page
58         lda     #$F8
59         tam     #%00000010      ; 2000-3FFF = Work RAM
60
61         ; FIXME: setup a larger block of memory to use with C-code
62         ;lda     #$F7
63         ;tam     #%00000100      ; 4000-5FFF = Save RAM
64         ;lda     #1
65         ;tam     #%00001000      ; 6000-7FFF  Page 2
66         ;lda     #2
67         ;tam     #%00010000      ; 8000-9FFF  Page 3
68         ;lda     #3
69         ;tam     #%00100000      ; A000-BFFF  Page 4
70         ;lda     #4
71         ;tam     #%01000000      ; C000-DFFF  Page 5
72         ;lda     #0
73         ;tam     #%10000000      ; e000-fFFF  hucard/syscard bank 0
74
75         ; Clear work RAM (2000-3FFF)
76         stz     <$00
77         tii     $2000, $2001, $1FFF
78
79         ; Initialize hardware
80         stz     TIMER_COUNT     ; Timer off
81         lda     #$07
82         sta     IRQ_MASK        ; Interrupts off
83         stz     IRQ_STATUS      ; Acknowledge timer
84
85         ; FIXME; i dont know why the heck this one doesnt work when called from a constructor :/
86         .import vdc_init
87         jsr     vdc_init
88
89         ; Turn on background and VD interrupt/IRQ1
90         lda     #$05
91         sta     IRQ_MASK        ; IRQ1=on
92
93         ; Clear the BSS data
94         jsr     zerobss
95
96         ; Copy the .data segment to RAM
97         lda     #<(__DATA_LOAD__)
98         sta     ptr1
99         lda     #>(__DATA_LOAD__)
100         sta     ptr1+1
101         lda     #<(__DATA_RUN__)
102         sta     ptr2
103         lda     #>(__DATA_RUN__)
104         sta     ptr2+1
105
106         ldx     #>(__DATA_SIZE__)
107 @l2:
108         beq     @s1             ; no more full pages
109
110         ; copy one page
111         ldy     #0
112 @l1:
113         lda     (ptr1),y
114         sta     (ptr2),y
115         iny
116         bne     @l1
117
118         inc     ptr1+1
119         inc     ptr2+1
120
121         dex
122         bne     @l2
123
124         ; copy remaining bytes
125 @s1:
126         ; copy one page
127         ldy     #0
128 @l3:
129         lda     (ptr1),y
130         sta     (ptr2),y
131         iny
132         cpy     #<(__DATA_SIZE__)
133         bne     @l3
134
135         ; setup the stack
136         lda     #<(__RAM_START__+__RAM_SIZE__)
137         sta     sp
138         lda     #>(__RAM_START__+__RAM_SIZE__)
139         sta     sp + 1
140
141         ; Call module constructors
142         jsr     initlib
143
144         cli     ; allow IRQ only after constructors have run
145
146         ; Pass an empty command line
147         jsr     push0           ; argc
148         jsr     push0           ; argv
149
150         ldy     #4              ; Argument size
151         jsr     _main           ; call the users code
152
153         ; Call module destructors. This is also the _exit entry.
154 _exit:
155         jsr     donelib         ; Run module destructors
156
157         ; reset the PCEngine (start over)
158         jmp     start
159
160 ; ------------------------------------------------------------------------
161 ; System V-Blank Interupt
162 ; FIXME: hooks should be provided so the user can abuse the IRQ
163 ; ------------------------------------------------------------------------
164
165 _irq1:
166         pha
167         phx
168         phy
169
170         ; increment the system tick counter
171         inc     tickcount
172         bne     @s1
173         inc     tickcount + 1
174         bne     @s1
175         inc     tickcount + 2
176         bne     @s1
177         inc     tickcount + 3
178 @s1:
179         ; Acknowlege interrupt
180         lda     a:VDC_CTRL
181
182         ply
183         plx
184         pla
185         rti
186 _irq2:
187         rti
188 _nmi:
189         rti
190 _timer:
191         stz     IRQ_STATUS
192         rti
193
194         .export initmainargs
195 initmainargs:
196         rts
197
198 ; ------------------------------------------------------------------------
199 ; hardware vectors
200 ; ------------------------------------------------------------------------
201         .segment "VECTORS"
202
203         .word   _irq2           ; $fff6 IRQ2 (External IRQ, BRK)
204         .word   _irq1           ; $fff8 IRQ1 (VDC)
205         .word   _timer          ; $fffa Timer
206         .word   _nmi            ; $fffc NMI
207         .word   start           ; $fffe reset