- Finding some contemporary parts
- Hacking into a Dallas NVRAM
- The Z8671 is alive
- Soldering the perfboard
- Game test in PBASIC
- Soldering displays
- Bending acrylics
- Console layout
- Finished console
- Finalized PCB
Like the classic Lunar Lander video game but on Earth and with no graphics, only some 7-segment displays
All parts of the PCB is wired up and all connections are buzzed out to test for shorts and bad connections.
Going from left to right on the PCB there are a screw terminal for 5 volts and a power-on LED and above that the reset button and its support circuity (including a very colorful red/yellow 1980's-era capacitor).
Then a standard FTDI-style pin header for TTL-level serial comms. The Z8671 supports using baud rates from 110 baud up to 19200.
A 74LS138 for address decoding, followed by the Z8671 MCU itself and a 8 kilobyte SRAM and the DALLAS DS1235 Non-volatile SRAM with a internal backup battery. The battery is by long dead but I dug out the innards and was able to hook up wires for attaching an external battery to it - which currently is not mounted on the PCB.
Finally the 74LS373 Address-latch that splits up the lower 8 address bits from the combined Adress/Data-bus the Z8671 is using as a pin-saving feature. Without that feature 16 pins for address and 8 pins for data (=24 pins) would be required on the 40-pin chip. Now "only" 16 is used leaving more pins for I/O.
The three resistors at the far end are for forcing the lower bits of the data bus to 010. This is used by the initialisation routines of the Z8671 to determine the desired baud rate. 010 gives 9600 baud. Actually this is an ugly hack since the Z8671 is really reading the address 0xFFFD to get the baud rate, and to properly handle that I'd need a lot of address decoding and also a three-state buffer. So this is easier - whenever an unused address is read the data buss will just be floating and these three resistors will gently pull the bits to the desired state.
Attaching the displays to the console was not easy. My first plan was to just use a hot glue gun, but that turned out to be not so good since the "chrome" spray paint has a rather loose surface so the glue is just ripping off the top layer of the paint as soon as some force is applied to it. And the glue didn't stick particularly well to the plastic of the displays either.
So after hotsnotting them into place I used a liberal amount of silicon sealant all over the place. I hope that if I'm careful enough when handling the panel the displays will stay there.
This is what the front of the console looks like now:
I attached the transparency to the acrylics using spray glue. It was a hard to fit it at the first try and it ended up slightly crooked, but not too bad. The glue did make the unpainted "windows" for the displays slightly cloudy but that have to do for the time being. If I make another panel like this I need to come up with an easier solution.
For the thruster control I needed a potentiometer with a lever mounted in 90-degree angle to the pot axis. I simply drilled a hole straight through it and attached a spare Dremel spindle to it. Problem solved.
The pot what then epoxied to a piece of scrap PCB that is securely held to the acrylic by two of the push buttons.
For the thruster handle I used a piece of a "touchscreen pen" that I glued to the end of the Dremel rod. All in all I think it looks fully acceptable for something done without any proper equipment.
I printed the layout of the panel onto transparent film and covered the areas for the displays with sticky tape on the backside of the film. Then I spray painted the back with "chrome" paint. It ended up more silver grey than a shiny chrome. It also "developed" my fingerprints that I got on the transparency so there are ugly dark tarnished areas on it. Not so nice, but I'll keep it anyways.
The transparency also got slightly wrinkled after being laser printed, I hope that it will not be a problem when I glue it to the acrylic.
I need a nice retro looking console to mount the displays on. So I took a A4-sized piece of acrylics and bent it using a small blowtorch. It was the first time I've evert tried bending acrylics and it was rather easy. I think it turned out quite well if I'm allowed to say that myself. ^_^
I spend a couple of hours soldering up all the required displays. I now have 10 displays each made out of a pair of 2-digit displays that I found in a bag I bought from Electronic Goldmine about 15 years ago.
I epoxied the displays together in pairs and then sat them up on my desk on a long line so I could easily wire them up with 0.2mm insulated wire point-to-point style. The insulation on the wire is quite easily solderable using a soldering iron set to 400C instead of my usual 290C. After the soldering I just cut the wires between the modules as required.
The shift registers and the resistors was just tacked onto the displays in dead bug style. Really ugly but it got the job done.
The 4-digit modules are driven by a HC595 shift register with 82 ohm resistors connected to the cathodes. So each module have 4 Anodes, VCC/GND and DataIn/Clock/Latch/DataOut that needs to be hooked to to the other modules.
The GND wire is a bit thicker that the rest of the wiring since it needs to carry quite a lot of current in total.
For some basic (pun intended) testing of the game logic I hacked up a quick test in PC-BASIC. It is an excellent open source implementation of the classic GW-BASIC from back in the good old days of the 1980's.
I just implemented the main thrust, no winds and no rotations so no real playability. I might polish up the code a bit the next few days...
For more info and download of the PC-BASIC go to [robhagemans.github.io/pcbasic](https://robhagemans.github.io/pcbasic/)
10 REM Earth Lander 84 - Rev 0.1 20 REM Copyright (c) 2016 Mats Engstrom firstname.lastname@example.org 30 REM Licensed under the MIT licence 40 GOSUB 9000 41 GOSUB 8000 100 REM --- GAME IN PROGRESS LOOP 110 KY$=INKEY$ 120 IF KY$=" " THEN BURN=0 121 IF KY$="1" THEN BURN=GRAVITY*0.2 122 IF KY$="2" THEN BURN=GRAVITY*0.4 123 IF KY$="3" THEN BURN=GRAVITY*0.6 124 IF KY$="4" THEN BURN=GRAVITY*0.8 125 IF KY$="5" THEN BURN=GRAVITY 126 IF KY$="6" THEN BURN=GRAVITY*1.2 127 IF KY$="7" THEN BURN=GRAVITY*1.4 128 IF KY$="8" THEN BURN=GRAVITY*1.6 129 IF KY$="9" THEN BURN=GRAVITY*1.8 180 FUEL=FUEL-(BURN*10) 190 IF FUEL<=0 THEN FUEL=0:BURN=0 195 DELTA=(GRAVITY-BURN)/10 200 DESCENT=DESCENT+DELTA 210 CALTI=CALTI-(DESCENT/10) 220 IF CALTI<0 THEN CALTI=0:DESCENT=0: BURN=0 230 IF CALTI>9999 THEN CALTI=9999: BURN=0 900 GOSUB 8100 910 GOSUB 9500 920 GOTO 100 8000 REM --- REDRAW FULL SCREEN 8010 CLS 8020 LOCATE 1,24: PRINT STRING$(31,"=") 8021 LOCATE 2,26: PRINT "E A R T H L A N D E R 8 4" 8022 LOCATE 3,24: PRINT STRING$(31,"=") 8030 LOCATE 5,15: PRINT "Remaining fuel Score" 8031 LOCATE 6,15: PRINT "+-------------+ +-------------+" 8032 LOCATE 7,15: PRINT "| | | |" 8033 LOCATE 8,15: PRINT "+-------------+ +-------------+" 8034 LOCATE 10,15: PRINT " Ship angle Wind speed" 8035 LOCATE 11,15: PRINT "+-------------+ +-------------+" 8036 LOCATE 12,15: PRINT "| | | |" 8037 LOCATE 13,15: PRINT "+-------------+ +-------------+" 8038 LOCATE 15,15: PRINT " Ground speed Latitude Target latitude" 8039 LOCATE 16,15: PRINT "+-------------+ +-------------+ +-------------+" 8040 LOCATE 17,15: PRINT "| | | | | |" 8041 LOCATE 18,15: PRINT "+-------------+ +-------------+ +-------------+" 8042 LOCATE 20,15: PRINT " Descent rate Altitude Target altitude" 8043 LOCATE 21,15: PRINT "+-------------+ +-------------+ +-------------+" 8044 LOCATE 22,15: PRINT "| | | | | |" 8045 LOCATE 23,15: PRINT "+-------------+ +-------------+ +-------------+" 8100 REM --- REDRAW NUMBERS 8110 LOCATE 7,20: PRINT USING "####";FUEL; 8111 LOCATE 7,54: PRINT USING "####";SCORE; 8112 LOCATE 12,20: PRINT USING "###.#";ANGLE; 8113 LOCATE 12,54: PRINT USING "###.#";WIND; 8114 LOCATE 17,20: PRINT USING "###.#";GSPEED; 8115 LOCATE 17,37: PRINT USING "####";CLAT; 8116 LOCATE 17,54: PRINT USING "####";TLAT; 8117 LOCATE 22,20: PRINT USING "###.#";DESCENT; 8118 LOCATE 22,37: PRINT USING "####";CALTI 8119 LOCATE 22,54: PRINT USING "####";TALTI; 8999 RETURN 9000 REM --- INIT ALL VARIABLES 9030 FUEL=9999 9040 WIND=0 9050 ANGLE=0 9060 GSPEED=0 9070 CLAT=500 9080 TLAT=500 9090 DESCENT=0 9100 CALTI=1500 9110 TALTI=0 9120 SCORE=0 9130 BURN=0 9140 GRAVITY=1 9199 RETURN 9500 REM --- WAIT UNTIL NEXT TICK 9510 IF TIMER= LASTTIMER GOTO 9510 9520 LASTTIMER=TIMER 9530 RETURN
I took a perfboard and soldered up power and the data/address busses of the MCU, SRAM, NVRAM and the address bus latch.
I did't really care about the exact order of the bits when wiring them up, I just went for the easiest layout. I'm not really sure why the manufacturers even care about designating the D0..D7 on a SRAM, the order is irrelevant as long as you don't move the chip to another system with live data on it. Same thing with the address bus. On a (EE)PROM it's required to carefully keep track of the A's and D's of course.
This is how it ended up:
Z8671 HEADER -------- ------ VCC P36 X2 P31 RW X1 P27 /E TX P26 a7 RX P25 6264 DS135 a6 /RES P24 ------- -------- a5 R/W P23 NC VCC A VCC a4 /DS P22 A /WE A /WE a3 /AS P21 A CS2 A A LS373 a2 P35 P20 A A A A ------- a1 GND P33 A a6 A a6 /OE VCC a0 P32 P34 a4 a7 a4 a7 a7 a6 d7 A8 d7 a5 /OE a5 /OE d7 d6 d6 A9 d6 a3 a2 a3 a2 d5 d4 d5 A10 d5 a0 /CS1 a0 /CE a5 a4 d4 A11 d4 a1 d7 a1 d7 a3 a2 d3 A12 d3 d5 d6 d5 d6 d3 d2 d2 A13 d2 d3 d4 d3 d4 d1 d0 d1 A14 d1 d1 d2 d1 d2 a1 a0 d0 A15 d0 GND d0 GND d0 GND LE GND
Only the front side is shown, the backside is a horrible mess of "roadrunner"-style point-to-point wiring using insulated magnet wire that I just soldered thru the insulation with a 400C soldering iron.
I didn't know if the processor was still working after all this time on a disintegrating piece of antistatic foam so I wired up the simplest possible test circuit on a solderless breadboard.
Just the CPU plus a 100nF cap and the crystal with its 20pF load caps is required. And three 1K resistors that pulls up the lower three bits of data bus to force the baudrate to be set to 300 baud.
It's hooked up to a Adafruit FTDI adapter which also supplies the 5 volts power for it.
It seems like it works rather well as can be seen on the terminal above. It complains about a syntax error at line 24950, but I guess that is because the BASIC firmware gets confused when databus is flowing while it probing the memory ranges. At least I hope it is so or else the BASIC ROM has succumbed to bitrot over the years. :-(
Since my EPROM burner is so old it connect via a parallel port I needed to find another solution for that. I found an old but never used Dallas DS1235 32Kx8 NVRAM module that I got in a goodie bag at some electronics seminar I attended way back in the past.
It's dated 1988 and looking at the data sheet the internal battery should last at least 10 years. Considering it's almost 20 years past the expiry date I wanted to make sure that the batteries wasn't dead.
The module consists of a SRAM with a DS1210 Nonvolatile Controller Chip and two lithium batteries potted in epoxy.
Luckily the top of the DS1210 was exposed at the bottom so it was rather easy to just use a hot soldering iron to scrape off the epoxy layer by layer to get down to the legs of the DS1210 so I could measure the voltages of VBAT1 and VBAT2.
It was dead... VBAT1 had just a few millivolts and VBAT2 had fared batter and was at 250mV.
I will dig out some more of the epoxy so I can cut one of the battery leads and attach an external battery to keep the module alive without VCC.
I'm not sure if I can use a single 3 volt coin cell battery and expect the SRAM to be within data retention limits since the DS1210 have a voltage drop of up to 0.3 volts. But the maximum voltage of VBAT1/2 on the DS1210 is 4.0 volts so I can't just series two coin cells.
So I have three choices. Either run it on a single standard 3v cell, get a 3.6 volt Li-ion coin cell or series two 3 volt cells and then hook it up with some diodes to drop off the extra voltage. But at nano amps the Vf of a diode is not much so I'd need a lot of them. Maybe I can use a LED instead....