]> git.sur5r.net Git - cc65/blobdiff - libsrc/cbm610/crt0.s
Made Olivers devnum patch (r4588) work with the PET-II models. On these
[cc65] / libsrc / cbm610 / crt0.s
index e14596d32ce21abe075ed50bb377d31295220f0e..21874438a46d66a3e2e356264ea922ccc030f56e 100644 (file)
@@ -1,16 +1,15 @@
 ;
 ; Startup code for cc65 (CBM 600/700 version)
-;
-; This must be the *first* file on the linker command line
 ;
 
-       .export         _exit, BRKVec, UDTIM
+       .export         _exit, BRKVec
+        .export         __STARTUP__ : absolute = 1      ; Mark as startup
 
-       .import         condes, initlib, donelib
+       .import         callirq_y, initlib, donelib
        .import         push0, callmain
        .import         __BSS_RUN__, __BSS_SIZE__, __EXTZP_RUN__
-       .import         __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
-       .import         SCNKEY
+       .import         __INTERRUPTOR_COUNT__
+       .import         scnkey, UDTIM
 
        .include        "zeropage.inc"
         .include        "extzp.inc"
@@ -46,7 +45,7 @@
 ; that is overwritten later.
 ;
 
-.segment        "BASICHDR"
+.segment        "EXEHDR"
 
         .byte  $03,$00,$11,$00,$0a,$00,$81,$20,$49,$b2,$30,$20,$a4,$20,$34,$00
        .byte   $19,$00,$14,$00,$87,$20,$4a,$00,$27,$00,$1e,$00,$97,$20,$32,$35
        .byte   $32,$00,$9e,$20,$32,$35,$36,$00,$4f,$00,$3c,$00,$83,$20,$31,$32
        .byte   $30,$2c,$31,$36,$39,$2c,$31,$2c,$31,$33,$33,$2c,$30,$00,$00,$00
 
+;------------------------------------------------------------------------------
+; A table that contains values that must be transfered from the system zero
+; page into out zero page. Contains pairs of bytes, first one is the address
+; in the system ZP, second one is our ZP address. The table goes into page 2,
+; but is declared here, because it is needed earlier.
+
+.SEGMENT        "PAGE2"
+
+.proc   transfer_table
+
+        .byte   $9F, DEVNUM
+        .byte   $CA, CURS_Y
+        .byte   $CB, CURS_X
+        .byte   $CC, graphmode
+        .byte   $D4, config
+
+.endproc
+
+
+;------------------------------------------------------------------------------
+; Page 3 data. This page contains the break vector and the bankswitch
+; subroutine that is copied into high memory on startup. The space occupied by
+; this routine will later be used for a copy of the bank 15 stack. It must be
+; saved, since we're going to destroy it when calling bank 15.
+
+.segment        "PAGE3"
+
+BRKVec: .addr   _exit           ; BRK indirect vector
+
+.proc   callbank15
+
+        excrts  = $FF05
+
+.org    $FECB
+
+entry:  php
+        pha
+        lda     #$0F                    ; Bank 15
+        sta     IndReg
+        txa
+        pha
+        tya
+        pha
+        sei
+        ldy     #$FF
+        lda     (sysp1),y
+        tay
+        lda     ExecReg
+        sta     (sysp1),y
+        dey
+
+        lda     #.hibyte(excrts-1)
+        sta     (sysp1),y
+        dey
+        lda     #.lobyte(excrts-1)
+        sta     (sysp1),y
+
+        tya
+        sec
+        sbc     #7
+        sta     $1FF                    ; Save new sp
+        tay
+
+        tsx
+
+        pla
+        iny
+        sta     (sysp1),y
+        pla
+        iny
+        sta     (sysp1),y
+        pla
+        iny
+        sta     (sysp1),y
+        pla
+        iny
+        sta     (sysp1),y
+
+        lda     $105,x
+        sec
+        sbc     #3
+        iny
+        sta     (sysp1),y
+        lda     $106,x
+        sbc     #0
+        iny
+        sta     (sysp1),y
+
+        ldy     $1FF                    ; Restore sp in bank 15
+
+        lda     #.hibyte(expull-1)
+        sta     (sysp1),y
+        dey
+        lda     #.lobyte(expull-1)
+        sta     (sysp1),y
+        dey
+        pla
+        pla
+        tsx
+        stx     $1FF
+        tya
+        tax
+        txs
+        lda     IndReg
+        jmp     $FFF6
+
+expull: pla
+        tay
+        pla
+        tax
+        pla
+        plp
+        rts
+
+.if (expull <> $FF2E)
+.error "Symbol expull must be aligned with kernal in bank 15"
+.endif
+
+.reloc
+
+.endproc
+
 ;------------------------------------------------------------------------------
 ; The code in the target bank when switching back will be put at the bottom
 ; of the stack. We will jump here to switch segments. The range $F2..$FF is
 
 .segment        "STARTUP"
 
