Sunday 12 May 2024

Minstrel Expansion Bus

The next of the new things I want to look at is the Minstrel Expansion Bus.

This plugs into the rear expansion connector on the Minstrel 2, Minstrel 3 or ZX81. It provides four 2x23 pin headers and a pass through rear edge connector.

The expansion bus pinout is identical to that used on the Minstrel 2 and 3 and the ZX81. The ZX80 is the same but without the /ROM_CS pin - you aren’t using this on a ZX80, are you?

You can construct this to be passive and power all the cards from the host machine. This is fine if you aren't using much power.

Alternatively, there is the facility to add it's own 9V in, 5V out power supply.

This follows the same design as the host machine. 9V is regulated down to 5V using a 7805 regulator. You can add a heatsink if you plan to need lots of power on the 5V rail, or fit a switch mode replacement.

You should only fit the 5V jumper you have not fitted a 7805 on the board.

If you omit the 9V jumper, 9V needs to be connected to both the host and the expansion bus.

If you fit the 9V jumper, you can connect 9V to either the host or the expansion bus.

This can be useful with a ZX81 to provide a better power connector, with the 9V feeding both the internal and external 7805 regulators.

You also gain a nice green power LED.

The kit includes all the parts, omit them if you don't need them.

The pass through connector means you can connect normal edge connector devices such as a RAM pack.

You can then add up to four expansion cards in between.

It doesn't have to be a RAM pack, you might be lucky enough to have a ZXpand or ZXPand+.

Here you can also add the expansion cards.

And can still power everything via the 9V DC connector on the Minstrel Expansion Bus.

Might look odd not having the power going into the ZX81, but it's more reliable that way.

You now have all the bits to load 3D Monster Maze on your ZX81.

Or maybe Minoss Knossoss, to make use of that joystick module.

The expansion bus is designed to be the same width as the ZX81 main board.

Which is of course the same size as the Minstrel 3, where it fits in very nicely.

Here I am using the power connector on the Minstrel 3, but either could be used.

You can also use the passive version, with all the power coming from the host.

That shows the option of soldering the expansion bus direct to the edge connector on the Minstrel 3, if you want a more permanent solution.

Or fit an edge connector if you want to be able to remove it.

The Minstrel Expansion Bus is available in assembled, kit and PCB only versions. If ordering assembled, let me know which options you would like.

But what can you plug in?

ZX-IO

Well, one of the cards I was using was David Stephenson's ZX-IO, a three port memory mapped IO card - post on that to follow. Thank you to David for sending the PCBs and the 8255.

More info here

Minstrel Joystick

This is a simple Kempston compatible joystick interface, but fully decoded at address 31 (0x1F).

More info on that here:

Also available in assembled, kit and PCB only versions.

That makes up for the lack of joystick on the Micro ZXpand Minstrel.

Speaking of which, that is available here:


Behind the Scenes Bonus

When I was testing that out, I was using an unmodified ZX81, and the picture via UHF wasn't great on my LCD monitor.

I could have cheated an just used screen shots from a Minstrel 3, but I decided to only slightly cheat and use a composite video feed from the ZX81.

Here I am tapping the composite video feed to the modulator and using the transistor buffer and video connector on a Minstrel 3 board to feed the monitor.

It was interesting to see the "jail bars" you get on a real ZX81 that are "fixed" on the Minstrel 3.


Advertisements

The full range of Minstrel and Mini PET kits and accessories are available form my SellMyRetro store.

All the links can be found here:

Patreon

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 5 May 2024

Minstrel Joystick

Introducing the Minstrel Joystick, a Kempston compatible joystick interface.

It could be fitted with an card edge connector to plug directly into the back of a Minstrel 2, Minstrel 3, ZX80 or ZX81, even a ZX Spectrum.

However, it is designed as the first module for the Minstrel Expansion Bus.

You might spot some other things on there, I will get onto those in due course.

"Kempston Compatible"

Kempston Compatible is a term used by lots of very different hardware, so many devices that look something like this. All of which implement pretty much the same interface as far as software is concerned.

Plug in a "standard" 9 way D joystick, a Commodore or Atari (but not a Spectrum +2, Amstrad or Atari 5200).

