
Appendix 2:  Video Code
//Gustavo
Bitdinger - gbb7
//Rangarajan
Rajagopalan - rr234
//ECE 476 Final
Project - Weatherdog 
//Mon. May 2,
2005
#pragma regalloc-    //I allocate the
registers myself
#pragma optsize-     //optimize for
speed     
                    
#include <Mega32.h>   
#include <stdio.h>
#include <stdlib.h> 
#include <math.h> 
#include <delay.h>  
#include <string.h>
//cycles =
63.625 * 16 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
#define begin {
#define end   } 
//screen line
definitions
#define ScreenTop 30
#define ScreenBot 230
#define width           126
#define length          99
#define inner_top       11
#define inner_bottom 76   
//NOTE that v1
to v8 and i must be in registers!  
register char
v1 @4; 
register char
v2 @5;
register char
v3 @6;
register char
v4 @7;
register char
v5 @8;
register char
v6 @9;
register char
v7 @10;
register char
v8 @11; 
register int
i @12;
register int
j @13;
#define LCDwidth 16
//define some
states
#define PLAY  0
#define WAIT1 1
#define WAIT2 2 
#pragma regalloc+ 
//video
synchronizationvariables
char syncON, syncOFF; 
int LineCount;
unsigned char
keyboard_input;  //input
from EITHER keyboard or PC
                                      
char screen[1600], t, ts[10],
temp_string[2];  
//some strings
to print to the TV
char program_string[] =
"WEATHERDOG";
char copyright_string[] =
"C.2005";
char input_string[] = "SEARCH@ICAO@CODE:@";
char result_temperature[] =
"TEMP@DEG@F@@@";
char result_humidity[] =
"HUMID@PERCENT";
char result_wind[] = "WIND
MPH@@@@@";
char result_visibility[] =
"VISIBILITY@MI";
char blankStr[] = "         ";
char blankStr1[] = "           ";
char blankStr2[] = "
";
char small_blankStr[] =
"@@@@@@@@@";                 
char searching[] =
"SEARCHING";
int index;  //index of where
cursor for input search is     
int index1;  //index for where
cursor of return value from PC is
unsigned char
blank_clear;  //a
state variable that decides what on the screen has been cleared on a PC return
of data
unsigned char
done_clear;  //indicates
that all screen clearing has been finished
unsigned char
from_pc;  //indicates
if input over SPI is from keyboard or PC              
unsigned char
tv_position;  //indicates
which parameter returned by the PC is being output to the TV
unsigned char
not_displayed;  //indicates
if a character is unknown and thus not to be displayed
 
//Point plot
lookup table   
//One bit masks
flash char
pos[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};                  
//define some
character bitmaps
//5x7 characters
flash char bitmap[41][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,
      0b10001000,
      //<space> = ']'
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      //.
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b01000100,
      0b00000000,
      //:   
      0b00000000,
      0b01000100,
      0b00000000,
      0b00000000,
      0b00000000,
      0b01000100,
      0b00000000
};
//================================
//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]={ 
      //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
};
//=================================//plot
one point 
//at x,y with
color 1=white 0=black 2=invert 
#pragma warn-
void video_pt(char x, char y, char c)
begin   
      
      #asm
      ;  i=(x>>3) + ((int)y<<4) ;  
the byte with the pixel in it
      push r16
      ldd r30,y+2             ;get
x
      lsr r30
      lsr r30
      lsr r30                 ;divide x by 8
      ldd r12,y+1             ;get
y
            lsl
r12                 ;mult
y by 16
            clr
r13
      lsl r12
      rol r13
      lsl r12
      rol r13
      lsl r12
      rol r13
      add r12, r30      ;add in x/8
      
      ;v2 = screen[i];   r5
        ;v3 = pos[x & 7];  r6
      ;v4 = c            r7
      ldi r30,low(_screen)
      ldi r31,high(_screen)
      add r30, r12
      adc r31, r13
      ld r5,Z           ;get screen byte
      ldd r26,y+2             ;get
x
      ldi r27,0
      andi r26,0x07          
