Attila Sukosd's blog

Browsing the web on an Amstrad CPC664 —

I’ve been an eager reader of hackaday.com and a while ago they have introduced this challenge to browser their retro site (retro.hackaday.com) from old machines. I thought about doing it back when they announced it, but as it is with everything, life always gets in the way. However, now that we have autumn holidays at the university, and there are no emergency projects to take care of, I thought it couldn’t hurt to spend a couple of hours hacking something together :)

 

I have been collecting old hardware (as you can probably see from some of the older posts), and in this collection the two oldest pieces I have is a 386 laptop with 6 MB of ram, and the Schneider CPC664 (aka. Amstrad CPC664). At first, I thought I would get the laptop running, as it would probably be the easiest… Just whip up a small Linux on the 2.5″ IDE disk, set up SLIP or PPP for a connection, and I would be browsing away happily with lynx or elinks, however, it turned out that while the machine booted up fine (couple of memory problems on the way, but oh well) the HDD in it was dead, and the IDE ribbon cable was also broken. After sourcing an other HDD (this time from a much newer laptop), and fixing the cable, it turned out that most likely the newer drive draws too much power, as it would start spinning up and cut out in the middle of the spinup. Lacking a working floppy drive and harddrive, I turned to the other much much cooler machine.

The story behind this Schneider CPC664 (as has been told by my mom) is that back in the mid-1980s (roughly 5 years before I was even born), my parents were working at a university in (western) Germany, where they got the machine in return their help in fixing some disk/filesystem problems for a computer retailer. Computers like this were very rare in Hungary back then, and it had to be smuggled into the country. They had been using it for their scientific work for a number of years, and I have some faint memories of playing chess on it, and writing (with the help of my parents) a program that could display my weekly schedule in primary school. ( I believe this was around mid-1990s, at that point my parents have upgraded to much newer hardware, and I got this one as a toy ) By the time I was old enough to start coding, I’ve also got a 386, and the CPC664 was packed up and stored in the basement. After surviving another decade, the close to 30 year old machine still works!

After figuring out what to plug where, and sourcing an old TV, machine powers up, the “in function” LED lights up, and magical words appear on the TV:

However, when I was trying to type something, only a couple of buttons worked, the others didn’t do anything. Not good. Time to take it appart:

Opening it up revealed that most likely the flat cable connecting the keyboard to the motherboard got loose (and the connector oxidized a bit), so after cleaning it off and plugging it back in, it worked. Easy enough :)   It was also a good excuse to look at what’s inside:

Btw, for those who might not be familiar with the CPC664, it houses a Zilog Z80 CPU running at 4Mhz and 64kByte of external RAM. It is capable of driving the screen at 160×200, 320×200 and 640×200 (thought this last mode is barely readable on the TV). It used to come with it’s own screen with a proprietary video connector, however it should be possible to interface it to regular tvs with SCART. I haven’t tried this, as my parents have built a separate device capable of converting the video from the machine into an RF TV signal, so it was possible to use it with regular TVs back in the days. It also has a 3″ floppy drive, which is I believe was a similar technology to the the 3.5″ we all know so well.. (I guess it was the HDDVD/Bluray war, but with floppies) Unfortunately I don’t have any of those old floppy disks anymore, or the tape drive, so everything needs to be typed. As an extension, it exposes a 16bit address bus and the 8bit data bus, which can be used for loading code from external ROMs, or in my case, a memory mapped RS232 serial.

After fiddling with PSUs, and serial connections etc, I finally ended up with a working setup. The CPC664 could communicate with my laptop, although at 300bps, it still worked. Then I was faced with the option on how to display the site, here I had a couple of possibilities:

  • Implement some sort of TCP/IP network over serial on the CPC => out of the scope of this project
  • Implement a serial HTTP proxy and process the HTTP on the CPC
  • Do the HTTP processing on the laptop and only send the text to the CPC to display as a dumb terminal

After pondering a bit about it, I ended up with a hybrid solution, which looks somewhat like this:

1. Python script running on the laptop, opens up a serial connection to the CPC, and prompts the user to enter the url, and dumps the raw html through the serial

2. 30 lines of Locomotive BASIC, which handles both serial in/out, and strips the tags from the received data.

 

So here is the result, Retro Hack a Day on the CPC664 (Inpatient ones skip to 5m30s):

Source to the BASIC script: serialbrowser.bas

