improved rewind capture performance (#127)

fixed random fastforward crash
fixed fastforward Video glitches(HDMA)
added fastforward toggle (short button press)
added savestate OSD entry and multiple slots using keyboard(F1-F4)
add MBC detection and address translation to simulation
This commit is contained in:
RobertPeip
2021-01-06 08:33:24 +01:00
committed by GitHub
parent 8cd6b8dfca
commit 31563c2ef6
9 changed files with 750 additions and 74 deletions

View File

@@ -150,7 +150,7 @@ assign AUDIO_MIX = status[8:7];
// 0 1 2 3
// 01234567890123456789012345678901
// 0123456789ABCDEFGHIJKLMNOPQRSTUV
// XXXXXXXXXXXXXXXXXXXXX XXXXX
// XXXXXXXXXXXXXXXXXXXXX XXXXXXX
`include "build_id.v"
localparam CONF_STR = {
@@ -170,6 +170,9 @@ localparam CONF_STR = {
"h2RA,Save Backup RAM;",
"OD,Autosave,Off,On;",
"-;",
"h3RS,Save state (Alt-F1);",
"h3RT,Restore state (F1);",
"-;",
"O34,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];",
"OIK,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%;",
"O5,Stabilize video(buffer),Off,On;",
@@ -185,6 +188,16 @@ localparam CONF_STR = {
"-;",
"R0,Reset;",
"J1,A,B,Select,Start,FastForward,SaveState,LoadState,Rewind;",
"I,",
"Save to state 1,",
"Restore state 1,",
"Save to state 2,",
"Restore state 2,",
"Save to state 3,",
"Restore state 3,",
"Save to state 4,",
"Restore state 4,",
"Rewinding...;",
"V,v",`BUILD_DATE
};
@@ -219,6 +232,7 @@ wire [15:0] ioctl_dout;
reg ioctl_wait;
wire [15:0] joystick_0, joystick_1, joystick_2, joystick_3;
wire [10:0] ps2_key;
wire [7:0] filetype;
@@ -263,7 +277,7 @@ hps_io #(.STRLEN($size(CONF_STR)>>3), .WIDE(1)) hps_io
.buttons(buttons),
.status(status),
.status_menumask({sav_supported,|tint,gg_available}),
.status_menumask({cart_ready,sav_supported,|tint,gg_available}),
.direct_video(direct_video),
.gamma_bus(gamma_bus),
.forced_scandoubler(forced_scandoubler),
@@ -271,7 +285,12 @@ hps_io #(.STRLEN($size(CONF_STR)>>3), .WIDE(1)) hps_io
.joystick_0(joystick_0),
.joystick_1(joystick_1),
.joystick_2(joystick_2),
.joystick_3(joystick_3)
.joystick_3(joystick_3),
.ps2_key(ps2_key),
.info_req(ss_info_req),
.info(ss_info)
);
///////////////////////////////////////////////////
@@ -287,7 +306,7 @@ wire [23:0] sdram_addr = cart_download? ioctl_addr[24:1]: {2'b00, mbc_bank, cart
wire sdram_oe = ~cart_download & cart_rd & ~cram_rd;
wire sdram_we = cart_download & dn_write;
wire sdram_refresh_force;
wire sdram_autorefresh = !fastforward;
wire sdram_autorefresh = !ff_on;
assign SDRAM_CKE = 1;
@@ -577,6 +596,8 @@ wire [1:0] lcd_mode;
wire lcd_on;
wire lcd_vsync;
wire HDMA_on;
assign AUDIO_S = 0;
wire reset = (RESET | status[0] | buttons[1] | cart_download | bk_loading);
@@ -628,7 +649,9 @@ gb gb (
.lcd_mode ( lcd_mode ),
.lcd_on ( lcd_on ),
.lcd_vsync ( lcd_vsync ),
.speed ( speed ),
.HDMA_on ( HDMA_on ),
// serial port
.sc_int_clock2(sc_int_clock_out),
@@ -645,9 +668,12 @@ gb gb (
.gg_available(gg_available),
// savestates
.save_state (joystick_0[9]),
.load_state (joystick_0[10]),
.cart_ram_size (cart_ram_size),
.save_state (ss_save),
.load_state (ss_load),
.savestate_number(ss_base),
.sleep_savestate (sleep_savestate),
.state_loaded (ss_loaded),
.SaveStateExt_Din (SaveStateBus_Din),
.SaveStateExt_Adr (SaveStateBus_Adr),
@@ -810,6 +836,7 @@ wire ce_cpu, ce_cpu2x;
wire cart_act = cart_wr | cart_rd;
wire fastforward = joystick_0[8] && !ioctl_download && !OSD_STATUS;
wire ff_on;
wire sleep_savestate;
@@ -821,15 +848,48 @@ end
speedcontrol speedcontrol
(
.clk_sys (clk_sys),
.speed (speed),
.pause (paused),
.speedup (fastforward),
.speedup (fast_forward),
.cart_act (cart_act),
.HDMA_on (HDMA_on),
.ce (ce_cpu),
.ce_2x (ce_cpu2x),
.refresh (sdram_refresh_force)
.refresh (sdram_refresh_force),
.ff_on (ff_on)
);
///////////////////////////// Fast Forward Latch /////////////////////////////////
reg fast_forward;
reg ff_latch;
always @(posedge clk_sys) begin : ffwd
reg last_ffw;
reg ff_was_held;
longint ff_count;
last_ffw <= fastforward;
if (fastforward)
ff_count <= ff_count + 1;
if (~last_ffw & fastforward) begin
ff_latch <= 0;
ff_count <= 0;
end
if ((last_ffw & ~fastforward)) begin // 32mhz clock, 0.2 seconds
ff_was_held <= 0;
if (ff_count < 3200000 && ~ff_was_held) begin
ff_was_held <= 1;
ff_latch <= 1;
end
end
fast_forward <= (fastforward | ff_latch);
end
///////////////////////////// savestates /////////////////////////////////
wire [63:0] SaveStateBus_Din;
@@ -866,6 +926,55 @@ ddram ddram
.ch1_ready(ss_ack)
);
// saving with keyboard/OSD/gamepad
wire pressed = ps2_key[9];
wire [7:0] code = ps2_key[7:0];
reg [1:0] ss_base = 0;
reg [7:0] ss_info;
reg ss_save, ss_load, ss_info_req;
wire ss_loaded;
always @(posedge clk_sys) begin
reg old_state;
reg alt = 0;
reg [1:0] old_st;
reg [1:0] old_st_joy;
old_state <= ps2_key[10];
if(cart_ready) begin
if(old_state != ps2_key[10]) begin
case(code)
'h11: alt <= pressed;
'h05: begin ss_save <= pressed & alt; ss_load <= pressed & ~alt; ss_base <= 0; end // F1
'h06: begin ss_save <= pressed & alt; ss_load <= pressed & ~alt; ss_base <= 1; end // F2
'h04: begin ss_save <= pressed & alt; ss_load <= pressed & ~alt; ss_base <= 2; end // F3
'h0C: begin ss_save <= pressed & alt; ss_load <= pressed & ~alt; ss_base <= 3; end // F4
endcase
end
old_st_joy <= joystick_0[10:9];
if(old_st_joy[0] ^ joystick_0[9]) ss_save <= joystick_0[9];
if(old_st_joy[1] ^ joystick_0[10]) ss_load <= joystick_0[10];
if(joystick_0[10:9]) ss_base <= 0;
old_st <= status[29:28];
if(old_st[0] ^ status[28]) ss_save <= status[28];
if(old_st[1] ^ status[29]) ss_load <= status[29];
if(status[29:28]) ss_base <= 0;
if(ss_load | ss_save) ss_info <= 7'd1 + {ss_base, ss_load};
ss_info_req <= (ss_loaded | ss_save);
// rewind info
if (status[27] & joystick_0[11]) begin
ss_info_req <= 1'b1;
ss_info <= 7'd9;
end
end
end
///////////////////////////// GBC BIOS /////////////////////////////////
wire [7:0] bios_do;

View File

@@ -58,6 +58,7 @@ module gb (
input [3:0] joy_din,
output speed, //GBC
output HDMA_on,
input gg_reset,
input gg_en,
@@ -72,9 +73,12 @@ module gb (
output serial_data_out,
// savestates
input save_state,
input load_state,
output sleep_savestate,
input [7:0] cart_ram_size,
input save_state,
input load_state,
input [1:0] savestate_number,
output sleep_savestate,
output state_loaded,
output [63:0] SaveStateExt_Din,
output [9:0] SaveStateExt_Adr,
@@ -233,7 +237,7 @@ wire clk_cpu = clk_sys & ce_cpu;
wire cpu_clken = !(isGBC && hdma_active) && ce_cpu; //when hdma is enabled stop CPU (GBC)
reg reset_r = 1;
reg reset_ss = 1;
wire reset_ss;
//sync reset with clock
always @ (posedge clk) begin
@@ -566,11 +570,11 @@ video video (
.dma_rd ( dma_rd ),
.dma_addr ( dma_addr ),
.dma_data ( dma_data ),
.Savestate_OAMRAMAddr (Savestate_RAMAddr[7:0]),
.Savestate_OAMRAMRWrEn (Savestate_RAMRWrEn[2]),
.Savestate_OAMRAMWriteData (Savestate_RAMWriteData),
.Savestate_OAMRAMReadData (Savestate_RAMReadData_ORAM),
.Savestate_OAMRAMAddr (Savestate_RAMAddr[7:0]),
.Savestate_OAMRAMRWrEn (Savestate_RAMRWrEn[2]),
.Savestate_OAMRAMWriteData (Savestate_RAMWriteData),
.Savestate_OAMRAMReadData (Savestate_RAMReadData_ORAM),
.SaveStateBus_Din (SaveStateBus_Din ),
.SaveStateBus_Adr (SaveStateBus_Adr ),
@@ -675,6 +679,8 @@ hdma hdma(
.SaveStateBus_Dout (SaveStateBus_wired_or[2])
);
assign HDMA_on = hdma_active;
// --------------------------------------------------------------------
// -------------------------- zero page ram ---------------------------
// --------------------------------------------------------------------
@@ -823,13 +829,15 @@ gb_savestates gb_savestates (
.reset_in (reset_r),
.reset_out (reset_ss),
//.load_done (load_done),
.load_done (state_loaded),
.save (savestate_savestate),
.load (savestate_loadstate),
.savestate_address (savestate_address),
.savestate_busy (savestate_busy),
.cart_ram_size (cart_ram_size),
.lcd_vsync (lcd_vsync),
.BUS_Din (SaveStateBus_Din),
@@ -867,7 +875,7 @@ gb_statemanager #(58720256, 33554432) gb_statemanager (
.rewind_on (rewind_on),
.rewind_active (rewind_active),
.savestate_number (1'b0),
.savestate_number (savestate_number),
.save (save_state),
.load (load_state),

View File

@@ -18,6 +18,8 @@ entity gb_savestates is
savestate_address : in integer;
savestate_busy : out std_logic;
cart_ram_size : in std_logic_vector(7 downto 0);
lcd_vsync : in std_logic;
BUS_Din : out std_logic_vector(BUS_buswidth-1 downto 0) := (others => '0');
@@ -60,13 +62,13 @@ architecture arch of gb_savestates is
constant SAVETYPESCOUNT : integer := 5;
signal savetype_counter : integer range 0 to SAVETYPESCOUNT;
type t_savetypes is array(0 to SAVETYPESCOUNT - 1) of integer;
constant savetypes : t_savetypes :=
signal savetypes : t_savetypes :=
(
32768, -- RAM
16384, -- VRAM
160, -- OAM
128, -- ZeroPage
131072 -- Saveram
131072 -- Saveram -> overwritten depending on cart_ram_size
);
type tstate is
@@ -126,6 +128,14 @@ begin
--if (reset_in = '1') then
-- header_amount <= (others => '0');
--end if;
case (cart_ram_size) is
when x"00" => savetypes(4) <= 512; -- for MBC2
when x"01" => savetypes(4) <= 2048; -- 2 KByte
when x"02" => savetypes(4) <= 8192; -- 8 KByte
when x"03" => savetypes(4) <= 32768; -- 32 KByte
when others => savetypes(4) <= 131072; -- 128 KByte
end case;
case state is
@@ -133,7 +143,7 @@ begin
savetype_counter <= 0;
if (reset_in = '1') then
reset_out <= '1';
BUS_rst <= '1';
BUS_rst <= '1';
elsif (save = '1') then
state <= SAVE_WAITVSYNC;
header_amount <= header_amount + 1;

View File

@@ -6,13 +6,14 @@ entity speedcontrol is
port
(
clk_sys : in std_logic;
speed : in std_logic;
pause : in std_logic;
speedup : in std_logic;
cart_act : in std_logic;
HDMA_on : in std_logic;
ce : out std_logic := '0';
ce_2x : buffer std_logic := '0';
refresh : out std_logic := '0'
refresh : out std_logic := '0';
ff_on : out std_logic := '0'
);
end entity;
@@ -63,7 +64,7 @@ begin
state <= PAUSED;
unpause_cnt <= 0;
end if;
elsif (speedup = '1' and pause = '0') then
elsif (speedup = '1' and pause = '0' and HDMA_on = '0' and clkdiv = "000") then
state <= FASTFORWARDSTART;
fastforward_cnt <= 0;
else
@@ -92,17 +93,19 @@ begin
when FASTFORWARDSTART =>
if (fastforward_cnt = 15) then
state <= FASTFORWARD;
ff_on <= '1';
else
fastforward_cnt <= fastforward_cnt + 1;
end if;
when FASTFORWARD =>
if (pause = '1' or speedup = '0') then
if (pause = '1' or speedup = '0' or HDMA_on = '1') then
state <= FASTFORWARDEND;
fastforward_cnt <= 0;
end if;
if (cart_act = '1' and cart_act_1 = '0') then
if (clkdiv(0) = '1') then
clkdiv <= "100";
end if;
elsif (cart_act = '1' and cart_act_1 = '0') then
state <= RAMACCESS;
sdram_busy <= 1;
elsif (cart_act = '0' and refreshcnt = 0) then
@@ -121,6 +124,7 @@ begin
when FASTFORWARDEND =>
if (fastforward_cnt = 15) then
state <= NORMAL;
ff_on <= '0';
else
fastforward_cnt <= fastforward_cnt + 1;
end if;

View File

@@ -362,7 +362,6 @@ generate
end
endgenerate
integer ii=0;
always @(posedge clk) begin
if(reset) begin
@@ -383,24 +382,39 @@ always @(posedge clk) begin
obpi_ai <= SS_Video2[ 45]; // 1'b0;
lyc <= SS_Video2[53:46]; // 8'h00;
for (ii=0;ii<8;ii=ii+1)begin
bgpd[ii*8+0] <= SS_BPAL[ii][ 7: 0]; //8'h00;
bgpd[ii*8+1] <= SS_BPAL[ii][15: 8]; //8'h00;
bgpd[ii*8+2] <= SS_BPAL[ii][23:16]; //8'h00;
bgpd[ii*8+3] <= SS_BPAL[ii][31:24]; //8'h00;
bgpd[ii*8+4] <= SS_BPAL[ii][39:32]; //8'h00;
bgpd[ii*8+5] <= SS_BPAL[ii][47:40]; //8'h00;
bgpd[ii*8+6] <= SS_BPAL[ii][55:48]; //8'h00;
bgpd[ii*8+7] <= SS_BPAL[ii][63:56]; //8'h00;
obpd[ii*8+0] <= SS_OPAL[ii][ 7: 0]; //8'h00;
obpd[ii*8+1] <= SS_OPAL[ii][15: 8]; //8'h00;
obpd[ii*8+2] <= SS_OPAL[ii][23:16]; //8'h00;
obpd[ii*8+3] <= SS_OPAL[ii][31:24]; //8'h00;
obpd[ii*8+4] <= SS_OPAL[ii][39:32]; //8'h00;
obpd[ii*8+5] <= SS_OPAL[ii][47:40]; //8'h00;
obpd[ii*8+6] <= SS_OPAL[ii][55:48]; //8'h00;
obpd[ii*8+7] <= SS_OPAL[ii][63:56]; //8'h00;
end
bgpd[ 0] <= SS_BPAL[0][ 7: 0]; bgpd[16] <= SS_BPAL[2][ 7: 0]; bgpd[32] <= SS_BPAL[4][ 7: 0]; bgpd[48] <= SS_BPAL[6][ 7: 0]; //8'h00;
bgpd[ 1] <= SS_BPAL[0][15: 8]; bgpd[17] <= SS_BPAL[2][15: 8]; bgpd[33] <= SS_BPAL[4][15: 8]; bgpd[49] <= SS_BPAL[6][15: 8]; //8'h00;
bgpd[ 2] <= SS_BPAL[0][23:16]; bgpd[18] <= SS_BPAL[2][23:16]; bgpd[34] <= SS_BPAL[4][23:16]; bgpd[50] <= SS_BPAL[6][23:16]; //8'h00;
bgpd[ 3] <= SS_BPAL[0][31:24]; bgpd[19] <= SS_BPAL[2][31:24]; bgpd[35] <= SS_BPAL[4][31:24]; bgpd[51] <= SS_BPAL[6][31:24]; //8'h00;
bgpd[ 4] <= SS_BPAL[0][39:32]; bgpd[20] <= SS_BPAL[2][39:32]; bgpd[36] <= SS_BPAL[4][39:32]; bgpd[52] <= SS_BPAL[6][39:32]; //8'h00;
bgpd[ 5] <= SS_BPAL[0][47:40]; bgpd[21] <= SS_BPAL[2][47:40]; bgpd[37] <= SS_BPAL[4][47:40]; bgpd[53] <= SS_BPAL[6][47:40]; //8'h00;
bgpd[ 6] <= SS_BPAL[0][55:48]; bgpd[22] <= SS_BPAL[2][55:48]; bgpd[38] <= SS_BPAL[4][55:48]; bgpd[54] <= SS_BPAL[6][55:48]; //8'h00;
bgpd[ 7] <= SS_BPAL[0][63:56]; bgpd[23] <= SS_BPAL[2][63:56]; bgpd[39] <= SS_BPAL[4][63:56]; bgpd[55] <= SS_BPAL[6][63:56]; //8'h00;
bgpd[ 8] <= SS_BPAL[1][ 7: 0]; bgpd[24] <= SS_BPAL[3][ 7: 0]; bgpd[40] <= SS_BPAL[5][ 7: 0]; bgpd[56] <= SS_BPAL[7][ 7: 0]; //8'h00;
bgpd[ 9] <= SS_BPAL[1][15: 8]; bgpd[25] <= SS_BPAL[3][15: 8]; bgpd[41] <= SS_BPAL[5][15: 8]; bgpd[57] <= SS_BPAL[7][15: 8]; //8'h00;
bgpd[10] <= SS_BPAL[1][23:16]; bgpd[26] <= SS_BPAL[3][23:16]; bgpd[42] <= SS_BPAL[5][23:16]; bgpd[58] <= SS_BPAL[7][23:16]; //8'h00;
bgpd[11] <= SS_BPAL[1][31:24]; bgpd[27] <= SS_BPAL[3][31:24]; bgpd[43] <= SS_BPAL[5][31:24]; bgpd[59] <= SS_BPAL[7][31:24]; //8'h00;
bgpd[12] <= SS_BPAL[1][39:32]; bgpd[28] <= SS_BPAL[3][39:32]; bgpd[44] <= SS_BPAL[5][39:32]; bgpd[60] <= SS_BPAL[7][39:32]; //8'h00;
bgpd[13] <= SS_BPAL[1][47:40]; bgpd[29] <= SS_BPAL[3][47:40]; bgpd[45] <= SS_BPAL[5][47:40]; bgpd[61] <= SS_BPAL[7][47:40]; //8'h00;
bgpd[14] <= SS_BPAL[1][55:48]; bgpd[30] <= SS_BPAL[3][55:48]; bgpd[46] <= SS_BPAL[5][55:48]; bgpd[62] <= SS_BPAL[7][55:48]; //8'h00;
bgpd[15] <= SS_BPAL[1][63:56]; bgpd[31] <= SS_BPAL[3][63:56]; bgpd[47] <= SS_BPAL[5][63:56]; bgpd[63] <= SS_BPAL[7][63:56]; //8'h00;
obpd[ 0] <= SS_OPAL[0][ 7: 0]; obpd[16] <= SS_OPAL[2][ 7: 0]; obpd[32] <= SS_OPAL[4][ 7: 0]; obpd[48] <= SS_OPAL[6][ 7: 0]; //8'h00;
obpd[ 1] <= SS_OPAL[0][15: 8]; obpd[17] <= SS_OPAL[2][15: 8]; obpd[33] <= SS_OPAL[4][15: 8]; obpd[49] <= SS_OPAL[6][15: 8]; //8'h00;
obpd[ 2] <= SS_OPAL[0][23:16]; obpd[18] <= SS_OPAL[2][23:16]; obpd[34] <= SS_OPAL[4][23:16]; obpd[50] <= SS_OPAL[6][23:16]; //8'h00;
obpd[ 3] <= SS_OPAL[0][31:24]; obpd[19] <= SS_OPAL[2][31:24]; obpd[35] <= SS_OPAL[4][31:24]; obpd[51] <= SS_OPAL[6][31:24]; //8'h00;
obpd[ 4] <= SS_OPAL[0][39:32]; obpd[20] <= SS_OPAL[2][39:32]; obpd[36] <= SS_OPAL[4][39:32]; obpd[52] <= SS_OPAL[6][39:32]; //8'h00;
obpd[ 5] <= SS_OPAL[0][47:40]; obpd[21] <= SS_OPAL[2][47:40]; obpd[37] <= SS_OPAL[4][47:40]; obpd[53] <= SS_OPAL[6][47:40]; //8'h00;
obpd[ 6] <= SS_OPAL[0][55:48]; obpd[22] <= SS_OPAL[2][55:48]; obpd[38] <= SS_OPAL[4][55:48]; obpd[54] <= SS_OPAL[6][55:48]; //8'h00;
obpd[ 7] <= SS_OPAL[0][63:56]; obpd[23] <= SS_OPAL[2][63:56]; obpd[39] <= SS_OPAL[4][63:56]; obpd[55] <= SS_OPAL[6][63:56]; //8'h00;
obpd[ 8] <= SS_OPAL[1][ 7: 0]; obpd[24] <= SS_OPAL[3][ 7: 0]; obpd[40] <= SS_OPAL[5][ 7: 0]; obpd[56] <= SS_OPAL[7][ 7: 0]; //8'h00;
obpd[ 9] <= SS_OPAL[1][15: 8]; obpd[25] <= SS_OPAL[3][15: 8]; obpd[41] <= SS_OPAL[5][15: 8]; obpd[57] <= SS_OPAL[7][15: 8]; //8'h00;
obpd[10] <= SS_OPAL[1][23:16]; obpd[26] <= SS_OPAL[3][23:16]; obpd[42] <= SS_OPAL[5][23:16]; obpd[58] <= SS_OPAL[7][23:16]; //8'h00;
obpd[11] <= SS_OPAL[1][31:24]; obpd[27] <= SS_OPAL[3][31:24]; obpd[43] <= SS_OPAL[5][31:24]; obpd[59] <= SS_OPAL[7][31:24]; //8'h00;
obpd[12] <= SS_OPAL[1][39:32]; obpd[28] <= SS_OPAL[3][39:32]; obpd[44] <= SS_OPAL[5][39:32]; obpd[60] <= SS_OPAL[7][39:32]; //8'h00;
obpd[13] <= SS_OPAL[1][47:40]; obpd[29] <= SS_OPAL[3][47:40]; obpd[45] <= SS_OPAL[5][47:40]; obpd[61] <= SS_OPAL[7][47:40]; //8'h00;
obpd[14] <= SS_OPAL[1][55:48]; obpd[30] <= SS_OPAL[3][55:48]; obpd[46] <= SS_OPAL[5][55:48]; obpd[62] <= SS_OPAL[7][55:48]; //8'h00;
obpd[15] <= SS_OPAL[1][63:56]; obpd[31] <= SS_OPAL[3][63:56]; obpd[47] <= SS_OPAL[5][63:56]; obpd[63] <= SS_OPAL[7][63:56]; //8'h00;
end else if (ce_cpu) begin
if(cpu_sel_reg && cpu_wr) begin

470
sim/src/gameboy/mbc.sv Normal file
View File

@@ -0,0 +1,470 @@
module mbc
(
input clk_sys,
input clkram,
input reset,
input ce_cpu2x,
input [15:0] cart_addr,
input cart_rd,
input cart_wr,
output [7:0] cart_do,
input [7:0] cart_di,
output reg [7:0] cart_ram_size,
output is_gbc,
input sleep_savestate,
input [63:0] SaveStateBus_Din,
input [9:0] SaveStateBus_Adr,
input SaveStateBus_wren,
input SaveStateBus_rst,
output [63:0] SaveStateBus_Dout,
input savestate_load,
input [19:0] Savestate_CRAMAddr,
input Savestate_CRAMRWrEn,
input [7:0] Savestate_CRAMWriteData,
output [7:0] Savestate_CRAMReadData
);
///////////////////////////////////////////////////
// http://fms.komkon.org/GameBoy/Tech/Carts.html
// 32MB SDRAM memory map using word addresses
// 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 D
// 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 S
// -------------------------------------------------
// 0 0 0 0 X X X X X X X X X X X X X X X X X X X X X up to 2MB used as ROM (MBC1-3), 8MB for MBC5
// 0 0 0 0 R R B B B B B C C C C C C C C C C C C C C MBC1 ROM (R=RAM bank in mode 0)
wire [6:0] mbc1_rom_bank_mode;
wire [8:0] rom_mask;
wire [3:0] ram_mask;
reg mbc_ram_enable;
reg mbc1_mode;
reg mbc3_mode;
reg [8:0] mbc_rom_bank_reg;
reg [3:0] mbc_ram_bank_reg; //0-15
reg [7:0] cart_logo_check = 8'd0;
reg [2:0] cart_logo_idx = 3'd0;
wire mbc1m = &cart_logo_check;
// 0x0000-0x3FFF = Bank 0
wire [8:0] mbc_rom_bank = (cart_addr[15:14] == 2'b00) ? 9'd0 : mbc_rom_bank_reg;
// mask address lines to enable proper mirroring
wire [6:0] mbc1_rom_bank = mbc1_rom_bank_mode & rom_mask[6:0]; //128
wire [6:0] mbc2_rom_bank = mbc_rom_bank[6:0] & rom_mask[6:0]; //16
wire [6:0] mbc3_rom_bank = mbc_rom_bank[6:0] & rom_mask[6:0]; //128
wire [8:0] mbc5_rom_bank = mbc_rom_bank & rom_mask; //480
// extract header fields extracted from cartridge
// during download
wire [7:0] cart_mbc_type;
reg [7:0] cart_rom_size;
reg [7:0] cart_cgb_flag;
reg [7:0] cart_sgb_flag;
reg [7:0] cart_old_licensee;
reg [15:0] cart_logo_data[0:7];
// RAM size
assign ram_mask = // 0 - no ram
(cart_ram_size == 1)?4'b0000: // 1 - 2k, 1 bank
(cart_ram_size == 2)?4'b0000: // 2 - 8k, 1 bank
(cart_ram_size == 3)?4'b0011: // 3 - 32k, 4 banks
4'b1111; // 4 - 128k 16 banks
// ROM size
assign rom_mask = // 0 - 2 banks, 32k direct mapped
(cart_rom_size == 1)? 9'b000000011: // 1 - 4 banks = 64k
(cart_rom_size == 2)? 9'b000000111: // 2 - 8 banks = 128k
(cart_rom_size == 3)? 9'b000001111: // 3 - 16 banks = 256k
(cart_rom_size == 4)? 9'b000011111: // 4 - 32 banks = 512k
(cart_rom_size == 5)? 9'b000111111: // 5 - 64 banks = 1M
(cart_rom_size == 6)? 9'b001111111: // 6 - 128 banks = 2M
(cart_rom_size == 7)? 9'b011111111: // 7 - 256 banks = 4M
(cart_rom_size == 8)? 9'b111111111: // 8 - 512 banks = 8M
(cart_rom_size == 82)?9'b001111111: //$52 - 72 banks = 1.1M
(cart_rom_size == 83)?9'b001111111: //$53 - 80 banks = 1.2M
(cart_rom_size == 84)?9'b001111111:
9'b001111111; //$54 - 96 banks = 1.5M
wire mbc1 = (cart_mbc_type == 1) || (cart_mbc_type == 2) || (cart_mbc_type == 3);
wire mbc2 = (cart_mbc_type == 5) || (cart_mbc_type == 6);
//wire mmm01 = (cart_mbc_type == 11) || (cart_mbc_type == 12) || (cart_mbc_type == 13) || (cart_mbc_type == 14);
wire mbc3 = (cart_mbc_type == 15) || (cart_mbc_type == 16) || (cart_mbc_type == 17) || (cart_mbc_type == 18) || (cart_mbc_type == 19);
//wire mbc4 = (cart_mbc_type == 21) || (cart_mbc_type == 22) || (cart_mbc_type == 23);
wire mbc5 = (cart_mbc_type == 25) || (cart_mbc_type == 26) || (cart_mbc_type == 27) || (cart_mbc_type == 28) || (cart_mbc_type == 29) || (cart_mbc_type == 30);
//wire tama5 = (cart_mbc_type == 253);
//wire tama6 = (cart_mbc_type == ???);
//wire HuC1 = (cart_mbc_type == 254);
//wire HuC3 = (cart_mbc_type == 255);
// ---------------------------------------------------------------
// ----------------------------- MBC1 ----------------------------
// ---------------------------------------------------------------
wire [9:0] mbc1_addr = {2'b00, mbc1_rom_bank, cart_addr[13]}; // 16k ROM Bank 0-127 or MBC1M Bank 0-63
wire [9:0] mbc2_addr = {2'b00, mbc2_rom_bank, cart_addr[13]}; // 16k ROM Bank 0-15
wire [9:0] mbc3_addr = {2'b00, mbc3_rom_bank, cart_addr[13]}; // 16k ROM Bank 0-127
wire [9:0] mbc5_addr = { mbc5_rom_bank, cart_addr[13]}; // 16k ROM Bank 0-480 (0h-1E0h)
// https://forums.nesdev.com/viewtopic.php?p=168940#p168940
// https://gekkio.fi/files/gb-docs/gbctr.pdf
// MBC1 $6000 Mode register:
// 0: Bank2 ANDed with CPU A14. Bank2 affects ROM 0x4000-0x7FFF only
// 1: Passthrough. Bank2 affects ROM 0x0000-0x3FFF, 0x4000-0x7FFF, RAM 0xA000-0xBFFF
wire [1:0] mbc1_bank2 = mbc_ram_bank_reg[1:0] & {2{cart_addr[14] | mbc1_mode}};
// -------------------------- RAM banking ------------------------
wire [1:0] mbc1_ram_bank = mbc1_bank2 & ram_mask[1:0];
wire [1:0] mbc3_ram_bank = mbc_ram_bank_reg[1:0] & ram_mask[1:0];
wire [3:0] mbc5_ram_bank = mbc_ram_bank_reg & ram_mask;
// -------------------------- ROM banking ------------------------
// MBC1: 4x32 16KByte banks, MBC1M: 4x16 16KByte banks
assign mbc1_rom_bank_mode = mbc1m ? { 1'b0, mbc1_bank2, mbc_rom_bank[3:0] }
: { mbc1_bank2, mbc_rom_bank[4:0] };
// in mode 0 map memory at A000-BFFF
// in mode 1 map rtc register at A000-BFFF
//wire [6:0] mbc3_ram_bank_addr = { mbc3_mode?2'b00:mbc3_ram_bank_reg, mbc3_rom_bank_reg};
wire mbc_battery = (cart_mbc_type == 8'h03) || (cart_mbc_type == 8'h06) || (cart_mbc_type == 8'h09) || (cart_mbc_type == 8'h0D) ||
(cart_mbc_type == 8'h10) || (cart_mbc_type == 8'h13) || (cart_mbc_type == 8'h1B) || (cart_mbc_type == 8'h1E) ||
(cart_mbc_type == 8'h22) || (cart_mbc_type == 8'hFF);
// --------------------- CPU register interface ------------------
wire [15:0] SS_Ext;
wire [15:0] SS_Ext_BACK;
assign SS_Ext_BACK[ 8: 0] = mbc_rom_bank_reg;
assign SS_Ext_BACK[12: 9] = mbc_ram_bank_reg;
assign SS_Ext_BACK[ 13] = mbc1_mode;
assign SS_Ext_BACK[ 14] = mbc3_mode;
assign SS_Ext_BACK[ 15] = mbc_ram_enable;
always @(posedge clk_sys) begin
if(savestate_load) begin
mbc_rom_bank_reg <= SS_Ext[ 8: 0]; //5'd1;
mbc_ram_bank_reg <= SS_Ext[12: 9]; //4'd0;
mbc1_mode <= SS_Ext[ 13]; //1'b0;
mbc3_mode <= SS_Ext[ 14]; //1'b0;
mbc_ram_enable <= SS_Ext[ 15]; //1'b0;
end else if(reset) begin
mbc_rom_bank_reg <= 5'd1;
mbc_ram_bank_reg <= 4'd0;
mbc1_mode <= 1'b0;
mbc3_mode <= 1'b0;
mbc_ram_enable <= 1'b0;
end else if(ce_cpu2x) begin
//write to ROM bank register
if(cart_wr && (cart_addr[15:13] == 3'b001)) begin
if(~mbc5 && cart_di[6:0]==0) //special case mbc1-3 rombank 0=1
mbc_rom_bank_reg <= 5'd1;
else if (mbc5) begin
if (cart_addr[13:12] == 2'b11) //3000-3FFF High bit
mbc_rom_bank_reg[8] <= cart_di[0];
else //2000-2FFF low 8 bits
mbc_rom_bank_reg[7:0] <= cart_di[7:0];
end else
mbc_rom_bank_reg <= {2'b00,cart_di[6:0]}; //mbc1-3
end
//write to RAM bank register
if(cart_wr && (cart_addr[15:13] == 3'b010)) begin
if (mbc3) begin
if (cart_di[3]==1)
mbc3_mode <= 1'b1; //enable RTC
else begin
mbc3_mode <= 1'b0; //enable RAM
mbc_ram_bank_reg <= {2'b00,cart_di[1:0]};
end
end else
if (mbc5)//can probably be simplified
mbc_ram_bank_reg <= cart_di[3:0];
else
mbc_ram_bank_reg <= {2'b00,cart_di[1:0]};
end
// MBC1 ROM/RAM Mode Select
if(mbc1 && cart_wr && (cart_addr[15:13] == 3'b011))
mbc1_mode <= cart_di[0];
//RAM enable/disable
if(ce_cpu2x && cart_wr && (cart_addr[15:13] == 3'b000))
mbc_ram_enable <= (cart_di[3:0] == 4'ha);
end
end
wire [9:0] mbc_bank =
mbc1?mbc1_addr: // MBC1, 16k bank 0, 16k bank 1-127 + ram
mbc2?mbc2_addr: // MBC2, 16k bank 0, 16k bank 1-15 + ram
mbc3?mbc3_addr:
mbc5?mbc5_addr:
// tama5?tama5_addr:
// HuC1?HuC1_addr:
// HuC3?HuC3_addr:
{8'd0, cart_addr[14:13]}; // no MBC, 32k linear address
wire isGBC_game = (cart_cgb_flag == 8'h80 || cart_cgb_flag == 8'hC0);
wire isSGB_game = (cart_sgb_flag == 8'h03 && cart_old_licensee == 8'h33);
assign is_gbc = isGBC_game;
reg [127:0] palette = 128'h828214517356305A5F1A3B4900000000;
// MBC1M detect
//always @(posedge clk_sys) begin
// if(~old_downloading & downloading) begin
// cart_logo_idx <= 3'd0;
// cart_logo_check <= 8'd0;
// end
//
// if(cart_download & ioctl_wr) begin
// case(ioctl_addr)
// 'h142: cart_cgb_flag <= ioctl_dout[15:8];
// 'h146: {cart_mbc_type, cart_sgb_flag} <= ioctl_dout;
// 'h148: { cart_ram_size, cart_rom_size } <= ioctl_dout;
// 'h14a: { cart_old_licensee } <= ioctl_dout[15:8];
// endcase
//
// //Store cart logo data
// if (ioctl_addr >= 'h104 && ioctl_addr <= 'h112) begin
// cart_logo_data[cart_logo_idx] <= ioctl_dout;
// cart_logo_idx <= cart_logo_idx + 1'b1;
// end
//
// // MBC1 Multicart detect: Compare 8 words of logo data at second 256KByte bank
// if (ioctl_addr >= 'h40104 && ioctl_addr <= 'h40112) begin
// cart_logo_check[cart_logo_idx] <= (ioctl_dout == cart_logo_data[cart_logo_idx]);
// cart_logo_idx <= cart_logo_idx + 1'b1;
// end
//
// end
//
// if (palette_download & ioctl_wr) begin
// palette[127:0] <= {palette[111:0], ioctl_dout[7:0], ioctl_dout[15:8]};
// end
//end
wire [7:0] sdram_do;
wire [23:0] sdram_addr = {1'b0, mbc_bank, cart_addr[12:0]};
sdram_model sdram_model
(
clkram,
sdram_addr,
cart_rd,
sdram_do,
cart_cgb_flag,
cart_sgb_flag,
cart_mbc_type,
cart_rom_size,
cart_ram_size,
cart_old_licensee
);
//TODO: e.g. output and read timer register values from mbc3 when selected
reg cart_ready = 1;
wire cram_rd;
wire [7:0] cram_do;
assign cart_do =
~cart_ready ?
8'h00 :
cram_rd ?
cram_do : sdram_do;
// cart_addr[0] ?
// sdram_do[15:8]:
// sdram_do[7:0];
reg isGBC = 0;
//always @(posedge clk_sys) if(reset) begin
// if(status[15:14]) isGBC <= status[15];
// else if(cart_download) isGBC <= !filetype[7:4];
//end
///////////////////////////// savestates /////////////////////////////////
eReg_SavestateV #(0, 32, 15, 0, 64'h0000000000000001) iREG_SAVESTATE_Ext (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_Dout, SS_Ext_BACK, SS_Ext);
///////////////////////// BRAM SAVE/LOAD /////////////////////////////
//wire [16:0] bk_addr = {sd_lba[7:0],sd_buff_addr};
//wire bk_wr = sd_buff_wr & sd_ack;
//wire [15:0] bk_data = sd_buff_dout;
//wire [15:0] bk_q;
//assign sd_buff_din = bk_q;
wire [16:0] cram_addr = sleep_savestate ? Savestate_CRAMAddr[16:0]:
mbc1? {2'b00,mbc1_ram_bank, cart_addr[12:0]}:
mbc3? {2'b00,mbc3_ram_bank, cart_addr[12:0]}:
mbc5? {mbc5_ram_bank, cart_addr[12:0]}:
{4'd0, cart_addr[12:0]};
wire [7:0] cram_q_h;
wire [7:0] cram_q_l;
wire [7:0] cram_q = cram_addr[0] ? cram_q_h : cram_q_l;
assign cram_do =
mbc_ram_enable ?
((cart_addr[15:9] == 7'b1010000) && mbc2) ?
{4'hF,cram_q[3:0]} : // 4 bit MBC2 Ram needs top half masked.
mbc3_mode ?
8'h0: // RTC mode
cram_q : // Return normal value
8'hFF; // Ram not enabled
reg read_low = 0;
always @(posedge clk_sys) begin
read_low <= cram_addr[0];
end
assign Savestate_CRAMReadData = read_low ? cram_q_h : cram_q_l;
wire is_cram_addr = (cart_addr[15:13] == 3'b101);
assign cram_rd = cart_rd & is_cram_addr;
wire cram_wr = sleep_savestate ? Savestate_CRAMRWrEn : cart_wr & is_cram_addr;
wire [7:0] cram_di = sleep_savestate ? Savestate_CRAMWriteData : cart_di;
// Up to 8kb * 16banks of Cart Ram (128kb)
dpram #(16) cram_l (
.clock_a (clk_sys),
.address_a (cram_addr[16:1]),
.wren_a (cram_wr & ~cram_addr[0]),
.data_a (cram_di),
.q_a (cram_q_l),
.clock_b (clk_sys),
.address_b (16'd0),
.wren_b (1'b0),
.data_b (8'b0)
//.clock_b (clk_sys),
//.address_b (bk_addr[15:0]),
//.wren_b (bk_wr),
//.data_b (bk_data[7:0]),
//.q_b (bk_q[7:0])
);
dpram #(16) cram_h (
.clock_a (clk_sys),
.address_a (cram_addr[16:1]),
.wren_a (cram_wr & cram_addr[0]),
.data_a (cram_di),
.q_a (cram_q_h),
.clock_b (clk_sys),
.address_b (16'd0),
.wren_b (1'b0),
.data_b (8'b0)
//.clock_b (clk_sys),
//.address_b (bk_addr[15:0]),
//.wren_b (bk_wr),
//.data_b (bk_data[15:8]),
//.q_b (bk_q[15:8])
);
//wire downloading = cart_download;
//reg bk_ena = 0;
//reg new_load = 0;
//reg old_downloading = 0;
//reg sav_pending = 0;
//wire sav_supported = (mbc_battery && (cart_ram_size > 0 || mbc2) && bk_ena);
//
//always @(posedge clk_sys) begin
// old_downloading <= downloading;
// if(~old_downloading & downloading) bk_ena <= 0;
//
// //Save file always mounted in the end of downloading state.
// if(downloading && img_mounted && !img_readonly) bk_ena <= 1;
//
// if (old_downloading & ~downloading & sav_supported)
// new_load <= 1'b1;
// else if (bk_state)
// new_load <= 1'b0;
//
// if (cram_wr & ~OSD_STATUS & sav_supported)
// sav_pending <= 1'b1;
// else if (bk_state)
// sav_pending <= 1'b0;
//end
//
//wire bk_load = status[9] | new_load;
//wire bk_save = status[10] | (sav_pending & OSD_STATUS & status[13]);
//reg bk_loading = 0;
//reg bk_state = 0;
// RAM size
wire [7:0] ram_mask_file = // 0 - no ram
(mbc2)?8'h01: // mbc2 512x4bits
(cart_ram_size == 1)?8'h03: // 1 - 2k, 1 bank sd_lba[1:0]
(cart_ram_size == 2)?8'h0F: // 2 - 8k, 1 bank sd_lba[3:0]
(cart_ram_size == 3)?8'h3F: // 3 - 32k, 4 banks sd_lba[5:0]
8'hFF; // 4 - 128k 16 banks sd_lba[7:0] 1111
//always @(posedge clk_sys) begin
// reg old_load = 0, old_save = 0, old_ack;
//
// old_load <= bk_load;
// old_save <= bk_save;
// old_ack <= sd_ack;
//
// if(~old_ack & sd_ack) {sd_rd, sd_wr} <= 0;
//
// if(!bk_state) begin
// if(bk_ena & ((~old_load & bk_load) | (~old_save & bk_save))) begin
// bk_state <= 1;
// bk_loading <= bk_load;
// sd_lba <= 32'd0;
// sd_rd <= bk_load;
// sd_wr <= ~bk_load;
// end
// if(old_downloading & ~downloading & |img_size & bk_ena) begin
// bk_state <= 1;
// bk_loading <= 1;
// sd_lba <= 0;
// sd_rd <= 1;
// sd_wr <= 0;
// end
// end else begin
// if(old_ack & ~sd_ack) begin
//
// if(sd_lba[7:0]>=ram_mask_file) begin
// bk_loading <= 0;
// bk_state <= 0;
// end else begin
// sd_lba <= sd_lba + 1'd1;
// sd_rd <= bk_loading;
// sd_wr <= ~bk_loading;
// end
// end
// end
//end
endmodule

View File

@@ -8,10 +8,16 @@ use tb.globals.all;
entity sdram_model is
port
(
clk : in std_logic;
cart_addr : in std_logic_vector(15 downto 0);
cart_rd : in std_logic;
cart_do : out std_logic_vector(7 downto 0)
clk : in std_logic;
cart_addr : in std_logic_vector(23 downto 0);
cart_rd : in std_logic;
cart_do : out std_logic_vector(7 downto 0);
cart_cgb_flag : out std_logic_vector(7 downto 0);
cart_sgb_flag : out std_logic_vector(7 downto 0);
cart_mbc_type : out std_logic_vector(7 downto 0);
cart_rom_size : out std_logic_vector(7 downto 0);
cart_ram_size : out std_logic_vector(7 downto 0);
cart_old_licensee : out std_logic_vector(7 downto 0)
);
end entity;
@@ -72,7 +78,14 @@ begin
wait until rising_edge(clk);
wait until rising_edge(clk);
cart_do <= std_logic_vector(to_unsigned(data(to_integer(unsigned(cart_addr))), 8));
end if;
end if;
cart_cgb_flag <= std_logic_vector(to_unsigned(data(16#143#), 8));
cart_sgb_flag <= std_logic_vector(to_unsigned(data(16#146#), 8));
cart_mbc_type <= std_logic_vector(to_unsigned(data(16#147#), 8));
cart_rom_size <= std_logic_vector(to_unsigned(data(16#148#), 8));
cart_ram_size <= std_logic_vector(to_unsigned(data(16#149#), 8));
cart_old_licensee <= std_logic_vector(to_unsigned(data(16#14B#), 8));
COMMAND_FILE_ACK_1 <= '0';
if COMMAND_FILE_START_1 = '1' then
@@ -102,7 +115,7 @@ begin
COMMAND_FILE_ACK_1 <= '1';
end if;
end process;

View File

@@ -31,6 +31,7 @@ architecture arch of etb is
signal ce_2x : std_logic := '1';
signal speed : std_logic;
signal HDMA_on : std_logic;
signal command_in : std_logic;
signal command_out : std_logic;
@@ -62,7 +63,7 @@ architecture arch of etb is
signal pixel_out_data : std_logic_vector(14 downto 0);
signal pixel_out_we : std_logic := '0';
signal is_CGB : std_logic := '0';
signal is_CGB : std_logic;
signal sleep_savestate : std_logic;
@@ -97,6 +98,20 @@ architecture arch of etb is
signal GB_SaveState : std_logic_vector(Reg_GB_SaveState.upper downto Reg_GB_SaveState.lower) := (others => '0');
signal GB_LoadState : std_logic_vector(Reg_GB_LoadState.upper downto Reg_GB_LoadState.lower) := (others => '0');
-- savestates
signal cart_ram_size : std_logic_vector(7 downto 0);
signal Savestate_CRAMAddr : std_logic_vector(19 downto 0);
signal Savestate_CRAMRWrEn : std_logic;
signal Savestate_CRAMWriteData : std_logic_vector(7 downto 0);
signal Savestate_CRAMReadData : std_logic_vector(7 downto 0);
signal SaveStateExt_Din : std_logic_vector(63 downto 0);
signal SaveStateExt_Adr : std_logic_vector(9 downto 0);
signal SaveStateExt_wren : std_logic;
signal SaveStateExt_rst : std_logic;
signal SaveStateExt_Dout : std_logic_vector(63 downto 0);
signal SaveStateExt_load : std_logic;
begin
@@ -115,23 +130,14 @@ begin
port map
(
clk_sys => clksys,
speed => speed,
pause => sleep_savestate,
speedup => '1',
cart_act => cart_act,
HDMA_on => HDMA_on,
ce => ce,
ce_2x => ce_2x
);
isdram_model : entity tb.sdram_model
port map
(
clk => clkram,
cart_addr => cart_addr,
cart_rd => cart_rd,
cart_do => cart_do
);
igb : entity gameboy.gb
port map
(
@@ -173,6 +179,7 @@ begin
joy_din => "1111",
speed => speed, --GBC
HDMA_on => HDMA_on,
gg_reset => reset,
gg_en => '0',
@@ -186,17 +193,24 @@ begin
serial_data_in => '0',
serial_data_out => open,
cart_ram_size => cart_ram_size,
save_state => GB_SaveState,
load_state => GB_LoadState,
sleep_savestate => sleep_savestate,
savestate_number => 0,
SaveStateExt_Din => open,
SaveStateExt_Adr => open,
SaveStateExt_wren => open,
SaveStateExt_rst => open,
SaveStateExt_Dout => (63 downto 0 => '0'),
SaveStateExt_Din => SaveStateExt_Din,
SaveStateExt_Adr => SaveStateExt_Adr,
SaveStateExt_wren => SaveStateExt_wren,
SaveStateExt_rst => SaveStateExt_rst,
SaveStateExt_Dout => SaveStateExt_Dout,
SaveStateExt_load => SaveStateExt_load,
Savestate_CRAMAddr => Savestate_CRAMAddr,
Savestate_CRAMRWrEn => Savestate_CRAMRWrEn,
Savestate_CRAMWriteData => Savestate_CRAMWriteData,
Savestate_CRAMReadData => Savestate_CRAMReadData,
Savestate_CRAMReadData => (7 downto 0 => '0'),
SAVE_out_Din => SAVE_out_Din,
SAVE_out_Dout => SAVE_out_Dout,
@@ -209,6 +223,39 @@ begin
rewind_active => '0'
);
imbc : entity gameboy.mbc
port map
(
clk_sys => clksys,
clkram => clkram,
reset => reset,
ce_cpu2x => ce_2x,
cart_addr => cart_addr,
cart_rd => cart_rd,
cart_wr => cart_wr,
cart_do => cart_do,
cart_di => cart_di,
cart_ram_size => cart_ram_size,
is_gbc => is_CGB,
sleep_savestate => sleep_savestate,
SaveStateBus_Din => SaveStateExt_Din,
SaveStateBus_Adr => SaveStateExt_Adr,
SaveStateBus_wren => SaveStateExt_wren,
SaveStateBus_rst => SaveStateExt_rst,
SaveStateBus_Dout => SaveStateExt_Dout,
savestate_load => SaveStateExt_load,
Savestate_CRAMAddr => Savestate_CRAMAddr,
Savestate_CRAMRWrEn => Savestate_CRAMRWrEn,
Savestate_CRAMWriteData => Savestate_CRAMWriteData,
Savestate_CRAMReadData => Savestate_CRAMReadData
);
ch1_addr <= SAVE_out_Adr(25 downto 0) & "0";
ch1_din <= SAVE_out_Din;
ch1_req <= SAVE_out_ena;
@@ -259,7 +306,7 @@ begin
address => gbc_bios_addr,
data => gbc_bios_do
);
process(clksys)
begin
if rising_edge(clksys) then
@@ -292,7 +339,7 @@ begin
when others => pixel_out_data <= "00000" & "00000" & "11111";
end case;
else
pixel_out_data <= lcd_data;
pixel_out_data <= lcd_data(4 downto 0) & lcd_data(9 downto 5) & lcd_data(14 downto 10);
end if;
end if;

View File

@@ -50,6 +50,7 @@ vlog -sv -quiet -work sim/gameboy ^
../rtl/gb.v
vlog -sv -quiet -work sim/gameboy ^
src/gameboy/mbc.sv ^
src/gameboy/cheatcodes.sv
vcom -quiet -work sim/gameboy ^