Загрузить файлы в «/»

This commit is contained in:
Дима 2025-01-15 00:30:49 +03:00
parent 6ceab794e2
commit b751730f87
4 changed files with 695 additions and 0 deletions

30
divmmc.qpf Normal file
View File

@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2013 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 64-Bit
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 22:40:48 September 08, 2020
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.0"
DATE = "22:40:48 September 08, 2020"
# Revisions
PROJECT_REVISION = "divmmc"

124
divmmc.qsf Normal file
View File

@ -0,0 +1,124 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2013 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 64-Bit
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 22:40:48 September 08, 2020
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# divmmc_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
# 2) Altera recommends that you do not modify this file. This
# file is updated automatically by the Quartus II software
# and any changes you make may be lost or overwritten.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY MAX7000S
set_global_assignment -name DEVICE "EPM7128STC100-7"
set_global_assignment -name TOP_LEVEL_ENTITY divmmc
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "22:40:48 SEPTEMBER 08, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name VHDL_FILE divmmc.vhd
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
set_global_assignment -name POWER_EXT_SUPPLY_VOLTAGE_TO_REGULATOR 3.3V
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_location_assignment PIN_9 -to A[0]
set_location_assignment PIN_12 -to A[1]
set_location_assignment PIN_13 -to A[10]
set_location_assignment PIN_19 -to A[11]
set_location_assignment PIN_80 -to A[12]
set_location_assignment PIN_79 -to A[13]
set_location_assignment PIN_77 -to A[14]
set_location_assignment PIN_76 -to A[15]
set_location_assignment PIN_14 -to A[2]
set_location_assignment PIN_17 -to A[3]
set_location_assignment PIN_20 -to A[4]
set_location_assignment PIN_22 -to A[5]
set_location_assignment PIN_24 -to A[6]
set_location_assignment PIN_25 -to A[7]
set_location_assignment PIN_23 -to A[8]
set_location_assignment PIN_21 -to A[9]
set_location_assignment PIN_32 -to bankout[0]
set_location_assignment PIN_31 -to bankout[1]
set_location_assignment PIN_36 -to bankout[2]
set_location_assignment PIN_30 -to bankout[3]
set_location_assignment PIN_35 -to bankout[4]
set_location_assignment PIN_29 -to bankout[5]
set_location_assignment PIN_47 -to card[0]
set_location_assignment PIN_46 -to card[1]
set_location_assignment PIN_87 -to clock
set_location_assignment PIN_7 -to d[0]
set_location_assignment PIN_5 -to d[1]
set_location_assignment PIN_1 -to d[2]
set_location_assignment PIN_99 -to d[3]
set_location_assignment PIN_100 -to d[4]
set_location_assignment PIN_2 -to d[5]
set_location_assignment PIN_6 -to d[6]
set_location_assignment PIN_8 -to d[7]
set_location_assignment PIN_72 -to eprom
set_location_assignment PIN_81 -to iorq
set_location_assignment PIN_92 -to m1
set_location_assignment PIN_70 -to mapcondout
set_location_assignment PIN_10 -to mreq
set_location_assignment PIN_71 -to poweron
set_location_assignment PIN_98 -to ramoe
set_location_assignment PIN_28 -to ramwr
set_location_assignment PIN_83 -to rd
set_location_assignment PIN_85 -to reset
set_location_assignment PIN_75 -to romcs
set_location_assignment PIN_16 -to romoe
set_location_assignment PIN_27 -to romwr
set_location_assignment PIN_48 -to spi_clock
set_location_assignment PIN_50 -to spi_datain
set_location_assignment PIN_49 -to spi_dataout
set_location_assignment PIN_84 -to wr
set_location_assignment PIN_93 -to IORQGE
set_global_assignment -name SEARCH_PATH "h:\\zx\\cpld_project\\divmmc\\divmmc_cpld_v0\\output_files"

279
divmmc.vhd Normal file
View File

