Lobsters retrocomputing - 13 Sep 2026

Page 6 of 8

I started off with a converted copy of the demonstration cassette, which was written by VTech themselves and serves as a rather slight introduction to the system. Although the individual files can be loaded from the SD card reader, it is not implemented as a cassette deck, so since each subsection of the demo is kept small to fit into a 4K VZ200, they will all soon try to load the next part and then just end up sitting there. At that point you must stop it with BREAK and manually load the next part, stored in numerical order. Still, it's very friendly and welcoming to new computer users, including a nice little semigraphics picture as part of the sequence. Remember that VDG semigraphics, at least as configured on the Laser series, are at most one colour plus black in the same 2x2 cell, appearing when the high bit in text screen memory is set. Despite that limitation, with a little thought you can use it to make very striking displays as it is the only mode where every single colour can appear onscreen simultaneously (or black can appear at all). Alternatively, another part of the demo is this slow but pretty bitmapped kaleidoscope. Besides text/semigraphics mode, the VZ200 has a simple 128x64 bitmapped display which consumes the entirety of the 2K VRAM. In this mode you get your choice of only two fixed four-colour palettes also selected by the 6847 CSS pin, neither of which is ideal, but at least every pixel can have its own colour. This particular display is drawn with the "pastels" (cyan, magenta and orange on a buff background) as opposed to a more garish one (red, blue and yellow on a green background). Notice that neither bitmap palette has black nor either of the alternate shades of green and orange.

A better measure of the hardware might be Five Finger Punch's 2018AD. There's not much of a VZ200 demoscene, but there are a few out there, and this exceptional demo is unquestionably one of the best. It will not run correctly on this particular computer because the video timing is different - not because the clock speed is faster, like you'd see between an NTSC Commodore 64 which is faster than a PAL Commodore 64, but because the NTSC VDG draws the screen faster and thus fires the end-of-frame interrupt more often, messing up synchronization. For that, you'll just have to watch this YouTube recording on actual PAL hardware.

It's set up like a trackmo, streaming cassette program data from one channel of a specially recorded CD audio track and using the other channel for music (admittedly a bit of a cheat but the music is excellent). If you didn't think rotozooms, raster splits and even FLD-type effects were possible on the 6847 VDG, then you're in for a treat. Another neat trick is the doubled vertical resolution while drawing the Kefrens bars. The source code is even available for your education.

The VZ200 also had its various arcade ports. Some were higher quality than others. This is a commendable, but slow, ripoff of Moon Patrol ("Mars Patrol," by Grant Rowe) entirely done with semigraphics. It restores the old light-on-dark screen colours used in earlier ROMs with POKE 30744,1 (this works with twiddling the CSS pin with COLOR,1 also). On the other hand, Hoppy is an above-average Frogger clone, and did the original one better by spreading the frog's journey over two screens. Hoppy came from the well-known duo of Dubois and McNamara (i.e., Greg Dubois and Tricia McNamara, though Greg did all the programming), who created various titles for a number of DSE systems that were sold in stores. I should note that for many games, including this one, the more-or-less standard control keys are Q and A for up and down, M and comma for left and right, and where a fire button is used, typically SHIFT (SPACE for secondary).

Note the "snow" in this shot - that's because the program was animating screen memory at the same time the VDG was trying to read it, so the VDG's memory access got briefly suppressed during that period. Because the display scan can't wait for the VDG to be enabled again, the result is a brief splat of garbage on that line until the VDG is allowed to proceed. Dubois could have simply waited for the VDG's next interframe interrupt, but there's also only so much time between frames before the VDG will start drawing again. As a result, for many programs where significant CPU time was required to do screen updates, outright ignoring the video artifacts turned out to be the least bad approach.

