1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2025-02-20 14:29:16 +00:00

can scroll scope when paused; updates to presets

This commit is contained in:
Steven Hugg 2018-02-28 11:09:29 -06:00
parent 8f1563f88e
commit db005dc98e
4 changed files with 88 additions and 54 deletions

View File

@ -7,7 +7,7 @@
`include "sound_generator.v" `include "sound_generator.v"
`include "cpu16.v" `include "cpu16.v"
module maze_game_top(clk, reset, hsync, vsync, rgb); module cpu_platform(clk, reset, hsync, vsync, rgb);
input clk, reset; input clk, reset;
output hsync, vsync; output hsync, vsync;
@ -19,11 +19,10 @@ module maze_game_top(clk, reset, hsync, vsync, rgb);
// video RAM bus // video RAM bus
wire [15:0] ram_read; wire [15:0] ram_read;
reg [15:0] ram_write = 0; reg [15:0] ram_write;
reg ram_writeenable = 0; reg ram_writeenable;
// multiplex sprite and tile RAM // multiplex sprite and tile RAM
wire sprite_ram_select = (vpos == 256);
reg [15:0] tile_ram_addr; reg [15:0] tile_ram_addr;
reg [5:0] sprite_ram_addr; reg [5:0] sprite_ram_addr;
wire tile_reading; wire tile_reading;
@ -32,8 +31,8 @@ module maze_game_top(clk, reset, hsync, vsync, rgb);
always @(*) always @(*)
if (cpu_busy) begin if (cpu_busy) begin
if (sprite_ram_select) if (sprite_reading)
mux_ram_addr = {9'b1111111, sprite_ram_addr}; mux_ram_addr = {9'b111111100, sprite_ram_addr};
else else
mux_ram_addr = tile_ram_addr[14:0]; mux_ram_addr = tile_ram_addr[14:0];
end else end else
@ -141,34 +140,45 @@ module maze_game_top(clk, reset, hsync, vsync, rgb);
.org 0x8000 .org 0x8000
.len 1024 .len 1024
mov sp,@$6fff mov sp,@$6fff
mov dx,@Init mov dx,@InitPageTable
jsr dx jsr dx
mov ax,#0 mov ax,@$4ffe
mov dx,@Clear mov dx,@ClearTiles
jsr dx
mov dx,@ClearSprites
jsr dx jsr dx
reset reset
Init: InitPageTable:
mov ax,@$6000 ; screen buffer mov ax,@$6000 ; screen buffer
mov bx,@$7e00 ; page table start mov bx,@$7e00 ; page table start
mov cx,#32 ; 32 rows mov cx,#32 ; 32 rows
InitLoop: InitPTLoop:
mov [bx],ax mov [bx],ax
mov [ax],ax
add ax,#32 add ax,#32
inc bx inc bx
dec cx dec cx
bnz InitLoop bnz InitPTLoop
rts rts
Clear: ClearTiles:
mov bx,@$7e00 mov bx,@$6000
mov cx,@1024 mov cx,@$390
ClearLoop: ClearLoop:
mov [bx],ax mov [bx],ax
inc bx inc bx
dec cx dec cx
bnz ClearLoop bnz ClearLoop
rts 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 __endasm
}; };
end end

View File

