From 25aff9cdc3df4d007c227d747414d6b7f4dd580b Mon Sep 17 00:00:00 2001 From: Alan Garfield Date: Tue, 6 Feb 2018 00:29:56 +1100 Subject: [PATCH] VGA module works. Still no hardware scrolling though --- roms/vga_vram.bin | 80 ++++++++++++++++----------------- rtl/apple1.v | 8 +--- rtl/clock.v | 19 +------- rtl/vga/font_rom.v | 2 +- rtl/vga/vga.v | 110 ++++++++++++++++++++++++++++++++------------- 5 files changed, 123 insertions(+), 96 deletions(-) diff --git a/roms/vga_vram.bin b/roms/vga_vram.bin index 9b22fab..5efc568 100644 --- a/roms/vga_vram.bin +++ b/roms/vga_vram.bin @@ -1,43 +1,43 @@ -000001 -000010 -000011 -000100 -000101 -000110 -000111 -001000 -001001 -001010 -001011 -001100 -001101 -001110 -001111 -010000 -010001 -010010 -010011 -010100 -010101 -010110 -010111 -011000 -011001 -011010 -011011 -011100 -011101 -011110 -011111 -100000 -100001 -100010 -100011 -100100 -100101 -100110 -100111 -101000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 +100000 100000 100000 100000 diff --git a/rtl/apple1.v b/rtl/apple1.v index af3023b..b1ea051 100644 --- a/rtl/apple1.v +++ b/rtl/apple1.v @@ -58,12 +58,10 @@ module apple1( // Clocks wire cpu_clken; - wire blink_clken; clock my_clock( .clk25(clk25), .rst_n(rst_n), - .cpu_clken(cpu_clken), - .blink_clken(blink_clken) + .cpu_clken(cpu_clken) ); ////////////////////////////////////////////////////////////////////////// @@ -196,9 +194,7 @@ module apple1( .address(ab[0]), .w_en(we & vga_cs), - .din(dbo), - - .blink_clken(blink_clken) + .din(dbo) ); ////////////////////////////////////////////////////////////////////////// diff --git a/rtl/clock.v b/rtl/clock.v index 2053531..2098365 100644 --- a/rtl/clock.v +++ b/rtl/clock.v @@ -28,8 +28,7 @@ module clock( input rst_n, // active low synchronous reset // Clock enables - output reg cpu_clken, // 1MHz clock enable for the CPU and devices - output reg blink_clken // 1Hz clock enable for cursor blink + output reg cpu_clken // 1MHz clock enable for the CPU and devices ); // generate clock enable once every @@ -70,20 +69,4 @@ module clock( end `endif - reg [20:0] bclk_div; - always @(posedge clk25) - begin - // note: bclk_div should be compared to - // N-1, where N is the clock divisor - if (cpu_clken) - begin - if ((bclk_div == 500000) || (rst_n == 1'b0)) - bclk_div <= 0; - else - bclk_div <= bclk_div + 1'b1; - - blink_clken <= (bclk_div[20:0] == 0); - end - end - endmodule diff --git a/rtl/vga/font_rom.v b/rtl/vga/font_rom.v index 1259c36..38cd9ff 100644 --- a/rtl/vga/font_rom.v +++ b/rtl/vga/font_rom.v @@ -48,7 +48,7 @@ module font_rom( wire [3:0] line_ptr = line[4:1]; always @(posedge clk) - out <= rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr]; + out <= (line[0] & pixel[0]) ? rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr] : 1'b0; endmodule diff --git a/rtl/vga/vga.v b/rtl/vga/vga.v index 68f3e09..5394484 100644 --- a/rtl/vga/vga.v +++ b/rtl/vga/vga.v @@ -9,12 +9,11 @@ module vga( output vga_blu, // blue VGA signal input address, // address bus input w_en, // active high write enable strobe - input [7:0] din, // 8-bit data bas (input) - input blink_clken // cursor blink enable strobe + input [7:0] din // 8-bit data bas (input) ); ////////////////////////////////////////////////////////////////////////// - // VGA Sync Generation + // Registers and Parameters // video structure constants parameter h_pixels = 799; // horizontal pixels per line @@ -32,17 +31,41 @@ module vga( wire [3:0] h_dot; reg [4:0] v_dot; + // hardware cursor registers + wire [9:0] cursor; reg [5:0] h_cursor; - reg [4:0] v_cursor; + reg [9:0] v_cursor; + // vram indexing registers + reg [9:0] vram_start_addr; + reg [5:0] vram_h_addr; + reg [9:0] vram_v_addr; + + // vram registers + wire [9:0] vram_r_addr; + reg [9:0] vram_w_addr; + reg vram_w_en; + reg [5:0] vram_din; + wire [5:0] vram_dout; + + // font rom registers + wire [5:0] font_char; + wire [3:0] font_pixel; + wire [4:0] font_line; + wire font_out; + + // cpu control registers + reg char_seen; + + // active region strobes wire h_active; wire v_active; assign h_active = (h_cnt >= hbp && h_cnt < hfp); assign v_active = (v_cnt >= vbp && v_cnt < vfp); - assign vga_h_sync = (h_cnt < h_pulse) ? 0 : 1; - assign vga_v_sync = (v_cnt < v_pulse) ? 0 : 1; - + ////////////////////////////////////////////////////////////////////////// + // VGA Sync Generation + // always @(posedge clk25 or posedge rst) begin if (rst) @@ -90,11 +113,6 @@ module vga( ////////////////////////////////////////////////////////////////////////// // Character ROM - wire [5:0] font_char; - wire [3:0] font_pixel; - wire [4:0] font_line; - wire font_out; - font_rom my_font_rom( .clk(clk25), .character(font_char), @@ -106,12 +124,6 @@ module vga( ////////////////////////////////////////////////////////////////////////// // Video RAM - wire [9:0] vram_r_addr; - reg [9:0] vram_w_addr; - reg vram_w_en; - reg [5:0] vram_din; - wire [5:0] vram_dout; - vram my_vram( .clk(clk25), .read_addr(vram_r_addr), @@ -122,10 +134,6 @@ module vga( .dout(vram_dout) ); - - reg [5:0] vram_h_addr; - reg [9:0] vram_v_addr; - ////////////////////////////////////////////////////////////////////////// // Video Signal Generation @@ -151,25 +159,53 @@ module vga( end end - assign vram_r_addr = ({4'd0, vram_h_addr} + vram_v_addr); - assign font_char = vram_dout; + ////////////////////////////////////////////////////////////////////////// + // Cursor blink + + reg blink; + reg [22:0] blink_div; + always @(posedge clk25 or posedge rst) + begin + if (rst) + blink_div <= 0; + else + begin + blink_div <= blink_div + 1; + + if (blink_div == 23'd0) + blink <= ~blink; + end + end + + ////////////////////////////////////////////////////////////////////////// + // Pipeline and VGA signals + + // vram to font rom to display pipeline assignments + assign cursor = ({4'd0, h_cursor} + v_cursor); + assign vram_r_addr = (vram_start_addr + {4'd0, vram_h_addr} + vram_v_addr); + assign font_char = (vram_r_addr != cursor) ? vram_dout : (blink) ? 6'd0 : 6'd32; assign font_pixel = h_dot + 1; // offset by one to get pixel into right cycle, // font output one pixel clk behind assign font_line = v_dot; + // vga signals out to monitor assign vga_red = font_out; assign vga_grn = font_out; assign vga_blu = font_out; + assign vga_h_sync = (h_cnt < h_pulse) ? 0 : 1; + assign vga_v_sync = (v_cnt < v_pulse) ? 0 : 1; - reg char_seen; + ////////////////////////////////////////////////////////////////////////// + // CPU control and hardware cursor always @(posedge clk25 or posedge rst) begin if (rst) begin h_cursor <= 6'd0; - v_cursor <= 5'd0; + v_cursor <= 10'd0; char_seen <= 0; + vram_start_addr <= 0; end else begin @@ -187,16 +223,16 @@ module vga( begin // handle carriage return h_cursor <= 0; - v_cursor <= v_cursor + 1; + v_cursor <= v_cursor + 10'h28; end 8'h7F: // ignore the DDR call to the PIA - h_cursor <= h_cursor + 1; + h_cursor <= 0; default: begin - vram_w_addr <= ((v_cursor * 40) + {4'b0, h_cursor}); + vram_w_addr <= cursor; vram_din <= {~din[6], din[4:0]}; vram_w_en <= 1; @@ -210,13 +246,25 @@ module vga( v_cursor <= v_cursor + 1; end + if (v_cursor == 920) + begin + // force cursor to start at bottom of screen + // FIXME: now we need to scroll + v_cursor <= 920; + vram_start_addr <= vram_start_addr + 10'h28; + end + + if (vram_start_addr >= 920) + vram_start_addr <= 0; + + /* if (v_cursor == 23) begin // here we need to add the scroll, probably by moving the // HEAD of vram up one line - v_cursor <= 0; + vram_start_addr <= vram_start_addr + 10'h28; end - + */ end else if(~enable & ~w_en) char_seen <= 0;