Here's a short video I recorded of another high quality arcade clone, Galaxon (gee, I wonder what that was) by Stephen Clarke. It shows loading from the SD card, the title and options screen (even the VZ200 had software pirates), and then playing the game, which worked fine on the keyboard. This and the other recordings I did for this entry were generated from the composite capture rig for video, but for audio using a microphone near the VZ200's piezo speaker to capture sound (since there's no audio out). You'll notice I'm pounding on the keys a bit, which the microphone faithfully picks up, though you do have to hit the keys with a bit of, shall we say, deliberateness to get them to register.

One of the more interesting games I ran across was Learjet, an IFR-style flight simulator drawn on the text screen. Here we are allegedly flying from Sydney to Melbourne, possibly because we don't know any better. When I get some time I want to figure this sim out a bit more because it seems quite sophisticated by 8-bit standards. Of course, it wouldn't be a home computer without at least a token attempt at education. Here is a very Australian variation of Lemonade Stand: Meatpies, where you sell pies. Yes, the meaty kind, America. Appropriately for a Four'n Twenty take on sugar-sweetened citrus beverages, you decide how many

glassespies you want to make, how many advertising signs you want to buy, and the price per item you want to request. Other than the pie business, Larry Taylor's port of the game seems to be heavily influenced by the well-known Apple II version and includes the same sort of simple graphics for weather reports and the like.

An exceptional entry in the VZ's edutainment canon is Factory by VSoftwareZ. It oozes professional quality with a slick title screen and menu, and is an extremely fun puzzler to boot. The aim is to create a factory from various primitive machines (paint, rotate, hole punch) that will generate a specific product. It is so well animated and so thoroughly polished that it deserves this short video to fully appreciate it.

Dubois and McNamara didn't just do games; one of their more ambitious projects was Wordpro for the VZ-300. You should refer to the copious documentation for all its features, as it was a surprisingly credible word processor on par with at least, say, Color Scripsit on the Tandy Color Computer, though Color Scripsit is some years older. Although Wordpro came as a cartridge intended for the VZ-300, it would work on a VZ-200 with correspondingly less document memory available, since it occupied the slot where the RAM expander would go. On the other hand, the program seems to be calibrated for a VZ-300 keyboard since on this VZ200 the keys seem to frequently stutter. (I'll talk about how I got it to work on this 4K system later, though it would not have been possible without the BennVenn RAM expansion.) The visual resemblance between Wordpro and Color Scripsit - see this emulation - is also notable because the CoCo 1/2 and the VZ-200/300 all lack lowercase, so both programs solve it in the same way by displaying "capital letters" in reverse video. Wordpro's user interface is more sophisticated than Color Scripsit's, but it's also newer. The lack of a lowercase option on the VZ-300 was again a real missed opportunity, and with the number of machines DSE was buying you'd think they could have talked VTech into engineering a solution. Although Wordpro supports both disk and tape, the BennVenn cartridge currently doesn't emulate them sufficiently for Wordpro to use it. Perhaps this is a hack we can do some other time. And of course a couple more games. Here is a simple Formula 1 racer (also by Stephen Clarke) a la Night Driver where you are apparently an alien with wings and feet ...

... alongside a rather good 3-D maze game by Laserlink. It's only rendered at 90 degree angles, but it's fast and well-written, and deserved another video.

Now, I mentioned there was another problem with the system. Some games, though many were fine, would show a weird line pattern over certain sections of the screen like this port of Exidy Circus/Midway Clowns. The pattern was annoying, but in the first few games I played where it manifested, it appeared to be cosmetic (it does not restrain the jumping figures here) and I initially chalked it up to some other undiscovered difference in this NTSC unit. However, when I tried (Space) Invaders, it became clear it was not merely a video artifact but actual garbage in VRAM. Indeed, Invaders would detect collisions with it and accordingly send the alien force on a hyperdrive descent, making the game practically unplayable.

As it happens, the very problem was there all along in some of the previous screenshots and videos. Can you see it? Here, let me clear the hi-res screen for you:

One ... lousy ... stuck ... bit!

First let's understand why this was a problem for some games and not others. I am a 6502 dweeb of long standing and - hi Martin! - it is therefore excruciatingly painful for me to say anything at all nice about the Z80 (even though there's one in my beloved Commodore 128DCR), but one unquestionable strength is its block transfer instructions. As any schoolchild will tell you, six of the Z80's registers, B, C, D, E, H and L, can be turned into 16-bit counters BC, DE and HL which likewise can indicate addresses. The Z80 has an instruction LDI that copies the contents of the address referenced by HL to the contents of the address referenced by DE; the instructions LDIR and LDDR expand upon it, running LDI repeatedly and decrementing the count in BC each time until it reaches zero, respectively incrementing or decrementing HL/DE on every step.

