]> git.sur5r.net Git - cc65/blobdiff - libsrc/pce/crt0.s
CMOS optimisation 3rd
[cc65] / libsrc / pce / crt0.s
index e456bdeacda7feff13c436ffbd44f2a44243f1fb..c9a8e8c8f19fa77f550d45f5b52d13c426d462f0 100644 (file)
 ; by Groepaz/Hitmen <groepaz@gmx.net>
 ; based on code by Ullrich von Bassewitz <uz@cc65.org>
 ;
-; This must be the *first* file on the linker command line
+; 2018-02-11, Greg King
 ;
 
-        .export _exit
-        .export __STARTUP__ : absolute = 1      ; Mark as startup
+        .export         _exit
+        .export         __STARTUP__ : absolute = 1      ; Mark as startup
 
-        .import initlib, donelib
-        .import push0, _main, zerobss
-        .import initheap
-        .import tmp1,tmp2,tmp3
+        .import         initlib, donelib
+        .import         push0, _main
+        .import         IRQStub
 
-        ; Linker generated
-        .import __RAM_START__, __RAM_SIZE__
-        .import __ROM0_START__, __ROM0_SIZE__
-        .import __ROM_START__, __ROM_SIZE__
-        .import __STARTUP_LOAD__,__STARTUP_RUN__, __STARTUP_SIZE__
-        .import __CODE_LOAD__,__CODE_RUN__, __CODE_SIZE__
-        .import __RODATA_LOAD__,__RODATA_RUN__, __RODATA_SIZE__
-        .import __DATA_LOAD__,__DATA_RUN__, __DATA_SIZE__
-        .import __BSS_SIZE__
+        ; Linker-generated
+        .import         __CARTSIZE__
+        .import         __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
+        .import         __BSS_RUN__, __BSS_SIZE__
+        .import         __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__
 
-        .include "pce.inc"
+        .include        "pce.inc"
+        .include        "extzp.inc"
 
-        .importzp sp
-        .importzp ptr1,ptr2
+        .importzp       sp
 
 ; ------------------------------------------------------------------------
 ; Place the startup code in a special segment.
 
-                .segment "STARTUP"
+        .segment "STARTUP"
 
 start:
 
