REKLAMA

TVout.zip

8-bit'owy komputer na podstawie arduino UNO

Witam, chciałbym w tym temacie udokumentować krok po kroku budowę komputera opartego na platformie arduino. Filmy nie będą się pojawiać systematycznie, lecz maksymalna przerwa to tydzień. Nie wiem dokładnie jeszcze jak będzie to wyglądać, ale myślę, że wszystko ułoży się po dwóch, trzech odcinkach. Nie będzie to mój pierwszy wideoporadnik, więc nie będzie też jak to mówią "nie ogarnięty". Narazie podałem 2 biblioteczki w załącznikach, zachęcam też do zapoznania się z artykułami: -Film z kanału ElektroMaras o bibliotece TVout https://www.youtube.com/watch?v=KdtY9_w-_WI -Artykuł o podłączeniu klawiatury przez PS2 do arduino(niestety po angielsku) pjrc-PS2Keyboard -Artykuł o TVout na arduino Playground(niestety też po angielsku) Arduino - TVout -Oraz oczywiście do przetestowania przykładów z tych dwóch bibliotek. Jestem otwarty na propozycje w odp. i pw. Pozdrawiam DJIntel.


Pobierz plik - link do postu
  • TVout.zip
    • keywords.txt
    • examples
      • TVoutTestR1
        • TVoutTestR1.pde
    • video_gen.h
    • video_gen.cpp
    • TVout.h
    • TVout.cpp
    • font_set.h


TVout.zip > video_gen.h

#ifndef VIDEO_GEN_H
#define VIDEO_GEN_H

#define CYCLES_PER_US (F_CPU / 1000000)

//screen properties
#define RESOLUTION_HORIZONTAL 128 // must be a multiple of 8
#define RESOLUTION_VERTICAL 96 // should be no larger than 100
#define RESOLUTION_VSCALE 2 // if vres & lt; = 100 set to 2 for squarer pixels

// timing for the video generation
// change these vales for PAL support
// PAL SUPPORT NOT YET WORKING DUE TO LACK OF SCANLINES
#define TIME_SCANLINE 63.625
#define TIME_HORZ_SYNC 4.7
#define TIME_OUTPUT_START 12
#define TIME_VIRT_SYNC (TIME_SCANLINE - TIME_HORZ_SYNC)

#define LINE_FRAME 262
#define LINE_START_RENDER 35
#define LINE_STOP_RENDER ((LINE_START_RENDER + (RESOLUTION_VERTICAL * RESOLUTION_VSCALE)) - 1)

#define CYCLES_SCANLINE ((TIME_SCANLINE * CYCLES_PER_US) - 1)
#define CYCLES_HORZ_SYNC ((TIME_HORZ_SYNC * CYCLES_PER_US) - 1)
#define CYCLES_OUTPUT_START ((TIME_OUTPUT_START * CYCLES_PER_US) - 1)
#define CYCLES_VIRT_SYNC ((TIME_VIRT_SYNC * CYCLES_PER_US) - 1)

//global variables for the screen
extern volatile unsigned char scanLine;
extern unsigned char screen[(RESOLUTION_HORIZONTAL/8)*RESOLUTION_VERTICAL];

static inline void render_line();
static inline void wait_until(unsigned char time);

#endif


TVout.zip > TVout.h

/*
Copyright (c) 2010 Myles Metzer

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the " Software " ), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TVOUT_H
#define TVOUT_H

/*
This library provides a simple method for outputting data to a tv
from a frame buffer stored in sram. This implementation is done
completly by interupt and will return give as much cpu time to the
application as possible.

Limitations:
- Currently only works with NTSC. PAl support would require modifying
the timings in video_gen.h as well as the OCR1A ISR to allow for a 16bit
line counter.
- each frame only consists of 256 scanlines vs 262 for the fake progressive
signal this is supposed to generate (works fine on my tv).
- virtical sync does not match the specs at all.


current hardware setup:
Pin9: Sync line: -- & gt; |--/\/\/\--o
Diode 1Kohm |
Pin8: Video line: -- & gt; |--/\/\/\--o---------------- RCA tip
Diode 330ohm |
o--/--/\/\/\--o-- RCA GND
Switch 75ohm |
V
GND


*/

