]> git.sur5r.net Git - cc65/blob - libsrc/nes/crt0.s
Moved the NES font into its own object module.
[cc65] / libsrc / nes / crt0.s
1 ;
2 ; Start-up code for cc65 (NES version)
3 ;
4 ; by Groepaz/Hitmen <groepaz@gmx.net>
5 ; based on code by Ullrich von Bassewitz <uz@cc65.org>
6 ;
7
8         .export         _exit
9         .export         __STARTUP__ : absolute = 1      ; Mark as startup
10
11         .import         initlib, donelib, callmain
12         .import         push0, _main, zerobss, copydata
13         .import         ppubuf_flush
14
15         ; Linker-generated symbols
16         .import         __RAM_START__, __RAM_SIZE__
17         .import         __SRAM_START__, __SRAM_SIZE__
18         .import         __ROM0_START__, __ROM0_SIZE__
19         .import         __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__
20         .import         __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__
21         .import         __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__
22
23 ; ------------------------------------------------------------------------
24 ; Character data
25 ; ------------------------------------------------------------------------
26         .forceimport    NESfont
27
28         .include        "zeropage.inc"
29         .include        "nes.inc"
30
31
32 ; ------------------------------------------------------------------------
33 ; 16-byte INES header
34
35 .segment        "HEADER"
36
37 ;    +--------+------+------------------------------------------+
38 ;    | Offset | Size | Content(s)                               |
39 ;    +--------+------+------------------------------------------+
40 ;    |   0    |  3   | 'NES'                                    |
41 ;    |   3    |  1   | $1A                                      |
42 ;    |   4    |  1   | 16K PRG-ROM page count                   |
43 ;    |   5    |  1   | 8K CHR-ROM page count                    |
44 ;    |   6    |  1   | ROM Control Byte #1                      |
45 ;    |        |      |   %####vTsM                              |
46 ;    |        |      |    |  ||||+- 0=Horizontal mirroring      |
47 ;    |        |      |    |  ||||   1=Vertical mirroring        |
48 ;    |        |      |    |  |||+-- 1=SRAM enabled              |
49 ;    |        |      |    |  ||+--- 1=512-byte trainer present  |
50 ;    |        |      |    |  |+---- 1=Four-screen mirroring     |
51 ;    |        |      |    |  |                                  |
52 ;    |        |      |    +--+----- Mapper # (lower 4-bits)     |
53 ;    |   7    |  1   | ROM Control Byte #2                      |
54 ;    |        |      |   %####0000                              |
55 ;    |        |      |    |  |                                  |
56 ;    |        |      |    +--+----- Mapper # (upper 4-bits)     |
57 ;    |  8-15  |  8   | $00                                      |
58 ;    | 16-..  |      | Actual 16K PRG-ROM pages (in linear      |
59 ;    |  ...   |      | order). If a trainer exists, it precedes |
60 ;    |  ...   |      | the first PRG-ROM page.                  |
61 ;    | ..-EOF |      | CHR-ROM pages (in ascending order).      |
62 ;    +--------+------+------------------------------------------+
63
64         .byte   $4e,$45,$53,$1a ; "NES"^Z
65         .byte   2               ; ines prg  - Specifies the number of 16k prg banks.
66         .byte   1               ; ines chr  - Specifies the number of 8k chr banks.
67         .byte   %00000011       ; ines mir  - Specifies VRAM mirroring of the banks.
68         .byte   %00000000       ; ines map  - Specifies the NES mapper used.
69         .byte   0,0,0,0,0,0,0,0 ; 8 zeroes
70
71
72 ; ------------------------------------------------------------------------
73 ; Place the startup code in a special segment.
74
75 .segment        "STARTUP"
76
77 start:
78
79 ; Set up the CPU and System-IRQ.
80
81         sei
82         cld
83         ldx     #0
84         stx     VBLANK_FLAG
85
86         stx     ringread
87         stx     ringwrite
88         stx     ringcount
89
90         txs
91
92         lda     #$20
93 @l:     sta     ringbuff,x
94         sta     ringbuff+$0100,x
95         sta     ringbuff+$0200,x
96         inx
97         bne     @l
98
99 ; Clear the BSS data.
100
101         jsr     zerobss
102
103 ; Initialize the data.
104         jsr     copydata
105
106 ; Set up the stack.
107
108         lda     #<(__SRAM_START__ + __SRAM_SIZE__)
109         ldx     #>(__SRAM_START__ + __SRAM_SIZE__)
110         sta     sp
111         stx     sp+1            ; Set argument stack ptr
112
113 ; Call the module constructors.
114
115         jsr     initlib
116
117 ; Push the command-line arguments; and, call main().
118
119         jsr     callmain
120
121 ; Call the module destructors. This is also the exit() entry.
122
123 _exit:  jsr     donelib         ; Run module destructors
124
125 ; Reset the NES.
126
127         jmp start
128
129 ; ------------------------------------------------------------------------
130 ; System V-Blank Interrupt
131 ; Updates PPU Memory (buffered).
132 ; Updates VBLANK_FLAG and tickcount.
133 ; ------------------------------------------------------------------------
134
135 nmi:    pha
136         tya
137         pha
138         txa
139         pha
140
141         lda     #1
142         sta     VBLANK_FLAG
143
144         inc     tickcount
145         bne     @s
146         inc     tickcount+1
147
148 @s:     jsr     ppubuf_flush
149
150         ; Reset the video counter.
151         lda     #$20
152         sta     PPU_VRAM_ADDR2
153         lda     #$00
154         sta     PPU_VRAM_ADDR2
155
156         ; Reset scrolling.
157         sta     PPU_VRAM_ADDR1
158         sta     PPU_VRAM_ADDR1
159
160         pla
161         tax
162         pla
163         tay
164         pla
165
166 ; Interrupt exit
167
168 irq:
169         rti
170
171
172 ; ------------------------------------------------------------------------
173 ; Hardware vectors
174 ; ------------------------------------------------------------------------
175
176 .segment "VECTORS"
177
178         .word   nmi         ; $fffa vblank nmi
179         .word   start       ; $fffc reset
180         .word   irq         ; $fffe irq / brk