Saturday, March 22, 2014

New blog, lots of 8-bit magic!

I just found out that there are still many people reading this blog even though I haven't published here for a long time. You may be interested in my current project: an 8-bit computer from scratch. In fact I've been working on this for quite some time now. If you are interested, you can find my new blog here:

Friday, February 3, 2012

Network SID Device Protocol

The Acid64 player supports playback of SID tunes via a network protocol which allows cycle-exact playback in emulators like the jsiddevice or on a real chip like in this project. I'm planning to support this protocol with the SIDboard (there will be a wrapper translating the network packages into commands that are sent via the serial port) and also within the FlowSID composer.

The main reason why I am writing this post is that I finally found a detailed description of the protocol in the jsidplay2 sources. I've extracted it for convenience:

Authors: Ken Händel, Antti S. Lankila, Wilfred Bos

JSIDPlay2 SID-emulation integration protocol. It is possible to have JSIDPlay2 take over the duty of the SID playback for a C64 emulator/player. Every jsidplay2 instance tries to open port 6581 where they will listen to connections that describe SID activity with the following protocol.


Version 2 of the protocol is structured as a request-response protocol:

  • Requests are variable length, with minimum packet size 4 bytes. There are 3 fields and an amorphous data blob:
    • 8-bit unsigned as command.
    • 8-bit unsigned as SID number.
    • 16-bit unsigned as length of data attached to header in bytes.
    • Data (if any)
  • All commands are ACKed with a response packet that takes one of the followingforms:
    • OK means that the commands were accepted by server and can be discarded by client. No data will be appended to response.
    • BUSY means that no part of the current command was accepted due to filled queue condition, and that client should wait and retry it later. 1 millisecond could be a suitable delay before retry. Queue length is limited both by number of events and maximum time drift between playback clock and client clock. No data will be attended to response.
    • READ: successful read operation, one byte value follows that is the value read from SID.
    • VERSION: response to VERSION operation. Version number will be appended to response.
    • COUNT: number of SIDs supported by network device.
    • INFO: info packet, which contains model code and zero-padded 20-byte UTF-8 encoded string representing model name.

Maximum packet length is 64k + header length. It is suggested that only short packets are transmitted, in the order of 1k and containing no more than about 1 ms worth of events. Otherwise the client-server desync brings jitter that may have unpleasant consequences. At the limit it's possible to simply send a fixed header that describes a single write with each packet, but this is probably measurably less efficient.


Structure of data is specific to command. Some commands require data, others will not use data even if such was provided. Some commands require specific lengths for the data packets. If data length is not correct, results are undefined.

