module cart (
  input              clk_in,           // system clock signal

  // Mapper config data.
  input       [39:0] cfg_in,           // cartridge config (from iNES header)
  input              cfg_upd_in,       // pulse signal on cfg_in update

  // PRG-ROM interface.
  input              prg_nce_in,       // prg-rom chip enable (active low)
  input       [14:0] prg_a_in,         // prg-rom address
  input              prg_r_nw_in,      // prg-rom read/write select
  input       [ 7:0] prg_d_in,         // prg-rom data in
  output      [ 7:0] prg_d_out,        // prg-rom data out

  // CHR-ROM interface.
  input       [13:0] chr_a_in,         // chr-rom address
  input              chr_r_nw_in,      // chr-rom read/write select
  input       [ 7:0] chr_d_in,         // chr-rom data in
  output      [ 7:0] chr_d_out,        // chr-rom data out
  output             ciram_nce_out,    // vram chip enable (active low)
  output             ciram_a10_out     // vram a10 value (controls mirroring)
);

wire        prgrom_bram_we;
wire [14:0] prgrom_bram_a;
wire [7:0]  prgrom_bram_dout;

// Block ram instance for PRG-ROM memory range (0x8000 - 0xFFFF).  Will eventually be
// replaced with SRAM.
single_port_ram_sync #(
  .ADDR_WIDTH   (15                   ),
  .DATA_WIDTH   (8                    ))
prgrom_bram     (
  .clk          (clk_in               ),
  .we           (prgrom_bram_we       ),
  .addr_a       (prgrom_bram_a        ),
  .din_a        (prg_d_in             ),
  .dout_a       (prgrom_bram_dout     )
);

assign prgrom_bram_we = (~prg_nce_in) ? ~prg_r_nw_in     : 1'b0;
assign prg_d_out      = (~prg_nce_in) ? prgrom_bram_dout : 8'h00;
assign prgrom_bram_a  = (cfg_in[33])  ? prg_a_in[14:0]   : { 1'b0, prg_a_in[13:0] };

wire       chrrom_pat_bram_we;
wire [7:0] chrrom_pat_bram_dout;

// Block ram instance for "CHR Pattern Table" memory range (0x0000 - 0x1FFF).
single_port_ram_sync #(
  .ADDR_WIDTH   (13                   ),
  .DATA_WIDTH   (8                    ))
chrrom_pat_bram (
  .clk          (clk_in               ),
  .we           (chrrom_pat_bram_we   ),
  .addr_a       (chr_a_in[12:0]       ),
  .din_a        (chr_d_in             ),
  .dout_a       (chrrom_pat_bram_dout )
);

assign ciram_nce_out      = ~chr_a_in[13];
assign ciram_a10_out      = (cfg_in[16])    ? chr_a_in[10] : chr_a_in[11];
assign chrrom_pat_bram_we = (ciram_nce_out) ? ~chr_r_nw_in : 1'b0;
assign chr_d_out          = (ciram_nce_out) ? chrrom_pat_bram_dout : 8'h00;

endmodule