diff --git a/Gameboy.sv b/Gameboy.sv index 517d0cf..b4887b7 100644 --- a/Gameboy.sv +++ b/Gameboy.sv @@ -104,7 +104,9 @@ module emu input UART_RXD, output UART_TXD, output UART_DTR, - input UART_DSR + input UART_DSR, + + input OSD_STATUS ); assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = 0; @@ -114,7 +116,7 @@ assign {UART_RTS, UART_TXD, UART_DTR} = 0; assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; -assign LED_USER = ioctl_download; +assign LED_USER = ioctl_download | sav_pending; assign LED_DISK = 0; assign LED_POWER = 0; @@ -142,8 +144,15 @@ localparam CONF_STR1 = { localparam CONF_STR2 = { ",GBP,Load Palette;", "-;", - "R9,Load Backup RAM;", - "RA,Save Backup RAM;", + "OD,OSD triggered autosaves,No,Yes;", +}; + +localparam CONF_STR3 = { + "9,Load Backup RAM;" +}; + +localparam CONF_STR4 = { + "A,Save Backup RAM;", "-;", "O34,Aspect ratio,4:3,10:9,16:9;", "O78,Stereo mix,none,25%,50%,100%;", @@ -196,12 +205,14 @@ wire img_mounted; wire img_readonly; wire [63:0] img_size; -hps_io #(.STRLEN(($size(CONF_STR1)>>3) + ($size(CONF_STR2)>>3) + 1), .WIDE(1)) hps_io +wire [7:0] sav_char = sav_supported ? "R" : "+"; + +hps_io #(.STRLEN(($size(CONF_STR1)>>3) + ($size(CONF_STR2)>>3) + ($size(CONF_STR3)>>3) + ($size(CONF_STR4)>>3) + 3), .WIDE(1)) hps_io ( .clk_sys(clk_sys), .HPS_BUS(HPS_BUS), - .conf_str({CONF_STR1,status[1]?"F":"+",CONF_STR2}), + .conf_str({CONF_STR1,status[1]?"F":"+",CONF_STR2, sav_char, CONF_STR3, sav_char, CONF_STR4}), .ioctl_download(ioctl_download), .ioctl_wr(ioctl_wr), @@ -341,6 +352,9 @@ wire [6:0] mbc2_rom_bank = mbc_rom_bank_reg[6:0] & rom_mask[6:0]; //16 wire [6:0] mbc3_rom_bank = mbc_rom_bank_reg[6:0] & rom_mask[6:0]; //128 wire [8:0] mbc5_rom_bank = mbc_rom_bank_reg & rom_mask; //480 +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 ------------------ reg mbc_ram_enable; @@ -672,19 +686,32 @@ dpram #(16) cram_h ( wire downloading = cart_download; -reg bk_ena = 0; +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 - reg old_downloading = 0; - 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_size && !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]; -wire bk_save = status[10]; +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; diff --git a/sys/osd.v b/sys/osd.v index b973eaa..8a5de30 100644 --- a/sys/osd.v +++ b/sys/osd.v @@ -13,7 +13,8 @@ module osd input [23:0] din, output [23:0] dout, input de_in, - output reg de_out + output reg de_out, + output osd_status ); parameter OSD_COLOR = 3'd4; @@ -33,6 +34,8 @@ reg [11:0] infox; reg [21:0] infoy; reg [21:0] hrheight; +assign osd_status = osd_enable; + always@(posedge clk_sys) begin reg [11:0] bcnt; reg [7:0] cmd; diff --git a/sys/sys_top.v b/sys/sys_top.v index c28e2d4..6682a1c 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -749,7 +749,9 @@ osd hdmi_osd .din(hdmi_data_sl), .dout(HDMI_TX_D), .de_in(hdmi_de), - .de_out(HDMI_TX_DE) + .de_out(HDMI_TX_DE), + + .osd_status(osd_status) ); assign HDMI_MCLK = 0; @@ -937,6 +939,7 @@ wire uart_cts; wire uart_rts; wire uart_rxd; wire uart_txd; +wire osd_status; emu emu ( @@ -1009,7 +1012,9 @@ emu emu .UART_RXD(uart_txd), .UART_TXD(uart_rxd), .UART_DTR(uart_dsr), - .UART_DSR(uart_dtr) + .UART_DSR(uart_dtr), + + .OSD_STATUS(osd_status) ); endmodule