]> git.sur5r.net Git - cc65/blobdiff - libsrc/cbm610/crt0.s
Merge pull request #692 from ops/cbmkernal_stage2
[cc65] / libsrc / cbm610 / crt0.s
index 5a9a9011b66c70b05a78863b533c50df339ec6c2..0ad343d7ffded05e29d0ec9391d4f26c8bcc9333 100644 (file)
@@ -1,59 +1,30 @@
 ;
-; Startup code for cc65 (Plus/4 version)
-;
-; This must be the *first* file on the linker command line
+; Startup code for cc65 (CBM 600/700 version)
 ;
 
-       .export         _exit
-       .import         __hinit, push0, doatexit, _main
-       .import         initconio
-       .import         __BSS_RUN__, __BSS_SIZE__
-       .import         irq, nmi
-               .import         k_irq, k_nmi, k_plot, k_udtim, k_scnkey
+        .export         _exit, BRKVec
+        .export         __STARTUP__ : absolute = 1      ; Mark as startup
 
-       .include        "zeropage.inc"
-       .include        "io.inc"
+        .import         callirq_y, initlib, donelib
+        .import         push0, callmain
+        .import         __BSS_RUN__, __BSS_SIZE__, __EXTZP_RUN__
+        .import         __INTERRUPTOR_COUNT__
+        .import         scnkey, UDTIM
 
+        .include        "zeropage.inc"
+        .include        "extzp.inc"
+        .include        "cbm610.inc"
 
-; ------------------------------------------------------------------------
-; Define and export the ZP variables for the CBM610 runtime
-
-       .exportzp       sp, sreg, regsave
-       .exportzp       ptr1, ptr2, ptr3, ptr4
-       .exportzp       tmp1, tmp2, tmp3, tmp4
-       .exportzp       regbank, zpspace
-       .exportzp       crtc, sid, IPCcia, cia, acia, tpi1, tpi2
-       .exportzp       ktab1, ktab2, ktab3, ktab4, time, RecvBuf, SendBuf
-
-.zeropage
-
-zpstart        = *
-sp:            .res    2       ; Stack pointer
-sreg:          .res    2       ; Secondary register/high 16 bit for longs
-regsave:       .res    2       ; slot to save/restore (E)AX into
-ptr1:          .res    2
-ptr2:          .res    2
-ptr3:          .res    2
-ptr4:          .res    2
-tmp1:          .res    1
-tmp2:          .res    1
-tmp3:          .res    1
-tmp4:          .res    1
-regbank:       .res    6       ; 6 byte register bank
-
-zpspace        = * - zpstart           ; Zero page space allocated
-
-.code
 
 ; ------------------------------------------------------------------------
-; BASIC header and a small BASIC program. Since it is not possible to start
+; The BASIC header and a small BASIC program. Since it isn't possible to start
 ; programs in other banks using SYS, the BASIC program will write a small
-; machine code program into memory at $100 and start that machine code
+; machine code program into memory at $100; and, start that machine code
 ; program. The machine code program will then start the machine language
 ; code in bank 1, which will initialize the system by copying stuff from
 ; the system bank, and start the application.
 ;
-; Here's the basic program that's in the following lines:
+; Here's the BASIC program that's in the following lines:
 ;
 ; 10 for i=0 to 4
 ; 20 read j
@@ -65,353 +36,454 @@ zpspace   = * - zpstart           ; Zero page space allocated
 ; The machine program in the data lines is:
 ;
 ; sei
-; lda    #$01
-; sta     $00          <-- Switch to bank 1 after this command
+; lda     #$01
+; sta     $00           <-- Switch to bank 1 after this command
 ;
-; Initialization is not only complex because of the jumping from one bank
-; into another. but also because we want to save memory, and because of
-; this, we will use the system memory ($00-$3FF) for initialization stuff
+; Initialization is complex not only because of the jumping from one bank
+; into another. but also because we want to save memory; and because of
+; that, we will use the system memory ($00-$3FF) for initialization stuff
 ; that is overwritten later.
 ;
 
