Sunday 29 October 2023

Building a Mini PET B Kit

Mini PET B is the version of the Mini PET designed to act as a drop in upgrade / replacement board for a Commodore PET or CBM.

It provides 32K of RAM, and selectable ROM sets. 40 x 25 monochrome video, compatible with most software other than a few demos which require a 6545 CRTC. Modern WDC W65Cxx chips are used to provide a PET compatible computer, with the same external port - IEEE-488, Userport and two datasette ports. Note the userport is the PET standard, and is not the same as the VIC20 / C64 (most importantly it does not provide external power).

Today I am building one of my kits. Step one is always to knoll all the parts out (or at least it is for me).

Note the parts on the bottom right are optional, if you require composite video output or barrel jack 9V DC power input.

I am going to build this one without those parts initially, but will add them in later so show different use cases.

I start with all the low-height components, the resistors, capacitors, diodes, the crystal, the two power transistors and the voltage regulator.

Next I fit all the IC sockets. If I am building one of these for myself, I normally do not use sockets for the logic chips, but I will in this case.

Next the resistor arrays, noting they are all oriented with their pin 1 dot to the left. Finally the remaining connectors and taller components.

With all that done and cleaned, time to fit the ICs. As ever, they are arranged on the foam pad in the same positions as the PCB.

And we are done. Time to install the board in the PET case. This is my 4032. The two holes on the front of the Mini PET board are for the mounting pillars. They are self adhesive, but you don't actually need to stick them down unless you plan to move your PET around a lot (have you tried to pick of of those it up?)

The top left of the board has an earthed pad which is the connection for chassis ground. Fix that with the original screw.

Top right is also screwed to an original pillar, but is not electrically connected.

Finally the power, monitor and keyboard connectors.

Power is either 9 pin on 2001N/30xx/40xx and 80xx machines, or 5 pin on 2001 PETs, aligned to the right of the connector. The blue wires on the 9 pin connector are for the 18V tap on the transformer, which is not required. The other black is an extra ground.

If you want to check voltages, black is common ground, and the centre tap of the transformer. the two brown wires are the other taps on the transformer. There should be around 9V AC between either brown wire and the black (ground). The two red wires are connected together at the big capacitor. There will be no voltage on the red wires unless they are plugged into the Mini PET. The left hand red wire is 9V DC OUT of the Mini PET to the capacitor, and the right hand is 9V DC back INTO the Mini PET from the capacitor. The grey boxes show the original parts mounted in the PET case, and not on the Mini PET PCB. (there are 100nF capacitors in parallel with each of the diodes, omitted for clarity)

With everything wired up, time to set the DIP switches and power on.

For the 12" 50Hz monitor in the 4032 I set switches 6 and 7 on, and the rest off.

Switch on, and there was the familiar chirp and there is the ready prompt.

I ran various test programs, including the built in self test (SYS 40960), and my old BASIC memtest program.

Maybe I am getting slightly better at taking pictures of CRTs?

To show an alternate use case, I removed the board again and installed the optional composite video out and DC in components. That allows the board to be tested outside of the PET case, or you may have some other use in mind.

Those allowed me to do some further bench testing with an SD2PET and a datasette.

The Mini PET B can be used stand alone like this, although, you probably want the Mini PET A instead.

Here everything again passed all the tests, so time to try a few games, I think I will load one from tape for old times sake.

All looks good. Loaded first time.

Here he comes, good old Rex.

Ooooh, I found the exit this time.

So there is the Mini PET V V1.58


The Mini PET B and A are available in kit and built forms from my SellMyRetro store:

Mini PET A

The Mini PET is a Commodore PET compatible 6502 based computer with 32K of RAM and a choice of PET BASIC 1,2 or 4, or Mini PET BASIC 4.0.

This is the stand alone version that can be used with one of my keyboards or another aftermarket PET keyboard (normal / graphics layout recommended for better compatibility than the business keyboard).

Mini PET A on SellMyRetro

Mini PET B

The B variant is designed as a drop in replacement for a PET motherboard. No keyboard options are provided, as you are expected to use the PETs original keyboard.

In addition to the DC power and composite video output of the A, the Mini PET B can use the PET power supply (5 pin or 9 pin) and drive a PET 9" or 12" monitor.

Mini PET B at SellMyRetro:


You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here, and some of these posts contain bits from several Patreon posts.

This also includes access to my Patreon only Discord server for even more regular updates.

Sunday 22 October 2023

PET IEEE-488 Diagnostics (updated version)