;form x & 7 
      ldi r30,low(_pos*2)  
      ldi r31,high(_pos*2)
      add r30,r26
      adc r31,r27
      lpm r6,Z
      ld r16,y          ;get c 
       
       ;if
(v4==1) screen[i] = v2 | v3 ; 
       ;if
(v4==0) screen[i] = v2 & ~v3; 
       ;if
(v4==2) screen[i] = v2 ^ v3 ; 
       
       cpi r16,1
       brne tst0
       or 
r5,r6
       tst0:
       cpi r16,0
       brne tst2 
       com r6
       and r5,r6
       tst2:
       cpi r16,2
       brne writescrn
       eor r5,r6
       writescrn:
            ldi
r30,low(_screen)
      ldi r31,high(_screen)
      add r30, r12
      adc r31, r13
      st Z, r5          ;write the byte back to the screen
      
      pop r16
      #endasm
       
end
#pragma warn+
//=================================//
put a big character on the screen
// c is index
into bitmap
void video_putchar(char x, char y, char c)  
begin 
    v7 = x;
    for (v6=0;v6<7;v6++)
    begin
        v1 = bitmap[c][v6]; 
        v8 = y+v6;
        video_pt(v7,   v8, (v1 & 0x80)==0x80);  
        video_pt(v7+1, v8, (v1 &
0x40)==0x40); 
        video_pt(v7+2, v8, (v1 &
0x20)==0x20);
        video_pt(v7+3, v8, (v1 & 0x10)==0x10);
        video_pt(v7+4, v8, (v1 &
0x08)==0x08);
    end
end
//=================================//
put a string of big characters on the screen
void video_puts(char x, char y, char *str)
begin
      char i ;
      for (i=0; str[i]!=0; i++)
      begin  
            if (str[i]>=0x30
&& str[i]<0x3a) begin  //a number
                  video_putchar(x,y,str[i]-0x30);    
            end
            else if (str[i] == 32) begin  //a space
                  video_putchar(x,y,38);
            end         
            else if (str[i] == 8) begin  //a backspace
                  video_putchar(x,y,38);
            end
            else if (str[i] == 46) begin  //a ':'
                  video_putchar(x,y,39); 
            end
            else if (str[i] == 58) begin  //a '.'
                  video_putchar(x,y,40);
            end       
            else if (str[i]>=65 && str[i]<=90)
begin  //an
alphabetical character
                  video_putchar(x,y,str[i]-0x40+9);
          end 
          else begin  //undefined
            not_displayed = 1;
          end
            x = x+6;
      end
end      
      
//=================================//
put a small character on the screen - special mode
// x-cood must
be divisible by 4 
// c is index
into bitmap
void video_smallchar(char x, char y, char c)  
begin 
      char mask;
      
      i=((int)x>>3) + ((int)y<<4) ;
      if (x == (x & 0xf8)) mask =
0x0f;     //f8
      else mask = 0xf0;
      
      screen[i] =    (screen[i]
& mask) | (smallbitmap[c][0] & ~mask); 
      screen[i+16]
= (screen[i+16] & mask) | (smallbitmap[c][1] & ~mask);
        screen[i+32] = (screen[i+32] &
mask) | (smallbitmap[c][2] & ~mask);
        screen[i+48] = (screen[i+48] &
mask) | (smallbitmap[c][3] & ~mask);
      screen[i+64]
= (screen[i+64] & mask) | (smallbitmap[c][4] & ~mask); 
end  
//=================================//
put a string of small characters on the screen
// x-cood must
be divisible by 4 
void video_putsmalls(char x, char y, char *str)
begin
      char i ;
      for (i=0; str[i]!=0; i++)
      begin  
            if (str[i]>=0x30
&& str[i]<=0x3a) begin  //a number
                  video_smallchar(x,y,str[i]-0x30);  
            end
            else if (str[i] == ' ') begin  //a space
                  video_smallchar(x,y,12);
            end
            else begin  //an alphabetical
character
                  video_smallchar(x,y,str[i]-0x40+12);
            end
            x = x+4;    
      end
end 
 
//=================================//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(char x1, char y1, char x2, char y2, char c)
begin   
      int e;
      signed char
