Cartridge Auto Start Tips?

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Cartridge Auto Start Tips?

Post by chysn »

Hello! So far, the extent of my cartridge work has been with wAx, which just acts like ROM in block 3 or block 5, and needs to be started by the user via SYS. I'm working on expanding my skills a bit and making a traditional auto-start game cartridge. I'm getting different results based on platform and launch method.

In VICE

(1) If I load my cartridge to block 5 with LOAD"CART",8,1, and then enter SYS64802, the VICE VIC-20 auto-starts my cartridge code perfectly. Everything works great. The NMI vector works as I expect when RESTORE is pressed. It's a happy land. But...

(2) If I do the same thing and do a "soft restart" of the VICE VIC-20, then the code starts, but the IRQ doesn't run. The vector is set correctly, and the I flag is 0, but the IRQ just doesn't seem to fire. Additionally, the NMI doesn't seem to fire. I know you can't mask NMI, but RESTORE does nothing.

On a Real VIC-20

(1) I burned the 8192-byte image onto an EEPROM, plugged it into a GORF PCB, and turned the VIC-20 on. The VIC-20 comes on with a blue screen and is unresponsive

(2) To rule out hardware issues (unconnected pins, failed burn, etc.) I burned a variant of the image to the same EEPROM, with the only difference being that the auto-start sequence is "a0CBL". Now, of course the VIC-20 starts at the READY prompt. SYS43355 (the entry point specified at $a000) starts the code, and everything works perfectly.

My questions would be, why is there a difference between SYS64802 and soft-resetting VICE? And why is there a difference between VICE and a real VIC-20?

My guess was that some stuff is done in one situation that doesn't get done in another. But the hardware reset vector at $fffc goes straight to $fd22 (64802), so I can't imagine what could possibly be different....
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Cartridge Auto Start Tips?

Post by chysn »

All right, checking the ROM disassembly here, and I think there are clues:

Code: Select all

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
So, if the test for a0CBM succeeds, the JMP ($A000) happens before the stuff at $FD2F, and that might not properly prepare the environment that my game expects.

The JMP even comes after an SEI, which might explain the IRQ issue. I'm not sure why VICE reports the I flag as clear, but I'm not worried about that right now.

Be right back after some testing...
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Cartridge Auto Start Tips?

Post by Mike »

The cartridge autostart code has to replicate at least part of the original continued reset code depending on what functions of hardware, KERNAL and BASIC you want to use:

Code: Select all

.FD22  A2 FF     LDX #$FF
.FD24  78        SEI
.FD25  9A        TXS
.FD26  D8        CLD
.FD27  20 3F FD  JSR $FD3F   ; check "A0CBM" signature
.FD2A  D0 03     BNE $FD2F
.FD2C  6C 00 A0  JMP ($A000)
.FD2F  20 8D FD  JSR $FD8D   ; check RAM size
.FD32  20 52 FD  JSR $FD52   ; init KERNAL vectors
.FD35  20 F9 FD  JSR $FDF9   ; init I/O (VIA registers)
.FD38  20 18 E5  JSR $E518   ; init screen editor
.FD3B  58        CLI
.FD3C  6C 00 C0  JMP ($C000) ; BASIC cold start
So, by $FD3C, all KERNAL functions, including interrupts, keyboard, screen, disk, tape, etc. work correctly. BASIC is cold started over its $C000 vector to set up its own stuff in the lower part of the zeropage and finally end up with the start-up prompt and a blinking cursor in direct mode.

During your investigations:

In VICE (1) you had the KERNAL already set up everything to work once. After LOAD"...",8,1 and SYS, the autostart signature diverted to your own code which however had the crucial things set up already while you were doing those things before SYS64802.

VICE (2) resets the hardware (including the VIAs) but doesn't clear RAM. The default/reset state of the VIAs is all bits off in their IERs, all port bits on input and everything else undefined for your purpose. With the IERs off, neither IRQs nor the RESTORE key work. JSR $FDF9 puts that in order, but you should also do JSR $FD52 before that to init all KERNAL vectors.

In real hardware (1) you pretty much had the same scenario as in VICE (2) and with real hardware (2) you effectively replicated VICE (1).


If you include the four JSRs from $FD2F to $FD38, your cartridge code should behave fine if you don't call any routines in the BASIC interpreter. You should note that if a RAM expansion >= 8K is present besides your cartridge, JSR $FD8D detects this and JSR $E518 already puts the VIC registers for a screen at $1000.

If you want to use BASIC, you need to continue the reset sequence a bit more, see here: a BASIC game as cartridge. This also contains code to "guard" against RAM expansions so the screen remains at $1E00.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Cartridge Auto Start Tips?

