//
// File:   cstringdisp.v
// Date:   24-Oct-05
// Author: I. Chuang, C. Terman
//
// Display an ASCII encoded character string in a video window at some
// specified x,y pixel location.
//
// INPUTS:
//
//   vclock       - video pixel clock
//   hcount       - horizontal (x) location of current pixel
//   vcount       - vertical (y) location of current pixel
//   cstring      - character string to display (8 bit ASCII for each char)
//   cx,cy        - pixel location (upper left corner) to display string at
//
// OUTPUT:
//
//   pixel        - video pixel value to display at current location
//
// PARAMETERS:
//
//   NCHAR        - number of characters in string to display
//   NCHAR_BITS   - number of bits to specify NCHAR
//
// pixel should be OR'ed (or XOR'ed) to your video data for display.
//
// Each character is 8x12, but pixels are doubled horizontally and vertically
// so fonts are magnified 2x.  On an XGA screen (1024x768) you can fit
// 64 x 32 such characters.
//
// Needs font_rom.v and font_rom.ngo
//
// For different fonts, you can change font_rom.  For different string 
// display colors, change the assignment to cpixel.


//////////////////////////////////////////////////////////////////////////////
//
// video character string display
//
//////////////////////////////////////////////////////////////////////////////

module char_string_display (vclock,hcount,vcount,pixel,cstring,cx,cy);

   parameter NCHAR = 8;	// number of 8-bit characters in cstring
   parameter NCHAR_BITS = 3; // number of bits in NCHAR

   input vclock;	// 65MHz clock
   input [10:0] hcount;	// horizontal index of current pixel (0..1023)
   input [9:0] 	vcount; // vertical index of current pixel (0..767)
   output reg [2:0] pixel;	// char display's pixel
   input [NCHAR*8-1:0] cstring;	// character string to display
   input [10:0] cx;
   input [9:0] 	cy;

   // 1 line x 8 character display (8 x 12 pixel-sized characters)

//   wire [10:0] 	hoff = hcount-1-cx;
      wire [10:0] 	hoff = hcount-1-cx + 5;
  
   wire [9:0] 	voff = vcount-cy;
//   wire [NCHAR_BITS-1:0] column = NCHAR-1-hoff[NCHAR_BITS-1+4:4];  // < NCHAR
   wire [NCHAR_BITS-1:0] column = NCHAR-1-hoff[NCHAR_BITS-1+3:3];  // < NCHAR
//   wire [2:0] 	h = hoff[3:1];            // 0 .. 7
//   wire [3:0] 	v = voff[4:1];		  // 0 .. 11

   wire [2:0] 	h = hoff[2:0];            // 0 .. 7
   wire [3:0] 	v = voff[3:0];		  // 0 .. 11

   // look up character to display (from character string)
   reg [7:0]  char;
   integer  n;
   always @(*) 
     for (n=0 ; n<8 ; n = n+1 )		// 8 bits per character (ASCII)
       char[n] <= cstring[column*8+n];

   // look up raster row from font rom
   wire reverse = char[7];
   wire [10:0] font_addr = char[6:0]*12 + v;    // 12 bytes per character
   wire [7:0]  font_byte;
   font_rom f(.clka(vclock), .ena(1), .addra(font_addr), .douta(font_byte)); 
   

   // generate character pixel if we're in the right h,v area
   wire [2:0] cpixel = (font_byte[7 - h] ^ reverse) ? 7 : 0;
//   wire dispflag = ((hcount > cx) & (vcount >= cy) & (hcount <= cx+NCHAR*16)
//		    & (vcount < cy + 24));

   wire dispflag = ((hcount > cx) & (vcount >= cy) & (hcount <= cx+NCHAR*8)
		    & (vcount < cy + 12));
		    		    
	always @(posedge vclock)	    
    pixel <= dispflag ? cpixel : 0;

endmodule
