Subscribe via RSS
19Oct/200

Replacing the ear microphones on a Sony Aibo ERS-7

He'd arrived a few weeks back and gets energised a few hours per week... but he's a bad dog! He says "Good bye" in repsonse to me saying "Hello Aibo" and I'm going to blame him first... it can't be my mumbling? Can it? Just to be certain, I browsed around and found a DIY Repair Guide on Aibo Doctor. I quickly ordered a selection of microphones from element14 and got to work. Canine surgery is daunting!

The Microphones

As I always manage to get my orders wrong, I went ahead and ordered a selection of Microphones.

DSC00731

Note that an ERS-7 Aibo needs 6mm microphones, so you can see that one set is already incorrect. Next, there's directional and omni-directional. The microphones in Aibo are omni*, so I settled with the KECG2742TBL-A units.

Disassembling Aibo's Visor

Following the instructions here, one can disassemble Aibo's head to get to his ears. First step, remove the rubber earlobes by stretching them over the silver joint. Next, open his mouth and remove the two screws.

DSC00740

With these two removed, you can un-hook the rear of the bottom half of his head. This shell is not directly connected to his bottom jaw, so open his mouth fully and then push the whole lower-half back. With it unhooked, you can then bring it forward again and bring it over his jaw. With this piece out of the way, it's back to the front of his head where we need to remove the two outside screws on the metal plate inside his nose.

DSC00742

With those two out, you then need a longer screwdriver to get to the two screws deeper inside his skull. They're on either side of where his jaw would attach near his ears. See the image below, one screw on one side is in focus.

DSC00746

Finally, there's a clip on each side just in front of his ears, holding the visor on.

DSC00744

Very gently pry this open and the visor should lift up. You now have the option to disconnect all the cabling, but instead I just let it rest forward. Make sure it doesn't put undue pressure on the ribbon cables inside.

DSC00748

You now have access to the ear joints.

Disassembling Aibo's Ear Joints

Ok, this isn't the actual ear/microphone yet... before we get to that, there's a bit of fidgeting required to get the ear joints disassembled. When following the next steps, at no time will you need to apply excessive force! Doing so will most-probably damage poor Aibo. The ear joints are a two-part component and are built to be assembled/disassembled with ease. If you look at either side of Aibo's ears, you'll see that one side has a fixed arm and the other has an arm that slides backwards. The fixed arm is at the front and also has a little actuator (metal bar with notch) that is the mechanism that flaps Aibo's ears around when he's playing.

So, back to the joints: two pieces, first is removed by sliding the rear arm further to the rear. From there, you can grab the whole circular joint and unhook it from both front lugs. There's a lug in the actual main arm and a lug in the little black actuator arm.

DSC00780

The image above doesn't really help to explain how to undo it. The movement is one-shot and you can see in the photo above that the black actuator is on the left. This means that you're looking at Aibo's right ear and that you'd grab the top silver circle and slide it gently to the right (rear of his head) until both lugs are clear on the left. Once done, you can then slide off the rear shield.

DSC00752

From here, it's a single screw and the microphone + housing is free. Make sure you also unhook the cable!

Replacing Aibo's Inner-Ear

With the microphone unhooked and unscrewed, the silver shell can be lifted off (gently) by applying pressure to the joints that hold it on. With this off, you can really see what condition Aibo's ears are in!

DSC00756

From here, you can slide the microphone out, just enough, to be able to de-solder and solder a new component.

DSC00767 DSC00768 DSC00776

As you can see, I cheated and used the phone the new microphones came in to hold them in-place whilst soldering. I used the datasheet to make sure I got the polarity the correct way around, assuming that red was positive.

With everything wired up, the microphone was pushed back into the housing and re-assembled. Make sure that you have the wires in the correct groove according to the side the ear has been removed from!

Finally, as per above, there is absolutely no need for excessive force on any part of this assembly. I found that, once trying to re-fit the visor, it wouldn't sit flat! Turns out that I'd assembled the rear part of the ear-joint incorrectly and only one side of the guides was actually in the right spot!

DSC00793

If you look above, you can see that the left guide is sitting above the plastic strip that it was meant to slide onto! This meant totally dismantling that ear again to pull that part back and slide it back on again! Painful, but required.

Can Aibo hear me now?

Nope, same as before! Turns out you can just use Clinic Mode to determine if his microphones actually really need replacing! I should've done this first, but I also sorta wanted to play doctor and see what his insides looked like!

17Oct/200

OpenTTD 0.1.4 on TurboLinux 1.1 for Power PC

So, TurboLinux 1.1 is up and running on my Power Computing PowerCenter 180. It took a lot of effort and what is the result? A cobbled-together version of RedHat 2.0 for PPC! Ancient. I should probably stick to tuxracer, but that may even be 'too new'. I want to get OTTD running on this, so I've chosen a really early version that will hopefully mean I don't need to uplift the entire kernel/OS to get running.

Automake and Autoconf

To build OpenTTD, we'll need an appropriate version of SDL. I chose 1.2.1 and, upon trying to build this, found out that it then needs newer versions of Automake and Autoconf. Actually, it requires Autoconf 2.13 and, perfectly, we only had 2.12 from the CD-ROM! One point makes a difference, eh? Linux from scratch has a great tutorial here for autoconf, so I just followed the instructions and installed very easily.

tar -xzvf autoconf-2.13.tar.gz
cd autoconf-2.13
./configure --prefix=/usr
make
make install

automake 1.4-p6 was then built and installed (same process as above, but with a different archive and folder name)... and now SDL would behave.

SDL 1.2.1

