OpenCores
URL https://opencores.org/ocsvn/rtftextcontroller/rtftextcontroller/trunk

Subversion Repositories rtftextcontroller

[/] [rtftextcontroller/] [trunk/] [rtl/] [verilog/] [GFX_TextController.sv] - Diff between revs 29 and 30

Only display areas with differences | Details | Blame | View Log

Rev 29 Rev 30
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2006-2020  Robert Finch, Waterloo
//   \\__/ o\    (C) 2006-2020  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch@finitron.ca
//     \/_//     robfinch@finitron.ca
//       ||
//       ||
//
//
//      GFX_TextController.sv
//      GFX_TextController.sv
//              text controller
//              text controller
//
//
// BSD 3-Clause License
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// modification, are permitted provided that the following conditions are met:
//
//
// 1. Redistributions of source code must retain the above copyright notice, this
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//    list of conditions and the following disclaimer.
//
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//    and/or other materials provided with the distribution.
//
//
// 3. Neither the name of the copyright holder nor the names of its
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//    this software without specific prior written permission.
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
//
//
//      Text Controller
//      Text Controller
//
//
//      FEATURES
//      FEATURES
//
//
//      This core requires an external timing generator to provide horizontal
//      This core requires an external timing generator to provide horizontal
//      and vertical sync signals, but otherwise can be used as a display
//      and vertical sync signals, but otherwise can be used as a display
//  controller on it's own. However, this core may also be embedded within
//  controller on it's own. However, this core may also be embedded within
//  another core such as a VGA controller.
//  another core such as a VGA controller.
//
//
//      Window positions are referenced to the rising edge of the vertical and
//      Window positions are referenced to the rising edge of the vertical and
//      horizontal sync pulses.
//      horizontal sync pulses.
//
//
//      The core includes an embedded dual port RAM to hold the screen
//      The core includes an embedded dual port RAM to hold the screen
//      characters.
//      characters.
//
//
//  The controller expects a 128kB memory region to be reserved.
//  The controller expects a 128kB memory region to be reserved.
//
//
//  Memory Map:
//  Memory Map:
//  00000-0FFFF   display ram
//  00000-0FFFF   display ram
//  17F00-17FFF   controller registers
//  17F00-17FFF   controller registers
//  18000-1FFFF   character bitmap ram
//  18000-1FFFF   character bitmap ram
//
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Registers
// Registers
//
//
// 00h
// 00h
//      7 - 0                    cccccccc  number of columns (horizontal displayed number of characters)
//      7 - 0                    cccccccc  number of columns (horizontal displayed number of characters)
//      15- 8                    rrrrrrrr        number of rows (vertical displayed number of characters)
//      15- 8                    rrrrrrrr        number of rows (vertical displayed number of characters)
//  19-16                dddd  character output delay
//  19-16                dddd  character output delay
//      43-32       nnnn nnnnnnnn  window left       (horizontal sync position - reference for left edge of displayed)
//      43-32       nnnn nnnnnnnn  window left       (horizontal sync position - reference for left edge of displayed)
//      59-48       nnnn nnnnnnnn  window top        (vertical sync position - reference for the top edge of displayed)
//      59-48       nnnn nnnnnnnn  window top        (vertical sync position - reference for the top edge of displayed)
// 01h
// 01h
//       4- 0               nnnnn  maximum scan line (char ROM max value is 7)
//       4- 0               nnnnn  maximum scan line (char ROM max value is 7)
//  11- 8                                                          wwww  pixel size - width
//  11- 8                                                          wwww  pixel size - width
//  15-12                                                          hhhh  pixel size - height
//  15-12                                                          hhhh  pixel size - height
//  24                      r  reset state bit
//  24                      r  reset state bit
//  48-52               nnnnn  yscroll
//  48-52               nnnnn  yscroll
//  56-60               nnnnn  xscroll
//  56-60               nnnnn  xscroll
// 02h
// 02h
//      20- 0   cccccccc cccccccc  color code for transparent background RGB 7,7,7
//      20- 0   cccccccc cccccccc  color code for transparent background RGB 7,7,7
//  63-32   cccc...cccc        border color ZRGB 8,8,8,8
//  63-32   cccc...cccc        border color ZRGB 8,8,8,8
// 03h
// 03h
//   4- 0               eeeee    cursor end
//   4- 0               eeeee    cursor end
//   7- 5                 bbb  blink control
//   7- 5                 bbb  blink control
//                             BP: 00=no blink
//                             BP: 00=no blink
//                             BP: 01=no display
//                             BP: 01=no display
//                             BP: 10=1/16 field rate blink
//                             BP: 10=1/16 field rate blink
//                             BP: 11=1/32 field rate blink
//                             BP: 11=1/32 field rate blink
//  12- 8               sssss  cursor start
//  12- 8               sssss  cursor start
//  15-14                                                                        tt      cursor image type (box, underline, sidebar, asterisk
//  15-14                                                                        tt      cursor image type (box, underline, sidebar, asterisk
//  47-32   aaaaaaaa aaaaaaaa    cursor position
//  47-32   aaaaaaaa aaaaaaaa    cursor position
// 04h
// 04h
//  15- 0   aaaaaaaa aaaaaaaa  start address (index into display memory)
//  15- 0   aaaaaaaa aaaaaaaa  start address (index into display memory)
// 05h
// 05h
//  15-0    aaaaaaaa aaaaaaaa  font address
//  15-0    aaaaaaaa aaaaaaaa  font address
// 07h
// 07h
//      150 - - aaaaaaaa aaaaaaaa  light pen position
//      150 - - aaaaaaaa aaaaaaaa  light pen position
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
//
// ============================================================================
// ============================================================================
//`define USE_CLOCK_GATE
//`define USE_CLOCK_GATE
module GFX_TextController(
module GFX_TextController(
        rst_i, clk_i, cs_i,
        rst_i, clk_i, cs_i,
        cti_i, cyc_i, stb_i, ack_o, wr_i, sel_i, adr_i, dat_i, dat_o,
        cti_i, cyc_i, stb_i, ack_o, wr_i, sel_i, adr_i, dat_i, dat_o,
        lp_i,
        lp_i,
        dot_clk_i, hsync_i, vsync_i, blank_i, border_i, zrgb_i, zrgb_o, xonoff_i
        dot_clk_i, hsync_i, vsync_i, blank_i, border_i, zrgb_i, zrgb_o, xonoff_i
);
);
parameter num = 4'd1;
parameter num = 4'd1;
parameter COLS = 8'd64;
parameter COLS = 8'd64;
parameter ROWS = 8'd33;
parameter ROWS = 8'd33;
// Syscon
// Syscon
input  rst_i;                   // reset
input  rst_i;                   // reset
input  clk_i;                   // clock
input  clk_i;                   // clock
// Slave signals
// Slave signals
input  cs_i;            // circuit select
input  cs_i;            // circuit select
input  [2:0] cti_i;
input  [2:0] cti_i;
input  cyc_i;                   // valid bus cycle
input  cyc_i;                   // valid bus cycle
input  stb_i;           // data strobe
input  stb_i;           // data strobe
output ack_o;                   // data acknowledge
output ack_o;                   // data acknowledge
input  wr_i;                    // write
input  wr_i;                    // write
input  [ 7:0] sel_i;    // byte lane select
input  [ 7:0] sel_i;    // byte lane select
input  [16:0] adr_i;    // address
input  [16:0] adr_i;    // address
input  [63:0] dat_i;    // data input
input  [63:0] dat_i;    // data input
output reg [63:0] dat_o;        // data output
output reg [63:0] dat_o;        // data output
input lp_i;                             // light pen
input lp_i;                             // light pen
// Video signals
// Video signals
input dot_clk_i;                // video dot clock
input dot_clk_i;                // video dot clock
input hsync_i;                  // end of scan line
input hsync_i;                  // end of scan line
input vsync_i;                  // end of frame
input vsync_i;                  // end of frame
input blank_i;                  // blanking signal
input blank_i;                  // blanking signal
input border_i;                 // border area
input border_i;                 // border area
input [31:0] zrgb_i;            // input pixel stream
input [31:0] zrgb_i;            // input pixel stream
output reg [31:0] zrgb_o;       // output pixel stream
output reg [31:0] zrgb_o;       // output pixel stream
input xonoff_i;
input xonoff_i;
integer n;
integer n;
reg controller_enable;
reg controller_enable;
reg [31:0] bkColor32, bkColor32d;       // background color
reg [31:0] bkColor32, bkColor32d;       // background color
reg [31:0] fgColor32, fgColor32d;       // foreground color
reg [31:0] fgColor32, fgColor32d;       // foreground color
wire pix;                                 // pixel value from character generator 1=on,0=off
wire pix;                                 // pixel value from character generator 1=on,0=off
reg por;
reg por;
wire vclk;
wire vclk;
reg [63:0] rego;
reg [63:0] rego;
reg [5:0] yscroll;
reg [5:0] yscroll;
reg [5:0] xscroll;
reg [5:0] xscroll;
reg [11:0] windowTop;
reg [11:0] windowTop;
reg [11:0] windowLeft;
reg [11:0] windowLeft;
reg [ 7:0] numCols;
reg [ 7:0] numCols;
reg [ 7:0] numRows;
reg [ 7:0] numRows;
reg [ 7:0] charOutDelay;
reg [ 7:0] charOutDelay;
reg [ 1:0] mode;
reg [ 1:0] mode;
reg [ 5:0] maxRowScan;
reg [ 5:0] maxRowScan;
reg [ 5:0] maxScanpix;
reg [ 5:0] maxScanpix;
reg [ 5:0] cursorStart, cursorEnd;
reg [ 5:0] cursorStart, cursorEnd;
reg [15:0] cursorPos;
reg [15:0] cursorPos;
reg [1:0] cursorType;
reg [1:0] cursorType;
reg [15:0] fontAddress;
reg [15:0] fontAddress;
reg [15:0] startAddress;
reg [15:0] startAddress;
reg [ 2:0] rBlink;
reg [ 2:0] rBlink;
reg [31:0] bdrColor;            // Border color
reg [31:0] bdrColor;            // Border color
reg [ 3:0] pixelWidth;  // horizontal pixel width in clock cycles
reg [ 3:0] pixelWidth;  // horizontal pixel width in clock cycles
reg [ 3:0] pixelHeight; // vertical pixel height in scan lines
reg [ 3:0] pixelHeight; // vertical pixel height in scan lines
reg ecm;                // extended color mode
reg ecm;                // extended color mode
wire [11:0] hctr;               // horizontal reference counter (counts clocks since hSync)
wire [11:0] hctr;               // horizontal reference counter (counts clocks since hSync)
wire [11:0] scanline;   // scan line
wire [11:0] scanline;   // scan line
reg [ 7:0] row;         // vertical reference counter (counts rows since vSync)
reg [ 7:0] row;         // vertical reference counter (counts rows since vSync)
reg [ 7:0] col;         // horizontal column
reg [ 7:0] col;         // horizontal column
reg [ 5:0] rowscan;     // scan line within row
reg [ 5:0] rowscan;     // scan line within row
reg [ 5:0] colscan;     // pixel column number within cell
reg [ 5:0] colscan;     // pixel column number within cell
wire nxt_row;                   // when to increment the row counter
wire nxt_row;                   // when to increment the row counter
wire nxt_col;                   // when to increment the column counter
wire nxt_col;                   // when to increment the column counter
reg [ 5:0] bcnt;                // blink timing counter
reg [ 5:0] bcnt;                // blink timing counter
wire blink;
wire blink;
reg  iblank;
reg  iblank;
reg [5:0] maxScanlinePlusOne;
reg [5:0] maxScanlinePlusOne;
wire nhp;                               // next horizontal pixel
wire nhp;                               // next horizontal pixel
wire ld_shft = nxt_col & nhp;
wire ld_shft = nxt_col & nhp;
// display and timing signals
// display and timing signals
reg [15:0] txtAddr;             // index into memory
reg [15:0] txtAddr;             // index into memory
reg [15:0] penAddr;
reg [15:0] penAddr;
wire [63:0] screen_ram_out;             // character code
wire [63:0] screen_ram_out;             // character code
wire [63:0] char_bmp;           // character ROM output
wire [63:0] char_bmp;           // character ROM output
wire [20:0] txtBkColor; // background color code
wire [20:0] txtBkColor; // background color code
wire [20:0] txtFgColor; // foreground color code
wire [20:0] txtFgColor; // foreground color code
wire [5:0] txtZorder;
wire [5:0] txtZorder;
reg  [20:0] txtTcCode;  // transparent color code
reg  [20:0] txtTcCode;  // transparent color code
reg  bgt, bgtd;
reg  bgt, bgtd;
wire [63:0] tdat_o;
wire [63:0] tdat_o;
wire [2:0] scanindex = rowscan[2:0];
wire [2:0] scanindex = rowscan[2:0];
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// bus interfacing
// bus interfacing
// Address Decoding
// Address Decoding
// I/O range Dx
// I/O range Dx
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Register the inputs
// Register the inputs
reg cs_rom, cs_reg, cs_text, cs_any;
reg cs_rom, cs_reg, cs_text, cs_any;
reg [16:0] radr_i;
reg [16:0] radr_i;
reg [63:0] rdat_i;
reg [63:0] rdat_i;
reg rwr_i;
reg rwr_i;
reg [7:0] rsel_i;
reg [7:0] rsel_i;
reg [7:0] wrs_i;
reg [7:0] wrs_i;
always @(posedge clk_i)
always @(posedge clk_i)
        cs_rom <= cs_i && cyc_i && stb_i && (adr_i[16:8] >  9'h17F);
        cs_rom <= cs_i && cyc_i && stb_i && (adr_i[16:8] >  9'h17F);
always @(posedge clk_i)
always @(posedge clk_i)
        cs_reg <= cs_i && cyc_i && stb_i && (adr_i[16:8] == 9'h17F);
        cs_reg <= cs_i && cyc_i && stb_i && (adr_i[16:8] == 9'h17F);
always @(posedge clk_i)
always @(posedge clk_i)
        cs_text <= cs_i && cyc_i && stb_i && (adr_i[16:8] < 9'h100);
        cs_text <= cs_i && cyc_i && stb_i && (adr_i[16:8] < 9'h100);
always @(posedge clk_i)
always @(posedge clk_i)
        cs_any <= cs_i && cyc_i && stb_i;
        cs_any <= cs_i && cyc_i && stb_i;
always @(posedge clk_i)
always @(posedge clk_i)
        wrs_i <= {8{wr_i}} & sel_i;
        wrs_i <= {8{wr_i}} & sel_i;
always @(posedge clk_i)
always @(posedge clk_i)
        rwr_i <= wr_i;
        rwr_i <= wr_i;
always @(posedge clk_i)
always @(posedge clk_i)
        rsel_i <= sel_i;
        rsel_i <= sel_i;
always @(posedge clk_i)
always @(posedge clk_i)
        radr_i[16:3] <= adr_i[16:3];
        radr_i[16:3] <= adr_i[16:3];
// Recreate LSB's for charram
// Recreate LSB's for charram
always @(posedge clk_i)
always @(posedge clk_i)
begin
begin
  radr_i[0] <= sel_i[1]|sel_i[3]|sel_i[5]|sel_i[7];
  radr_i[0] <= sel_i[1]|sel_i[3]|sel_i[5]|sel_i[7];
  radr_i[1] <= |sel_i[3:2] | |sel_i[7:6];
  radr_i[1] <= |sel_i[3:2] | |sel_i[7:6];
  radr_i[2] <= |sel_i[7:4];
  radr_i[2] <= |sel_i[7:4];
end
end
always @(posedge clk_i)
always @(posedge clk_i)
        rdat_i <= dat_i;
        rdat_i <= dat_i;
// Register outputs
// Register outputs
// The output is "sticky" to give more hold time.
// The output is "sticky" to give more hold time.
always @(posedge clk_i)
always @(posedge clk_i)
        casez({cs_rom,cs_reg,cs_text})
        casez({cs_rom,cs_reg,cs_text})
        3'b01?: dat_o <= rego;
        3'b01?: dat_o <= rego;
        3'b001: dat_o <= tdat_o;
        3'b001: dat_o <= tdat_o;
        default:        dat_o <= dat_o;
        default:        dat_o <= dat_o;
        endcase
        endcase
//always @(posedge clk_i)
//always @(posedge clk_i)
//      if (cs_text) begin
//      if (cs_text) begin
//              $display("TC WRite: %h %h", adr_i, dat_i);
//              $display("TC WRite: %h %h", adr_i, dat_i);
//              $stop;
//              $stop;
//      end
//      end
// - there is a four cycle latency for reads, an ack is generated
// - there is a four cycle latency for reads, an ack is generated
//   after the synchronous RAM read
//   after the synchronous RAM read
// - writes can be acknowledged right away.
// - writes can be acknowledged right away.
ack_gen #(
ack_gen #(
        .READ_STAGES(5),
        .READ_STAGES(5),
        .WRITE_STAGES(1),
        .WRITE_STAGES(1),
        .REGISTER_OUTPUT(1)
        .REGISTER_OUTPUT(1)
)
)
uag1 (
uag1 (
        .clk_i(clk_i),
        .clk_i(clk_i),
        .ce_i(1'b1),
        .ce_i(1'b1),
        .i(cs_any),
        .i(cs_any),
        .we_i(cs_any & rwr_i),
        .we_i(cs_any & rwr_i),
        .o(ack_o)
        .o(ack_o)
);
);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
`ifdef USE_CLOCK_GATE
`ifdef USE_CLOCK_GATE
BUFHCE ucb1 (.I(dot_clk_i), .CE(controller_enable), .O(vclk));
BUFHCE ucb1 (.I(dot_clk_i), .CE(controller_enable), .O(vclk));
`else
`else
assign vclk = dot_clk_i;
assign vclk = dot_clk_i;
`endif
`endif
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Video Memory
// Video Memory
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Address Calculation:
// Address Calculation:
//  - Simple: the row times the number of  cols plus the col plus the
//  - Simple: the row times the number of  cols plus the col plus the
//    base screen address
//    base screen address
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
reg [15:0] rowcol;
reg [15:0] rowcol;
always @(posedge vclk)
always @(posedge vclk)
  if (ld_shft)
  if (ld_shft)
          txtAddr <= startAddress + rowcol + col;
          txtAddr <= startAddress + rowcol + col;
// Register read-back memory
// Register read-back memory
// Allows reading back of register values by shadowing them with ram
// Allows reading back of register values by shadowing them with ram
wire [3:0] rrm_adr = radr_i[6:3];
wire [3:0] rrm_adr = radr_i[6:3];
wire [63:0] rrm_o;
wire [63:0] rrm_o;
regReadbackMem #(.WID(8)) rrm0L
regReadbackMem #(.WID(8)) rrm0L
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[0]),
  .we(rwr_i & rsel_i[0]),
  .i(rdat_i[7:0]),
  .i(rdat_i[7:0]),
  .o(rrm_o[7:0])
  .o(rrm_o[7:0])
);
);
regReadbackMem #(.WID(8)) rrm0H
regReadbackMem #(.WID(8)) rrm0H
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[1]),
  .we(rwr_i & rsel_i[1]),
  .i(rdat_i[15:8]),
  .i(rdat_i[15:8]),
  .o(rrm_o[15:8])
  .o(rrm_o[15:8])
);
);
regReadbackMem #(.WID(8)) rrm1L
regReadbackMem #(.WID(8)) rrm1L
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[2]),
  .we(rwr_i & rsel_i[2]),
  .i(rdat_i[23:16]),
  .i(rdat_i[23:16]),
  .o(rrm_o[23:16])
  .o(rrm_o[23:16])
);
);
regReadbackMem #(.WID(8)) rrm1H
regReadbackMem #(.WID(8)) rrm1H
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[3]),
  .we(rwr_i & rsel_i[3]),
  .i(rdat_i[31:24]),
  .i(rdat_i[31:24]),
  .o(rrm_o[31:24])
  .o(rrm_o[31:24])
);
);
regReadbackMem #(.WID(8)) rrm2L
regReadbackMem #(.WID(8)) rrm2L
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[4]),
  .we(rwr_i & rsel_i[4]),
  .i(rdat_i[39:32]),
  .i(rdat_i[39:32]),
  .o(rrm_o[39:32])
  .o(rrm_o[39:32])
);
);
regReadbackMem #(.WID(8)) rrm2H
regReadbackMem #(.WID(8)) rrm2H
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[5]),
  .we(rwr_i & rsel_i[5]),
  .i(rdat_i[47:40]),
  .i(rdat_i[47:40]),
  .o(rrm_o[47:40])
  .o(rrm_o[47:40])
);
);
regReadbackMem #(.WID(8)) rrm3L
regReadbackMem #(.WID(8)) rrm3L
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[6]),
  .we(rwr_i & rsel_i[6]),
  .i(rdat_i[55:48]),
  .i(rdat_i[55:48]),
  .o(rrm_o[55:48])
  .o(rrm_o[55:48])
);
);
regReadbackMem #(.WID(8)) rrm3H
regReadbackMem #(.WID(8)) rrm3H
(
(
  .wclk(clk_i),
  .wclk(clk_i),
  .adr(rrm_adr),
  .adr(rrm_adr),
  .wce(cs_reg),
  .wce(cs_reg),
  .we(rwr_i & rsel_i[7]),
  .we(rwr_i & rsel_i[7]),
  .i(rdat_i[63:56]),
  .i(rdat_i[63:56]),
  .o(rrm_o[63:56])
  .o(rrm_o[63:56])
);
);
wire [23:0] lfsr1_o;
wire [23:0] lfsr1_o;
lfsr #(24) ulfsr1(rst_i, dot_clk_i, 1'b1, 1'b0, lfsr1_o);
lfsr #(24) ulfsr1(rst_i, dot_clk_i, 1'b1, 1'b0, lfsr1_o);
wire [63:0] lfsr_o = {6'h20,
wire [63:0] lfsr_o = {6'h20,
                                                                                                lfsr1_o[23:21],4'b0,lfsr1_o[20:18],4'b0,lfsr1_o[17:16],5'b0,
                                                                                                lfsr1_o[23:21],4'b0,lfsr1_o[20:18],4'b0,lfsr1_o[17:16],5'b0,
                                                                                                lfsr1_o[15:13],4'b0,lfsr1_o[12:10],4'b0,lfsr1_o[9:8],5'b0,
                                                                                                lfsr1_o[15:13],4'b0,lfsr1_o[12:10],4'b0,lfsr1_o[9:8],5'b0,
                                                                                                8'h00,lfsr1_o[7:0]
                                                                                                8'h00,lfsr1_o[7:0]
                                                                                };
                                                                                };