Or maybe even one of TFW8b's custom build ones.

Read port 31 ($1F in hex) and you will get back 0 if the joystick is not moving.

You will read 1 if the joystick is moving right, 2 for left, 4 for down, 8 for up and 16 if fire is pressed.

If the joystick is held at a diagonal, you will get the sum of both directions (e.g. up and right is 8+1 = 9), or +16 if fire is pressed (e.g. up and fire = 8+16 = 24)

If you are writing code in assembler, it is just a case of

IN A,(31) 

and you have your value to parse as appropriate.

A BASIC IN command was added for the ZX Spectrum, but in ZX81 BASIC land, things are a bit more complicated.

You can create small assembler routines to call from BASIC, and return values via the BC register pair (or HL if you are running ZX80 4K BASIC).

XOR A
LD B,A
IN A,(31)
LD C,A
RET

Thanks to George Beckett for help with that.

You need somewhere to store these 6 bytes of code, and REM statements are traditionally used. You would normally use a loader where you run a program on the ZX81 and type in the bytes and it populates the REM statement for you. In this case, it's easier to just use POKE statements.

16514 is the address of the "J" of "JSREAD" in RAM, and should always be that if it remains the first line of code.

When you run the program, the characters in the REM statement are replaced with the assembled code.

You can then delete lines 10-60 and replace them with your program code, just call USR 16514 when you need to read the joystick. (the REM statement needs to stay as the first line so this address does not change).

The REM statement was modified when the code ran, and the six bytes after it have been overwritten. 

Several of these are symbols, such as "<=" and "TAN" which are stored as a single byte, but displayed as multiple characters. The two "?" represents bytes that do not have a printable equivalent.

The code added in lines 10-30, will display the value read from the port.

The value displayed will be 0 and will change as you move the joystick and press fire.

That single byte input port is all pretty standard, and is implemented by dozens of different devices over the years, but the hardware is often very different. Usually it involves a read buffer IC and some address decoding.

The Read Buffer

There are a few options here. Most often used are things like the 74LS240, an octal inverting buffer, or the 74LS366, a hex inverting buffer.

These are inverting as the joystick is traditionally setup as it is in the Atari 2600 or Commodore 64 etc. with common as 0V.

As you move in a direction, a switch is closed and connects that pin to the common.

If you are lucky, those will be nice microswitches, if not they will be little metal domes that flex down to make contact with the PCB trace below.

The switch inputs are pulled up to 5V normally, so read as a 1, unless the joystick is pushed in that direction and the switch is activated, in which case they read as a 0.

The inverting buffers convert that to the slightly easier to understand 1 when moving, 0 otherwise, which is the standard.

There are some versions of the "Kempston" interface which use non-inverting buffers, 74LS365, 74LS367 or 74LS244 (including one from Kempston themselves, so it must be OK then?) 

These do not invert the signal, but still need to support the same protocol, so they feed the common of the joystick with 5V and pull all the signal down to 0V. This will stop any autofire circuits from working, potentially even damage them if they are not expecting a reverse voltage? But will otherwise give the correct 0s and 1s on the interface bus.

All of theses buffer chips have two enable inputs. Some require both inputs to be low for any of the outputs to be enabled (e.g. 74LS365, 74LS366, 74LS540), but most use one pin for 4 of the outputs and the other other for the remaining 2 or 4 outputs (e.g. 74LS367, 74LS240, 74LS244).

Decoding Logic

So you have your buffer, this needs to be enabled in one precise condition - an IO read request at address 31. 

IORQ is low, RD is low, and the lower half of the address bus is 0001 1111, so A7, A6 and A5 are low, and A4-A0 are high.

It should also not respond during an interrupt acknowledge cycle. Here IORQ and M1 are low to indicate the external device should place the interrupt handler address on the bus. The joystick interface should stay out of this. That can be detected by making sure that at the same time as the IO request, that the M1 signal is high, or the read RD signal is low (or both).

The logic used varies a lot, usually one chip, occasionally two are used, although sometimes no additional decoding is employed.

A common theme though is not bothering to decode the whole address. Most only look at A5.