SDL was actually very straight-forward, once I knew what I was doing. I actually initially started down a path of upgrading the compiler and libc, but then quickly decided that it was a dependency-can-of-worms and just left everything as 'stock' as possible. So, back to SDL, downloaded 1.2.1 from here, extract it and try to configure it. Actually, you can't, you need to call autogen.sh first...

./autogen.sh

With the above auto* tools installed, autogen will sit quietly for a few minutes and then tell you that you're ready to run configure...

./configure

This completed cleaning, so now we just make...

make

This then took hours... and eventually failed! There was a very obvious error: the installed version of RedHat 2.0 (I mean, TurboLinux 1.1) does not have a linux/joystick.h header file! What to do/guess?

./configure --disable-joystick

It didn't complain, and rebuilt the Makefiles... including those in the src/joystick folder... bad sign? Let's quickly build that and see what happens...

cd src/joystick
make

It compiled fine! Seems that it still needs to create a 'don't make anything' Makefile in there. Also, you could see a new GCC arg of -DDISABLE_JOYSTICK, so my fluke worked perfectly. Anyway, let's go back and re-build.

cd ..
make

The build continued... And finished! What next?

make install

This also succeeded, with a few warning through it, and a bit of doco which zoomed past, not allowing me to scroll back up! Regardless, the following is used when configuring:

which sdl-config
/usr/local/bin/sdl-config

Nice! But actually, it wasn't... I'd later find out that half of the source was still expecting joysticks and that I should've performed a make clean when I re-configure'd! Also, the SDL bits and bobs landed in the /usr/local folder... not optimal on this system, so at the very start, if you're playing at home, use this configure line instead:

./configure --disable-joystick --prefix=/usr

And then OTTD will build! Or so we hope...

OpenTTD 0.1.4

The source was extracted and I started by trying to configure:

# ./configure
error: permission denied
# chmod a+x configure
# ./configure
: bad option

Actually inspecting the configure script just shows it replacing the SDL variables in a JamFile? Uh oh... not a Makefile... we don't have Jam on here! There's also a Makefile, does that work?

# make
...
Makefile:113: window.d: No such file or directory
...

Eh? Started building OTTD and it was quickly apparent that it hated the Makefile. I started creating a new version, and things were working, so I looked at the old one again and realised the line-endings were incorrect! Make sure your Makefile has just \n and not windows endings! Kicking it off again, all was working fine, until it got to minilzo.c/.h.

minilzo.c:249: Invalid token in expression

This file is sprinkled with multi-line \'d source and gcc simply hates it all... so it had to all be collapsed.

#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
		(m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)

#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
	(BOUNDS_CHECKING_OFF_IN_EXPR( \
		(PTR_LT(m_pos,in) || \
		 (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
		  m_off > max_offset) ))

All those slashes weren't allowed... so a quick find/replace in Notepad++ of '\\n' to '' worked a treat. lzoconf.h also had a few... but, with these all collapsed...

unix.c:10: sys/statvfs.h: No such file or directory

Indeed, the file didn't exist! But, statfs.h did, so I did a quick rename! And well, it built! And failed when I ran it as english.lng was missing. Usually you'd build the strings, but I stole the file plus the other required GRFs from my standard TTDX Data Archive.. that was always kept near for emergencies such as this!

DSC01038

And it loaded! Slow, chuggy and crashy with lots of frameskip warning shown in the console. Actually, the whole thing would segfault when I tried to move the window on the screen. From here, I'm happy to have achieved this much, but I'm not going to polish it. Instead, it's time to test a newer version of Linux.

Filed under: Apple No Comments
15Oct/200

TurboLinux 1.1 on a PowerCenter 180

I've been meaning to try this for a long time, after getting BeOS to work on the PowerCenter. Actually, I now realise I haven't even posted about that... I promise to do that later. Anyway, I'd recently been scouring the vintage column on eBay and trundled across a beautiful jewel-cased 2-CD version of TurboLinux 1.1 for PowerPC (original site). There was absolutely no one bidding on it, so I took that and a camera for a Raspberry Pi, of which I'll tinker with later.

DSC00927

DSC00930 DSC00936 DSC01036

For those who want a copy of the ISOs, I've dumped them via the instructions here. Of course, if you're inside TurboLinux (Inception?) then you can't use isoinfo as it doesn't exist. Instead, I loaded into Mac OS 9 and loaded up Adaptec Toast to get the data. Actually, I loaded up Toast to make a toast-formatted ISO. But instead, toast just 'stopped' when I asked it to save a disc image. Either way, dd worked with the parameters that Toast provided and I even managed to use a burnt copy to run the final install... how else to test?

CD Images and somesuch...

A note on the images above, they were built with dd on ppc linux (TurboLinux 1.1 at that!) and they failed to burn with PowerISO. Somehow ImgBurn succeeded.

To get this up-and-running, I needed to put my PowerCenter 180 back together. I'd recently scavenged a few parts to get the AV Power Mac 6400 running (oh crap, that's another post that never happened) and so slapped RAM back in this machine and a second spare 50-pin SCSI drive.

Note that there's already some great tutorials online. This LinuxPPC Installation Guide by Jérôme Cornet helped me tremendously.

Preparing the SCSI drive

I could've/should've changed the order of this post... but for those playing at home who just want to get this installed and working, you'll want to set up your drive correctly first! When I was first tinkering, I happened to do it in the reverse order: slap the drive in and start the Linux install... I don't recommend this as the partitioning tool doesn't really like 'weird' disks. I had issues when trying to re-write the partition tables on PC formatted drives, to the point where some would prevent the machine from even booting.

