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  

 

Back to Main Page