Trains… a backlog.
I'm sure I should've posted these events as they happened... but one thing lead to another and... I didn't. The folders were starting to cover my desktop so badly that I've now decided to just cull 95% of the photos and keep the only very best... or are required for story-telling.
Below are the happenings since some time around October last year.
Cs on the North-East
The C class is a good-looking locomotive. Delegated to freight, they never get their chances on express passenger services. One train buff in Australia happened to gather enough support to fund a passenger tour hauled by a C class locomotive. This tour ran from Melbourne through to Albury and return.
I caught it at Wandong, just north of Melbourne. Happened to be a nice sweeping curved and I totally fluked it. There were a few other trains in the vicinity also.
Steamrail Kaniva Loop Tour
This tour was run on both gauges. We had V/Line use it's P-Class locomotives first, which got us to Ararat. We then transfered over to the Standard Guage and had a TL pull us all the way out to Kaniva. I'm sure this town used to have ... people ... but not much happens nowadays!
The highlight? The roof panel split off on the way back... must've been fiberglass debris everywhere.
Hunter Valley Steamfest
This is a huge annual event centered on Maitland, NSW. All heritage groups get together and bring their shiniest locomotives to the event. There's always a "Great Train Race" and this year the 6029 Garratt appeared. Canberra actually entered 2 of the 4 trains in the race. Fortunately, there's also 100s of other trains in the area; it's the backbone of the Hunter Valley coal train network.
The steamers, prior to the race, were running shuttles left-right-and-center. Most had a diesel on the rear to prevent any repercussions if a breakdown were to occur.
Then, it happened.
A damn cool sight... and supposedly a world-record! The rest was just coal trains and more freight.
..and now I'm somewhere up-to-date. Enjoy.
Commodore 64: Datasette Maintenance
So, Double Dragon had issues loading on a Tape Drive I'd acquired. It had come in a mouldy box, so I had a hunch that the drive itself would need a thorough clean and alignment.
There are multiple alignment tools, downloadable as disk images or PRG files. I could copy these onto my SD2IEC, but there was an issue: the SD2IEC gained power from the Datasette port which was now in use by the Datasette drive itself!
Powering the SD2IEC from the Datasette Cable
Fortunately, the Datasette plug has a screw that makes accessing the internal pins very easy. I opened it up, taking note of the cracked, flimsy plastic, and inspected the contents.
The green wire, pin 2, is the +5v that we're after. Bare back some plastic on the wire so we can solder to it. I found a male+female standard round DC power socket to use. Make sure the female is on the 'power' side, otherwise you'll have a potential for shorts if there is exposed bare metal with current flowing through it. Of course, the outer metal is ground, but still better to be safer than sorry.
From here I soldered on the plug and grinded out some plastic from where the main cable feeds in. This allowed the plug to hang out the end. Not the cleanest job, but it worked quite well. I sorted wanted to feed it out the side where the ground wire is... but I hadn't left enough length.
Next, on the SD2IEC end, bare some wire also. Grab the plug and solder it on, then use some form of insulator to tidy it all up. Nothing a little duct-tape can't fix.
Everything was plugged in and good to go!
Cleaning the head
Everyone recommends alcohol (isopropyl) wipes for this. The wipes have the benefit of leaving little residue and drying cleanly. You'll find that KFC wipes are also usable.
Take the swab out of the packet and wipe the heads, specifically the central metal one. I didn't actually know which way to wipe, or how much pressure to apply. So just be gentle and attempt to remove any visible dirt. Don't put a tape back in until everything is try.
Aliging the head
There are a few options here. Download Cassette Azimuth, also known as 'Recorder Justage', and Minimal Head Align. Both do the same thing, the former is more complex.
I copied them both onto the SD2IEC and then loaded them via the file browser. Cassette Azimuth is easy to work with. Load it up and then hit play on your tape. If nothing is happening then you'll need to start adjusting the player already. If you see data, and it's erratic, then you'll also need to adjust. The goal is to have straight vertical lines.
To actually do the adjusting, there is a tiny screw-hole above the rewind button that a small jeweller's screw driver will fit through. When the tape drive is playing, the hole lines up with the head adjustment screw. Turn this screw all the way clockwise (not too much pressure!) and then turn back in small increments as required. Pause between turns to let the screen update with the new readings.
You can hit F1 to get the guide-lines for the data. I couldn't work out if the data lines were meant to draw over the top, or in between, or where... but at least I got them vertical!
Here's the same process with Minimal Head Align. The app is much more raw; it starts off with a screen full of garbage which starts refreshing once you start feeding it data from the tape drive.
Back to Double Dragon
I had assumed that all the loading issues were from a dirty/misaligned head... so I thought I'd try the game again now that the tape was producing cleaner, more vertical lines on the test programs. I didn't have much faith... but it worked! It took just as long as last time, but this time I got to the first level!
The graphics are intense... hah. Controlling the character was hard at the start... then I realised it was because my controller probably hadn't been used in a decade. I'd found a sega mastersystem controller at a second-hand shop over the weekend. Works perfectly.
So as the game was loading, it got to the point right before the title and asked me to reset the counter to 0. Turns out this is so that, when you die, you know where to rewind the tape to.
From there you rewind to zero, press play... wait for the load and then have another go. I might try source the game on floppies to see if the extra data capacity allowed for a different version. Hmm... then again if this review is anything to go by, then there's no hope.
Amiga 1200: Installing AmigaOS 3.9
After having Amiga OS 3.1 on the 1200 for a while, I'd decided it was time to upgrade to Amiga OS 3.9. I had instantly realised there was a problem with this; the installation media is on a CD! There was no way I was going digging for an accelerator card with SCSI, or a PCMCIA CD Drive, so I resorted to emulation to get the OS installed. Therefore, henceforth are the steps required to build a compactflash card with a real OS for use on real hardware. Godspeed.
Please note, a lot of this was gleamed from watching How to add a 8 GB Compact Flash hard drive to your Amiga 1200 (works with 4 GB too) and I want to thank Alex Rosato for providing this video. Please watch it if you have any issues with the steps here.
I also need to thank GothicKane for his video Upgrading Workbench 3.1 to Amiga OS 3.9. Both videos combined were required to get my A1200 up to AmigaOS 3.9.
Finally, the requirements are as follows: An Amiga 1200 with Kickstart 3.1, an 8gb CF Card + adapter and an accelerator card or memory expansion of at least 4mb. The base 2mb in the Amiga 1200 is not enough to run Amiga OS 3.9 successfully!
Choosing a CF Card
There's no real requirement here. Most posts will indicate that your card needs to be no bigger than 4gig. This tutorial will expect that your card is 8gig. I bought the smallest card available from a local camera shop (seems to be the only retail shops left with stock!) and 8gig was the minimum. I therefore had to go to extra lengths to get the partitions created. But it's now working perfectly.
Next you'll need a CF Card Reader for your ('non-amiga') computer. I've got a crappy USB all-in-one and it works fine.
Partitions
Off-the-shelf CF cards will come with FAT partitions on them. On Windows 10, drop to command prompt (Start, cmd) and then type diskpart. You'll get UAC prompt, accept it. You'll now need to be VERY CAREFUL. Type list disk and work out the number of your CF Card.
Microsoft DiskPart version 10.0.10586 Copyright (C) 1999-2013 Microsoft Corporation. On computer: WHITEBOARD-PC DISKPART> list disk Disk ### Status Size Free Dyn Gpt -------- ------------- ------- ------- --- --- Disk 0 Online 465 GB 0 B Disk 1 Online 1863 GB 0 B Disk 2 Online 1863 GB 879 GB Disk 3 No Media 0 B 0 B Disk 4 Online 7847 MB 0 B Disk 5 No Media 0 B 0 B Disk 6 No Media 0 B 0 B DISKPART>
As you can see, the all-in-one reader provides too many disks to choose from. Either way, I know I have an 8gig card in the slot, so it's Disk 4 that we're after. Therefore, type select disk 4. From here we need to view the partitions, so type list partition.
DISKPART> select disk 1 Disk 1 is now the selected disk. DISKPART> list partition Partition ### Type Size Offset ------------- ---------------- ------- ------- Partition 1 Primary 7847 MB 0 B DISKPART>
Once you're sure that you've got the right disk, and that you see the correct list of partitions to remove, you can either delete them one-by-one or use the command clean. I actually take objection to Microsoft indicating that 'clean' should clear all partitions. It sounds quite innocent when, in fact, it is obliterating all your data!
Either way, the goal is to end up with zero partitions on your CF card.
Installing and Configuring WinUAE
Our emulator-of-choice for the Amiga is WinUAE. Download it from here. Once installed, you'll need to always open it via Run As Administrator. WinUAE will need higher system privileges to access the low-level area of your CF Card, so don't forget to always run it in this manner. If you don't, then chances are you'll see "Access Denied" next to the CF card in the list further on.
Here's the fun part... to get WinUAE booted, you'll need the following items:
- Kickstart ROM 3.1
- Workbench 3.1 Disks (ADF)
- AmigaOS 3.9 CD
I.. won't tell you how to get them... but it's not hard... any of those terms, with the relevant verbs appended, when typed into google, should get you the binary 1s and 0s that you seek.
Next are some supporting files to allow greater-than-4gb disks to be useful. Create a folder somewhere on your disk and call it work. Download and extract (you can use 7-zip for this) the following to this directory:
Once you have the required loot then you can configure the rest of WinUAE to get a bootable emulator.
Creating Amiga Partitions
Start the emulator with its new configuration... patience will be required throughout the rest of this process. You should end up at the workbench desktop with a crap-tonne of floppies mounted. Firsly we'll drill into the work folder, where we have our after-market goodies, and partition the new disk.
At this point, I'm going to assume you extracted the goodies into this folder, if you haven't, then go do so now! Browse to work and open the HDInstTools drawer (that's what they're called on Workbench) and then the HDInstTools application. There should be one item listed here: the CF Disk as 0 0 0 with manufacturer of UAE-IDE.
Select this disk, make sure it's highlighted, and then press the File System button. At this stage there shouldn't be any filesystems listed, so choose Add... and select: work:Smartfilesystem/AmigaOS3.x/L/SmartFilesystem. Once selected, change the DOSType to SFS\0 (PRESSING ENTER AFTER CHANGING THE VALUE!.) Now press the Use button and you'll return to the FileSystem list. Press Use again to return to the main HDInstTools menu.
From here, since we now have a new filesystem declared, we can create partitions under it. Select Partition drive... and then hit Add Partition. A partition the full size of the disk will be created, but we don't want this. So hit Edit partition... so we can configure it further.
Drag the size slider to somewhere below 4gig. I would actually recommend below 2gig. Here I chose 1gig for this first partition. Set the File System to Custom and then manually type in SFS\0 for the DOSType. Press ENTER after typing in the new code whilst the text cursor is still in the text field! The cursor will move to the next field when enter is pressed. This way you'll be sure that the value has been applied. Next, change MaxTransfer to 0x001FE00 and Buffers to 100. Hit enter after entering each value! Then press the Use button to confirm changes to your first partition.
At this point, add as many other partitions as you want using the exact same method as above. They can be any size after this, but make sure that, if you're ever going to boot on an older Kickstart (pre v3.1) or older OS that you keep them at sane values. 2gig is a good theoretical maximum. There's also no harm in multiple 2gig drives for games, utilities, videos, mods, mp3s, downloads, etc...
Once you've got your partitions configured, hit Use and then Save changes to drive. At this point you'll be told that you need to restart. Hit F12 to get to WinUAE's configuration and save your settings. Finally, press the restart button in the bottom-left of the WinUAE control panel.
If all goes well, you'll be back at workbench with a DH0:NDOS on the desktop also. If this isn't visible then you'll need to go back to the start and open HDInstTool and see what configuration has stuck and what hasn't. Work out the gaps and run through the process again.
If you can see DH0:NDOS, then it's time to format it. Open up the Workbench3.1 disk, browse to System and then open the Shell. Browse to the smartfilesystem folder (cd work:SmartFileSystem) and then format the disk with the following command: sfsformat drive DH0: name OS. You can call the partition anything you want here.
If OS then appears on your desktop then you're set to install your operating system!
Installing Workbench 3.1
This is a pretty straight-forward install. You can save a lot of time by making sure the first 4 disks are already in the drives. You'll want wbench,install,extras and locale in first. Once ready, go to the Install disk and run the English installer.
A lot of the time you'll be hitting Proceed as we'll be using a lot of the default settings. Choose Intermediate Install and then go with the defaults. Make sure that the location is correct. You can see that my default location wasn't correct and that I had to select the proper OS: drive.
Once that's all out of the way, the installation will proceed. Let it do its thing until it asks for the next disk. This will be the Fonts disk. It'll want the Storage disk after this, so put both in to the df2 and df3 slots. Hit F12 to get to the WinUAE Configuration window and then swap the disks in.
Let it chug along further until you get the message to restart. Hit F12, eject all of the floppies and then reboot the emulator.
Congratulations, Workbench 3.1 is installed.
Other patches
Firstly, add the latest version of Installer to your new WB. This will allow your to install applications that require the newest version. Drag the executable to OS:C/.
NSD is the 'new style devices' driver. Install this by double-clicking on it.
Now it's time for the next version of WB.
Workbench 3.9
And finally... The latest release for the A1200. This is also very simple. Just make sure you have the 8mb of FastRAM configured and the ISO in the drive. Firstly, we need to set up the CD Drive. So head into WinUAE Configuration and then to the CD/HD tab. Here you need to Add SCSI/IDE CD Drive. Choose the defaults and hit Add CD Drive. Load the ISO into the slot at the bottom of the window. Also make sure that CDFS automount is enabled!
Reboot WinUAE and you'll have a CD on your desktop. Find and run the installer.
And now... the installation. Very straight-forward... hit Proceed in most circumstances. Just make sure you choose a OS3.9 full installation over OS3.0 or empty HD. Also make sure you get the target disk correct!
Restart and you're there! Browse to OS:Prefs and double-click on ScreeMode to change the screen resolution and color depth.
Boing Bags
These are service packs for the Amiga. Download Boing Bags 1-4 here. Install them in order, started from 1. Make sure you install the ROM update from BB2.
Extra features
The OS3.9 CD has a few goodies on it. Don't forget to browse it and copy anything you might want onto your HDD. It gets painful down the track if you have safely secured your CD Card into your A1200 and then have to fight floppy disks to transfer data across.
I'll post again on OS3.9 when I work out what you can do with it. Learning starts now...
Commodore 64: Tape Drives
This was really a lesson in jumping in the deep-end. I'd bought Double Dragon for the C64 recently on eBay, somewhat blindly, and found out that it was on datasette. It had been relegated to museum shelf until I happened across a cheap tape drive. Below is the story of learning how these things work.
The Datasette drive arrives
The seller had mentioned 'original box' and 'complete'. Indeed it was. I take it, though, that the box had been in the back of the shed for quite some time. The manual pages were mould-glued shut and the box was probably releasing spores every time I touched it. Due to this, I took photos for historical-sake and then destroyed the evidence; keeping only the actual drive.
The first game: Double Dragon
Double Dragon (for C64), released by Melbourne House (more information here), is a side-scrolling beat-em-up. The name of the company is confusing, as it sounds like it might be Australian, but was actually started in London. There is/was an Australian branch though, but it was known as Beam Software.
I'd played this game with my brother decades ago on the 286/386. Actually, I think nearly every Australian kid who grew up in the 80s/90s would've played this on a platform somewhere... maybe sega/nintendo/x86/amiga/atari/etc... Or even at the arcade! Either way, I wanted to check this out on the Commodore 64.
Intricacies of a Datasette Drive
This device has a single cable that plugs onto the PCB edge-connector 'port' at the back of the C64. It's a similar connection to the User Port; very raw and very cheap for Commodore to produce en-mass. The cable also has a grounding wire, but I don't quite know where you'd connect this to?
As you can see, everything was there, ready to hook up and run. I did just that, plugging the tape drive in, the power and TV. Switching it all on brought me to the usual BASIC prompt. I had heard the tape drive make a few faint clicks. The tape needed rewinding, so I let that run it's course (hah, how I don't miss having to do that!)
I'd found out, by accidently typing only LOAD previously, that this was the command to load tapes. After hitting enter, you get a prompt to press the Play button on the tape drive. So, at this point, I did exactly that. As I hit Play on the Datasette, the tape spun, then slowed down... then .... stopped......... Sure, this 30 year-old equipment had been stagnating in someones shed for decades... probably worn-out and dead.
As I was pressing the eject button, the tape started playing again... demons? ghost in the machine? not quite... turns out that a slight bit of pressure on the eject button releases the bottom-right 'guide' that keeps tension on the magnetic tape in the tape case as the tape is playing. This component was able to apply WAY too much tension and therefore effectively 'braked' the tape and cause the motor/band to slip.
'Band', you say? Yes. Band. No belts with teeth here... the drive mechanism is a cute little motor with a rubber band driving the other pulleys. There is then a further rubber band to drive the counter. 'How do I know this?', you ask? ... I took the thing apart as soon as I could!
The bands looked pretty stock-standard. A quick google showed zero results for replacements... so... searching around the house I found some probably-too-small substitutes. Having a band too tight will probably pull on components and put waaaay too much pressure on old equipment that may not be rated for it; but hey, you can only try!
Replacing the main band required 3 screws to be removed. See above. Once removed or loosened, you can slip the main band out.
I then put my two replacements in. Lo'and'behold... the bloody tape started playing. The results? The screen went blue for 15.5 counts, the tape paused and then a message came up: Found Double Dragon! Woah.. then a slight pause and then the tape continued. Then it was ... rubbish?
I gave up after 20s of garbage picture and noise... must be a crap tape or damaged head. But... it did recognise the data on the tape... I mean, it knew the name?
Another Tape: The Android
Along with the datasette drive, I also purchased a 5-tape set of miscellaneous games. I whipped the first one out, named Android and tried it. The C64 successully saw that it was indeed The Android and then ... more crap loading. Loosing heart, full bladder, too much Sapporo... I excused myself, letting it play...
Returned a while later and.. WHAT THE!?... It loaded!? So... wait... those loading images are expected!? That crappy video that would trigger an epileptic fit and that sound that's drilling into my inner-ear is normal?
Android Control (different name on tape vs. name on 'found' vs. name on title?) loaded, I played it for 5 seconds... but I'll try that again later.
Back to Double Dragon
So, now knowing that I need to sit back and wait... I slapped Double Dragon back in again. It took the same 15.5 counts to the Found Double Dragon message and then 58 counts to the next message.
Ok, we're getting somewhere... I hit space...
DAMN! 3 minutes of waiting... first time around the tape actually reached the end... that actually indicates a data issue. Second time around I got the error above. So Android will load, but Double Dragon wont! Might have to clean the heads... Will report back when I have time to try again.
Amiga 1200: Indivision AGA MK2cr
After toying with video output on the Amiga 1200, I'd come to the realisation that old technology just wont display well on brand new TVs. Due to this I therefore researched what everyone else on the interwebs did to get a better resolution from these old beasts.
Results came up quickly and all signs pointed to this device, the Indivision AGA MK2cr by Individual Computers (buy it here.)
This device piggy-backs onto the Lisa chip (the Amiga's Video processing chip), taking the output and then using it's own CPU to convert this to a more recent standard that newer TVs and Monitors can reproduce. It has upgradeable firmware and configurable options. It's stated that, out-of-the-box, you won't need to configure a single boolean value to get it running.
The price isn't low.. but all the reviews I'd read indicated that the value for money ratio was high. I therefore set out in pursuit to find one and came across some hits on Amibay, but watched as faster hawks snapped the prey up VERY quickly.
eBay showed some results also; and then it happened... the exact seller of whom I bought the 1200 from provided the device up for sale. I couldn't resist... Steve understands eBay and had treated me perfectly on the previous sale and so I grabbed this item. Turns out I got a few extra bits too, of which I'll report about later.
Unboxing
The item arrived in record time and it felt like Christmas had come early once again. I knew I had to take my time with this though... opening a ~30 year old piece of equipment (although you could tell it had previously already been modified) required patience and a steady hand.
The box came with all the required components. No software is provided as the device works primarily via its own firmware to detect the video signals being produced by the Lisa chip and convert them out to DVI-capable resolutions.
Installing it
All in all, this was a piece of cake. As mentioned, this Amiga 1200 had been toyed with before and so there was no hassle of breaking warranty seals and the like. Case screws were undone and then the top plate was removed.
I'd previously wondered what the extra DB-25 port was on the left-hand-side (as you look at the back of the machine) and this became clear on opening the case. It's a SCSI port for an accelerator that contains a SCSI interface. As you can see, no such accelerator is in the slot, so the internal end of the cable was sitting loose.
Over near the Lisa chip, I found the CF card to be sitting directly above it. Turns out that there's enough clearance above the MK2cr to have the CF sitting on top, so I unstuck it, flipped it over and stuck the new hardware in place. This went on with a nice click. Even pressure was applied to the center area, where the 4 holes are. Once in place, the cable was run (very tightly, it's the perfect length!) to the location where I'd removed the SCSI plug. Fortunately, I received a 3D printed plate to hold the DVI connector in place. I did need aftermarket screws to secure the plug in the housing; the nuts that were removed from the end of the DVI plug weren't long enough to go through the plastic plate.
First Impression
This always counts... this device was marketed as 'no configuration' ... reminds me of the old 'plug-n-pray' days. Sometimes I miss ISA/EISA cards and their jumpers of which I had supreme control over. Anyway, I hooked up a cheap VGA cable via a DVI-to-VGA adapter and plugged it into the TV. Powering it up... I nearly cried.
The ghosting was immense ... and I truly wasn't expecting this from a Digital product. A quick google lead me to believe that the DVI-to-VGA and then the VGA cable were trashing the signal. I also noted that the resolution being output was 1280x1024. That's a great resolution; but a shitty VGA cable might have issues. I quickly tested the shit VGA cable and adapter on a VGA monitor... it looked better, but still not up to the standard I was expecting.
So, I opened the warchest and found a chunkier cable that had a DVI on one end and a VGA on the other... on the LCD Monitor still showed minor ghosting, as follows...
But on the TV, the ghosting was hardly noticable... Score! This is the pixel-for-pixel that I was looking for.
At this stage I was content with the output... It has since occurred to me that I could convert the DVI to HDMI and keep the signal totally digital. I'll try that and report back soon.
Configuration Options
The 'overscan' area can be customised. On bigger screens, it will default to the background colour of Workbench. You can confgure this using BorderBlank.
Next, resolutions. The MK2cr supports the 'HighRes' driver. Download it here. To install it, move the HighGFX file from the archive to your "sys:devs/monitors" directory and reboot. Higher resolutions should now be visible in the ScreenMode prefs.
If you want to toy with the devices configuration itself, then firstly grab the Flashing tool and v2.6 firmware to see if you have the latest installed. Once you're up to date, you can use the v1.5 Config Tool to configure the device.
From what I understand, you choose the mode on the left and then re-map it to a resolution from the VGA column. Then hit Test/Use/Save. Will update when I tinker further...
The resolutions are awesome. You can find the HD720 driver in the HIGHGFX package, drag that to your dev/monitors folder also. I switched my TV to 16:9 scaling and the resolution looked great!
Time for model train controller programming and games!
Parallel Port: Digital to Analog
Most parallel ports on most computers (Amiga, C64, PC, etc...) have (at least) 8 true digital pins that one can interface with for either input or output. This can be extended using shift registers or multiplexers; I've written up an example of this here.
With a lot more pins at one's disposal, more items can be controlled; as long as what you want to control is in the digital realm. To control a standard DC motor, for example, you'll need to be in the analog world and we'll describe how to get there below.
Digital to Analog Converters
The basic principal is to use a number of digital inputs and map these to relevant resistance values on an output. If you had 4 pins available, then you could determine the maximum resistance you needed and divide by the number of pins. You'd then make sure that, as each pin was brought HIGH, that the resistance summed towards the final value that you required.
You can either use a bunch of resistors to do this, or an integrated DAC circuit.
R/2R Ladder
This circuit consists of a bunch of resisters in parallel/serial, using properties of such combinations to provide a stepped resistance output. This is known as an R/2R Ladder and is a popular method for converting digital signals to analog.
We're going to implement one using 10k/20k resistors and an LM358 opamp to buffer the output. This part of the circuit is borrowed from the 8-bit digital to analog converter circuit over at IKALOGIC.
Combining it into our Parallel Port Interface
The 8 outputs from the 595 need to be de-coupled from the LEDs and provided as the inputs to the resistor ladder.
As that we can send any value to the 595, you don't really need to be careful as to which end is the MSB, but do remind yourself of it as it'll become important when writing the software.
You should now be able to check the voltage on pins 1 or 2 to see the variance between 0 and 5v when you're switching the bits on and off.
To my surprise, the output voltage was nearly exactly double the byte value being output by both the Commodore 64 and the Windows Parallel Port.
Once the test breadboard produced the result I wanted, I confirmed it all by soldering it together on the PCB. Not the ugliest mess I've created, but not very far off! And... it works.
What's next?
Now that we have an analog interface, we can control a PWM throttle. To do this, we'll go back to the Arduino world and steal a motor controller. I've previously worked with H-Bridges before and will use a module to make this easy. Controlling direction will be easy also!
Commodore 64: cc65 and the User Port
Ok, we've build the user port to parallel port adapter. We've build the parallel port interface. We've hooked a shift register onto it and now we want to control it. Doing this through BASIC would be fun... but compiling real C code and getting this onto the C64 will be thoroughly more enjoyable. Go and download cc65, along with your favourite emulator. VICE works very well on Windows.
Getting a sample running
Before we even think of real hardware, let's get the samples running on VICE. Once you have everything installed, open a command prompt. Switch to the directory where cc65 is installed. Also set your path to the cc65/c64/bin folder. Run cc65 to check if you've got everything correct.
Microsoft Windows [Version 10.0.10586] (c) 2015 Microsoft Corporation. All rights reserved. C:\Users\windows_user_1>d: D:\>cd cc65 D:\cc65>set path=d:\cc65\bin D:\cc65>cc65 cc65: No input files D:\cc65>
Download the samples from the github repository and save them nearby. Switch into the samples folder. Choose a sample to compile; I chose ascii. Compile it. Don't expect much from the compiler if there is no error. We're going to use cl65 here which also does all the linking for us.
D:\cc65>cd samples D:\cc65\samples>dir Volume in drive D is Data Directory of D:\cc65\samples 26/05/2016 12:40 PM <DIR> . 26/05/2016 12:40 PM <DIR> .. 17/05/2016 02:26 PM 2,300 ascii.c 17/05/2016 02:26 PM 8,068 diodemo.c 17/05/2016 02:26 PM 2,455 enumdevdir.c 17/05/2016 02:26 PM 6,928 fire.c 17/05/2016 02:26 PM <DIR> geos 17/05/2016 02:26 PM 6,592 gunzip65.c 17/05/2016 02:26 PM 1,956 hello.c 17/05/2016 02:26 PM 3,772 Makefile 17/05/2016 02:26 PM 3,711 mandelbrot.c 17/05/2016 02:26 PM 7,345 mousetest.c 17/05/2016 02:26 PM 6,236 multidemo.c 17/05/2016 02:26 PM 69,766 nachtm.c 17/05/2016 02:26 PM 3,117 overlaydemo.c 17/05/2016 02:26 PM 8,573 plasma.c 17/05/2016 02:26 PM 5,865 README 17/05/2016 02:26 PM 2,876 sieve.c 17/05/2016 02:26 PM 5,269 tgidemo.c 17/05/2016 02:26 PM <DIR> tutorial 16 File(s) 144,829 bytes 4 Dir(s) 1,717,242,986,496 bytes free D:\cc65\samples>cl65 -O -t c64 ascii.c D:\cc65\samples>
Quickly check that there's a binary called 'ascii' in the folder with no extension.
D:\cc65\samples>dir Volume in drive D is Data Directory of D:\cc65\samples 26/05/2016 12:52 PM <DIR> . 26/05/2016 12:52 PM <DIR> .. 26/05/2016 12:52 PM 2,648 ascii 17/05/2016 02:26 PM 2,300 ascii.c 26/05/2016 12:52 PM 2,767 ascii.o ...
You've got a compiled application! Let's run it. Open up VICE (x64.exe is the c64 version) and choose File -> Autostart disk/tape image. You'll need to browse to where you compiled the sample and set the filter to all files.
Once you see 'ascii' (or whatever you compiled) double-click it.
Feel free to play with the other samples and see what C code is available and explained.
Poking the Port
BASIC had two commands that altered system memory. PEEK and POKE were essentially READ and WRITE. They allowed the user to change values in RAM or read values back. Hitting certain addresses did certain things. Specifically, on the C64, POKING 56579 altered the input/output configuration of the User Port and then POKING 56577 changed the values being sent.
To do this in C, we need equivalent functions. Fortunately, the cc65 wiki has all the information we need. It turns out that no function is required, you can simply write to ports by setting the address (via a pointer) to the value you require. To make it a little less difficult to read, they've also provided macros to do the same thing. They'll help when you come back to the code 6 months down the track and can't read a thing you wrote!
#define POKE(addr,val) (*(unsigned char*) (addr) = (val)) #define POKEW(addr,val) (*(unsigned*) (addr) = (val)) #define PEEK(addr) (*(unsigned char*) (addr)) #define PEEKW(addr) (*(unsigned*) (addr))
There's also pokes for 'WORDs' there, but we don't really need them. Look here for a huge list of what you can PEEK and POKE. Turns out there's more memory address to poke here.
Note: These defines are also in peekpoke.h, just include that!
Moving the cursor
By default, as per CMD or any other Console, the text just rolls down the screen. Scrolling (with a buffer) is something that you actually need to implement in C64, so either start preparing for a buffer, or just get ready to use a single screen and clean up after yourself.
I want to draw a diagram of the 8 LEDs I'm about to control, so for this purpose we'll need to be able to place characters at certain positions. This involves moving the cursor to the required location and then outputting the character.
Fortunately, functions are already there to do all this... just use the gotoxy as per the source listing below.
Controlling the parallel port and 74HC595
So, we now have everything we need to write out the data required to control the 595. I'll just list it below. There's more information back here on how it actually works.
#include <stdlib.h> #include <string.h> #include <conio.h> #include <joystick.h> #include <peekpoke.h> #define USERPORT_DATA 0xDD01 #define USERPORT_DDR 0xDD03 static const char Text [] = "Train Controller!"; void shiftout(int val) { int i = 0, zzz = 0; for (i = 7; i >= 0; i--) { POKE(USERPORT_DATA, (val & (1 << i)) == val ? 1 : 0); POKE(USERPORT_DATA , 2); for (zzz = 0; zzz < 1000; zzz++) {} POKE(USERPORT_DATA , 0); } POKE(USERPORT_DATA , 4); POKE(USERPORT_DATA , 0); } int main (void) { unsigned char XSize, YSize; int i = 0, z = 0, zz = 0; //set all pins to output. POKE(USERPORT_DDR, 255); /* Set screen colors, hide the cursor */ textcolor (COLOR_WHITE); bordercolor (COLOR_BLACK); bgcolor (COLOR_BLACK); cursor (0); /* Clear the screen, put cursor in upper left corner */ clrscr (); /* Ask for the screen size */ screensize (&XSize, &YSize); /* Top line */ cputc (CH_ULCORNER); chline (XSize - 2); cputc (CH_URCORNER); /* Vertical line, left side */ cvlinexy (0, 1, YSize - 2); /* Bottom line */ cputc (CH_LLCORNER); chline (XSize - 2); cputc (CH_LRCORNER); /* Vertical line, right side */ cvlinexy (XSize - 1, 1, YSize - 2); /* Write the greeting in the mid of the screen */ gotoxy ((XSize - strlen (Text)) / 2, YSize / 2); cprintf ("%s", Text); /* MARQUEE */ for (zz = 0; zz < 4; zz++) { for (i = 0; i < 8; i++) { shiftout(1 << i); for (z = 0; z < 8; z++) { gotoxy (((XSize - 15) / 2) + (z * 2), (YSize / 2) + 4); cputc((z == i ? 'X' : '_')); } } for (i = 7; i >= 0; i--) { shiftout(1 << i); for (z = 0; z < 8; z++) { gotoxy (((XSize - 15) / 2) + (z * 2), (YSize / 2) + 4); cputc((z == i ? 'X' : '_')); } } } /* Wait for the user to press a key */ (void) cgetc (); /* Clear the screen again */ clrscr (); /* Done */ return EXIT_SUCCESS; }
Note: some cputc calls reference defined characters such as CH_URCORNER, etc... These are PETSCII, the embedded character set of the Commodore. The wiki page has the numbers for the characters. Go to the include folder of cc65 and then cbm.h to see if the character is defined, otherwise just put the value in as a raw number.
And the result.. the bloody thing worked first go. Pretty scary actually... compiling and executing C code on the C64 was too easy. Of course, I cheated by using an SD2IEC. The load command was LOAD "0:TRAINCTL",8 followed by RUN.
You'll note that my keys are still on order... I can't wait for them to arrive as pressing 8 is tedious. Also that the last shot shows two Xs lit. Blame shutter speed and screen refresh times.
What's next?
Maybe it's time to hook up the serial port? nanoflite has provided a C driver which may well help us. Otherwise it's time to write a real railway controller for the parallel port interface... but I should actually finish that first.
Commodore 64: Wiring up the User Port
The User Port on the Commodore 64 is a combined parallel port + serial port. Both of these can be used after a little wiring effort. Memotronics has the ports available, with nice handles. The handle is imperative for ease of removal. You really don't want to be pulling on wires to unplug anexternal device! I purchased this and also couldn't resist the 200 random LED bag.
User Port Socket Alignment
There's a row of letters and a row of numbers... make sure the numbers are along the top. Looking at the back of the C64, you'll notice there's two slots for socket alignment. To the right are two pins, then the center block, then 1 pin on the left.
Yes, the socket is plugged on upside-down in that middle picture!
The socket from memotronics comes with two white spacers in a plastic bag. Slide them into the slots appropriate for each side of the socket. Once done, tin up your wires and solder through to the parallel port.
Connecting it to our circuit
The whole reason behind this is to control the circuit described here and here. The goal was to use a standard interface, being the parallel port. The Amiga and the PC happily work; the Commodore was next. As mentioned above, the data pins are there, we just need to wire it through.
One really good point: once you've attached the wire to the parallel port end, draw a black line down pin one to the other end. Knowing which wire is which will get confusing once you've jammed it through the user port socket 'cap'. I actually surprised myself expecting to see the black line elsewhere and was glad I'd drawn it.
With the User Port socket in hand, I reviewed a few documents to work out which pins did what. All pinouts was a good source, until I realised that 'I' was missing. I assumed they got it wrong and so went searching further. The c64 Wiki has a pinout also, which also doesn't include 'I'. What's that old saying? No 'I' in 'Team'? There's no 'I' in 'User Port' either...
One quick check elsewhere at hardwarebook.info told me that the port I had from memotronics, which has an 'I', is incorrect. So... just make sure that the
The 'middle' 8 lower pins of the socket are the data pins that 1-to-1 match D0-D7 of the parallel port. You can then use Pin 1 and 12 to GND on the parallel (18-25) and yes, 17 is GND, but not on Amiga!
Putting it all together
Everything plugged together nicely... I powered up the circuit first; you should always make sure perpipherals are powered on first, prior to turning on the C64. Either way, LEDs lit as per usual and then it was time to hack in BASIC. You can see on the screen that I tried to output an 8-bit binary value to the 595... but the results weren't stable. It was late and I'd accomplished the first task: The pins were wired in and the LEDs between the optos and the C64 lit as expected!
What's Next?
Either I continue hacking BASIC and get the 595 driven, or I use something like cc65 and write real C. I think I'll go the latter. I also want to hook up the Serial port here... so I'll extend my little dongle to have a serial port hanging out of it also.
See this post on cc65 for an example of how to program the Usre Port via C!
Parallel Port: Shift Registers
Now that we've controlled a LED by a single pin on the Parallel Port, it's time to expand our abilities. The goal of this post is to describe the usage of Shift Registers and then consume a minimal amount of pins, 3 out of the 8 available, to control up to 64 outputs!
A Shift What?
So, you have 8 digital input/output pins on the Parallel Port. This isn't the greatest amount and it'd be really nice to extend the amount available. There are a few ways, but a popular method is to employ a shift register.
A shift register is an IC which takes a 'serial' input and then outputs this on it's output pins in 'parallel'. By 'serial', we mean that the IC accepts input data on one pin only. This data is provided by you, as either a '1' or a '0'. Once you've set the value on the input pin, you then toggle another pin, known as the 'clock' pin, to tell the IC that the data is ready to be consumed.
The shift register, once the clock pin is toggled to a '1' and then back to a '0', will look at the input pin and then copy this value into it's internal register. We're using a 74HC595 which has 8 internal registers and therefore 8 output pins. At this point, the IC shifts all values on it's 8 internal registers up one slot and then sets the very first internal slot to the value you've provided.
You can then provide 7 more values, toggling the clock pin between each, an the IC will shift them along it's internal registers. What you've now done is set an 8-bit value inside this IC. Once the IC contains the value you've requested, you toggle the 'latch' pin and the IC will shift these 8 values out to the 8 output pins. These are known as 'parallel' as there is a single pin for each value; as opposed to the input which is serial (or one-after-another) on a single pin.
So, we've used 3 pins/wires here to control 8 output pins... pretty neat hey? We've turned our original 8 Parallel Port pins into (8-3) + 8... 13!
But wait, there's more! There's an 'output' pin on the shift register that reports the 'shifted off' value. What can you do with this? Feed it into a neighbour shift register as the 'input'. Hook up the same clock/latch wires as the first register and then, when you shift the 9th bit into the first, the very first bit you shifted in will be shifted out of the first register and into the second.
This means that, with the same 3 wires, you now have 16 outputs! Of course, you can keep doing this. I can't find anywhere that mentions how many you can effectively chain up. Of course, as you add more, the time to toggle out the values increases and you need to make sure that your code/hardware has time to think about other things instead of spending it all talking to the shift registers.
Connecting it to our previous circuit
We only used one line of the parallel port in the previous circuit and therefore only controlled one LED. For this first shift register, we'll need 3 lines. First thing is to hook up three LEDs with matching resistors. We could just hook two other lines up direct to our new shift register, but I like being able to visualise the data (and troubleshoot issues!)
With this circuit, you'll be able to use the sample code in the previous post to control the 3 LEDs.
Sending out a 1, 2 or 4 should switch them on individually. Sending any combination of these, by adding them together, will turn on the associated LEDs. For example, sending out the decimal value 3 will switch on the first and second LED. The value 5 will switch on the first and third LED. As the value makes it to the port, it is split into it's individual bits, which are then translated to the data pins.
Once these are working, we're going to splice in some opto-couplers. We don't want any untoward voltages getting back to the parallel port. Optocouplers contain an LED and an internal light sensor. When power is applied to the input, the LED lights and the light sensor receives the signal. This is then output to the secondary circuit. This effectively provides an 'air gap' between the two circuits.
From these couplers we can control our shift register(s). Hook the three outputs to the 74HC595 shift registers SERIAL, CLOCK and LATCH pins. Remember the order as they each play key roles (as per the description of how they work above.)
Once you're ready, check that the three input LEDs react accordingly to basic Parallel Port data. Note that you may get erroneous data coming out of the shift register from the get-go. Data coming off the Parallel Port during system boot cannot be controlled and may cause havoc. We'll do something about this in a later article.
Building this required a LED array... you could do it easier and get one of those bar-graph arrays. Wiring up all the individual LEDs gets a little tricky.
Controlling the data output
Based on the initial description of the shift register, we know that we have to control the 3 data lines in a special sequence. First thing we need is an 8-bit data value to send out. Once we have this we can send each data bit out via the SERIAL line; toggling the CLOCK signal in-between. Finally, toggling the LATCH should see our value displayed in a glorious binary LED representation!
I've used Windows and the Parallel Port code here to manually try and turn on LEDs. My wires are hooked up as D0:SERIAL, D1:CLOCK and D2:LATCH. I am going to send 00000001 as the value to ensure that all LEDs are turned off bar the first.
- Ensure that LATCH is low (red)
- Toggle D0 to RED, this is a '0' for the first bit of the serial value.
- Now toggle the CLOCK (D1) on and off 7 times.
- Toggle D0 to GREEN.
- Toggle the CLOCK on/off once more.
- Toggle D2 on and off...
If everything is hooked up, then you should now have one LED showing on the output of the 74HC595. It didn't quite work with this initial circuit... LEDs would light a little randomly.
Noise
Although the above circuit worked, it was not reliable! Every now and then one LED (or two) past the one I wanted to switch on would also switch on! Sure, my soldering was dodgy, let alone the wiring also being messy. Either way, noise was being introduced and the flipping of the serial and clock was jumbled, causing random output.
The solution to this was to put a 100nf capacitor across the +5v and gnd supplying the 74hc595. This cap should be put as close to the IC pins as possible. Once in place, this stabilised the data from the PC Parallel port.
References
- HowTo: Understand the 74HC595 (David Caffey)
- Gammon Forum: Using a 74HC595 output shift register as a port-expander
- protostack: Introduction to 74HC595 shift register – Controlling 16 LEDs
What's Next?
Next is a 12v throttle. I intend on using the described sample here. The only issue is that it wants a potentiometer to vary the output voltage. This is an analogue method; we'll convert it to digital by calculating 8 resistor values to imitate the throttle at 8 positions.
I'll write this up soon once I've completed the circuit.
Parallel Port: Model Railways
Am sure this has been done 100 times before, but I've recently acquired two relic computers and I want them to control my trains. They both have ports consisting of 8 digital I/O pins and I'll utilise these to control a throttle, direction and points. I'll also use them to read sensors.
Having only 8 pins provides a nice challenge... but nothing a few shift registers cannot handle!
First step, LEDs
Let's get started very simply by switching a LED on and off. One might think that, as that LEDs are synonymous with digital electronics, that one can just hook it up to a digital pin and set the output to HIGH. One could... but the current draw would likely kill the 'controller' that the parallel port relies on!
Due to this, you must make sure that you provide sufficient safeguards to prevent damage to your delicate hardware. Once you trash a parallel port in a system (especially of this vintage), you cannot go back.
The trick we'll use is known as opto-coupling or opto-isolation. The goal is to use ICs that have both a LED and a light sensor inside them. When you trigger a HIGH state on the LED side, the light sensor is activated and the associated HIGH state is seen on the output side.
This effectively isolates the electrical circuits and prevents any unweildly voltages on the 'peripheral' side from trashing your valuable hardware.
Thanks to Ian Stedman, we can use the circuit he has provided to hook up LEDs and opto-couplers.
The Amiga port provides a lower current than most PC Parallel ports, so we'll use it as the lowest denominator when creating this circuit so that we can use this hardware across multiple platforms.
(Excuse the paint-brush infancy!)
A 74HC7404 Hex Inverter is used to 'sink' the current used by the LED or Opto-coupler. This IC is much more capable of handling the current and will link the GND wires together internally rather than sending the GND signal back through the parallel port to be linked inside the Amiga (or other device that you've plugged this in to.) This provides a secondary level of protection.
The circuit was built on a crappy prototype board; I seem to have misplaced my breadboard. I used ribbon cable and a standard DB-25 male printer port plug. I've left room for future expansion. I had some spare RGB leds, so the red light is showing that 5v is available and green indicates a 'LOW' output from D0 (or pin 2 of the parallel port.)
Controlling it via code
Thanking Ian again, he's provided us links to demonstration code to test out the circuit we've just created. Download the first sample here.
This sample provides a compiled version of 'Pario' which is a C program to test the parallel port on the Amiga. This code is for the console, so extract it and then run the PARIO/PARcode binary.
Excuse the quality of the photos... haven't learnt how to take screen captures on the Amiga and photographing an LCD TV isn't easy.
Either way, once the program is loaded you'll get a list of options... Press 1 then enter then set the ports to output. Then Press 2 and enter either FF or 00. This is a blanket 'all on' or 'all off' for the 8 data pins.
Doing this made my LED successfully light up and turn off! Winner!
Cross-platform: PC test on Windows 7
This wasn't fun. First I had to re-image my Lenovo X61 as it had a huge amount of spyware on it after lending it to a friend. Then I had to make LPT1 work. Device Manager indicated that all was swell, but the sample code from Code Project just didn't work. On reboot, the green LED would flicker, so I knew that the port was live and communicating.
I dug deeper and tried a second example, using TVicPort, but this also didn't work. I went into the BIOS and found the port disabled!?! Why did Windows tell me it was fine?
After enabling it, there was still no dice. I dug through the sample code and it all seemed to set the port into ECP mode. Was this the same as "bi-directional" which was the default setting in the BIOS? Had no clue.. so back into the BIOS where this could be changed to ECP. Had to be it!
And blam! It works. Hitting D0 on the first sample app works a treat!
Cross-platform: Making this work from the Commodore 64!
My User Port interface for the C64 arrived and I decided that using BASIC was going to provide a good challenge. I've also now coded the User Port in C.
With the hardware hooked up, I ran the following sample to control the LEDs. A thanks to Coronax for the initial example.
Originally the code was to test all values up to 255, or 11111111b. We only need to test the first three pins in our case, so going to 7 (or 111b) will iterate through the values as expected.
Line 20 sets the magical address 56579 to 11111111b. This means that all 8 pins are '1' or 'output'. 56577 is then the I/O for the port and setting a 0 or a 1 provides a digital LOW or HIGH respectively.
10 PRINT "USER PORT EXAMPLE" 20 POKE 56579, 255 30 FOR I = 0 TO 7 40 POKE 56577, I 50 FOR J = 1 TO 150: NEXT J 60 NEXT I 70 GOTO 30
Does it work? Yes... Check out more on coding the User Port here.
What's next?
Next is a shift register... with the ultimate goal being a minimal-pin-usage 12v throttle for the railway. Stay Tuned.