To get started, you'll need a totally separate SCSI HDD from your Macintosh install (if you have one) to get TurboLinux going in a PowerCenter. On my specific machine, the OpenFirmware boot screen stays black, so I actually don't know if there are options there, or if the quik bootloader (installed at the end of the process) actually work. If they do, then you may be able to get away with one HDD, if the bootloader let's you back into Mac OS. Or maybe Boot-X will work, I'll test that at the end of the article.

Anyway, I grabbed a spare Seagate 2.1gb drive and installed it as SCSI ID 0. I then downloaded FWB Hard Disk Toolkit 4.5.2 and formatted it. Finally, the drive was partitioned with one 2gb root partition and one swap partition. I found that there are errors if the root partition is over 2gb, so please make it no larger. Note that you cannot use the LinuxPPC partition type. I tried this first and TurboLinux will just tell you that your drive isn't prepared. Instead, you have to choose custom and then type in Apple_UNIX_SVR2 as the partition type, for your swap partition also! The installer then distinguishes the partition by name, so make sure, as above, you call them root and swap!

Picture 18 Picture 19 Picture 20

Picture 21 Picture 22 Picture 42

Picture 43 Picture 44 Picture 45

Picture 47

Note that I didn't low-level format the drive the first time and managed to muck up the whole drive when attempting my first install. This was because I'd created a 4gb root partition and the system reported that it was out of space!? I then used pdisk in the installer and somehow whacked the drive to the point where it started reporting that it was only 1gb in size. Because of all this, I can only recommend that you simply start fresh with a low-level-formatted clean disk.

Grab your Linux CD

TurboLinux requires a 1.44mb floppy to boot the installer. Make sure you have a clean Macintosh-formatted floppy available. Note that during the install, it managed to fail when copying installer.coff file over to the floppy. I Ok'd out of the error and just copied the file manually. In hindsight, you should eject the floppy now! I then re-ran the installer, skipping the copy-to-floppy, and it turns out the final step afterwards is 'double-clicking' on the Install Linux icon that it's put on the desktop...

Picture 2

Picture 3 Picture 4 Picture 5

Picture 6 Picture 7 Picture 8

Picture 9 Picture 10 Picture 11

Picture 12 Picture 13 Picture 14

Picture 15 Picture 16 Picture 17

So, that Install Linux icon just loads up a preset into the Boot Variables control panel. This was installed by the TurboLinux installer and is just a GUI to manipulate OpenFirmware's settings. The preset it loads is to boot installer.coff file from the floppy drive. Double-click the link on the desktop and then choose Write & Reboot. It'll ask if you're ready to reboot. Eject the floppy now (if you haven't followed the above advice) and hit Yes. As soon as you press the button, slap that floppy disk back in. I took my time to do this the first time and got nothing but a black screen! Turns out my machine was sitting at the OpenFirmware prompt, but I couldn't see it and had no idea what was going on. At this point, as that I hadn't ejected the floppy, it got ejected as part of the reboot process (without me noticing), and OpenFirmware just baulked at a command to boot from a floppy disk when there was nothing in the drive.

What to do? Either reboot again with the disk in the drive, or just slap the disk back in, blindly type boot and hit enter.

Nostalgique RedHat 2.0 (I mean TurboLinux) Installation Process!

If you've made it this far, then you're doing well! My gosh... I remember sitting on the floor of a friend's house (Hi Nathan!) back in maybe 1997 installing RedHat 5.x and running through these screens. Back then the IP configuration confused the crap outta me... doesn't this come with a DHCP client? Anyway, this time around it was entirely painless... just follow the usual prompts...

DSC00943

DSC00945 DSC00946 DSC00949

DSC00950

Next up, partitioning! Make sure to highlight the correct SCSI device in the top list... use the tab key to get up there and select with up/down arrows.

DSC00952

If you skipped the partitioning step above, then you'll need to hit Edit and follow the next block. If you have already partitioned your disk, then hit Done and skip it with gleeeeeee...!

Partitioning with pdisk

Yeah, not fdisk, pdisk! Note that fdisk is also on the distro, but pdisk is a wrapper for PowerPC-style partitioning which knows how to create Apple Partition Maps.

If you've really keen to do it this way, then I'll assume that the installer has listed your drive and you've tabbed over and chosen Edit. From here, you're thrown to a console prompt at the bottom of the screen and you'll need to navigate pdisk carefully. Please make sure to chose the correct partition first, before hitting Edit!

DSC00835

Disregard that it tells you you've chosen one device in the /dev folder and that its actually loaded the same device from the /tmp folder. This is just the way it seems to work and you'll need to find the device in /tmp later if you want to switch to another console and hack behind-the-scenes.

Anyway, pdisk accepts most of the fdisk commands, such as p to list the partition table. If you want to mangle it yourself, then use d # to delete individual partitions or i to completely re-write the partition map and start fresh.

Once you've got space to create your root and swap partitions, you'll want to use the command c to create them. If you're feeling professional, then split everything up into usr/home/root into partitions (this stops one of them from stealing all of the disk space from another and causing system failure). But, if you're lazy like me, then you only need to create a 64mb swap partition and then another partition for root, filling up the rest of the drive.

The basic structure to create a partition is as follows:

c 2p 64m swap

The command above will create a 64mb partition with the name swap at position 2. You can then type p and hit enter to see the new listing. Specifically you can see how much space is left on the disk. I had 1.9g available, so I then created root:

c 3p 1900m root

As opposed to fdisk, you don't need to specify the partition types here. You just need to name them accordingly: swap for swap, root for root. After creating the root partition, I went ahead and checked out the table via the command: p.I was happy with it and wrote the changes to disk via w. Finally, q took me back to the installer and tabbing in a loop back to OK allowed me to proceed to the formatting stage.

Formatting and Package Selection

From here, if you haven't low-level formatted your drive, then I'd recommend bad-block checking on both formatting runs.