/* The following code was for WB burst access to the text memory. About the
/* The following code was for WB burst access to the text memory. About the
   only time burst access is used is for screen clear. This is just code bloat.
   only time burst access is used is for screen clear. This is just code bloat.
wire pe_cs;
wire pe_cs;
edge_det u1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs_text), .pe(pe_cs), .ne(), .ee() );
edge_det u1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(cs_text), .pe(pe_cs), .ne(), .ee() );
reg [14:0] ctr;
reg [14:0] ctr;
always @(posedge clk_i)
always @(posedge clk_i)
        if (pe_cs) begin
        if (pe_cs) begin
                if (cti_i==3'b000)
                if (cti_i==3'b000)
                        ctr <= adr_i[16:3];
                        ctr <= adr_i[16:3];
                else
                else
                        ctr <= adr_i[16:3] + 12'd1;
                        ctr <= adr_i[16:3] + 12'd1;
                cnt <= 3'b000;
                cnt <= 3'b000;
        end
        end
        else if (cs_text && cnt[2:0]!=3'b100 && cti_i!=3'b000) begin
        else if (cs_text && cnt[2:0]!=3'b100 && cti_i!=3'b000) begin
                ctr <= ctr + 2'd1;
                ctr <= ctr + 2'd1;
                cnt <= cnt + 3'd1;
                cnt <= cnt + 3'd1;
        end
        end
reg [13:0] radr;
reg [13:0] radr;
always @(posedge clk_i)
always @(posedge clk_i)
        radr <= pe_cs ? adr_i[16:3] : ctr;
        radr <= pe_cs ? adr_i[16:3] : ctr;
*/
*/
// text screen RAM
// text screen RAM
wire [15:0] bram_adr = radr_i[15:0];
wire [15:0] bram_adr = radr_i[15:0];
syncRam8kx64 screen_ram1
syncRam8kx64 screen_ram1
(
(
  .clka(clk_i),
  .clka(clk_i),
  .ena(cs_text),
  .ena(cs_text),
  .wea(wrs_i),
  .wea(wrs_i),
  .addra(bram_adr[15:3]),
  .addra(bram_adr[15:3]),
  .dina(rdat_i),
  .dina(rdat_i),
  .douta(tdat_o),
  .douta(tdat_o),
  .clkb(vclk),
  .clkb(vclk),
  .enb(ld_shft|por),
  .enb(ld_shft|por),
  .web({8{por}}),
  .web({8{por}}),
  .addrb(txtAddr[12:0]),
  .addrb(txtAddr[12:0]),
  .dinb(lfsr_o),
  .dinb(lfsr_o),
  .doutb(screen_ram_out)
  .doutb(screen_ram_out)
);
);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Character bitmap ROM/RAM
// Character bitmap ROM/RAM
// - 32kB
// - 32kB
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
char_ram charRam0
char_ram charRam0
(
(
        .clk_i(clk_i),
        .clk_i(clk_i),
        .cs_i(cs_rom),
        .cs_i(cs_rom),
        .we_i(1'b0),
        .we_i(1'b0),
        .adr_i(bram_adr[14:0]),
        .adr_i(bram_adr[14:0]),
        .dat_i(rdat_i >> {bram_adr[2:0],3'b0}),
        .dat_i(rdat_i >> {bram_adr[2:0],3'b0}),
        .dot_clk_i(vclk),
        .dot_clk_i(vclk),
        .ce_i(ld_shft),
        .ce_i(ld_shft),
        .fontAddress_i(fontAddress),
        .fontAddress_i(fontAddress),
        .char_code_i(screen_ram_out[11:0]),
        .char_code_i(screen_ram_out[11:0]),
        .maxScanpix_i(maxScanpix),
        .maxScanpix_i(maxScanpix),
        .maxscanline_i(maxScanlinePlusOne),
        .maxscanline_i(maxScanlinePlusOne),
        .scanline_i(rowscan),
        .scanline_i(rowscan),
        .bmp_o(char_bmp)
        .bmp_o(char_bmp)
);
);
// pipeline delay - sync color with character bitmap output
// pipeline delay - sync color with character bitmap output
reg [20:0] txtBkCode1;
wire [20:0] txtBkCode1;
reg [20:0] txtFgCode1;
wire [20:0] txtFgCode1;
reg [5:0] txtZorder1;
wire [5:0] txtZorder1;
always @(posedge vclk)
 
        if (ld_shft) txtBkCode1 <= screen_ram_out[36:16];
delay #(.WID(21),.DEP(3)) udlyb (.clk(vclk), .ce(ld_shft), .i(screen_ram_out[36:16]), .o(txtBkCode1));
always @(posedge vclk)
delay #(.WID(21),.DEP(3)) udlyf (.clk(vclk), .ce(ld_shft), .i(screen_ram_out[57:37]), .o(txtFgCode1));
        if (ld_shft) txtFgCode1 <= screen_ram_out[57:37];
delay #(.WID( 6),.DEP(3)) udlyz (.clk(vclk), .ce(ld_shft), .i(screen_ram_out[63:58]), .o(txtZorder1));
always @(posedge vclk)
 
        if (ld_shft) txtZorder1 <= screen_ram_out[63:58];
 
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Light Pen
// Light Pen
//--------------------------------------------------------------------
//--------------------------------------------------------------------
wire lpe;
wire lpe;
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(lp_i), .pe(lpe), .ne(), .ee() );
edge_det u1 (.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(lp_i), .pe(lpe), .ne(), .ee() );
always @(posedge clk_i)
always @(posedge clk_i)
        if (rst_i)
        if (rst_i)
                penAddr <= 32'h0000_0000;
                penAddr <= 32'h0000_0000;
        else begin
        else begin
                if (lpe)
                if (lpe)
                        penAddr <= txtAddr;
                        penAddr <= txtAddr;
        end
        end
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Register read port
// Register read port
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
always @*
always @*
        if (cs_reg) begin
        if (cs_reg) begin
                case(rrm_adr)
                case(rrm_adr)
                4'd7:             rego <= penAddr;
                4'd7:             rego <= penAddr;
                default:        rego <= rrm_o;
                default:        rego <= rrm_o;
                endcase
                endcase
        end
        end
        else
        else
                rego <= 64'h0000;
                rego <= 64'h0000;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Register write port
// Register write port
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
always @(posedge clk_i)
always @(posedge clk_i)
        if (rst_i) begin
        if (rst_i) begin
          por <= 1'b1;
          por <= 1'b1;
          controller_enable <= 1'b1;
          controller_enable <= 1'b1;
    xscroll              <= 6'd0;
    xscroll              <= 6'd0;
    yscroll              <= 6'd0;
    yscroll              <= 6'd0;
    txtTcCode    <= 16'h1ff;
    txtTcCode    <= 16'h1ff;
    bdrColor     <= 32'hFFBF2020;
    bdrColor     <= 32'hFFBF2020;
    startAddress <= 16'h0000;
    startAddress <= 16'h0000;
    fontAddress  <= 16'h0000;
    fontAddress  <= 16'h0000;
    cursorStart  <= 5'd00;
    cursorStart  <= 5'd00;
    cursorEnd    <= 5'd31;
    cursorEnd    <= 5'd31;
    cursorPos    <= 16'h0003;
    cursorPos    <= 16'h0003;
    cursorType   <= 2'b00;
    cursorType   <= 2'b00;
// 104x63
// 104x63
/*
/*
                windowTop    <= 12'd26;
                windowTop    <= 12'd26;
                windowLeft   <= 12'd260;
                windowLeft   <= 12'd260;
                pixelWidth   <= 4'd0;
                pixelWidth   <= 4'd0;
                pixelHeight  <= 4'd1;           // 525 pixels (408 with border)
                pixelHeight  <= 4'd1;           // 525 pixels (408 with border)
*/
*/
// 52x31
// 52x31
/*
/*
                // 84x47
                // 84x47
                windowTop    <= 12'd16;
                windowTop    <= 12'd16;
                windowLeft   <= 12'd90;
                windowLeft   <= 12'd90;
                pixelWidth   <= 4'd1;           // 681 pixels
                pixelWidth   <= 4'd1;           // 681 pixels
                pixelHeight  <= 4'd1;           // 384 pixels
                pixelHeight  <= 4'd1;           // 384 pixels
*/
*/
                // 48x29
                // 48x29
                if (num==4'd1) begin
                if (num==4'd1) begin
      windowTop    <= 12'd4058;//12'd16;
      windowTop    <= 12'd4058;//12'd16;
      windowLeft   <= 12'd3944;//12'd3930;//12'd86;
      windowLeft   <= 12'd3964;//12'd3930;//12'd86;
      pixelWidth   <= 4'd0;             // 1280 pixels
      pixelWidth   <= 4'd0;             // 1280 pixels
      pixelHeight  <= 4'd0;             // 720 pixels
      pixelHeight  <= 4'd0;             // 720 pixels
      numCols      <= COLS;
      numCols      <= COLS;
      numRows      <= ROWS;
      numRows      <= ROWS;
      maxRowScan  <= 6'd17;
      maxRowScan  <= 6'd17;
      maxScanpix   <= 6'd11;
      maxScanpix   <= 6'd11;
      rBlink       <= 3'b111;           // 01 = non display
      rBlink       <= 3'b111;           // 01 = non display
      charOutDelay <= 8'd7;
      charOutDelay <= 8'd7;
                end
                end
                else if (num==4'd2) begin
                else if (num==4'd2) begin
      windowTop    <= 12'd4032;//12'd16;
      windowTop    <= 12'd4032;//12'd16;
      windowLeft   <= 12'd3720;//12'd86;
      windowLeft   <= 12'd3720;//12'd86;
      pixelWidth   <= 4'd0;        // 800 pixels
      pixelWidth   <= 4'd0;        // 800 pixels
      pixelHeight  <= 4'd0;        // 600 pixels
      pixelHeight  <= 4'd0;        // 600 pixels
      numCols      <= 40;
      numCols      <= 40;
      numRows      <= 25;
      numRows      <= 25;
      maxRowScan  <= 6'd7;
      maxRowScan  <= 6'd7;
      maxScanpix   <= 6'd7;
      maxScanpix   <= 6'd7;
      rBlink       <= 3'b111;        // 01 = non display
      rBlink       <= 3'b111;        // 01 = non display
      charOutDelay <= 8'd6;
      charOutDelay <= 8'd6;
                end
                end
        end
        end
        else begin
        else begin
                if (bcnt > 6'd10)
                if (bcnt > 6'd10)
                        por <= 1'b0;
                        por <= 1'b0;
                if (cs_reg & rwr_i) begin       // register write ?
                if (cs_reg & rwr_i) begin       // register write ?
                        $display("TC Write: r%d=%h", rrm_adr, rdat_i);
                        $display("TC Write: r%d=%h", rrm_adr, rdat_i);
                        case(rrm_adr)
                        case(rrm_adr)
                        4'd0:   begin
                        4'd0:   begin
                                        if (rsel_i[0]) numCols    <= rdat_i[7:0];
                                        if (rsel_i[0]) numCols    <= rdat_i[7:0];
                                        if (rsel_i[1]) numRows    <= rdat_i[15:8];
                                        if (rsel_i[1]) numRows    <= rdat_i[15:8];
                                        if (rsel_i[2]) charOutDelay <= rdat_i[23:16];
                                        if (rsel_i[2]) charOutDelay <= rdat_i[23:16];
                                        if (rsel_i[4]) windowLeft[7:0] <= rdat_i[39:32];
                                        if (rsel_i[4]) windowLeft[7:0] <= rdat_i[39:32];
                                        if (rsel_i[5]) windowLeft[11:8] <= rdat_i[43:40];
                                        if (rsel_i[5]) windowLeft[11:8] <= rdat_i[43:40];
                                        if (rsel_i[6]) windowTop[7:0]  <= rdat_i[55:48];
                                        if (rsel_i[6]) windowTop[7:0]  <= rdat_i[55:48];
                                        if (rsel_i[7]) windowTop[11:8]  <= rdat_i[59:56];
                                        if (rsel_i[7]) windowTop[11:8]  <= rdat_i[59:56];
                                        end
                                        end
                        4'd1:
                        4'd1:
                                begin
                                begin
                                        if (rsel_i[0]) maxRowScan <= rdat_i[5:0];
                                        if (rsel_i[0]) maxRowScan <= rdat_i[5:0];
                                        if (rsel_i[1]) begin
                                        if (rsel_i[1]) begin
                                                pixelHeight <= rdat_i[15:12];
                                                pixelHeight <= rdat_i[15:12];
                                                pixelWidth  <= rdat_i[11:8];    // horizontal pixel width
                                                pixelWidth  <= rdat_i[11:8];    // horizontal pixel width
                                        end
                                        end
                                        if (rsel_i[2]) maxScanpix <= rdat_i[21:16];
                                        if (rsel_i[2]) maxScanpix <= rdat_i[21:16];
                                        if (rsel_i[3]) por <= rdat_i[24];
                                        if (rsel_i[3]) por <= rdat_i[24];
                                        if (rsel_i[4]) controller_enable <= rdat_i[32];
                                        if (rsel_i[4]) controller_enable <= rdat_i[32];
                                        if (rsel_i[6]) yscroll <= rdat_i[53:48];
                                        if (rsel_i[6]) yscroll <= rdat_i[53:48];
                                        if (rsel_i[7]) xscroll <= rdat_i[61:56];
                                        if (rsel_i[7]) xscroll <= rdat_i[61:56];
                                end
                                end
                        4'd2:   // Color Control
                        4'd2:   // Color Control
                                begin
                                begin
                                        if (rsel_i[0]) txtTcCode[7:0] <= rdat_i[7:0];
                                        if (rsel_i[0]) txtTcCode[7:0] <= rdat_i[7:0];
                                        if (rsel_i[1]) txtTcCode[15:8] <= rdat_i[15:8];
                                        if (rsel_i[1]) txtTcCode[15:8] <= rdat_i[15:8];
                                        if (rsel_i[2]) txtTcCode[20:16] <= rdat_i[20:16];
                                        if (rsel_i[2]) txtTcCode[20:16] <= rdat_i[20:16];
                                        if (rsel_i[4]) bdrColor[7:0] <= dat_i[39:32];
                                        if (rsel_i[4]) bdrColor[7:0] <= dat_i[39:32];
                                        if (rsel_i[5]) bdrColor[15:8] <= dat_i[47:40];
                                        if (rsel_i[5]) bdrColor[15:8] <= dat_i[47:40];
                                        if (rsel_i[6]) bdrColor[23:16] <= dat_i[55:48];
                                        if (rsel_i[6]) bdrColor[23:16] <= dat_i[55:48];
                                        if (rsel_i[7]) bdrColor[31:24] <= dat_i[63:56];
                                        if (rsel_i[7]) bdrColor[31:24] <= dat_i[63:56];
                                end
                                end
                        4'd3:   // Cursor Control
                        4'd3:   // Cursor Control
                                begin
                                begin
                                        if (rsel_i[0]) begin
                                        if (rsel_i[0]) begin
                                                cursorEnd <= rdat_i[4:0];       // scan line sursor starts on
                                                cursorEnd <= rdat_i[4:0];       // scan line sursor starts on
                                                rBlink      <= rdat_i[7:5];
                                                rBlink      <= rdat_i[7:5];
                                        end
                                        end
                                        if (rsel_i[1]) begin
                                        if (rsel_i[1]) begin
                                                cursorStart <= rdat_i[12:8];    // scan line cursor ends on
                                                cursorStart <= rdat_i[12:8];    // scan line cursor ends on
                                                cursorType  <= rdat_i[15:14];
                                                cursorType  <= rdat_i[15:14];
                                        end
                                        end
                                        if (rsel_i[4]) cursorPos[7:0] <= rdat_i[39:32];
                                        if (rsel_i[4]) cursorPos[7:0] <= rdat_i[39:32];
                                        if (rsel_i[5]) cursorPos[15:8] <= rdat_i[47:40];
                                        if (rsel_i[5]) cursorPos[15:8] <= rdat_i[47:40];
                                end
                                end
                        4'd4:   // Page flipping / scrolling
                        4'd4:   // Page flipping / scrolling
                                begin
                                begin
                                        if (rsel_i[0]) startAddress[7:0] <= rdat_i[7:0];
                                        if (rsel_i[0]) startAddress[7:0] <= rdat_i[7:0];
                                        if (rsel_i[1]) startAddress[15:8] <= rdat_i[15:8];
                                        if (rsel_i[1]) startAddress[15:8] <= rdat_i[15:8];
                                end
                                end
                  4'd5:
                  4'd5:
                    begin
                    begin
                      if (rsel_i[0]) fontAddress[7:0] <= rdat_i[7:0];
                      if (rsel_i[0]) fontAddress[7:0] <= rdat_i[7:0];
                      if (rsel_i[1]) fontAddress[15:8] <= rdat_i[15:8];
                      if (rsel_i[1]) fontAddress[15:8] <= rdat_i[15:8];
                    end
                    end
                        default: ;
                        default: ;
                        endcase
                        endcase
                end
                end
        end
        end
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// "Box" cursor bitmap
// "Box" cursor bitmap
(* ram_style="block" *)
(* ram_style="block" *)
reg [31:0] curram [0:511];
reg [31:0] curram [0:511];
reg [31:0] curout, curout1;
reg [31:0] curout, curout1;
initial begin
initial begin
        // Box cursor
        // Box cursor
  curram[0] = 8'b11111110;
  curram[0] = 8'b11111110;
  curram[1] = 8'b10000010;
  curram[1] = 8'b10000010;
  curram[2] = 8'b10000010;
  curram[2] = 8'b10000010;
  curram[3] = 8'b10000010;
  curram[3] = 8'b10000010;
  curram[4] = 8'b10000010;
  curram[4] = 8'b10000010;
  curram[5] = 8'b10000010;
  curram[5] = 8'b10000010;
  curram[6] = 8'b10010010;
  curram[6] = 8'b10010010;
  curram[7] = 8'b11111110;
  curram[7] = 8'b11111110;
        // vertical bar cursor
        // vertical bar cursor
  curram[32] = 8'b11000000;
  curram[32] = 8'b11000000;
  curram[33] = 8'b10000000;
  curram[33] = 8'b10000000;
  curram[34] = 8'b10000000;
  curram[34] = 8'b10000000;
  curram[35] = 8'b10000000;
  curram[35] = 8'b10000000;
  curram[36] = 8'b10000000;
  curram[36] = 8'b10000000;
  curram[37] = 8'b10000000;
  curram[37] = 8'b10000000;
  curram[38] = 8'b10000000;
  curram[38] = 8'b10000000;
  curram[39] = 8'b11000000;
  curram[39] = 8'b11000000;
        // underline cursor
        // underline cursor
  curram[64] = 8'b00000000;
  curram[64] = 8'b00000000;
  curram[65] = 8'b00000000;
  curram[65] = 8'b00000000;
  curram[66] = 8'b00000000;
  curram[66] = 8'b00000000;
  curram[67] = 8'b00000000;
  curram[67] = 8'b00000000;
  curram[68] = 8'b00000000;
  curram[68] = 8'b00000000;
  curram[69] = 8'b00000000;
  curram[69] = 8'b00000000;
  curram[70] = 8'b00000000;
  curram[70] = 8'b00000000;
  curram[71] = 8'b11111111;
  curram[71] = 8'b11111111;
        // Asterisk
        // Asterisk
  curram[96] = 8'b00000000;
  curram[96] = 8'b00000000;
  curram[97] = 8'b00000000;
  curram[97] = 8'b00000000;
  curram[98] = 8'b00100100;
  curram[98] = 8'b00100100;
  curram[99] = 8'b00011000;
  curram[99] = 8'b00011000;
  curram[100] = 8'b01111110;
  curram[100] = 8'b01111110;
  curram[101] = 8'b00011000;
  curram[101] = 8'b00011000;
  curram[102] = 8'b00100100;
  curram[102] = 8'b00100100;
  curram[103] = 8'b00000000;
  curram[103] = 8'b00000000;
end
end
always @(posedge vclk)
always @(posedge vclk)
  if (ld_shft)
  if (ld_shft)
          curout1 <= curram[{cursorType,rowscan}];
          curout1 <= curram[{cursorType,rowscan}];
always @(posedge vclk)
always @(posedge vclk)
  curout <= curout1;
  curout <= curout1;
//-------------------------------------------------------------
//-------------------------------------------------------------
// Video Stuff
// Video Stuff
//-------------------------------------------------------------
//-------------------------------------------------------------
wire pe_hsync;
wire pe_hsync;
wire pe_vsync;
wire pe_vsync;
edge_det edh1
edge_det edh1
(
(
        .rst(rst_i),
        .rst(rst_i),
        .clk(vclk),
        .clk(vclk),
        .ce(1'b1),
        .ce(1'b1),
        .i(hsync_i),
        .i(hsync_i),
        .pe(pe_hsync),
        .pe(pe_hsync),
        .ne(),
        .ne(),
        .ee()
        .ee()
);
);
edge_det edv1
edge_det edv1
(
(
        .rst(rst_i),
        .rst(rst_i),
        .clk(vclk),
        .clk(vclk),
        .ce(1'b1),
        .ce(1'b1),
        .i(vsync_i),
        .i(vsync_i),
        .pe(pe_vsync),
        .pe(pe_vsync),
        .ne(),
        .ne(),
        .ee()
        .ee()
);
);
// Horizontal counter:
// Horizontal counter:
//
//
/*
/*
HVCounter uhv1
HVCounter uhv1
(
(
        .rst(rst_i),
        .rst(rst_i),
        .vclk(vclk),
        .vclk(vclk),
        .pixcce(1'b1),
        .pixcce(1'b1),
        .sync(hsync_i),
        .sync(hsync_i),
        .cnt_offs(windowLeft),
        .cnt_offs(windowLeft),
        .pixsz(pixelWidth),
        .pixsz(pixelWidth),
        .maxpix(maxScanpix),
        .maxpix(maxScanpix),
        .nxt_pix(nhp),
        .nxt_pix(nhp),
        .pos(col),
        .pos(col),
        .nxt_pos(nxt_col),
        .nxt_pos(nxt_col),
        .ctr(hctr)
        .ctr(hctr)
);
);
*/
*/
// Vertical counter:
// Vertical counter:
//
//
/*
/*
HVCounter uhv2
HVCounter uhv2
(
(
        .rst(rst_i),
        .rst(rst_i),
        .vclk(vclk),
        .vclk(vclk),
        .pixcce(pe_hsync),
        .pixcce(pe_hsync),
        .sync(vsync_i),
        .sync(vsync_i),
        .cnt_offs(windowTop),
        .cnt_offs(windowTop),
        .pixsz(pixelHeight),
        .pixsz(pixelHeight),
        .maxpix(maxRowScan),
        .maxpix(maxRowScan),
        .nxt_pix(),
        .nxt_pix(),
        .pos(row),
        .pos(row),
        .nxt_pos(nxt_row),
        .nxt_pos(nxt_row),
        .ctr(scanline)
        .ctr(scanline)
);
);
*/
*/
// We generally don't care about the exact reset point, unless debugging in
// We generally don't care about the exact reset point, unless debugging in
// simulation. The counters will eventually cycle to a proper state. A little
// simulation. The counters will eventually cycle to a proper state. A little
// bit of logic / routing can be avoided by omitting the reset.
// bit of logic / routing can be avoided by omitting the reset.
`ifdef SIM
`ifdef SIM
wire sym_rst = rst_i;
wire sym_rst = rst_i;
`else
`else
wire sym_rst = 1'b0;
wire sym_rst = 1'b0;
`endif
`endif
// Raw scanline counter
// Raw scanline counter
vid_counter #(12) u_vctr (.rst(sym_rst), .clk(vclk), .ce(pe_hsync), .ld(pe_vsync), .d(windowTop), .q(scanline), .tc());
vid_counter #(12) u_vctr (.rst(sym_rst), .clk(vclk), .ce(pe_hsync), .ld(pe_vsync), .d(windowTop), .q(scanline), .tc());
vid_counter #(12) u_hctr (.rst(sym_rst), .clk(vclk), .ce(1'b1), .ld(pe_hsync), .d(windowLeft), .q(hctr), .tc());
vid_counter #(12) u_hctr (.rst(sym_rst), .clk(vclk), .ce(1'b1), .ld(pe_hsync), .d(windowLeft), .q(hctr), .tc());
// Vertical pixel height counter, synchronized to scanline #0
// Vertical pixel height counter, synchronized to scanline #0
reg [3:0] vpx;
reg [3:0] vpx;
wire nvp = vpx==pixelHeight;
wire nvp = vpx==pixelHeight;
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        vpx <= 4'b0;
        vpx <= 4'b0;
else begin
else begin
        if (pe_hsync) begin
        if (pe_hsync) begin
                if (scanline==12'd0)
                if (scanline==12'd0)
                        vpx <= 4'b0;
                        vpx <= 4'b0;
                else if (nvp)
                else if (nvp)
                        vpx <= 4'd0;
                        vpx <= 4'd0;
                else
                else
                        vpx <= vpx + 4'd1;
                        vpx <= vpx + 4'd1;
        end
        end
end
end
reg [3:0] hpx;
reg [3:0] hpx;
assign nhp = hpx==pixelWidth;
assign nhp = hpx==pixelWidth;
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        hpx <= 4'b0;
        hpx <= 4'b0;
else begin
else begin
        if (hctr==12'd0)
        if (hctr==12'd0)
                hpx <= 4'b0;
                hpx <= 4'b0;
        else if (nhp)
        else if (nhp)
                hpx <= 4'd0;
                hpx <= 4'd0;
        else
        else
                hpx <= hpx + 4'd1;
                hpx <= hpx + 4'd1;
end
end
// The scanline row within a character bitmap
// The scanline row within a character bitmap
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        rowscan <= 6'd0;
        rowscan <= 6'd0;
else begin
else begin
        if (pe_hsync & nvp) begin
        if (pe_hsync & nvp) begin
                if (scanline==12'd0)
                if (scanline==12'd0)
                        rowscan <= yscroll;
                        rowscan <= yscroll;
                else if (rowscan==maxRowScan)
                else if (rowscan==maxRowScan)
                        rowscan <= 6'd0;
                        rowscan <= 6'd0;
                else
                else
                        rowscan <= rowscan + 1'd1;
                        rowscan <= rowscan + 1'd1;
        end
        end
end
end
assign nxt_col = colscan==maxScanpix;
assign nxt_col = colscan==maxScanpix;
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        colscan <= 6'd0;
        colscan <= 6'd0;
else begin
else begin
        if (nhp) begin
        if (nhp) begin
                if (hctr==12'd0)
                if (hctr==12'd0)
                        colscan <= xscroll;
                        colscan <= xscroll;
                else if (nxt_col)
                else if (nxt_col)
                        colscan <= 6'd0;
                        colscan <= 6'd0;
                else
                else
                        colscan <= colscan + 1'd1;
                        colscan <= colscan + 1'd1;
        end
        end
end
end
// The screen row
// The screen row
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        row <= 8'd0;
        row <= 8'd0;
else begin
else begin
        if (pe_hsync & nvp) begin
        if (pe_hsync & nvp) begin
                if (scanline==12'd0)
                if (scanline==12'd0)
                        row <= 8'd0;
                        row <= 8'd0;
                else if (rowscan==maxRowScan)
                else if (rowscan==maxRowScan)
                        row <= row + 8'd1;
                        row <= row + 8'd1;
        end
        end
end
end
// The screen column
// The screen column
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        col <= 8'd0;
        col <= 8'd0;
else begin
else begin
        if (hctr==12'd0)
        if (hctr==12'd0)
                col <= 8'd0;
                col <= 8'd0;
        else if (nhp) begin
        else if (nhp) begin
                if (nxt_col)
                if (nxt_col)
                        col <= col + 8'd1;
                        col <= col + 8'd1;
        end
        end
end
end
// More useful, the offset of the start of the text display on a line.
// More useful, the offset of the start of the text display on a line.
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        rowcol <= 16'd0;
        rowcol <= 16'd0;
else begin
else begin
        if (pe_hsync & nvp) begin
        if (pe_hsync & nvp) begin
                if (scanline==12'd0)
                if (scanline==12'd0)
                        rowcol <= 8'd0;
                        rowcol <= 8'd0;
                else if (rowscan==maxRowScan)
                else if (rowscan==maxRowScan)
                        rowcol <= rowcol + numCols;
                        rowcol <= rowcol + numCols;
        end
        end
end
end
// Takes 3 clock for scanline to become stable, but should be stable before any
// Takes 3 clock for scanline to become stable, but should be stable before any
// chars are displayed.
// chars are displayed.
reg [13:0] rxmslp1;
reg [13:0] rxmslp1;
always @(posedge vclk)
always @(posedge vclk)
        maxScanlinePlusOne <= maxRowScan + 1'd1;
        maxScanlinePlusOne <= maxRowScan + 1'd1;
//always @(posedge vclk)
//always @(posedge vclk)
//      rxmslp1 <= row * maxScanlinePlusOne;
//      rxmslp1 <= row * maxScanlinePlusOne;
//always @(posedge vclk)
//always @(posedge vclk)
//      scanline <= scanline - rxmslp1;
//      scanline <= scanline - rxmslp1;
// Blink counter
// Blink counter
//
//
always @(posedge vclk)
always @(posedge vclk)
if (sym_rst)
if (sym_rst)
        bcnt <= 6'd0;
        bcnt <= 6'd0;
else begin
else begin
        if (pe_vsync)
        if (pe_vsync)
                bcnt <= bcnt + 6'd1;
                bcnt <= bcnt + 6'd1;
end
end
reg blink_en;
reg blink_en;
always @(posedge vclk)
always @(posedge vclk)
        blink_en <= (cursorPos+3==txtAddr) && (rowscan >= cursorStart) && (rowscan <= cursorEnd);
        blink_en <= (cursorPos+3==txtAddr) && (rowscan >= cursorStart) && (rowscan <= cursorEnd);
VT151 ub2
VT151 ub2
(
(
        .e_n(!blink_en),
        .e_n(!blink_en),
        .s(rBlink),
        .s(rBlink),
        .i0(1'b1), .i1(1'b0), .i2(bcnt[4]), .i3(bcnt[5]),
        .i0(1'b1), .i1(1'b0), .i2(bcnt[4]), .i3(bcnt[5]),
        .i4(1'b1), .i5(1'b0), .i6(bcnt[4]), .i7(bcnt[5]),
        .i4(1'b1), .i5(1'b0), .i6(bcnt[4]), .i7(bcnt[5]),
        .z(blink),
        .z(blink),
        .z_n()
        .z_n()
);
);
always @(posedge vclk)
always @(posedge vclk)
        if (ld_shft)
  if (ld_shft)
                bkColor32 <= {txtZorder1,2'b00,txtBkCode1[20:14],1'b0,txtBkCode1[13:7],1'b0,txtBkCode1[6:0],1'b0};
    bkColor32 <= {txtZorder1,2'b00,txtBkCode1[20:14],1'b0,txtBkCode1[13:7],1'b0,txtBkCode1[6:0],1'b0};
always @(posedge vclk)
always @(posedge vclk)
        if (nhp)
        if (nhp)
                bkColor32d <= bkColor32;
                bkColor32d <= bkColor32;
 
 
always @(posedge vclk)
always @(posedge vclk)
        if (ld_shft)
  if (ld_shft)
                fgColor32 <= {txtZorder1,2'b00,txtFgCode1[20:14],1'b0,txtFgCode1[13:7],1'b0,txtFgCode1[6:0],1'b0};
    fgColor32 <= {txtZorder1,2'b00,txtFgCode1[20:14],1'b0,txtFgCode1[13:7],1'b0,txtFgCode1[6:0],1'b0};
always @(posedge vclk)
always @(posedge vclk)
        if (nhp)
        if (nhp)
                fgColor32d <= fgColor32;
                fgColor32d <= fgColor32;
always @(posedge vclk)
always @(posedge vclk)
        if (ld_shft)
        if (ld_shft)
                bgt <= txtBkCode1==txtTcCode;
                bgt <= txtBkCode1==txtTcCode;
always @(posedge vclk)
always @(posedge vclk)
        if (nhp)
        if (nhp)
                bgtd <= bgt;
                bgtd <= bgt;
reg [63:0] charout1;
reg [63:0] charout1;
always @(posedge vclk)
always @(posedge vclk)
        charout1 <= blink ? (char_bmp ^ curout) : char_bmp;
        charout1 <= blink ? (char_bmp ^ curout) : char_bmp;
// Convert parallel to serial
// Convert parallel to serial
ParallelToSerial ups1
ParallelToSerial ups1
(
(
        .rst(rst_i),
        .rst(rst_i),
        .clk(vclk),
        .clk(vclk),
        .ce(nhp),
        .ce(nhp),
        .ld(ld_shft),
        .ld(ld_shft),
        .a(maxScanpix[5:3]),
        .a(maxScanpix[5:3]),
        .qin(1'b0),
        .qin(1'b0),
        .d(charout1),
        .d(charout1),
        .qh(pix)
        .qh(pix)
);
);
// Pipelining Effect:
// Pipelining Effect:
// - character output is delayed by 2 or 3 character times relative to the video counters
// - character output is delayed by 2 or 3 character times relative to the video counters
//   depending on the resolution selected
//   depending on the resolution selected
// - this means we must adapt the blanking signal by shifting the blanking window
// - this means we must adapt the blanking signal by shifting the blanking window
//   two or three character times.
//   two or three character times.
always @(posedge vclk)
always @(posedge vclk)
        if (nhp)
        if (nhp)
                iblank <= (row >= numRows) || (col >= numCols + charOutDelay) || (col < charOutDelay);
                iblank <= (row >= numRows) || (col >= numCols + charOutDelay) || (col < charOutDelay);
wire bpix = hctr[2] ^ rowscan[4];// ^ blink;
wire bpix = hctr[2] ^ rowscan[4];// ^ blink;
// Choose between input RGB and controller generated RGB
// Choose between input RGB and controller generated RGB
// Select between foreground and background colours.
// Select between foreground and background colours.
// Note the ungated dot clock must be used here, or output from other
// Note the ungated dot clock must be used here, or output from other
// controllers would not be visible if the clock were gated off.
// controllers would not be visible if the clock were gated off.
always @(posedge dot_clk_i)
always @(posedge dot_clk_i)
        casez({controller_enable&xonoff_i,blank_i,iblank,border_i,bpix,pix})
        casez({controller_enable&xonoff_i,blank_i,iblank,border_i,bpix,pix})
        6'b?1????:      zrgb_o <= 32'h00000000;
        6'b?1????:      zrgb_o <= 32'h00000000;
        6'b1001??:      zrgb_o <= bdrColor;
        6'b1001??:      zrgb_o <= bdrColor;
        //6'b10010?:    zrgb_o <= 32'hFFBF2020;
        //6'b10010?:    zrgb_o <= 32'hFFBF2020;
        //6'b10011?:    zrgb_o <= 32'hFFDFDFDF;
        //6'b10011?:    zrgb_o <= 32'hFFDFDFDF;
        6'b1000?0:      zrgb_o <= ((zrgb_i[31:24] <= bkColor32d[31:24]) || bgtd) ? zrgb_i : bkColor32d;
        6'b1000?0:      zrgb_o <= ((zrgb_i[31:24] <= bkColor32d[31:24]) || bgtd) ? zrgb_i : bkColor32d;
        6'b1000?1:      zrgb_o <= fgColor32d; // ToDo: compare z-order
        6'b1000?1:      zrgb_o <= fgColor32d; // ToDo: compare z-order
//      6'b1010?0:      zrgb_o <= bgtd ? zrgb_i : bkColor32d;
//      6'b1010?0:      zrgb_o <= bgtd ? zrgb_i : bkColor32d;
//      6'b1010?1:      zrgb_o <= fgColor32d;
//      6'b1010?1:      zrgb_o <= fgColor32d;
        default:        zrgb_o <= zrgb_i;
        default:        zrgb_o <= zrgb_i;
        endcase
        endcase
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.