Post by chysn »

Well, after getting the $FD52 and $FDF9 calls in there, and a CLI, everything works great in VICE.

The real VIC-20 still gets the blue screen, which is terribly frustrating.

I did a diff of the contents of the chip vs the image file I burned. I also burned an image of Dragonfire onto the same chip and it worked fine. So it's not any kind of EEPROM or other hardware issue.

My god, Dragonfire is freaking hard.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Cartridge Auto Start Tips?

Post by Mike »

chysn wrote:Well, after getting the $FD52 and $FDF9 calls in there, and a CLI, everything works great in VICE.

The real VIC-20 still gets the blue screen, which is terribly frustrating.
Then include $FD8D and $E518, too. All 4 calls in the same order as in $FD2F..$FD38.

If your cartridge uses any routines in the BASIC interpreter ($C000..$E49F), then you should also call $E45B and $E3A4 and re-position the stack to $FB (see my other thread I linked to).

In VICE, you should also check with the "attach cartridge" facility to see what a hard reset (i.e. power cycle on real hardware) results in.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Cartridge Auto Start Tips?

Post by chysn »

Yep, cool! I am using PRTSTR and PRTFIX from BASIC, and including $e518 and $fd8d made the thing come to life! Thank you!
In VICE, you should also check with the "attach cartridge" facility to see what a hard reset (i.e. power cycle on real hardware) results in.
I wasn't sure I was doing this right before, because the look of the failure was different (blue screen vs. screen of random-ish characters in VICE). But now that the cartridge image is working, I understand how "attach cartridge" works.

Now I think I can do some proper work! I've got an empty 3K of RAM and an extra 4.5K of program space. I can hardly imagine such luxury!
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Cartridge Auto Start Tips?

Post by Mike »

chysn wrote:I am using PRTSTR and PRTFIX from BASIC, and including $e518 made the thing come to life!
That is not how it is supposed to work! From what you tell, the program still misses out on certain calls of the reset sequence.

The reset sequence sets up state variables and lots of buffer pointers in the OS workspace. Uninitialized, the pointers may still operate on addressable RAM and then your user code seems to work - until the pointers run up to unsuspecting other data structures or open (i.e., non-existing) memory. From that point, further OS calls overwrite that other data or lose data and then your program ultimately crashes.

You were missing a lot of crucial initialisation right at the start, and the crashes happened immediately. Employing a piecemeal strategy - by including just those inits that seem momentarily necessary - will just lead to difficult to track down "bugs" later in program execution.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Cartridge Auto Start Tips?

Post by chysn »

Mike wrote: Mon Aug 16, 2021 9:37 am
chysn wrote:I am using PRTSTR and PRTFIX from BASIC, and including $e518 made the thing come to life!
That is not how it is supposed to work! From what you tell, the program still misses out on certain calls of the reset sequence.
I had included them all in the code, I just missed one in the first version of my post. For the record, the start of the code is as follows, and it's the only thing that works. Nothing must be omitted, as you say:

Code: Select all

Welcome:    jsr $fd8d           ; Test RAM, initialize VIC chip
            jsr $fd52           ; Restore default I/O vectors
            jsr $fdf9           ; Initialize I/O registers
            jsr $e518           ; Initialize BASIC
            cli                 ; Clear interrupt flag from ROM jump
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Cartridge Auto Start Tips?

Post by chysn »

There was actually a little bit more that I had to do to prevent the two BASIC routines I'm using from stepping on my extremely liberal use of zero page.

The routine at $E3A4 is called from the cold start (JMP ($C000)), and sets the stack pointer at $16 for PRTSTR to $19. This is the only location that I'm aware of really needing to be set; but since I wrote this game assuming that the user is starting from BASIC, I figure that simply running the whole routine would cut down on additional surprises.

For completeness, I'm also setting the BASIC vectors from $E45B, even though I haven't seen any problems with not doing this. Here's where I'm at now:

Code: Select all

Welcome:    jsr $fd8d           ; Test RAM, initialize VIC chip
            jsr $fd52           ; Restore default I/O vectors
            jsr $fdf9           ; Initialize I/O registers
            jsr $e518           ; Initialize hardware
            jsr $e45b           ; Initialize BASIC vectors
            jsr	$e3a4           ; Initialize BASIC RAM locations
            cli                 ; Clear interrupt flag from ROM jump
I might go ahead and write my own PRTSTR and PRTFIX routines, and be entirely free of BASIC. With unexpanded VIC, these two routines are mainstays because they do some heavy lifting. But they do more weird things than I'd like and use a lot of ZP space, and I now have plenty of memory to replace them.
Post Reply