DSC00955 DSC00956 DSC00959

DSC00960

You'll then be asked the packages you want to install. Choose what you feel is relevant. You can always mount the CD-ROM at a later stage and individually install RPMS at a later date.

DSC00961

If you've chosen a miriad of groups, then there might be dependencies that need to be installed... please consider and then accept... otherwise your packages will fail to install.

DSC00963 DSC00964 DSC00966

DSC00970

The install will then make the filesystem on the root partition and install the selected packages. If you selected Everything, then expect the following errors during installaion! The packages seem to be corrupt on both the original CD and my copy!

DSC01026 DSC01027 DSC01029

DSC01030

DSC01031 DSC01034 DSC01035

Aww... no Mahjongg!? Note that the packages aren't really important... the machine still worked fine afterwards.

DSC00972

DSC00973 DSC00975 DSC00977

DSC00978 DSC00979 DSC00980

DSC00981 DSC00984 DSC00986

DSC00989

Finally it'll ask a few questions about mice, networking, printers and boot parameters. You really should take a photo of the final window to record the boot-device and boot-file settings required for OpenFirmware!

Once all is done, the machine will reboot, ejecting the floppy. I'd installed TurboLinux around 6 times by the time I'd gotten to this part of writing this article and every-so-often one wouldn't boot at this point... the machine would restart, chime and hang at a black screen. I had to use the magic 4-finger-salute: Option+Command+P+R to get back to Mac OS and then re-enter the boot params from the final step of the installation process back into the Boot Variables control panel and Write & Reboot. It would then boot without fail!

TurboLinux is starting for the first time...

Shit, it booted! But I got a lot of crappy errors in the boot log.. which zoomed past and landed me at the boot prompt.

DSC00993

I logged in as root (as the installer didn't let me create any other users) and checked dmesg...

DSC00886

Not good.. seems that anything network-related just crashed?

DSC00995

Let's check X-Windows: startx got me to a very mustard-flavoured OpenStep desktop, but the Netscape icon from the launcher did nothing... I then tried netscape from xterm and got a segfault! Why is all network-related code throwing exceptions? Oh wait, I have two PCI cards installed in this system doing nothing. One is a 'bootable' Sonnet IDE card and another is a Kingston KNE100TX LAN card. Maybe TurboLinux can't work out if it should be using the onboard LAN or PCI LAN? Let's remove both cards...

DSC00888

A clean boot! I can even ping!

DSC00889

Netscape then even wanted to load... but got sad when it couldn't phone home. Poor thing... a few decades too late!

Screen Resolution

TurboLinux will use the resolution that you had Mac OS configured to. That value is store as a mode-number in PRAM and, unless you've reset it recently, should therefore display how you expect. If you want to override this, then choose a value from the list below...

#    1   512 x  386  60Hz (interlaced, NTSC)
#    2   512 x  386  60Hz
#    3   640 x  480  50Hz (interlaced, PAL)
#    4   640 x  480  60Hz (interlaced, NTSC)
#    5   640 x  480  60Hz
#    6   640 x  480  67Hz
#    7   640 x  870  75Hz (portrait)
#    8   768 x  576  50Hz (interlaced, PAL)
#    9   800 x  600  56Hz
#   10   800 x  600  60Hz
#   11   800 x  600  72Hz
#   12   800 x  600  75Hz
#   13   832 x  624  75Hz
#   14  1024 x  768  60Hz
#   15  1024 x  768  72Hz
#   16  1024 x  768  75Hz
#   17  1024 x  768  75Hz
#   18  1152 x  870  75Hz
#   19  1280 x  960  75Hz
#   20  1280 x 1024  75Hz

And replace the value '20' in the command below...

startx -- -mode 20

You'll then get the resolution you desire... as long as you have a monitor that supports what get's output. And maybe as long as you have the VRAM? This unit is decked out, so mode 20 worked fine. You can also pass -DEPTH with the value 8, 16 or 24.

Mounting HFS Extended Partitions

No-can-do out of the box! hfsutils can't mound HFS Extended partitions. Instead you'll just get the HFS shim with the Where_have_all_my_files_gone? file explaining that your data is still on the drive, but your current software is perfectly rubbish. I haven't found a solution to this yet... it seems that hfsprogs is open-source from Apple, but this OS may be way too old to compile it.

Getting back into Mac OS

There's a Linux tool called nvsetenv that will allow you to set the OpenFirmware boot-device setting inside Linux so that you can get back to MacOS on the next reboot:

nvsetenv boot-device "/AAPL,ROM"

Using BootX?

BootX (download it here) got installed whilst I was mucking around with Linux 1999 (mentioned below, and I'll write up a HOWTO on that also) during failed installs of TurboLinux. Just like BeOS, it throws a system extension in Mac OS with a symbol as the first character of its name to make it get loaded first. It then pops up a cute boot dialog to let you choose Mac OS or Linux with a configurable default. This is much nicer than the OpenFirmware prompt as it actually displays!

Unfortunately, there's an issue when you want to try and use it for TurboLinux. We'd need a vmlinux bootstrap kernel available for it to boot that matches the 2.1.x kernel in TurboLinux 1.1, otherwise there'll be a version mismatch. I tried all vmlinux files I could find on the CD; I even copied the exact file from the root partition... but BootX would just display a black screen each time I tried to boot it! Just for fun, I then used the 'Standard LinuxPPC' kernel with /dev/sda4 as the root and the bloody thing booted! But there was no sound and I had no idea what other damage might occur with a mismatched body vs. head.

So this is a really old version of Linux....

I went a'googlin and tried to find something newer, but there doesn't seem to be one! That site also doesn't have these ISOs, so I'll contribute those in due course. PowerISO on Win10 just threw a CRC error reading them? I might try Toast on the actual Mac. And then? Let's try LinuxPPC 1999 or LinuxPPC 2000.

But does it run OpenTTD?

There's no un-emulated version of A-Train to get running on here, so let's aim for OpenTTD. I've actually made this topic a new post as I nearly tripled the draft of this one with my moaning as to how hard it is to find a correct collection of libraries to build anything!

Filed under: Apple No Comments
27Sep/200

Smushing JSON into submission!

I don't even know how to describe this operation on JSON. The basic idea is that we want to deserialise a stream into something legible, without creating a class for each item in an array. json2csharp believes that each item should be an array since it sees them all as individually named classes. Let me prove it! Here's a chunk'o'data:

{
    "trainCount":122,
    "requestTimestamp":1601124556789,
    "responseTimestamp":1601128156789,
    "nextUrl":"https://junatkartalla-cal-prod.herokuapp.com/trains/1601128156789",
    "trains":{
        "8":{
			"id":"8",
			"from":"LR",
			"to":"HKI",
			"title":"IC8",
			"latitude":60.172097,
			"longitude":24.941249,
			"speed":0,
			"direction":0,
			"category":"IC",
			"status":"1",
			"delta":60,
			"trainType":"LONGDISTANCE",
			"updated":1601127783841,
			"action":"deleted"
        },
        "9":{
			"id":"9",
			"from":"HKI",
			"to":"LR",
			"title":"S9",
			"latitude":60.571148,
			"longitude":25.199523,
			"speed":0,
			"direction":0,
			"category":"S",
			"status":"1",
			"delta":60,
			"trainType":"LONGDISTANCE",
			"updated":1601128143878,
			"action":"modified"
        }
    }
}

So, if you slam that JSON into json2csharp, you'll get the following:

    public class 8    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public long updated { get; set; } 
        public string action { get; set; } 
    }

    public class 9    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public long updated { get; set; } 
        public string action { get; set; } 
    }

    public class Trains    {
        public 8 8 { get; set; } 
        public 9 9 { get; set; } 
    }

    public class Root    {
        public int trainCount { get; set; } 
        public long requestTimestamp { get; set; } 
        public long responseTimestamp { get; set; } 
        public string nextUrl { get; set; } 
        public Trains trains { get; set; } 
    }

