Page 1 of 1

NMI on a Vic-20

Posted: Sun Aug 25, 2019 9:17 pm
by kakemoms
Hi

The NMI on the Vic-20 is connected directly to the "RESTORE" key on the keyboard. Not much happens if you press it since the routine just returns to the interrupt break point with a RTI. That is unless the "RUN STOP" key is pressed. In that case, it does not return to the interrupt breaking point. It seems like the Commodore Basic at this point clears the stack by writing $FA into the stack pointer.

During Basic cold start, it clears the stack by writing $FB into the stack pointer.

During reset, it clears the stack by writing $FF into the stack pointer (which kind of makes more sense).

The question is why the "Kernal" writes $FB or $FA into the stack pointer during different cold starts. It retains something there, but I can't understand what.

I don't know how much of this code is Commodore specific since its basically MS Basic v2.0.

Re: NMI on a Vic-20

Posted: Mon Aug 26, 2019 12:32 am
by barrym95838
Although I am not by any means an 8-bit Commodore expert, I can readily postulate that the behavior you mention is completely Commodore-specific, since there is not a single "RTI" in nearly 7000 lines of the original 6502 source, implying to me that MSBASIC has no stake in any interrupt handling. Why the "Kernal" initializes the stack pointer differently during different cold starts is a question whose answer is beyond my pay grade. ;-)

Re: NMI on a Vic-20

Posted: Mon Aug 26, 2019 1:33 am
by floobydust
IIRC, the Vicmon cartridge used the NMI to perform single step execution, and it might have been used for the RS-232 implementation using the 6522 VIA. Fortunately, a disassembly of the ROMs are available which you will likely find useful and enlightening.

http://www.zimmers.net/anonftp/pub/cbm/ ... index.html

Re: NMI on a Vic-20

Posted: Mon Aug 26, 2019 5:50 am
by raccoon
kakemoms wrote:
During Basic cold start, it clears the stack by writing $FB into the stack pointer.
In the C64, Commodore calls this a warm start. It restarts BASIC and the shell, but not the kernel (or kernal in Commodore parlance).
The top of the stack me already be in use by the kernel, so it should not be overwritten.

Re: NMI on a Vic-20

Posted: Mon Aug 26, 2019 6:21 am
by BigEd
floobydust wrote:
... a disassembly of the ROMs are available which you will likely find useful and enlightening.

http://www.zimmers.net/anonftp/pub/cbm/ ... index.html
Thanks! It looks like the top of page 1 is used for storage, which might help explain why the stack is (sometimes) initialised to a different value:

Code: Select all

LAB_01FC	= $01FC		; chain link pointer high byte
LAB_01FD	= $01FD		; chain link pointer low byte

LAB_01FE	= $01FE		; line number low byte before crunched line
LAB_01FF	= $01FF		; line number high byte before crunched line
Here are the three initialisations:

Code: Select all

; flush BASIC stack and clear the continue pointer

LAB_C67A
	LDX	#LAB_19		; get descriptor stack start
	STX	LAB_16		; set descriptor stack pointer
	PLA				; pull return address low byte
	TAY				; copy it
	PLA				; pull return address high byte
	LDX	#$FA			; set cleared stack pointer
	TXS				; set stack
	PHA				; push return address high byte
	TYA				; restore return address low byte
	PHA				; push return address low byte
	LDA	#$00			; clear A
	STA	LAB_3E		; clear continue pointer high byte
	STA	LAB_10		; clear subscript/FNX flag
LAB_C68D
	RTS

Code: Select all

; BASIC cold start entry point

LAB_E378
	JSR	LAB_E45B		; initialise BASIC vector table
	JSR	LAB_E3A4		; initialise BASIC RAM locations
	JSR	LAB_E404		; print start up message and initialise memory pointers
	LDX	#$FB			; value for start stack
	TXS				; set stack pointer
	JMP	LAB_C474		; do "READY." warm start

Code: Select all

; RESET, hardware reset starts here

LAB_FD22
	LDX	#$FF			; set X for stack
	SEI				; disable interrupts
	TXS				; clear stack
	CLD				; clear decimal mode
	JSR	LAB_FD3F		; scan for autostart ROM at $A000
	BNE	LAB_FD2F		; if not there continue Vic startup

	JMP	(LAB_A000)		; call ROM start code

LAB_FD2F
	JSR	LAB_FD8D		; initialise and test RAM
	JSR	LAB_FD52		; restore default I/O vectors
	JSR	LAB_FDF9		; initialize I/O registers
	JSR	LAB_E518		; initialise hardware
	CLI				; enable interrupts
	JMP	(LAB_C000)		; execute BASIC