Re: [cc65] C64 Cartridge Program

From: Greg King <gngking1erols.com>
Date: 2007-05-19 01:25:20
From: Bill Katsak; on Friday, May 18, 2007; at 07:02 AM -0400
>
> Here is the start-up code as I am using it:
>
> ;
> ; Startup code for cc65 (C64 version)

    ... <snip> ...

>
> ;Cartridge AUTOSTART header
>     .byte $09,$80
>     .byte $19,$80
>     .byte $c3,$c2,$cd,$38,$30

That code will look better with labels and text:

    .addr Cold, Warm
    .byte "CBM80"
Cold:

>
> ;Kernal init routines.
>     stx $d016
>     jsr $fda3
>     jsr $fd50
>     jsr $fd15
>     jsr $ff5b
>     cli

Warm:

>
> ;These are BASIC init. routines, I tried them just for the heck of it.
> ;   jsr $e453
> ;   jsr $e3bf
> ;   jsr $e422
> ;   ldx #$fb
> ;   txs
>
> ; --------------------------------------------
> ; Actual code
>
>     ldx #zpspace-1
> L1: lda sp,x
>     sta zpsave,x ; Save the zero-page locations we need
>     dex
>     bpl L1
>
> ; Close open files
>
>     jsr CLRCH

The save-and-restore code isn't needed because the cartridge starts with a
_cold_ machine -- and, I assume, it won't run BASIC when it finishes.

>
> ; Switch to second charset
>
>     lda #14
>     jsr BSOUT

>
> ; Switch off the BASIC ROM
> ;
> ;   lda $01
> ;   pha      ; Remember the value
> ;   and #$F8
> ;   ora #$06 ; Enable Kernal+I/O, disable BASIC
> ;   sta $01

Originally, simple eight-Kibibyte cartridges were intended to hold BASIC
extensions (e.g., Super Expander).  So, those cartridges are turned off
when the BASIC ROM is turned off.  (The same thing happens to a
sixteen-Kibibyte cartridge.)

>
> ; Clear the BSS data
>
>     jsr zerobss
>
> ; Copy DATA to RAM
>
>     jsr copydata

>
> ; Save system settings and setup the stack
>
>     pla
>     sta mmusave ; Save the memory configuration
>
>     tsx
>     stx spsave  ; Save the system stack ptr

More unneeded save-and-restore stuff.

>
>     lda #<(__RAM_START__ + __RAM_SIZE__)
>     sta sp
>     lda #>(__RAM_START__ + __RAM_SIZE__)
>     sta sp+1 ; Set argument stack ptr.

By the way, did you remember to change the size of "RAM:" in your ld65
configure-script, so that it stops at $8000?

>
> ; Call module constructors
>
>     jsr initlib
>
> ; If we have IRQ functions, chain our stub into the IRQ vector
>
>     lda #<__INTERRUPTOR_COUNT__
>     beq NoIRQ1
>     lda IRQVec
>     ldx IRQVec+1
>     sta IRQInd+1
>     stx IRQInd+2
>     lda #<IRQStub
>     ldx #>IRQStub
>     sei
>     sta IRQVec
>     stx IRQVec+1
>     cli
> NoIRQ1:

OK ... a bug is there; eventually, it will be fixed in all of the start-up
files -- but, you can fix it now, in your code.

The interrupt-handler must be connected before the constructors are run
because they can be used to start interrupt-hardware.  (In one of my
programs, a constructor switches from the jiffy-interrupt to a
raster-interrupt.  A handler resets the VIC-II, so that it can make the
next interrupt.  When I link to the original "c64.o", the program stalls if
the VIC happens to interrupt between the "jsr initlib" and the "sei".)

Therefore, move that "jsr initlib" down to here, in your start-up file.
(Notice that I moved the "NoIRQ1:" label!)

>
> ; Push arguments, and call main().
>
>     jsr callmain
>
> ; Back from main (This is also the _exit entry).
> ; Reset the IRQ vector if we chained it.
>
> _exit:

>     pha ; Save the return code on stack

>     lda #<__INTERRUPTOR_COUNT__
>     beq NoIRQ2
>     lda IRQInd+1
>     ldx IRQInd+2
>     sei
>     sta IRQVec
>     stx IRQVec+1
>     cli
>
> ; Run module destructors
>
> NoIRQ2: jsr donelib

(Again, that will be fixed, eventually.  "donelib" must be run before the
handler is unhooked.)

>
> ; Copy back the zero page stuff
>
>     ldx #zpspace-1
> L2: lda zpsave,x
>     sta sp,x
>     dex
>     bpl L2
>
> ; Place the program return code into ST
>
>     pla
>     sta ST
>
> ; Restore system stuff
>
>     ldx spsave
>     txs     ; Restore stack pointer
>     ldx mmusave
>     stx $01 ; Restore memory configuration
>
> ; Reset changed vectors, back to BASIC
>
>     jmp RESTOR

Everything between the "_exit:" label and this spot is a part of the
save-and-restore stuff -- you don't need it in your cartridge.  Instead,
you should put this:

    jmp ($fffc)

>
> ; -------------------------------------------
> ; The IRQ vector jumps here,
> ; if condes routines are defined with type 2.
>
> IRQStub:
>     cld         ; Just to be sure
>     jsr callirq ; Call the functions
>     jmp IRQInd  ; Jump to the saved IRQ vector
>
> ; -------------------------------------------
> ; Data
>
> .data
>
> zpsave: .res zpspace
> IRQInd: jmp  $0000

The "zpsave" line and the lines below are a part of the save-and-restore
stuff.

>
> .bss
>
> spsave: .res 1
> mmusave:.res 1
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sat May 19 01:26:06 2007

This archive was generated by hypermail 2.1.8 : 2007-05-19 01:26:18 CEST