So, that's actually uncompilable code. Is uncompilable a word? Dunno... this is actually the first time that json2csharp has failed me! No matter the options selected on the site, the output was always bad code... json2csharp doesn't work with ALL json! So, what to do? Well, we actually need to mangle this JSON into submission. The best bet would be to move that train id/number into the array object as a parameter, rather than having it as the dictionary key. We have two methods to do this...

Using jQuery MAP Function

If you are pulling JSON from a hosted browser, then you can run JS in the browsers console and produce cleaner JSON. In this case, you want to use jQuery's MAP function to rewrite each array object:

json_data.trains = $.map(json_data.trains, function (data, idx) { return data; });

If you feed the JSON at the top of this post into that function, you'll get the following:

{
	"trainCount": 122,
	"requestTimestamp": 1601124556789,
	"responseTimestamp": 1601128156789,
	"nextUrl": "https://junatkartalla-cal-prod.herokuapp.com/trains/1601128156789",
	"trains": [{
		"id": "8",
		"from": "LR",
		"to": "HKI",
		"title": "IC8",
		"latitude": 60.172097,
		"longitude": 24.941249,
		"speed": 0,
		"direction": 0,
		"category": "IC",
		"status": "1",
		"delta": 60,
		"trainType": "LONGDISTANCE",
		"updated": 1601127783841,
		"action": "deleted"
	}, {
		"id": "9",
		"from": "HKI",
		"to": "LR",
		"title": "S9",
		"latitude": 60.571148,
		"longitude": 25.199523,
		"speed": 0,
		"direction": 0,
		"category": "S",
		"status": "1",
		"delta": 60,
		"trainType": "LONGDISTANCE",
		"updated": 1601128143878,
		"action": "modified"
	}]
}

Very nice.

Using C# Regex

I've never thoroughly learnt Regex and it still makes me sad. One day I'll sit down and go through a course. For now, googlin' works nicely to find an example for this scenario. Effectively we want to remove the "NUM": and just leave the curly braces. We then also need to remove a curly brace at the end.

            var data = (new System.Net.WebClient()).DownloadString(nextUrl);
            data = new Regex("\"([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9])\":").Replace(data, "");
            data = data.Replace("\"trains\":{", "\"trains\":[");
            data = data.Replace("}}}", "}]}");

So, the first line downloads the data. The second uses Regex to find anything in double-quotes that's a number from 0-9. I actually wanted 0-9999, but it seems you need to match each character 1-by-1, so I gave it options with | (pipe) up to 99999. From there, the third line turns the trains object into an array and the final line closes that array with a square bracket instead of the existing curly brace.

Final C# Class Output

With either of the methods above, you end up with cleaned JSON. From here, slapping that back in json2csharp gets you the following:

    public class Train    {
        public string id { get; set; } 
        public string from { get; set; } 
        public string to { get; set; } 
        public string title { get; set; } 
        public double latitude { get; set; } 
        public double longitude { get; set; } 
        public int speed { get; set; } 
        public int direction { get; set; } 
        public string category { get; set; } 
        public string status { get; set; } 
        public int delta { get; set; } 
        public string trainType { get; set; } 
        public object updated { get; set; } 
        public string action { get; set; } 
    }

    public class Root    {
        public int trainCount { get; set; } 
        public long requestTimestamp { get; set; } 
        public long responseTimestamp { get; set; } 
        public string nextUrl { get; set; } 
        public List<Train> trains { get; set; } 
    }

