mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-26 10:49:17 +00:00
152 lines
3.5 KiB
Verilog
152 lines
3.5 KiB
Verilog
`include "hvsync_generator.v"
|
|
|
|
module car_bitmap(yofs, bits);
|
|
|
|
input [3:0] yofs;
|
|
output [7:0] bits;
|
|
|
|
reg [7:0] bitarray[16];
|
|
|
|
assign bits = bitarray[yofs];
|
|
|
|
initial begin/*{w:8,h:16}*/
|
|
bitarray[0] = 8'b110000;
|
|
bitarray[1] = 8'b1110111;
|
|
bitarray[2] = 8'b11100110;
|
|
bitarray[3] = 8'b11111111;
|
|
bitarray[4] = 8'b11100110;
|
|
bitarray[5] = 8'b1100111;
|
|
bitarray[6] = 8'b110000;
|
|
bitarray[7] = 8'b110000;
|
|
bitarray[8] = 8'b110000;
|
|
bitarray[9] = 8'b1110000;
|
|
bitarray[10] = 8'b1100000;
|
|
bitarray[11] = 8'b11100000;
|
|
bitarray[12] = 8'b11101100;
|
|
bitarray[13] = 8'b11111100;
|
|
bitarray[14] = 8'b11001100;
|
|
bitarray[15] = 8'b1100;
|
|
end
|
|
endmodule
|
|
|
|
module sprite_renderer(clk, vstart, load, hstart, rom_yofs, rom_bits,
|
|
gfx, in_progress);
|
|
|
|
input clk, vstart, load, hstart;
|
|
output [3:0] rom_yofs;
|
|
input [7:0] rom_bits;
|
|
output gfx;
|
|
output in_progress = yactive;
|
|
|
|
reg [3:0] ycount;
|
|
reg [3:0] xcount;
|
|
reg yactive;
|
|
reg xactive;
|
|
reg loading;
|
|
|
|
reg [7:0] outbits;
|
|
|
|
always @(posedge clk)
|
|
begin
|
|
// set a default value (blank) for pixel output
|
|
// note: multiple non-blocking assignments are vendor-specific
|
|
gfx <= 0;
|
|
// load next line? set ROM address
|
|
if (yactive && load) begin
|
|
rom_yofs <= ~ycount;
|
|
loading <= 1;
|
|
// ROM address was set, now latch bits from bus
|
|
end else if (loading) begin
|
|
outbits <= rom_bits;
|
|
loading <= 0;
|
|
ycount <= ycount + 1;
|
|
// start sprite at this vertical scanline
|
|
end else if (vstart) begin
|
|
yactive <= 1;
|
|
//ycount <= 0;
|
|
// start sprite at this horizontal clock
|
|
end else if (hstart && yactive) begin
|
|
xactive <= 1;
|
|
//xcount <= 0;
|
|
// both X & Y active, set pixel output
|
|
end else if (xactive && yactive)
|
|
begin
|
|
// mirror graphics left/right
|
|
gfx <= outbits[xcount[3]?~xcount[2:0]:xcount[2:0]];
|
|
xcount <= xcount + 1;
|
|
if (xcount == 15) begin // pre-increment value
|
|
xactive <= 0; // done drawing this scanline
|
|
if (ycount == 0) // post-increment value
|
|
yactive <= 0; // done drawing sprite
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
module test_top(clk, hsync, vsync, rgb, hpaddle, vpaddle);
|
|
|
|
input clk;
|
|
input hpaddle, vpaddle;
|
|
output hsync, vsync;
|
|
output [2:0] rgb;
|
|
wire display_on;
|
|
wire [8:0] hpos;
|
|
wire [8:0] vpos;
|
|
|
|
reg [7:0] player_x;
|
|
reg [7:0] player_y;
|
|
|
|
reg [7:0] paddle_x;
|
|
reg [7:0] paddle_y;
|
|
|
|
hvsync_generator hvsync_gen(
|
|
.clk(clk),
|
|
.hsync(hsync),
|
|
.vsync(vsync),
|
|
.display_on(display_on),
|
|
.hpos(hpos),
|
|
.vpos(vpos)
|
|
);
|
|
|
|
wire [3:0] car_sprite_yofs;
|
|
wire [7:0] car_sprite_bits;
|
|
|
|
car_bitmap car(
|
|
.yofs(car_sprite_yofs),
|
|
.bits(car_sprite_bits));
|
|
|
|
wire vstart = {1'0,player_y} == vpos;
|
|
wire hstart = {1'0,player_x} == hpos;
|
|
wire car_gfx;
|
|
wire unused;
|
|
|
|
sprite_renderer renderer(
|
|
.clk(clk),
|
|
.vstart(vstart),
|
|
.load(hsync),
|
|
.hstart(hstart),
|
|
.rom_yofs(car_sprite_yofs),
|
|
.rom_bits(car_sprite_bits),
|
|
.gfx(car_gfx),
|
|
.in_progress(unused));
|
|
|
|
always @(posedge hsync)
|
|
begin
|
|
if (!hpaddle) paddle_x <= vpos[7:0];
|
|
if (!vpaddle) paddle_y <= vpos[7:0];
|
|
end
|
|
|
|
always @(posedge vsync)
|
|
begin
|
|
player_x <= paddle_x;
|
|
player_y <= paddle_y;
|
|
end
|
|
|
|
wire r = display_on && car_gfx;
|
|
wire g = display_on && car_gfx;
|
|
wire b = display_on && car_gfx;
|
|
assign rgb = {b,g,r};
|
|
|
|
endmodule
|