mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
Merge pull request #153 from paulb-nl/ppu
Fixes for Conker Pocket Tales & Altered Space
This commit is contained in:
@@ -77,7 +77,7 @@ use work.pReg_savestates.all;
|
||||
|
||||
entity GBse is
|
||||
generic(
|
||||
T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
|
||||
T2Write : integer := 2; -- 0 => WR_n active in T3, 1 => WR_n active in T2, Other => WR_n active in T2+T3
|
||||
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||
);
|
||||
port(
|
||||
@@ -231,12 +231,18 @@ begin
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
else
|
||||
elsif T2Write = 1 then
|
||||
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
|
||||
WR_n <= '0';
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
else
|
||||
if (TState = "001" or TState = "010") and Write = '1' then
|
||||
WR_n <= '0';
|
||||
IORQ_n <= not IORQ;
|
||||
MREQ_n <= IORQ;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
if TState = "011" and Wait_n = '1' then
|
||||
|
||||
43
rtl/gb.v
43
rtl/gb.v
@@ -117,10 +117,10 @@ wire [4:0] Savestate_RAMRWrEn;
|
||||
localparam SAVESTATE_MODULES = 7;
|
||||
wire [63:0] SaveStateBus_wired_or[0:SAVESTATE_MODULES-1];
|
||||
|
||||
wire [53:0] SS_Top;
|
||||
wire [53:0] SS_Top_BACK;
|
||||
wire [54:0] SS_Top;
|
||||
wire [54:0] SS_Top_BACK;
|
||||
|
||||
eReg_SavestateV #(0, 31, 53, 0, 64'h0000000000800001) iREG_SAVESTATE_Top (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[6], SS_Top_BACK, SS_Top);
|
||||
eReg_SavestateV #(0, 31, 54, 0, 64'h0000000000800001) iREG_SAVESTATE_Top (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[6], SS_Top_BACK, SS_Top);
|
||||
|
||||
// include cpu
|
||||
reg boot_rom_enabled;
|
||||
@@ -263,6 +263,15 @@ always @ (posedge clk) begin
|
||||
reset_r <= reset;
|
||||
end
|
||||
|
||||
reg old_cpu_wr_n;
|
||||
|
||||
assign SS_Top_BACK[54] = old_cpu_wr_n;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(reset_ss) old_cpu_wr_n <= SS_Top[54]; // 1'b0
|
||||
else if (cpu_clken) old_cpu_wr_n <= cpu_wr_n;
|
||||
end
|
||||
wire cpu_wr_n_edge = ~(old_cpu_wr_n & ~cpu_wr_n);
|
||||
|
||||
wire cpu_stop;
|
||||
|
||||
@@ -328,7 +337,7 @@ always @(posedge clk_sys) begin
|
||||
cpu_speed <= SS_Top[3]; // 1'b0;
|
||||
prepare_switch <= SS_Top[4]; // 1'b0;
|
||||
end
|
||||
else if (ce_2x && sel_key1 && !cpu_wr_n)begin
|
||||
else if (ce_2x && sel_key1 && !cpu_wr_n_edge)begin
|
||||
prepare_switch <= cpu_do[0];
|
||||
end
|
||||
|
||||
@@ -343,7 +352,7 @@ end
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
wire audio_rd = !cpu_rd_n && sel_audio;
|
||||
wire audio_wr = !cpu_wr_n && sel_audio;
|
||||
wire audio_wr = !cpu_wr_n_edge && sel_audio;
|
||||
|
||||
gbc_snd audio (
|
||||
.clk ( clk_sys ),
|
||||
@@ -384,7 +393,7 @@ link link (
|
||||
|
||||
.sel_sc(sel_sc),
|
||||
.sel_sb(sel_sb),
|
||||
.cpu_wr_n(cpu_wr_n),
|
||||
.cpu_wr_n(cpu_wr_n_edge),
|
||||
.sc_start_in(cpu_do[7]),
|
||||
.sc_int_clock_in(cpu_do[0]),
|
||||
|
||||
@@ -417,7 +426,7 @@ assign SS_Top_BACK[6:5] = p54;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
if(reset_ss) p54 <= SS_Top[6:5]; //2'b00 for DMG, 2'b11 for CGB/SGB will be written by BIOS
|
||||
else if(ce_cpu && sel_joy && !cpu_wr_n) p54 <= cpu_do[5:4];
|
||||
else if(ce_cpu && sel_joy && !cpu_wr_n_edge) p54 <= cpu_do[5:4];
|
||||
end
|
||||
|
||||
assign joy_do = { 2'b11, p54, joy_din };
|
||||
@@ -438,7 +447,7 @@ always @(posedge clk_sys) begin
|
||||
FF73 <= SS_Top[42:35]; // 0;
|
||||
FF74 <= SS_Top[50:43]; // 0;
|
||||
FF75 <= SS_Top[53:51]; // 0;
|
||||
end else if(ce_cpu && !cpu_wr_n) begin
|
||||
end else if(ce_cpu && !cpu_wr_n_edge) begin
|
||||
if (sel_FF72) FF72 <= cpu_do;
|
||||
if (sel_FF73) FF73 <= cpu_do;
|
||||
if (sel_FF74) FF74 <= cpu_do;
|
||||
@@ -536,11 +545,11 @@ always @(negedge clk_sys) begin //negedge to trigger interrupt earlier
|
||||
end
|
||||
|
||||
// cpu writes interrupt enable register
|
||||
if(sel_ie && !cpu_wr_n)
|
||||
if(sel_ie && !cpu_wr_n_edge)
|
||||
ie_r <= cpu_do;
|
||||
|
||||
// cpu writes interrupt flag register
|
||||
if(sel_if && !cpu_wr_n)
|
||||
if(sel_if && !cpu_wr_n_edge)
|
||||
if_r <= cpu_do[4:0];
|
||||
|
||||
end
|
||||
@@ -559,7 +568,7 @@ timer timer (
|
||||
|
||||
.cpu_sel ( sel_timer ),
|
||||
.cpu_addr ( cpu_addr[1:0] ),
|
||||
.cpu_wr ( !cpu_wr_n ),
|
||||
.cpu_wr ( !cpu_wr_n_edge ),
|
||||
.cpu_di ( cpu_do ),
|
||||
.cpu_do ( timer_do ),
|
||||
|
||||
@@ -595,7 +604,7 @@ video video (
|
||||
.cpu_sel_reg ( sel_video_reg ),
|
||||
.cpu_sel_oam ( sel_video_oam ),
|
||||
.cpu_addr ( cpu_addr[7:0] ),
|
||||
.cpu_wr ( !cpu_wr_n ),
|
||||
.cpu_wr ( !cpu_wr_n_edge ),
|
||||
.cpu_di ( cpu_do ),
|
||||
.cpu_do ( video_do ),
|
||||
|
||||
@@ -689,7 +698,7 @@ always @(posedge clk_sys) begin
|
||||
if(reset_ss)
|
||||
vram_bank <= SS_Top[22]; // 1'd0;
|
||||
else if (ce_cpu) begin
|
||||
if((cpu_addr == 16'hff4f) && !cpu_wr_n && isGBC)
|
||||
if((cpu_addr == 16'hff4f) && !cpu_wr_n_edge && isGBC)
|
||||
vram_bank <= cpu_do[0];
|
||||
end
|
||||
end
|
||||
@@ -707,7 +716,7 @@ hdma hdma(
|
||||
// cpu register interface
|
||||
.sel_reg ( sel_hdma ),
|
||||
.addr ( cpu_addr[3:0] ),
|
||||
.wr ( !cpu_wr_n ),
|
||||
.wr ( !cpu_wr_n_edge ),
|
||||
.dout ( hdma_do ),
|
||||
.din ( cpu_do ),
|
||||
|
||||
@@ -784,7 +793,7 @@ assign SS_Top_BACK[2:0] = iram_bank;
|
||||
always @(posedge clk_sys) begin
|
||||
if(reset_ss)
|
||||
iram_bank <= SS_Top[2:0]; // 3'd1;
|
||||
else if(ce_cpu && sel_iram_bank && !cpu_wr_n) begin
|
||||
else if(ce_cpu && sel_iram_bank && !cpu_wr_n_edge) begin
|
||||
if (cpu_do[2:0]==3'd0) // 0 -> 1;
|
||||
iram_bank <= 3'd1;
|
||||
else
|
||||
@@ -804,7 +813,7 @@ always @(posedge clk_sys) begin
|
||||
if(reset_ss)
|
||||
boot_rom_enabled <= SS_Top[23]; // 1'b1;
|
||||
else if (ce) begin
|
||||
if((cpu_addr == 16'hff50) && !cpu_wr_n)
|
||||
if((cpu_addr == 16'hff50) && !cpu_wr_n_edge)
|
||||
if ((isGBC && cpu_do[7:0]==8'h11) || (!isGBC && cpu_do[0]))
|
||||
boot_rom_enabled <= 1'b0;
|
||||
end
|
||||
@@ -830,7 +839,7 @@ assign is_hdma_cart_addr = (hdma_sel_rom || hdma_sel_cram); //rom or external ra
|
||||
assign cart_di = cpu_do;
|
||||
assign cart_addr = (isGBC&&hdma_rd&&is_hdma_cart_addr)?hdma_source_addr:(dma_rd&&is_dma_cart_addr)?dma_addr:cpu_addr;
|
||||
assign cart_rd = (isGBC&&hdma_rd&&is_hdma_cart_addr) || (dma_rd&&is_dma_cart_addr) || ((sel_rom || sel_cram) && !cpu_rd_n);
|
||||
assign cart_wr = (sel_rom || sel_cram) && !cpu_wr_n && !hdma_rd;
|
||||
assign cart_wr = (sel_rom || sel_cram) && !cpu_wr_n_edge && !hdma_rd;
|
||||
|
||||
assign gbc_bios_addr = hdma_rd?hdma_source_addr[11:0]:cpu_addr[11:0];
|
||||
|
||||
|
||||
18
rtl/video.v
18
rtl/video.v
@@ -238,14 +238,14 @@ wire h_clk_en_neg = (lcd_on && h_div_cnt == 2'd2);
|
||||
wire hcnt_end = (h_cnt == 7'd113);
|
||||
wire vblank = (v_cnt >= 144);
|
||||
|
||||
reg vblank_l, vblank_t, vblank_ll;
|
||||
reg vblank_l, vblank_t;
|
||||
reg end_of_line, end_of_line_l;
|
||||
reg lyc_match_l, lyc_match_t;
|
||||
|
||||
assign SS_Video3_BACK[0] = vblank_l;
|
||||
assign SS_Video3_BACK[1] = end_of_line;
|
||||
assign SS_Video3_BACK[2] = end_of_line_l;
|
||||
assign SS_Video3_BACK[3] = vblank_ll;
|
||||
assign SS_Video3_BACK[3] = 0;
|
||||
assign SS_Video3_BACK[6] = vblank_t;
|
||||
|
||||
always @(posedge clk) begin
|
||||
@@ -253,17 +253,14 @@ always @(posedge clk) begin
|
||||
vblank_l <= SS_Video3[0]; //1'b0;
|
||||
end_of_line <= SS_Video3[1]; //1'b0;
|
||||
end_of_line_l <= SS_Video3[2]; //1'b0;
|
||||
vblank_ll <= SS_Video3[3]; //1'b0;
|
||||
vblank_t <= SS_Video3[6]; //1'b0;
|
||||
end else if (!lcd_on) begin
|
||||
vblank_l <= 1'b0;
|
||||
end_of_line <= 1'b0;
|
||||
end_of_line_l <= 1'b0;
|
||||
vblank_ll <= 1'b0;
|
||||
vblank_t <= 1'b0;
|
||||
end else if (ce) begin
|
||||
vblank_l <= vblank_t;
|
||||
vblank_ll <= vblank_l;
|
||||
|
||||
if (h_clk_en_neg & hcnt_end)
|
||||
end_of_line <= 1'b1;
|
||||
@@ -273,9 +270,6 @@ always @(posedge clk) begin
|
||||
// It also makes the OAM interrupt at line 0 after Vblank a few cycles late.
|
||||
if (h_clk_en) begin
|
||||
vblank_t <= vblank;
|
||||
if (vblank_t & ~vblank & ~isGBC) begin // DMG: vblank falling edge must be 1 cycle faster to pass some tests.
|
||||
vblank_l <= vblank;
|
||||
end
|
||||
end
|
||||
// end_of_line is active for 4 cycles
|
||||
if (h_clk_en_neg) begin
|
||||
@@ -325,7 +319,7 @@ always @(posedge clk) begin
|
||||
end
|
||||
|
||||
wire int_lyc = (stat[6] & lyc_match_l);
|
||||
wire int_oam = (stat[5] & end_of_line_l & (isGBC ? ~vblank_l : ~vblank_ll) );
|
||||
wire int_oam = (stat[5] & end_of_line_l & ~vblank_l);
|
||||
wire int_vbl = (stat[4] & vblank_l);
|
||||
wire int_hbl = (stat[3] & mode3_end_l & ~vblank_l);
|
||||
|
||||
@@ -355,8 +349,12 @@ always @(posedge clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
// DMG: STAT reads mode 0 for 1 Tcycle between Vblank and mode 2
|
||||
// but the interrupt signals of Vblank and mode 2 do overlap
|
||||
wire mode_vblank = isGBC ? vblank_l : (vblank_l & vblank_t);
|
||||
|
||||
assign mode =
|
||||
vblank_l ? 2'b01 :
|
||||
mode_vblank ? 2'b01 :
|
||||
oam_eval_l ? 2'b10 :
|
||||
mode3_l & ~mode3_end ? 2'b11 :
|
||||
2'b00;
|
||||
|
||||
Reference in New Issue
Block a user