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
- lft_phasor_presentation_and_cam_1280x720 (Presentation video with demo, 1280x720, 70.1 MB)
- lft_phasor_capture (High quality capture by Barta Zoli, 720x576, 475.8 MB)
- Linus Akesson - Phasor (Soundtrack, MP3, 3.9 MB)
- lft-phasor-src (Schematics, firmware binaries and source code, 80.1 kB)
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):
Cycle | Value on odd line | Value on even line |
---|---|---|
1 | Y + U cos(0) + V sin(0) | Y + U cos(-0) + V sin(-0) |
2 | Y + U cos(π/2) + V sin(π/2) | Y + U cos(-π/2) + V sin(-π/2) |
3 | Y + U cos(π) + V sin(π) | Y + U cos(-π) + V sin(-π) |
4 | Y + U cos(3π/2) + V sin(3π/2) | Y + U cos(-3π/2) + V sin(-3π/2) |
Simplify the expressions:
Cycle | Value on odd line | Value on even line |
---|---|---|
1 | Y + U | Y + U |
2 | Y + V | Y - V |
3 | Y - U | Y - U |
4 | Y - V | Y + 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:
Cycle | Value on odd line | Value on even line | Sum | Difference |
---|---|---|---|---|
1 | +U | +U | +2U | 0 |
2 | +V | -V | 0 | +2V |
3 | -U | -U | -2U | 0 |
4 | -V | +V | 0 | -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.
Cycle | Value on odd line | Value on even line | Sum | Difference |
---|---|---|---|---|
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(VA, VB) - 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.
Thu 8-Apr-2010 20:46
Greetings
Sun 2-May-2010 03:54
Sun 2-May-2010 04:08
Sun 2-May-2010 04:21
Sun 2-May-2010 08:23
Sun 2-May-2010 09:15
Sun 2-May-2010 10:29
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!
Sun 2-May-2010 14:29
Sun 2-May-2010 14:45
Thank you for sharing this.
Jeroen Tel and Rob Hubbard would be proud!
Sun 2-May-2010 22:07
Wed 5-May-2010 04:00
Wed 5-May-2010 23:37
Linus Åkesson
Fri 7-May-2010 16:25
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.
Tue 11-May-2010 11:17
Thu 13-May-2010 18:33
Fri 21-May-2010 10:45
\ViktorB
Sat 22-May-2010 17:35
\ViktorB
Zoli.
Fri 28-May-2010 12:52
\ViktorB
Zoli.
Thu 3-Jun-2010 00:19
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
Linus Åkesson
Sun 6-Jun-2010 13:43
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
Tue 8-Jun-2010 16:05
lft wrote:
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.
Wed 23-Jun-2010 21:16
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?
Fri 25-Jun-2010 22:42
Fri 9-Jul-2010 11:00
Sat 10-Jul-2010 19:40
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
Thu 15-Jul-2010 07:49
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!
Sun 25-Jul-2010 03:13
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
Mon 26-Jul-2010 10:04
Such a great project! Keep up the amazing work.
--
Post protected by LBackup
http://www.lbackup.org
Wed 11-Aug-2010 07:15
Wed 11-Aug-2010 23:32
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.
Sun 19-Sep-2010 20:01
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
Thu 28-Oct-2010 02:32
muy bueno¡¡¡¡¡¡¡
Lucas
Sat 22-Jan-2011 05:42
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?
Thu 24-Feb-2011 15:39
Keep up the awesome work! (and please don't sue me ^.^)
Sun 16-Dec-2012 04:27
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
Fri 7-Jun-2013 11:58
Mon 8-Jul-2013 14:28
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.
Sun 10-May-2015 20:20
Mon 21-Mar-2016 08:08
Sun 14-Aug-2016 13:39
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
Tue 26-Sep-2017 20:24
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.
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.Kasane Kona
Tue 30-Jul-2019 18:01
Fri 7-Aug-2020 00:13
https://www.mamedev.org/?p=484