Source to the Python HTTP/serial proxy: term.py

And a couple of more pics:

 


XBMC MMS streaming fix —

So, today I wanted to add some online (mms) TV streams to our media center running XBMC, however it turns out that XBMC-Live comes with an old version of libmms, which refused to play back the stream…
So I ended up downloading the latest version (0.6.2) from sourceforge (libmms.sf.net), compile and install it into /usr/local, and finally add an LD_PRELOAD_PATH to /usr/bin/runXBMC (line 52 in my case) to prefer /usr/local/lib before the system libs, thus making xbmc use it first. After restarting xbmc, voila, the streams played fine without issues :)

So the steps were:

1. apt-get install libglib2.0-dev

2. wget http://downloads.sourceforge.net/project/libmms/libmms/0.6.2/libmms-0.6.2.tar.gz

3. tar xfvz libmms-0.6.2.tar.gz

4. cd libmms-0.6.2/ && ./configure && make && make install

5. Modify /usr/bin/runXBMC line 52 from:

echo “/usr/bin/xbmc –standalone” >>  /home/$xbmcUser/.xsession

to

echo “LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/lib /usr/bin/xbmc –standalone” >>  /home/$xbmcUser/.xsession

6. Restart XBMC

 

 

Just thought I’ll post in case it’s useful for someone…

Once I have some free time, I’ll post some more about some of my other ongoing projects, but just as a teaser, it includes tvheadend, heyu, arduinos, a bunch of OSS and some cheap hardware ;)

 


Reusing an old game port steering wheel —

Introduction

Well, I have this bad habit of holding on to everything, so as you can imagine, I have quite a few old stuff lurking around. One of these was this good old thurstmaster formula 1 racing wheel, which served me well back in the days, but is now completely useless as modern PCs have no game ports.

Gameport? What is that?

The game port was a traditional connector for video game input devices back in the day, usually integrated on the sound card. Since USB has taken over for almost all devices out there, the game port has pretty much vanished from the game controller industry. This is indicated clearly by even Microsoft discontinuing game port support from Windows Vista.

