From db005dc98e13318176e28219c2d80cd8513903d9 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 28 Feb 2018 11:09:29 -0600 Subject: [PATCH] can scroll scope when paused; updates to presets --- .../verilog/{maze_game.v => cpu_platform.v} | 44 ++++++++------ presets/verilog/sprite_scanline_renderer.v | 10 +--- presets/verilog/tile_renderer.v | 59 ++++++++++++------- src/platform/verilog.js | 29 ++++++--- 4 files changed, 88 insertions(+), 54 deletions(-) rename presets/verilog/{maze_game.v => cpu_platform.v} (83%) diff --git a/presets/verilog/maze_game.v b/presets/verilog/cpu_platform.v similarity index 83% rename from presets/verilog/maze_game.v rename to presets/verilog/cpu_platform.v index 9f1be8ed..c72c3742 100644 --- a/presets/verilog/maze_game.v +++ b/presets/verilog/cpu_platform.v @@ -7,7 +7,7 @@ `include "sound_generator.v" `include "cpu16.v" -module maze_game_top(clk, reset, hsync, vsync, rgb); +module cpu_platform(clk, reset, hsync, vsync, rgb); input clk, reset; output hsync, vsync; @@ -19,11 +19,10 @@ module maze_game_top(clk, reset, hsync, vsync, rgb); // video RAM bus wire [15:0] ram_read; - reg [15:0] ram_write = 0; - reg ram_writeenable = 0; + reg [15:0] ram_write; + reg ram_writeenable; // multiplex sprite and tile RAM - wire sprite_ram_select = (vpos == 256); reg [15:0] tile_ram_addr; reg [5:0] sprite_ram_addr; wire tile_reading; @@ -32,8 +31,8 @@ module maze_game_top(clk, reset, hsync, vsync, rgb); always @(*) if (cpu_busy) begin - if (sprite_ram_select) - mux_ram_addr = {9'b1111111, sprite_ram_addr}; + if (sprite_reading) + mux_ram_addr = {9'b111111100, sprite_ram_addr}; else mux_ram_addr = tile_ram_addr[14:0]; end else @@ -141,34 +140,45 @@ module maze_game_top(clk, reset, hsync, vsync, rgb); .org 0x8000 .len 1024 mov sp,@$6fff - mov dx,@Init + mov dx,@InitPageTable jsr dx - mov ax,#0 - mov dx,@Clear + mov ax,@$4ffe + mov dx,@ClearTiles + jsr dx + mov dx,@ClearSprites jsr dx reset -Init: +InitPageTable: mov ax,@$6000 ; screen buffer mov bx,@$7e00 ; page table start mov cx,#32 ; 32 rows -InitLoop: +InitPTLoop: mov [bx],ax - mov [ax],ax add ax,#32 inc bx dec cx - bnz InitLoop + bnz InitPTLoop rts -Clear: - mov bx,@$7e00 - mov cx,@1024 +ClearTiles: + mov bx,@$6000 + mov cx,@$390 ClearLoop: mov [bx],ax inc bx dec cx bnz ClearLoop - rts +ClearSprites: + mov bx,@$7f00 + mov ax,#0 + mov cx,#$80 +ClearSLoop: + mov ax,[bx] + add ax,@$101 + mov [bx],ax + inc bx + dec cx + bnz ClearSLoop __endasm }; end diff --git a/presets/verilog/sprite_scanline_renderer.v b/presets/verilog/sprite_scanline_renderer.v index e5c08ec4..bb357f42 100644 --- a/presets/verilog/sprite_scanline_renderer.v +++ b/presets/verilog/sprite_scanline_renderer.v @@ -94,7 +94,8 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb, if (reset || vpos[8]) begin // load sprites from RAM on line 260 // 8 cycles per sprite - if (vpos == 260 && hpos < N*8) begin + // do first sprite twice b/c CPU might still be busy + if (vpos == 260 && hpos < N*8+8) begin ram_busy <= 1; case (hpos[2:0]) 3: begin @@ -167,13 +168,6 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb, scanline[read_bufidx] <= 0; end - initial - begin - sprite_xpos[0] = 0; - sprite_ypos[0] = 0; - sprite_attr[0] = 1; - end - endmodule module test_scanline_render_top(clk, reset, hsync, vsync, rgb); diff --git a/presets/verilog/tile_renderer.v b/presets/verilog/tile_renderer.v index d50d27d9..01528e74 100644 --- a/presets/verilog/tile_renderer.v +++ b/presets/verilog/tile_renderer.v @@ -2,7 +2,7 @@ `include "font_cp437_8x8.v" `include "ram.v" -module tile_renderer(clk, reset, hpos, vpos, display_on, +module tile_renderer(clk, reset, hpos, vpos, rgb, ram_addr, ram_read, ram_busy, rom_addr, rom_data); @@ -10,7 +10,6 @@ module tile_renderer(clk, reset, hpos, vpos, display_on, input clk, reset; input [8:0] hpos; input [8:0] vpos; - input display_on; output [3:0] rgb; output reg [15:0] ram_addr; @@ -22,33 +21,42 @@ module tile_renderer(clk, reset, hpos, vpos, display_on, reg [7:0] page_base = 8'h7e; // page table base (8 bits) reg [15:0] row_base; // row table base (16 bits) - - wire [4:0] row = vpos[7:3]; // 5-bit row, vpos / 8 + reg [4:0] row; + //wire [4:0] row = vpos[7:3]; // 5-bit row, vpos / 8 wire [4:0] col = hpos[7:3]; // 5-bit column, hpos / 8 wire [2:0] yofs = vpos[2:0]; // scanline of cell (0-7) wire [2:0] xofs = hpos[2:0]; // which pixel to draw (0-7) - reg [7:0] char; - reg [7:0] attr; + reg [15:0] cur_cell; + wire [7:0] cur_char = cur_cell[7:0]; + wire [7:0] cur_attr = cur_cell[15:8]; // tile ROM address - assign rom_addr = {char, yofs}; + assign rom_addr = {cur_char, yofs}; reg [15:0] row_buffer[0:31]; - + // lookup char and attr always @(posedge clk) begin + // reset row to 0 when last row displayed + if (vpos == 248) begin + row <= 0; + end // time to read a row? if (vpos[2:0] == 7) begin // read row_base from page table (2 bytes) case (hpos[7:0]) - 186: ram_busy <= 1; + 185: ram_busy <= 1; 190: ram_addr <= {page_base, 3'b000, row}; 192: row_base <= ram_read; - 192+32: ram_busy <= 0; + 192+32: begin + ram_busy <= 0; + row <= row + 1; + end endcase // load row of tile data from RAM - if (hpos >= 192 && hpos < 192+32) begin + // (last two twice) + if (hpos >= 192 && hpos < 192+34) begin ram_addr <= row_base + 16'(hpos[4:0]); row_buffer[hpos[4:0]-2] <= ram_read; end @@ -57,17 +65,16 @@ module tile_renderer(clk, reset, hpos, vpos, display_on, if (hpos < 256) begin case (hpos[2:0]) 7: begin - char <= row_buffer[col][7:0]; - attr <= row_buffer[col][15:8]; + cur_cell <= row_buffer[col+1]; end endcase + end else if (hpos == 308) begin + cur_cell <= row_buffer[0]; end end // extract bit from ROM output - assign rgb = display_on - ? (rom_data[~xofs] ? attr[3:0] : attr[7:4]) - : 0; + assign rgb = rom_data[~xofs] ? cur_attr[3:0] : cur_attr[7:4]; endmodule @@ -108,26 +115,38 @@ module test_tilerender_top(clk, reset, hsync, vsync, rgb); .addr(ram_addr), .we(ram_writeenable) ); - + + wire [3:0] rgb_tile; + tile_renderer tile_gen( .clk(clk), .reset(reset), .hpos(hpos), .vpos(vpos), - .display_on(display_on), .ram_addr(ram_addr), .ram_read(ram_read), .ram_busy(ram_busy), .rom_addr(rom_addr), .rom_data(rom_data), - .rgb(rgb) + .rgb(rgb_tile) ); + + assign rgb = display_on ? rgb_tile : rgb_tile|8; // tile ROM font_cp437_8x8 tile_rom( .addr(rom_addr), .data(rom_data) ); - + + initial begin + for (int i=0; i<32; i++) begin + ram.mem[16'h7e00 + 16'(i)] = 16'(i*32); + ram.mem[16'(i*32)] = 16'hfa1b; + ram.mem[16'(i*32+31)] = 16'hfb1a; + ram.mem[16'(i)] = 16'hfc18; + ram.mem[16'(28*32+i)] = 16'hfd19; + end + end endmodule diff --git a/src/platform/verilog.js b/src/platform/verilog.js index beefbc93..cfd07198 100644 --- a/src/platform/verilog.js +++ b/src/platform/verilog.js @@ -24,7 +24,7 @@ var VERILOG_PRESETS = [ {id:'tile_renderer.v', name:'Tile Renderer'}, {id:'sprite_scanline_renderer.v', name:'Sprite Scanline Renderer'}, {id:'cpu16.v', name:'16-Bit CPU'}, - {id:'maze_game.v', name:'Maze Game'}, + {id:'cpu_platform.v', name:'CPU Platform'}, ]; var VERILOG_KEYCODE_MAP = makeKeycodeMap([ @@ -332,7 +332,7 @@ var VerilogPlatform = function(mainElement, options) { var fps = self.getFrameRate(); // darken the previous frame? if (fps < 45) { - var mask = fps > 10 ? 0xcfffffff : 0x7fdddddd; + var mask = fps > 5 ? 0xe7ffffff : 0x7fdddddd; for (var i=0; i 0.01) { video.getContext().fillStyle = "black"; video.getContext().fillRect(0, 0, videoWidth, videoHeight); @@ -359,9 +368,6 @@ var VerilogPlatform = function(mainElement, options) { // smooth transition scope_a = scope_a * 0.9 + (trace?1.0:0.0) * 0.1; scope_y_top = (1 - scope_a*0.7) * videoHeight - (1 - scope_a) * scope_y_offset; - updateInspectionPostFrame(); - self.restartDebugState(); - gen.__unreset(); } function displayTraceBuffer() { @@ -520,7 +526,7 @@ var VerilogPlatform = function(mainElement, options) { if (mouse_pressed) { scope_y_offset = clamp(Math.min(0,-scope_max_y+videoHeight), 0, scope_y_offset + new_y - paddle_y); scope_time_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 16); - dirty = true; + redrawFrame(); } paddle_x = clamp(8, 240, new_x); paddle_y = clamp(8, 240, new_y); @@ -529,16 +535,17 @@ var VerilogPlatform = function(mainElement, options) { scope_time_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 16); mouse_pressed = true; if (e.target.setCapture) e.target.setCapture(); - dirty = true; + redrawFrame(); }); $(video.canvas).mouseup(function(e) { mouse_pressed = false; if (e.target.setCapture) e.target.releaseCapture(); + redrawFrame(); }); $(video.canvas).keydown(function(e) { switch (e.keyCode) { - case 37: scope_time_x--; dirty=true; break; - case 39: scope_time_x++; dirty=true; break; + case 37: scope_time_x--; redrawFrame(); break; + case 39: scope_time_x++; redrawFrame(); break; } }); idata = video.getFrameData(); @@ -555,6 +562,10 @@ var VerilogPlatform = function(mainElement, options) { self.setFrameRate(60); } + function redrawFrame() { + updateAnimateScope(); + } + this.printErrorCodeContext = function(e, code) { if (e.lineNumber && e.message) { var lines = code.split('\n');