PSCD32 Development Diary

Pushing the button

The A500 is out. I've got a few of these things. Some of them are cherished family devices that have been passed down through three generations. Others are old stock from schools that have been mangled by poshknob lucky children and withheld from the local plebs who are undeserving of Scala Multimedia. I'm using an A500 that's been serviced a little by yours truly: keyboard matrix swap, floppy drive swap and clean. Now it'll be my test machine for my super device... The software I'm using is Amiga Test Kit by Kier Fraser (https://github.com/keirf/Amiga-Stuff). This useful piece of software works on all models of Amigas and can test pretty much any port or piece of hardware you choose. It has a useful game port testing mode which allows you to independently select whether each game port should be read as a one/two/three-button joystick, a one/two/three-button mouse or a CD32 gamepad. And the results were mixed! The host computer did not burst into flames. The controller didn't either. Amiga Test Kit didn't crash or burst into digital flames. But when I held down a fire button, the output repeatedly flickered. I was warned that the components might be too protective, but I did the math and the resistors I chose put me within 2% of making a potentially unsafe scenario. If I manually ground the signals with a jerry wire, they show up as solid in the program, even through the resistor, so I suspect it's my protocols that are at fault. I've got DIP switches and I've got a multimeter. I can figure this out.

Some Hours Later...

Alright. Now it doesn't even Not Work anymore.

The First Problem:

The first problem was that I was writing to PORTx and not LATx. What does that mean? In the dsPIC33/PIC24 Family Reference Manual: I/O Ports with Peripheral Pin Select (PPS) chapter, you've got this diagram. This guy indicates that: • If you've set TRISx for your port pin, it will be tristated. • If you've set ODx for your port pin, it will only ever be driven low, never high. • When you read from PORTx, you're reading the value from the I/O pin. • When you read from LATx, you're reading from the data latch. • When you write to PORTx or LATx, you're writing to the data latch. My problem was that I was writing to PORTx in my code. In the manual it warns about doing this in assembly, but I was doing it in C, so it was even worse. When you manipulate the PORTx bitfields in code, you read, mask, OR and write to PORTx, which means you're writing a mixture of the values that you've calculated and want to send, and the voltage values present at the pin, which is rarely what you want. When folks say writes to PORTx are the same as writes to LATx, they're correct if you're only ever directly setting the value. For some reason, that never came up as an issue with the Ocelot. I just assumed that setting PORTx directly as well as reading from PORTx resulted in tidier code. You learn something new every 2 A.M.! The solution here is to be very, very explicit about what you're writing to. Triple check all your TRISx and LATx assignments. This fixed some of the issues, but I can't quite get the second fire button working. Up, Down, Left, Right and Fire all work. I need Fire2 in order to get the CD32's serial protocol working. This time I think it's those 'squirrelly' pins. The resistor I installed is too resisty. When the PIC tries to pull it down, the Amiga is throwing so much juice at it that it only goes half way down and doesn't count as a zero. With a 470 Ohm safety resistor on the MCU side (expecting a max current of 12mA), it results in a 1.7V voltage at the output pin. To determine the correct resistances, I'm using the very professional technique of simply holding a tangle of resistors with the leads twisted together against the exposed contacts on my board while the system is powered up. I think I ought to buy one of those resistors assortments in future. Experimentally, by soldering towers of resistors that I had to hand, I found that the Amiga will respond to a pull to ground through no more than 70 Ohms. But let's do some maths. Using a few different values for the resistances and seeing what current was drawn through the grounded pin, I arrived at a model of the Amiga as being a 5V voltage source through 350 Ohms. Which means that to pull it down to 0.5V I'd need a resistor on the order of 40 Ohms. Grounding without a resistor would result in a current draw of 17 mA, which is a heck of a lot of juice to just throw away detecting a button. It's pretty absurd considering the maximum current requirement for the PIC itself at 16 MIPS full number-crunching processing power is 20 mA. I thought the maximum safe rating for a pin on my system was 12 mA. That is - if I told my mini CPU to Hold The Line unprotected, it would receive 17 mA flowing into that pin and it would die. However, re-checking the datasheet for the exact chip I have, it was 25 mA. Getting the good chips is always a good plan! I *could* just connect it directly and let those ~20 mA fire all over the place; that's apparently what's happening every time you hold down a fire or mouse button. But I like safe things. I could have connected all the PS2 side directly too but it all seems happy enough as it is. It's safe, it's happy, I'm happy. Adding a 40 Ohm resistor gives a current draw of 13 mA by the PIC when the pin is pulled low. That's not very 'digital logic', if I'm being honest. I'm not super jazzed about the idea but its safer than nothing. 5 Volts / 40 Ohms = 125 mA. That's a bit of heavy juice slopping out if things go awry and my model of the Amiga's pin is incorrect. The direction switches are pulled up to 5V through 4.7k by the Amiga, so they're safe as houses. There is a 4.7R resistor going into the joystick port's power supply which means that anything supremely slurpy is going to have some trouble slurping the system to death but from the amount of times I've written the word 'slurp' here, you might (correctly) guess that I don't want to rely on this.

Shopping for resistors

I live in the northwest of England, and looking for a local elecronics shop to get these missing gizmos is not easy. Maplin died last year. Tandy died when I was perhaps 3. Which is a shame, because I probably would have loved it. I want to go to a shop in person. I found a nice sounding shop online that's open on Saturdays: a local, family-run repair place with a parts counter. Bootle, not to far from me. I've been there a dozen times. But, oh no, wait, that's not Bootle Liverpool, that's Bolton, Manchester. Thanks, Google. It's not as if I mean what I type or anything. Meanwhile: Yes, Argos, that is exactly the kind of useful electronics hobby stuff I am looking for, thank you.

An idea before bed

Maybe I can use the SPI2 module to respond to the CD32 twiddle request. SPI is supposed to interface with shift registers, after all. It should be able to simulate one. I could use an interrupt like CN to respond to changes on the appropriate JOYMODE line, set up output direction etc. set up a word or a byte or something in SPIxBUF. Use SPI2 interrupts to keep SPIxBUF filled with zeroes. When it goes idle again, revert to Atari behavior and turn off SPI module hoping to cancel existing transaction instead of having lingering half-transmissions. But what is the clock phase from the Amiga when this starts? And how do I synchronise everything up... will the SPI hardware like it?