Thank you json2charp, that's exactly the reusability that I was looking for!

26Sep/200

Repairing Atari 2600 Original Wireless Controllers

So, I've recently been repairing a large selection of Atari paraphenalia and, included in the container-load, was an official Atari-branded CX-42 wireless controller kit! The setup is pretty awesome; the base unit has a power input and then an output to go to the console. This means it doesn't need a separate power adapter as it chains into the power for your Atari. It then has the two controller plugs which you simply insert into the left and right controller ports on your console. Finally, the joysticks are more-or-less standard one-button Atari joysticks with extra 4cm bases to contain a 9v battery and radio circuitry.

DSC00668

DSC00674 DSC00671 DSC00698

Of course, this came to me due to being unhealthy. One of the controllers wouldn't go left! I'd usually associate this to cable failure, but... well... they don't really get much abuse in this scenario! They needed a good clean anyway, so the tear-down and diagnosis begun.

Is it the controller? (Hard way!)

So, just because I'd previously torn 100s of these apart, I went straight to the controller to check the internal switches. The construction of these is relatively simple, until you try to separate the joystick circuit board from the actual joystick... so many screws and springs fly everywhere. Regardless, once the unit was open, all switches were tested and found to be functional. I didn't think of taking a photo at the time, so you'll just have to imagine.

Is it the controller? (Easy way!)

After a little googlin', I stumbled across this hint stating that you could 'hear' the controllers using an FM radio. Hah, of course you can... It seems that they use frequencies down around ~40mhz, but somehow you can hear this at ~100mhz on your FM radio. So, what to do? Find an FM radio first. Fortunately I had some on the shelf thanks to wanting to listen to tapes a few months back.

On Windows 10, you'll find there's no more sndrec32. Instead you need to browse over here and Voice Recorder. Yey for anti-monopolistic effort! Anyway, I managed to record the following:

What you'll hear above is: Static -> radio station -> static -> radio station -> static -> weak carrier signal! -> misc. tuning -> STRONG CARRIER SIGNAL! -> 5 presses of the fire button -> ~7 full rotations of the joystick -> 6 presses of the fire button (the last one is longer) -> static. Totally random! But it's a great way to test.

As you can hear above, I started just above ~102mhz FM and scrolled down until I found the carrier signal. Note that I had difficulty originally finding the signal as it's not that strong. Make sure you hold the joystick against whatever FM receiver you're using.

Once the carrier signal was found, I then fine-tuned it until the signal was the strongest and began mashing buttons. Of course, just because LEFT is transmitting something, doesn't mean it's transmitting the correct signal! But hey, we can now check the base to see if there's any obvious issue.

Is it the base unit?

The circuitry inside this unit is, thankfully, quite easy to trace and diagnose. The unit consists of two individual circuits, decoding each controller independently. This is actually a life-saver, thanks to one of the joysticks being 100% functional! With my multimeter in-hand, I went ahead reviewing the circuit and measuring signals along the way. Doing this for both joysticks and both circuits meant that it was straight-forward to determine where the signal started going funny!

DSC00648

Starting from the output, there are two hex-inverter chips on each side. All 6 inverters (2chips x 3inverters) on each side are used and these flip the signal before sending it out to the controller port. The left button was seeing a twitch in the voltage, but not enough to flip the inverter to full +5v. The input was meant to drag to ground, sending the full signal out, but it wasn't happening.

Tracing the signal back, there is an OKI MSM4015RS IC and, for the life of me, I still can't find a datasheet online. I thought this would be a show-stopper, but after testing the signals on this IC for both joysticks when the fire button was pressed, it turns out they're both reporting the same values.

I therefore traced the value back up towards the output and found that the output after the first inverter wasn't being dragged low enough. It was 0.6v on the working joystick and 0.7v on the failing joystick. The output of the inverter is tied to ground with a green-cap and tied high with a 4.7k resistor.

The resistor checked out, but I had no way to test the capacitor with my multimeter. Instead, I swapped the capacitor from joystick one's side to joystick two's. Surprisingly, this now saw joystick one's LEFT button working and joystick two's was now faulty. Nice!

Replacing all green-caps

You'll find three different-valued sets of green-caps on this board: 10x 183k100v (18nf), 10x 223k100v (or 2A223K) (22nf) and 6x 104k100v (100nf). I went ahead and purchased a full set of them from Jaycar with the goal to replace every one of them.

DSC00677

Who knows how close another is to frying?

DSC00696

