]> git.sur5r.net Git - cc65/blob - libsrc/lynx/crt0.s
Latest versions of startup code and config by Karri Kaksonen. Citing: The new
[cc65] / libsrc / lynx / crt0.s
1 ; ***
2 ; CC65 Lynx Library
3 ;
4 ; Originally by Bastian Schick
5 ; http://www.geocities.com/SiliconValley/Byte/4242/lynx/
6 ;
7 ; Ported to cc65 (http://www.cc65.org) by
8 ; Shawn Jefferson, June 2004
9 ;
10 ; ***
11 ;
12 ; Startup code for cc65 (Lynx version).  Based on Atari 8-bit startup
13 ; code structure.  The C stack is located at the end of the RAM memory
14 ; segment and grows downward.  Bastian Schick's executable header is put
15 ; on the front of the fully linked binary (see EXEHDR segment.)
16 ;
17
18         .include        "lynx.inc"
19         .export         _exit
20         .export         __STARTUP__ : absolute = 1      ; Mark as startup
21
22         .import         callirq, initlib, donelib
23         .import         zerobss
24         .import         callmain
25         .import         _main
26         .import         __BSS_LOAD__
27         .import         __INTERRUPTOR_COUNT__
28         .import         __RAM_START__, __RAM_SIZE__, __STACKSIZE__
29         .import         __BSS_SIZE__
30
31         .include        "zeropage.inc"
32         .include        "extzp.inc"
33
34
35 ; ------------------------------------------------------------------------
36 ; EXE header
37 __BLOCKSIZE__=1024
38         .segment "EXEHDR"
39         .byte   'L','Y','N','X'                         ; magic
40         .word   __BLOCKSIZE__                           ; bank 0 page size
41         .word   __BLOCKSIZE__                           ; bank 1 page size
42         .word   1                                       ; version number
43         .asciiz "Cart name                      "       ; 32 bytes cart name
44         .asciiz "Manufacturer   "                       ; 16 bytes manufacturer
45         .byte   0                                       ; rotation 1=left
46                                                         ; rotation 2=right
47         .byte   0,0,0,0,0                               ; spare
48
49 __LOADER_SIZE__=410
50
51         ; The cart starts with an encrypted loader for 1024 bytes/block
52         ; images. The size of the loader is 410 bytes followed by two
53         ; mandatory directory entries.
54         .byte   $FD,$C1,$0D,$8E,$E9,$EE,$09,$13,$E5,$96
55         .byte   $0C,$34,$64,$DA,$D4,$BB,$99,$EC,$CE,$4F
56         .byte   $AA,$8C,$ED,$65,$F0,$32,$70,$A3,$84,$C4
57         .byte   $FC,$A2,$6D,$3A,$F8,$77,$4B,$AC,$9B,$54
58         .byte   $7D,$82,$6F,$F8,$A5,$06,$4D,$7B,$77,$55
59         .byte   $E4,$31,$C4,$2C,$2F,$2F,$B6,$4D,$15,$A9
60         .byte   $C7,$99,$5D,$6E,$B3,$97,$92,$44,$7B,$2B
61         .byte   $85,$18,$E6,$F1,$96,$F4,$C4,$DE,$A4,$CF
62         .byte   $79,$E2,$C1,$1A,$E0,$0C,$93,$C5,$26,$BD
63         .byte   $A3,$16,$8A,$C3,$59,$A0,$39,$38,$A0,$3B
64         .byte   $EF,$BB,$1D,$5C,$0D,$1D,$CC,$48,$1D,$DD
65         .byte   $98,$9A,$7A,$F7,$96,$F9,$61,$03,$50,$DA
66         .byte   $47,$69,$94,$C3,$80,$DA,$A9,$99,$A1,$21
67         .byte   $2B,$2E,$7D,$F5,$E4,$F7,$B3,$5C,$A8,$14
68         .byte   $FA,$E9,$06,$AC,$1E,$9F,$B5,$31,$BE,$42
69         .byte   $14,$08,$0E,$05,$FB,$25,$BB,$5C,$5C,$66
70         .byte   $76,$8E,$36,$E8,$EB,$39,$F2,$26,$BD,$17
71         .byte   $29,$F4,$B8,$1D,$7E,$EE,$47,$61,$BB,$9E
72         .byte   $F5,$72,$C9,$BC,$26,$37,$D5,$78,$8F,$D0
73         .byte   $CE,$95,$21,$EB,$4A,$07,$8D,$3A,$3A,$01
74         .byte   $82,$CF,$01,$C5,$1E,$1D,$A8,$41,$4F,$BD
75         .byte   $C1,$76,$22,$A3,$88,$D9,$57,$C9,$51,$3A
76         .byte   $26,$BE,$4A,$1A,$7F,$42,$61,$CF,$FC,$FC
77         .byte   $5B,$06,$94,$D2,$2C,$78,$45,$BA,$93,$C4
78         .byte   $7D,$7C,$81,$73,$07,$4F,$E2,$6C,$E9,$81
79         .byte   $1A,$DE,$77,$74,$87,$DE,$26,$9E,$7A,$A8
80         .byte   $19,$A7,$34,$32,$70,$ED,$59,$A8,$4A,$D8
81         .byte   $FE,$CB,$DD,$02,$2F,$CE,$92,$E9,$13,$A6
82         .byte   $FF,$B4,$4B,$18,$9D,$63,$48,$E0,$3B,$3B
83         .byte   $0D,$2B,$FC,$04,$A4,$E3,$5E,$4C,$3C,$94
84         .byte   $70,$C4,$F0,$64,$15,$48,$68,$17,$DE,$14
85         .byte   $72,$F0,$59,$33,$4C,$49,$47,$8D,$B6,$F4
86         .byte   $82,$4E,$B7,$4E,$01,$C9,$C2,$82,$0B,$7A
87         .byte   $AC,$67,$9B,$0F,$04,$E1,$B6,$78,$34,$C8
88         .byte   $4F,$2A,$11,$ED,$D0,$1C,$6D,$CD,$3D,$47
89         .byte   $09,$8B,$E5,$38,$19,$7A,$31,$6E,$30,$71
90         .byte   $1C,$90,$34,$E5,$44,$CC,$00,$C7,$41,$D0
91         .byte   $27,$8A,$06,$29,$5C,$2B,$E4,$26,$63,$09
92         .byte   $52,$D3,$97,$33,$D7,$59,$1C,$36,$2F,$C9
93         .byte   $A9,$A2,$B5,$BB,$A9,$1D,$E6,$36,$7E,$56
94         .byte   $05,$A4,$9C,$E0,$45,$59,$21,$E1,$E6,$21
95
96         ; The directory structure required by the 410 byte bootloader
97 __DIRECTORY_START__:
98 ; Entry 0 - title sprite (mandatory)
99 off0=__LOADER_SIZE__+(__DIRECTORY_END__-__DIRECTORY_START__)
100 blocka=off0/__BLOCKSIZE__
101 len0=(__TITLE_END__-__TITLE_START__)
102         .byte   <blocka
103         .word   off0 & (__BLOCKSIZE__ - 1)
104         .byte   $00
105         .word   __TITLE_START__
106         .word   len0
107
108 ; Entry 1 - first executable (mandatory)
109 off1=off0+len0
110 block1=off1/__BLOCKSIZE__
111 len1=__RAM_SIZE__-__BSS_SIZE__
112         .byte   <block1
113         .word   off1 & (__BLOCKSIZE__ - 1)
114         .byte   $88
115         .word   __RAM_START__
116         .word   len1
117 __DIRECTORY_END__:
118         .org $b000
119 __TITLE_START__:
120         ; The palette for the title sprite. Complete black.
121         .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
122         .byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
123         ; The title sprite
124 cls_sprite:
125         .byte   %00000001                       ; A pixel sprite
126         .byte   %00010000
127         .byte   %00100000
128         .addr   0,pixel_bitmap
129         .word   0
130         .word   0
131         .word   $a000                           ; 160
132         .word   $6600                           ; 102
133         .byte   $00
134 pixel_bitmap:
135         .byte   3,%10000100,%00000000, $0       ; A pixel bitmap
136 __TITLE_END__:
137         .reloc
138
139 ; ------------------------------------------------------------------------
140 ; Mikey and Suzy init data, reg offsets and data
141
142         .rodata
143
144 SuzyInitReg:    .byte $28,$2a,$04,$06,$92,$83,$90
145 SuzyInitData:   .byte $7f,$7f,$00,$00,$24,$f3,$01
146
147 MikeyInitReg:   .byte $00,$01,$08,$09,$20,$28,$30,$38,$44,$50,$8a,$8b,$8c,$92,$93
148 MikeyInitData:  .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$29
149
150
151 ; ------------------------------------------------------------------------
152 ; Actual code
153
154         .segment "STARTUP"
155
156 ; set up system
157
158         sei
159         cld
160         ldx     #$FF
161         txs
162
163 ; init bank switching
164
165         lda     #$C
166         sta     MAPCTL                  ; $FFF9
167
168 ; disable all timer interrupts
169
170         lda     #$80
171         trb     TIM0CTLA
172         trb     TIM1CTLA
173         trb     TIM2CTLA
174         trb     TIM3CTLA
175         trb     TIM5CTLA
176         trb     TIM6CTLA
177         trb     TIM7CTLA
178
179 ; disable TX/RX IRQ, set to 8E1
180
181         lda     #%11101
182         sta     SERCTL
183
184 ; clear all pending interrupts
185
186         lda     INTSET
187         sta     INTRST
188
189 ; setup the stack
190
191         lda     #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
192         sta     sp
193         lda     #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
194         sta     sp+1
195
196 ; Init Mickey
197
198         ldx     #.sizeof(MikeyInitReg)-1
199 mloop:  ldy     MikeyInitReg,x
200         lda     MikeyInitData,x
201         sta     $fd00,y
202         dex
203         bpl     mloop
204
205 ; these are RAM-shadows of read only regs
206
207         ldx     #$1b
208         stx     __iodat
209         dex                             ; $1A
210         stx     __iodir
211         ldx     #$d
212         stx     __viddma
213
214 ; Init Suzy
215
216         ldx     #.sizeof(SuzyInitReg)-1
217 sloop:  ldy     SuzyInitReg,x
218         lda     SuzyInitData,x
219         sta     $fc00,y
220         dex
221         bpl     sloop
222
223         lda     #$24
224         sta     __sprsys
225
226 ; Clear the BSS data
227
228         jsr     zerobss
229
230 ; If we have IRQ functions, set the IRQ vector
231 ; as Lynx is a console there is not much point in releasing the IRQ
232
233         lda     #<__INTERRUPTOR_COUNT__
234         beq     NoIRQ1
235         lda     #<IRQStub
236         ldx     #>IRQStub
237         sei
238         sta     INTVECTL
239         stx     INTVECTH
240         cli
241
242 ; Call module constructors
243
244 NoIRQ1: jsr     initlib
245
246 ; Push arguments and call main
247
248         jsr     callmain
249
250 ; Call module destructors. This is also the _exit entry.
251
252 _exit:  jsr     donelib         ; Run module destructors
253
254 ; Endless loop
255
256 noret:  bra     noret
257
258
259         .segment "CODE"
260 IRQStub:
261         phy
262         phx
263         pha
264         cld
265         jsr     callirq
266         lda     INTSET
267         sta     INTRST
268         pla
269         plx
270         ply
271         rti
272