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