The Synchronizatron 3000

In advance of my appearance at the Ultrachip Festival in Edinburgh next month (19th-20th August! Two nights of awesomeness from the UK’s finest chiptune musicians! Free entry! W00t!), I thought this would be a good time to reveal the secret weapon at the heart of my live shows. Ladies and gentlemen, behold… the Synchronizatron 3000.

Out of all my projects, I like this one a lot. I like it because it brought me out of my comfort zone and into the murky world of hardware design (aided by the Arduino project which does a fine job of making that world accessible to electronics noobs like me). I also like it because it elegantly solves a problem that, in all likelihood, nobody in the world but me has. But most of all, I like it because it has a pair of blinky LEDs on the top which serve no meaningful purpose.

A couple of the songs in my set are played using two Spectrums together, to get an unthinkable 6 (SIX!) channels of sound. At AY Riders concerts in the past, we synchronised them through the low-tech method of having two of us with our fingers poised over the space bar while one of us counted us in. This method has two drawbacks: firstly, if the timing is even slightly out, it’s very noticeable. Secondly, different models of Spectrum have slightly different clock speeds, which causes them to slowly drift out of sync over the duration of the song. My two ‘performance’ Spectrums are an original 128+ and my Speccy2010, which are about as different as you can get – so that wasn’t going to cut it.

The job of the Synchronizatron 3000 is to provide a common external 50Hz clock signal for the two Spectrums to use, in place of their own timers. This signal gets fed in through whichever port happens to be convenient – for the Speccy2010, it’s the joystick port, which handily also provides a +5V line for powering the whole thing – and for the 128+, it’s the cassette (EAR) port. Using the cassette port adds another hurdle, because it’s designed to receive audio-frequency signals, so (presumably due to bandpass filters and other things I don’t understand) it won’t respond to simply flipping the signal high and low every 50th of a second – so instead, it rapidly alternates between generating an 8000Hz tone and silence. The code is really laughably simple:

void setup() {                
  // initialize the digital pin as an output.
  pinMode(13, OUTPUT); // clock signal
  pinMode(9, INPUT);   // on/off switch
  pinMode(10, OUTPUT); // off (red) LED
  pinMode(11, OUTPUT); // on (green) LED
}

void loop() {
  if (digitalRead(9)) {  // switched on
    digitalWrite(10, LOW);
    digitalWrite(11, HIGH);
    tone(13, 8000); // burst of high frequency
    delay(5);   // play it for 5ms
    noTone(13); // set signal off
    delay(15);  // wait for 15ms
  } else {  // switched off
    digitalWrite(10, HIGH);
    digitalWrite(11, LOW);
  }
}

The Z80 code on the Spectrum side to listen to those pulses goes something like this – it’s somewhat similar to what the Spectrum’s own tape loading routines do when listening for the end of a ‘beeeeeee’ in ‘beeeeeee bip! beeeeeee bipipipipi…’, except that here it gets done 50 times a second:

	call init_music
loop:
wait_low:
	call get_pulse      ; check for presence of a tone
	jr nz,wait_low      ; don't proceed until the tone has stopped
wait_high:
	call get_pulse      ; now wait for the tone to start up again
	jr z,wait_high      ; - don't proceed until we detect a pulse
	call play_music     ; play the next 'frame' of music -
	                    ; - we want to do this every 1/50s
	jr loop             ; repeat ad infinitum
	
get_pulse:
	in a,(254)          ; read the cassette port:
	and 0x40            ; - bit 6 of port 254
	ld d,a              ; save its initial value in d
	ld b,255            ; see if it changes over the next 255 iterations over this loop:
get_pulse_loop:
	in a,(254)          ; re-read the cassette port
	and 0x40
	cp d                ; compare with initial value
	ret nz              ; return (with zero flag reset) if there's been a change
	djnz get_pulse_loop
	ret                 ; return (with zero flag set) after 255 iterations with no change

Having successfully proved the concept with the full Arduino board, accompanying breadboard and rats-nest of wires, transferring the whole thing to a standalone circuit on stripboard was dead easy – even easier than the regular instructions for doing that, because the Speccy2010 joystick port already gives us a regulated 5V line that saves us from having to rig one up ourselves on the board.

(the stripboard schematic, with obligatory coffee stain)

Thanks to Oleg, Ben and the rest of the Oxford Hack Space crowd for their technical, organisational and moral support while cooking this up!

It all worked splendidly on the night in Eersel, and you’ll be able to witness it in action again if you come along to Ultrachip next month. Go on, you know you want to…

4 Responses to “The Synchronizatron 3000”

  1. Poopi says:

    Mat check this out. I’ve made a mod for SPeccy that supports Turbo Sound (2xAY)

    http://poopi-san.blogspot.com/2011/09/updated-speccy-2010.html

  2. rot says:

    Hey gasman, great stuff. I’m not sure if youre still checking this blog and if this is the best place to ask. I’m interested in building something like this to try and sync spectrum to other devices, for example LSDJ on a gameboy. Thanks so much for posting the z80 code, but I’m kinda a noob when it comes to spectrum stuff. I understand the bit you posted, but I was wondering what the play_music routine would actually look like?

    Finding documentation for this sorta stuff is kinda tricky. I’ve searched around for this but the only suitable program would be something like specAY, which i would have to dissassemble and cannibalise so that it waits for a pulse before every cycle? Maybe there is a more streamlined way to do this? Would you be able to point me towards a simple suitable ‘drop in’ commented player code? Like one that people use for demos…

  3. matt says:

    Hi rot – good to hear about more people playing around with this sort of stuff!

    Music trackers for the Spectrum will usually have an option to save your track with the player routine bundled with it, either as a single code block or a pair of code blocks to be loaded in together. For instance, Vortex Tracker (probably the most convenient tool for this, as it saves having to transfer things in and out of emulators…) has the option File -> Exports -> Save with ZX Spectrum player. (You could also look at my tracker2ay tool, if you’re starting from a .stc / .sqt / .pt3 file.)

    When you export your track in this way, you’ll be given the addresses of two entry points: an ‘init’ routine to be called before you start playing (and again at the end, to silence the AY chip) and a ‘play’ routine that needs to be called every 1/50 of a second. It’s these addresses that you would slot into the routine above as init_music and play_music.

    The .AY format as used by specAY also works off the same principle – Z80 code embedded in the file, with those two entry points – but I’d say it’s probably more trouble than it’s worth to pick the format apart.

  4. rot says:

    OK, wow thanks for the reply. That really helps to clarify things a bit. Think its just going to take a bit of time for me to get my head around how it all fits together. Just need to get my hands dirty in some z80 code. I’ll be sure to let you know if i get anywhere with this!

    Anyway, great work man. I think the spectrum deserves more appreciation, (outside of the demoscene) for sure.

Leave a Reply