A typical interface looks something like this.

Here the decoding is A5, IORQ and RD are low. This should avoid problems with interrupt acknowledge as RD is not low at this point. But the address decoding means it will respond to IO read events on addresses from $00-$1F, $40-$5F, $80-9F and $C0-$DF (that is 128 out of the 256 available addresses).

Not really a problem as most of these interfaces do not have pass through connectors, so will likely be the only thing plugged into the bus. In that case, it doesn't matter if they use up lots of the address space. 

Remember this is the ZX81, and it has already used up all even addresses by decoding FE as "A0 is low".

It does mean that if you try to read any even address in the decoded range that the buffer chip on the interface and the buffer chip in the ZX81 (well, part of the ULA), will both be writing at the same time.

The three unused inputs are pulled up to 5V, so when inverted, those bits will always read as 0 as expected.

The most complete decoding I have seen is one from Cheetah which decoded A5, A6 and A7 low, and also IORQ and RD low and M1 high.

That covers most of the bases and only responds to IO read requests from $00-$1F, and not interrupt acknowledges.

It uses a different approach to dealing with the unused bits, D5 is driven by the buffer chip, but D6 and D7 are pulled low when the enable signal goes low. Both valid approaches. These days an octal buffer would be cheaper than a hex buffer and two diodes, but probably not in the 1980s.

I did find one interface from "RAM" with only a single chip.

It looks like it was designed for two chips, but at some point they cheaped out and instead of the second chip, they fitted a wire link.

I think I need to reverse engineer the schematic.

One moment please.

This is what I think it was meant to look like, with a 74LS00 as the missing chip.

The 74LS366 is only a hex buffer, so diodes are used to drive the three unused bits from a single output. They can't do it in the same was as the Cheetah one above as their partially decoded enable line only exists within the buffer chip.

The intended circuit deals with things slightly differently, checking for IORQ low, A5 low and M1 high. This will avoid the interrupt acknowledge, and be active over half the address range as above. It will also be active during write cycles, should you try to write to $00-$1F etc. you will get a bus conflict.

The single chip + wire link version just connected IORQ to the enable line, so will only check for IO and A5 low. That means it will respond to read and write and interrupt acknowledge events. Not ideal, but I guess it is functional and someone saved 10p in the 1980s.

It wasn't the only way they cheaped out. You might notice all of these interfaces use the 2x23 way ZX81 edge connector. Most of them were acutally used with ZX Spectrums, which has a larger 2x28 way edge connector. They are not identical, but the few pins that are used here are common between the two systems, so you can use these on a ZX81 or ZX Spectrum as long as you make sure they key way is aligned.

I wonder if the missing M1 signal you find on many Spectrums is what led to changing the decoding on that interface to ignore M1?

Which way did I do it?

Well, I went a bit far, as usual, and fully decoded the address.

I fully decoded address $1F, and also checked for IORQ and RD low and M1 high for good measure.

This is intended to sit with other modules in a bus system, so I didn't want to tie up extra addresses unnecessarily.

The other difference is I have wired up pins 5 and 9 on the joystick as additional fire buttons to bits 5 and 7, as I have done on other interfaces in the past.

Which games support it?

There are a few ZX81 games which already support a Kempston joystick, such as Paul Farrow's ZX81 Kong (and other games).

http://www.fruitcake.plus.com/Sinclair/ZX80/FlickerFree/ZX80_Kong.htm

And David Stephenson's Minossss Knossosssss.

https://www.zx81keyboardadventure.com/2024/04/zx81-game-minoss-knossoss.html


The Minstrel Joystick is available as assembled - https://www.sellmyretro.com/offer/details/64329

Full kit - https://www.sellmyretro.com/offer/details/64328

Or PCB only - https://www.sellmyretro.com/offer/details/64330

As are some of the other new things, posts on those to follow shortly.

There is an introductory post with all the links you need - http://blog.tynemouthsoftware.co.uk/2024/04/lots-of-new-things-for-minstrel-3.html



Advertisements

The full range of Minstrel and Mini PET kits and accessories are available form my SellMyRetro store.

All the links can be found here:

Patreon

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.