Known commands are identified by small integers, starting from 0:

  • FLUSH (0): destroy queued data on all SIDs, and cease audio production.
    • sid number is ignored.
    • data packet must be 0 length.
    • should probably be followed by RESET (SID is in unpredictable state).
    • always returns OK
  • TRY_SET_SID_COUNT (1): set number of SID devices available for writing
    • sid number equals the count of SIDs wanted.
    • data packet must be 0 length.
    • returns BUSY until audio quiescent, otherwise OK.
  • MUTE (2): mute/unmute a voice on specified SID
    • data packet must contain two 8-bit unsigned bytes:
      • the voice number from 0 to 2
      • 0 or 1 to disable/enable voice
      • this command bypasses buffer and takes immediate effect.
    • always returns OK
  • TRY_RESET (3): reset all SIDs, setting volume to provided value.
    • data packet must be a 8-bit unsigned value which is written to volume register.
    • returns BUSY until audio quiescent, otherwise OK.
  • TRY_DELAY (4): inform emulation that no events have occured for a given count of cycles
    • data packet must be 16-bit unsigned value interpreted as delay in C64 clocks. 0 is not allowed.
    • allows audio generation in absence of other activity.
    • returns BUSY if there is already enough data for playback, otherwise OK.
  • TRY_WRITE (5): try to queue a number of write-to-sid events.
    • data packet must be 4*N bytes long, repeating this structure:
      • 16-bit unsigned value interpreted as delay before the write in C64 clocks. (Currently there seems to be a bug somewhere, probably in my software, that causes strange sounds (hanging bleeps, etc) unless the delay is placed after the write. However, Wilfred Bos, author of ACID64, assured me that the delay should be indeed before the write (which seems logical). I will post an update when I found out what's going on here.)
      • 8-bit unsigned SID register number from 0x00 to 0x1f.
      • 8-bit unsigned data value to write
    • returns BUSY if there is already enough data for playback, otherwise OK.
  • TRY_READ (6): reads SID chip register.
    • data packet must be a 4n+3 bytes long, where n >= 0. The protocol used for the first n packets is the same as the TRY_WRITE protocol, returning potentially BUSY if the delay implied by the READ, or the WRITEs can not yet be buffered.
    • Read packet structure trails the write packet structure:
      • 16-bit unsigned value interpreted as delay before the read in C64 clocks.
      • 8-bit unsigned SID register number from 0x00 to 0x1f.
    • returns BUSY if there is already enough data for playback, otherwise READ and a data byte, which is the read value from SID.
  • GET_VERSION (7): returns the version of the SID Network protocol.
    • sid number is ignored.
    • data packet must be 0 length.
    • returns 2 bytes: VERSION and a data byte, which is the version of the SID Network protocol.
  • SET_SAMPLING (8): set the resampling method for all SID devices.
    • sid number is ignored.
    • data packet is 1 byte long and contains:
      • 0 for pure decimator (low quality)
      • 1 for low-pass filtered decimator (high quality).
    • returns BUSY until audio quiescent, otherwise OK.
  • SET_CLOCKING (9): set the clock source speed for all SID devices.
    • sid number is ignored.
    • data packet is 1 byte long and contains:
      • 0 for PAL
      • 1 for NTSC
  • returns BUSY until audio quiescent, otherwise OK.
  • GET_CONFIG_COUNT (10): Query number of SID configurations supported by server.
  • sid number is ignored.
  • data packet is ignored and should be 0 length.
    • always returns COUNT and a 8-bit unsigned value that is 1 larger than the maximum valid configuration.
  • GET_CONFIG_INFO (11): query the name and model of the SID configuration.
    • data packet is ignored and should be 0 length.
    • returns INFO and 8-bit unsigned-value and a string in ISO-8859-1 encoding with a maximum of 255 characters excluding a null terminated byte
      • INFO code
      • Model: 0 = 6581, 1 = 8580
      • Model name (max. 255 chars + 1 null terminated byte)
  • SET_SID_POSITION (12): set sid position on the audio mix
    • data packet is 1 byte long and contains:
      • -100 to 0: audio is panned to left
      • 0 to 100: audio is panned to right
    • always returns OK.
  • SET_SID_LEVEL (13): set SID level adjustment in dB
    • data packet is 1 byte long and contains:
      • 8-bit signed dB adjustment in cB (centibels), 0 means no adjustment
    • always returns OK.
  • SET_SID_MODEL (14):
    • data packet is 1 byte long and contains:
      • 8-bit unsigned value between 0 <= value <= max_config-1
    • always returns OK.


  • Version 1 contains all commmands up to 7 (VERSION). There were 8 SID devices where bit 0 gave 6581/8580, bit 1 PAL/NTSC and bit 2 RESAMPLE/DECIMATE mode of operation.
  • Version 2 contains commands SAMPLING and CLOCKING. There are 4 different SIDdevices, 3x 6581 and 1x 8580. The commands SAMPLING and CLOCKING can be used to setparticular SID kind.


The delay values do not contain the time taken to write the value to SID chip, and a delay length of 0 between writes is impossible to achieve with a true C64 system, although this emulator will accept it and execute several writes on the same clock.

At start of connection, the SID starts from RESET state with volume=0 and empty buffer.

Suitable packet size for TRY_WRITE is about 20 ms long. If TRY_WRITE returns BUSY, then client should wait about 20 ms (same as the play length of one packet) before retry.

Future expansion:

  • stereo SID support
  • select filter type in dialog
  • route chips to left, right or mono.
  • implement protocol via UDP
  • combine read and write in one data packet

Saturday, January 28, 2012

The SIDboard

I've been working on a new hardware project. I had been successfully intefacing the SID soundchip last year. Now I'm building my own SID synthesizer. I know, there's the HardSID, Catweasel and many such projects on YouTube. However, this is for fun and for learning. This particular board will have the following features:
  • Support for up to 4 SID chips
  • Support for both, the old (6581) and new (8580) SID in all slots.
  • Jumper-selectable filter configuration
  • Serial Interface (including RTS/CTS flow control)
  • Full MIDI interface (IN, THRU and OUT)
  • 3 x 16 character LCD
  • Real Time Clock
  • Extension Port

I've already designed a PCB. I couldn't fit it all on a single PCB so I split it into two boards that will be put on top of each other like a sandwich. This helps to separate digital and analog circuitry and keeps the bus lines short.

Friday, June 3, 2011

Video: Making PCBs with solder resist

Ever wanted to make PCBs that look like the real thing and are easy to solder, even with SMD parts? With green solder resist and all? I'ts possible! Here's what you need:

  • UV lamp
  • PCB base material with photoresist
  • Transparencies for printing your layout (and a printer of course)
  • Sodium Hydroxide (NaOH)
  • Sodium Persulfate (Na2S2O8) or your favorite PCB etchant
  • Hot roll laminator with hot and cold settings
  • Dynamask or similar solder resist laminate
  • Sodium Carbonate (Na2CO3)
  • A soft brush (you could also use your fingers)
  • Containers for the chemicals
  • Timer or stopwatch
And here's how to do it:

Wednesday, May 11, 2011

Video: My Workshop

Here is a Video of my new workshop, my workbench and some tools:

You might ask what the hole in the middle is for. I am going to place a garbage bag right under it so I can easily keep my workspace clean.

Friday, May 6, 2011


For the record (no one seems to read this anyways):
  • I managed to produce high-resolution double-sided PCBs with solder resist mask.
  • The Pill Reminder got a redesign using SMD parts and the hardware has been built. The PCB fits behind the pill box now.
  • I got a workshop and therefore more space. Currently I am building a workbench. The landlord needs to fix electricity, though.
  • I am still after that cyborg thing. I already got the most important parts and some basic tests went well.
More posts (including pictures and videos) are about to come when I got electricity in the workshop.