The most obvious application for these instructions is copying a block of memory elsewhere, but a less obvious application is using them to fill memory. Consider this segment of actual code from Invaders (dumped with z80dismblr):

; Subroutine: Size=36, CC=1.

; Called by: LBL1[8254h], LBL4[8F3Bh].

; Calls: -

8C9E SUB40:

8C9E ld hl,7000h ; 28672

8CA1 ld (DATA47),hl ; 8DCEh

8CA4 ld de,7001h ; 28673

8CA7 ld bc,081Fh ; 2079

8CAA ld (hl),00h ; 0

8CAC ldir

Ignoring the instruction at $8ca1, you can see that this is setting the source to $7000 - i.e., the start of VRAM - and the destination to $7001 (?!), for a total of $0820 bytes (the zero test is post-decrement). Now, what would that accomplish? Just before the LDIR, we set the contents of $7000 (in HL) to zero. Let's step through the process LDIR takes manually. $7000 is first copied to $7001, which is now zero as well. HL is incremented to $7001, DE to $7002, BC decremented to $081e. Next, $7001 is copied to $7002, but $7001 had zero in it because it was copied from $7000, so all three locations are now zero. HL is incremented to $7002, DE to $7003, BC decremented to $081d. Then, $7002 is copied to $7003, so now all four locations are zero, and so on, filling all intervening locations with the immediate value before. At the end, when BC finally gets to zero, all locations from $7000 to $781f inclusive (i.e., the entirety of video memory and a little past it in system RAM) will have been zeroed out.

This is how Invaders clears the hi-res screen and it is indeed faster than a naive loop, especially for large tracts of memory. But our obnoxious little plastic beast here throws in a wrench by having a location where the RAM isn't working properly. When the "copy" gets to that point, because the copy is only between adjacent memory locations, for every subsequent location the stuck bit will be propagated forward and faithfully copied to each and every byte afterwards. That's also why the pattern doesn't cover the whole screen, because the problem doesn't actually manifest until the "copy" operation arrives there. In fact, in the process Invaders was unwittingly corrupting some of its own game variables with the same stuck bit when they should have been zero, possibly another reason why it wouldn't run correctly.

The direct and most definitive solution would be to "simply" replace the VRAM chip, and I even have 6116 SRAMs in stock, but I warned you this is a very cheaply made PCB. Far better repairpersons than I have tried and failed to replace chips on these computers without requiring a lot of rework and bodges, and the prior portions of this article should have already convinced you it's only by the grace of God I haven't soldered my own fool face to the workbench yet. I did not want to try replacing that SRAM chip solely because of one stinking bad bit; I was only likely to make a bigger mess or render the computer completely inoperable.

But again: we have an alternative. This fill trick was not universally used or even known by all programmers at the time. The games that do work clear the screen with a simple loop that doesn't propagate the bad bit forward, which works because the store doesn't depend on what memory contents are already "there." Likewise, VTech doesn't seem to use it in the ROMs, which is why the problem didn't manifest during the demonstration tape or with BASIC programs drawing to the screen with BASIC keywords. Most VZ programs are small enough and this code idiom distinctive enough (and usually only present once) that such code can be found and patched to use a slightly slower but functional loop. As such a loop would generally require more bytes, the patch could either direct execution to a tacked-on routine to do the clear, or we could patch it to point to a standard routine in memory.

And how are we going to get a standard, always-present, stock routine into memory to do that? Easy: we're going to soft-alter the BennVenn SD loader's firmware. No, stop laughing, because we have a simple means to accomplish it. At the same time we'll combine that with a serial port loader so that we can test these programs live without having to constantly swap the SD card to and from the Talos II, so we'll also build it a bitbanged serial port (I said stop laughing). There were homebrew serial devices back in the day for these computers, so consider this one merely another entry from a venerable tradition.

