Line 1... |
Line 1... |
// ============================================================================
|
// ============================================================================
|
// 2006-2011 Robert Finch
|
// (C) 2006-2011 Robert Finch
|
// robfinch@<remove>sympatico.ca
|
// robfinch@<remove>opencores.org
|
//
|
//
|
// rtfTextController.v
|
// rtfTextController.v
|
// text controller
|
// text controller
|
//
|
//
|
// This source code is available for evaluation and validation purposes
|
// This source file is free software: you can redistribute it and/or modify
|
// only. This copyright statement and disclaimer must remain present in
|
// it under the terms of the GNU Lesser General Public License as published
|
// the file.
|
// by the Free Software Foundation, either version 3 of the License, or
|
//
|
// (at your option) any later version.
|
//
|
//
|
// NO WARRANTY.
|
// This source file is distributed in the hope that it will be useful,
|
// THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// EXPRESS OR IMPLIED. The user must assume the entire risk of using the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// Work.
|
// GNU General Public License for more details.
|
//
|
//
|
// IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
|
// You should have received a copy of the GNU General Public License
|
// INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
|
|
//
|
|
// IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
|
|
// IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
|
|
// REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
|
|
// LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
|
|
// AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
|
|
// LOSSES RELATING TO SUCH UNAUTHORIZED USE.
|
|
//
|
//
|
//
|
//
|
// Text Controller
|
// Text Controller
|
//
|
//
|
// FEATURES
|
// FEATURES
|
Line 41... |
Line 33... |
//
|
//
|
// 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.
|
//
|
//
|
//
|
//
|
// Window Co-ordinates
|
//--------------------------------------------------------------------
|
// 0: LEF - left
|
// Registers
|
// [11: 0] horizontal position (hctr value)
|
//
|
// [15:14] size of horizontal pixels - 1 in clock cycles
|
// 00 - nnnnnnnn number of columns (horizontal displayed number of characters)
|
// [ 13] text screen enable
|
// 01 - nnnnnnnn number of rows (vertical displayed number of characters)
|
// 1: TOP - top
|
// 02 - n nnnnnnnn window left (horizontal sync position - reference for left edge of displayed)
|
// [10: 0] vertical position (vctr value)
|
// 03 - n nnnnnnnn window top (vertical sync position - reference for the top edge of displayed)
|
// [15:14] size of vertical pixels in scan-lines - 1
|
// 04 - ---nnnnn maximum scan line (char ROM max value is 7)
|
// 2: RIG - right
|
// 05 - hhhhwwww pixel size, hhhh=height,wwww=width
|
// [11: 0] horizontal position (hctr value)
|
// 07 - ---nnnnn color code for transparent background
|
// 3: BOT - bottom
|
// 08 - -BPnnnnn cursor start / blink control
|
// [10: 0] vertical position (vctr value)
|
// BP: 00=no blink
|
//
|
// BP: 01=no display
|
//
|
// BP: 10=1/16 field rate blink
|
// Webpack 9.1i xc3s1000-4ft256
|
// BP: 11=1/32 field rate blink
|
// 156 LUTs / 81 slices / 128.607 MHz
|
// 09 - ----nnnnn cursor end
|
// 3 block rams
|
// 10 - aaaaaaaa aaaaaaaaa start address (index into display memory)
|
// 1 multiplier
|
// 11 - aaaaaaaa aaaaaaaaa cursor position
|
|
// 12 - aaaaaaaa aaaaaaaaa light pen position
|
|
//--------------------------------------------------------------------
|
//
|
//
|
// ============================================================================
|
// ============================================================================
|
|
|
`define DEBUG 1
|
module rtfTextController(
|
|
|
module FF_TextController(
|
|
rst_i, clk_i,
|
rst_i, clk_i,
|
cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o,
|
cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o,
|
lp, curpos,
|
lp, curpos,
|
vclk, eol, eof, blank, border, rgbIn, rgbOut
|
vclk, eol, eof, blank, border, rgbIn, rgbOut
|
);
|
);
|
Line 104... |
Line 96... |
output reg [24:0] rgbOut; // output pixel stream
|
output reg [24:0] rgbOut; // output pixel stream
|
|
|
|
|
wire [23:0] bkColor24; // background color
|
wire [23:0] bkColor24; // background color
|
wire [23:0] fgColor24; // foreground color
|
wire [23:0] fgColor24; // foreground color
|
|
wire [23:0] tcColor24; // transparent color
|
|
|
wire pix; // pixel value from character generator 1=on,0=off
|
wire pix; // pixel value from character generator 1=on,0=off
|
|
|
reg [15:0] rego;
|
reg [15:0] rego;
|
reg [11:0] windowTop;
|
reg [11:0] windowTop;
|
Line 145... |
Line 138... |
reg [15:0] penAddr;
|
reg [15:0] penAddr;
|
wire [8:0] txtOut; // character code
|
wire [8:0] txtOut; // character code
|
wire [7:0] charOut; // character ROM output
|
wire [7:0] charOut; // character ROM output
|
wire [3:0] txtBkCode; // background color code
|
wire [3:0] txtBkCode; // background color code
|
wire [4:0] txtFgCode; // foreground color code
|
wire [4:0] txtFgCode; // foreground color code
|
|
reg [4:0] txtTcCode; // transparent color code
|
|
reg bgt;
|
|
|
wire [8:0] tdat_o;
|
wire [8:0] tdat_o;
|
wire [8:0] cdat_o;
|
wire [8:0] cdat_o;
|
wire [7:0] chdat_o;
|
wire [7:0] chdat_o;
|
|
|
Line 188... |
Line 183... |
|
|
// text screen RAM
|
// text screen RAM
|
syncRam4kx9_1rw1r textRam0
|
syncRam4kx9_1rw1r textRam0
|
(
|
(
|
.wclk(clk_i),
|
.wclk(clk_i),
|
.wadr(adr_i[12:1]),
|
.wadr(adr_i[13:1]),
|
.i(dat_i),
|
.i(dat_i),
|
.wo(tdat_o),
|
.wo(tdat_o),
|
.wce(cs_text),
|
.wce(cs_text),
|
.we(we_i),
|
.we(we_i),
|
.wrst(1'b0),
|
.wrst(1'b0),
|
|
|
.rclk(vclk),
|
.rclk(vclk),
|
.radr(txtAddr[11:0]),
|
.radr(txtAddr[12:0]),
|
.o(txtOut),
|
.o(txtOut),
|
.rce(ld_shft),
|
.rce(ld_shft),
|
.rrst(1'b0)
|
.rrst(1'b0)
|
);
|
);
|
|
|
// screen attribute RAM
|
// screen attribute RAM
|
syncRam4kx9_1rw1r colorRam0
|
syncRam4kx9_1rw1r colorRam0
|
(
|
(
|
.wclk(clk_i),
|
.wclk(clk_i),
|
.wadr(adr_i[12:1]),
|
.wadr(adr_i[13:1]),
|
.i(dat_i),
|
.i(dat_i),
|
.wo(cdat_o),
|
.wo(cdat_o),
|
.wce(cs_color),
|
.wce(cs_color),
|
.we(we_i),
|
.we(we_i),
|
.wrst(1'b0),
|
.wrst(1'b0),
|
|
|
.rclk(vclk),
|
.rclk(vclk),
|
.radr(txtAddr[11:0]),
|
.radr(txtAddr[12:0]),
|
.o({txtBkCode,txtFgCode}),
|
.o({txtBkCode,txtFgCode}),
|
.rce(ld_shft),
|
.rce(ld_shft),
|
.rrst(1'b0)
|
.rrst(1'b0)
|
);
|
);
|
|
|
Line 305... |
Line 300... |
// Register read port
|
// Register read port
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
always @(cs_reg or cursorPos or penAddr or adr_i)
|
always @(cs_reg or cursorPos or penAddr or adr_i)
|
if (cs_reg) begin
|
if (cs_reg) begin
|
case(adr_i[4:1])
|
case(adr_i[4:1])
|
|
4'd0: rego <= numCols;
|
|
4'd1: rego <= numRows;
|
4'd11: rego <= cursorPos;
|
4'd11: rego <= cursorPos;
|
4'd12: rego <= penAddr;
|
4'd12: rego <= penAddr;
|
default: rego <= 16'h0000;
|
default: rego <= 16'h0000;
|
endcase
|
endcase
|
end
|
end
|
Line 321... |
Line 318... |
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
reg interlace;
|
reg interlace;
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
if (rst_i) begin
|
if (rst_i) begin
|
// 104x65
|
// 104x63
|
// windowTop <= 12'd20;
|
/*
|
// windowLeft <= 12'd284;
|
windowTop <= 12'd26;
|
// pixelWidth <= 4'd0;
|
windowLeft <= 12'd260;
|
// pixelHeight <= 4'd1; // 525 pixels (408 with border)
|
pixelWidth <= 4'd0;
|
|
pixelHeight <= 4'd1; // 525 pixels (408 with border)
|
|
*/
|
// 52x31
|
// 52x31
|
windowTop <= 12'd14;
|
windowTop <= 12'd14;
|
windowLeft <= 12'd117;
|
windowLeft <= 12'd117;
|
pixelWidth <= 4'd1;
|
pixelWidth <= 4'd1;
|
pixelHeight <= 4'd3; // 262 pixels (248 with border)
|
pixelHeight <= 4'd3; // 262 pixels (248 with border)
|
|
|
numCols <= COLS;
|
numCols <= COLS;
|
numRows <= ROWS;
|
numRows <= ROWS;
|
maxScanline <= 5'd7;
|
maxScanline <= 5'd7;
|
maxScanpix <= 5'd7;
|
maxScanpix <= 5'd7;
|
rBlink <= 3'b111; // 01 = non display
|
rBlink <= 3'b111; // 01 = non display
|
startAddress <= 16'h0000;
|
startAddress <= 16'h0000;
|
cursorStart <= 5'd00;
|
cursorStart <= 5'd00;
|
cursorEnd <= 5'd31;
|
cursorEnd <= 5'd31;
|
cursorPos <= 16'h0003;
|
cursorPos <= 16'h0003;
|
|
txtTcCode <= 5'd31;
|
end
|
end
|
else begin
|
else begin
|
cursorPos <= curpos;
|
|
|
|
if (cs_reg & we_i) begin // register write ?
|
if (cs_reg & we_i) begin // register write ?
|
|
|
case(adr_i[4:1])
|
case(adr_i[4:1])
|
4'd00: numCols <= dat_i; // horizontal displayed
|
4'd00: numCols <= dat_i; // horizontal displayed
|
Line 356... |
Line 356... |
4'd04: maxScanline <= dat_i[4:0];
|
4'd04: maxScanline <= dat_i[4:0];
|
4'd05: begin
|
4'd05: begin
|
pixelHeight <= dat_i[7:4];
|
pixelHeight <= dat_i[7:4];
|
pixelWidth <= dat_i[3:0]; // horizontal pixel width
|
pixelWidth <= dat_i[3:0]; // horizontal pixel width
|
end
|
end
|
|
4'd07: txtTcCode <= dat_i[4:0];
|
4'd08: begin
|
4'd08: begin
|
cursorStart <= dat_i[4:0]; // scan line sursor starts on
|
cursorStart <= dat_i[4:0]; // scan line sursor starts on
|
rBlink <= dat_i[7:5];
|
rBlink <= dat_i[7:5];
|
end
|
end
|
4'd09: cursorEnd <= dat_i[4:0]; // scan line cursor ends on
|
4'd09: cursorEnd <= dat_i[4:0]; // scan line cursor ends on
|
Line 443... |
Line 444... |
.ld_n(1'b1),
|
.ld_n(1'b1),
|
.d(6'd0),
|
.d(6'd0),
|
.q(bcnt)
|
.q(bcnt)
|
);
|
);
|
|
|
wire blink_en = (cursorPos==txtAddr+3) && (scanline[4:0] >= cursorStart) && (scanline[4:0] <= cursorEnd);
|
wire blink_en = (cursorPos==txtAddr+2) && (scanline[4:0] >= cursorStart) && (scanline[4:0] <= cursorEnd);
|
|
|
VT151 ub2
|
VT151 ub2
|
(
|
(
|
.e_n(!blink_en),
|
.e_n(!blink_en),
|
.s(rBlink),
|
.s(rBlink),
|
Line 458... |
Line 459... |
);
|
);
|
|
|
// These tables map a five bit color code to an eight bit color value.
|
// These tables map a five bit color code to an eight bit color value.
|
rtfColorROM ucm1 (.clk(vclk), .ce(nhp & ld_shft), .code(txtBkCode1), .color(bkColor24) );
|
rtfColorROM ucm1 (.clk(vclk), .ce(nhp & ld_shft), .code(txtBkCode1), .color(bkColor24) );
|
rtfColorROM ucm2 (.clk(vclk), .ce(nhp & ld_shft), .code(txtFgCode1), .color(fgColor24) );
|
rtfColorROM ucm2 (.clk(vclk), .ce(nhp & ld_shft), .code(txtFgCode1), .color(fgColor24) );
|
|
always @(posedge vclk)
|
|
if (nhp & ld_shft)
|
|
bgt <= {1'b0,txtBkCode1}==txtTcCode;
|
|
|
|
|
// Convert character bitmap to pixels
|
// Convert character bitmap to pixels
|
// For convenience, the character bitmap data in the ROM is in the
|
// For convenience, the character bitmap data in the ROM is in the
|
// opposite bit order to what's needed for the display. The following
|
// opposite bit order to what's needed for the display. The following
|
Line 510... |
Line 514... |
casex({blank,iblank,border,bpix,pix})
|
casex({blank,iblank,border,bpix,pix})
|
5'b1xxxx: rgbOut <= 25'h0000000;
|
5'b1xxxx: rgbOut <= 25'h0000000;
|
5'b01xxx: rgbOut <= rgbIn;
|
5'b01xxx: rgbOut <= rgbIn;
|
5'b0010x: rgbOut <= 24'hBF2020;
|
5'b0010x: rgbOut <= 24'hBF2020;
|
5'b0011x: rgbOut <= 24'hDFDFDF;
|
5'b0011x: rgbOut <= 24'hDFDFDF;
|
5'b000x0: rgbOut <= bkColor24;
|
5'b000x0: rgbOut <= bgt ? rgbIn : bkColor24;
|
5'b000x1: rgbOut <= fgColor24;
|
5'b000x1: rgbOut <= fgColor24;
|
default: rgbOut <= rgbIn;
|
default: rgbOut <= rgbIn;
|
endcase
|
endcase
|
end
|
end
|
|
|