Sunday, 11 January 2026

A New CRTC for the Minstrel 4th? Part 1

This is the the start of a series made up from an amalgam of several Patreon posts over the last year or so, and various new and revised bits to try to make it flow.

I have written various versions of this introduction, some got into the Patreon posts, some got filed away into the "got a bit too ranty folder".

When I bought back the Minstrel 4th in May (almost, but not quite, entirely so I could do the May the 4th joke again), it was pretty much unchanged from the previous version.

As always, I couldn't resist tweaking a few things. Just minor things like updating the logo and adding an NMI button in case it comes in useful in future.

I only had limited parts left, so I only ordered a small batch of boards, to see how it went.

Now I need to order some more boards, it's time to consider a problem.

The Problem

Here in very simple terms in the problem:

The microcontroller I use for the CRTC was marked end of life in 2023 in the PDIP packages (plastic DIP through hole), along with the ones I use for the Mini PET.

I thought it would be useful to just talk through all of those, see if I can talk myself out of any of them, or if any of them suddenly seem the obvious option.

I have been playing with a new toy, a 9 input logic analyser, the IKA logic SP259i.

That has been very useful at looking at the signals on the video section of the Minstrel 4th.

I can do a single capture and get several complete frames of video with all the relevant signals captured.

I can then zoom into individual lines of video.

And even down to individual clock pulses, all on the same capture.

It also has a mode where the 9th input can be used as the clock for sampling, so now all the results are shown in terms of CPU clock cycles, so I can see there that line goes low for 3 clock cycles, then high for 5. Much easier than looking at time periods.

It avoids keep having to divide 460ns by 153.84ns to find that is 2.99 clock cycles. Less of an issue at 1MHz or 8MHz with 1ms or 125ns cycles, but with the 6.5MHz is really helps.

(N.B., that presents a somewhat idealistic view, with a sample on the falling edge of each clock cycle, there may be glitches or all sorts happening in between, but in this particular application, it is ideal for what I need to see)

Option 1 - The Simple Way

The simplest way is to change to a new microcontroller.

The part I used was the ATmega48PA.

The part numbering scheme here is ATmega <memory size> <package> <suffixes>

The memory size runs from 4K on the device I chose up to 32K on the ATmeag328 used on the Arduino etc.

