;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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