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