-                ; setup the CPU and System-IRQ
-
-                ; Initialize CPU
-
-                sei
-                nop
-                csh                     ; set high speed CPU mode
-                nop
-                cld
-                nop
-
-                ; Setup stack and memory mapping
-                ldx     #$FF            ; Stack top ($21FF)
-                txs
-
-                ; at startup all MPRs are set to 0, so init them
-                lda     #$ff
-                tam     #%00000001      ; 0000-1FFF = Hardware page
-                lda     #$F8
-                tam     #%00000010      ; 2000-3FFF = Work RAM
-                ;lda     #$F7
-                ;tam     #%00000100      ; 4000-5FFF = Save RAM
-                ;lda     #1
-                ;tam     #%00001000      ; 6000-7FFF  Page 2
-                ;lda     #2
-                ;tam     #%00010000      ; 8000-9FFF  Page 3
-                ;lda     #3
-                ;tam     #%00100000      ; A000-BFFF  Page 4
-                ;lda     #4
-                ;tam     #%01000000      ; C000-DFFF  Page 5
-                ;lda     #0
-                ;tam     #%10000000      ; e000-fFFF  hucard/syscard bank 0
-
-                ; Clear work RAM (2000-3FFF)
-                stz     <$00
-                tii     $2000, $2001, $1FFF
-
-                ; Initialize hardware
-                stz     TIMER_COUNT   ; Timer off
-                lda     #$07
-                sta     IRQ_MASK     ; Interrupts off
-                stz     IRQ_STATUS   ; Acknowledge timer
-
-                ;; FIXME; i dont know why the heck this one doesnt work when called from a constructor :/
-                .import vdc_init
-                jsr     vdc_init
-
-                ; Turn on background and VD interrupt/IRQ1
-                lda     #$05
-                sta     IRQ_MASK           ; IRQ1=on
-
-                cli
-
-                ; Clear the BSS data
-                jsr     zerobss
-
-                ; Copy the .data segment to RAM
-                lda     #<(__DATA_LOAD__)
-                sta     ptr1
-                lda     #>(__DATA_LOAD__)
-                sta     ptr1+1
-                lda     #<(__DATA_RUN__)
-                sta     ptr2
-                lda     #>(__DATA_RUN__)
-                sta     ptr2+1
-
-                ldx     #>(__DATA_SIZE__)
-@l2:
-                beq     @s1        ; no more full pages
-
-                ; copy one page
-                ldy     #0
-@l1:
-                lda     (ptr1),y
-                sta     (ptr2),y
-                iny
-                bne     @l1
-
-                inc     ptr1+1
-                inc     ptr2+1
-
-                dex
-                bne     @l2
-
-                ; copy remaining bytes
-@s1:
-                ; copy one page
-                ldy     #0
-@l3:
-                lda     (ptr1),y
-                sta     (ptr2),y
-                iny
-                cpy     #<(__DATA_SIZE__)
-                bne     @l3
-
-                ; setup the stack
-                lda     #<(__RAM_START__+__RAM_SIZE__)
-                sta     sp
-                lda     #>(__RAM_START__+__RAM_SIZE__)
-                sta     sp+1
-
-                ; Call module constructors
-                jsr     initlib
-
-                ; Pass an empty command line
-                jsr     push0                ; argc
-                jsr     push0                ; argv
-
-                ldy     #4                   ; Argument size
-                jsr     _main                ; call the users code
-
-                ; Call module destructors. This is also the _exit entry.
+        ; Set up the CPU and System-IRQ
+
+        ; Initialize CPU
+        sei
+        nop
+        csh                     ; Set high speed CPU mode
+        nop
+        nop
+
+        ; Set up stack and memory mapping
+        ldx     #$FF            ; Stack top ($21FF)
+        txs
+
+        ; At power-on, most MPRs have random values; so, initiate them.
+        lda     #$FF
+        tam     #%00000001      ; $0000-$1FFF = Hardware bank
+        lda     #$F8
+        tam     #%00000010      ; $2000-$3FFF = Work RAM
+        ;lda     #$F7
+        ;tam     #%00000100      ; $4000-$47FF = 2K Battery-backed RAM
+        ;lda     #4
+        ;tam     #%00001000      ; $6000-$7FFF
+
+        lda     #$01
+        ldx     #>$8000
+        cpx     #>__CARTSIZE__
+        bcc     @L1             ;(blt)
+        tam     #%00010000      ; $8000-$9FFF = ROM bank 1 (32K block of ROM)
+        inc     a
+        tam     #%00100000      ; $A000-$BFFF = ROM bank 2
+        inc     a
+@L1:    tam     #%01000000      ; $C000-$DFFF = ROM bank 3 (32K) or 1 (16K)
+        ;lda    #$00            ; (The reset default)
+        ;tam    #%10000000      ; $E000-$FFFF  hucard/syscard bank 0
+
+        ; Initialize hardware
+        stz     TIMER_CTRL      ; Timer off
+        lda     #$07
+        sta     IRQ_MASK        ; Interrupts off
+        stz     IRQ_STATUS      ; Acknowledge timer
+
+        ; FIXME; i dont know why the heck this one doesnt work when called from a constructor :/
+        .import vdc_init
+        jsr     vdc_init
+
+        ; Turn on background and VD interrupt/IRQ1
+        lda     #$05
+        sta     IRQ_MASK        ; IRQ1=on
+
+        ; Copy the .data segment to RAM
+        tii     __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
+
+        ; Clear the .bss segment
+        stz     __BSS_RUN__
+        tii     __BSS_RUN__, __BSS_RUN__ + 1, __BSS_SIZE__ - 1
+
+        ; Set up the stack
+        lda     #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
+        ldx     #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
+        sta     sp
+        stx     sp + 1
+
+        ; Call module constructors
+        jsr     initlib
+
+        cli     ; allow IRQ only after constructors have run
+
+        ; Pass an empty command line
+        jsr     push0           ; argc
+        jsr     push0           ; argv
+
+        ldy     #4              ; Argument size
+        jsr     _main           ; Call the users code
+
+        ; Call module destructors. This is also the _exit entry.
 _exit:
-                jsr     donelib                ; Run module destructors
+        jsr     donelib         ; Run module destructors
 
-                ; reset the PCEngine (start over)
-                jmp start
+        ; reset the PCEngine (start over)
+        jmp     start
 
-; ------------------------------------------------------------------------
-; System V-Blank Interupt
-; FIXME: hooks should be provided so the user can abuse the IRQ
-; ------------------------------------------------------------------------
-
-_irq1:
-                pha
-                phx
-                phy
-
-
-                inc     tickcount
-                bne     @s1
-                inc     tickcount+1
-                bne     @s1
-                inc     tickcount+2
-                bne     @s1
-                inc     tickcount+3
-@s1:
-                ; Acknowlege interrupt
-                lda     a:VDC_CTRL
-
-                ply
-                plx
-                pla
-                rti
-_irq2:
-                rti
 _nmi:
-                rti
-_timer:
-                stz     IRQ_STATUS
-                rti
+        rti
 
-                .export initmainargs
+        .export initmainargs
 initmainargs:
-                rts
+        rts
 
 ; ------------------------------------------------------------------------
 ; hardware vectors
 ; ------------------------------------------------------------------------
-                .segment "VECTORS"
+        .segment "VECTORS"
 
-                .word   _irq2           ; $fff6 IRQ2 (External IRQ, BRK)
-                .word   _irq1           ; $fff8 IRQ1 (VDC)
-                .word   _timer          ; $fffa Timer
-                .word   _nmi            ; $fffc NMI
-                .word   start           ; $fffe reset
+        .word   IRQStub         ; $fff6 IRQ2 (External IRQ, BRK)
+        .word   IRQStub         ; $fff8 IRQ1 (VDC)
+        .word   IRQStub         ; $fffa Timer
+        .word   _nmi            ; $fffc NMI
+        .word   start           ; $fffe reset