]> Joshua Wise's Git repositories - vterm.git/blobdiff - VTerm.v
Add a cursor. Add backspace.
[vterm.git] / VTerm.v
diff --git a/VTerm.v b/VTerm.v
index 09b130093e4eb199536c2d4f12ca8c3c70d730a1..e9df92bc3b732aabd3281e3f62e91d20eb9210fe 100644 (file)
--- a/VTerm.v
+++ b/VTerm.v
@@ -36,8 +36,9 @@ module VTerm(
        output reg [2:0] red,
        output reg [2:0] green,
        output reg [1:0] blue,
-       input serrx
-       );
+       input serrx,
+       output sertx,
+       input ps2c, ps2d);
        
        wire clk25;
 
@@ -65,11 +66,19 @@ module VTerm(
        
        wire odata;
        
+       wire [7:0] sertxdata;
+       wire sertxwr;
+       
+       wire [6:0] vcursx;
+       wire [4:0] vcursy;
+       
        CharSet cs(cschar, csrow, csdata);
        VideoRAM vram(clk25, vraddr + vscroll, vrdata, vwaddr, vwdata, vwr);
-       VDisplay dpy(clk25, x, y, vraddr, vrdata, cschar, csrow, csdata, odata);
+       VDisplay dpy(clk25, x, y, vraddr, vrdata, cschar, csrow, csdata, vcursx, vcursy, odata);
        SerRX rx(clk25, serwr, serdata, serrx);
-       RXState rxsm(clk25, vwr, vwaddr, vwdata, vscroll, serwr, serdata);
+       SerTX tx(clk25, sertxwr, sertxdata, sertx);
+       RXState rxsm(clk25, vwr, vwaddr, vwdata, vscroll, vcursx, vcursy, serwr, serdata);
+       PS2 ps2(clk25, ps2c, ps2d, sertxwr, sertxdata);
        
        always @(posedge clk25) begin
                red <= border ? 0 : {3{odata}};
@@ -151,8 +160,9 @@ module VDisplay(
        output wire [7:0] cschar,
        output wire [2:0] csrow,
        input [7:0] csdata,
-       output reg data
-       );
+       input [6:0] cursx,
+       input [4:0] cursy,
+       output reg data);
 
        wire [7:0] col = x[11:3];
        wire [5:0] row = y[9:3];
