Those childhood learning computers can be turned into pretty nice Z80 hacking stations!
This project describes a journey into vintage Z80 based learning computers manufactured by "V-Tech" in the 80s and 90s. Starting with some reverse engineering information, PCBs for interfacing the cartridge port and software development notes.
Currently, there is proof-of-concept support for enabling MIDI in/out, or using it as a terminal for a Raspberry Pi, interfacing a PC using FTDI and the printer port, and even some DOS or CP/M like functionality using a SD card and an Arduino.
The goal of this project is to create a set of hardware and software tools to "hack" the 1000/2000/4000 and 6000 series of VTech 8-bit learning computers ("PreComputer").
The hardware is well understood: Z80 CPU,HD44780 LCD controller, keyboard matrix, printer port, bank switching, sound, LED, ROM, RAM and cartridge port.
The firmware has been reverse engineered to a degree that allows writing custom system ROMs, as well as compiling ROM images that are recognized as cartridges and run by unmodified systems.
Software can be compiled using SDCC and emulated using MAME.
The other day, I decided to do something "completely different" for a change. So I went to my wall of VTech Genius Notebooks and grabbed a random one from the pile that had the same cartridge port as the 4000, but a larger screen.
My pick: the Genius Leader 6000SL aka. Genius PreComputer Prestige.
This time around I wanted to cheat a bit, since I didn't want to spend another 2 years analyzing it (as I did with the 1000/2000/4000 series). Instead of building a debugging cartridge and finding all the memory and port mappings myself, I just searched for some emulation source. And I found a driver in the trusty old MAME repository (src/mame/drivers/prestige.cpp). It is missing some functions (printer port, sound), but the basic stuff is there.
First thing that sparked my interest: The machine seemed to use a DMA based LCD (240x100, graphical), so there is no need for weird LCD initialization code and software frame buffer stuff. It's as simple as poking bitmap data into memory at 0xE000-0xEBB8 and it gets drawn on the screen automagically!
The keyboard is also pretty straight forward (matrix at ports 0x40, 0x41, 0x42) and didn't take much effort to get working. And even the mouse (yes, it has an external mouse!) is directly mapped to ports 0x04 and 0x05 for the X and Y positions. Nice!
I must say, I am quite impressed about how much easier it is to work with the 6000 compared to the 1000/2000 and 4000 series. It took just one day to write my first "Hello World" from scratch (including custom font rendering). I would call that an "instant gratification" :-)
The bank switching / memory mapping in the Prestige is also quite nice: It allows for the cartridge to be mapped to lower memory at address 0x0000. This means that a CP/M style system could run on that machine without any hardware modifications (i.e. no "Chip Select hack" needed)!
So maybe I'll just give it a try and create a Plug & Play CP/M cartridge for that machine!
Update: I have updated the VGLDK Github repository to allow compilation against the new "gl6000sl" target. Cheers!
With CP/M working as a proof-of-concept, an important personal milestone has been reached.
While doing so, a lot of new interesting ideas came up. That's why I am now spending a little time incorporating all the development so far into a VTech Genius LEADER Development Kit - the VGLDK.
Even though I would very much appreciate it, if the VGL support for the Z88DK would improve, I feel like it is a little bit too over-engineered and complicated for the rather "simple things" I try to accomplish. Those being: Enabling everyone to develop software for the system quickly and hassle free.
So I created a Github repo at https://github.com/hotkeymuc/vgldk and started filling it with some initial content. My current focus lies on smooth portability between the 1000, 2000 and 4000 series. (Series 3000, 5000, 6000, 7000 and 8000 may follow eventually.) Additionally, the build process must allow compiling programs for use in a cartridge ROM, as system replacement ROMs, and also for runtime-linking (e.g. when using CP/M or some sort of DOS). I might also migrate the VGL CP/M project right into the VGLDK.
I had the feeling that I was going around in circles: Adjusting some assembly code, compiling, burning an EEPROM, inserting it, bootstrapping the RAM cartridge for CP/M, switching from ROM to RAM, booting CP/M, loading a .COM-file over serial, running it, ... and crashing.
This became very tiresome quickly, as you can imagine.
"Emulation to the rescue!", I thought. So I took a deep dive into the MAME source code and patched the PC2000 emulator: I changed the memory banks to be write enabled to simulate the RAM-switching hardware mod needed for running CP/M. I also added a debug port that allows sending and receiving data to/from MAME via stdin/stdout.
That worked like a breeze. Now it's only one click to compile and pack the CP/M ROM, fire up MAME, load CP/M and open a data channel between the emulated CP/M machine and a python "host" script. This really speeds up the process of loading and altering code for debugging. I also added a TRAP function to BDOS, which allows stopping the program flow at a desired address, dumping registers+stack, and continuing with the execution.
Having these tools at hand, I quickly identified a bank-switching bug and an error when reading records from files.
I crossed my fingers, uploaded "ZORK1" to the emulated CP/M and gave it a try...
...it opened the "ZORK1.DAT" file...
...read some records...
...then some more...
...and even more...
Yeeeeha! I've never felt better, standing in an open field on a cold night like this :-D
Don't get too excited, yet, because I immediately ran into the next 2-3 bugs with the keyboard handler. So it is not really playable at the moment. But this has been a really big milestone.
Update: It's usable!
A little fix in memory layout here, a change in keyboard layout there and...
Yesterday night I pulled out my oscilloscope and tweaked the timings used by the software serial implementation. I noticed some bits getting lost and tracked it down to the "edge delay" used to sync up with the start bit.
Now data transmission is much more reliable than before. Nonetheless, it is recommended to employ a protocol with checksums and re-transmit to ensure binary proof data transmission.
So, what should we do with it?
Maybe... allow the CP/M BDOS to load files via serial from a computer?
Since I got "boot from RAM" working yesterday, I eagerly started implementing the basic BIOS/BDOS functions of CP/M 2.2. No disk access, yet, but just the standard console input/output and housekeeping functions.
Fortunately, CP/M is well documented and there aren't actually that many functions that need to be implemented for a basic system.
So, I fixed my broken LCD DDRAM mapping and optimized the keyboard handler a little and added the most important CP/M BDOS functions.
Then I took a small .COM file (SYSGEN), placed it into RAM and jumped to it...
I was greeted by the program banner! It works!
That was really unexpectedly simple! The next 1-2 weeks will be used to implement a simple file system and all the necessary open/close/read/write functions, so we all can play ZORK before the year is over! :-)
Most of the inner workings of the V-Tech Genius Leader / PreComputer have been discovered. Even some lesser known functionality, which is hidden inside a proprietary silicon, is understood. Especially, how the LCD, the keyboard matrix, printer port and most of bank switching works.
Now for the philosophical question: What should we do with it?
When talking to people, most of them agree that getting an own operating system to work is priority 1. But on which OS to focus on is not fully clear. Personally, I would prefer CP/M, since it is the Z80 operating system with the most impact and support.
There are two problems with CP/M on this "toy hardware":
CP/M requires a disk drive. The V-Tech computers don't have one. But since we do have a cartridge port and proof-of-concept memory-mapped I/O, as well as a working serial port, getting some sort of SD card reader or serial storage medium to work should not be a big problem. In the meantime we can use bank-switched ROM/PROMS/SRAM or load software from the serial port (already working!)
The latter problem is a bit more tricky. See, on power-up the Z80 CPU jumps to address 0x0000 and starts executing the instructions located there. That's why there is a big system ROM located at that address.
Bank switching the system ROM
After thinking long and hard, I decided to leave the "non-invasive" route and add a little hardware modification to my beloved Genius Leader 4000 Quadro. I opened it up and put wires to the "Chip Select" lines of the ROM, the RAM and the cartridge port. Fortunately, these 3 lines are conveniently located on one corner of the PCB (near the cartridge port) and each go through a wire bridge. It is really simple to cut these bridges and add some wires, so they can be connected/disconnected at will:
On its own, this is not a very helpful mod :)
But now you can insert a ROM cartridge and use a different "Chip Select" pin (the new "internal ROM ~CS" instead of the default "cartridge ~CS" on Pin 35). A slight modification in your code (segment now needs to be 0x0000 instead of 0x8000) and your external ROM cartridge can now act as the internal system ROM! That means: Now we have a full 32kB of additional address space without de-soldering the internal ROM!
But be aware that the internal system ROM also contains crucial hardware initialization functions which now need to be done in our own ROM. This includes the LCD initialization sequence, resetting all the MUXes and bank switchers and -most importantly- reacting to interrupts and polling the keyboard matrix.
My current implementation works fine in the MAME gl4000 emulator, but still has some issues with the LCD (one line is not showing - using a non-standard DDRAM mapping) and the keyboard is not working reliably. This still needs some more research to get right. But enough to continue with some more experiments...
Booting from RAM
But now for the really tricky part: As I said, CP/M needs RAM to be at 0x0000. But since RAM is -usually- volatile, we can not simply solder in a SRAM IC and call it a day. It won't boot, since it is empty.
My current idea is to use the battery backed SRAM cartridge VTech Super Speicher 32KB for that. It contains a 32 kilobyte SRAM IC, as well as a coin cell battery and a few transistors (to invert signals and switch from internal to external power).
It should be possible to boot from a custom system ROM (mapped to 0x0000) while having the SRAM connected to the cartridge slot (mapped to 0x8000). Then, prepare/bootstrap the RAM contents to contain the initial jump instructions....
Worth mentioning is the work done by @Alex Rider about the french "YENO Compusavant". which seems similar to the "Genius Leader 6000 SL". Check out his website for more info: http://alexandre.botzung.fr/
I think I will be setting up a Github repository to merge all findings in an "(Unofficial) V-Tech 8-Bit DevKit".
Since many owners of models that don't have a printer port pointed out: There are some unpopulated parts on their main PCB and asked if the printer port could be retro-fitted.
Well, I guess so!
So there are only 8+1 bits in the OUT direction and a single bit in the IN direction. The latter is used to tell if a printer is connected and ready.
As I have found out, it is also used for PC communication: Using the 8 data output bits, the notebook selects, which bit of the incoming byte it wants to be set on Pin 11. So I guess the PC-Link cable contains an 8-bit "AND" IC.
But enough chatter: Here is the list of missing parts for the printer port:
P9506AN / DM74LS244N
74LS244N Octal Buffer
Ribbon cable to D-SUB 25
Ribbon 1-9 to Pin 1-9 Ribbon 10 to Pin 11 Ribbon 11 to Pins 18...25 and Shield (where Ribbon 1 is near C93)
40 nF capacitor
2.2 nF capacitor
R35, R41, R42, R43, R44
brown black orange
LM90 / 14C / M[otorola] 521
LM90 / 15 C / M[otorola] 512
Please let me know if you find any mistakes. Also, drop me a line if you managed to pull off the upgrade procedure. I'd love to hear about it!
I haven't written much about the PCB I have created to interface the V-Tech cartridge bus. That's mainly because I just haven't had enough experience designing PCBs so far, and didn't want to unleash a poorly designed and untested layout to the masses. So I spent 2018 doing a lot of design iterations on the so called V-Tech BusF###er cartridge, making it more configurable, reliable and debuggable.
It is 2019 now and I finally dared to send the first PCB layout to the manufacturing plant... And I was pleasantly surprised about the quality of the boards -- and disappointed about my skills ;-) as I simply made a lot of stupid mistakes (connected wrong GNDs, didn't leave space for additional caps or pull-downs, made important traces impossible to reach etc.)
But as of July 2019, there are now several Rev C boards on my desk, each successfully serving a custom boot ROM and having latches and registers to allow for memory mapped I/O to custom periphery! That is: 8 bits of data going onto the bus, and 8 bits going out. That is enough for letting 8 LEDs blink or querying the state of 8 push buttons. (If this would have been a commercial product back in the 90s, I would definitely have wanted one! Imagine "V-Techuino" ;-) ). Oh, and the boards are now daisy-chainable! The more boards you add, the more fun there is, of course.
On the software side I have developed a Serial Loader ROM, which allows code to be sent over a USB-to-serial FTDI cable connected to the V-Tech printer port. Just one click and your code gets compiled, transmitted, relocated, linked and run. Hardware and software development is now much, much quicker!
I have also been contacted by a chap named Erik Olsen and we might be cooperating on this project from here on. We both dream of having some sort of DOS running on the PreComputer and we have already made some serious progress. Maybe using FRAM or re-purposing GameBoy Flash Carts.... hmmm..
Thanx to the help of some great people at the Z88DK forum (hi alvin!) I was able to add some rudimentary support for the V-Tech Genius Leader / PreComputer to the Z88DK development suite. Just have a look at the platform called vgl to see some of my demo programs. It was quite a hassle for me to get used to implementing the necessary "newlib" I/O functions. Especially so, as they differ slightly for the 1000, 2000 and 4000 series.
Going forward, though, I recommend using just the simpler SDCC compiler if you want to get started on V-Tech development. You will not be able to benefit from the extensive demos of the Z88DK, but the overall installation and maintenance is much easier when just calling sdcc. The V-Tech headers and includes will be available on this project page or my github page soon.