-Back:  sei
-        ldx    spsave
-       txs
-       lda     IndReg
-       sta     ExecReg
+Back:   sta    ExecReg
 
-;------------------------------------------------------------------------------
 ; We are at $100 now. The following snippet is a copy of the code that is poked
 ; in the system bank memory by the basic header program, it's only for
 ; documentation and not actually used here:
@@ -83,7 +199,7 @@ Back:        sei
 
         jmp     Origin
 
-; Hardware vectors, copied to $FFFA
+; Hardware vectors, copied to $FFF6
 
 .proc   vectors
         sta     ExecReg
@@ -112,23 +228,10 @@ Back:     sei
         .word          $eb49           ; ktab4
 .endproc
 
-; The following code is part of the kernal call subroutine. It is copied
-; to $FFAE
-
-.proc   callsysbank_15
-        php
-        pha
-        lda     #$0F                    ; Bank 15
-        sta     IndReg
-        sei
-.endproc
-
-; Save the old stack pointer from the system bank and setup our hw sp
+; Switch the indirect segment to the system bank
 
-Origin: tsx
-               stx     spsave          ; Save the system stackpointer
-       ldx     #$FE            ; Leave $1FF untouched for cross bank calls
-       txs                     ; Set up our own stack
+Origin: lda    #$0F
+       sta     IndReg
 
 ; Initialize the extended zeropage
 
@@ -138,76 +241,71 @@ L1:     lda     extzp,x
         dex
         bpl     L1
 
-; Set the interrupt, NMI and other vectors
+; Save the old stack pointer from the system bank and setup our hw sp
+
+        tsx
+        txa
+        ldy     #$FF
+        sta     (sysp1),y       ; Save system stack point into $F:$1FF
+       ldx     #$FE            ; Leave $1FF untouched for cross bank calls
+       txs                     ; Set up our own stack
 
-       ldy     #.sizeof(vectors)-1
-L2:            lda     vectors,y
-       sta     $10000 - .sizeof(vectors),y
-       dey
-               bpl     L2
+; Copy stuff from the system zeropage to ours
 
-; Switch the indirect segment to the system bank
+        lda     #.sizeof(transfer_table)
+        sta     ktmp
+L2:     ldx     ktmp
+        ldy     transfer_table-2,x
+        lda     transfer_table-1,x
+        tax
+        lda     (sysp0),y
+        sta     $00,x
+        dec     ktmp
+        dec     ktmp
+        bne     L2
 
-       lda     #$0F
-       sta     IndReg
+; Set the interrupt, NMI and other vectors
+
+       ldx     #.sizeof(vectors)-1
+L3:            lda     vectors,x
+       sta     $10000 - .sizeof(vectors),x
+       dex
+               bpl     L3
 
 ; Setup the C stack
 
-       lda     #.lobyte($FEB5 - .sizeof(callsysbank_15))
-       sta     sp
-       lda     #.hibyte($FEB5 - .sizeof(callsysbank_15))
+       lda     #.lobyte(callbank15::entry)
+       sta     sp
+       lda     #.hibyte(callbank15::entry)
        sta     sp+1
 
 ; Setup the subroutine and jump vector table that redirects kernal calls to
-; the system bank. Copy the bank switch routines starting at $FEB5 from the
-; system bank into the current bank.
-
+; the system bank.
 
-        ldy     #.sizeof(callsysbank_15)-1      ; Copy the modified part
-@L1:    lda     callsysbank_15,y
-        sta     $FEB5 - .sizeof(callsysbank_15),y
+        ldy     #.sizeof(callbank15)
+@L1:    lda     callbank15-1,y
+        sta     callbank15::entry-1,y
         dey
-        bpl     @L1
-
-        lda     #.lobyte($FEB5)                 ; Copy the ROM part
-        sta     ptr1
-        lda     #.hibyte($FEB5)
-        sta     ptr1+1
-        ldy     #$00
-@L2:    lda     (ptr1),y
-        sta     $FEB5,y
-        iny
-        cpy     #<($FF6F-$FEB5)
-        bne     @L2
+        bne     @L1
 
-; Setup the jump vector table
+; Setup the jump vector table. Y is zero on entry.
 
-        ldy     #$00
         ldx     #45-1                   ; Number of vectors
-@L3:    lda     #$20                    ; JSR opcode
+@L2:    lda     #$20                    ; JSR opcode
         sta     $FF6F,y
         iny
-        lda     #.lobyte($FEB5 - .sizeof(callsysbank_15))
+        lda     #.lobyte(callbank15::entry)
         sta     $FF6F,y
         iny
-        lda     #.hibyte($FEB5 - .sizeof(callsysbank_15))
+        lda     #.hibyte(callbank15::entry)
         sta     $FF6F,y
         iny
         dex