@@ -163,11 +173,17 @@ module VDisplay(
        assign cschar = rchar;
        assign csrow = y[2:0];
        
+       reg [23:0] blinktime = 0;
+       
+       always @(posedge pixclk) blinktime <= blinktime + 1;
+       
+       wire curssel = (cursx == col) && (cursy == row) && blinktime[23];
+       
        always @(posedge pixclk)
                xdly <= x;
        
        always @(posedge pixclk)
-               data = ((xdly < 80 * 8) && (y < 25 * 8)) ? csdata[7 - xdly[2:0]] : 0;
+               data = ((xdly < 80 * 8) && (y < 25 * 8)) ? (csdata[7 - xdly[2:0]] ^ curssel) : 0;
 endmodule
 
 `define IN_CLK 25000000
@@ -178,8 +194,7 @@ module SerRX(
        input pixclk,
        output reg wr = 0,
        output reg [7:0] wchar = 0,
-       input serialrx
-);
+       input serialrx);
 
        reg [15:0] rx_clkdiv = 0;
        reg [3:0] rx_state = 4'b0000;
@@ -222,7 +237,50 @@ module SerRX(
                else
                        rx_clkdiv <= rx_clkdiv + 1;
        end
+endmodule
+
+module SerTX(
+       input pixclk,
+       input wr,
+       input [7:0] char,
+       output reg serial = 1);
+       
+       reg [7:0] tx_data = 0;
+       reg [15:0] tx_clkdiv = 0;
+       reg [3:0] tx_state = 4'b0000;
+       reg tx_busy = 0;
+       wire tx_newdata = wr && !tx_busy;
 
+       always @(posedge pixclk)
+       begin
+               if(tx_newdata) begin
+                       tx_data <= char;
+                       tx_state <= 4'b0000;
+                       tx_busy <= 1;
+               end else if (tx_clkdiv == 0) begin
+                       tx_state <= tx_state + 1;
+                       if (tx_busy)
+                               case (tx_state)
+                               4'b0000: serial <= 0;
+                               4'b0001: serial <= tx_data[0];
+                               4'b0010: serial <= tx_data[1];
+                               4'b0011: serial <= tx_data[2];
+                               4'b0100: serial <= tx_data[3];
+                               4'b0101: serial <= tx_data[4];
+                               4'b0110: serial <= tx_data[5];
+                               4'b0111: serial <= tx_data[6];
+                               4'b1000: serial <= tx_data[7];
+                               4'b1001: serial <= 1;
+                               4'b1010: tx_busy <= 0;
+                               default: $stop;
+                               endcase
+               end
+               
+               if(tx_newdata || (tx_clkdiv == `CLK_DIV))
+                       tx_clkdiv <= 0;
+               else
+                       tx_clkdiv <= tx_clkdiv + 1;
+       end
 endmodule
 
 module RXState(
@@ -231,6 +289,8 @@ module RXState(
        output reg [10:0] vwaddr = 0,
        output reg [7:0] vwdata = 0,
        output reg [10:0] vscroll = 0,
+       output wire [6:0] vcursx,
+       output wire [4:0] vcursy,
        input serwr,
        input [7:0] serdata);
 
@@ -243,6 +303,9 @@ module RXState(
        reg [6:0] x = 0;
        reg [4:0] y = 0;
        
+       assign vcursx = x;
+       assign vcursy = y;
+       
        reg [10:0] clearstart = 0;
        reg [10:0] clearend = 11'b11111111111;
        
@@ -251,6 +314,7 @@ module RXState(
                STATE_IDLE:     if (serwr) begin
                                        if (serdata == 8'h0A) begin
                                                state <= STATE_NEWLINE;
+                                               x <= 0;
                                                vwr <= 0;
                                        end else if (serdata == 8'h0D) begin
                                                x <= 0;
@@ -262,6 +326,10 @@ module RXState(
                                                y <= 0;
                                                vscroll <= 0;
                                                state <= STATE_CLEAR;
+                                       end else if (serdata == 8'h08) begin
+                                               if (x != 0)
+                                                       x <= x - 1;
+                                               vwr <= 0;
                                        end else begin
                                                vwr <= 1;
                                                vwaddr <= ({y,4'b0} + {y,6'b0} + {4'h0,x}) + vscroll;
@@ -297,3 +365,108 @@ module RXState(
                        end
                endcase
 endmodule
+
+module PS2(
+       input pixclk,
+       input inclk,
+       input indata,
+       output reg wr,
+       output reg [7:0] data
+       );
+
+       reg [3:0] bitcount = 0;
+       reg [7:0] key = 0;
+       reg keyarrow = 0, keyup = 0, parity = 0;
+
+       
+       /* Clock debouncing */
+       reg lastinclk = 0;
+       reg [6:0] debounce = 0;
+       reg fixedclk = 0;
+       reg [11:0] resetcountdown = 0;
+       
+       reg [6:0] unshiftedrom [127:0]; initial $readmemh("scancodes.unshifted.hex", unshiftedrom);
+       reg [6:0] shiftedrom [127:0];   initial $readmemh("scancodes.shifted.hex", shiftedrom);
+       
+       reg mod_lshift = 0;
+       reg mod_rshift = 0;
+       reg mod_capslock = 0;
+       wire mod_shifted = (mod_lshift | mod_rshift) ^ mod_capslock;
+       
+       reg nd = 0;
+       reg lastnd = 0;
+       
+       always @(posedge pixclk) begin
+               if (inclk != lastinclk) begin
+                       lastinclk <= inclk;
+                       debounce <= 1;
+                       resetcountdown <= 12'b111111111111;
+               end else if (debounce == 0) begin
+                       fixedclk <= inclk;
+                       resetcountdown <= resetcountdown - 1;
+               end else
+                       debounce <= debounce + 1;
+               
+               if (nd ^ lastnd) begin
+                       lastnd <= nd;
+                       wr <= 1;
+               end else
+                       wr <= 0;
+       end
+
+       always @(negedge fixedclk) begin
+               if (resetcountdown == 0)
+                       bitcount <= 0;
+               else if (bitcount == 10) begin
+                       bitcount <= 0;
+                       if(parity != (^ key)) begin
+                               if(keyarrow) begin
+                                       casex(key)
+                                               8'hF0: keyup <= 1;
+                                               8'hxx: keyarrow <= 0;
+                                       endcase
+                               end
+                               else begin
+                                       if(keyup) begin
+                                               keyup <= 0;
+                                               keyarrow <= 0;
+                                               casex (key)
+                                               8'h12: mod_lshift <= 0;
+                                               8'h59: mod_rshift <= 0;
+                                               endcase
+                                               // handle this? I don't fucking know
+                                       end
+                                       else begin
+                                               casex(key)
+                                                       8'hE0: keyarrow <= 1;   // handle these? I don't fucking know
+                                                       8'hF0: keyup <= 1;
+                                                       8'h12: mod_lshift <= 1;
+                                                       8'h59: mod_rshift <= 1;
+                                                       8'h14: mod_capslock <= ~mod_capslock;
+                                                       8'b0xxxxxxx: begin nd <= ~nd; data <= mod_shifted ? shiftedrom[key] : unshiftedrom[key]; end
+                                                       8'b1xxxxxxx: begin /* AAAAAAASSSSSSSS */ end
+                                               endcase
+                                       end
+                               end
+                       end
+                       else begin
+                               keyarrow <= 0;
+                               keyup <= 0;
+                       end
+               end else
+                       bitcount <= bitcount + 1;
+
+               case(bitcount)
+                       1: key[0] <= indata;
+                       2: key[1] <= indata;
+                       3: key[2] <= indata;
+                       4: key[3] <= indata;
+                       5: key[4] <= indata;
+                       6: key[5] <= indata;
+                       7: key[6] <= indata;
+                       8: key[7] <= indata;
+                       9: parity <= indata;
+               endcase
+       end
+
+endmodule
This page took 0.03154 seconds and 4 git commands to generate.