mirror of
https://github.com/cc65/cc65.git
synced 2024-10-30 12:28:25 +00:00
8216bf1d6a
main() is encountered. Define this symbol in the startup code. This will automatically force linking of the startup code which can then reside inside the standard library as any other object file. git-svn-id: svn://svn.cc65.org/cc65/trunk@3988 b7a2c559-68d2-44c3-8de9-860c34a00d81
190 lines
5.3 KiB
ArmAsm
190 lines
5.3 KiB
ArmAsm
;
|
|
; Startup code for cc65 (NES version)
|
|
;
|
|
; by Groepaz/Hitmen <groepaz@gmx.net>
|
|
; based on code by Ullrich von Bassewitz <uz@cc65.org>
|
|
;
|
|
|
|
.export _exit
|
|
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
|
.import initlib, donelib, callmain
|
|
.import push0, _main, zerobss, copydata
|
|
.import ppubuf_flush
|
|
|
|
; Linker generated symbols
|
|
.import __RAM_START__, __RAM_SIZE__
|
|
.import __SRAM_START__, __SRAM_SIZE__
|
|
.import __ROM0_START__, __ROM0_SIZE__
|
|
.import __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__
|
|
.import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__
|
|
.import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__
|
|
|
|
.include "zeropage.inc"
|
|
.include "nes.inc"
|
|
|
|
|
|
; ------------------------------------------------------------------------
|
|
; 16 bytes INES header
|
|
|
|
.segment "HEADER"
|
|
|
|
; +--------+------+------------------------------------------+
|
|
; | Offset | Size | Content(s) |
|
|
; +--------+------+------------------------------------------+
|
|
; | 0 | 3 | 'NES' |
|
|
; | 3 | 1 | $1A |
|
|
; | 4 | 1 | 16K PRG-ROM page count |
|
|
; | 5 | 1 | 8K CHR-ROM page count |
|
|
; | 6 | 1 | ROM Control Byte #1 |
|
|
; | | | %####vTsM |
|
|
; | | | | ||||+- 0=Horizontal mirroring |
|
|
; | | | | |||| 1=Vertical mirroring |
|
|
; | | | | |||+-- 1=SRAM enabled |
|
|
; | | | | ||+--- 1=512-byte trainer present |
|
|
; | | | | |+---- 1=Four-screen mirroring |
|
|
; | | | | | |
|
|
; | | | +--+----- Mapper # (lower 4-bits) |
|
|
; | 7 | 1 | ROM Control Byte #2 |
|
|
; | | | %####0000 |
|
|
; | | | | | |
|
|
; | | | +--+----- Mapper # (upper 4-bits) |
|
|
; | 8-15 | 8 | $00 |
|
|
; | 16-.. | | Actual 16K PRG-ROM pages (in linear |
|
|
; | ... | | order). If a trainer exists, it precedes |
|
|
; | ... | | the first PRG-ROM page. |
|
|
; | ..-EOF | | CHR-ROM pages (in ascending order). |
|
|
; +--------+------+------------------------------------------+
|
|
|
|
.byte $4e,$45,$53,$1a ; "NES"^Z
|
|
.byte 2 ; ines prg - Specifies the number of 16k prg banks.
|
|
.byte 1 ; ines chr - Specifies the number of 8k chr banks.
|
|
.byte %00000011 ; ines mir - Specifies VRAM mirroring of the banks.
|
|
.byte %00000000 ; ines map - Specifies the NES mapper used.
|
|
.byte 0,0,0,0,0,0,0,0 ; 8 zeroes
|
|
|
|
|
|
; ------------------------------------------------------------------------
|
|
; Place the startup code in a special segment.
|
|
|
|
.segment "STARTUP"
|
|
|
|
start:
|
|
|
|
; setup the CPU and System-IRQ
|
|
|
|
sei
|
|
cld
|
|
ldx #0
|
|
stx VBLANK_FLAG
|
|
|
|
stx ringread
|
|
stx ringwrite
|
|
stx ringcount
|
|
|
|
txs
|
|
|
|
lda #$20
|
|
@l: sta ringbuff,x
|
|
sta ringbuff+$0100,x
|
|
sta ringbuff+$0200,x
|
|
inx
|
|
bne @l
|
|
|
|
; Clear the BSS data
|
|
|
|
jsr zerobss
|
|
|
|
; initialize data
|
|
jsr copydata
|
|
|
|
; setup the stack
|
|
|
|
lda #<(__SRAM_START__ + __SRAM_SIZE__)
|
|
sta sp
|
|
lda #>(__SRAM_START__ + __SRAM_SIZE__)
|
|
sta sp+1 ; Set argument stack ptr
|
|
|
|
; Call module constructors
|
|
|
|
jsr initlib
|
|
|
|
; Push arguments and call main()
|
|
|
|
jsr callmain
|
|
|
|
; Call module destructors. This is also the _exit entry.
|
|
|
|
_exit: jsr donelib ; Run module destructors
|
|
|
|
; Reset the NES
|
|
|
|
jmp start
|
|
|
|
; ------------------------------------------------------------------------
|
|
; System V-Blank Interupt
|
|
; updates PPU Memory (buffered)
|
|
; updates VBLANK_FLAG and tickcount
|
|
; ------------------------------------------------------------------------
|
|
|
|
nmi: pha
|
|
tya
|
|
pha
|
|
txa
|
|
pha
|
|
|
|
lda #1
|
|
sta VBLANK_FLAG
|
|
|
|
inc tickcount
|
|
bne @s
|
|
inc tickcount+1
|
|
|
|
@s: jsr ppubuf_flush
|
|
|
|
; reset the video counter
|
|
lda #$20
|
|
sta PPU_VRAM_ADDR2
|
|
lda #$00
|
|
sta PPU_VRAM_ADDR2
|
|
|
|
; reset scrolling
|
|
sta PPU_VRAM_ADDR1
|
|
sta PPU_VRAM_ADDR1
|
|
|
|
pla
|
|
tax
|
|
pla
|
|
tay
|
|
pla
|
|
|
|
; Interrupt exit
|
|
|
|
irq2:
|
|
irq1:
|
|
timerirq:
|
|
irq:
|
|
rti
|
|
|
|
; ------------------------------------------------------------------------
|
|
; hardware vectors
|
|
; ------------------------------------------------------------------------
|
|
|
|
.segment "VECTORS"
|
|
|
|
.word irq2 ; $fff4 ?
|
|
.word irq1 ; $fff6 ?
|
|
.word timerirq ; $fff8 ?
|
|
.word nmi ; $fffa vblank nmi
|
|
.word start ; $fffc reset
|
|
.word irq ; $fffe irq / brk
|
|
|
|
; ------------------------------------------------------------------------
|
|
; character data
|
|
; ------------------------------------------------------------------------
|
|
|
|
.segment "CHARS"
|
|
|
|
.include "neschar.inc"
|
|
|
|
|