Ophis/platform/c64_0.oph
Michael Martin 60f03a34af Improvements to c64_0.oph startup/teardown code
16 additional bytes from the zero page are now available; the ZP
locations from $02-$8F are now free for your program's use.

Approximately 128 additional bytes in main RAM are now available,
giving you free reign from $0800-$CFFF. Zero Page backup is now
handled underneath the KERNAL's ROM, with the program epilogue
safely handling swapping out the KERNAL for the duration of the
switch. (IRQs are disabled, and NMI handling code is replicated
and modified to not hurt anything.)

Program exit is now handled by keyboard buffer and jumping
through BASIC's warm reset vector. This technique lets programs
play more nicely with PUCRUNCH and onefilers (which otherwise
often confused BASIC as the BASIC prologue would change as part
of decompression or link-loading).
2014-05-14 07:33:07 -07:00

87 lines
1.8 KiB
Plaintext

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Commodore 64 Basic Runtime File
;;
;; Include this at the TOP of your C64 program, and it will handle
;; hiding away the BASIC ROM and data and restoring it at the end.
;;
;; You will have a contiguous block of RAM from $0800 to $CFFF, and
;; Zero Page access from $02 to $8F in the segment "zp".
.word $0801
.org $0801
; BASIC program that just calls our machine language code
.scope
.word _next, 10 ; Next line and current line number
.byte $9e," 2062",0 ; SYS 2062
_next: .word 0 ; End of program
.scend
.data zp ; Zero Page memory segment.
.org $0002
.text
.scope
; Cache BASIC zero page underneath the KERNAL, while also
; making RAM copies of the NMI routines
ldx #$00
* lda $00, x
sta $e000, x
lda $fe00, x
sta $fe00, x
lda $ff00, x
sta $ff00, x
inx
bne -
; Swap out the BASIC ROM for RAM
lda $01
and #$fe
ora #$06
sta $01
; Run the real program
jsr _main
; Swap out KERNAL to expose cached BASIC ZP values
; Block IRQs during this period. NMIs cannot be blocked,
; but we copied enough of the processing code into the
; RAM under the KERNAL that we can disable NMI processing
; during this period
sei ; Disable IRQs
lda #$c1 ; Defang NMIs
sta $318
lda $01 ; Swap out KERNAL
and #$fd
sta $01
; Restore BASIC zero page
ldx #$8E
* lda $e001, x
sta $01, x
dex
bne -
; Restore BASIC ROM, KERNAL, and interrupts
lda $01
ora #$07
sta $01
lda #$47 ; Restore NMI vector
sta $318
cli ; Re-enable interrupts
; Back to BASIC. We do this by clearing the keyboard
; buffer and then jumping through the warm start
; vector. This will more cleanly handle case where
; the program has somehow modified BASIC's state,
; such as running through PUCRUNCH or a onefiler.
stx $c6 ; .X is zero from previous loop
jmp ($a002)
_main:
; Program follows...
.scend