Sunday, 15 May 2022

PET Sounds

In recent months, between the new posts, I have been posting update versions of content previously published on my Patreon. This one is slightly different as I have effectively recreated the Patreon post using some new kit. More info on that later, but I will hand you over to past me writing on Patreon.....

I have been writing a few games for the Commodore PET / Mini PET recently, and I wanted to add sound to them.

The PET has a 1 bit sound output, A piezo transducer which can be set as on or off. To create sounds, you turn it on and off quickly. 

And that's the end of today's post. Goodbye.


OK, so maybe you want some more detail. I couldn't find much information on how exactly to achieve the "turn it on and off quickly" bit, so I thought I would document what I worked out.


Back in the days of the first PETs (to be precise, all the 9" non-CRTC PETs), the PET didn't have any built in sound capability. Games like Space Invaders benefited greatly from sound, so the PET implementation contained instructions on how to wire up a speaker to your PET so that when you hit an alien you heard the noise.


The idea is basically taking the output from the CB2 pin on the user port and feeding it to an audio amplifier. This concept was taken onboard by Commodore when they produced the 12" CRTC Based CBM machines (which we all still call PETs anyway - see a future post for the long and detailed story behind that).


Here they took the CB2 output but also ANDed it with the DIAG pin on the user port, PA7 on the keyboard PIA. This is the pin that should be pulled low to activate the machine code monitor on boot. Not quite sure why they did that, it means you can drive the speaker from two different outputs, so I suppose you could technically have two voices or create some kind of tremelo effect?

For the Mini PET, I wired up a piezo transducer to the same signals.

Whilst the diag pin is an option, I will concentrate on the CB2 pin, as this will also work on any PETs adapted as per the Space Invaders instructions.

Method one - bit bashing

One way to make sounds is to turn the CB2 pin on and off quickly. CB2 is designed for handshaking, so it needs to be driven differently to a normal IO PIN.

The VIA PCR (Peripheral Control Register) is at address 0xE84C (59468). This controls 4 pins, CA1, CA2, CB1 and CB2.


CA1 and CB1 are input only, and can't even be read directly, all they can do is trigger an interrupt. CA2 is used to control the video character set, low is uppercase / graphics, high is lowercase / uppercase. Any changes made to that register need to keep these other settings intact.

The values for normal operation are 0xCC (204) for off, 0xEC (236) for on. The first thing to tryis a simple BASIC program.


However, that's not particularly fast, and the output is switching at just under 50Hz. Congratulations you have created a mains hum simulator. Take the rest of the day off.


Here it is interesting to look at some of the speed improvements you can get by optimising the simple BASIC program. 


I thought putting everything on a single line might make any difference, but it didn't, so lets try a few more tricks. Here I am using abbreviated commands and assigning a variable to the address being POKEd at.


That's more like it. 100Hz, double what we previously achieved.


I next tried using variables for the two POKEd values as well.

Again a doubling in speed, now 200Hz. 

That is still only 200Hz, a low, annoying hum. To create something more tuneful, we need to look to assembly language. I've been doing a lot of 6502 coding recently, so I just typed this in, but it probably needs more explanation. 


This is a listing of the same code (looks like I got it right)


I picked 1000 as the base address as that is normally free, but the code could have been based anywhere. This does the same thing as the BASIC program, POKE one value, POKE the other value, go back to the start. Only in assembler, it does it a whole lot faster.


This is now 66.7KHz, well outside of my hearing range. To make it audible, all it needs is a delay between the on and off pulses. 


Using the simplest delay loops counting to 256 gets that down to around 400Hz, so you can see it's just a case of fine tuning the delay values to get around the tone you want.


There are a few problems with this. Firstly, it ties up the processor in loops and also, you can might just be able to make out some of the gaps are slightly longer than the others. This is more obvious on the higher frequency version without the delay. These are caused by the system timer interrupts, and you can actually change the tone of the sound by pressing keys (which extends the interrupt slightly). 

Zooming in on the gap, the interrupt routine lasts around 640uS, during which time, there is no sound output. So this approach is not really viable in practice.


Method Two - Shift Register

Using the CB2 pin for sound wasn't just an arbitrary choice of an available I/O pin. The other thing the CB2 pin has going for it is that it can be configured as a shift register output, which will shift out at a speed determined by a counter running directly from the system clock. This has the advantage that it doesn't tie up the processor, and is not disrupted by interrupts. 

This is controlled by three registers, the first of which is the ACR (Auxiliary Control Register) at 0xE84B (59467). 

The option we want here is "shift out free running at T2 rate". So the ACR is set to 0x10.

The second register is the shift register value, at 0xE84A (59466). This controls what bits get sent to the port. The three most useful values here are:

  • 0x0F - 00001111
  • 0x33 - 00110011
  • 0x55 - 01010101

You can also use the inverse of those (0xF0, 0xCC or 0xAA). Other values (such as 0x01, 0x03 etc. will alter the mark space ratio of the output pulse and produce a less pure note (which may be what you want).

If you think about it as they are drawing the output waveform, so the output is high when there are 1s, and low with 0s. So, the way they are shifted out, 0x33 will look the same as 0x0F if shifted out twice as fast. So shift is set to 0x0F.

The final register is the lower byte of timer T2 in the VIA chip. This controls how long it is before the next bit is shifted out. The high the value, the lower the note. 

This note will continue to play as you get on with other things, so it can all be controlled from BASIC. The final POKE 59467,0 turns off the shift register output.


As an example, 0xEE will cause bits to be shifted out so that 8 bits takes 3.84mS. With the 0x0F pattern in the shift register, that forms 4 lows and 4 highs, which creates a square wave of 260Hz, which is almost the 261 Hz of middle C.


If I try to mark out the byte that is being shifted out, you can see the 00001111 of 0x0F.


If I leave everything else the same, but change the shift register to output 0x33 instead of 0x0F, the frequency is doubled to 520Hz (C5).


And again, changing it to 0x55, we get C6.


So that is that's all there is to it. The counter value sets the note, and the shift register pattern sets the octave. (or rather, the lowest octave - you can get about three octaves from each setting with different counter values)

So what was all this for?

Well, I have been working on an adaptation of David Stephenson's Tut-Tut. That was originally written for the ZX Spectrum (as a type in listing in Paleotronic magazine - https://paleotronic.com/2019/11/05/tut-tut-a-new-game-for-the-zx-spectrum/), and then for ZX81 (https://www.zx81keyboardadventure.com/2019/10/zx81-game-tut-tut.html) and then an improved ZX Spectrum version (https://www.zx81keyboardadventure.com/2020/04/zx-spectrum-game-tut-tut-2020-ed.html) and finally a port for the Jupiter Ace / Minstrel 4th (https://www.zx81keyboardadventure.com/2020/05/tut-tut-on-jupiter-ace-part-1.html).


This is a great game, reminds me of my old favourite Repton.


The ZX Spectrum versions had a little tune (almost, but not quite, entirely unlike "Walk like an Egyptian"). In the Spectrum version, this was done as a series of BEEP commands, with a parameter selecting the full or brief version:

if ubFull then
        beep .25,-2 : beep .125,8 : beep .125,5 : beep .25,5 : beep .25,-2 : beep .25,5
end if
beep .25,-2 : beep  .125,3 : beep .125,3 : beep .25,8 : beep .125,-2 : beep .125,-2

Beep takes two values, a duration in seconds, and a note with middle C being 0. 

  •  -2 = A#
  •   0 = C4
  •   3 = D#4
  •   5 = F4
  •   8 = G#4

I had the mechanism to play the notes, just needed to set the duration. That wasn't too critical, so I just used a simple counter.


I added a 5mS gap between notes as that was what the Spectrum was producing.


And there was the finished song, and it sounds just like the Spectrum. (side note, I had to cheat as I couldn't quite get the A#3 note, but it's closer to that than B3.


But Dave, you said a couple of games?

Yes, well, I did try to add sound to my remake of 3D Monster Maze from the ZX81.


I tried to do the sound of footsteps and also tried a sort of Jaws type sting, but both ended up quite low notes, and sounded comically awful on the tinny piezo speaker in a PET, so it remains true to the original, silent. All you can here are the tormented screams of the player.

PET Synth

If you just want to play "music", or makes some noise, have a look at PET Synth, 


The website has gone, but here is an archived link:

https://web.archive.org/web/20140111224730/http://www.petsynth.org/

See also this video by Sam at Look Mum, No Computer, who built a Mini PET kit and then had a go at circuit bending it. See also most of the other videos on the channel if you like unusual ways of making electronic music.


Advertisements

A big thank you to Keysight who have generously donated the oscilloscope I used to get the screenshots in this post.


There will be a full review on this once I learn how to use more of it, but so far it is doing an excellent job. Expect to see a lot more screenshots in future posts as these are so much better than my previous attempts to take photos of my 30 year old CRT scope.

(N.B. yes there is a plastic keycap stuck over the speaker with a bit of blu tak. Most of the tones I was producing today were not the most pleasant to listen to.)

Mini PET

The Mini PET 40/80 kits to build a PET like the one I used in this article have now all sold out, but there are still some Mini PET 40/80D pre-assembled drop in replacement PET boards available from The Future Was 8 bit:

https://www.thefuturewas8bit.com/shop/tynemouth-products/minipet4080d.html

You can see that board and these games being played on this video by The 8 bit Guy

Tapes

Tut-Tut and 3D Monster Maze are available on cassette from The Future Was 8 bit:

https://www.thefuturewas8bit.com/shop/tynemouth-products/cas024.html

https://www.thefuturewas8bit.com/shop/tynemouth-products/cas022.html

Or digital downloads from my itch.io store

https://tynemouth.itch.io/

Patreon

The original version of this posts and many other advance previews and behind the scenes progress on new projects, can be found on my Patreon. I am very grateful for the support I have received from my Patreons over the last few years. If you would like to support me, here is the link:

https://www.patreon.com/tynemouthsoftware

Footnote

I know very little about music, so I may have all got the terms wrong, please forgive me.

Sunday, 8 May 2022

Sinclair 5x8 Keyboards

Today I am going to have a look at the evolution of the 5x8 matrix keyboards used on Z80 machines from Sinclair (and others).


They all follow a similar format to the matrix shown below on the keyboard PCB from one of my Minstrel ZX8x clones.


The matrix is composed of 8 rows of 5 keys. The 5 columns are mirrored on the right hand rows. Here you can see the rows are not ordered sequentially, presumably whatever was most convenient for PCB layout.

I have tried various ways of drawing the switches in those schematics, and I think those angled ones I drew are the clearest. 

I just need to be careful not to use them individually, as they keep reminding me of V.I.N.CENT from Black Hole when I do.


The ZX80

The first to use this format was the Sinclair ZX80. I am not aware of any machines before that which had a full alphanumeric keyboard with only 40 keys. Most were either 16-20 key hexadecimal keypads or much larger more traditional style keyboards.


For a closer view, here is one of my overlay stickers which can be used to convert a ZX81 membrane for use with other machines. You can see they use the 10 numbers, 26 letters, and the remaining 4 keys are shift, new line (a.k.a. enter or return), space and dot / comma. It would have been nice to have also had a delete key, but that is achieved on most of these keyboards as SHIFT + 0 (on the ZX80/81 called "rubout").


The next step is the ZX81, but a the ZX81 ROM was available as an upgrade for the ZX80 (supporting all functions apart from the new NMI controlled flicker free slow mode). In order to keep in style with the ZX80, I produced another overlay in the style of the ZX80, but with the ZX81 graphics and keywords.

The ZX81

The actual ZX81 used the more familiar colour scheme of black, white with red highlights.


This was also used on the TS1000 with some minor changes.


The ZX80, ZX81 and TS1000 all used the same key arrangement. The only changes on the TS1000 were the replacement of the names RUBOUT and NEW LINE by the more familiar terms DELETE and ENTER.


The changes from the ZX80's original integer maths based 4K BASIC to the floating point maths 8K ROM found in the other machines were more noticeable. Many new keywords were added, and most of the existing keywords and graphics were moved around.


Jupiter ACE

The first deviation from that key layout came with the Jupiter Ace. Not a Sinclair product, but close enough to be considered here.


At first glance, it appears to use the same layout, different graphics and keywords, but the keys are in the same places. However, although the physical keyboard placed symbol shift where the dot/comma key had been, electrically it is wired where Z would normally be. Z is where X would be, X where C would be and so on until M which is where dot/comma would have been.


I did make an overlay that would allow a ZX81 keyboard membrane to be used on a Jupiter Ace (or Minstrel 4th ). Here you can see the Z,X,C etc. keys are shifted one place to the right.


This may have been to avoid copyright (I am thinking of the Micro Ace ZX80 clone that tried to avoid copyright by swapping two of the data lines in the ROM so it was no longer binary identical when read outside of the machine). It is also useful to be able to check the two modifier keys on the same row.


If they had used the ZX81 matrix, the Symbol Shift would have been on Row 8 and Shift on row 6.

The ZX Spectrum

The next machine from Sinclair was the ZX Spectrum. This also had a 5x8 matrix keyboard from the ZX80 and ZX81, the use of Enter and Delete from the TS1000 and the Symbol Shift key from the Jupiter ACE. (oh, and it was colour and you could play Jet Pac on it etc.)


I did make an overlay in the Spectrum style for use with a Spectrum clone, You can see the Spectrum, although very compact is somewhat larger that it's predecessor.


The Spectrum also has a Symbol Shift key on the right, but this time it is in the matching location in the matrix. Other than the name changes, all the rest looks the same, but ah, no, two of the address lines have been switched.

I would have expected Sinclair to keep the same keyboard layout. I am not aware of any specific reason for the switch, routing the membrane maybe, but then that could have been switched on the PCB. Maybe the address lines used for the rows may have been accidentally transposed during the construction of the ZX Spectrum prototype (seen here at the Centre for Computing History - http://www.computinghistory.org.uk/det/51620/Sinclair-ZX-Spectrum-Prototype/


The ZX Spectrum +

The next machine to be released was a Spectrum+, this was a larger case, but had the same board inside, and therefore had to use the same 5x8 keyboard matrix. But it had extra keys?


The extra keys were created using trick membranes that pressed two keys simultaneously. All of the extra keys are simply combinations of two of the existing keys When you press the " key, it actually pressed Symbol Shift and P at the same time, so it is interpreted as ". Left arrow is Shift and 5 etc.


The Spectrum +2

This layout persisted to the end of the ZX Spectrum range, with the same technique being used on the Spectrum + 128K and the grey Spectrum +2. 


The grey +2 membrane looks more complex, but still has just the 5x8 matrix connections.


The Amstrad designed +2A/B/+3 black machines had the same external appearance, but underneath they had a different keyboard matrix.


Rather than 5x8 like all the previous keyboards, this was 11x13 and there was no magic double layered membrane.


With all the extra connections, it looks like an 11x13 matrix, but in fact it is the good old 5x8 matrix and a completely separate 6x5 matrix. (I'll cheat here and use the diagram from the service manual rather than redrawing it)

Other than those minor anomalies, the same matrix survived intact for most of the 1980s. Even the competition when trying to make a machine of a similar size and cost had 50% more keys.


After a long romance with 100+ key keyboards (like the beloved IBM Model M I am typing this on), it seems we will never go back to the elegant simplicity of 5x8 matrix keyboard. 

But again, saying that, with those awful touch screens taking over everywhere (give me a buckling spring any day), a return to a simpler interface with fewer keys does seem to be underway.

Third Party Keyboards

There were several after market keyboards for the ZX81 and ZX Spectrum that also added extra keys. How did they work? Well, tune in next week to find out. I will be reverse engineering some of them to see what all of this extra gubbins does.



Advertisements

The various overlay stickers and keyboard PCBs for the ZX80, ZX81, Minstrel 2, 3 and 4th are available from my SellMyRetro store:

https://www.sellmyretro.com/store/tynemouth-software


This post is an updated version of a post from my Patreon. If you want advance previews of posts like this and behind the scenes progress on new projects, you can follow along and support me on Patreon:

https://www.patreon.com/tynemouthsoftware