-; To make things more simple, make the code of this module absolute.
-
-       .org    $0001
-Head:  .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   $36,$aa,$49,$2c,$4a,$00,$2f,$00,$28,$00,$82,$20,$49,$00,$39,$00
-       .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
-
-; Since we need some vectors to access stuff in the system bank for our own,
-; we will include them here, starting from $60:
+.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   $36,$aa,$49,$2c,$4a,$00,$2f,$00,$28,$00,$82,$20,$49,$00,$39,$00
+        .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 transferred from the system zero-
+; page into our 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"
+
+; (We use .proc because we need both a label and a scope.)
+
+.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        ; In bank 15 ROM
+
+.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
 
-       .res    $60-*
+.if (expull <> $FF2E)
+.error "Symbol expull must be aligned with Kernal in bank 15"
+.endif
 
-crtc:                  .word   $d800
-sid:           .word   $da00
-IPCcia:                .word   $db00
-cia:                   .word   $dc00
-acia:                  .word   $dd00
-tpi1:          .word   $de00
-tpi2:                  .word   $df00
-ktab1:         .word   $ea29
-ktab2:         .word   $ea89
-ktab3:         .word   $eae9
-ktab4:         .word   $eb49
-time:          .dword  $0000
-RecvBuf:       .word   $0100           ; RS232 received buffer
-SendBuf:       .word   $0200           ; RS232 send buffer
+.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
-; not used by any kernal routine.
+; not used by any Kernal routine.
 
-       .res    $F8-*
-Back:  ldx     spsave
-       txs
-       lda     IndReg
-       sta     ExecReg
+.segment        "STARTUP"
 
-; The following code 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:
+Back:   sta     ExecReg
 
-       sei
-       lda     #$01
-       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:
+
+        sei
+        lda     #$01
+        sta     ExecReg
 
 ; This is the actual starting point of our code after switching banks for
 ; startup. Beware: The following code will get overwritten as soon as we
