]> git.sur5r.net Git - cc65/blob - libsrc/vic20/crt0.s
170ac3a39c72038d666e3e26f560c42a233d1a18
[cc65] / libsrc / vic20 / crt0.s
1 ;
2 ; Startup code for cc65 (Vic20 version)
3 ;
4
5         .export         _exit
6         .export         __STARTUP__ : absolute = 1      ; Mark as startup
7         .import         initlib, donelib, callirq
8         .import         zerobss, push0
9         .import         callmain
10         .import         RESTOR, BSOUT, CLRCH
11         .import         __INTERRUPTOR_COUNT__
12         .import         __RAM_START__, __RAM_SIZE__     ; Linker generated
13         .import         __STACKSIZE__                   ; Linker generated
14         .importzp       ST
15
16         .include        "zeropage.inc"
17         .include        "vic20.inc"
18
19 ; ------------------------------------------------------------------------
20 ; Startup code
21
22 .segment        "STARTUP"
23
24 Start:
25
26 ; Save the zero page locations we need
27
28         ldx     #zpspace-1
29 L1:     lda     sp,x
30         sta     zpsave,x
31         dex
32         bpl     L1
33
34 ; Switch to second charset
35
36         lda     #14
37         jsr     BSOUT
38
39 ; Clear the BSS data
40
41         jsr     zerobss
42
43 ; Save system stuff and setup the stack
44
45         tsx
46         stx     spsave          ; Save the system stack ptr
47
48         lda     #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
49         sta     sp
50         lda     #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
51         sta     sp+1            ; Set argument stack ptr
52
53 ; If we have IRQ functions, chain our stub into the IRQ vector
54
55         lda     #<__INTERRUPTOR_COUNT__
56         beq     NoIRQ1
57         lda     IRQVec
58         ldx     IRQVec+1
59         sta     IRQInd+1
60         stx     IRQInd+2
61         lda     #<IRQStub
62         ldx     #>IRQStub
63         sei
64         sta     IRQVec
65         stx     IRQVec+1
66         cli
67
68 ; Call module constructors
69
70 NoIRQ1: jsr     initlib
71
72 ; Push arguments and call main()
73
74         jsr     callmain
75
76 ; Back from main (This is also the _exit entry). Run module destructors
77
78 _exit:  jsr     donelib
79
80 ; Reset the IRQ vector if we chained it.
81
82         pha                     ; Save the return code on stack
83         lda     #<__INTERRUPTOR_COUNT__
84         beq     NoIRQ2
85         lda     IRQInd+1
86         ldx     IRQInd+2
87         sei
88         sta     IRQVec
89         stx     IRQVec+1
90         cli
91
92 ; Copy back the zero page stuff
93
94 NoIRQ2: ldx     #zpspace-1
95 L2:     lda     zpsave,x
96         sta     sp,x
97         dex
98         bpl     L2
99
100 ; Place the program return code into ST
101
102         pla
103         sta     ST
104
105 ; Restore the stack pointer
106
107         ldx     spsave
108         txs
109
110 ; Back to basic
111
112         rts
113
114
115 ; ------------------------------------------------------------------------
116 ; The IRQ vector jumps here, if condes routines are defined with type 2.
117
118 IRQStub:
119         cld                             ; Just to be sure
120         jsr     callirq                 ; Call the functions
121         jmp     IRQInd                  ; Jump to the saved IRQ vector
122
123 ; ------------------------------------------------------------------------
124 ; Data
125
126 .data
127
128 IRQInd: jmp     $0000
129
130 .segment        "ZPSAVE"
131
132 zpsave: .res    zpspace
133
134 .bss
135
136 spsave: .res    1