@ -0,0 +1,279 @@
----------------------------------------------------------------------------------
-- Inital version 1.0 for xc9572xl-vq64
-- Engineer: Mario Prato
-- Create Date: 10:07:18 11/22/2012
--
-- Modified for Altera EPM3128ATC100-10
-- Modified for Altera EPM7128STC100-7
-- Engineer: valerium
-- Design Name: divmmc ver. 1.1
-- Redesign Date: 02:54:18 10/05/2021
--
-- Module Name: divmmc - Behavioral
-- Project Name: divmmc
-- Target Devices: EPM3128ATC100-10
-- Target Devices: EPM7128STC100-7
-- Tool versions: Quartus II 13.0SP1
-- Description: zx spectrum mmc sd interface
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity divmmc is
Port (
-- z80 cpu signals
A : in std_logic_vector (15 downto 0);
D : inout std_logic_vector (7 downto 0);
iorq : in std_logic;
IORQGE : out STD_LOGIC;
mreq : in std_logic;
wr : in std_logic;
rd : in std_logic;
m1 : in std_logic;
reset : in std_logic;
clock : in std_logic; -- Z80 Clock from ula chip (must be negated from edge connector signal)
-- ram/rom signals
romcs : out STD_LOGIC; -- 1 -> page out spectrum rom
romoe : out STD_LOGIC; -- eeprom oe pin
romwr : out STD_LOGIC; -- eeprom wr pin
ramoe : out STD_LOGIC; -- ram oe pin
ramwr : out STD_LOGIC; -- ram wr pin
bankout : out STD_LOGIC_VECTOR (5 downto 0); --ram bank no.
-- spi interface
card : out std_logic_vector(1 downto 0) :="11"; -- Cards CS
spi_clock : out std_logic :='1'; -- card clock
spi_dataout : out std_logic :='1'; -- card data in
spi_datain : in std_logic :='1'; -- card data out
-- various
poweron : in STD_LOGIC; -- low pulse on poweron
eprom : in STD_LOGIC; -- eprom jumper
mapcondout : out std_logic -- hi when divmmc mem paged in
);
end divmmc;
-- ============================================================================================================
architecture Behavioral of divmmc is
signal address : std_logic_vector(7 downto 0) ;
signal zxmmcio : std_logic;
signal divideio : std_logic;
signal bank : std_logic_vector (5 downto 0) := "000000";
signal mapterm : std_logic := '0';
signal mapcond : std_logic := '0';
signal conmem : std_logic := '0';
signal mapram : std_logic := '0';
signal automap : std_logic := '0';
signal map3DXX : std_logic;
signal map1F00 : std_logic;
signal bank3 : std_logic;
-- Transmission states
type transStates is (
IDLE, -- Wait for a WR or RD request on port 0xEB
SAMPLE, -- As there is an I/O request, prepare the transmission; sample the CPU databus if required
TRANSMIT); -- Transmission (SEND or RECEIVE)
signal transState : transStates := IDLE; -- Transmission state (initially IDLE)
signal TState : unsigned(3 downto 0) := (others => '0'); -- Counts the T-States during transmission
signal fromSDByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte received from SD
signal toSDByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte to send to SD
signal toCPUByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte seen by the CPU after a byte read
-- dichiarazioni constanti
constant divide_control_port : std_logic_vector(7 downto 0) := x"E3"; -- port %11100011
constant zxmmc_control_port : std_logic_vector(7 downto 0) := x"E7"; -- era la porta 31 nella zxmmc+
constant zxmmc_spi_port : std_logic_vector(7 downto 0) := x"EB"; -- era la porta 63 nella zxmmc+
attribute PWR_MODE: string;
attribute FAST: string;
attribute BUFG: string;
-- ============================================================================================================
begin
address <= A(7 downto 0);
bank3 <= '1' when bank ="000011" else '0';
IORQGE <= '1' when (address = divide_control_port) OR (address = zxmmc_control_port) OR (address = zxmmc_spi_port) else 'Z';
-- IORQGE for exUSSR clone's on NemoBUS
-- (SL60, SL62 socked, like ISA slot in x386 machines)
-- Need Hi-Z or VCC pinOut state (VCC=Blocked all ports in ZX mainboard)
-- ROM read write signals
romoe <= rd or A(15) or A(14) or A(13) or (not conmem and mapram) or (not conmem and not automap) or (not conmem and eprom);
-- 5 OR Act.level=0; rd=0; A[15..13]=0; eprom=in_Pin;
romcs <= '1' when ((automap and not eprom) or (automap and mapram) or conmem )='1' else '0' ; -- RDR NemoBUS
-- 3 OR Act.level=0; conmem=; inv.eprom=in_Pin;
romwr <= '0' when wr ='0' and a(13)='0' and a(14)='0' and a(15)='0' and eprom='1' and conmem='1' else '1';
-- 6 AND Act.level=0; inv.pin; A[15..13]=0; wr=0; eprom=1; conmem=Q_DFF;
-- RAM read write signals
ramoe <= rd or A(15) or A(14) or ( not A(13) and not mapram) or ( not A(13) and conmem) or (not conmem and not automap) or (not conmem and eprom and not mapram);
ramwr <= wr or A(15) or A(14) or not a(13) or (not conmem and mapram and bank3 ) or (not conmem and not automap) or (not conmem and eprom and not mapram);
--
-- Divide Automapping logic
mapterm <= '1' when A(15 downto 0) = x"0000" or
A(15 downto 0) = x"0008" or
A(15 downto 0) = x"0038" or
A(15 downto 0) = x"0066" or
A(15 downto 0) = x"04c6" or
A(15 downto 0) = x"0562" else '0';
map3DXX <= '1' when A(15 downto 8) = "00111101" else '0'; -- mappa 3D00 - 3DFF
map1F00 <= '0' when A(15 downto 3) = "0001111111111" else '1'; -- 1ff8 - 1fff
-- ============================================================================================================
process(mreq)
begin
if falling_edge(mreq) then
if m1='0' then
mapcond <= mapterm or map3DXX or (mapcond and map1F00);
automap <= mapcond or map3DXX;
end if;
end if;
end process;
mapcondout <= mapcond; -- Q_DFF_mapcond=Pin_out;
-- divide control port
divideio <='0' when iorq='0' and wr='0' and M1='1' and address = divide_control_port else '1'; --divideio=CLK_DFF's
-- 4 AND m1=1; iorq=0; wr=0; A[7..0]=hE3 adr.
-- ============================================================================================================
process(divideio,poweron)
begin
-- if poweron ='0' then -- originally by M.Prato
if poweron ='0' or reset = '0' then -- patch by valerium
bank <= "000000";
mapram <= '0';
conmem <= '0';
elsif rising_edge(divideio) then
bank(5 downto 0) <= D(5 downto 0);
mapram <= D(6) or mapram;
conmem <= D(7);
end if;
end process;
-- ============================================================================================================
-- ram banks
bankout(0) <= bank(0) or not A(13); -- Bank = 8kB
bankout(1) <= bank(1) or not A(13);
bankout(2) <= bank(2) and A(13);
bankout(3) <= bank(3) and A(13);
bankout(4) <= bank(4) and A(13);
bankout(5) <= bank(5) and A(13);
-- SD CS signal management
zxmmcio <= '0' when address = zxmmc_control_port and iorq='0' and m1='1' and wr ='0' else '1';
process(reset, zxmmcio)
begin
if reset = '0' then
card(0) <= '1'; -- Master SD VCC= no active
card(1) <= '1'; -- Slave SD
elsif rising_edge(zxmmcio) then
card(0) <= D(0); -- Master SD
card(1) <= D(1); -- Slave SD
end if;
end process;
-- ============================================================================================================
-- spi transmission/reception
-- Update transmission state
process(clock, reset)
begin
if reset = '0' then
transState <= IDLE;
TState <= (others => '0');
fromSDByte <= (others => '1');
toSDByte <= (others => '1');
toCPUByte <= (others => '1');
elsif falling_edge(clock) then
case transState is
when IDLE => -- Intercept a new transmission request (port 0x3F)
if address = zxmmc_spi_port and iorq='0' and m1='1' then -- If there is a transmission request, prepare to SAMPLE the databus
transState <= SAMPLE;
end if;
when SAMPLE =>
if wr = '0' then -- If it is a SEND request, sample the CPU data bus
toSDByte <= D;
end if;
transState <= TRANSMIT; -- then start the transmission
when TRANSMIT =>
TState <= TState + 1;
if TState < 15 then
if TState(0) = '1' then
toSDByte <= toSDByte(6 downto 0)&'1';
fromSDByte <= fromSDByte(6 downto 0)& spi_datain;
end if;
else
if TState = 15 then -- transmission is completed; intercept if there is a new transmission request
if address = zxmmc_spi_port and iorq='0' and m1='1'and wr='0' then
toSDByte <= D;
transState <= TRANSMIT;
else -- else we'll go in IDLE state.
transState <= IDLE;
-- TState <= "0000";
end if;
toCPUByte <= fromSDByte(6 downto 0)& spi_datain;
end if;
end if;
when OTHERS =>
null;
end case;
end if;
-- SPI SD Card pins
SPI_clock <= TState(0);
spi_dataout <= toSDByte(7);
end process;
D <= toCPUByte when (address = zxmmc_spi_port) and (iorq = '0') and (rd = '0') and m1='1' else "ZZZZZZZZ";
-- ============================================================================================================
end Behavioral;