The programs that we'll write, including our replacement firmware, need to be in .VZ format. Here's a simple, complete example of "Hello World" showing how to construct that header and which can run directly from the card, demonstrated in the screenshot. This is one of several files you will find in this article's Github repo. As with all our assembler projects except for the 6502 and PowerPC, we crossbuild using the Macroassembler AS.

org 07fe8h ; $8000 - $18

; emit .vz header (24 bytes)

db 056h,05ah,046h,031h ; "VZF1"

db "HELLO\0\0\0\0\0\0\0\0\0\0\0\0" ; filename null terminated

db 0f1h

dw entry

entry ; now at 8000h

ld hl,msg

call 028a7h

ret

msg db "HELLO WORLD", 13, 0

The 24-byte header marks this as a machine language program that starts at $8000, the beginning of the extra memory furnished by the BennVenn device. Although the magic number VZF0 (for BASIC programs, which always start at $7ae9) or VZF1 would appear to be critical, the firmware doesn't seem to check it on loading or even generate it on saving, only that the byte just before the starting address word (everything is Z80 little-endian) is either $f0 or $f1. Upon execution our program then calls a "display null-terminated string" routine in the VZ ROM, the update for which is pushed to the screen during the next VDG interframe period, and returns to BASIC. The binary is assembled with AS like so, using a simple Makefile:

% make hello.vz

asl -cpu z80 -t 2 -L hello.a80

Assembling hello.a80

PASS 1

hello.a80(17)

PASS 2

hello.a80(17)

0.00 seconds assembly time

17 lines source file

2 passes

0 errors

0 warnings

p2bin hello.p hello.vz

Deduced address range: 0x00007FE8-0x00008013

hello.p==>>hello.vz (44 Bytes)

% xd hello.vz

00000000 56 5a 46 31 48 45 4c 4c 4f 00 00 00 00 00 00 00 |VZF1HELLO.......|

00000010 00 00 00 00 00 f1 00 80 21 07 80 cd a7 28 c9 48 |........!....(.H|

00000020 45 4c 4c 4f 20 57 4f 52 4c 44 0d 00 |ELLO WORLD..|

0000002c

We then copy it to the card, where LOAD"HELLO" will load and immediately execute it from the given entry address (which is both the load and execute address), as shown in the screenshot above.

Now we'll proceed with the hardware part, and we won't even need to solder anything from here on out, because we'll just use DuPont female jumpers to connect to the BennVenn GPIO pins we've already attached - everything else will be done in software. The SD card board uses 3.3V logic and has 24 GPIO pins that can be individually configured as inputs or outputs. These are all accessible through the Z80's I/O space, with locations 68-70 setting the data direction (1=input), and locations 71-73 setting the value of outputs. All pins can be read, not only pins configured as inputs, but also the current state of any output pins. The SD card board's GPIO pins provide +5V and +9V lines as well, but we won't be needing them for this project.

As an example, in the Github repo I have a small program to cycle the LEDs on his proto board, which you can see in this brief video. It sets all GPIO pins to output and lights all 24 green LEDs connected to them (the red ones are check LEDs for 3.3V, 5V and 9V), then cycles a dark one through them from left to right until a key is pressed. This is done by hooking into the interrupt routine called when the VDG completes a frame, the only regular timesource on an unaltered VZ200, and used back in the day as a simple clock by various programs. Every third tick of the interrupt routine, this code runs:

push ix

and a ; clear carry flag

ld ix,scrby

rl (ix)

rl (ix+1)

rl (ix+2)

pop ix

ld a,(scrby)

; put top bit back into low bit, if set

jr nc, ledsout

or 1

ld (scrby),a

ledsout out (71),a

ld a,(scrby+1)

out (72),a

ld a,(scrby+2)

out (73),a

It rotates an in-memory image of the GPIO pin values, then emits that to the I/O locations. Because the rotation is to the left, we can see that the GPIO lines must also be oriented little-endian, i.e., the least significant bit of each GPIO output register is on the left.

Next page | Previous page | More Lobsters retrocomputing | Headlines

Original: http://oldvcr.blogspot.com/2026/09/a-dick-smith-vz200-without-dick-smith.html