/*
TVout.cpp contains a brief expenation of each function.
*/
class TVout {
public:
void start_render();
void clear_screen();
void set_pixel(char x, char y, char c);
void draw_line(char x1, char y1, char x2, char y2, char c);
void print_char(char x, char y, char c);
void print_str(char x, char y, char *str);
};

#endif


TVout.zip > keywords.txt

TVout KEYWORD1
start_render KEYWORD2
clear_screen KEYWORD2
set_pixel KEYWORD2
draw_line KEYWORD2
print_char KEYWORD2
print_str KEYWORD2


TVout.zip > TVout.cpp

/*
Copyright (c) 2010 Myles Metzer

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the " Software " ), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

/*
This library provides a simple method for outputting data to a tv
from a frame buffer stored in sram. This implementation is done
completly by interupt and will return give as much cpu time to the
application as possible.

Limitations:
- Currently only works with NTSC. PAl support would require modifying
the timings in video_gen.h as well as the OCR1A ISR to allow for a 16bit
line counter.
- each frame only consists of 256 scanlines vs 262 for the fake progressive
signal this is supposed to generate (works fine on my tv).
- virtical sync does not match the specs at all.


current hardware setup:
Pin9: Sync line: -- & gt; |--/\/\/\--o
Diode 1Kohm |
Pin8: Video line: -- & gt; |--/\/\/\--o---------------- RCA tip
Diode 330ohm |
o--/--/\/\/\--o-- RCA GND
Switch 75ohm |
V
GND


*/

#include & lt; avr/io.h & gt;
#include & lt; avr/pgmspace.h & gt;
#include & lt; avr/interrupt.h & gt;

#include " TVout.h "
#include " video_gen.h "

PROGMEM const unsigned char ascii[] = {
#include " font_set.h "
};

/* call this to start video output
*/
void TVout::start_render() {

scanLine = 0;
clear_screen();

//setup the ports
DDRB |= 0x03;
PORTB & = ~0x02;
PORTB |= 0x02;

// inverted fast pwm mode on timer 1
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
ICR1 = CYCLES_SCANLINE;
OCR1A = CYCLES_HORZ_SYNC;
OCR1B = CYCLES_OUTPUT_START-20;

TIMSK1 = _BV(OCIE1A);

sei();
}

/* Clears the screen
*/
void TVout::clear_screen() {
for (int i = 0; i & lt; (RESOLUTION_HORIZONTAL/8)*RESOLUTION_VERTICAL; i++)
screen[i] = 0;
}