262
divmmc.vhd (orig) Normal file
View File

@ -0,0 +1,262 @@
----------------------------------------------------------------------------------
-- Inital version 1.0 for xc9572xl-vq64
-- Engineer: Mario Prato
-- Create Date: 10:07:18 11/22/2012
--
-- Modified for Altera EPM3128ATC100-10
-- Engineer: valerium
-- Design Name: divmmc ver. 1.1
-- Redesign Date: 02:54:18 10/05/2021
--
-- Module Name: divmmc - Behavioral
-- Project Name: divmmc
-- Target Devices: EPM3128ATC100-10
-- Tool versions: Quartus II 13.0SP1
-- Description: zx spectrum mmc sd interface
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity divmmc is
Port (
-- z80 cpu signals
A : in std_logic_vector (15 downto 0);
D : inout std_logic_vector (7 downto 0);
iorq : in std_logic;
mreq : in std_logic;
wr : in std_logic;
rd : in std_logic;
m1 : in std_logic;
reset : in std_logic;
clock : in std_logic; -- Z80 Clock from ula chip (must be negated from edge connector signal)
-- ram/rom signals
romcs : out STD_LOGIC; -- 1 -> page out spectrum rom
romoe : out STD_LOGIC; -- eeprom oe pin
romwr : out STD_LOGIC; -- eeprom wr pin
ramoe : out STD_LOGIC; -- ram oe pin
ramwr : out STD_LOGIC; -- ram wr pin
bankout : out STD_LOGIC_VECTOR (5 downto 0); --ram bank no.
-- spi interface
card : out std_logic_vector(1 downto 0) :="11"; -- Cards CS
spi_clock : out std_logic :='1'; -- card clock
spi_dataout : out std_logic :='1'; -- card data in
spi_datain : in std_logic :='1'; -- card data out
-- various
poweron : in STD_LOGIC; -- low pulse on poweron
eprom : in STD_LOGIC; -- eprom jumper
mapcondout : out std_logic -- hi when divmmc mem paged in
);
end divmmc;
architecture Behavioral of divmmc is
signal address : std_logic_vector(7 downto 0) ;
signal zxmmcio : std_logic;
signal divideio : std_logic;
signal bank : std_logic_vector (5 downto 0) := "000000";
signal mapterm : std_logic := '0';
signal mapcond : std_logic := '0';
signal conmem : std_logic := '0';
signal mapram : std_logic := '0';
signal automap : std_logic := '0';
signal map3DXX : std_logic;
signal map1F00 : std_logic;
signal bank3 : std_logic;
-- Transmission states
type transStates is (
IDLE, -- Wait for a WR or RD request on port 0xEB
SAMPLE, -- As there is an I/O request, prepare the transmission; sample the CPU databus if required
TRANSMIT); -- Transmission (SEND or RECEIVE)
signal transState : transStates := IDLE; -- Transmission state (initially IDLE)
signal TState : unsigned(3 downto 0) := (others => '0'); -- Counts the T-States during transmission
signal fromSDByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte received from SD
signal toSDByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte to send to SD
signal toCPUByte : std_logic_vector(7 downto 0) := (others => '1'); -- Byte seen by the CPU after a byte read
-- dichiarazioni constanti
constant divide_control_port : std_logic_vector(7 downto 0) := x"E3"; -- port %11100011
constant zxmmc_control_port : std_logic_vector(7 downto 0) := x"E7"; -- era la porta 31 nella zxmmc+
constant zxmmc_spi_port : std_logic_vector(7 downto 0) := x"EB"; -- era la porta 63 nella zxmmc+
attribute PWR_MODE: string;
attribute FAST: string;
attribute BUFG: string;
begin
address <= A(7 downto 0);
bank3 <= '1' when bank ="000011" else '0';
-- ROM RAM read write signals
romoe <= rd or A(15) or A(14) or A(13) or (not conmem and mapram) or (not conmem and not automap) or (not conmem and eprom);
romwr <= '0' when wr ='0' and a(13)='0' and a(14)='0' and a(15)='0' and eprom='1' and conmem='1' else '1';
ramoe <= rd or A(15) or A(14) or ( not A(13) and not mapram) or ( not A(13) and conmem) or (not conmem and not automap) or (not conmem and eprom and not mapram);
ramwr <= wr or A(15) or A(14) or not a(13) or (not conmem and mapram and bank3 ) or (not conmem and not automap) or (not conmem and eprom and not mapram);
romcs <= '1' when ((automap and not eprom) or (automap and mapram) or conmem )='1' else '0' ;
--
-- Divide Automapping logic
mapterm <= '1' when A(15 downto 0) = x"0000" or
A(15 downto 0) = x"0008" or
A(15 downto 0) = x"0038" or
A(15 downto 0) = x"0066" or
A(15 downto 0) = x"04c6" or
A(15 downto 0) = x"0562" else '0';
map3DXX <= '1' when A(15 downto 8) = "00111101" else '0'; -- mappa 3D00 - 3DFF
map1F00 <= '0' when A(15 downto 3) = "0001111111111" else '1'; -- 1ff8 - 1fff
process(mreq)
begin
if falling_edge(mreq) then
if m1='0' then
mapcond <= mapterm or map3DXX or (mapcond and map1F00);
automap <= mapcond or map3DXX;
end if;
end if;
end process;
mapcondout <= mapcond;
-- divide control port
divideio <='0' when iorq='0' and wr='0' and M1='1' and address = divide_control_port else '1';
process(divideio,poweron)
begin
-- if poweron ='0' then -- originally by M.Prato
if poweron ='0' or reset = '0' then -- patch by valerium
bank <= "000000";
mapram <= '0';
conmem <= '0';
elsif rising_edge(divideio) then
bank(5 downto 0) <= D(5 downto 0);
mapram <= D(6) or mapram;
conmem <= D(7);
end if;
end process;
-- ram banks
bankout(0) <= bank(0) or not A(13);
bankout(1) <= bank(1) or not A(13);
bankout(2) <= bank(2) and A(13);
bankout(3) <= bank(3) and A(13);
bankout(4) <= bank(4) and A(13);
bankout(5) <= bank(5) and A(13);
-- SD CS signal management
zxmmcio <= '0' when address = zxmmc_control_port and iorq='0' and m1='1' and wr ='0' else '1';
process(reset, zxmmcio)
begin
if reset = '0' then
card(0) <= '1';
card(1) <= '1';
elsif rising_edge(zxmmcio) then
card(0) <= D(0);
card(1) <= D(1);
end if;
end process;
-- spi transmission/reception
-- Update transmission state
process(clock, reset)
begin
if reset = '0' then
transState <= IDLE;
TState <= (others => '0');
fromSDByte <= (others => '1');
toSDByte <= (others => '1');
toCPUByte <= (others => '1');
elsif falling_edge(clock) then
case transState is
when IDLE => -- Intercept a new transmission request (port 0x3F)
if address = zxmmc_spi_port and iorq='0' and m1='1' then -- If there is a transmission request, prepare to SAMPLE the databus
transState <= SAMPLE;
end if;
when SAMPLE =>
if wr = '0' then -- If it is a SEND request, sample the CPU data bus
toSDByte <= D;
end if;
transState <= TRANSMIT; -- then start the transmission
when TRANSMIT =>
TState <= TState + 1;
if TState < 15 then
if TState(0) = '1' then
toSDByte <= toSDByte(6 downto 0)&'1';
fromSDByte <= fromSDByte(6 downto 0)& spi_datain;
end if;
else
if TState = 15 then -- transmission is completed; intercept if there is a new transmission request
if address = zxmmc_spi_port and iorq='0' and m1='1'and wr='0' then
toSDByte <= D;
transState <= TRANSMIT;
else -- else we'll go in IDLE state.
transState <= IDLE;
-- TState <= "0000";
end if;
toCPUByte <= fromSDByte(6 downto 0)& spi_datain;
end if;
end if;
when OTHERS =>
null;
end case;
end if;
-- SPI SD Card pins
SPI_clock <= TState(0);
spi_dataout <= toSDByte(7);
end process;
D <= toCPUByte when (address = zxmmc_spi_port) and (iorq = '0') and (rd = '0') and m1='1' else "ZZZZZZZZ";
end Behavioral;