mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-05-24 03:03:25 +00:00
redone fastforward and pause handling to fix sdram access and refresh bugs and increase fastforward speed, some fixes to simulation
This commit is contained in:
33
Gameboy.sv
33
Gameboy.sv
@@ -151,7 +151,7 @@ assign AUDIO_MIX = status[8:7];
|
||||
// 0 1 2 3
|
||||
// 01234567890123456789012345678901
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUV
|
||||
// XXXXXXXXXXXXXXXXXXXXX XXXXX
|
||||
// XXXXXXXXXXXXXXXXXXXXX XXXX
|
||||
|
||||
`include "build_id.v"
|
||||
localparam CONF_STR = {
|
||||
@@ -180,8 +180,8 @@ localparam CONF_STR = {
|
||||
"OB,Boot,Normal,Fast;",
|
||||
"O6,Link Port,Disabled,Enabled;",
|
||||
"-;",
|
||||
"OPQ,FastForward Sound,Normal,Hack,Off;",
|
||||
"OR,Pause when OSD is open,Off,On;",
|
||||
"OP,FastForward Sound,On,Off;",
|
||||
"OQ,Pause when OSD is open,Off,On;",
|
||||
"-;",
|
||||
"R0,Reset;",
|
||||
"J1,A,B,Select,Start,FastForward;",
|
||||
@@ -286,6 +286,8 @@ wire [15:0] sdram_di = cart_download ? ioctl_dout : 16'd0;
|
||||
wire [23:0] sdram_addr = cart_download? ioctl_addr[24:1]: {2'b00, mbc_bank, cart_addr[12:1]};
|
||||
wire sdram_oe = ~cart_download & cart_rd & ~cram_rd;
|
||||
wire sdram_we = cart_download & dn_write;
|
||||
wire sdram_refresh_force;
|
||||
wire sdram_autorefresh = !fastforward;
|
||||
|
||||
assign SDRAM_CKE = 1;
|
||||
|
||||
@@ -312,6 +314,8 @@ sdram sdram (
|
||||
.ds ( sdram_ds ),
|
||||
.we ( sdram_we ),
|
||||
.oe ( sdram_oe ),
|
||||
.autorefresh ( sdram_autorefresh ),
|
||||
.refresh ( sdram_refresh_force ),
|
||||
.dout ( sdram_do )
|
||||
);
|
||||
|
||||
@@ -583,7 +587,6 @@ gb gb (
|
||||
.clk_sys ( clk_sys ),
|
||||
.ce ( ce_cpu ), // the whole gameboy runs on 4mhnz
|
||||
.ce_2x ( ce_cpu2x ), // ~8MHz in dualspeed mode (GBC)
|
||||
.ce_sound ( ce_sound ), // ~8Mhz if not fastforward
|
||||
|
||||
.fast_boot ( status[11] ),
|
||||
|
||||
@@ -631,8 +634,8 @@ gb gb (
|
||||
.gg_available(gg_available)
|
||||
);
|
||||
|
||||
assign AUDIO_L = (joystick_0[8] && status[26]) ? 16'd0 : GB_AUDIO_L;
|
||||
assign AUDIO_R = (joystick_0[8] && status[26]) ? 16'd0 : GB_AUDIO_R;
|
||||
assign AUDIO_L = (joystick_0[8] && status[25]) ? 16'd0 : GB_AUDIO_L;
|
||||
assign AUDIO_R = (joystick_0[8] && status[25]) ? 16'd0 : GB_AUDIO_R;
|
||||
|
||||
// the lcd to vga converter
|
||||
wire [7:0] video_r, video_g, video_b;
|
||||
@@ -765,22 +768,28 @@ video_mixer #(.LINE_LENGTH(200), .GAMMA(1)) video_mixer
|
||||
//////////////////////////////// CE ////////////////////////////////////
|
||||
|
||||
|
||||
wire ce_cpu, ce_cpu2x, ce_sound, ce_soundhack;
|
||||
wire ce_cpu, ce_cpu2x;
|
||||
wire cart_act = cart_wr | cart_rd;
|
||||
|
||||
wire fastforward = joystick_0[8] && !ioctl_download && !OSD_STATUS;
|
||||
|
||||
reg paused;
|
||||
always_ff @(posedge clk_sys) begin
|
||||
paused <= status[26] && OSD_STATUS && !ioctl_download && !reset;
|
||||
end
|
||||
|
||||
speedcontrol speedcontrol
|
||||
(
|
||||
.clk_sys (clk_sys),
|
||||
.pause (status[27] && OSD_STATUS && !ioctl_download),
|
||||
.speedup (joystick_0[8] && !ioctl_download && !OSD_STATUS),
|
||||
.speed (speed),
|
||||
.pause (paused),
|
||||
.speedup (fastforward),
|
||||
.cart_act (cart_act),
|
||||
.ce (ce_cpu),
|
||||
.ce_2x (ce_cpu2x),
|
||||
.ce_2xNormal (ce_soundhack)
|
||||
.refresh (sdram_refresh_force)
|
||||
);
|
||||
|
||||
assign ce_sound = status[25] ? ce_soundhack : ce_cpu2x;
|
||||
|
||||
///////////////////////////// GBC BIOS /////////////////////////////////
|
||||
|
||||
wire [7:0] bios_do;
|
||||
|
||||
3
rtl/gb.v
3
rtl/gb.v
@@ -25,7 +25,6 @@ module gb (
|
||||
input clk_sys,
|
||||
input ce,
|
||||
input ce_2x,
|
||||
input ce_sound,
|
||||
|
||||
input fast_boot,
|
||||
input [7:0] joystick,
|
||||
@@ -268,7 +267,7 @@ wire audio_wr = !cpu_wr_n && sel_audio;
|
||||
|
||||
gbc_snd audio (
|
||||
.clk ( clk_sys ),
|
||||
.ce ( ce_sound ),
|
||||
.ce ( ce_2x ),
|
||||
.reset ( reset_r ),
|
||||
|
||||
.is_gbc ( isGBC ),
|
||||
|
||||
12
rtl/sdram.sv
12
rtl/sdram.sv
@@ -50,7 +50,9 @@ module sdram
|
||||
input [23:0] addr, // 24 bit word address
|
||||
input [1:0] ds, // upper/lower data strobe
|
||||
input oe, // cpu/chipset requests read
|
||||
input we // cpu/chipset requests write
|
||||
input we, // cpu/chipset requests write
|
||||
input autorefresh,// autorefresh when no read or write required
|
||||
input refresh // force refresh when core is paused or fastforward
|
||||
);
|
||||
|
||||
localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 3 cycles@128MHz
|
||||
@@ -122,11 +124,15 @@ reg [2:0] stage;
|
||||
always @(posedge clk) begin
|
||||
reg [12:0] addr_r;
|
||||
reg old_sync;
|
||||
reg old_oe;
|
||||
|
||||
if(|stage) stage <= stage + 1'd1;
|
||||
|
||||
old_sync <= sync;
|
||||
if(~old_sync & sync) stage <= 1;
|
||||
old_oe <= oe;
|
||||
if(~old_sync && sync && autorefresh) stage <= 1; // normal operation with read/write and refresh
|
||||
if(refresh && stage == STATE_FIRST) stage <= 1; // forced refresh when paused or fastforward
|
||||
if(~old_oe && oe && ~autorefresh) stage <= 1; // react on request only with fastforward
|
||||
|
||||
sd_cmd <= CMD_INHIBIT; // default: idle
|
||||
sd_data <= 16'hZZZZ;
|
||||
@@ -163,7 +169,7 @@ always @(posedge clk) begin
|
||||
din_r <= din;
|
||||
addr_r <= { we ? ~ds : 2'b00, 2'b10, addr[22], addr[7:0] }; // auto precharge
|
||||
end
|
||||
else begin
|
||||
else if (autorefresh || refresh) begin
|
||||
sd_cmd <= CMD_AUTO_REFRESH;
|
||||
mode <= 0;
|
||||
end
|
||||
|
||||
@@ -5,69 +5,138 @@ use IEEE.numeric_std.all;
|
||||
entity speedcontrol is
|
||||
port
|
||||
(
|
||||
clk_sys : in std_logic;
|
||||
pause : in std_logic;
|
||||
speedup : in std_logic;
|
||||
cart_act : in std_logic;
|
||||
ce : out std_logic := '0';
|
||||
ce_2x : out std_logic := '0';
|
||||
ceNormal : out std_logic := '0';
|
||||
ce_2xNormal : out std_logic := '0'
|
||||
clk_sys : in std_logic;
|
||||
speed : in std_logic;
|
||||
pause : in std_logic;
|
||||
speedup : in std_logic;
|
||||
cart_act : in std_logic;
|
||||
ce : out std_logic := '0';
|
||||
ce_2x : buffer std_logic := '0';
|
||||
refresh : out std_logic := '0'
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of speedcontrol is
|
||||
|
||||
signal clkdiv : unsigned(2 downto 0) := (others => '0');
|
||||
signal nextdiv : unsigned(2 downto 0) := (others => '0');
|
||||
|
||||
signal clkdivNormal : unsigned(2 downto 0) := (others => '0');
|
||||
|
||||
signal cart_act_1 : std_logic := '0';
|
||||
signal clkdiv : unsigned(2 downto 0) := (others => '0');
|
||||
|
||||
signal cart_act_1 : std_logic := '0';
|
||||
|
||||
signal unpause_cnt : integer range 0 to 15 := 0;
|
||||
signal fastforward_cnt : integer range 0 to 15 := 0;
|
||||
|
||||
signal refreshcnt : integer range 0 to 127 := 0;
|
||||
signal sdram_busy : integer range 0 to 1 := 0;
|
||||
|
||||
type tstate is
|
||||
(
|
||||
NORMAL,
|
||||
PAUSED,
|
||||
FASTFORWARDSTART,
|
||||
FASTFORWARD,
|
||||
FASTFORWARDEND,
|
||||
RAMACCESS
|
||||
);
|
||||
signal state : tstate := NORMAL;
|
||||
|
||||
begin
|
||||
|
||||
process(clk_sys)
|
||||
begin
|
||||
if falling_edge(clk_sys) then
|
||||
if (pause = '1') then
|
||||
|
||||
ce <= '0';
|
||||
ce_2x <= '0';
|
||||
refresh <= '0';
|
||||
|
||||
ce <= '0';
|
||||
ce_2x <= '0';
|
||||
ceNormal <= '0';
|
||||
ce_2xNormal <= '0';
|
||||
|
||||
else
|
||||
|
||||
clkdiv <= clkdiv + 1;
|
||||
clkdivNormal <= clkdivNormal + 1;
|
||||
|
||||
-- generation for speed depending on speedup
|
||||
cart_act_1 <= cart_act;
|
||||
|
||||
if (clkdiv = "000") then ce <= '1'; else ce <= '0'; end if;
|
||||
if ((nextdiv = "111" and clkdiv(1 downto 0) = "00") or nextdiv = "001") then ce_2x <= '1'; else ce_2x <= '0'; end if;
|
||||
|
||||
if (clkdiv = nextdiv and (clkdiv = "111" or cart_act = '0')) then
|
||||
clkdiv <= "000";
|
||||
if (speedup = '1') then
|
||||
nextdiv <= "001";
|
||||
else
|
||||
nextdiv <= "111";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (cart_act = '1' and cart_act_1 = '0') then
|
||||
nextdiv <= "111";
|
||||
end if;
|
||||
|
||||
-- generation for non speed up base, used e.g. for sound hack
|
||||
if (clkdivNormal = "000") then ceNormal <= '1'; else ceNormal <= '0'; end if;
|
||||
if (clkdivNormal(1 downto 0) = "00") then ce_2xNormal <= '1'; else ce_2xNormal <= '0'; end if;
|
||||
cart_act_1 <= cart_act;
|
||||
|
||||
if (refreshcnt > 0) then
|
||||
refreshcnt <= refreshcnt - 1;
|
||||
end if;
|
||||
|
||||
case (state) is
|
||||
|
||||
when NORMAL =>
|
||||
if (pause = '1' and clkdiv = "111") then
|
||||
if (cart_act = '0') then
|
||||
state <= PAUSED;
|
||||
unpause_cnt <= 0;
|
||||
end if;
|
||||
elsif (speedup = '1' and pause = '0') then
|
||||
state <= FASTFORWARDSTART;
|
||||
fastforward_cnt <= 0;
|
||||
else
|
||||
clkdiv <= clkdiv + 1;
|
||||
if (clkdiv = "000") then
|
||||
ce <= '1';
|
||||
end if;
|
||||
if (clkdiv(1 downto 0) = "00") then
|
||||
ce_2x <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when PAUSED =>
|
||||
if (unpause_cnt = 0) then
|
||||
refresh <= '1';
|
||||
end if;
|
||||
|
||||
if (pause = '0') then
|
||||
if (unpause_cnt = 15) then
|
||||
state <= NORMAL;
|
||||
else
|
||||
unpause_cnt <= unpause_cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when FASTFORWARDSTART =>
|
||||
if (fastforward_cnt = 15) then
|
||||
state <= FASTFORWARD;
|
||||
else
|
||||
fastforward_cnt <= fastforward_cnt + 1;
|
||||
end if;
|
||||
|
||||
when FASTFORWARD =>
|
||||
if (pause = '1' or speedup = '0') then
|
||||
state <= FASTFORWARDEND;
|
||||
fastforward_cnt <= 0;
|
||||
end if;
|
||||
|
||||
if (cart_act = '1' and cart_act_1 = '0') then
|
||||
state <= RAMACCESS;
|
||||
sdram_busy <= 1;
|
||||
elsif (cart_act = '0' and refreshcnt = 0) then
|
||||
refreshcnt <= 127;
|
||||
refresh <= '1';
|
||||
state <= RAMACCESS;
|
||||
sdram_busy <= 1;
|
||||
else
|
||||
clkdiv(0) <= not clkdiv(0);
|
||||
if (clkdiv(0) = '0') then
|
||||
ce <= '1';
|
||||
end if;
|
||||
ce_2x <= '1';
|
||||
end if;
|
||||
|
||||
when FASTFORWARDEND =>
|
||||
if (fastforward_cnt = 15) then
|
||||
state <= NORMAL;
|
||||
else
|
||||
fastforward_cnt <= fastforward_cnt + 1;
|
||||
end if;
|
||||
|
||||
when RAMACCESS =>
|
||||
if (sdram_busy > 0) then
|
||||
sdram_busy <= sdram_busy - 1;
|
||||
else
|
||||
state <= FASTFORWARD;
|
||||
end if;
|
||||
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
|
||||
end architecture;
|
||||
|
||||
@@ -65,7 +65,6 @@ begin
|
||||
wait until rising_edge(clk);
|
||||
|
||||
if (cart_rd = '1') then
|
||||
cart_do <= x"FF";
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
|
||||
@@ -24,6 +24,7 @@ architecture arch of etb is
|
||||
|
||||
signal reset : std_logic := '1';
|
||||
signal clksys : std_logic := '1';
|
||||
signal clkram : std_logic := '1';
|
||||
|
||||
signal clkdiv : unsigned(2 downto 0) := (others => '0');
|
||||
signal nextdiv : unsigned(2 downto 0) := (others => '0');
|
||||
@@ -31,6 +32,8 @@ architecture arch of etb is
|
||||
signal ce : std_logic := '1';
|
||||
signal ce_2x : std_logic := '1';
|
||||
|
||||
signal speed : std_logic;
|
||||
|
||||
signal command_in : std_logic;
|
||||
signal command_out : std_logic;
|
||||
signal command_out_filter : std_logic;
|
||||
@@ -62,6 +65,8 @@ architecture arch of etb is
|
||||
signal pixel_out_we : std_logic := '0';
|
||||
|
||||
|
||||
signal is_CGB : std_logic := '1';
|
||||
|
||||
-- settings
|
||||
signal GB_on : std_logic_vector(Reg_GB_on.upper downto Reg_GB_on.lower) := (others => '0');
|
||||
|
||||
@@ -69,7 +74,8 @@ architecture arch of etb is
|
||||
begin
|
||||
|
||||
reset <= not GB_on(0);
|
||||
clksys <= not clksys after 15 ns;
|
||||
clksys <= not clksys after 14 ns;
|
||||
clkram <= not clkram after 7 ns;
|
||||
|
||||
clk100 <= not clk100 after 5 ns;
|
||||
|
||||
@@ -82,6 +88,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clk_sys => clksys,
|
||||
speed => speed,
|
||||
pause => '0',
|
||||
speedup => '1',
|
||||
cart_act => cart_act,
|
||||
@@ -89,24 +96,15 @@ begin
|
||||
ce_2x => ce_2x
|
||||
);
|
||||
|
||||
|
||||
isdram_model : entity tb.sdram_model
|
||||
port map
|
||||
(
|
||||
clk => clksys,
|
||||
clk => clkram,
|
||||
cart_addr => cart_addr,
|
||||
cart_rd => cart_rd,
|
||||
cart_do => cart_do
|
||||
);
|
||||
|
||||
--itetris : entity gameboy.tetris
|
||||
--port map
|
||||
--(
|
||||
-- clk => clksys,
|
||||
-- address => cart_addr(14 downto 0),
|
||||
-- data => cart_do
|
||||
--);
|
||||
|
||||
igb : entity gameboy.gb
|
||||
port map
|
||||
(
|
||||
@@ -115,12 +113,11 @@ begin
|
||||
clk_sys => clksys,
|
||||
ce => ce,
|
||||
ce_2x => ce_2x,
|
||||
--ce_sound => ce_2x,
|
||||
|
||||
fast_boot => '1',
|
||||
joystick => x"00",
|
||||
isGBC => '0',
|
||||
isGBC_game => '0',
|
||||
isGBC => is_CGB,
|
||||
isGBC_game => is_CGB,
|
||||
|
||||
-- cartridge interface
|
||||
-- can adress up to 1MB ROM
|
||||
@@ -148,7 +145,7 @@ begin
|
||||
joy_p54 => open,
|
||||
joy_din => "0000",
|
||||
|
||||
speed => open, --GBC
|
||||
speed => speed, --GBC
|
||||
|
||||
gg_reset => reset,
|
||||
gg_en => '0',
|
||||
@@ -167,7 +164,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clk => clksys,
|
||||
address => gbc_bios_addr(7 downto 0),
|
||||
address => gbc_bios_addr,
|
||||
data => gbc_bios_do
|
||||
);
|
||||
|
||||
@@ -195,13 +192,17 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
case (lcd_data(1 downto 0)) is
|
||||
when "00" => pixel_out_data <= "11111" & "11111" & "11111";
|
||||
when "01" => pixel_out_data <= "10000" & "10000" & "10000";
|
||||
when "10" => pixel_out_data <= "01000" & "01000" & "01000";
|
||||
when "11" => pixel_out_data <= "00000" & "00000" & "00000";
|
||||
when others => pixel_out_data <= "00000" & "00000" & "11111";
|
||||
end case;
|
||||
if (is_CGB = '0') then
|
||||
case (lcd_data(1 downto 0)) is
|
||||
when "00" => pixel_out_data <= "11111" & "11111" & "11111";
|
||||
when "01" => pixel_out_data <= "10000" & "10000" & "10000";
|
||||
when "10" => pixel_out_data <= "01000" & "01000" & "01000";
|
||||
when "11" => pixel_out_data <= "00000" & "00000" & "00000";
|
||||
when others => pixel_out_data <= "00000" & "00000" & "11111";
|
||||
end case;
|
||||
else
|
||||
pixel_out_data <= lcd_data;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -3,6 +3,7 @@ vcom -93 -quiet -work sim/tb ^
|
||||
src/tb/globals.vhd
|
||||
|
||||
vcom -93 -quiet -work sim/mem ^
|
||||
src/mem/SyncRamDualByteEnable.vhd ^
|
||||
src/mem/SyncFifo.vhd
|
||||
|
||||
vcom -quiet -work sim/rs232 ^
|
||||
|
||||
Reference in New Issue
Block a user