From fdc93fb0d27f8c205d7f254573becf852f8e0417 Mon Sep 17 00:00:00 2001 From: Alan Garfield Date: Thu, 8 Feb 2018 00:40:43 +1100 Subject: [PATCH] Hardware scrolling seems to be working! --- roms/vga_vram.bin | 1024 ++++++++++++++++++++++++++++++++++++++++++++ rtl/apple1.v | 22 +- rtl/vga/font_rom.v | 22 +- rtl/vga/vga.v | 101 +++-- rtl/vga/vram.v | 8 +- 5 files changed, 1108 insertions(+), 69 deletions(-) diff --git a/roms/vga_vram.bin b/roms/vga_vram.bin index 5efc568..eace898 100644 --- a/roms/vga_vram.bin +++ b/roms/vga_vram.bin @@ -1022,3 +1022,1027 @@ 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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 b1ea051..dc659b5 100644 --- a/rtl/apple1.v +++ b/rtl/apple1.v @@ -88,8 +88,8 @@ module apple1( .we (we), .irq_n (1'b1), .nmi_n (1'b1), - .ready (cpu_clken), - .pc_monitor (pc_monitor) + .ready (cpu_clken) + //.pc_monitor (pc_monitor) ); ////////////////////////////////////////////////////////////////////////// @@ -112,6 +112,8 @@ module apple1( wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF + wire mode_cs = (ab[15:12] == 4'b1100); // 0xC000 + ////////////////////////////////////////////////////////////////////////// // RAM and ROM @@ -182,10 +184,12 @@ module apple1( ); // VGA Display interface + reg [1:0] vga_mode; vga my_vga( .clk25(clk25), .enable(vga_cs & cpu_clken), .rst(rst), + .vga_h_sync(vga_h_sync), .vga_v_sync(vga_v_sync), .vga_red(vga_red), @@ -194,9 +198,20 @@ module apple1( .address(ab[0]), .w_en(we & vga_cs), - .din(dbo) + .din(dbo), + .mode(vga_mode), + .debug(pc_monitor) ); + always @(posedge clk25 or posedge rst) + begin + if (rst) + vga_mode <= 2'b0; + else + if (mode_cs & we & cpu_clken) + vga_mode <= dbo[1:0]; + end + ////////////////////////////////////////////////////////////////////////// // CPU Data In MUX @@ -206,5 +221,6 @@ module apple1( basic_cs ? basic_dout : uart_cs ? uart_dout : ps2kb_cs ? ps2_dout : + mode_cs ? vga_mode : 8'hFF; endmodule diff --git a/rtl/vga/font_rom.v b/rtl/vga/font_rom.v index 1530ac2..04b57a9 100644 --- a/rtl/vga/font_rom.v +++ b/rtl/vga/font_rom.v @@ -26,6 +26,7 @@ module font_rom( input clk, // clock signal + input [1:0] mode, // character mode input [5:0] character, // address bus input [3:0] pixel, // address of the pixel to output input [4:0] line, // address of the line to output @@ -38,10 +39,10 @@ module font_rom( parameter ROM_FILENAME = "../../roms/vga_font.bin"; `endif - reg [7:0] rom[0:639]; + reg [7:0] rom[0:1023]; initial - $readmemb(ROM_FILENAME, rom, 0, 639); + $readmemb(ROM_FILENAME, rom, 0, 1023); // double width of pixel by ignoring bit 0 wire [2:0] pixel_ptr; @@ -52,15 +53,14 @@ module font_rom( always @(posedge clk) begin - `ifdef DOTTY - out <= (line[0] & pixel[0]) ? rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr] : 1'b0; - `endif - `ifdef SCANLINES - out <= (line[0]) ? rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr] : 1'b0; - `endif - `ifdef NORMAL - out <= rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr]; - `endif + // mode + // 00 - normal + // 01 - vertical scanlines + // 10 - horizontal scanlines + // 11 - dotty mode + out <= (mode[1] & line[0]) ? 1'b0 : + (mode[0] & pixel[0]) ? 1'b0 : + rom[(character * 10) + {2'd0, line_ptr}][pixel_ptr]; end endmodule diff --git a/rtl/vga/vga.v b/rtl/vga/vga.v index 5394484..f4ae96a 100644 --- a/rtl/vga/vga.v +++ b/rtl/vga/vga.v @@ -9,7 +9,9 @@ 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 [7:0] din, // 8-bit data bus (input) + input [1:0] mode, // 2-bit mode setting for pixel doubling + output [15:0] debug ); ////////////////////////////////////////////////////////////////////////// @@ -32,18 +34,19 @@ module vga( reg [4:0] v_dot; // hardware cursor registers - wire [9:0] cursor; + wire [10:0] cursor; reg [5:0] h_cursor; - reg [9:0] v_cursor; + reg [4:0] v_cursor; // vram indexing registers - reg [9:0] vram_start_addr; reg [5:0] vram_h_addr; - reg [9:0] vram_v_addr; + reg [4:0] vram_v_addr; + reg [4:0] vram_start_addr; + reg [4:0] vram_end_addr; // vram registers - wire [9:0] vram_r_addr; - reg [9:0] vram_w_addr; + wire [10:0] vram_r_addr; + reg [10:0] vram_w_addr; reg vram_w_en; reg [5:0] vram_din; wire [5:0] vram_dout; @@ -115,6 +118,7 @@ module vga( font_rom my_font_rom( .clk(clk25), + .mode(mode), .character(font_char), .pixel(font_pixel), .line(font_line), @@ -139,23 +143,23 @@ module vga( always @(posedge clk25 or posedge rst) begin if (rst) begin - vram_h_addr <= 0; - vram_v_addr <= 0; + vram_h_addr <= 'd0; + vram_v_addr <= 'd0; end else begin // start the pipeline for reading vram and font details // 3 pixel clock cycles early if (h_dot == 4'hC) - vram_h_addr <= vram_h_addr + 1; + vram_h_addr <= vram_h_addr + 'd1; // advance to next row when last display line is reached for row if (v_dot == 5'd19 && h_cnt == 10'd0) - vram_v_addr <= vram_v_addr + 10'h28; + vram_v_addr <= vram_v_addr + 'd1; // clear the address registers if we're not in visible area if (~h_active) - vram_h_addr <= 0; + vram_h_addr <= 'd0; if (~v_active) - vram_v_addr <= 0; + vram_v_addr <= vram_start_addr; end end @@ -181,8 +185,9 @@ module vga( // 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 cursor = {v_cursor, h_cursor}; + assign vram_r_addr = {vram_v_addr, vram_h_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 @@ -195,6 +200,8 @@ module vga( assign vga_h_sync = (h_cnt < h_pulse) ? 0 : 1; assign vga_v_sync = (v_cnt < v_pulse) ? 0 : 1; + assign debug = {v_cursor, 6'd0, vram_start_addr}; + ////////////////////////////////////////////////////////////////////////// // CPU control and hardware cursor @@ -203,14 +210,28 @@ module vga( if (rst) begin h_cursor <= 6'd0; - v_cursor <= 10'd0; - char_seen <= 0; - vram_start_addr <= 0; + v_cursor <= 5'd0; + char_seen <= 'b0; + vram_start_addr <= 5'd0; + vram_end_addr <= 5'd23; end else begin vram_w_en <= 0; + // cursor overflow handling + if (h_cursor == 6'd40) + begin + h_cursor <= 6'd0; + v_cursor <= v_cursor + 'd1; + end + + if (v_cursor == vram_end_addr) + begin + vram_start_addr <= vram_start_addr + 'd1; + vram_end_addr <= vram_end_addr + 'd1; + end + if (address == 1'b0) // address low == TX register begin if (enable & w_en & ~char_seen) @@ -219,56 +240,34 @@ module vga( char_seen <= 1; case(din) - 8'h8D: - begin + 8'h8D: begin // handle carriage return h_cursor <= 0; - v_cursor <= v_cursor + 10'h28; + v_cursor <= v_cursor + 'd1; end - 8'h7F: + 8'h7F: begin // ignore the DDR call to the PIA h_cursor <= 0; + end - default: - begin + default: begin vram_w_addr <= cursor; vram_din <= {~din[6], din[4:0]}; vram_w_en <= 1; - h_cursor <= h_cursor + 1; end endcase - - if (h_cursor == 39) - begin - h_cursor <= 0; - 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 - vram_start_addr <= vram_start_addr + 10'h28; - end - */ end else if(~enable & ~w_en) char_seen <= 0; end + else + begin + vram_w_addr <= {(vram_end_addr + 2), vram_h_addr}; + vram_din <= 6'd32; + vram_w_en <= 1; + end end end diff --git a/rtl/vga/vram.v b/rtl/vga/vram.v index cdf1706..f793b74 100644 --- a/rtl/vga/vram.v +++ b/rtl/vga/vram.v @@ -24,8 +24,8 @@ module vram( input clk, // clock signal - input [9:0] read_addr, // read address bus - input [9:0] write_addr, // write address bus + input [10:0] read_addr, // read address bus + input [10:0] write_addr, // write address bus input r_en, // active high read enable strobe input w_en, // active high write enable strobe input [5:0] din, // 6-bit data bus (input) @@ -38,10 +38,10 @@ module vram( parameter RAM_FILENAME = "../../roms/vga_vram.bin"; `endif - reg [5:0] ram_data[0:1023]; + reg [5:0] ram_data[0:2047]; initial - $readmemb(RAM_FILENAME, ram_data, 0, 1023); + $readmemb(RAM_FILENAME, ram_data, 0, 2047); always @(posedge clk) begin