/* plot one point
* at x,y with color 1=white 0=black 2=invert
*/
void TVout::set_pixel(char x, char y, char c) {
//each line has 18 bytes
//calculate i based upon this and x,y
// the byte with the pixel in it
char pos[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
int i = (x/8) + ((int)y*16);

if (c==1)
screen[i] = screen[i] | pos[x & 7];
else if (c==0)
screen[i] = screen[i] & ~pos[x & 7];
else
screen[i] = screen[i] ^ pos[x & 7];
}

/* draw a line
* x1,y1 to x2,y2
* with color 1 = white, 0=black, 2=invert
*/
void TVout::draw_line(char x1, char y1, char x2, char y2, char c) {
int e;
signed int dx,dy,j, temp;
signed char s1,s2, xchange;
signed int x,y;

x = x1;
y = y1;

//take absolute value
if (x2 & lt; x1) {
dx = x1 - x2;
s1 = -1;
}
else if (x2 == x1) {
dx = 0;
s1 = 0;
}
else {
dx = x2 - x1;
s1 = 1;
}

if (y2 & lt; y1) {
dy = y1 - y2;
s2 = -1;
}
else if (y2 == y1) {
dy = 0;
s2 = 0;
}
else {
dy = y2 - y1;
s2 = 1;
}

xchange = 0;

if (dy & gt; dx) {
temp = dx;
dx = dy;
dy = temp;
xchange = 1;
}

e = ((int)dy & lt; & lt; 1) - dx;

for (j=0; j & lt; =dx; j++) {
set_pixel(x,y,c);

if (e & gt; =0) {
if (xchange==1) x = x + s1;
else y = y + s2;
e = e - ((int)dx & lt; & lt; 1);
}
if (xchange==1)
y = y + s2;
else
x = x + s1;
e = e + ((int)dy & lt; & lt; 1);
}
}

/* print a character c at x,y
*/
void TVout::print_char(char x, char y, char c) {
char i;
char y_pos;
uint8_t j;

for (i=0;i & lt; 7;i++) {
y_pos = y + i;

j = pgm_read_byte(((uint32_t)(ascii)) + c*7 + i);

set_pixel(x, y_pos, (j & 0x80)==0x80);
set_pixel(x+1, y_pos, (j & 0x40)==0x40);
set_pixel(x+2, y_pos, (j & 0x20)==0x20);
set_pixel(x+3, y_pos, (j & 0x10)==0x10);
set_pixel(x+4, y_pos, (j & 0x08)==0x08);
}
}

/* print a null terminated string at x,y
*/
void TVout::print_str(char x, char y, char *str) {
char i;
for (i=0; str[i]!=0; i++) {
print_char(x,y,str[i]);
x = x+6;
}
}


TVout.zip > font_set.h

//0
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//1
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//2
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//3
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//4
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//5
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//6
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//7
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//8
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//9
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//10
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//11
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//12
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//13
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//14
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//15
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//16
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//17
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//18
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//19
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//20
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//21
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//22
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//23
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//24
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//25
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//26
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//27
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//28
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//29
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//30
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//31
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//32 Space
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//33 Exclamation !
0b01100000,
0b01100000,
0b01100000,
0b01100000,
0b00000000,
0b00000000,
0b01100000,
//34 Quotes "
0b01010000,
0b01010000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//35 Number #
0b00000000,
0b01010000,
0b11111000,
0b01010000,
0b11111000,
0b01010000,
0b00000000,
//36 Dollars $
0b01110000,
0b10100000,
0b10100000,
0b01110000,
0b00101000,
0b00101000,
0b01110000,
//37 Percent %
0b01000000,
0b10101000,
0b01010000,
0b00100000,
0b01010000,
0b10101000,
0b00010000,
//38 Ampersand &
0b00100000,
0b01010000,
0b10100000,
0b01000000,
0b10101000,
0b10010000,
0b01101000,
//39 Single Quote '
0b01000000,
0b01000000,
0b01000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//40 Left Parenthesis (
0b00010000,
0b00100000,
0b01000000,
0b01000000,
0b01000000,
0b00100000,
0b00010000,
//41 Right Parenthesis )
0b01000000,
0b00100000,
0b00010000,
0b00010000,
0b00010000,
0b00100000,
0b01000000,
//42 Star *
0b00010000,
0b00111000,
0b00010000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//43 Plus +
0b00000000,
0b00100000,
0b00100000,
0b11111000,
0b00100000,
0b00100000,
0b00000000,
//44 Comma ,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00010000,
0b00010000,
//45 Minus -
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b11111000,
0b00000000,
0b00000000,
//46 Period .
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00010000,
// 47 Backslash /
0b00000000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000000,
// 48 Zero
0b01110000,
0b10001000,
0b10011000,
0b10101000,
0b11001000,
0b10001000,
0b01110000,
//49 One
0b00100000,
0b01100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b01110000,
//50 two
0b01110000,
0b10001000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b11111000,
//51 Three
0b11111000,
0b00010000,
0b00100000,
0b00010000,
0b00001000,
0b10001000,
0b01110000,
//52 Four
0b00010000,
0b00110000,
0b01010000,
0b10010000,
0b11111000,
0b00010000,
0b00010000,
//53 Five
0b11111000,
0b10000000,
0b11110000,
0b00001000,
0b00001000,
0b10001000,
0b01110000,
//54 Six
0b01000000,
0b10000000,
0b10000000,
0b11110000,
0b10001000,
0b10001000,
0b01110000,
//55 Seven
0b11111000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b10000000,
//56 Eight
0b01110000,
0b10001000,
0b10001000,
0b01110000,
0b10001000,
0b10001000,
0b01110000,
//57 Nine
0b01110000,
0b10001000,
0b10001000,
0b01111000,
0b00001000,
0b00001000,
0b00010000,
//58 :
0b00000000,
0b00000000,
0b00100000,
0b00000000,
0b00000000,
0b00000000,
0b00100000,
//59 ;
0b00000000,
0b00000000,
0b00100000,
0b00000000,
0b00000000,
0b00100000,
0b00100000,
//60 & lt;
0b00000000,
0b00011000,
0b01100000,
0b10000000,
0b01100000,
0b00011000,
0b00000000,
//61 =
0b00000000,
0b00000000,
0b01111000,
0b00000000,
0b01111000,
0b00000000,
0b00000000,
//62 & gt;
0b00000000,
0b11000000,
0b00110000,
0b00001000,
0b00110000,
0b11000000,
0b00000000,
//63 ?
0b00110000,
0b01001000,
0b00010000,
0b00100000,
0b00100000,
0b00000000,
0b00100000,
//64 @
0b01110000,
0b10001000,
0b10111000,
0b10101000,
0b10010000,
0b10001000,
0b01110000,
//65 A
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b11111000,
0b10001000,
0b10001000,
//B
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10001000,
0b10001000,
0b11110000,
//C
0b01110000,
0b10001000,
0b10000000,
0b10000000,
0b10000000,
0b10001000,
0b01110000,
//D
0b11110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b11110000,
//E
0b11111000,
0b10000000,
0b10000000,
0b11111000,
0b10000000,
0b10000000,
0b11111000,
//F
0b11111000,
0b10000000,
0b10000000,
0b11111000,
0b10000000,
0b10000000,
0b10000000,
//G
0b01110000,
0b10001000,
0b10000000,
0b10011000,
0b10001000,
0b10001000,
0b01110000,
//H
0b10001000,
0b10001000,
0b10001000,
0b11111000,
0b10001000,
0b10001000,
0b10001000,
//I
0b01110000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b01110000,
//J
0b00111000,
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b10010000,
0b01100000,
//K
0b10001000,
0b10010000,
0b10100000,
0b11000000,
0b10100000,
0b10010000,
0b10001000,
//L
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b11111000,
//M
0b10001000,
0b11011000,
0b10101000,
0b10101000,
0b10001000,
0b10001000,
0b10001000,
//N
0b10001000,
0b10001000,
0b11001000,
0b10101000,
0b10011000,
0b10001000,
0b10001000,
//O
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000,
//P
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10000000,
0b10000000,
0b10000000,
//Q
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10101000,
0b10010000,
0b01101000,
//R
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10100000,
0b10010000,
0b10001000,
//S
0b01111000,
0b10000000,
0b10000000,
0b01110000,
0b00001000,
0b00001000,
0b11110000,
//T
0b11111000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
//U
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000,
//V
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01010000,
0b00100000,
//W
0b10001000,
0b10001000,
0b10001000,
0b10101000,
0b10101000,
0b10101000,
0b01010000,
//X
0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b01010000,
0b10001000,
0b10001000,
//Y
0b10001000,
0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b00100000,
0b00100000,
//Z
0b11111000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b11111000,
//91 [
0b11100000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b11100000,
//92 (backslash)
0b00000000,
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000000,
//93 ]
0b00111000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00111000,
//94 ^
0b00100000,
0b01010000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//95 _
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b11111000,
//96 `
0b10000000,
0b01000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//97 a
0b00000000,
0b01100000,
0b00010000,
0b01110000,
0b10010000,
0b01100000,
0b00000000,
//98 b
0b10000000,
0b10000000,
0b11100000,
0b10010000,
0b10010000,
0b11100000,
0b00000000,
//99 c
0b00000000,
0b00000000,
0b01110000,
0b10000000,
0b10000000,
0b01110000,
0b00000000,
// 100 d
0b00010000,
0b00010000,
0b01110000,
0b10010000,
0b10010000,
0b01110000,
0b00000000,
//101 e
0b00000000,
0b01100000,
0b10010000,
0b11110000,
0b10000000,
0b01110000,
0b00000000,
//102 f
0b00110000,
0b01000000,
0b11100000,
0b01000000,
0b01000000,
0b01000000,
0b00000000,
//103 g
0b00000000,
0b01100000,
0b10010000,
0b01110000,
0b00010000,
0b00010000,
0b01100000,
//104 h
0b10000000,
0b10000000,
0b11100000,
0b10010000,
0b10010000,
0b10010000,
0b00000000,
//105 i
0b00000000,
0b00100000,
0b00000000,
0b00100000,
0b00100000,
0b00100000,
0b00000000,
//106 j
0b00000000,
0b00010000,
0b00000000,
0b00010000,
0b00010000,
0b00010000,
0b01100000,
//107 k
0b10000000,
0b10010000,
0b10100000,
0b11000000,
0b10100000,
0b10010000,
0b00000000,
//108 l
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00000000,
//109 m
0b00000000,
0b00000000,
0b01010000,
0b10101000,
0b10101000,
0b10101000,
0b00000000,
//110 n
0b00000000,
0b00000000,
0b01100000,
0b10010000,
0b10010000,
0b10010000,
0b00000000,
//111 o
0b00000000,
0b00000000,
0b01100000,
0b10010000,
0b10010000,
0b01100000,
0b00000000,
//112 p
0b00000000,
0b00000000,
0b01100000,
0b10010000,
0b11110000,
0b10000000,
0b10000000,
//113 q
0b00000000,
0b00000000,
0b01100000,
0b10010000,
0b11110000,
0b00010000,
0b00010000,
//114 r
0b00000000,
0b00000000,
0b10111000,
0b01000000,
0b01000000,
0b01000000,
0b00000000,
//115 s
0b00000000,
0b00000000,
0b01110000,
0b01000000,
0b00010000,
0b01110000,
0b00000000,
//116 t
0b01000000,
0b01000000,
0b11100000,
0b01000000,
0b01000000,
0b01000000,
0b00000000,
// 117u
0b00000000,
0b00000000,
0b10010000,
0b10010000,
0b10010000,
0b01100000,
0b00000000,
//118 v
0b00000000,
0b00000000,
0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b00000000,
//119 w
0b00000000,
0b00000000,
0b10101000,
0b10101000,
0b01010000,
0b01010000,
0b00000000,
//120 x
0b00000000,
0b00000000,
0b10010000,
0b01100000,
0b01100000,
0b10010000,
0b00000000,
//121 y
0b00000000,
0b00000000,
0b10010000,
0b10010000,
0b01100000,
0b01000000,
0b10000000,
//122 z
0b00000000,
0b00000000,
0b11110000,
0b00100000,
0b01000000,
0b11110000,
0b00000000,
//123 {
0b00100000,
0b01000000,
0b01000000,
0b10000000,
0b01000000,
0b01000000,
0b00100000,
//124 |
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
//125 }
0b00100000,
0b00010000,
0b00010000,
0b00001000,
0b00010000,
0b00010000,
0b00100000,
//126 ~
0b00000000,
0b00000000,
0b01000000,
0b10101000,
0b00010000,
0b00000000,
0b00000000,
//127 DEL
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000


TVout.zip > video_gen.cpp

#include & lt; avr/interrupt.h & gt;
#include & lt; avr/io.h & gt;

#include " video_gen.h "

//gobal variables
volatile unsigned char scanLine; //current scanline
volatile unsigned int renderLine; //offset from screen of the current line
unsigned char screen[(RESOLUTION_HORIZONTAL/8)*RESOLUTION_VERTICAL];
unsigned char * screenptr;

// this interupt occurs at OCR1A (end of that lines sync period
ISR(TIMER1_COMPA_vect) {
switch (scanLine) {
case 2: //start vsync
OCR1A = CYCLES_VIRT_SYNC;
break;
case 5: //stop vsync
OCR1A = CYCLES_HORZ_SYNC;
break;

case LINE_START_RENDER: //start to render each line
TIMSK1 |= _BV(OCIE1B);
renderLine = 0;
break;
case LINE_STOP_RENDER: //stop rendering each line
TIMSK1 & = ~_BV(OCIE1B);
break;
}
scanLine++;
}

// render a line
ISR(TIMER1_COMPB_vect) {
wait_until(CYCLES_OUTPUT_START);
render_line();
}

/* At the end of the inline assembly timer1 == time
* time must be at least 10cycles smaller than than
* timer1 at the time the asm starts.
* only works until timer1 == 256.
*/
static inline void wait_until(unsigned char time) {

__asm__ __volatile__ (
" sub %[time], %[tcnt1l]\n\t "
" subi %[time], 10\n "
" 100:\n\t "
" subi %[time], 3\n\t "
" brcc 100b\n\t "
" subi %[time], 0-3\n\t "
" breq 101f\n\t "
" dec %[time]\n\t "
" breq 102f\n\t "
" rjmp 102f\n "
" 101:\n\t "
" nop\n "
" 102:\n "
:
: [time] " a " (time),
[tcnt1l] " a " (TCNT1L)
);
}

/* render a 128 pixel line.
* 6 cycles/pixel 5 is possible if port state needs to be preserved
* fewer than 3 cycles should be possible without saving the status of the
* port. however the output pin would be restricted to the highest or lowest
* order pin on the output port and the output port must not be the same one
* sync outputs on (3c would be destructive).
*/
static inline void render_line() {
screenptr = screen + ((renderLine/RESOLUTION_VSCALE) & 0xFFF0);

__asm__ __volatile__ (
//save PORTB
" IN r16,%[port]\n\t "
" ANDI r16,0xFD\n\t "

" .macro output\n\t "
" BLD r16,0\n\t " //output pin of the port here pinB0
" OUT %[port],r16\n " //and on the last line of asm
" .endm\n "

" .macro pixeldelay\n\t " // delay time for setting pixel width
" NOP\n\t " // one can be removed for smaller
" NOP\n\t " // pixels dont forget to remove the
" NOP\n\t " // nop at the start of byteshift
" .endm\n "

" .macro byteshift\n\t "
" NOP\n\t "
" BST __tmp_reg__,7\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,6\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,5\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,4\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,3\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,2\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,1\n\t "
" output\n\t "
" pixeldelay\n\t "
" BST __tmp_reg__,0\n\t "
" output\n "
" .endm\n\t "

//output thingy
" LD __tmp_reg__,X+\n\t " //1
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //2
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //3
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //4
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //5
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //6
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //7
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //8
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //9
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //10
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //11
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //12
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //13
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //14
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //15
" byteshift\n\t "
" LD __tmp_reg__,X+\n\t " //16
" byteshift\n "

" EndLine_%=:\n\t "
" CBI %[port],0\n\t "
// assembly variable IO:
:
: [port] " i " (_SFR_IO_ADDR(PORTB)),
" x " (screenptr)
: " r16 " // try to remove this clobber later...
);
renderLine+=16;
}