-        bpl     @L3
-
-; Copy the stack from the system bank into page 3
-
-        ldy     #$FF
-L4:     lda     (sysp1),y
-        sta     $300,y
-        dey
-        cpy     spsave
-        bne     L4
+        bpl     @L2
 
 ; Set the indirect segment to bank we're executing in
 
-       lda     ExecReg
+       lda     ExecReg
        sta     IndReg
 
 ; Zero the BSS segment. We will do that here instead calling the routine
@@ -229,7 +327,7 @@ Z1: sta     (ptr1),y
        iny
        bne     Z1
        inc     ptr1+1                  ; Next page
-       dex
+       dex
        bne     Z1
 
 ; Clear the remaining page
@@ -248,49 +346,69 @@ Z4:     jmp     Init
 
 .segment        "PAGE2"
 
-; Call module constructors, enable chained IRQs afterwards.
+; Activate chained interrupt handlers, then enable interrupts.
 
-Init:          jsr     initlib
-        lda     #.lobyte(__IRQFUNC_COUNT__*2)
+Init:   lda     #.lobyte(__INTERRUPTOR_COUNT__*2)
         sta     irqcount
+       cli
 
-; Enable interrupts
+; Call module constructors.
 
-       cli
+        jsr    initlib
 
 ; Push arguments and call main()
 
                jsr     callmain
 
-; Disable Call module destructors. This is also the _exit entry and the default entry
+; Call module destructors. This is also the _exit entry and the default entry
 ; point for the break vector.
 
-_exit:  lda     #$00
-        sta     irqcount        ; Disable custom irq handlers
+_exit:  pha                    ; Save the return code
         jsr    donelib         ; Run module destructors
+       lda     #$00
+        sta     irqcount        ; Disable custom irq handlers
 
-; Adress the system bank
+; Address the system bank
 
         lda     #$0F
         sta     IndReg
 
-; Copy back the old system bank stack contents
+; Copy stuff back from our zeropage to the systems
 
-        ldy     #$FF
-@L1:    lda     $300,y
-        sta     (sysp1),y
-        dey
-        cpy     spsave
-        bne     @L1
+.if 0
+        lda     #.sizeof(transfer_table)
+        sta     ktmp
+@L0:    ldx     ktmp
+        ldy     transfer_table-2,x
+        lda     transfer_table-1,x
+        tax
+        lda     $00,x
+        sta     (sysp0),y
+        dec     ktmp
+        dec     ktmp
+        bne     @L0
+.endif
+
+; Place the program return code into ST
+
+       pla
+       ldy     #$9C            ; ST
+       sta     (sysp0),y
 
 ; Setup the welcome code at the stack bottom in the system bank.
 
-        ldy     #$00
+        ldy     #$FF
+        lda     (sysp1),y       ; Load system bank sp
+        tax
+        iny                     ; Y = 0
         lda     #$58            ; CLI opcode
         sta     (sysp1),y
         iny
         lda     #$60            ; RTS opcode
         sta     (sysp1),y
+       lda     IndReg
+        sei
+       txs
         jmp     Back
 
 ; -------------------------------------------------------------------------
@@ -317,8 +435,8 @@ irq:    pha
         lda     ExecReg
         sta     IndReg                  ; Be sure to address our segment
        tsx
-               lda     $105,x                  ; Get the flags from the stack
-       and     #$10                    ; Test break flag
+               lda     $105,x                  ; Get the flags from the stack
+       and     #$10                    ; Test break flag
                bne     dobrk
 
 ; It's an IRQ
@@ -329,9 +447,7 @@ irq:    pha
 
                ldy     irqcount
         beq     irqskip
-               lda     #<__IRQFUNC_TABLE__
-       ldx     #>__IRQFUNC_TABLE__
-       jsr     condes                  ; Call the functions
+               jsr     callirq_y               ; Call the functions
 
 ; Done with chained IRQ handlers, check the TPI for IRQs and handle them
 
@@ -345,7 +461,7 @@ irqskip:lda #$0F
 
        cmp     #%00000001              ; ticker irq?
        bne     irqend
-       jsr     SCNKEY                  ; Poll the keyboard
+               jsr     scnkey                  ; Poll the keyboard
         jsr    UDTIM                   ; Bump the time
 
 ; Done
@@ -364,38 +480,9 @@ nmi:       rti
 
 dobrk:  jmp    (BRKVec)
 
-; -------------------------------------------------------------------------
-; udtim routine for the 610. We will not check for the stop key here, since
-; C programs will not use it.
-;
-
-.proc  UDTIM
-
-       inc     time
-       bne     L9
-       inc     time+1
-       bne     L9
-       inc     time+2
-       bne     L9
-       inc     time+3
-L9:    rts
-
-.endproc
-
-; -------------------------------------------------------------------------
-; Page 3
-
-.segment        "PAGE3"
-
-BRKVec: .addr   _exit           ; BRK indirect vector
-
-
 ; -------------------------------------------------------------------------
 ; Data area.
 
-.data
-spsave:        .res    1
-
 .bss
 irqcount:       .byte   0