Cliquez ici pour la version francophone
This project is concept demo to show that a color NTSC signal can be generated with simple hardware. This project implement a 1976 arcade game named breakout.
The hardware use only 2 actives components a PIC12F1572 which is an 8 pins MCU with 2 Kwords of flash and 256 bytes of ram. The other is an external oscillator runnung 28.636 Mhz which 8 times the chroma reference frequency of NTSC signal.
The NTSC TV color composite signal is named so because all information is combined in a single signal, vertical synchronization , horizontal synchronization, color and luminescence contrary to VGA where all thoses signals travels on different wires.
Although generating color NTSC is more complex than generating a VGA signals it quite doable on the following hardware
This circuit can generate 6 colors
color | C (RA1) | Y (RA4) |
---|---|---|
black | hi-z | hi-z |
white | hi-z | Vdd |
yellow | ref. phase | Vdd |
mauve | 180° phase | Vdd |
bleu | 180° phase | Vdd |
dark-green | ref. phase | hi-z |
hi-z means the output is disconnected
Vdd means the output is set at logic 1
ref. phase means the chroma signal is at reference phase.
180° phase means the chroma signal is in inverted phase.
As shown on the schematic the 3 signals synchronization (V & H), the chroma frequency and the luminescence Y signals are all combined with a resistor network R1-R2-R3.
There is a simple audio output to generate a brief sound when the ball bounce on bricks or paddle. This audio output share a pin with the RV1 potentiometer which control the paddle position on screen. With so few pins this sharing was required.
pin | signal |
---|---|
RA0 | audio output et potientiometer input |
RA1 | chroma output (C) |
RA2 | synchronization output |
RA3 | button input |
RA4 | luminescence output (Y) |
RA5 | external oscillator input. |
The final assembly was done on a perforated board.
It run on 4 AAA cells with a current around 20 mA.
The horizontal and vertical synchronization signal is generated by PWM3 periphals. The PIC12F1572 as 3 16 bits PWM. The project use the 3 and the analog to digital converter to read RV1 potientiometer. No other peripherals than these are used.
peripheral | usage |
---|---|
PWM1 | chroma signal output (3.58 Mhz) on pin RA1 |
PWM2 | audio output RA0, (shared with RV1 reading). |
PMW3 | synchronization signal output |
ADC | channel 0 of ADC read potentiometer on RA0 |
The external oscillator run at 8 times the NTSC chroma reference frequency 8*3.759545 Mhz = 28.636 Mhz. The PIC core are 4 T machines, meanings that the core need 4 Oscillator cycles to execute an instruction so the instruction cycles is at 7.159 Mhz this gives 140 nanosecond per instruction.
The video pixels are bitbanged and it take 5 cpu cycles to output 1 pixels, 4*140nsec.=700nsec. The visible part of an NTSC horizontal line last 52µsec. Then the maximum pixels that can be outputed on a line is 74.
But there is not enough memory for a frame buffer. The video buffer is only for 1 horizontal line and must be filled at the beginning of each line before shipping that line out. This procedure take time and depending of the content the time required varies. I limited the video buffer to 48 pixels. There is 6 bricks rows. Each row is 12 bricks of 4 pixels each. The video buffer then is 6 bytes, each pixel beeing represented by a single bit. This imply that on a single line only 2 colors can be display. No problem as each break row is of uniform color. In hole where there is no brick black is displayed. The brick color for a line is selected before shipping the video buffer. The white borders are not part of the video buffer but create before and after the call to display_vbuffer.
The software is organized as a round robin scheduler. PWM3 that generate synchronization signal trigger an interrupt at every horizontal line and all the work is done inside this interrupt service routine. Inside this ISR there is a task switch selecting which job must be done on that line. The NTSC standard is composed of 2 alternated fields of 262.5 lines which are interlaced on the screen for a total of 525 lines. But all those lines are not visible on screen, there is about only 240 lines visibles, but the game use only 220 of them. The lines that doesn't ship video out can be used for other tasks, line reading the button and paddle and game logic.
Here a table showing the usage of the scan lines.
scan lines | slices | usage |
---|---|---|
1-3 | 6 | task 0, vertical pre-equalization |
4-6 | 6 | task 1, vertical sync |
7-9 | 6 | task 2, vertical post-equalization |
10 | 1 | task 3, synchronization end |
11 | 1 | task 4, read paddle |
12 | 1 | task 5, sound timer |
13 | 1 | task 6, read button |
14 | 1 | task 7, move ball |
15 | 1 | task 8, collision control |
16-29 | 14 | task 9, do nothing until first visible line |
30-49 | 20 | task 10, display score and balls count |
50-57 | 8 | task 11, draw top border |
58-73 | 16 | task 12, draw space over bricks rows |
74-121 | 48 | task 13, draw 6 bricks rows |
122-241 | 120 | task 14, draw space below bricks rows |
242-249 | 8 | task 15, draw paddle |
250-262/3 | 11/12 | task 16, wait end of field |
Short youtube video (camera not readering mauve color properly).