Difference between revisions of "MBC1"
(→Behavior: add VHDL code) |
|||
Line 140: | Line 140: | ||
<pre> | <pre> | ||
+ | library IEEE; | ||
+ | use IEEE.std_logic_1164.all; | ||
+ | entity MBC1 is | ||
+ | Port( | ||
+ | RESET_N : in std_logic; | ||
+ | RD_N : in std_logic; | ||
+ | WR_N : in std_logic; | ||
+ | CS_N : in std_logic; | ||
+ | A : in std_logic_vector(15 downto 13); | ||
+ | D : in std_logic_vector(4 downto 0); | ||
+ | RA : out std_logic_vector(18 downto 14); | ||
+ | AA : out std_logic_vector(14 downto 13); | ||
+ | ROM_CS_N : out std_logic; | ||
+ | RAM_CS_N : out std_logic; | ||
+ | RAM_CS : out std_logic | ||
+ | ); | ||
+ | end entity MBC1; | ||
+ | |||
+ | architecture Behavioral of MBC1 is | ||
+ | |||
+ | signal ram_enable_r : std_logic_vector(3 downto 0); | ||
+ | signal rom_bank_r : std_logic_vector(4 downto 0); | ||
+ | signal ram_bank_r : std_logic_vector(1 downto 0); | ||
+ | signal mode_r : std_logic_vector(0 downto 0); | ||
+ | |||
+ | signal ram_enable_r_clk : std_logic; | ||
+ | signal rom_bank_r_clk : std_logic; | ||
+ | signal ram_bank_r_clk : std_logic; | ||
+ | signal mode_r_clk : std_logic; | ||
+ | |||
+ | begin | ||
+ | |||
+ | ROM_CS_N <= '0' when ((A(15) = '0' and RD_N = '0') or RESET_N = '0') else | ||
+ | '1'; | ||
+ | |||
+ | RAM_CS_N <= '0' when (CS_N = '0' and A(14) = '0' and ram_enable_r = x"A" and RESET_N = '1') else | ||
+ | '1'; | ||
+ | RAM_CS <= not RAM_CS_N; | ||
+ | |||
+ | RA(18 downto 14) <= "00000" when (A(14) = '0' or RESET_N = '0') else | ||
+ | rom_bank_r when (rom_bank_r /= "00000") else | ||
+ | "00001"; | ||
+ | |||
+ | AA(14 downto 13) <= "00" when (A(14) = '0' and mode_r = "0") else | ||
+ | ram_bank_r; | ||
+ | |||
+ | ram_enable_r_clk <= '0' when (A = "000" and WR_N = '0') else | ||
+ | '1'; | ||
+ | |||
+ | rom_bank_r_clk <= '0' when (A = "001" and WR_N = '0') else | ||
+ | '1'; | ||
+ | |||
+ | ram_bank_r_clk <= '0' when (A = "010" and WR_N = '0') else | ||
+ | '1'; | ||
+ | |||
+ | mode_r_clk <= '0' when (A = "011" and WR_N = '0') else | ||
+ | '1'; | ||
+ | |||
+ | ----------------------------------------------------------------------- | ||
+ | -- Registers | ||
+ | ----------------------------------------------------------------------- | ||
+ | |||
+ | ram_enable_p : process ( | ||
+ | RESET_N, | ||
+ | ram_enable_r_clk | ||
+ | ) | ||
+ | begin | ||
+ | |||
+ | if (RESET_N = '0') then | ||
+ | |||
+ | ram_enable_r <= x"0"; | ||
+ | |||
+ | elsif (rising_edge(ram_enable_r_clk)) then | ||
+ | |||
+ | ram_enable_r <= D(3 downto 0); | ||
+ | |||
+ | end if; | ||
+ | |||
+ | end process ram_enable_p; | ||
+ | |||
+ | rom_bank_p : process ( | ||
+ | RESET_N, | ||
+ | rom_bank_r_clk | ||
+ | ) | ||
+ | begin | ||
+ | |||
+ | if (RESET_N = '0') then | ||
+ | |||
+ | rom_bank_r <= "00000"; | ||
+ | |||
+ | elsif (rising_edge(rom_bank_r_clk)) then | ||
+ | |||
+ | rom_bank_r <= D; | ||
+ | |||
+ | end if; | ||
+ | |||
+ | end process rom_bank_p; | ||
+ | |||
+ | ram_bank_p : process ( | ||
+ | RESET_N, | ||
+ | ram_bank_r_clk | ||
+ | ) | ||
+ | begin | ||
+ | |||
+ | if (RESET_N = '0') then | ||
+ | |||
+ | ram_bank_r <= "00"; | ||
+ | |||
+ | elsif (rising_edge(ram_bank_r_clk)) then | ||
+ | |||
+ | ram_bank_r <= D(1 downto 0); | ||
+ | |||
+ | end if; | ||
+ | |||
+ | end process ram_bank_p; | ||
+ | |||
+ | mode_p : process ( | ||
+ | RESET_N, | ||
+ | mode_r_clk | ||
+ | ) | ||
+ | begin | ||
+ | |||
+ | if (RESET_N = '0') then | ||
+ | |||
+ | mode_r <= "0"; | ||
+ | |||
+ | elsif (rising_edge(mode_r_clk)) then | ||
+ | |||
+ | mode_r <= D(0 downto 0); | ||
+ | |||
+ | end if; | ||
+ | |||
+ | end process mode_p; | ||
+ | |||
+ | end architecture Behavioral; | ||
</pre> | </pre> | ||
Revision as of 01:10, 27 May 2015
Contents
MBC1
Nintendo's MBC1 can be used to address up to 16 Mbit of ROM and 256 kbit of SRAM, depending on the mode MBC1 is set to.
Pinout
Pin No. | Name | Type | Comment |
---|---|---|---|
24 | VCC | PWR | 5V supply |
14 | GND | PWR | Ground supply |
5Template:Ndash1 | D4Template:NdashD0 | I | Data Bus |
11 | RD | I | Low-Active Read Enable |
22 | WR | I | Low-Active Write Enable |
23 | CS | I | Low-Active Chip Select |
10 | RESET | I | Low-Active Asynchronous Reset |
21Template:Ndash19 | A15Template:NdashA13 | I | Address Bus |
18Template:Ndash14 | RA18Template:NdashRA14 | O | Upper ROM Address Lines |
7Template:Ndash6 | AA14Template:NdashAA13 | O | Upper ROM/RAM Address Lines |
8 | RAM_CS | O | Low-Active RAM Chip Select |
9 | RAM_CS | O | High-Active RAM Chip Select |
13 | ROM_CS | O | Low-Active ROM Chip Select |
Registers
Write-Accessible Registers:
- 0x0000-0x1FFF: RAM Enable register
- 0x2000-0x3FFF: ROM Bank register
- 0x4000-0x5FFF: RAM Bank register
- 0x6000-0x7FFF: Mode register
RAM Enable Register
XX XX XX XX D3 D2 D1 D0 0x00 @ reset \_________/ \-------- RAM Enable
A value of 0x0A enables SRAM access, all other values disable SRAM access.
ROM Bank Register
XX XX XX D4 D3 D2 D1 D0 0x00 @ reset \____________/ \-------- ROM Bank
ROM Bank selects which bank is mapped to 0x4000-0x7FFF. The written value is zero-adjusted before output on RA18Template:NdashRA14.
RAM Bank Register
XX XX XX XX XX XX D1 D0 0x00 @ reset \___/ \----- RAM Bank
RAM Bank selects which bank is mapped to 0xA000-0xBFFF when in mode 4 MBit/256 kbit. When in mode 16 Mbit/64 kbit, it can be used to select the upper two ROM address lines.
Mode Register
XX XX XX XX XX XX XX D0 0x00 @ reset \/ \--- Mode
The mode bit switches between 16 Mbit ROM/64 kbit SRAM mode ('0') and 4 Mbit ROM/256 kbit SRAM mode ('1'). When in 16 Mbit/64 kbit mode, address lines AA14Template:NdashAA13 switch according to A14. When in 4 Mbit/256 kbit mode, the upper address lines AA14Template:NdashAA13 stay fixed regardless of A14.
Behavior
library IEEE; use IEEE.std_logic_1164.all; entity MBC1 is Port( RESET_N : in std_logic; RD_N : in std_logic; WR_N : in std_logic; CS_N : in std_logic; A : in std_logic_vector(15 downto 13); D : in std_logic_vector(4 downto 0); RA : out std_logic_vector(18 downto 14); AA : out std_logic_vector(14 downto 13); ROM_CS_N : out std_logic; RAM_CS_N : out std_logic; RAM_CS : out std_logic ); end entity MBC1; architecture Behavioral of MBC1 is signal ram_enable_r : std_logic_vector(3 downto 0); signal rom_bank_r : std_logic_vector(4 downto 0); signal ram_bank_r : std_logic_vector(1 downto 0); signal mode_r : std_logic_vector(0 downto 0); signal ram_enable_r_clk : std_logic; signal rom_bank_r_clk : std_logic; signal ram_bank_r_clk : std_logic; signal mode_r_clk : std_logic; begin ROM_CS_N <= '0' when ((A(15) = '0' and RD_N = '0') or RESET_N = '0') else '1'; RAM_CS_N <= '0' when (CS_N = '0' and A(14) = '0' and ram_enable_r = x"A" and RESET_N = '1') else '1'; RAM_CS <= not RAM_CS_N; RA(18 downto 14) <= "00000" when (A(14) = '0' or RESET_N = '0') else rom_bank_r when (rom_bank_r /= "00000") else "00001"; AA(14 downto 13) <= "00" when (A(14) = '0' and mode_r = "0") else ram_bank_r; ram_enable_r_clk <= '0' when (A = "000" and WR_N = '0') else '1'; rom_bank_r_clk <= '0' when (A = "001" and WR_N = '0') else '1'; ram_bank_r_clk <= '0' when (A = "010" and WR_N = '0') else '1'; mode_r_clk <= '0' when (A = "011" and WR_N = '0') else '1'; ----------------------------------------------------------------------- -- Registers ----------------------------------------------------------------------- ram_enable_p : process ( RESET_N, ram_enable_r_clk ) begin if (RESET_N = '0') then ram_enable_r <= x"0"; elsif (rising_edge(ram_enable_r_clk)) then ram_enable_r <= D(3 downto 0); end if; end process ram_enable_p; rom_bank_p : process ( RESET_N, rom_bank_r_clk ) begin if (RESET_N = '0') then rom_bank_r <= "00000"; elsif (rising_edge(rom_bank_r_clk)) then rom_bank_r <= D; end if; end process rom_bank_p; ram_bank_p : process ( RESET_N, ram_bank_r_clk ) begin if (RESET_N = '0') then ram_bank_r <= "00"; elsif (rising_edge(ram_bank_r_clk)) then ram_bank_r <= D(1 downto 0); end if; end process ram_bank_p; mode_p : process ( RESET_N, mode_r_clk ) begin if (RESET_N = '0') then mode_r <= "0"; elsif (rising_edge(mode_r_clk)) then mode_r <= D(0 downto 0); end if; end process mode_p; end architecture Behavioral;