This is the new version of my PET IEEE-488 diagnostics board.

It is designed to plug between a Commodore PET or Mini PET and an IEEE-488 bus device.

When the bus is in use, the LEDs will flash to show activity.

This is an update of my older version with an LED bargraph, I think the individual LEDs look better.

I have also updated the drivers, they are now using 74HCT245 chips to reduce loading on the bus signals. This also allows the LEDs to be lit when the signals on the bus are asserted (low), the previous version was inverted and the LEDs lit when the signals were inactive (floating high).

The input ranges of the 74HCT245 suit the IEEE-488 bus, with low and high being comfortably in range, and the input being tolerant up to 5V, although in practice, the bus voltage should not normally be as high as that.

IEEE-488 Typical
Asserted (low)
0.4V (max)
0.8V (max)
Released (high)
2.4V (min)
2.0V (min)

I have used a mix of red and green LEDs, although you can use whatever you prefer.

There is now also space for a pin header to be installed to attach a logic analyser to debug signals on the bus, if you happen to be developing a new IEEE-488 bus device (who me? you might think that, but I couldn't possibly comment)

Diagnosing PET IEEE-488 Bus Faults

The following section is extracted from a previous post, updated to cover using this new board.

All of the Commodore PET series of computers have an IEEE-488 port, used for disk drives and printers. (I checked all of my PETs, and none of them seem to be labelled, but imagine it says IEEE-488 over that port)

There are quite a lot of elements that go to making up the port, and thus many things that can go wrong. It is a parallel 24 pin bus, with 8 data pins, and 8 handshaking lines, and 8 ground pins.

Close by the port, there are three MC3446 buffer chips, and next to that a 6520 PIA. You might think that with more than 16 IO pins, that 6520 would be enough to drive the port, but that's not the case.

It is arranged so that each pin on the IEEE-488 port is connected to two IO pins, one to drive the pin, and one to read the values. So as well as all the pins on that 6520, it also uses a number of IO pins on the other 6520 (near the keyboard connector) and the 6522.

REN is not used, the PET is always going to be the bus master, so it is tied low. IFC is only an output, and SRQ only an input.

Reset buffered through 7417
Tied low

In the above table, there are three main chips referred to PIA#2 is the 6520 nearest the keyboard connector, PIA#1 is the other 6520, nearest the IEEE-488 port, VIA is the 6522, usually between those two.

The IEEE-488 bus is one part of the PET which didn't change from the 2001 up to the 8032, and with a few minor changes onto the later CBM-II machines.

This two way circuitry does make it possible to do quite a lot of testing from the machine itself. If you read back the value of a pin, then change the machine output and read it back again, you can see if it has changed. The 8 data bits are the easiest to start with, whatever value you write to address 59426 is written to the port, so:

POKE 59426,0

will set all the outputs low (all LEDs should be on). Writing 0 to one of these outputs pulls the bus line low, this is the 'asserted' signal, and means it is active (LED on). When no device is asserting that signal, the line is pulled high by pull up resistors, 'released' to high, and the LED will be off. Nothing should ever drive the bus high, all they do is let it float high or pull it low. 

To read back from the port, type:


That should show 0. If it does not, there is a problem with PIA#1 or one of the MC3446 buffers. You can then try various other values up to 255 which should have all the output lines high (all LEDs off).

Testing other pins is a little more complicated, this table shows the values to poke and peek at.

Write 0 (Assert)
Write 1 (Release)
Read value
POKE 59426,0
POKE 59426,255
POKE 59409,52
POKE 59409,60
POKE 59427,52
POKE 59427,60
POKE 59456,253
POKE 59409,255
POKE 59425,52
POKE 59425,60
POKE 59456,251
POKE 59456,255

This can be useful to identify which pins are working, and any that are at fault. It does not show if the problem is the output pin (or it's associated buffer) failing to drive the output low, or the input pin (or it's associated buffer) failing to read back the state correctly.

You can check this with a multimeter on the pins of the port, but it is easier to use the PET IEEE-488 Diagnostic module and monitor the signals on the LEDs.

If the LEDs do not change when you poke values, then the problem is either the MC3446 or the PIA/VIA chip driving the output. You would need to probe the signal between those chips to see if that is changing to see which it is.

If the LEDs are changing, but the values read back, then the problems is either the MC3446 or the PIA/VIA chip reading the input. Again, probe the signal between the chips to see which is at fault.

I should have done this last year when I designed this updated version of the boards and got them made, but you know how it is.....

A tweet* yesterday from Ian Scott Johnston showed a similar board he had made for the GPIB interface, and reminded me I needed to write this up.

* what am I supposed to call them now, "a post on X"?

If you don't know Ian, you should check out his YouTube channel for some great test gear repair videos.


I have listed these on SellMyRetro, it is not (currently) possible to use a dropdown to select different options, so I have listed the PCB only, full kit and assembled versions separately. All include the board to tap power from the datasette, although you can use an alternate 5V DC supply if you wish.

PET IEEE-488 Diagnostics Assembled

PET IEEE-488 Diagnostics Full Kit

PET IEEE-488 Diagnostics PCBs only


You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here, and some of these posts contain bits from several Patreon posts.

This also includes access to my Patreon only Discord server for even more regular updates.

Sunday 15 October 2023

How the ZX81 Generates Video

Now the Minstrel kits are back in stock, it's time for the second in this series of posts from my Patreon, this one covering the video output of the ZX81.

Following on from the previous post which covered the inner workings of the ZX80, today we look at the changes made for the ZX81.

Most of the video generation circuitry is the same as that in the ZX80, so please refer to the previous post if you have not already seen it.

Before discussing the actual changes, I should first address the biggest practical change. All of the TTL logic chips used in the ZX80, as well as all the logic required to implement the other changes have all been contained within a single IC. The ULA (Uncommitted Logic Array), an early form of CPLD, in this case a factory mask programmed array of logic gates. This is a very early one, with just a date code.

The new ZX81 board (right) was a lot smaller and simpler than the ZX80 (left) thanks to most of the chips being replaced by the ULA.

The exact implementation of the new features is not obvious from looking at the board or the schematic. It has been reverse engineered by various people over the years, most notably Grant Searle who's website is a mine of information for all things 8-bit single board computer and ZX80/81 related..

Other than the cost reduction and simplification of the ZX81 into essentially a 4 chip computer, the main aim was to get rid of the flicker whenever a key was pressed or code was run.

The Z80 in the ZX80 was usually in one of two states, it was either drawing the screen, or running code. 

Since the Z80 is so intricately involved in generating the screen, it cannot run code at the same time. When it has to run code, it can not generate a screen. This leads to anything from a slight flicker when you press a key to extended periods where no video signal is generated as user code is executing.

A modern TV will switch to "No signal" after a few seconds of that. 

(you still get a black screen on an old TV, it would only be snow if the modulator was shut down, but it's difficult to take a picture of a black screen, so here is a picture of some snow in case you are feeling festive)

To get around that, the ZX81 added a new mode. The ZX80 style mode became known as "fast" mode. A mode where code is run at full speed, but cannot generate a screen.

The ZX81's new mode was the corresponding "slow" mode. Here, code is run when the blank areas at the top and bottom of the screen are being generated. The rest of the time, the screen is generated as normal. Code is only run for a short amount of time, hence the "slow" mode.

The USA models had fewer blank lines each frame (64 vs 112), so slow mode on a TS1000 was even slower than on a ZX81.

The "fast" mode was still available if a lot of code needed to be run quickly, a notable example being the "mists of time" when the maze is generated in 3D Monster Maze (oddly, this is mainly due to that section being written in BASIC, unlike the rest of the game).

The new version of BASIC for the ZX81 was double the size, an 8K ROM, with trig functions and a floating point number system. It also had an updated font (see ZX80 post for examples of the change to the K character).

It added lots of functions, and moved many of the existing ones around, into more familiar places such as PRINT and " on the P key, and LOAD on J.

There were also keywords to enter the new SLOW mode and FAST mode.

So, how does it work?

A quick recap of how the ZX80 generates normal lines:

The Z80 is setup to read a line of characters in the display file. It progresses through that line, incrementing the refresh counter for each character, until the new line character is reached. This halts the Z80 and it remains halted for a short time until woken by an interrupt at the end of the line.

HSync indicates the start of a line, /Halt goes low whilst halted, and the IntAck pulses show where the interrupt is acknowledged. (I am not showing /Int here as it is tied to A6 which does a lot of other things, so it does not help)

The blank lines at the top and bottom of the display are generated by pointing at the start of the DFILE which is a newline character, so it immediately halts and starts to run NOP instructions internally.

It remains halted for the rest of the line, until it is again woken by an interrupt.

That is a lot of time spent halted, and this wasted time is used on the ZX81 to execute user code.

Previously the mechanism to generate the interrupt at the end of the line relied on the Z80 refresh counter counting up to a point where A6 was low and an interrupt was triggered.

Using the refresh counter relies on the instructions all being the same number of cycles (they are NOP instructions). User code will contain a variety of instructions and the number of cycles each instruction uses varies, so this will no longer be a constant time.

To get around this, the ZX81 added a counter which is reset at the start of each line. When it counts 208 cycles, it is reset and the next line begins. The start of each line generates the horizontal sync pulse, and when configured to do so, a Non Maskable Interrupt that will interrupt user code and increment an internal counter of how many lines have been drawn.

NMI generator enable

To control if the NMI signals should be generated, a latch is used. This is set by OUT FE,A, and cleared by OUT FD,A. These calls are generated by the OS as part of generating the display.

Looking at a whole frame, you can see the NMI generator is enabled in the sections at the top and bottom of the screen.

Why is the generator disabled during the VSync pulse? well that is when the keyboard is scanned, as it was in the ZX80. The first keyboard read is actually the trigger for the VSync pulse (see the ZX80 post for further details).

The NMI Generator enabled signal (here shown as NMI_On) is used to gate the HSync signal to create an /NMI pulse at the same time.

/Wait is also pulled low, to ensure the Z80 is in the correct T-State when the NMI is serviced. This is gated by the /Halt signal, which would always be high as that is normally triggered by processing the End of Line character, which will not happen on the non-visible lines.

I have drawn the /Wait signal generator using a NAND gate (as it is in the Minstrel 3), but that is not the way it was implemented on the ZX81. The ULA contains all the counters and logic to create the /NMI pulse, but the /Wait signal was implemented externally with a single transistor and some passive components.

It looks a little odd in the ZX81 schematic, so I have redrawn it differently to make it easier to see what is happening. For the moment, imagine the emitter was connected to 0V instead of /NMI. It is then a simple inverter. When /Halt is low, the transistor is off, so /Wait is pulled high by R17. When /Halt is high, the transistor switches on and pulls /Wait low. Now, add in the complication that the emitter is actually tied to /NMI. No current can flow in the transistor unless /Halt is high and /NMI is low, in which case, /Wait is also pulled low. (what is the capacitor doing there? it speeds up the switching time of the transistor).

Here you can see the last few visible lines, the NMI generator being enabled and then the first lines where user code is run.

During the text lines, /Halt is used to halt the Z80 until it is at the end of the line. This stops when user code is running, and /NMI pulses take over.

HSync counter

HSync pulses are generated based on a self resetting counter. The counter is reset when outputs Q0, Q1, Q2, Q3, Q6 and Q7 are high. The first time this is reached, Q4 and Q5 will be low, so the value will be 1100 1111, 0xCF, or 207. So it counts from 0 to 207 based on a 3,25MHz clock. 3,250,000 / 208 = 15,625. The gives a line frequency of 15.625KHz, a period of 64uS, exactly as required.

Q4 and Q5 are not tested, so the pulse would be generated at CF, DF, EF and FF, but the counter should be reset the first time the other outputs are all high at CF, so it is not necessary to test those.

I have drawn the schematic using ideal parts, to make it easier to follow. For example, the counter is actually two 4 bit counters chained together, and you can't get a 6 input AND gate, so in practice a triple 3 input AND gate or dual 4 input AND gate would be used, but that makes it a little more difficult to follow.

For the text lines, the end of the line causes an interrupt to fire. Once this is processed, an Interrupt Acknowledge signal is generated. The IntAck appears to arrive just before the counter would reach 208, so the count = 208 pulse is not fired for text lines. Both the IntAck and counter=208 pulses should reset the counter, so they are ORed to create the counter reset pulse.

The counter is tapped at the Q3 point to get a 16 cycle clock, a pulse every 4.92uS. A series of flip flops is then used to generate some pulses based on this. HSync needs to start after 16 cycles, and last 16 cycles, so the following logic is used to create the appropriate 16 cycle / 4.92uS pulse.

Fast Mode

In "fast" mode, (the only option in the ZX80) the Z80 is dedicated to running code, so the screen does not get updated.

The 208 cycle counter is still running and generating HSync pulses, but there is no activity on the other signals.

The NMI generator is not enabled, so no /NMI pulses are generated. The keyboard is being periodically checked, which activates the VSync, so that signal is permanently stuck low, and the composite video signal is flat. Yellow is composite video, blue shows the HSync signal.

Disabling VSync Generation

When blank lines are being generated and user code being run, the VSync generation circuitry is disabled. An AND gate is added to stop a user keyboard read from starting a VSync pulse in the middle of a line.

A NOR gate is used to interrupt the signal which loads the shift register, so the output remains low, which translates to a white line on the screen.

The HSync signal generated by the old hardware is no longer used, so in the Minstrel 3 I omitted the circuit. That means only VSync is used as the save signal now, with no glitches caused by the HSync circuitry.

Back Porch

On the Minstrel 3, I added an extra flip flop to the circuit that generates the HSync pulse. This is an additional 16 cycle pulse directly after the HSync, and is used to create the missing back porch of the video signal. On the Minstrel 2, this was generated using an RC circuit, but I prefer the this approach.

Here you can see the three pulses generated at the start of each line.

The timings are close enough to the requirements, so that works well.

Ideal Timing
Actual Timings
Horizontal Sync
Back Porch

Here you can see the /Hsync in blue and the back porch in green and the resulting composite video signal in yellow at the end of a line.

The later ZX81 2C210E ULA also had a back porch signal, probably generated in a similar way.

The first pulse on the above schematic is marked as the front porch, although it is not used. That could have been generated and ANDed with the back porch signal to generate a proper front and back porch, but in practice, it does not seem to matter. The timing would also need adjusting. The front porch should be approximately 1.65μS, so that 16 cycle pulse would need to be gated with the lower bits of the times to make it only active for the last 4, 5 or 6 cycles of the 16 cycle pulse.

Ideal Timing
Actual Timings
Front Porch
Alternate 1
Alternate 2
Alternate 3

Other Minstrel 3 changes

The Minstrel 2 followed the ZX80 schematic quite closely, other than the improved composite video circuitry tacked onto the end in place of the RF modulator, and the modern ROM and RAM chips.

The Minstrel 3 deviated quite considerably. I started with the Minstrel 2 version of the ZX80 schematic and added in all of the above changes.

A big change was the switch from 74LS series TTL chips to the high speed CMOS 74HC series. This cleaned up all the signals, and reduced the current consumption by about a third.

There were also two new jumper options.

The first disables slow mode to make the circuitry act like the ZX80. It stops the NMI generator latch being triggered, so slow mode will never be enabled.

This has also been reimplemented with a 74HC74 flip flop, so the power on state can be controlled by the reset line. The same has happened with the VSync flip flop.

This helps when using the ZX80 4K ROM on the Minstrel 3 hardware. The 8K ROM starts with OUT ($FD),A which disabled the NMI generator, but the 4K ROM knows nothing of it. VSync starting on just means the composite video output with start low for a clean first frame.

The second creates a grey-scale border by feeding a chequerboard pulse into the shift register input which is used when no data is being clocked in, when no characters are being displayed. This is the clock pulse XORed with the lowest bit of the line counter so it alternates each line. As seen in the previous post, this gives an insight into the unexpanded display file.

There are also jumpers to select normal / inverse video and 50Hz / 60Hz frame rate as in the Minstrel 2, and jumpers to select the upper address lines to allow multiple ROM images to be used.

As was later added to the Minstrel 2, a character synchronisation flip flop is used to tidy up the video signal so it always generates equally sized pixels. The clear input of the flip flop is used to add the back porch signal.

A composite video mixer is used to provide a reasonably standard composite video signal.

Here showing a screen full of chequerboard characters.

For details of other changes, including the mysterious "high resolution graphics enabling device", see a previous post:

The latest revision of the Minstrel 3 has a pin header which mirrors the signals at the edge connector. This is going to be useful for expansion cards, and also for attaching logic analysers for debugging.

For the traces in this post, most of the signals I need are on the other side of the board, so there are a few more wires there.


Minstrel 3

The Minstrel 3 is a ZX81 compatible Z80 based computer with 32K of RAM and 8K floating point BASIC. It does support slow mode, and several high resolution mechanisms, so the majority of ZX81 games will run fine.

Minstrel 3 kits are available from

And also in built, kit and PCB only form from SellMyRetro

See also Minstrel 2 (ZX80 compatible) and Mini PET (Commodore PET compatible) kits, more info here

And Minstrel 4D kits (Jupiter Ace compatible)


You can support me via Patreon, and get access to advance previews of posts like this and behind the scenes updates. These are often in more detail than I can fit in here, and some of these posts contain bits from several Patreon posts. This also includes access to my Patreon only Discord server for even more regular updates.