dx,dy,j, temp;
      signed char
s1,s2, xchange;
        signed char x,y;
        
      x = x1;
      y = y1;
      dx = cabs(x2-x1);
      dy = cabs(y2-y1
      );
      s1 = csign(x2-x1);
      s2 = csign(y2-y1);
      xchange = 0;   
      if (dy>dx)
      begin
            temp = dx;
            dx = dy;
            dy = temp;
            xchange = 1;
      end 
      e = ((int)dy<<1) -
dx;   
      for (j=0; j<=dx; j++)
      begin
            video_pt(x,y,c) ; 
            if (e>=0)
            begin
                  if (xchange==1) x =
x + s1;
                  else y = y + s2;
                  e = e - ((int)dx<<1);
            end
            if (xchange==1) y = y +
s2;
            else x = x + s1;
            e = e + ((int)dy<<1);
      end
end
//=================================//return
the value of one point 
//at x,y with
color 1=white 0=black 2=invert                                                   
char video_set(char x, char y)
begin
      //The following construction 
      //detects exactly one bit at the x,y location
      i=((int)x>>3) + ((int)y<<4) ; 
    return (
screen[i] & 1<<(7-(x & 0x7)));  
  
end     
//=================================//This
is the sync generator and raster generator. It MUST be entered from 
//sleep mode to
get accurate timing of the sync pulses
#pragma warn-
interrupt [TIM1_COMPA] void t1_cmpA(void)
begin
      SPCR = 0b01000000; 
      
  //start the
Horizontal sync pulse    
  PORTD = syncON;  
  //update the curent
scanline number
  LineCount ++ ;   
  //begin inverted
(Vertical) synch after line 247
  if
(LineCount==248) begin 
    syncON = 0b00100000;
    syncOFF = 0;
  end
  //back to regular
sync after line 250
  if
(LineCount==251) begin
    syncON = 0;
    syncOFF = 0b00100000;
  end  
         
  //start new frame
after line 262
  if
(LineCount==263) 
  begin
     LineCount = 1;
  end  
  
  delay_us(2); //adjust
to make 5 us pulses
  //end sync pulse
  PORTD= syncOFF; 
  
  if
(LineCount<ScreenBot && LineCount>=ScreenTop) 
    begin 
       
       //compute byte
index for beginning of the next line
       //left-shift 4
would be individual lines
       // <<3
means line-double the pixels 
       //The 0xfff8
truncates the odd line bit
       //i=(LineCount-ScreenTop)<<3
& 0xfff8; //
       
       #asm
       push r16
       lds  
r12, _LineCount
       lds  
r13, _Linecount+1
       ldi  
r16, 30
       sub 
r12, r16 
       ldi 
r16,0
       sbc 
r13, r16 
       lsl 
r12
       rol 
r13
       lsl 
r12
       rol 
r13
       lsl 
r12    
       rol 
r13
       mov 
r16,r12
       andi r16,0xf0
       mov 
r12,r16
       pop r16 
       #endasm
        
       //load 16
registers with screen info
       #asm
       push r14
       push r15
       push r16
       push r17
       push r18 
       push r19 
       push r26
       push r27
       
       ldi 
r26,low(_screen)   ;base address
of screen
       ldi 
r27,high(_screen)   
       add 
r26,r12            ;offset into
screen (add i)
       adc 
r27,r13
       ld  
r4,x+              ;load 16 registers
and inc pointer
       ld  
r5,x+
       ld  
r6,x+  
       ld  
r7,x+
       ld  
r8,x+ 
       ld  
r9,x+
       ld  
r10,x+  
       ld  
r11,x+
       ld  
r12,x+ 
       ld  
r13,x+
       ld  
r14,x+  
       ld  
r15,x+
       ld  
r16,x+   
       ld  
r17,x+  
       ld  
r18,x+
       ld  
r19,x 
       
       pop 
r27
       pop 
r26
       #endasm 
       delay_us(4);  //adjust to center
image on screen
       
       //blast 16
bytes to the screen   
       #asm
       ;but first a macro to make the code
shorter  
       ;the macro takes a register number as a parameter
       ;and dumps its bits serially to