The package was 4 for 40 pin and 8 for 2pin, (don't ask me why)

The suffix is where it got confusing. There was a plain version with no suffix, and ones with A, P, V, PA and PB on the end. These were lower power / die shrunk versions, although the exact differences are never clearly explained and cause much confusion, particularly as some parts have the same device ID and others do not.

I could use any of the 28 pin devices, other than the V which is low power and cannot run the higher clock frequencies. The PB is an updated version, but is only available in surface mount.

I could use the ATmega48, ATmega48A, ATmega48P and ATmega48PA. 

I could also use similar devices with more program memory (ATmega88PA, ATmega168PA, ATmega328PA etc.). These are pin compatible and largely code compatible, just requiring a rebuild due to changes such as additional timers in the devices with the larger memory space affecting the interrupt vector table.

At one point, it seemed all of those went out of stock, potentially as everyone stocked up on their last time buys.

(N.B. as of January 2026, the ATmega164PA and similar used in the MiniPET are no longer available in PDIP, but the ATmega48PA still appears to be)

Time to look at alternatives

(yes I know the new one is apparently 3 years old and the one that is meant to be discontinued was made earlier this year......)

The ones that appear to be in production and likely to continue are the AVRxDx and AVRxEx ranges, with a slightly (but only just slightly) less confusing naming scheme.

The naming convention here is AVR <memory size> <range> <pin count>. 

Memory size is 16, 32, 64 or 128, and pin count goes from 14 to 64, including through hole and surface mount variations.

The range is where the wheels come off a bit. There is DA, DB, DD, DE, DU, EA and probably several more. Nowhere have I found a useful guide to say what the differences are. Some have additional analogue components like OP Amps and Compactors. Some have port C able to run at a different IO voltage to the rest of the chip. The number and type of timers also change.

(there is now also a version with an S suffix that appears to be PDID support which allows you to disable the programmer and debugger features and completely lock the chips down)

The one I chose was the AVR16EA28. This is one of the simpler of the versions, with enough pins and memory for the task

The number of available IO pins worked out the same, but they are arranged differently, so I will need to rejig the code to cope with things like a counter being on PA2-PA6 rather than PD0-PD4. Handily, I can swap the single cycle increment instruction for a single cycle addition to a register which is preset to 4, so it will count up in 4s but I will still see 0-32 on the pins.

The downside is this will still need the dual port RAM chip.

My mind keeps idly wondering if I can maybe replace that as well, since that is also discontinued?

Option 2 - Cache and carry

This idea would still need the dual port RAM, but as I have been thinking about other options, one that has suggested itself to me is to try to cache the reads to the video RAM at the start of a row of characters (8 lines), a bit like the VIC-II chip in the C64 does. That would only needs reads to the font RAM to get the pixel bitmaps, but still half the reads during display generation.

But maybe I could cache the font RAM as well?

Or even, I could cache the whole frame in the microcontrollers 2K RAM (more is available in pin compatible chips).

Using that capture, it is easy to see that there are 50,000 cycles between the end of one frame of video and the next. Easily enough to read in 2000 bytes from the video RAM, whilst still generating the video framework. (and maybe skip the cache update if there have been no writes to the video RAM?)

That was a quick test of firing a series of interrupts at important points whilst a main thread could be filling up the cache / frame buffer in the background.

Option 3 - Be the video RAM

It then occurs to me, maybe I can cut out the middle man here and remove the dual port RAM altogether, making it easier in terms of parts in future.

The video RAM could be written by the Z80 at any time, but because of the number of cycles most of the write instructions take, that might only be relatively slow at the microcontroller. And I could always run the microcontroller at 13MHz to have twice as long to deal with things and just have an extra divider stage to get back to 6.5MHz externally. (note to self, try to find those 13MHz crystals you ordered last time you had a mad idea like this, or order some more before the RS cut off deadline)

The top line shows the Z80 writing to video RAM at the start of each frame in the "ZX81 BASIC for Minstrel 4th" ROM. The normal Ace ROM only writes to RAM when it needs to change, so this is worse case.

You can see about 4 writes during a line of video, and 64 instructions between them.

Of course, you can run the Z80 at double speed, 6.5MHz. (although loading from tape won't work, so I haven't mentioned that in the ZX81 BASIC posts, I might have a go at doubling the delays in the loading code and see if I could get that working for a 600% ZX81 speed option)

Here the Z80 frame buffer completes almost before the visible line drawing starts, but the writes are now twice as fast, 32 instructions separating them.

What is the fastest it could write to RAM? LD (DE), A is 7 cycles. Maybe if you set the stack pointer in video RAM a JSR would cause two writes close together as the return address is pushed onto the stack?

It's not impossible anyway. I think I would probably have some latches for the address and / or data, then it is just up to the microcontroller to read those in before the next write?

That would only work for writes. The character RAM is write only, so that is fine, but video RAM is read write.

(and I have since proved that I can't even make reads work with a 24MHz microcontroller and a 1MHz CPU - http://blog.tynemouthsoftware.co.uk/2025/12/faster-isnt-always-better-a-cautionary-tale.html )

That's fine, there is space in the main RAM chip that is not being used at those addresses. I could enable that in the video RAM range, and have writes going to both there and the microcontroller, and reads only coming from the main RAM.

It would need some trick logic in the addressing so that access to $2000-$23FF acts the same as the mirror at $2400-$27FF.

I could even bring in the Ace priority system, writes to $2000 upwards are Z80 priority, and should be actioned even at the cost of snow on the display.

Writes to $2400 upwards should favour the video display and could use the Wait line to halt the Z80 until the a quiet period in the display to process the write.

Hmm, lots of options there.

Option 4 - Use a Raspberry Pi

You will find the unsubscribe button in the usual place.

Revisiting Rabbit Holes

Using the internal RAM as a cache or the main video RAM opens the option of using the internal shift register rather than an external 74HC166, to save pins.

One of the great things about having 15 years worth of blog posts, is I can look back at ideas I was considering in the past and read through my thoughts at the time. (which is another reason for writing all of this now)

Reading some old posts may have saved me going down a rabbit hole again with this.

Thank you past me.

That was in the context of trying to run three shift registers for RGB, so maybe a single version would still be viable?

Which option then?

Lots of options to consider.

I think the best plan for now is to look at the new microcontroller option.

Tune in next week to see what fun I had with the "easy" option.


Adverts

Check out my Tindie store for all sort of kits, test gear and upgrades for the ZX80, ZX81, Jupiter ACE, Commodore PET.


Patreon

You can support me via Patreon, and get access to advance previews of development logs on new projects like the Mini PET II and Mini VIC (when I get back to them once I have finished tidying up) and other behind the scenes updates. This also includes access to my Patreon only Discord server for even more regular updates.