Ophis/platform/c64_0.oph

79 lines
1.6 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".
.include "c64header.oph"
.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