The aftermath... (did I say only the green-caps? Ooops.. I didn't discriminate and took out the electros as well.)

DSC00701

Removing and replacing was easy enough. I really recommend Goot-Wick desoldering braid for cleaning up the PCB whilst you're doing things like this.

Now up doesn't work?

Hah, seems that enough plugging-and-un-plugging of the controller output cables from the main board caused one pin to fail. Thanks to standard technology, there were plenty of these plugs in my junk box, although not with the same pin count...

DSC00687

So I borrowed an internal connector from a three-pin plug and soldered it in. Worked perfectly!

A minor note on the usage of these wireless controllers

With the wireless base unit powered-on and fully-connected to your Atari, it'll send spurious/erratic/totally-crazy signals to the console on the joystick cable of any joystick that is turned off! There is therefore a correct sequence for powering everything up... Turn the joysticks on first and then the base unit. Note that the base unit doesn't have a power switch, so I'd recommend always turning it off at the wall. I suppose you could then leave the Atari power switch on, as you'll be using the wall switch as the power cable is chained through the wireless controller receiver. Just make sure that both controllers are powered on BEFORE you turn on the wall switch!

When I was first diagnosing this kit, I thought all was pointless after seeing the random signals coming out of the base unit. I was very happy to see the signals settle once the joysticks were powered up!

Testing

This unit worked splendidly with 2600-series consoles and games.

DSC00708

Even 2600 games in a 7800 console. What didn't work was the built-in asteroids for/on the 7800.

DSC00712

For some reason, the down and fire buttons won't work. Of course, a standard 1-button Atari 2600 joystick works fine on 7800-Asteroids, but this unit doesn't. I did a little digging and found that the pins aren't brought straight to ground... instead they hover around 150-250 ohms... I wonder if that's enough to not send through a proper button press? Also, they seem to 'repeat'... the multimeter actually goes pretty damn crazy when a button is pressed, beeping on and off as the resistance floats near-zero. As mentioned above, each output is tied high by a 4.7k resistor and low by a 22nf green-cap capacitor. I assume the cap is there to de-bounce the incoming signal, but maybe it's not big enough to trigger a single press for the 7800? I don't want to modify this unit as it's very original, so I'll just suggest that if anyone else wants to use this on a 7800 then they should tinker with the pull-down capacitors on the output lines.

Again, they worked 100% perfectly with all 2600-series equipment I tested.

Battery Cover

One was missing, so I used my Creality CR6-SE to bring a replacement. It didn't turn out toooooo bad. Works well when there's a battery inside... falls out when there's no battery!

DSC00715 DSC00716 DSC00718

DSC00722

Filed under: Retro No Comments
16Sep/204

I’m not original…

In fact, my new best friend is over 16 years old!

DSC00644

I ... thiiiiink ... he's half deaf... might be time to replace his ears.

12Sep/200

EZIO + OS9 + Hypercard (Or Just Windows)

The EZIO Board is a serial-based I/O module that can connect to both Windows and Macintosh machines. Actually, it can connect to anything that speaks RS-232. One of these came up on eBay recently and I couldn't resist. I saw the Macintosh serial port and decided to give it a go. It's really similar to an Arduino, but from a few decades before the Arduino was even a dream. If I'd known about these back in the early 2000s then I would've definitely had a very nice automated model railway. But alas, I only happen to find one now thanks to eBay!

DSC00616

The unit has 10 digital output lines, 10 digital input lines, 8 analog-to-digital lines and two PWM lines. You then get 4 +5v terminals and 4 GND terminals. There's a PIC microcontroller in the middle running the show and a MAX232 for the RS-232 comms. The unit has a DC-rectifier, so you can feed it 5-15v either AC or DC. The 5-15v is literally the operating recommendations of the 7805 voltage regulator on-board.

There's a whole lot of code on the old site (yeah, you have to use web archive to get to it), but it's mainly for Director!? and Macintosh. Hilariously, the Macintosh example uses Hypercard! Before booting up the Power Mac, I instead wrote a quick bit of C# to test out the unit.

ezio-test-app

The shot above uses dotnet-ncurses, allowing the console to act like a canvas. It's really nice to be able to draw text to specific areas, rather than scrolling the screen. Anyway, the basic idea is that you can control the digital out and then everything else is read in. Interestingly, floating pins show some very random values... so if you're using this device, make sure you tie everything to ground or use pull-up resistors where appropriate.

Of course, the whole reason I bought this was due to the Macintosh serial port. I wasn't overly-energetic, so I tried a virtual Macintosh first...

ezio-basiliskii

After installing Hypercard, the app came up, but the performance once it started trying to interact with the serial port was terrible. It also just didn't work, so I gave up and booted up the Power Mac.

DSC00618

Yup, works a charm. Hypercard is pretty clunky, but I'm sure you could do a lot with it. I'll have to dig out the railway track and control a train!

5Sep/200

Philips CDI 450 – Laser Replacement

The Philips CD-i (Compact Disc-Interactive) brand/tech was released back in 1990 to add a level of interactivity to CD-ROM based entertainment. Philips, from 1990 through to 1998, produced and released multiple devices for both the home and educational markets based on this technology. One of those models was the CDI 450 and I just happened to stumble across one a long time back at a Belgian flea market. It's been in a box for quite a while and I've only just gotten around to looking at it... The driving factors were: #1 COVID lockdown is driving me crazy and #2 there's a version of The 7th Guest for this unit!

DSC00507

The unit came with the power supply, a controller with it's face missing and, randomly, a game CD in the drive.

DSC00513 DSC00510 DSC00509

The controller was obviously useless, so I went to GAME OVER? in Amsterdam and picked up the cheapest controller I could find.

DSC00586

There's the standard rule of 'sunk cost' where you don't spend large amounts of money on something that could be dead. I then returned to Australia and the unit has been in the box since. Only recently did I turn it on...

DSC00519 DSC00523 DSC00524

DSC00532

Cool! It works! My French is rusty, so I wanted to try and get other games working. No matter what I tried, the unit would not read CDRs. Every google search I tried lead me to believe that the laser was gone, or going, so I scoured eBay for a replacement. It turns out that searching for VAM-1201 will give you shops in China that have the exact 'new old stock' component that I needed! I ordered one, expecting it to take years, instead having it arrive in just under two weeks!

DSC00537

Popping open the CDI was easy enough. There are four screws in the unit. Two are in the CD bay and two are in the 'optional module area' to the left. Open the CD lid and then remove the plastic shell to the left. It has two clips that need to be pushed in. Woah, what's this? My unit has the Digital Video Cartridge!

DSC00538 DSC00540 DSC00542

With the screws out, you'll now find the RF shield in the way... remove this evenly, prying it up from each corner and making sure there are no wires in the way.

DSC00544

Mine had a lovely amount of discolouration... maybe from the rain that was falling in the flea market in Belgium? Fortunately the motherboard looked pristine.

DSC00547

The Laser aparatus consists of the laser unit and drive motor in a plastic housing, attached to a metal plate via rubber suspension joints. This whole component is held in place by the two screws from the main case and two plastic lugs along the top frame. Gently lift the whole lot, evenly pulling it up. The top two lugs are quite tight, to make sure to ease the unit vertically away from them until it's free. Once done, don't lift too high as you'll first need to disconnect the data ribbon cable and power cables underneath.

DSC00549

Once done, you then need to remove the laser unit from the metal plate. It's held there by four rubber spacers. Note that these are old now, so be very gentle when sliding them out laterally from the slots in the laser housing. I managed to break one when doing so, but fortunately this didn't impact the ability of the unit.

DSC00560

Once you've slotted the new laser on the housing, place it back into the main unit. This is as simple as lining up the lugs at the top, holding the unit at 45-degrees whilst doing so. Note that the wired cable might be longer than the original... just place the wires somewhere in the spacing to the bottom-right. Also make sure the wires don't get pinched when you place the RF shielding back in!

From here? We test...

DSC00562 DSC00563 DSC00564

DSC00565

DSC00567 DSC00569 DSC00571

DSC00572 DSC00573 DSC00574

And the icing on the cake:

DSC00582

A perfect game to test out the DVC! It worked very very nicely.

Filed under: Retro No Comments
1Sep/200

Atari 2600 Jr – Reset/Select Switch Repairs

I've recently come across an Atari 2600 Jrs with faulty select and reset buttons. Turns out that the mylar strip that conducts the button presses to the motherboard is toast. It doesn't conduct anything at all and I can't work out exactly where the break is.

DSC00424

To test if the button area even works, you can insert wires as above and check for continuity. In this case, they did, so I considered the following options to repair them.

Silver Conductive Pen

This nearly worked, but I couldn't get the paste to set correctly. The pen is from Jaycar and the basic idea is to draw a line where you want the circuit and let it set. I drew some pretty bad lines on the plastic film, but my first attempt seems to have failed as I drew the tracks too thickly. The 'ink' only becomes conductive once it's totally dry and I'm blaming winter and the fact that I don't have an incandescent bulb in the house anymore.

DSC00428 DSC00431 DSC00432

The next attempts were seemingly too thin. It also seems that you can't 'restart' a trace... the joint isn't conductive? Finally, the resistance seen down the track is totally erratic... but that may also be due to wet ink.

Threaded Wire

I punched a few holes in the mylar and threaded copper wire through. It was a little too stiff but, once in-place, seemed to work quite well! The main issue with this method is that, at either end of the plastic strip, adhering the wire to the conductive trace is difficult. Of course, at the motherboard end you can just jam the wires in the socket!

DSC00436

At the button end, you need to slip it in under the top-layer of plastic. I didn't feel confident that I could keep a valid joint and therefore didn't pursue this technique.

Microswitches

Prior to opening and testing the methods above, I was always intending on just replacing whole plastic strip with microswitches. There's a nice plastic base behind the push buttons and one could easily drill in some switches. This would also give a nice tactile experience to what is (from the factory) a really awful and mushy button press.

DSC00444

I went ahead and drilled holes slightly smaller than the switches. From here, I gouged out the rest of the required space as I wanted a tight fit. Of course, I was imagining things thinking that I tight fit would be enough to hold the switches in place... a hard button-press would probably send them into the case.

DSC00449 DSC00451 DSC00458

Therefore I glued a strip of plastic (yeah, it's a cable-tie) along the back of the holes as a backing plate for the switches. This worked perfectly! I probably should've soldered the wiring first, but it was each enough once the switches were in position!

DSC00467

Once it was all back together, it turns out that the buttons were pressed in 100% of the time. To fix this, I had to drill out a section of the plastic where the button meets the switch. This worked nicely. I then decided to remove the rubber as the press was being overly-softened by it. I'd recommend you test it both ways to see which feels the best... you can also try mounting the rubber on the actual case to make sure the alignment is correct.

DSC00481 DSC00478 DSC00486

From here, I just soldered the wiring up to a standard pin-header which fit snugly into the socket on the motherboard.

DSC00487

Testing began and the switches performed perfectly!

Filed under: Retro No Comments
6Aug/200

Fluke Multimeter Repair – Elastometric Strips

What what? I'd had this Fluke Multimeter sitting broken in my box'o'junk for literal decades. It used to work great, but failed at some point a long time ago and was never fixed. Recently, I snapped the cable off a shitty AUD$10 multimeter that I'd been using and so, in my infinite wisdom, thought I'd resurrect the Fluke!

DSC00395

It turned on, but the buttons didn't work.. so it wasn't much good except for the default setting of DC voltage. Testing voltages takes up 50% of my time, but I still need resistance and continuity! Let's rip it open...

DSC00397 DSC00403 DSC00405

So, not shown above (since I'd already fixed it and this post is months old) is that the strips of weird rubber weren't both there. The top strip was, but it turns out there's a lower strip needed. I had probably replaced the battery back in the day and somehow managed to discard the strip that conducts the button presses.

DSC00410

That's where it was meant to go. You can sorta see there's 5-ish segments on the PCB down in the channel, but there's a beautiful air-gap between that PCB and the mainboard. What's meant to go in the middle? I popped out the strip at the top and I, telling the truth, had no idea what the material was. A little bit of googlin' allowed me to realise that it was elastometric strip! Andy's Surplus came to the rescue and quickly delivered two cuttable strips of elastometricity!

Cut.. cut again...

DSC00415

And cut once more and ... TADA!

DSC00417

It works. And whilst the beast is open, replace the battery and solder that battery terminal!

DSC00409

Damn this thing is beautiful.