//video gen and Kalidascope //D.5 is sync:1000 ohm + diode to 75 ohm resistor //D.6 is video:330 ohm + diode to 75 ohm resistor #define F_CPU 16000000 #include #include #include #include #include #include #include //cycles = 63.625 * 8 Note NTSC is 63.55 //but this line duration makes each frame exactly 1/60 sec //which is nice for keeping a realtime clock #define lineTime 1018 // = 509*2 #define ScreenTop 30 #define ScreenBot 230 #define T0reload 256-60 //NOTE that the first line of CHARs must be in registers! //volatile int8_t syncON, syncOFF, v1, v2, v3, v4, v5, v6, v7, v8; register uint8_t syncON asm("r4"); register uint8_t syncOFF asm("r5"); register uint8_t v1 asm("r6"); register uint8_t v2 asm("r7"); register uint8_t v3 asm("r8"); register uint8_t v4 asm("r9"); register uint8_t v5 asm("r10"); register uint8_t v6 asm("r11"); register uint8_t v7 asm("r12"); register uint8_t v8 asm("r13"); volatile int i,LineCount; volatile uint8_t time, gaugeY; volatile uint8_t figure ; //state variable for waving figure char screen[800], t, ts[10]; char cu1[]="JOE"; char cu2[]="CROP"; //define some character bitmaps //5x7 characters char bitmap[38][7]={ //0 {0b01110000, 0b10001000, 0b10011000, 0b10101000, 0b11001000, 0b10001000, 0b01110000}, //1 {0b00100000, 0b01100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b01110000}, //2 {0b01110000, 0b10001000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b11111000}, //3 {0b11111000, 0b00010000, 0b00100000, 0b00010000, 0b00001000, 0b10001000, 0b01110000}, //4 {0b00010000, 0b00110000, 0b01010000, 0b10010000, 0b11111000, 0b00010000, 0b00010000}, //5 {0b11111000, 0b10000000, 0b11110000, 0b00001000, 0b00001000, 0b10001000, 0b01110000}, //6 {0b01000000, 0b10000000, 0b10000000, 0b11110000, 0b10001000, 0b10001000, 0b01110000}, //7 {0b11111000, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b10000000, 0b10000000}, //8 {0b01110000, 0b10001000, 0b10001000, 0b01110000, 0b10001000, 0b10001000, 0b01110000}, //9 {0b01110000, 0b10001000, 0b10001000, 0b01111000, 0b00001000, 0b00001000, 0b00010000}, //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}, //figure1 {0b01110000, 0b00100000, 0b01110000, 0b10101000, 0b00100000, 0b01010000, 0b10001000}, //figure2 {0b01110000, 0b10101000, 0b01110000, 0b00100000, 0b00100000, 0b01010000, 0b01010000} }; //================================ //3x5 font numbers, then letters //packed two per definition for fast //copy to the screen at x-position divisible by 4 //flash char smallbitmap[39][5]={ char smallbitmap[39][5]={ //0 {0b11101110, 0b10101010, 0b10101010, 0b10101010, 0b11101110}, //1 {0b01000100, 0b11001100, 0b01000100, 0b01000100, 0b11101110}, //2 {0b11101110, 0b00100010, 0b11101110, 0b10001000, 0b11101110}, //3 {0b11101110, 0b00100010, 0b11101110, 0b00100010, 0b11101110}, //4 {0b10101010, 0b10101010, 0b11101110, 0b00100010, 0b00100010}, //5 {0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110}, //6 {0b11001100, 0b10001000, 0b11101110, 0b10101010, 0b11101110}, //7 {0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b10001000}, //8 {0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b11101110}, //9 {0b11101110, 0b10101010, 0b11101110, 0b00100010, 0b01100110}, //: {0b00000000, 0b01000100, 0b00000000, 0b01000100, 0b00000000}, //= {0b00000000, 0b11101110, 0b00000000, 0b11101110, 0b00000000}, //blank {0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}, //A {0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b10101010}, //B {0b11001100, 0b10101010, 0b11101110, 0b10101010, 0b11001100}, //C {0b11101110, 0b10001000, 0b10001000, 0b10001000, 0b11101110}, //D {0b11001100, 0b10101010, 0b10101010, 0b10101010, 0b11001100}, //E {0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b11101110}, //F {0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b10001000}, //G {0b11101110, 0b10001000, 0b10001000, 0b10101010, 0b11101110}, //H {0b10101010, 0b10101010, 0b11101110, 0b10101010, 0b10101010}, //I {0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b11101110}, //J {0b00100010, 0b00100010, 0b00100010, 0b10101010, 0b11101110}, //K {0b10001000, 0b10101010, 0b11001100, 0b11001100, 0b10101010}, //L {0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b11101110}, //M {0b10101010, 0b11101110, 0b11101110, 0b10101010, 0b10101010}, //N {0b00000000, 0b11001100, 0b10101010, 0b10101010, 0b10101010}, //O {0b01000100, 0b10101010, 0b10101010, 0b10101010, 0b01000100}, //P {0b11101110, 0b10101010, 0b11101110, 0b10001000, 0b10001000}, //Q {0b01000100, 0b10101010, 0b10101010, 0b11101110, 0b01100110}, //R {0b11101110, 0b10101010, 0b11001100, 0b11101110, 0b10101010}, //S {0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110}, //T {0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b01000100}, //U {0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b11101110}, //V {0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b01000100}, //W {0b10101010, 0b10101010, 0b11101110, 0b11101110, 0b10101010}, //X {0b00000000, 0b10101010, 0b01000100, 0b01000100, 0b10101010}, //Y {0b10101010, 0b10101010, 0b01000100, 0b01000100, 0b01000100}, //Z {0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b11101110} }; //================================== //This is the sync generator. It MUST be entered from //sleep mode to get accurate timing of the sync pulses //At 8 MHz, all of the sync logic fits in the 5 uSec sync //pulse ISR(TIMER1_COMPA_vect) { //start the Horizontal sync pulse PORTD = syncON; //count timer 0 at 1/usec // TCNT0=0; //update the curent scanline number LineCount ++ ; //begin inverted (Vertical) synch after line 247 if (LineCount==248) { syncON = 0b00100000; syncOFF = 0; } //back to regular sync after line 250 if (LineCount==251) { syncON = 0; syncOFF = 0b00100000; } //start new frame after line 262 if (LineCount==263) { LineCount = 1; } _delay_us(2.65); //end sync pulse PORTD = syncOFF; } //================================== //plot one point //at x,y with color 1=white 0=black 2=invert void video_pt(uint8_t x, uint8_t y, uint8_t c) { //The following odd construction //sets/clears exactly one bit at the x,y location i=((int)x>>3) + ((int)y<<3) ; if (c==1) screen[i] = screen[i] | 1<<(7-(x & 0x7)); if (c==0) screen[i] = screen[i] & ~(1<<(7-(x & 0x7))); if (c==2) screen[i] = screen[i] ^ (1<<(7-(x & 0x7))); } //================================== // put a big character on the screen // c is index into bitmap void video_putchar(uint8_t x, uint8_t y, uint8_t c) { uint8_t j; for (j=0;j<7;j++) { v1 = bitmap[c][j]; video_pt(x, y+j, (v1 & 0x80)==0x80); video_pt(x+1, y+j, (v1 & 0x40)==0x40); video_pt(x+2, y+j, (v1 & 0x20)==0x20); video_pt(x+3, y+j, (v1 & 0x10)==0x10); video_pt(x+4, y+j, (v1 & 0x08)==0x08); } } //================================== // put a string of big characters on the screen void video_puts(uint8_t x, uint8_t y, char *str) { uint8_t i ; for (i=0; str[i]!=0; i++) { if (str[i]>=0x30 && str[i]<=0x39) video_putchar(x,y,str[i]-0x30); else video_putchar(x,y,str[i]-0x40+9); x = x+6; } } //================================== // put a small character on the screen // x-cood must be on divisible by 4 // c is index into bitmap void video_smallchar(uint8_t x, uint8_t y, uint8_t c) { uint8_t mask; i=((int)x>>3) + ((int)y<<3) ; if (x == (x & 0xf8)) mask = 0x0f; else mask = 0xf0; screen[i] = (screen[i] & mask) | (smallbitmap[c][0] & ~mask); screen[i+8] = (screen[i+8] & mask) | (smallbitmap[c][1] & ~mask); screen[i+16] = (screen[i+16] & mask) | (smallbitmap[c][2] & ~mask); screen[i+24] = (screen[i+24] & mask) | (smallbitmap[c][3] & ~mask); screen[i+32] = (screen[i+32] & mask) | (smallbitmap[c][4] & ~mask); } //================================== // put a string of small characters on the screen // x-cood must be on divisible by 4 void video_putsmalls(uint8_t x, uint8_t y, char *str) { uint8_t i ; for (i=0; str[i]!=0; i++) { if (str[i]>=0x30 && str[i]<=0x39) video_smallchar(x,y,str[i]-0x30); else video_smallchar(x,y,str[i]-0x40+12); x = x+4; } } //===================== //finds sign of a char. // int8_t sign(int8_t x) { if(x < 0) return -1; else if(x > 0) return 1; else return 0; } //================================== //plot a line //at x1,y1 to x2,y2 with color 1=white 0=black 2=invert //NOTE: this function requires signed chars //Code is from David Rodgers, //"Procedural Elements of Computer Graphics",1985 void video_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t c) { int8_t x,y,dx,dy,e,j, temp; uint8_t s1,s2, xchange; x = x1; y = y1; dx = abs(x2-x1); dy = abs(y2-y1); s1 = sign(x2-x1); s2 = sign(y2-y1); xchange = 0; if (dy>dx) { temp = dx; dx = dy; dy = temp; xchange = 1; } e = (dy<<1) - dx; for (j=0; j<=dx; j++) { video_pt(x,y,c) ; if (e>=0) { if (xchange==1) x = x + s1; else y = y + s2; e = e - (dx<<1); } if (xchange==1) y = y + s2; else x = x + s1; e = e + (dy<<1); } } //================================== //return the value of one point //at x,y with color 1=white 0=black 2=invert uint8_t video_set(uint8_t x, uint8_t y) { //The following construction //detects exactly one bit at the x,y location i=((int)x>>3) + ((int)y<<3) ; return ( screen[i] & 1<<(7-(x & 0x7))); } //================================== // set up the ports and timers int main(void) { //init timer 1 to generate sync OCR1A = lineTime; //One NTSC line TCCR1B = 9; //full speed; clear-on-match TCCR1A = 0x00; //turn off pwm and oc lines TIMSK = 0x10; //enable interrupt T1 cmp //init ports DDRD = 0xf0; //video out and switches //D.5 is sync:1000 ohm + diode to 75 ohm resistor //D.6 is video:330 ohm + diode to 75 ohm resistor //init timer 0 to 1/uSec TCCR0 = 2; //initialize synch constants LineCount = 1; syncON = 0b00000000; syncOFF = 0b00100000; //Print "JOE" video_puts(10,3,cu1); //Print "CROP" video_puts(38,3,cu2); /* video_pt(30, 30, 1); video_pt(31, 30, 1); video_pt(32, 30, 1); video_pt(30, 31, 1); video_pt(31, 31, 0); video_pt(32, 31, 1); video_pt(30, 32, 0); video_pt(31, 32, 1); video_pt(32, 32, 0); */ //Init figure figure=0; // video_putchar(40,75,36); //side lines // video_line(0,0,0,99,1); // video_line(63,0,63,99,1); //top line & bottom lines video_line(0,0,63,0,1); video_line(0,99,63,99,1); video_line(0,11,63,11,1); video_line(0,89,63,89,1); //build a fuel gauge // video_line(5,85,16,85,1); // video_line(5,40,16,40,1); // video_line(5,40,5,85,1); // video_line(16,40,16,85,1); //Test the numeric chars // video_putsmalls(4,26,numstr); // video_smallchar(44,26,10); // video_smallchar(48,26,11); //Test the alpha character set // video_putsmalls(4,14,alphastr1); // video_putsmalls(4,20,alphastr2); //Test the big numbers // video_puts(2,32,numstr); //test big letters // video_puts(18,40,alphastr3); // video_puts(18,48,alphastr4); // video_puts(18,56,alphastr5); // video_puts(18,64,alphastr6); //init random num gen // srand(1); //init software timer t=0; time=0; //enable sleep mode // MCUCR = 0b01000000; sleep_enable(); sei(); //The following loop executes once/video line during lines //1-230, then does all of the frame end processing while(1) { //precompute pixel index for next line if (LineCount=ScreenTop) { //left-shift 3 would be individual lines // <<2 means line-double the pixels //The 0xfff8 truncates the odd line bit i=(LineCount-ScreenTop)<<2 & 0xfff8;; } //stall here until next line starts //sleep enable; mode=idle //use sleep to make entry into sync ISR uniform time sleep_cpu(); //Put code here to execute once/line //During the active portion of a line; //--TCNT1 goes from about 130 to about 480 //--Usable lines 1 to about 240 if (LineCountScreenTop) { //load the pixels into registers v1 = screen[i]; v2 = screen[++i]; v3 = screen[++i]; v4 = screen[++i]; v5 = screen[++i]; v6 = screen[++i]; v7 = screen[++i]; v8 = screen[++i]; /* v1 = 0x00; v2 = 0x00; v3 = 0x00; v4 = 0x00; v5 = 0x00; v6 = 0x00; v7 = 0x00; v8 = 0x0F; */ //now blast them out to the screen // line 1 if(((v1 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v1 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 2 if(((v2 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v2 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 3 if(((v3 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v3 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 4 if(((v4 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v4 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 5 if(((v5 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v5 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 6 if(((v6 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v6 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); // line 7 if(((v7 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v7 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b10000000)>>7) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b01000000)>>6) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00100000)>>5) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00010000)>>4) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00001000)>>3) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00000100)>>2) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00000010)>>1) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); if(((v8 & 0b00000001)>>0) == 1) { PORTD |= 0x40; } else { PORTD &= 0xBF; asm("nop"::); asm("nop"::); } asm("nop"::); asm("nop"::); PORTD &= 0xBF; } //The following code executes during the vertical blanking //Code here can be as long as 63 uSec/line //For a total of 30 lines x 63.5 uSec/line x 8 cycles/uSec // Every 60 uSec or so, you should insert a "sleep" //command so that the timer 1 ISR happens at a regular interval, //but it may not matter to most TVs if (LineCount==231) { //animate the fuel gauge //erase the old one // gaugeY=84-(t>>1); // video_line(6,gaugeY,15,gaugeY,0); // video_smallchar(8,gaugeY-5,12); // video_smallchar(12,gaugeY-5,12); t++ ; // 1/60 second counter //draw the new one // gaugeY=84-(t>>1); // video_line(6,gaugeY,14,gaugeY,1); sprintf(ts,"%03d",(t>>1)); // video_smallchar(8,gaugeY-5,ts[1]-0x30); // video_smallchar(12,gaugeY-5,ts[2]-0x30); //keep track of seconds //erase the last gauge entry // gaugeY=84-(t>>1); // video_line(6,gaugeY,15,gaugeY,0); // video_smallchar(8,gaugeY-5,12); // video_smallchar(12,gaugeY-5,12); if(t > 59) { t=0; //inc second count time++; //print the time sprintf(ts,"%05d",time); video_putsmalls(36,83,ts+1); } if(t== 0 || t == 30) { //udate figure if (figure==0) { figure=1; video_putchar(40,75,37); } else { figure=0; video_putchar(40,75,36); } } } //line 231 } //while } //main