NMI on a Vic-20

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
kakemoms
Posts: 349
Joined: 02 Mar 2016

NMI on a Vic-20

Post 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.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: NMI on a Vic-20

Post 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. ;-)
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: NMI on a Vic-20

Post 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
raccoon
Posts: 21
Joined: 05 Feb 2006
Location: The Netherlands

Re: NMI on a Vic-20

Post 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.
I trust my somewhat flawed English is comprehensible to all.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: NMI on a Vic-20

Post 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
Post Reply