-; use the stack (since it's in page 1)!
-
-       tsx
-               stx     spsave          ; Save the system stackpointer
-       ldx     #$FF
-       txs                     ; Set up our own stack
-
-; Set the interrupt, NMI and other vectors
-
-       ldy     #vectable_size
-L0:    lda     vectable-1,y
-       sta     $FF80,y
-       dey
-               bne     L0
-
-; Switch the indirect segment to the system bank
+; use the stack (since it's in page 1)! We jump to another location since
+; we need some space for subroutines that aren't used later.
 
-       lda     #$0F
-       sta     IndReg
+        jmp     Origin
 
-; Copy the kernal zero page ($90-$F2) from the system bank
+; Hardware vectors, copied to $FFF6
 
-       lda     #$90
-       sta     ptr1
-       lda     #$00
-       sta     ptr1+1
-       ldy     #$62-1
-L1:    lda     (ptr1),y
-       sta     $90,y
-       dey
-       bpl     L1
-
-; Copy the page 3 vectors in place
-
-       ldy     #$00
-L2:    lda     p3vectable,y
-       sta     $300,y
-       iny
-       cpy     #p3vectable_size
-               bne     L2
-
-; Copy the rest of page 3 from the system bank
-
-       lda     #$00
-       sta     ptr1
-       lda     #$03
-       sta     ptr1+1
-L3:    lda     (ptr1),y
-       sta     $300,y
-       iny
-       bne     L3
-
-; Set the indirect segment to bank we're executing in
-
-       lda     ExecReg
-       sta     IndReg
-
-; Zero the BSS segment. We will do that here instead calling the routine
-; in the common library, since we have the memory anyway, and this way,
+.proc   vectors
+        sta     ExecReg
+        rts
+        nop
+        .word   nmi             ; NMI vector
+        .word   0               ; Reset -- not used
+        .word   irq             ; IRQ vector
+.endproc
+
+; Initializers for the extended zero-page. See "extzp.s".
+
+.proc   extzp
+        .word   $0100           ; sysp1
+        .word   $0300           ; sysp3
+        .word   $d800           ; crtc
+        .word   $da00           ; sid
+        .word   $db00           ; ipccia
+        .word   $dc00           ; cia
+        .word   $dd00           ; acia
+        .word   $de00           ; tpi1
+        .word   $df00           ; tpi2
+        .word   $ea29           ; ktab1
+        .word   $ea89           ; ktab2
+        .word   $eae9           ; ktab3
+        .word   $eb49           ; ktab4
+.endproc
+
+; Switch the indirect segment to the system bank.
+
+Origin: lda     #$0F
+        sta     IndReg
+
+; Initialize the extended zero-page.
+
+        ldx     #.sizeof(extzp)-1
+L1:     lda     extzp,x
+        sta     <__EXTZP_RUN__,x
+        dex
+        bpl     L1
+
+; Save the old stack pointer from the system bank; and, set up 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
+
+; Copy stuff from the system zero-page to ours.
+
+        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
+
+; Set the interrupt, NMI, and other vectors.
+
+        ldx     #.sizeof(vectors)-1
+L3:     lda     vectors,x
+        sta     $10000 - .sizeof(vectors),x
+        dex
+        bpl     L3
+
+; Set up the C stack.
+
+        lda     #.lobyte(callbank15::entry)
+        sta     sp
+        lda     #.hibyte(callbank15::entry)
+        sta     sp+1
+
+; Set up the subroutine and jump vector table that redirects Kernal calls to
+; the system bank.
+
+        ldy     #.sizeof(callbank15)
+@L1:    lda     callbank15-1,y
+        sta     callbank15::entry-1,y
+        dey
+        bne     @L1
+
+; Set up the jump vector table. Y is zero on entry.
+
+        ldx     #45-1           ; Number of vectors
+@L2:    lda     #$20            ; JSR opcode
+        sta     $FF6F,y
+        iny
+        lda     #.lobyte(callbank15::entry)
+        sta     $FF6F,y
+        iny
+        lda     #.hibyte(callbank15::entry)
+        sta     $FF6F,y
+        iny
+        dex
+        bpl     @L2
+
+; Set the indirect segment to the bank that we're executing in.
+
+        lda     ExecReg
+        sta     IndReg
+
+; Zero the BSS segment. We will do that here instead of calling the routine
+; in the common library, since we have the memory anyway; and this way,
 ; it's reused later.
 
-       lda     #<__BSS_RUN__
-       sta     ptr1
-       lda     #>__BSS_RUN__
-       sta     ptr1+1
-       lda     #0
-       tay
-
-; Clear full pages
-
-       ldx     #>__BSS_SIZE__
-       beq     Z2
-Z1:    sta     (ptr1),y
-       iny
-       bne     Z1
-       inc     ptr1+1                  ; Next page
-       dex
-       bne     Z1
-
-; Clear the remaining page
-
-Z2:    ldx     #<__BSS_SIZE__
-       beq     Z4
-Z3:    sta     (ptr1),y
-       iny
-       dex
-       bne     Z3
-Z4:
-
-; Setup the C stack
-
-       lda     #<$FF81
-       sta     sp
-               lda     #>$FF81
-       sta     sp+1
-
-; We expect to be in page 2 now
-
-.if    (* < $1FD)
-       jmp     $200
-       .res    $200-*
-.endif
-.if    (* < $200)
-       .res    $200-*,$EA
-.endif
-.if            (* >= $2F0)
-.error "Code range invalid"
-.endif
-
-; This code is in page 2, so we may now start calling subroutines safely,
-; since the code we execute is no longer in the stack page.
-
-       jsr     __hinit                 ; Initialize the heap
-       jsr     initconio               ; Initialize conio stuff
-
-; Create the (empty) command line for the program
-
-               jsr     push0           ; argc
-               jsr     push0           ; argv
-
-; Execute the program code
-
-       jmp     Start
-
-; ------------------------------------------------------------------------
-; Additional data that we need for initialization and that's overwritten
-; later
-
-vectable:
-       jmp     $0000           ; CINT
-       jmp     $0000           ; IOINIT
-       jmp     $0000           ; RAMTAS
-       jmp     $0000           ; RESTOR
-       jmp     $0000           ; VECTOR
-       jmp     $0000           ; SETMSG
-       jmp     $0000           ; SECOND
-       jmp     $0000           ; TKSA
-       jmp     $0000           ; MEMTOP
-       jmp     $0000           ; MEMBOT
-       jmp     k_scnkey        ; SCNKEY
-       jmp     $0000           ; SETTMO
-       jmp     $0000           ; ACPTR
-       jmp     $0000           ; CIOUT
-       jmp     $0000           ; UNTLK
-       jmp     $0000           ; UNLSN
-       jmp     $0000           ; LISTEN
-       jmp     $0000           ; TALK
-       jmp     $0000           ; READST
-               jmp     k_setlfs        ; SETLFS
-               jmp     k_setnam        ; SETNAM
-       jmp     $0000           ; OPEN
-       jmp     $0000           ; CLOSE
-       jmp     $0000           ; CHKIN
-       jmp     $0000           ; CKOUT
-       jmp     $0000           ; CLRCH
-       jmp     $0000           ; BASIN
-       jmp     $0000           ; BSOUT
-       jmp     $0000           ; LOAD
-       jmp     $0000           ; SAVE
-       jmp     k_settim        ; SETTIM
-               jmp     k_rdtim         ; RDTIM
-       jmp     $0000           ; STOP
-       jmp     $0000           ; GETIN
-       jmp     $0000           ; CLALL
-       jmp     k_udtim         ; UDTIM
-       jmp     k_screen        ; SCREEN
-       jmp     k_plot          ; PLOT
-       jmp     k_iobase        ; IOBASE
-       sta     ExecReg
-       rts
-       .byte   $01             ; Filler
-               .word   nmi
-               .word   0               ; Reset - not used
-               .word   irq
-vectable_size  = * - vectable
-
-p3vectable:
-       .word   k_irq           ; IRQ user vector
-       .word   k_brk           ; BRK user vector
-       .word   k_nmi           ; NMI user vector
-p3vectable_size        = * - p3vectable
-
+        lda     #<__BSS_RUN__
+        sta     ptr1
+        lda     #>__BSS_RUN__
+        sta     ptr1+1
+        lda     #0
+        tay
+
+; Clear full pages.
+
+        ldx     #>__BSS_SIZE__
+        beq     Z2
+Z1:     sta     (ptr1),y
+        iny
+        bne     Z1
+        inc     ptr1+1          ; Next page
+        dex
+        bne     Z1
+
+; Clear the remaining page.
+
+Z2:     ldx     #<__BSS_SIZE__
+        beq     Z4
+Z3:     sta     (ptr1),y
+        iny
+        dex
+        bne     Z3
+Z4:     jmp     Init
 
 ; ------------------------------------------------------------------------
-; This is the program code after setup. It starts at $400
+; We are at $200 now. We may now start calling subroutines safely since
+; the code we execute is no longer in the stack page.
 
-       .res    $400-*
+.segment        "PAGE2"
 
-Start:
+; Activate the chained interrupt handlers; then, enable interrupts.
 
-; Enable interrupts
+Init:   lda     #.lobyte(__INTERRUPTOR_COUNT__*2)
+        sta     irqcount
+        cli
 
-       cli
+; Call module constructors.
 
-; Call the user code
+        jsr     initlib
 
-               ldy     #4              ; Argument size
-               jsr     _main           ; call the users code
+; Push the command-line arguments; and, call main().
 
-; Fall thru to exit.
+        jsr     callmain
 
-_exit:         jsr     doatexit        ; call exit functions
+; Call the module destructors. This is also the exit() entry and the default entry
+; point for the break vector.
 
-; Clear the start of the zero page, since it will be interpreted as a
-; (garbage) BASIC program otherwise. This is also the default entry for
-; the break vector.
+_exit:  pha                     ; Save the return code
+        jsr     donelib         ; Run module destructors
+        lda     #$00
+        sta     irqcount        ; Disable custom irq handlers
 
-k_brk: sei
-       lda     #$00
-       ldx     #$3E
-Clear: sta     $02,x
-       dex
-       bne     Clear
+; Address the system bank.
 
-; Setup the welcome code at the stack bottom in the system bank. Use
-; the F4/F5 vector to access the system bank
+        lda     #$0F
+        sta     IndReg
 
-       lda     #$0F
-       sta     IndReg
-       ldy     #$00
-               sty     $F4
-       iny
-       sty     $F5
-       ldy     #reset_size-1
-@L1:   lda     reset,y
-       sta     ($F4),y
-       dey
-       bne     @L1
-       jmp     Back
+; Copy stuff back from our zero-page to the system's.
 
-; ------------------------------------------------------------------------
-; Code that is copied into the system bank at $100 when switching back
+.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
 
-reset: cli
-       jmp     $8000                   ; BASIC cold start
-reset_size = * - reset
+; Place the program return code into BASIC's status variable.
 
-; ------------------------------------------------------------------------
-; Code for a few simpler kernal calls goes here
-
-k_iobase:
-       ldx     cia
-       ldy     cia+1
-       rts
-
-k_screen:
-       ldx     #80             ; Columns
-       ldy     #25             ; Lines
-       rts
-
-k_setlfs:
-        sta     LogicalAdr
-        stx     FirstAdr
-        sty     SecondAdr
-        rts
+        pla
+        ldy     #$9C            ; ST
+        sta     (sysp0),y
 
-k_setnam:
-        sta     FileNameLen
-        lda     $00,x
-        sta     FileNameAdrLo
-        lda     $01,x
-        sta     FileNameAdrHi
-        lda     $02,x
-        sta     FileNameAdrSeg
-        rts
+; Set up the welcome code at the stack bottom in the system bank.
 
-k_rdtim:
-       sei
-       lda     time+0
-       ldx     time+1
-       ldy     time+2
-       cli
-       rts
-
-k_settim:
-       sei
-       sta     time+0
-       stx     time+1
-       sty     time+2
-       cli
-       rts
+        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
 
 ; -------------------------------------------------------------------------
-; Data area - switch back to relocatable mode
-
-       .reloc
+; The IRQ handler goes into PAGE2. For performance reasons, and to allow
+; easier chaining, we do handle the IRQs in the execution bank (instead of
+; passing them to the system bank).
 
-.data
-spsave:        .res    1
+; This is the mapping of the active IRQ register of the 6525 (tpi1):
+;
+; Bit   7       6       5       4       3       2       1       0
+;                               |       |       |       |       ^ 50 Hz.
+;                               |       |       |       ^ SRQ IEEE 488
+;                               |       |       ^ CIA
+;                               |       ^ IRQB ext. Port
+;                               ^ ACIA
+
+irq:    pha
+        txa
+        pha
+        tya
+        pha
+        lda     IndReg
+        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
+        bne     dobrk
+
+; It's an IRQ.
+
+        cld
+
+; Call the chained IRQ handlers.
+
+        ldy     irqcount
+        beq     irqskip
+        jsr     callirq_y       ; Call the functions
+
+; Done with the chained IRQ handlers; check the TPI for IRQs, and handle them.
+
+irqskip:lda     #$0F
+        sta     IndReg
+        ldy     #TPI::AIR
+        lda     (tpi1),y        ; Interrupt Register 6525
+        beq     noirq
+
+; 50/60Hz. interrupt
+
+        cmp     #%00000001      ; ticker IRQ?
+        bne     irqend
+        jsr     scnkey          ; Poll the keyboard
+        jsr     UDTIM           ; Bump the time
+
+; Done.
+
+irqend: ldy     #TPI::AIR
+        sta     (tpi1),y        ; Clear interrupt
+
+noirq:  pla
+        sta     IndReg
+        pla
+        tay
+        pla
+        tax
+        pla
+nmi:    rti
+
+dobrk:  jmp     (BRKVec)
 
+; -------------------------------------------------------------------------
+; Data area
 
+.bss
+irqcount:       .byte   0