It featured a number of analog (converted into digital with an ADC [analog digital converter on the sound card]) and digital signals, which were usually driven by potentiometers and switches. This allowed for 4 digital buttons, and 4 analog axis, which could be used in one joystick, or two with an appropriate splitter cable. (More at: http://en.wikipedia.org/wiki/Game_port)

Thrustmaster Formula 1 Steering Wheel

The steering wheel contains two buttons on the wheel itself, a stick shift with up and down (respectively two more buttons), and an accelerator and brake pedals. The steering wheel and the pedals are the analog signals, using the supplied Vcc and GND to return a voltage corresponding to the position of the wheel. After measuring the signals with a volt meter, the readings did not seem to vary a lot, so putting in an extra resistor on the two analog lines (acting as a voltage divider) allowed for some better measurements.

Arduino

Even though I have been doing some microcontroller programming the last couple of years, I have only recently discovered the Arduino. It seems like a hot topic nowadays, and it turns out it can be pretty useful in certain situations. The aim of the device is to provide everyone a relatively easy start into the microcontroller world, and yet it still manages to keep the flexibility to do advanced stuff too (such as in line assembly or direct register manipulations). It provides some very convenient libraries to prototype projects fast, without having to deal with very low level issues such as timers/interrupt service routines and such.  (More at: http://www.arduino.cc/)

The Project

To give a better idea on how the project is built up, here is an overview:

The first step in the process is that the joystick needs to be calibrated. Why? Because every analog joystick is a bit different, which means returns a different range of values for the same position. Moreover, due to mechanical wear, this calibration process needs to be redone every now and then too.

During the calibration process, the two analog axis need to be moved to their furthest possible locations in order to find out the minimum and maximum positions, as well as their center. The center is also important, because there are cases where the center is NOT in the middle of the maximum-minimum location, and in that case the joystick would constantly “turn left” (or right in the case of a steering wheel), or accelerate/brake without pressing the pedals.

So to return meaningful and uniform values from any kind of joystick, the decision was made that it will return the location of each axis in percentage, being 50% the neutral position. (The calculation on how the values were normalized can be found in the source code)

Once the values are read out of the joystick, a packet size of 7 bytes are sent over the serial line to the PC. These 7 bytes consist of the first byte indicating if the joystick has been calibrated or not, then the values for the X and Y axis, and the values for the four buttons. (This could be further optimized by modifying individual bits in a byte for both the calibration and the 4 buttons, but programming wise this was simpler and there aren’t any latency concerns to worry about)

On the PC side, a small C code is sitting and listening on the serial port for packets, once it receives them it does some post processing (inverting axis: I found out that apparently >50 is braking and < 50 is accelerating… would have thought the opposite…), and sends the received values to the PPJoy Virtual Joystick (http://ppjoy.blogspot.com/) over some IOCTLs.  PPJoy emulates a joystick device, which can then be used in any game which supports the standard joysticks.

And thats it! A few hours of hacking over the weekend, and the old steering wheel is back in action.

 

Sure I could have went out and bought a new USB steering wheel, or an existing game-port to USB  device, but where is the fun in that? The journey is just as important as the results right? ;)


ProxMox (OpenVZ) + Fog Project (v0.29) —

Alright, so at one of my works in my university, I am in charge of around 40 workstations with some very good hardware (i7, 6/12GB ram, Nvidia Quadro FX5800), and all of it should of course run Windows 7 to take advantage of the DX11 support etc.  In the previous years, the sysadmins before me were using Symantec Ghost to image all the machines, by running around and popping in a CD to every machine (back then ghost didnt support pxe boot)

Anyway, since I’m not a big fan of Windows or Symantec, I’ve decided to look for an opensource solution, and the nicest one I’ve found was http://fogproject.org. It has a pretty good web interface, and supports many things..

So recently, I’ve setup a ProxMox cluster of 2 32bit P4 machines (more on that in another post), which of course have no Intel-VT to run kvm guests, and since I’m planning to run linux on the server side mostly, OpenVZ serves the purpose with much less overhead anyway. Then I just created a new VM for Fog, downloaded the latest sources/installer, but then I realised it tries to use the kernel NFS server, which obviously won’t work since OpenVZ shares kernels with the host, so after looking at the source for 5 minutes, it turns out you only need to change 4 lines to replace nfs-kernel-server with unfs3, which runs in the user space:

lib/ubuntu/functions.sh (lines 108-110):

sysv-rc-conf nfs-kernel-server on >/dev/null 2>&1;
/etc/init.d/nfs-kernel-server stop >/dev/null 2>&1;
/etc/init.d/nfs-kernel-server start >/dev/null 2>&1;

To:

sysv-rc-conf unfs3 on >/dev/null 2>&1;
/etc/init.d/unfs3 stop >/dev/null 2>&1;
/etc/init.d/unfs3 start >/dev/null 2>&1;

And in lib/ubuntu/config.sh (lines 24,25):

packages=”apache2 php5 php5-gd php5-cli php5-mysql php5-curl mysql-server mysql-client dhcp3-server tftpd-hpa tftp-hpa nfs-kernel-server vsftpd net-tools wget xinetd  sysv-rc-conf tar gzip build-essential cpp gcc g++ m4 htmldoc perl libcrypt-passwdmd5-perl lftp openssh-server php-gettext clamav-freshclam”;
storageNodePackages=”apache2 php5 php5-cli php5-mysql php5-curl mysql-client nfs-kernel-server vsftpd net-tools wget xinetd sysv-rc-conf tar gzip build-essential cpp gcc g++ m4 lftp php-gettext”;
langPackages=”language-pack-it language-pack-en language-pack-zh-hans”;
dhcpname=”dhcp3-server”;

To:

packages=”apache2 php5 php5-gd php5-cli php5-mysql php5-curl mysql-server mysql-client dhcp3-server tftpd-hpa tftp-hpa unfs3 vsftpd net-tools wget xinetd  sysv-rc-conf tar gzip build-essential cpp gcc g++ m4 htmldoc perl libcrypt-passwdmd5-perl lftp openssh-server php-gettext clamav-freshclam”;
storageNodePackages=”apache2 php5 php5-cli php5-mysql php5-curl mysql-client unfs3 vsftpd net-tools wget xinetd sysv-rc-conf tar gzip build-essential cpp gcc g++ m4 lftp php-gettext”;
langPackages=”language-pack-it language-pack-en language-pack-zh-hans”;
dhcpname=”dhcp3-server”;

Then just run the installfog.sh in the bin directory, and you should be good to go!

I haven’t tested performance extensively yet, but it seems decent so far.