portD.6   
       ;the nop can be eliminated to make the
display narrower
       .macro videobits ;regnum
        BST 
@0,7
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30  
      
      BST  @0,6
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30 
      
      BST  @0,5
      IN   R30,0x12
      BLD  R30,6 
      nop
      OUT  0x12,R30 
      
      BST  @0,4
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30 
      
      BST  @0,3
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30 
      
      BST  @0,2
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30 
      
      BST  @0,1
      IN   R30,0x12
      BLD  R30,6 
      nop
      OUT  0x12,R30 
      
      BST  @0,0
      IN   R30,0x12
      BLD  R30,6
      nop
      OUT  0x12,R30 
       .endm    
        
      videobits r4 ;video line -- byte 1
        videobits r5 ;byte 2  
        videobits r6 ;byte 3
        videobits r7 ;byte 4
        videobits r8 ;byte 5
        videobits r9 ;byte 6
        videobits r10 ;byte 7
        videobits r11 ;byte 8 
        videobits r12 ;byte 9
        videobits r13 ;byte 10  
        videobits r14 ;byte 11
        videobits r15 ;byte 12
        videobits r16 ;byte 13
        videobits r17 ;byte 14
        videobits r18 ;byte 15
        videobits r19 ;byte 16
      clt   ;clear video after
the last pixel on the line
      IN   R30,0x12
      BLD  R30,6
      OUT  0x12,R30
                                                
       pop r19
       pop r18
       pop r17 
       pop r16 
       pop r15
       pop r14
       #endasm
              
    end  
end  
#pragma warn+
//=================================//
Initializations
void initialize(void) begin
 
      //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
= 0x60;            //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
  
      //initialize synch constants 
      LineCount
= 1;
      syncON
= 0b00000000;
      syncOFF
= 0b00100000;  
      //init software timer
      t=0;  
      //enable sleep mode
      MCUCR
= 0b10000000;  //VIDEO
ONLY
      //Print "WEATHERDOG" 
      video_puts(3,3,program_string);     
      //Print "C.2005" 
      video_puts(90,3,copyright_string); 
     
      //side lines 
      video_line(0,0,0,length,1);
      video_line(width,0,width,length,1);
  
      //top & bottom lines
      video_line(0,0,width,0,1);
      video_line(0,length,width,length,1);
      video_line(0,inner_top,width,inner_top,1); 
      
      //middle line
      video_line(0,34,width,34,1);
      
      from_pc = 0;   
      video_putsmalls(4,16,input_string); 
                                             
    video_putsmalls(4,50,result_temperature);
    video_putsmalls(4,60,result_humidity);
      video_putsmalls(4,70,result_wind);
      video_putsmalls(4,80,result_visibility);    
    
    
    //bit 7:
interrupt enable
      //bit 6: SPI enable
      //bit 5: data bit order, 0:MSB first
      //bit 4: master/slave select, 0:slave
      //bit 3: SCK polarity
      //bit 2: SCK phase
      //bits 1 and 0: SCK speed; 00=CLK/4
      SPCR = 0b01000000;                     
      //bit 7: SCK
      //bit 6: MISO (master in, slave out)
      //bit 5: MOSI (master out, slave in)
      //bit 4: !SS (slave select)
      DDRB = 0x01001111;
      
    index = 3; 
//start search string index at x=3
    index1 = 65;  //place all return
values from pc at x=65
    blank_clear = 0;  
    done_clear = 0; 
    tv_position = 0;      
    not_displayed = 0;
                                 
      #asm
("sei");
end
//=================================
void main(void) begin 
      initialize();
           
      while(1) begin 
            //stall here until next line
starts
            //sleep enable; mode=idle  
            //use sleep to make entry into
sync ISR uniform time  
         #asm
("sleep");
         if (LineCount==231) begin              
                  if ((SPSR &
0x80)>>7) begin
                        
                        //clear everything before outputing keyboard stuff
                        if
(blank_clear == 8) begin
                              video_putsmalls(84,16,small_blankStr);  //blank out "searching"
