RESTORE key now acts as very soft reset, and for startup

This reverts commit 69d9f49b5c.
This commit is contained in:
John Lorentzson 2025-07-30 22:04:00 +02:00
parent 24b2374d3e
commit cf56f3c11c
2 changed files with 43 additions and 102 deletions

View file

@ -1,6 +1,6 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- ;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.scope STARTUP .proc STARTUP
;; Settings positions ;; Settings positions
CR1 = $d011; Graphic settings CR1 = $d011; Graphic settings
VIC_bank_settings = $DD00 ; Vic position VIC_bank_settings = $DD00 ; Vic position
@ -69,8 +69,7 @@
;; Disable maskeble interups (not all) ;; Disable maskeble interups (not all)
SEI SEI
;; Set up bank switching. ;; Disable BASIC ROM mohahaha
;; Disable BASIC and KERNAL(sic) ROM, keep I/O
;; https://www.c64-wiki.com/wiki/Bank_Switching ;; https://www.c64-wiki.com/wiki/Bank_Switching
LDA #%11111000 LDA #%11111000
AND $01 AND $01
@ -81,29 +80,36 @@
;;Disable non maskable interupts ;;Disable non maskable interupts
;;https://codebase64.org/doku.php?id=base:nmi_lock_without_kernal ;;https://codebase64.org/doku.php?id=base:nmi_lock_without_kernal
;; write to $FFFA/$FFFB possible (and needed) if KERNAL ROM is disabled ;; write to $FFFA/$FFFB possible (and needed) if BASIC ROM is disabled
LDA #<NMI_routine LDA #<NMI_routine
STA $FFFA STA $FFFA
LDA #>NMI_routine LDA #>NMI_routine
STA $FFFB STA $FFFB
LDA #$00 ;; stop Timer A
STA $DD0E
STA $DD04 ;; set Timer A to 0, after starting
STA $DD05 ;; NMI will occur immediately
LDA #$81
STA $DD0D ;; set Timer A as source for NMI
LDA #$01
STA $DD0E ;; start Timer A -> NMI
;; from here on NMI is disabled
;; Set up IRQ for userprog transfer timer
LDA #<IRQ_routine LDA #<IRQ_routine
STA $FFFE STA $FFFE
LDA #>IRQ_routine LDA #>IRQ_routine
STA $FFFF STA $FFFF
LDA #%00101000 ;; stop Timer A
STA $DD0E
STA $DD04 ;; set Timer A to 0, after starting
STA $DD05 ;; NMI will occur immediately
LDA #$80
STA $DD0D ;; set Timer A as source for NMI
LDA #%00101000
STA $DD0E ;; start Timer A -> NMI
;; from here on NMI is disabled
JMP mainsetup JMP mainsetup
NMI_routine: NMI_routine:
RTI ;; exit interrupt not acknowledged BIT $DD0D
.endscope LDA #%11111110
STA $DD0D
JMP STARTUP
IRQ_routine:
PHA
BIT $DC0D
LDA #$00
STA $DC0D
PLA
RTI
.endproc

View file

@ -1,6 +1,5 @@
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- ;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
mainsetup: .proc mainsetup
.scope mainsetup
USERPROG = $C000 USERPROG = $C000
.repeat 4, I .repeat 4, I
ldy #$00 ldy #$00
@ -10,60 +9,20 @@ mainsetup:
dey dey
bne :- bne :-
.endrep .endrep
.endproc
@waitstart: ;; Wait until joystick 2 has been pulled down to start the program mainstart:
dec $d020
lda #%11111111
sta $dc02
lda #%00000000
sta $dc03
lda #%01111111
sta $dc00
lda $dc01
eor #$ff
beq @waitstart
lda #%00000000
sta $dc02
endsetup:
DOWNLOAD_TIMER = $FFFF
lda #$0d lda #$0d
sta $d020 sta $d020
;; Turn on CIA 1's Timer A as IRQ source Summary: Timer A counts down .scope mainloop
;; for 0xFFFF cycles. When it finishes, an IRQ is sent to the
;; CPU. Once it's ready to receive it, the IRQ routine is called,
;; which checks if a userprog download is beginning. If it is, we
;; download and reset the unwind the stack. The transfer hardware has
;; a certain delay between the transfer command being sent and the
;; start of bits being sent. This duration must be some amount longer
;; than the timer's duration to account for variable execution time of
;; interrupt-free routines.
sei ; let's be extra sure interrupts are disabled
lda #<DOWNLOAD_TIMER
sta $dc04 ; Timer A's counter low byte
lda #>DOWNLOAD_TIMER
sta $dc05 ; Likewise for high byte
lda #%10000001 ; Send IRQ to CPU when Timer A is done
sta $dc0d
lda #%00011001 ; Start Timer A, one-shot mode, cycle counting mode
sta $dc0e
ldx #$00 ldx #$00
stx FRAMECOUNT stx FRAMECOUNT
inx inx
sta FIRSTTIME sta FIRSTTIME
.endscope
.proc mainloop ml:
USERPROG = $C000 USERPROG = $C000
RASTER = $D012 RASTER = $D012
@ -72,9 +31,19 @@ endsetup:
ora $01 ora $01
sta $01 sta $01
cli jsr maybe_download_userprog
beq @nochange
ldx #$00
stx FRAMECOUNT
inx
sta FIRSTTIME
@nochange:
jsr USERPROG jsr USERPROG
;; Bank out character ROM, I/O in
lda #%00000100
ora $01
sta $01
@framewait: @framewait:
ldy RASTER ldy RASTER
cpy #$66 cpy #$66
@ -82,8 +51,8 @@ endsetup:
inc FRAMECOUNT inc FRAMECOUNT
lda #$00 lda #$00
sta FIRSTTIME sta FIRSTTIME
jmp mainloop jmp ml
.endproc .endscope
.proc time ; user-procedure .proc time ; user-procedure
lda FRAMECOUNT lda FRAMECOUNT
@ -107,41 +76,7 @@ endsetup:
rts rts
.endproc .endproc
.proc reset_userprog
ldx #$00
stx FRAMECOUNT
inx
sta FIRSTTIME
.endproc
FRAMECOUNT: .byte 0 FRAMECOUNT: .byte 0
FIRSTTIME: .byte 1 FIRSTTIME: .byte 1
RESTORE_DEST: .word mainsetup
IRQ_routine:
lda $dc0d ; Check CIA 1's status
beq @somethingelse
jsr maybe_download_userprog
beq @done
jsr reset_userprog
;; Reconstruct the stack to exit to toplevel
ldx #$00
txs
lda #<mainloop
pha
lda #>mainloop
pha
txa
pha
lda #%00011001 ; Start Timer A, one-shot mode, cycle counting
sta $dc0e
rti
@somethingelse:
;; TODO: Ack potential VIC-II IRQ
@done:
lda #%00011001 ; Start Timer A, one-shot mode, cycle counting
sta $dc0e
rti