@ -94,7 +94,8 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb,
if (reset || vpos[8]) begin if (reset || vpos[8]) begin
// load sprites from RAM on line 260 // load sprites from RAM on line 260
// 8 cycles per sprite // 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; ram_busy <= 1;
case (hpos[2:0]) case (hpos[2:0])
3: begin 3: begin
@ -167,13 +168,6 @@ module sprite_scanline_renderer(clk, reset, hpos, vpos, rgb,
scanline[read_bufidx] <= 0; scanline[read_bufidx] <= 0;
end end
initial
begin
sprite_xpos[0] = 0;
sprite_ypos[0] = 0;
sprite_attr[0] = 1;
end
endmodule endmodule
module test_scanline_render_top(clk, reset, hsync, vsync, rgb); module test_scanline_render_top(clk, reset, hsync, vsync, rgb);

View File

@ -2,7 +2,7 @@
`include "font_cp437_8x8.v" `include "font_cp437_8x8.v"
`include "ram.v" `include "ram.v"
module tile_renderer(clk, reset, hpos, vpos, display_on, module tile_renderer(clk, reset, hpos, vpos,
rgb, rgb,
ram_addr, ram_read, ram_busy, ram_addr, ram_read, ram_busy,
rom_addr, rom_data); rom_addr, rom_data);
@ -10,7 +10,6 @@ module tile_renderer(clk, reset, hpos, vpos, display_on,
input clk, reset; input clk, reset;
input [8:0] hpos; input [8:0] hpos;
input [8:0] vpos; input [8:0] vpos;
input display_on;
output [3:0] rgb; output [3:0] rgb;
output reg [15:0] ram_addr; 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 [7:0] page_base = 8'h7e; // page table base (8 bits)
reg [15:0] row_base; // row table base (16 bits) reg [15:0] row_base; // row table base (16 bits)
reg [4:0] row;
wire [4:0] row = vpos[7:3]; // 5-bit row, vpos / 8 //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 [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] yofs = vpos[2:0]; // scanline of cell (0-7)
wire [2:0] xofs = hpos[2:0]; // which pixel to draw (0-7) wire [2:0] xofs = hpos[2:0]; // which pixel to draw (0-7)
reg [7:0] char; reg [15:0] cur_cell;
reg [7:0] attr; wire [7:0] cur_char = cur_cell[7:0];
wire [7:0] cur_attr = cur_cell[15:8];
// tile ROM address // tile ROM address
assign rom_addr = {char, yofs}; assign rom_addr = {cur_char, yofs};
reg [15:0] row_buffer[0:31]; reg [15:0] row_buffer[0:31];
// lookup char and attr // lookup char and attr
always @(posedge clk) begin always @(posedge clk) begin
// reset row to 0 when last row displayed
if (vpos == 248) begin
row <= 0;
end
// time to read a row? // time to read a row?
if (vpos[2:0] == 7) begin if (vpos[2:0] == 7) begin
// read row_base from page table (2 bytes) // read row_base from page table (2 bytes)
case (hpos[7:0]) case (hpos[7:0])
186: ram_busy <= 1; 185: ram_busy <= 1;
190: ram_addr <= {page_base, 3'b000, row}; 190: ram_addr <= {page_base, 3'b000, row};
192: row_base <= ram_read; 192: row_base <= ram_read;
192+32: ram_busy <= 0; 192+32: begin
ram_busy <= 0;
row <= row + 1;
end
endcase endcase
// load row of tile data from RAM // 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]); ram_addr <= row_base + 16'(hpos[4:0]);
row_buffer[hpos[4:0]-2] <= ram_read; row_buffer[hpos[4:0]-2] <= ram_read;
end end
@ -57,17 +65,16 @@ module tile_renderer(clk, reset, hpos, vpos, display_on,
if (hpos < 256) begin if (hpos < 256) begin
case (hpos[2:0]) case (hpos[2:0])
7: begin 7: begin
char <= row_buffer[col][7:0]; cur_cell <= row_buffer[col+1];
attr <= row_buffer[col][15:8];
end end
endcase endcase
end else if (hpos == 308) begin
cur_cell <= row_buffer[0];
end end
end end
// extract bit from ROM output // extract bit from ROM output
assign rgb = display_on assign rgb = rom_data[~xofs] ? cur_attr[3:0] : cur_attr[7:4];
? (rom_data[~xofs] ? attr[3:0] : attr[7:4])
: 0;
endmodule endmodule
@ -109,25 +116,37 @@ module test_tilerender_top(clk, reset, hsync, vsync, rgb);
.we(ram_writeenable) .we(ram_writeenable)
); );
wire [3:0] rgb_tile;
tile_renderer tile_gen( tile_renderer tile_gen(
.clk(clk), .clk(clk),
.reset(reset), .reset(reset),
.hpos(hpos), .hpos(hpos),
.vpos(vpos), .vpos(vpos),
.display_on(display_on),
.ram_addr(ram_addr), .ram_addr(ram_addr),
.ram_read(ram_read), .ram_read(ram_read),
.ram_busy(ram_busy), .ram_busy(ram_busy),
.rom_addr(rom_addr), .rom_addr(rom_addr),
.rom_data(rom_data), .rom_data(rom_data),
.rgb(rgb) .rgb(rgb_tile)
); );
assign rgb = display_on ? rgb_tile : rgb_tile|8;
// tile ROM // tile ROM
font_cp437_8x8 tile_rom( font_cp437_8x8 tile_rom(
.addr(rom_addr), .addr(rom_addr),
.data(rom_data) .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 endmodule

View File

@ -24,7 +24,7 @@ var VERILOG_PRESETS = [
{id:'tile_renderer.v', name:'Tile Renderer'}, {id:'tile_renderer.v', name:'Tile Renderer'},
{id:'sprite_scanline_renderer.v', name:'Sprite Scanline Renderer'}, {id:'sprite_scanline_renderer.v', name:'Sprite Scanline Renderer'},
{id:'cpu16.v', name:'16-Bit CPU'}, {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([ var VERILOG_KEYCODE_MAP = makeKeycodeMap([
@ -332,7 +332,7 @@ var VerilogPlatform = function(mainElement, options) {
var fps = self.getFrameRate(); var fps = self.getFrameRate();
// darken the previous frame? // darken the previous frame?
if (fps < 45) { if (fps < 45) {
var mask = fps > 10 ? 0xcfffffff : 0x7fdddddd; var mask = fps > 5 ? 0xe7ffffff : 0x7fdddddd;
for (var i=0; i<idata.length; i++) for (var i=0; i<idata.length; i++)
idata[i] &= mask; idata[i] &= mask;
} }
@ -342,6 +342,15 @@ var VerilogPlatform = function(mainElement, options) {
updateVideoFrameCycles(cyclesPerFrame * fps/60 + 1, sync, trace); updateVideoFrameCycles(cyclesPerFrame * fps/60 + 1, sync, trace);
//if (trace) displayTraceBuffer(); //if (trace) displayTraceBuffer();
updateInspectionFrame(); updateInspectionFrame();
updateAnimateScope(trace);
updateInspectionPostFrame();
self.restartDebugState();
gen.__unreset();
}
function updateAnimateScope() {
var fps = self.getFrameRate();
var trace = fps < 0.02;
if (scope_a > 0.01) { if (scope_a > 0.01) {
video.getContext().fillStyle = "black"; video.getContext().fillStyle = "black";
video.getContext().fillRect(0, 0, videoWidth, videoHeight); video.getContext().fillRect(0, 0, videoWidth, videoHeight);
@ -359,9 +368,6 @@ var VerilogPlatform = function(mainElement, options) {
// smooth transition // smooth transition
scope_a = scope_a * 0.9 + (trace?1.0:0.0) * 0.1; 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; scope_y_top = (1 - scope_a*0.7) * videoHeight - (1 - scope_a) * scope_y_offset;
updateInspectionPostFrame();
self.restartDebugState();
gen.__unreset();
} }
function displayTraceBuffer() { function displayTraceBuffer() {
@ -520,7 +526,7 @@ var VerilogPlatform = function(mainElement, options) {
if (mouse_pressed) { if (mouse_pressed) {
scope_y_offset = clamp(Math.min(0,-scope_max_y+videoHeight), 0, scope_y_offset + new_y - paddle_y); 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); 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_x = clamp(8, 240, new_x);
paddle_y = clamp(8, 240, new_y); 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); scope_time_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 16);
mouse_pressed = true; mouse_pressed = true;
if (e.target.setCapture) e.target.setCapture(); if (e.target.setCapture) e.target.setCapture();
dirty = true; redrawFrame();
}); });
$(video.canvas).mouseup(function(e) { $(video.canvas).mouseup(function(e) {
mouse_pressed = false; mouse_pressed = false;
if (e.target.setCapture) e.target.releaseCapture(); if (e.target.setCapture) e.target.releaseCapture();
redrawFrame();
}); });
$(video.canvas).keydown(function(e) { $(video.canvas).keydown(function(e) {
switch (e.keyCode) { switch (e.keyCode) {
case 37: scope_time_x--; dirty=true; break; case 37: scope_time_x--; redrawFrame(); break;
case 39: scope_time_x++; dirty=true; break; case 39: scope_time_x++; redrawFrame(); break;
} }
}); });
idata = video.getFrameData(); idata = video.getFrameData();
@ -555,6 +562,10 @@ var VerilogPlatform = function(mainElement, options) {
self.setFrameRate(60); self.setFrameRate(60);
} }
function redrawFrame() {
updateAnimateScope();
}
this.printErrorCodeContext = function(e, code) { this.printErrorCodeContext = function(e, code) {
if (e.lineNumber && e.message) { if (e.lineNumber && e.message) {
var lines = code.split('\n'); var lines = code.split('\n');