indicator
                              done_clear = 1;
                              blank_clear = 0;
                              keyboard_input = SPDR;  
                        end
                        else if (blank_clear == 7) begin
                              video_puts(56,26,blankStr);  //clear second half
of old search string
                              blank_clear = 8;
                              keyboard_input = SPDR;
                        end 
                        else if (blank_clear == 6) begin
                              video_puts(65,78,blankStr);  //clear old return
visibility value
                           
blank_clear =7;
                           
keyboard_input = SPDR;
                        end    
                        else if (blank_clear == 5) begin
                              video_puts(65,68,blankStr);  //clear old return
wind value
                           
blank_clear = 6;
                           
keyboard_input = SPDR;
                        end
                        else if (blank_clear == 4) begin
                           
video_puts(65,58,blankStr);  //clear old return humidity value
                           
blank_clear = 5;
                           
keyboard_input = SPDR;
                        end
                        else if (blank_clear == 3) begin
                              video_puts(65,48,blankStr);  //clear old return
temperature value
                              blank_clear = 4;
                              keyboard_input = SPDR;
                        end                                                                  
                        else if (blank_clear
== 2) begin  //acts
as a second short delay
                              blank_clear = 3;
                              keyboard_input = SPDR;
                        end
                        else if (blank_clear == 1) begin  //acts as a short
delay
                              blank_clear = 2; 
                              keyboard_input = SPDR;  //concurrently get
next keyboard_input from SPI interface
                        end
                        else if (blank_clear
== 0) begin
                              keyboard_input
= SPDR;  //this
always happens, whether it's a keyboard input or pc input
                              if ((keyboard_input == ';') && (tv_position
== 0)) begin  //first
item sent back
                                    video_puts(3,26,blankStr);  //clear first half
of old search string
                                    blank_clear
= 1;  //begin
process of clearing stuff on screen
                              tv_position++;  //indicates now
that are going to print out the time to the TV
                              from_pc
= 1;
                              index
= 3;
                                    index1
= 65;
                              end                                     
                              else if
(keyboard_input == ';') begin //subsequent item sent
back
                              from_pc
= 1;
                              tv_position++;
                              index1
= 65;
                              end  
                        end
                        
                        if (from_pc == 0) begin
                              temp_string[0]=
keyboard_input;         
                              temp_string[1]=0;
                              if (keyboard_input == 8) begin //a backspace - only do if there is something to delete.
                                    index
= index-6;  //adjust
search string index            
                                    video_puts(index,26,temp_string);  //output the new
character from the pc
                              end
                              else if
(keyboard_input == 0) begin //an enter
                                    video_putsmalls(84,16,searching);  //output searching
indicator
                              end
                              else begin  //anything else
                                    video_puts(index,26,temp_string);  //output it
                                    index
= index+6;  //adjust
search string index
                              end
                        
                        end
                        else if (keyboard_input
!= ';') begin  //dealing
with a pc input
                              temp_string[0]
= keyboard_input;
                              temp_string[1] = 0;
                              if (tv_position == 1) begin  //time
                                    //adjustment
of 62 is so that time outputs starting from left of screen
                                    video_puts(index1-62,38,blankStr2);
                                    video_puts(index1-62,38,temp_string);
                              end   
                              else if (tv_position
== 2) begin  //temperature
                                    video_puts(index1,48,temp_string);
                              end
                              else if (tv_position
== 3) begin  //humidity
                                    video_puts(index1,58,temp_string);
                              end
                              else if (tv_position
== 4) begin  //wind
                                    video_puts(index1,68,temp_string);
                              end
                              else if (tv_position
== 5) begin  //visibility
                                    video_puts(index1,78,temp_string);
                              end                            
                              //catch for characters that are not displayed
                              if (not_displayed == 0) begin  
                                    index1
= index1+6;
                              end
                              else begin
                                    not_displayed
= 0;
                              end
                              if ((keyboard_input == 0x00) && (tv_position
== 5)) begin  //end
of inputs from PC for a search.
                                    from_pc
= 0;
                                    done_clear
= 0;
                                    tv_position
= 0;  
                              end
                  end
                  
            end    
      end
      end  //while                                                 
                                      
end  //main