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 77start: 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 135nmi: 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 168irq: 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 181