Updated RAM selection to use bit D7 of the EXXX and FXXX register, D7=1 is RAM, D7=0 is ROM

This commit is contained in:
Philip Smart
2026-04-02 09:35:13 +01:00
parent 4863dd122f
commit efcba04379

83
CPLD/v1.2/sfd700.vhd vendored
View File

@@ -112,8 +112,6 @@ architecture rtl of cpld128 is
signal EXXX_WR_SELni : std_logic;
signal FXXX_RD_SELni : std_logic;
signal FXXX_WR_SELni : std_logic;
signal RAMEN_RD_SELni : std_logic;
signal RAMEN_WR_SELni : std_logic;
signal MODE_RD_SELni : std_logic;
signal ROMINHSET_WR_SELni : std_logic;
signal ROMINHCLR_WR_SELni : std_logic;
@@ -131,11 +129,10 @@ architecture rtl of cpld128 is
signal REG_SIDE : std_logic;
signal REG_DDEN : std_logic;
signal REG_INT : std_logic;
signal REG_EXXX_PAGE : std_logic_vector(6 downto 0);
signal REG_FXXX_PAGE : std_logic_vector(6 downto 0);
signal REG_EXXX_PAGE : std_logic_vector(7 downto 0); -- D7 = RAM enable, D6:0 = page address.
signal REG_FXXX_PAGE : std_logic_vector(7 downto 0); -- D7 = RAM enable, D6:0 = page address.
signal REG_ROMDIS : std_logic;
signal REG_ROMINH : std_logic;
signal REG_RAMEN : std_logic;
-- Selected mode of the interface, ie. which machine it will be plugged into.
signal IFMODE : integer range 0 to 7 := 0;
@@ -149,7 +146,6 @@ architecture rtl of cpld128 is
signal INTEN_SYNC : std_logic := '1';
signal EXXX_WR_SYNC : std_logic := '1';
signal FXXX_WR_SYNC : std_logic := '1';
signal RAMEN_WR_SYNC : std_logic := '1';
signal ROMINHSET_WR_SYNC : std_logic := '1';
signal ROMINHCLR_WR_SYNC : std_logic := '1';
signal ROMDISSET_WR_SYNC : std_logic := '1';
@@ -206,7 +202,6 @@ begin
INTEN_SYNC <= '1';
EXXX_WR_SYNC <= '1';
FXXX_WR_SYNC <= '1';
RAMEN_WR_SYNC <= '1';
ROMINHSET_WR_SYNC <= '1';
ROMINHCLR_WR_SYNC <= '1';
ROMDISSET_WR_SYNC <= '1';
@@ -221,7 +216,6 @@ begin
INTEN_SYNC <= INTEN_SELni;
EXXX_WR_SYNC <= EXXX_WR_SELni;
FXXX_WR_SYNC <= FXXX_WR_SELni;
RAMEN_WR_SYNC <= RAMEN_WR_SELni;
ROMINHSET_WR_SYNC <= ROMINHSET_WR_SELni;
ROMINHCLR_WR_SYNC <= ROMINHCLR_WR_SELni;
ROMDISSET_WR_SYNC <= ROMDISSET_WR_SELni;
@@ -335,34 +329,33 @@ begin
end if;
end process;
-- Set FlashROM/RAM EXXX (E300:EFFF) page address. Each bank is 4K but due to the memory mapped I/O, only
-- E300:EFFF is useable in RFS.
-- A write t0 0x60 copies D6:0 into the EXXX page address register which selects a required 4K page in region E300:EFFF
-- Set FlashROM/RAM EXXX (E300:EFFF) page address and ROM/RAM select. Each bank is 4K but due to the
-- memory mapped I/O, only E300:EFFF is useable in RFS.
-- A write to 0x60: D7 = 1 selects RAM, D7 = 0 selects FlashROM; D6:0 = 4K page address.
SETEXXXPAGE: process( Z80_RESETn, CLK_16M )
variable EXXX_SEL_LASTni : std_logic;
begin
if(Z80_RESETn = '0') then
-- Customised UROM containing RFS start bank.
REG_EXXX_PAGE <= "0000010";
-- Customised UROM containing RFS start bank (page 2, ROM).
REG_EXXX_PAGE <= "00000010";
EXXX_SEL_LASTni := '1';
elsif(rising_edge(CLK_16M)) then
if(EXXX_WR_SYNC = '0' and EXXX_SEL_LASTni = '1') then
REG_EXXX_PAGE <= Z80_DATA_SYNC(6 downto 0);
REG_EXXX_PAGE <= Z80_DATA_SYNC;
end if;
EXXX_SEL_LASTni := EXXX_WR_SYNC;
end if;
end process;
-- Set FlashROM/RAM FXXX (F000:FFFF) page address.
-- A write to 0x61 copies D6:0 into the FXXX page address register which selects a 4K page
-- window of ROM/RAM accessible in the FXXX window.
-- Set FlashROM/RAM FXXX (F000:FFFF) page address and ROM/RAM select.
-- A write to 0x61: D7 = 1 selects RAM, D7 = 0 selects FlashROM; D6:0 = 4K page address.
SETFXXXPAGE: process( Z80_RESETn, CLK_16M )
variable FXXX_SEL_LASTni : std_logic;
variable RESET_DONE : std_logic;
begin
if(Z80_RESETn = '0') then
-- Initial page is set to 0, which is the MZ-80A AFI ROM. The original ROM is 2K so potential to add additional code in the upper block.
-- Initial page is set to 0 (ROM), which is the MZ-80A AFI ROM.
REG_FXXX_PAGE <= (others => '0');
FXXX_SEL_LASTni := '1';
RESET_DONE := '0';
@@ -373,15 +366,15 @@ begin
-- IFMODE is a synchronous register captured during reset, so it is stable here.
if(RESET_DONE = '0') then
RESET_DONE := '1';
-- MZ-700, starting at the second 4K page, set banking register to the block which stores the MZ-700 AFI ROM.
-- MZ-700, starting at the second 4K page (ROM), set banking register to the block which stores the MZ-700 AFI ROM.
if(IFMODE = MODE_MZ700) then
REG_FXXX_PAGE(1 downto 0) <= "01";
end if;
end if;
-- Set 4k F000:FFFF page address.
-- Set 4k F000:FFFF page address and ROM/RAM select.
if(FXXX_WR_SYNC = '0' and FXXX_SEL_LASTni = '1') then
REG_FXXX_PAGE <= Z80_DATA_SYNC(6 downto 0);
REG_FXXX_PAGE <= Z80_DATA_SYNC;
end if;
-- Edge detection.
@@ -389,23 +382,6 @@ begin
end if;
end process;
-- Enable FlashROM or RAM.
-- A write to 0x62 with D0 = low enables FlashROM, D0 = high enables RAM.
SETRAMEN: process( Z80_RESETn, CLK_16M )
variable RAMEN_SEL_LASTni: std_logic;
begin
if(Z80_RESETn = '0') then
REG_RAMEN <= '0';
RAMEN_SEL_LASTni := '1';
elsif(rising_edge(CLK_16M)) then
if(RAMEN_WR_SYNC = '0' and RAMEN_SEL_LASTni = '1') then
REG_RAMEN <= Z80_DATA_SYNC(0);
end if;
RAMEN_SEL_LASTni := RAMEN_WR_SYNC;
end if;
end process;
-- MZ-700/MZ-1500 paged memory logic. Detect the memory paging I/O operations and enable/disable access to the onboard FlashROM/RAM.
--
-- MZ-700 Memory Management Ports
@@ -460,13 +436,19 @@ begin
else '1';
MEM_FXXX_SELni <= '0' when Z80_MREQn = '0' and unsigned(Z80_ADDR(15 downto 8)) >= X"F0" and unsigned(Z80_ADDR(15 downto 8)) <= X"FF"
else '1';
ROM_SELni <= '0' when (IFMODE = MODE_MZ700 or IFMODE = MODE_MZ1500) and REG_ROMINH = '0' and REG_ROMDIS = '0' and REG_RAMEN = '0' and (MEM_EXXX_SELni = '0' or MEM_FXXX_SELni = '0')
-- ROM/RAM select is now per-region: bit 7 of REG_EXXX_PAGE/REG_FXXX_PAGE determines whether that
-- region maps to FlashROM (bit 7 = 0) or RAM (bit 7 = 1). Each region is independent.
ROM_SELni <= '0' when (IFMODE = MODE_MZ700 or IFMODE = MODE_MZ1500) and REG_ROMINH = '0' and REG_ROMDIS = '0'
and ((MEM_EXXX_SELni = '0' and REG_EXXX_PAGE(7) = '0') or (MEM_FXXX_SELni = '0' and REG_FXXX_PAGE(7) = '0'))
else
'0' when (IFMODE = MODE_MZ1200 or IFMODE = MODE_MZ80A) and REG_RAMEN = '0' and (MEM_EXXX_SELni = '0' or MEM_FXXX_SELni = '0')
'0' when (IFMODE = MODE_MZ1200 or IFMODE = MODE_MZ80A)
and ((MEM_EXXX_SELni = '0' and REG_EXXX_PAGE(7) = '0') or (MEM_FXXX_SELni = '0' and REG_FXXX_PAGE(7) = '0'))
else '1';
RAM_SELni <= '0' when (IFMODE = MODE_MZ700 or IFMODE = MODE_MZ1500) and REG_ROMINH = '0' and REG_ROMDIS = '0' and REG_RAMEN = '1' and (MEM_EXXX_SELni = '0' or MEM_FXXX_SELni = '0')
RAM_SELni <= '0' when (IFMODE = MODE_MZ700 or IFMODE = MODE_MZ1500) and REG_ROMINH = '0' and REG_ROMDIS = '0'
and ((MEM_EXXX_SELni = '0' and REG_EXXX_PAGE(7) = '1') or (MEM_FXXX_SELni = '0' and REG_FXXX_PAGE(7) = '1'))
else
'0' when (IFMODE = MODE_MZ1200 or IFMODE = MODE_MZ80A) and REG_RAMEN = '1' and (MEM_EXXX_SELni = '0' or MEM_FXXX_SELni = '0')
'0' when (IFMODE = MODE_MZ1200 or IFMODE = MODE_MZ80A)
and ((MEM_EXXX_SELni = '0' and REG_EXXX_PAGE(7) = '1') or (MEM_FXXX_SELni = '0' and REG_FXXX_PAGE(7) = '1'))
else '1';
-- I/O Port select.
@@ -488,10 +470,6 @@ begin
else '1';
FXXX_WR_SELni <= '0' when Z80_IORQn = '0' and Z80_WRn = '0' and unsigned(Z80_ADDR(7 downto 0)) = X"61"
else '1';
RAMEN_RD_SELni <= '0' when Z80_IORQn = '0' and Z80_RDn = '0' and unsigned(Z80_ADDR(7 downto 0)) = X"62"
else '1';
RAMEN_WR_SELni <= '0' when Z80_IORQn = '0' and Z80_WRn = '0' and unsigned(Z80_ADDR(7 downto 0)) = X"62"
else '1';
MODE_RD_SELni <= '0' when Z80_IORQn = '0' and Z80_RDn = '0' and unsigned(Z80_ADDR(7 downto 0)) = X"63"
else '1';
ROMINHSET_WR_SELni <= '0' when Z80_IORQn = '0' and Z80_WRn = '0' and unsigned(Z80_ADDR(7 downto 0)) = X"E5"
@@ -518,12 +496,13 @@ begin
ROM_CSn_REG <= ROM_SELni;
RAM_CSn_REG <= RAM_SELni;
-- Register the page address and output enable for non-FDC memory accesses.
-- Register the page address (D6:0) and output enable for non-FDC memory accesses.
-- Bit 7 is the ROM/RAM select and is not part of the address.
if(MEM_EXXX_SELni = '0') then
ID_REG <= REG_EXXX_PAGE & Z80_ADDR(11);
ID_REG <= REG_EXXX_PAGE(6 downto 0) & Z80_ADDR(11);
ID_OEn <= '0';
elsif(MEM_FXXX_SELni = '0') then
ID_REG <= REG_FXXX_PAGE & Z80_ADDR(11);
ID_REG <= REG_FXXX_PAGE(6 downto 0) & Z80_ADDR(11);
ID_OEn <= '0';
else
ID_OEn <= '1';
@@ -537,11 +516,9 @@ begin
-- Data bus control.
Z80_DATA <= not ID when FDC_SELni = '0' and Z80_WRn = '1' -- WD1773
else
'0' & REG_EXXX_PAGE when EXXX_RD_SELni = '0' -- EXXX Register contents.
REG_EXXX_PAGE when EXXX_RD_SELni = '0' -- EXXX Register: D7=RAM, D6:0=page.
else
'0' & REG_FXXX_PAGE when FXXX_RD_SELni = '0' -- FXXX Register contents.
else
"0000000" & REG_RAMEN when RAMEN_RD_SELni = '0' -- ROM/RAM Enable register contents.
REG_FXXX_PAGE when FXXX_RD_SELni = '0' -- FXXX Register: D7=RAM, D6:0=page.
else
"00000" & MODE when MODE_RD_SELni = '0' -- Configured mode.
else