(hide navigation)
  • Swedish content
Fund my projects
Patreon
Steady
Don't miss
Page thumbnail
Live at LCP 2011
Forum
Register
Log in
Latest comments
Syndication
RSS feed
Feedback
Music downloads
Video clips
Scene productions
Chip music
Hardware projects

Phasor

Phasor, like Craft, is a demo running on a custom minimalistic ATmega88-based demo platform. But it generates a composite video signal (PAL) instead of a VGA signal.

Download

It was my contribution to the Console / Real Wild compo at Breakpoint 2010, and ended up on 2nd place. Here's the Pouët page for Phasor.

Sorry for the low quality camera rip, but the composite signal was too lo-fi for the recording equipment at Breakpoint. They made a heroic effort, trying to filter the signal through all sorts of hardware, but to no avail. It works well with every CRT and TFT monitor I've come across, though. If anybody replicates the board and manages to record the signal, please let me know!

How does it work?

The composite video signal is a strange beast. Back when television was black and white, an analogue voltage was used to represent luminance (light intensity), as the electron beam swept across the TV one line at a time. 0.3 V represented black, 1.0 V represented white, and the voltages in between represented shades of grey. Horizontal and vertical sync signals were added in the form of brief pulses of 0 V, i.e. "blacker than black".

Since then, colour has been introduced by adding a small sinusoidal variation (technically not a phasor, but that's where I got the name from) on top of the black and white signal. The amplitude of the sine wave corresponds to colour intensity, or saturation. The phase of the sine wave is used to encode hue. Equivalently, you could say that the colour information is quadrature modulated in the sine and cosine components of the wave, and those components correspond to U and V in the YUV colourspace. The frequency of the colour wave is fixed at 4.43361875 MHz (because, somewhat simplified, this was determined to be the frequency that would interfere the least with old black and white equipment).

Two tricks

In this demo, the microcontroller is clocked at 17.73447 MHz, exactly four times the frequency of the colour carrier wave. In other words, four clock cycles per "colour pixel", and in those four cycles one has to generate a sine wave with controlled amplitude, phase and constant offset. First of all, there is no chance of generating a smooth sine wave, because the CPU is limited to a maximum output resolution of one sample per clock cycle. But even this is not really feasible to do entirely in software, except for very basic visuals, such as a bunch of static colour bars.

But the effort can be cut in half thanks to a loophole in the PAL encoding scheme. In PAL, the phase of the colour signal is inverted on every other line (PAL = Phase Alternate Line). This is quite clever, because it causes transmission errors to affect saturation rather than hue, and the brain is more sensitive to errors in hue. At the receiving end, a PAL TV or monitor compares each incoming pixel with the one above it, and uses a sum and difference formula to determine the correct colour. The vertical resolution of the colour information is effectively halved because of this. But this redundancy enables a really neat hack: By transmitting different values on odd and even raster lines, it is possible to get away with generating pixel data at every other clock cycle, which is only half the nominal rate.

This is what the signal is supposed to look like, if the time dimension is reduced to four discrete time slots (corresponding to four CPU cycles):

CycleValue on odd lineValue on even line
1Y + U cos(0) + V sin(0)Y + U cos(-0) + V sin(-0)
2Y + U cos(π/2) + V sin(π/2)Y + U cos(-π/2) + V sin(-π/2)
3Y + U cos(π) + V sin(π)Y + U cos(-π) + V sin(-π)
4Y + U cos(3π/2) + V sin(3π/2)Y + U cos(-3π/2) + V sin(-3π/2)

Simplify the expressions:

CycleValue on odd lineValue on even line
1Y + UY + U
2Y + VY - V
3Y - UY - U
4Y - VY + V

The monitor first separates Y from U and V using bandpass and notch filters. Then it expects to get roughly the same U and V from vertically adjacent pixels (unless there is a sharp colour change in the image at that exact spot, in which case there will be unwanted artifacts), and applies a sum and difference formula to reduce transmission errors:

CycleValue on odd lineValue on even lineSumDifference
1+U+U+2U0
2+V-V0+2V
3-U-U-2U0
4-V+V0-2V

The sum and difference columns are sinusoids with amplitudes proportional to U and V, respectively.

My demo transmits a signal that would result in very different U and V values on each line, and relies on the sum and difference formula to make sure that the monitor displays a single, solid colour.

CycleValue on odd lineValue on even lineSumDifference
1, 2+U + V+U - V+2U+2V
3, 4-U - V-U + V-2U-2V

As you can see, the sum and difference columns are still sinusoids with amplitudes proportional to U and V. And that's how to get away with emitting pixels at half the nominal rate.

The second trick is that toggling between two voltages can be done with the help of one of the timers inside the ATmega88. The circuit below consists of two emitter followers in parallel.

Each transistor tries to force the voltage at the emitter to be 0.7 V below the voltage at the base. But they can only pull the voltage upwards to a higher level. The upshot of this is that the output voltage will be 0.7 V below the highest of the two input voltages (Out = max(VAVB) - 0.7).

The diodes allow two microcontroller pins to independently pull each input down to 0.7 V, causing the other input to be "chosen" by the emitter followers. Timer 1 in the ATmega88 can be configured to generate a two-cycles-high, two-cycles-low square wave on one output compare pin, and its inverse on another output compare pin. That way, the software only has to provide the two input values (four bits each, conveniently the high and low nibbles of PORTD), and the timer, diodes and transistors will work together to create a square wave, oscillating between these two voltages automatically. Of course, the software still has to transmit different values on odd and even raster lines and keep in phase with the timer, so timing is crucial. But we get just enough support from the hardware to get by without having to spend all cpu cycles generating the colour wave.

The reason for going with Timer 1 rather than Timer 0 is that the output compare unit of Timer 0 is sharing pins with PORTD, and I wanted all eight bits of PORTD to go into the DACs. But Timer 1 is the only 16-bit timer on the chip, and I needed a raster interrupt to occur every 1135 cycles. Fortunately, 1135 happens to be an even multiple of five, so I'm using Timer 0 to generate interrupts every 227 cycles, and letting the software disregard four out of five of them.

Music

Sound is generated during the horizontal blanking periods. That gives a sample rate of 15.625 kHz. Of course, only the really timing critical part (waveform generation) is performed during the horizontal blanking. Melody, rhythm, amplitude envelopes, arpeggios etc. are handled by a playroutine which gets called once for every video frame, during vertical blanking.

There are four sound channels in total, each with its own fixed waveform. The waveforms are 4-bit triangle, filtered variable pulse, unfiltered variable pulse and white noise. The filter is a two-pole non-resonant low-pass filter. The noise is generated by means of a 15-bit shift register. The volume of each channel can be individually controlled.

Schematics

This is how it all fits together, hardware-wise. If you are interested in the physical layout used on the breadboard, you can find it along with firmware and source code near the top of the page.

                                                            .---__---.                           +  10uF
                                  (to programmer) --- RESET |        | PC5 ---[ 2K ]----------+---|(-----
                                                            |        |               .-[ 1K ]-'        Audio
                               GND --[ 2K ]-+-[ 2K ]--- PD0 |        | PC4 ---[ 2K ]-+--------.   GND ---
                                   .-[ 1K ]-'               |        |               .-[ 1K ]-'
                                   `--------+-[ 2K ]--- PD1 |        | PC3 ---[ 2K ]-+--------.
          VCC      VCC --[ 2K ]-.  .-[ 1K ]-'               |        |               .-[ 1K ]-'
           \       GND -[ 442 ]-+  `--------+-[ 2K ]--- PD2 |        | PC2 ---[ 2K ]-+--------.
           C\| B                |  .-[ 1K ]-'               |        |               .-[ 1K ]-'
             |---+------[ 442 ]-+--+----------[ 2K ]--- PD3 |        | PC1 ---[ 2K ]-+--------.
           E/|   |                                          |        |               .-[ 1K ]-'
           /     |             GND --[ 2K ]-+-[ 2K ]--- PD4 |        | PC0 ---[ 2K ]-+-[ 2K ]---- GND
          |      |                 .-[ 1K ]-'               |        |       
          |      |                 |                    VCC |        | GND
          |      |                 |                        |        |
          |      |                 |                    GND |        | AREF (n.c.)
          |      |                 |          22pF          |        |
  --------+      |                 |      GND -||--+- XTAL1 |        | VCC
Video     |      |                 | 17.73447 MHz [ ]       |        |
  -- GND  |      |                 |      GND -||--+- XTAL2 |        | SCK ---- (to programmer)
          |      |                 |          22pF          |        |
          |      |                 `--------+-[ 2K ]--- PD5 |        | MISO --- (to programmer)
          |      | VCC --[ 2K ]-.  .-[ 1K ]-'               |        |
           \     | GND -[ 442 ]-+  `--------+-[ 2K ]--- PD6 |        | MOSI --- (to programmer)
           E\| B |              |  .-[ 1K ]-'               |        |
             |---|-+----[ 442 ]-+--+----------[ 2K ]--- PD7 |        | OC1B --------.
           C/|   | |                                        |        |              |
           /     | |                             (n.c.) PB0 |        | OC1A --.     |
          VCC    | |                                        `--------'       _|_   _|_
                 | |                                                         /_\   /_\
                 | |                                                          |     |
                 | `----------------------------------------------------------'     |
                 `------------------------------------------------------------------'

If you want to learn more, I suggest you dive into the source code, starting with video.S and main.S. The compressed data tables are generated by pack.c.

Update

I am very grateful to Barta Zoli from Hungary, for building a replica of the circuit, making a high quality video capture and allowing me to share it here. You can find it in the Download section above.

Posted Wednesday 7-Apr-2010 13:58

Discuss this page

Disclaimer: I am not responsible for what people (other than myself) write in the forums. Please report any abuse, such as insults, slander, spam and illegal material, and I will take appropriate actions. Don't feed the trolls.

Jag tar inget ansvar för det som skrivs i forumet, förutom mina egna inlägg. Vänligen rapportera alla inlägg som bryter mot reglerna, så ska jag se vad jag kan göra. Som regelbrott räknas till exempel förolämpningar, förtal, spam och olagligt material. Mata inte trålarna.

Swierkdeck
Thu 8-Apr-2010 20:46
Hi Linus! The more I see this demo I think it gets better! I am thinking about where did you get all that knowledge? ;)
Greetings
Anonymous
Sun 2-May-2010 03:54
Found the link on "Hack A Day" and am in awe (and getting a Sinclair flashback). Good work!
Anonymous
Sun 2-May-2010 04:08
Very impressive.
Anonymous
Sun 2-May-2010 04:21
I've worked in broadcast video technology and micros since the late 70's, and I have to admit that any broadcast technology manufacturer would hire you in a heartbeat. Your understandng and respect for the timing and fundamental technology is well worth the reward. Congratulations on a great example of persistence and quality.
Anonymous
Sun 2-May-2010 08:23
.....WOW!
Anonymous
Sun 2-May-2010 09:15
That is amazing! I take my hat off to you sir.
Anonymous
Sun 2-May-2010 10:29
Me recuerda la antigua demoscene cuando en menos de 64Kb se metía un archivo de música .MOD y una animación como la tuya. ¡Fantástico!
It is remenber me the 80's years demoscene: 64Kb are enough to the music in .MOD file and the animation like the yours. Amazing!
Anonymous
Sun 2-May-2010 14:29
Dude, you deserve the deepest respect. This is beyond cool, it's mindboggingly awesome. Keep that up!
Anonymous
Sun 2-May-2010 14:45
Unbelievable.
Thank you for sharing this.
Jeroen Tel and Rob Hubbard would be proud!
Anonymous
Sun 2-May-2010 22:07
absolutely awesome!
Anonymous
Wed 5-May-2010 04:00
I was directed here by a comment in the Arduino forums; amazing doesn't begin to describe this work! WOW!
Anonymous
Wed 5-May-2010 23:37
Linus, Would this be possible on NTSC or no because of the phase alternation?
lft
Linus Åkesson
Fri 7-May-2010 16:25
Linus, Would this be possible on NTSC or no because of the phase alternation?

No, unfortunately it won't work on NTSC, since it doesn't do phase alternation. You'd only be able to get the subset of colours where U = V.
Anonymous
Tue 11-May-2010 11:17
It is impossible! I know AVR over 12 years in any detail, but this must surprise me. Congratulation.
Anonymous
Thu 13-May-2010 18:33
I'd like to know what kind of software do you use to design the breadboard layout and the printed topology.
Anonymous
Fri 21-May-2010 10:45
I'd like to know what kind of software do you use to design the breadboard layout and the printed topology.
lft is using PostScript. See his comment, dated Tue 5-Aug-2008 05:41, on his page for the Craft project.
\ViktorB
Anonymous
Sat 22-May-2010 17:35
I'd like to know what kind of software do you use to design the breadboard layout and the printed topology.
lft is using PostScript. See his comment, dated Tue 5-Aug-2008 05:41, on his page for the Craft project.
\ViktorB
Thank you for your answer Viktor. I studied craft.eps file, but it doesn't seen to be an interactive method to design something. I think it is good only to store electronically a manually designed plan. I hoped that is there any really designer program for this purpose like PCB designers for example.
Zoli.
Anonymous
Fri 28-May-2010 12:52
I'd like to know what kind of software do you use to design the breadboard layout and the printed topology.
lft is using PostScript. See his comment, dated Tue 5-Aug-2008 05:41, on his page for the Craft project.
\ViktorB
Thank you for your answer Viktor. I studied craft.eps file, but it doesn't seen to be an interactive method to design something. I think it is good only to store electronically a manually designed plan. I hoped that is there any really designer program for this purpose like PCB designers for example.
Zoli.
No, as far as I know lft, he's coding it by hand. You should give it a try yourself, it's fun! \ViktorB
Anonymous
Thu 3-Jun-2010 00:19
Hi Linus,
I rebuilt your Phasor circuit, and recorded it's output into a very nice mpeg file. I'd like to send it to you, so please remove my E-mail address (*@freemail.hu) from your spam list.
Regards, Zoli
lft
Linus Åkesson
Sun 6-Jun-2010 13:43
Hi Linus,
I rebuilt your Phasor circuit, and recorded it's output into a very nice mpeg file. I'd like to send it to you, so please remove my E-mail address (*@freemail.hu) from your spam list.
Regards, Zoli

Please try this address instead: linuslft@gmail.com
Anonymous
Tue 8-Jun-2010 16:05

lft wrote:

Hi Linus,
I rebuilt your Phasor circuit, and recorded it's output into a very nice mpeg file. I'd like to send it to you, so please remove my E-mail address (*@freemail.hu) from your spam list.
Regards, Zoli

Please try this address instead: linuslft@gmail.com

I sent a link via dropbox, please open that letter.
Anonymous
Wed 23-Jun-2010 21:16
Great Job again linus!
I really aspire to reach a level you are at.

If I make eagle schematic files of this like last time will your consider posting them?
Anonymous
Fri 25-Jun-2010 22:42
Amazing! I cannot believe how that much video and audio can be created with 8.5kB worth of program. Or how the AVR can render some of those graphics. It's brilliant!
Anonymous
Fri 9-Jul-2010 11:00
Love it! So much so that I'm building my own, but I'm curious about the 442 resistors. That's a really odd value, even if I read it like an SMD part and get 4.4k. Is the value critical, or can I get away with a 4.7k?
Anonymous
Sat 10-Jul-2010 19:40
Love it! So much so that I'm building my own, but I'm curious about the 442 resistors. That's a really odd value, even if I read it like an SMD part and get 4.4k. Is the value critical, or can I get away with a 4.7k?

Wait, I just realised it's in an R-2R ladder arrangement with the 220ohm resistors. There's actually plenty of room in the stripboard layout to replace each 442 with a pair of 220s in series, so I'll do that instead of sourcing resistors out of E48. :D
Anonymous
Thu 15-Jul-2010 07:49
I just realised it's in an R-2R ladder arrangement with the 220ohm resistors.

And just as quickly realised that I was thinking of the Craft schematic instead of Phasor's. Oops! :)

Anyway, I just finished building it, and it works beautifully! Thanks lft!
Anonymous
Sun 25-Jul-2010 03:13
You are probably familiar with this but i thought it was worth posting the link.

http://www.techeblog.com/index.php/tech-gadget/feature-modder-hacks-1980s-ibm-pc-to-play-full-motion-color-video

This is an IBM AT that some guy has playing full motion (60fps) video.
henri
henri
Mon 26-Jul-2010 10:04
The PAL output is awesome! I am also really amazed at the way the timing is handled.

Such a great project! Keep up the amazing work.

--
Post protected by LBackup
http://www.lbackup.org
Anonymous
Wed 11-Aug-2010 07:15
Respect.
Anonymous
Wed 11-Aug-2010 23:32
Linus,

As I was on LCP 2009 I was totally amazed by your piece of music. Now that I, one year later, checked you up in more detail, I must say your work is brilliant.
Anonymous
Sun 19-Sep-2010 20:01
I guess you could have gone with an AD725 or similar RGB to PAL converter. But then nothing would be learnt!

The output analog switch is a nice twist. With the timer it keeps everything in sync which would be really hard otherwise - I was previously convinced no extra work could be done in the limited time. I now know that if it looks right on screen, then it *is* right. What else matters?

First time I saw microcontroller PAL encoding was Rickard Gunee's Pong project a few years ago which was quite interesting too.

Conor
Anonymous
Thu 28-Oct-2010 02:32
tremendo loco¡ te fuistes a la mierda¡
muy bueno¡¡¡¡¡¡¡
Smb123w64gb
Lucas
Sat 22-Jan-2011 05:42
Linus,

Your music in this was really good and was wondering if you can make this with out the video output but with an impressive sound output only and that other people can make and preform music on it.

Thanks for all the good work,and do you have Ubuntu Linux like me?
nazlfrag
Thu 24-Feb-2011 15:39
Hey Linus, congratulations on a beautiful hack and an amazing demo. I loved it so much I made a font in tribute, http://fontstruct.com/fontstructions/show/353703

Keep up the awesome work! (and please don't sue me ^.^)
Anonymous
Sun 16-Dec-2012 04:27
Hi Linus
I tried to open your ift-phosor-src but I can't seem to open it.
After extracting using 7Zip the file shows an extension of "file" and that seems to be wrong. can you put the files in another format or post to Github or Google code?

I am very keen to have a look at your code and files as what you have achieved is amazing.
PS - Where did you get the crystal?
Regards
Denis in Oz
Anonymous
Fri 7-Jun-2013 11:58
Take my money...
Anonymous
Mon 8-Jul-2013 14:28
Dude, this is really cool.
I just started expirimenting with arduino this year and I've done some cool stuff...like emulating the atari 8bit floppydrive with it and loading emulator rom files from an sdcard on my real atari.

I just took apart some tv set-top box and it contained an AtMega88 on the controller board....was thinking about doing something cool with it, but looking at this makes me think IT CAN NOT GET ANY COOLER.....except making a game out of it.
Anonymous
Sun 10-May-2015 20:20
Great Work!
Anonymous
Mon 21-Mar-2016 08:08
Genial.
Anonymous
Sun 14-Aug-2016 13:39
I need only ctatic Pal Picture
A 10 X 10 grid of white lines and three colored square
blue green red at the center of the vertical.
atmega 128 atmega8 atmega 16 in stock
1icri
Tue 26-Sep-2017 20:24
While looking in the source, I noticed the song is supposed to end on bar 112 (around line 34 in music.S), but the song goes on for 134 bars and the story sequence for 136 bars. Am I overlooking something simple or is this an error in the given source files?
lft
Linus Åkesson
Wed 27-Sep-2017 21:48

1icri wrote:

While looking in the source, I noticed the song is supposed to end on bar 112 (around line 34 in music.S), but the song goes on for 134 bars and the story sequence for 136 bars. Am I overlooking something simple or is this an error in the given source files?

Look at music.S again. It's reading from the song table. An entry is either a track number (0..95), or a transpose setting (96..127) followed by a track number. As a special case, a transpose byte that indicates no transpose (in the middle of the range, i.e. 96+16) marks the end of the song.
Anonymous
Thu 28-Sep-2017 21:50

lft wrote:

Look at music.S again. It's reading from the song table. An entry is either a track number (0..95), or a transpose setting (96..127) followed by a track number. As a special case, a transpose byte that indicates no transpose (in the middle of the range, i.e. 96+16) marks the end of the song.
Ah, I guess I made a rather silly mistake then! Thanks.
Kasane
Kasane Kona
Tue 30-Jul-2019 18:01
Hey, it's been a while (I'm 1icri/Anonymous above), I saw some interest in an "oscilloscope view" for this demo and some other lft hardware demos, so I finished up my rather messy music player program and created one! https://youtu.be/scAk5WIpQwQ hope you enjoy it!
Anonymous
Fri 7-Aug-2020 00:13
Emulated by MAME as of MAME 0.223. :-)
https://www.mamedev.org/?p=484