mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-05-17 03:03:43 +00:00
GBC: added colour management to BG, full flags support for sprites (not used yet)
This commit is contained in:
@@ -488,7 +488,7 @@ wire cart_rd;
|
||||
wire cart_wr;
|
||||
|
||||
wire lcd_clkena;
|
||||
wire [1:0] lcd_data;
|
||||
wire [14:0] lcd_data;
|
||||
wire [1:0] lcd_mode;
|
||||
wire lcd_on;
|
||||
|
||||
@@ -534,7 +534,7 @@ lcd lcd (
|
||||
.pclk ( clk_sys ),
|
||||
.pce ( ce_pix ),
|
||||
.clk ( clk_cpu ),
|
||||
.isGBC ( /*status[11]*/ ),
|
||||
.isGBC ( status[11] ),
|
||||
|
||||
.tint ( status[1] ),
|
||||
.inv ( status[12] ),
|
||||
|
||||
7
gb.v
7
gb.v
@@ -152,6 +152,7 @@ GBse cpu (
|
||||
wire clk_cpu = clk;
|
||||
reg cpu_speed; // - 0 Normal mode (4MHz) - 1 Double Speed Mode (8MHz)
|
||||
reg prepare_switch; // set to 1 to toggle speed
|
||||
assign speed = cpu_speed;
|
||||
|
||||
always @(posedge clk2x) begin
|
||||
if(reset) begin
|
||||
@@ -359,6 +360,8 @@ video video (
|
||||
.reset ( reset ),
|
||||
.clk ( clk ),
|
||||
.clk_dma ( clk_cpu ), //can be 2x in cgb double speed mode
|
||||
.isGBC ( isGBC ),
|
||||
|
||||
|
||||
.irq ( video_irq ),
|
||||
|
||||
@@ -378,6 +381,9 @@ video video (
|
||||
.vram_addr ( video_addr ),
|
||||
.vram_data ( vram_do ),
|
||||
|
||||
// vram connection bank1 (GBC)
|
||||
.vram1_data ( vram1_do ),
|
||||
|
||||
.dma_rd ( dma_rd ),
|
||||
.dma_addr ( dma_addr ),
|
||||
.dma_data ( dma_data )
|
||||
@@ -399,7 +405,6 @@ wire vram1_wren = video_rd?1'b0:vram_bank&&((hdma_rd&&isGBC)||cpu_wr_vram);
|
||||
wire [12:0] vram_addr = video_rd?video_addr:(dma_rd&&dma_sel_vram)?dma_addr[12:0]:(hdma_rd&&isGBC)?hdma_target_addr[12:0]:cpu_addr[12:0];
|
||||
|
||||
|
||||
|
||||
spram #(13) vram0 (
|
||||
.clock ( clk ),
|
||||
.address ( vram_addr ),
|
||||
|
||||
14
sprite.v
14
sprite.v
@@ -64,14 +64,14 @@ wire visible = v_visible && (h_cnt + 8'd8 >= x_pos) && (h_cnt < x_pos);
|
||||
|
||||
// x position within sprite, mirror horizontally if required
|
||||
wire [7:0] col_n = h_cnt - x_pos;
|
||||
wire [2:0] col = flags[1]?col_n[2:0]:~col_n[2:0];
|
||||
wire [2:0] col = flags[5]?col_n[2:0]:~col_n[2:0];
|
||||
|
||||
assign pixel_data = { data1[col], data0[col] };
|
||||
assign pixel_active = (pixel_data != 0) && visible;
|
||||
|
||||
// y position within sprite, mirror vertically if required
|
||||
wire [7:0] row_n = v_cnt - y_pos;
|
||||
wire [3:0] row = flags[2]?~row_n[3:0]:row_n[3:0];
|
||||
wire [3:0] row = flags[6]?~row_n[3:0]:row_n[3:0];
|
||||
|
||||
// 16 pixel tall sprites use one more rwo counter bit and the lsb
|
||||
// of the tile index is ignored
|
||||
@@ -79,13 +79,13 @@ wire [10:0] addr8 = { tile , row[2:0]};
|
||||
wire [10:0] addr16 = { tile[7:1] , row};
|
||||
assign addr = size16?addr16:addr8;
|
||||
|
||||
assign pixel_cmap = flags[0];
|
||||
assign pixel_prio = flags[3];
|
||||
assign pixel_cmap = flags[4];
|
||||
assign pixel_prio = flags[7];
|
||||
|
||||
reg [7:0] y_pos;
|
||||
reg [7:0] x_pos;
|
||||
reg [7:0] tile;
|
||||
reg [3:0] flags;
|
||||
reg [7:0] flags;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(oam_wr) begin
|
||||
@@ -93,7 +93,7 @@ always @(posedge clk) begin
|
||||
0: y_pos <= oam_di;
|
||||
1: x_pos <= oam_di;
|
||||
2: tile <= oam_di;
|
||||
3: flags <= oam_di[7:4];
|
||||
3: flags <= oam_di;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
@@ -102,6 +102,6 @@ assign oam_do =
|
||||
(oam_addr == 0)?y_pos:
|
||||
(oam_addr == 1)?x_pos:
|
||||
(oam_addr == 2)?tile:
|
||||
{ flags, 4'h0 };
|
||||
flags;
|
||||
|
||||
endmodule
|
||||
|
||||
64
video.v
64
video.v
@@ -36,7 +36,7 @@ module video (
|
||||
// output to lcd
|
||||
output lcd_on,
|
||||
output lcd_clkena,
|
||||
output [1:0] lcd_data,
|
||||
output [14:0] lcd_data,
|
||||
output reg irq,
|
||||
|
||||
// vram connection
|
||||
@@ -44,6 +44,9 @@ module video (
|
||||
output vram_rd,
|
||||
output [12:0] vram_addr,
|
||||
input [7:0] vram_data,
|
||||
|
||||
// vram connection bank1 (GBC)
|
||||
input [7:0] vram1_data,
|
||||
|
||||
// dma connection
|
||||
output dma_rd,
|
||||
@@ -299,27 +302,36 @@ assign cpu_do =
|
||||
assign lcd_data = stage2_data;
|
||||
assign lcd_clkena = stage2_clkena;
|
||||
|
||||
reg [1:0] stage2_data;
|
||||
reg [14:0] stage2_data;
|
||||
reg stage2_clkena;
|
||||
|
||||
reg [1:0] stage2_buffer [159:0];
|
||||
reg [2:0] stage2_bgp_buffer [19:0]; //GBC only keep record of palette used for tile
|
||||
reg [7:0] stage2_wptr;
|
||||
reg [7:0] stage2_rptr;
|
||||
|
||||
reg [4:0] bg_palette_rptr; //GBC
|
||||
reg [2:0] bg_palette_rcnt;
|
||||
|
||||
|
||||
wire [5:0] palette_index = (stage2_bgp_buffer[bg_palette_rptr] << 3) + (stage2_buffer[stage2_rptr]<<1); //gbc
|
||||
|
||||
|
||||
// apply bg palette
|
||||
wire [1:0] stage2_bg_pix = (!lcdc_bg_ena && !window_ena)?2'b11: // background off?
|
||||
(stage2_buffer[stage2_rptr] == 2'b00)?bgp[1:0]:
|
||||
(stage2_buffer[stage2_rptr] == 2'b01)?bgp[3:2]:
|
||||
(stage2_buffer[stage2_rptr] == 2'b10)?bgp[5:4]:
|
||||
bgp[7:6];
|
||||
wire [14:0] stage2_bg_pix = (!lcdc_bg_ena && !window_ena)?15'h7FFF: // background off?
|
||||
isGBC?{bgpd[palette_index+1][6:0],bgpd[palette_index]}: //gbc
|
||||
(stage2_buffer[stage2_rptr] == 2'b00)?{13'd0,bgp[1:0]}:
|
||||
(stage2_buffer[stage2_rptr] == 2'b01)?{13'd0,bgp[3:2]}:
|
||||
(stage2_buffer[stage2_rptr] == 2'b10)?{13'd0,bgp[5:4]}:
|
||||
{13'd0,bgp[7:6]};
|
||||
|
||||
// apply sprite palette
|
||||
wire [7:0] obp = sprite_pixel_cmap?obp1:obp0;
|
||||
wire [1:0] sprite_pix =
|
||||
(sprite_pixel_data == 2'b00)?obp[1:0]:
|
||||
(sprite_pixel_data == 2'b01)?obp[3:2]:
|
||||
(sprite_pixel_data == 2'b10)?obp[5:4]:
|
||||
obp[7:6];
|
||||
wire [14:0] sprite_pix =
|
||||
(sprite_pixel_data == 2'b00)?{13'd0,obp[1:0]}:
|
||||
(sprite_pixel_data == 2'b01)?{13'd0,obp[3:2]}:
|
||||
(sprite_pixel_data == 2'b10)?{13'd0,obp[5:4]}:
|
||||
{13'd0,obp[7:6]};
|
||||
|
||||
// a sprite pixel is visible if
|
||||
// - sprites are enabled
|
||||
@@ -335,6 +347,8 @@ always @(posedge clk) begin
|
||||
if(h_cnt == 455) begin
|
||||
stage2_wptr <= 8'h00;
|
||||
stage2_rptr <= 8'h00;
|
||||
bg_palette_rptr <= 5'd0; //GBC
|
||||
bg_palette_rcnt <= 3'b111;
|
||||
end
|
||||
|
||||
if(stage1_clkena) begin
|
||||
@@ -349,6 +363,10 @@ always @(posedge clk) begin
|
||||
else stage2_data <= stage2_bg_pix;
|
||||
|
||||
stage2_rptr <= stage2_rptr + 8'd1;
|
||||
|
||||
bg_palette_rcnt <= bg_palette_rcnt - 3'd1;
|
||||
if (bg_palette_rcnt==0)
|
||||
bg_palette_rptr <= bg_palette_rptr + 5'd1;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -363,20 +381,38 @@ reg [7:0] tile_shift_0;
|
||||
reg [7:0] tile_shift_1;
|
||||
|
||||
reg [7:0] bg_tile;
|
||||
reg [7:0] bg_tile_attr; //GBC
|
||||
reg [7:0] bg_tile_data0;
|
||||
reg [7:0] bg_tile_data1;
|
||||
|
||||
reg [4:0] bg_palette_wptr; //GBC
|
||||
|
||||
wire stage1_clkena = !vblank && hdvalid;
|
||||
wire [1:0] stage1_data = { tile_shift_1[7], tile_shift_0[7] };
|
||||
|
||||
// read data half a clock cycle after ram has been selected
|
||||
always @(posedge clk) begin
|
||||
|
||||
if (reset || (h_cnt == 455))
|
||||
bg_palette_wptr <= 5'd0;
|
||||
|
||||
// every memory access is two pixel cycles
|
||||
if(h_cnt[0]) begin
|
||||
if(bg_tile_map_rd) bg_tile <= vram_data;
|
||||
if(bg_tile_data0_rd) bg_tile_data0 <= vram_data;
|
||||
if(bg_tile_data1_rd) bg_tile_data1 <= vram_data;
|
||||
|
||||
if (isGBC) begin
|
||||
if(bg_tile_map_rd) begin
|
||||
bg_tile_attr <= vram1_data; //get tile attr from vram bank1
|
||||
stage2_bgp_buffer[bg_palette_wptr] <= vram1_data[2:0]; //keep a copy of the palette used
|
||||
bg_palette_wptr <= bg_palette_wptr + 5'd1;
|
||||
end
|
||||
if(bg_tile_data0_rd) bg_tile_data0 <= bg_tile_attr[3]?vram1_data:vram_data;
|
||||
if(bg_tile_data1_rd) bg_tile_data1 <= bg_tile_attr[3]?vram1_data:vram_data;
|
||||
end else begin
|
||||
if(bg_tile_data0_rd) bg_tile_data0 <= vram_data;
|
||||
if(bg_tile_data1_rd) bg_tile_data1 <= vram_data;
|
||||
end
|
||||
|
||||
// sprite data is evaluated inside the sprite engine
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user