]> git.sur5r.net Git - cc65/blob - libsrc/c128/crt0.s
Removed the call to CLRCH in the startup code.
[cc65] / libsrc / c128 / crt0.s
1 ;
2 ; Startup code for cc65 (C128 version)
3 ;
4
5         .export         _exit
6         .export         __STARTUP__ : absolute = 1      ; Mark as startup
7         .import         callirq, initlib, donelib
8         .import         zerobss
9         .import         push0, callmain
10         .import         RESTOR, BSOUT, CLRCH
11         .import         __INTERRUPTOR_COUNT__
12         .import         __RAM_START__, __RAM_SIZE__
13
14         .include        "zeropage.inc"
15         .include        "c128.inc"
16
17
18 ; ------------------------------------------------------------------------
19 ; Constants
20
21 IRQInd          = $2FD  ; JMP $0000 - used as indirect IRQ vector
22
23 ; ------------------------------------------------------------------------
24 ; BASIC header with a SYS call
25
26 .segment        "EXEHDR"
27
28         .word   Head            ; Load address
29 Head:   .word   @Next
30         .word   .version        ; Line number
31         .byte   $9E             ; SYS token
32         .byte   <(((Start / 1000) .mod 10) + $30)
33         .byte   <(((Start /  100) .mod 10) + $30)
34         .byte   <(((Start /   10) .mod 10) + $30)
35         .byte   <(((Start /    1) .mod 10) + $30)
36         .byte   $00             ; End of BASIC line
37 @Next:  .word   0               ; BASIC end marker
38
39 ; ------------------------------------------------------------------------
40 ; Startup code
41
42 .segment        "STARTUP"
43
44 Start:
45
46 ; Switch to the second charset
47
48         lda     #14
49         jsr     BSOUT
50
51 ; Before doing anything else, we have to setup our banking configuration.
52 ; Otherwise just the lowest 16K are actually RAM. Writing through the ROM
53 ; to the underlying RAM works, but it is bad style.
54
55         lda     MMU_CR          ; Get current memory configuration...
56         pha                     ; ...and save it for later
57         lda     #MMU_CFG_CC65   ; Bank0 with kernal ROM
58         sta     MMU_CR
59
60 ; Save the zero page locations we need
61
62         ldx     #zpspace-1
63 L1:     lda     sp,x
64         sta     zpsave,x
65         dex
66         bpl     L1
67
68 ; Clear the BSS data
69
70         jsr     zerobss
71
72 ; Save system stuff and setup the stack
73
74         pla                     ; Get MMU setting
75         sta     mmusave
76
77         tsx
78         stx     spsave          ; Save the system stack pointer
79
80         lda     #<(__RAM_START__ + __RAM_SIZE__)
81         sta     sp
82         lda     #>(__RAM_START__ + __RAM_SIZE__)
83         sta     sp+1            ; Set argument stack ptr
84
85 ; If we have IRQ functions, chain our stub into the IRQ vector
86
87         lda     #<__INTERRUPTOR_COUNT__
88         beq     NoIRQ1
89         lda     IRQVec
90         ldx     IRQVec+1
91         sta     IRQInd+1
92         stx     IRQInd+2
93         lda     #<IRQStub
94         ldx     #>IRQStub
95         sei
96         sta     IRQVec
97         stx     IRQVec+1
98         cli
99
100 ; Call module constructors
101
102 NoIRQ1: jsr     initlib
103
104 ; Set the bank for the file name to our execution bank. We must do this,
105 ; *after* calling constructors, because some of them may depend on the
106 ; original value of this register.
107
108         lda     #0
109         sta     FNAM_BANK
110
111 ; Push arguments and call main()
112
113         jsr     callmain
114
115 ; Back from main (this is also the _exit entry). Run module destructors
116
117 _exit:  jsr     donelib
118
119 ; Reset the IRQ vector if we chained it.
120
121         pha                             ; Save the return code on stack
122         lda     #<__INTERRUPTOR_COUNT__
123         beq     NoIRQ2
124         lda     IRQInd+1
125         ldx     IRQInd+2
126         sei
127         sta     IRQVec
128         stx     IRQVec+1
129         cli
130
131 ; Copy back the zero page stuff
132
133 NoIRQ2: ldx     #zpspace-1
134 L2:     lda     zpsave,x
135         sta     sp,x
136         dex
137         bpl     L2
138
139 ; Place the program return code into ST
140
141         pla
142         sta     ST
143
144 ; Reset the stack and the memory configuration
145
146         ldx     spsave
147         txs
148         ldx     mmusave
149         stx     MMU_CR
150
151 ; Done, restore kernal vectors in an attempt to cleanup
152
153         jmp     RESTOR
154
155 ; ------------------------------------------------------------------------
156 ; The C128 has ROM parallel to the RAM starting from $4000. The startup code
157 ; above will change this setting so that we have RAM from $0000-$BFFF. This
158 ; works quite well with the exception of interrupts: The interrupt handler
159 ; is in ROM, and the ROM switches back to the ROM configuration, which means
160 ; that parts of our program may not be accessible. To solve this, we place
161 ; the following code into a special segment called "LOWCODE" which will be
162 ; placed just above the startup code, so it goes into a RAM area that is
163 ; not banked.
164
165 .segment        "LOWCODE"
166
167 IRQStub:
168         cld                             ; Just to be sure
169         lda     MMU_CR                  ; Get old register value
170         pha                             ; And save on stack
171         lda     #MMU_CFG_CC65           ; Bank 0 with kernal ROM
172         sta     MMU_CR
173         jsr     callirq                 ; Call the functions
174         pla                             ; Get old register value
175         sta     MMU_CR
176         jmp     IRQInd                  ; Jump to the saved IRQ vector
177
178
179 ; ------------------------------------------------------------------------
180 ; Data
181
182 .segment        "ZPSAVE"
183
184 zpsave: .res    zpspace
185
186 .bss
187 spsave: .res    1
188 mmusave:.res    1
189
190
191