aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-06-09 23:47:46 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-06-09 23:47:46 -0700
commit93bf8766459e27a558aa14cd0f77bd5d893e59e2 (patch)
treead1b658589f4ea1312f4941fd49914cf95d5b6d9
parent9daadfddc1d15ed413047f2c9290e184adca33b5 (diff)
downloadabc80-93bf8766459e27a558aa14cd0f77bd5d893e59e2.tar.gz
abc80-93bf8766459e27a558aa14cd0f77bd5d893e59e2.tar.xz
abc80-93bf8766459e27a558aa14cd0f77bd5d893e59e2.zip
Change from T80 to TV80.
Change from T80 (VHDL) to TV80 (Verilog). Doesn't work yet, for unknown reasons. Try to see if there are old bugs reintroduced in TV80?
-rw-r--r--abc80.v8
-rwxr-xr-x[-rw-r--r--]cfdisk.v8
-rwxr-xr-x[-rw-r--r--]keyboard.v6
-rw-r--r--t80/DebugSystem.vhd181
-rw-r--r--t80/DebugSystemXR.vhd185
-rw-r--r--t80/SSRAM.vhd94
-rw-r--r--t80/SSRAM2.vhd92
-rw-r--r--t80/SSRAMX.vhd132
-rw-r--r--t80/T16450.vhd459
-rw-r--r--t80/T80.vhd1078
-rw-r--r--t80/T8080se.vhd185
-rw-r--r--t80/T80_ALU.vhd351
-rw-r--r--t80/T80_MCode.vhd1937
-rw-r--r--t80/T80_Pack.vhd210
-rw-r--r--t80/T80_Reg.vhd105
-rw-r--r--t80/T80_RegX.vhd167
-rw-r--r--t80/T80a.vhd255
-rw-r--r--t80/T80s.vhd192
-rw-r--r--t80/T80se.vhd186
-rw-r--r--tv80/tv80_alu.v442
-rwxr-xr-xtv80/tv80_core.v1360
-rw-r--r--tv80/tv80_mcode.v2657
-rw-r--r--tv80/tv80_reg.v71
-rw-r--r--tv80/tv80n.v182
-rwxr-xr-xtv80/tv80s.v162
-rwxr-xr-xtv80/tv80se.v163
26 files changed, 5048 insertions, 5820 deletions
diff --git a/abc80.v b/abc80.v
index df44609..f26d08e 100644
--- a/abc80.v
+++ b/abc80.v
@@ -1097,9 +1097,9 @@ module abc80 (
end
endcase // case( cpu_turbo )
- T80se cpu (
- .clk_n ( cpu_clk ),
- .clken ( cpu_clk_en ),
+ tv80se cpu (
+ .clk ( cpu_clk ),
+ .cen ( cpu_clk_en ),
.reset_n ( rst_n ),
.wait_n ( cpu_wait_n ),
.int_n ( cpu_int_n ),
@@ -1114,7 +1114,7 @@ module abc80 (
.wr_n ( cpu_wr_n ),
.rfsh_n ( cpu_rfsh_n ),
.halt_n ( cpu_halt_n ),
- .a ( cpu_a ),
+ .A ( cpu_a ),
.di ( cpu_di ),
.do ( cpu_do )
);
diff --git a/cfdisk.v b/cfdisk.v
index c8274bf..a7a6922 100644..100755
--- a/cfdisk.v
+++ b/cfdisk.v
@@ -141,10 +141,10 @@ module cfcontroller(
reg cpu_int_n;
reg cpu_nmi_n;
- T80se cf_cpu (
- .clk_n ( clk ),
+ tv80se cf_cpu (
+ .clk ( clk ),
.reset_n ( ~ireset ),
- .clken ( cf_cpu_wait_n ),
+ .cen ( cf_cpu_wait_n ),
.wait_n ( 1 ),
.int_n ( cpu_int_n ),
.nmi_n ( cpu_nmi_n ),
@@ -154,7 +154,7 @@ module cfcontroller(
.iorq_n ( cpu_iorq_n ),
.rd_n ( cpu_rd_n ),
.wr_n ( cpu_wr_n ),
- .a ( cpu_a ),
+ .A ( cpu_a ),
.di ( cpu_di ),
.do ( cpu_do )
);
diff --git a/keyboard.v b/keyboard.v
index 5803e5b..ae83f7e 100644..100755
--- a/keyboard.v
+++ b/keyboard.v
@@ -63,8 +63,8 @@ module keyboard (
wire [7:0] cpu_di;
wire [7:0] cpu_do;
- T80s kbd_cpu (
- .clk_n ( clkin ),
+ tv80s kbd_cpu (
+ .clk ( clkin ),
.reset_n ( reset_n ),
.wait_n ( 1 ),
.int_n ( 1 ),
@@ -75,7 +75,7 @@ module keyboard (
.iorq_n ( cpu_iorq_n ),
.rd_n ( cpu_rd_n ),
.wr_n ( cpu_wr_n ),
- .a ( cpu_a ),
+ .A ( cpu_a ),
.di ( cpu_di ),
.do ( cpu_do )
);
diff --git a/t80/DebugSystem.vhd b/t80/DebugSystem.vhd
deleted file mode 100644
index c11663b..0000000
--- a/t80/DebugSystem.vhd
+++ /dev/null
@@ -1,181 +0,0 @@
--- Z80, Monitor ROM, 4k RAM and two 16450 UARTs
--- that can be synthesized and used with
--- the NoICE debugger that can be found at
--- http://www.noicedebugger.com/
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-
-entity DebugSystem is
- port(
- Reset_n : in std_logic;
- Clk : in std_logic;
- NMI_n : in std_logic;
- RXD0 : in std_logic;
- CTS0 : in std_logic;
- DSR0 : in std_logic;
- RI0 : in std_logic;
- DCD0 : in std_logic;
- RXD1 : in std_logic;
- CTS1 : in std_logic;
- DSR1 : in std_logic;
- RI1 : in std_logic;
- DCD1 : in std_logic;
- TXD0 : out std_logic;
- RTS0 : out std_logic;
- DTR0 : out std_logic;
- TXD1 : out std_logic;
- RTS1 : out std_logic;
- DTR1 : out std_logic
- );
-end DebugSystem;
-
-architecture struct of DebugSystem is
-
- signal M1_n : std_logic;
- signal MREQ_n : std_logic;
- signal IORQ_n : std_logic;
- signal RD_n : std_logic;
- signal WR_n : std_logic;
- signal RFSH_n : std_logic;
- signal HALT_n : std_logic;
- signal WAIT_n : std_logic;
- signal INT_n : std_logic;
- signal RESET_s : std_logic;
- signal BUSRQ_n : std_logic;
- signal BUSAK_n : std_logic;
- signal A : std_logic_vector(15 downto 0);
- signal D : std_logic_vector(7 downto 0);
- signal ROM_D : std_logic_vector(7 downto 0);
- signal SRAM_D : std_logic_vector(7 downto 0);
- signal UART0_D : std_logic_vector(7 downto 0);
- signal UART1_D : std_logic_vector(7 downto 0);
- signal CPU_D : std_logic_vector(7 downto 0);
-
- signal Mirror : std_logic;
-
- signal IOWR_n : std_logic;
- signal RAMCS_n : std_logic;
- signal UART0CS_n : std_logic;
- signal UART1CS_n : std_logic;
-
- signal BaudOut0 : std_logic;
- signal BaudOut1 : std_logic;
-
-begin
-
- Wait_n <= '1';
- BusRq_n <= '1';
- INT_n <= '1';
-
- process (Reset_n, Clk)
- begin
- if Reset_n = '0' then
- Reset_s <= '0';
- Mirror <= '0';
- elsif Clk'event and Clk = '1' then
- Reset_s <= '1';
- if IORQ_n = '0' and A(7 downto 4) = "1111" then
- Mirror <= D(0);
- end if;
- end if;
- end process;
-
- IOWR_n <= WR_n or IORQ_n;
- RAMCS_n <= (not Mirror and not A(15)) or MREQ_n;
- UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1';
- UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1';
-
- CPU_D <=
- SRAM_D when RAMCS_n = '0' else
- UART0_D when UART0CS_n = '0' else
- UART1_D when UART1CS_n = '0' else
- ROM_D;
-
- u0 : entity work.T80s
- generic map(Mode => 1, T2Write => 1, IOWait => 0)
- port map(
- RESET_n => RESET_s,
- CLK_n => Clk,
- WAIT_n => WAIT_n,
- INT_n => INT_n,
- NMI_n => NMI_n,
- BUSRQ_n => BUSRQ_n,
- M1_n => M1_n,
- MREQ_n => MREQ_n,
- IORQ_n => IORQ_n,
- RD_n => RD_n,
- WR_n => WR_n,
- RFSH_n => RFSH_n,
- HALT_n => HALT_n,
- BUSAK_n => BUSAK_n,
- A => A,
- DI => CPU_D,
- DO => D);
-
- u1 : entity work.MonZ80
- port map(
- Clk => Clk,
- A => A(10 downto 0),
- D => ROM_D);
-
- u2 : entity work.SSRAM
- generic map(
- AddrWidth => 12)
- port map(
- Clk => Clk,
- CE_n => RAMCS_n,
- WE_n => WR_n,
- A => A(11 downto 0),
- DIn => D,
- DOut => SRAM_D);
-
- u3 : entity work.T16450
- port map(
- MR_n => Reset_s,
- XIn => Clk,
- RClk => BaudOut0,
- CS_n => UART0CS_n,
- Rd_n => RD_n,
- Wr_n => IOWR_n,
- A => A(2 downto 0),
- D_In => D,
- D_Out => UART0_D,
- SIn => RXD0,
- CTS_n => CTS0,
- DSR_n => DSR0,
- RI_n => RI0,
- DCD_n => DCD0,
- SOut => TXD0,
- RTS_n => RTS0,
- DTR_n => DTR0,
- OUT1_n => open,
- OUT2_n => open,
- BaudOut => BaudOut0,
- Intr => open);
-
- u4 : entity work.T16450
- port map(
- MR_n => Reset_s,
- XIn => Clk,
- RClk => BaudOut1,
- CS_n => UART1CS_n,
- Rd_n => RD_n,
- Wr_n => IOWR_n,
- A => A(2 downto 0),
- D_In => D,
- D_Out => UART1_D,
- SIn => RXD1,
- CTS_n => CTS1,
- DSR_n => DSR1,
- RI_n => RI1,
- DCD_n => DCD1,
- SOut => TXD1,
- RTS_n => RTS1,
- DTR_n => DTR1,
- OUT1_n => open,
- OUT2_n => open,
- BaudOut => BaudOut1,
- Intr => open);
-
-end;
diff --git a/t80/DebugSystemXR.vhd b/t80/DebugSystemXR.vhd
deleted file mode 100644
index ca8fa87..0000000
--- a/t80/DebugSystemXR.vhd
+++ /dev/null
@@ -1,185 +0,0 @@
--- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs
--- that can be synthesized and used with
--- the NoICE debugger that can be found at
--- http://www.noicedebugger.com/
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-
-entity DebugSystemXR is
- port(
- Reset_n : in std_logic;
- Clk : in std_logic;
- NMI_n : in std_logic;
- OE_n : out std_logic;
- WE_n : out std_logic;
- RAMCS_n : out std_logic;
- ROMCS_n : out std_logic;
- PGM_n : out std_logic;
- A : out std_logic_vector(16 downto 0);
- D : inout std_logic_vector(7 downto 0);
- RXD0 : in std_logic;
- CTS0 : in std_logic;
- DSR0 : in std_logic;
- RI0 : in std_logic;
- DCD0 : in std_logic;
- RXD1 : in std_logic;
- CTS1 : in std_logic;
- DSR1 : in std_logic;
- RI1 : in std_logic;
- DCD1 : in std_logic;
- TXD0 : out std_logic;
- RTS0 : out std_logic;
- DTR0 : out std_logic;
- TXD1 : out std_logic;
- RTS1 : out std_logic;
- DTR1 : out std_logic
- );
-end entity DebugSystemXR;
-
-architecture struct of DebugSystemXR is
-
- signal M1_n : std_logic;
- signal MREQ_n : std_logic;
- signal IORQ_n : std_logic;
- signal RD_n : std_logic;
- signal WR_n : std_logic;
- signal RFSH_n : std_logic;
- signal HALT_n : std_logic;
- signal WAIT_n : std_logic;
- signal INT_n : std_logic;
- signal RESET_s : std_logic;
- signal BUSRQ_n : std_logic;
- signal BUSAK_n : std_logic;
- signal A_i : std_logic_vector(15 downto 0);
- signal D_i : std_logic_vector(7 downto 0);
- signal ROM_D : std_logic_vector(7 downto 0);
- signal UART0_D : std_logic_vector(7 downto 0);
- signal UART1_D : std_logic_vector(7 downto 0);
- signal CPU_D : std_logic_vector(7 downto 0);
-
- signal Mirror : std_logic;
-
- signal IOWR_n : std_logic;
- signal RAMCS_n_i : std_logic;
- signal UART0CS_n : std_logic;
- signal UART1CS_n : std_logic;
-
- signal BaudOut0 : std_logic;
- signal BaudOut1 : std_logic;
-
-begin
-
- Wait_n <= '1';
- BusRq_n <= '1';
- INT_n <= '1';
-
- OE_n <= RD_n;
- WE_n <= WR_n;
- RAMCS_n <= RAMCS_n_i;
- ROMCS_n <= '1';
- PGM_n <= '1';
- A(14 downto 0) <= A_i(14 downto 0);
- A(16 downto 15) <= "00";
- D <= D_i when WR_n = '0' else "ZZZZZZZZ";
-
- process (Reset_n, Clk)
- begin
- if Reset_n = '0' then
- Reset_s <= '0';
- Mirror <= '0';
- elsif Clk'event and Clk = '1' then
- Reset_s <= '1';
- if IORQ_n = '0' and A_i(7 downto 4) = "1111" then
- Mirror <= D_i(0);
- end if;
- end if;
- end process;
-
- IOWR_n <= WR_n or IORQ_n;
- RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n;
- UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1';
- UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1';
-
- CPU_D <=
- D when RAMCS_n_i = '0' else
- UART0_D when UART0CS_n = '0' else
- UART1_D when UART1CS_n = '0' else
- ROM_D;
-
- u0 : entity work.T80s
- generic map(Mode => 1, T2Write => 1, IOWait => 0)
- port map(
- RESET_n => RESET_s,
- CLK_n => Clk,
- WAIT_n => WAIT_n,
- INT_n => INT_n,
- NMI_n => NMI_n,
- BUSRQ_n => BUSRQ_n,
- M1_n => M1_n,
- MREQ_n => MREQ_n,
- IORQ_n => IORQ_n,
- RD_n => RD_n,
- WR_n => WR_n,
- RFSH_n => RFSH_n,
- HALT_n => HALT_n,
- BUSAK_n => BUSAK_n,
- A => A_i,
- DI => CPU_D,
- DO => D_i);
-
- u1 : entity work.MonZ80
- port map(
- Clk => Clk,
- A => A_i(10 downto 0),
- D => ROM_D);
-
- u3 : entity work.T16450
- port map(
- MR_n => Reset_s,
- XIn => Clk,
- RClk => BaudOut0,
- CS_n => UART0CS_n,
- Rd_n => RD_n,
- Wr_n => IOWR_n,
- A => A_i(2 downto 0),
- D_In => D_i,
- D_Out => UART0_D,
- SIn => RXD0,
- CTS_n => CTS0,
- DSR_n => DSR0,
- RI_n => RI0,
- DCD_n => DCD0,
- SOut => TXD0,
- RTS_n => RTS0,
- DTR_n => DTR0,
- OUT1_n => open,
- OUT2_n => open,
- BaudOut => BaudOut0,
- Intr => open);
-
- u4 : entity work.T16450
- port map(
- MR_n => Reset_s,
- XIn => Clk,
- RClk => BaudOut1,
- CS_n => UART1CS_n,
- Rd_n => RD_n,
- Wr_n => IOWR_n,
- A => A_i(2 downto 0),
- D_In => D_i,
- D_Out => UART1_D,
- SIn => RXD1,
- CTS_n => CTS1,
- DSR_n => DSR1,
- RI_n => RI1,
- DCD_n => DCD1,
- SOut => TXD1,
- RTS_n => RTS1,
- DTR_n => DTR1,
- OUT1_n => open,
- OUT2_n => open,
- BaudOut => BaudOut1,
- Intr => open);
-
-end;
diff --git a/t80/SSRAM.vhd b/t80/SSRAM.vhd
deleted file mode 100644
index 5d59eb8..0000000
--- a/t80/SSRAM.vhd
+++ /dev/null
@@ -1,94 +0,0 @@
---
--- Inferrable Synchronous SRAM for XST synthesis
---
--- Version : 0220
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t51/
---
--- Limitations :
---
--- File history :
--- 0208 : Initial release
--- 0218 : Fixed data out at write
--- 0220 : Added support for XST
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity SSRAM is
- generic(
- AddrWidth : integer := 11;
- DataWidth : integer := 8
- );
- port(
- Clk : in std_logic;
- CE_n : in std_logic;
- WE_n : in std_logic;
- A : in std_logic_vector(AddrWidth - 1 downto 0);
- DIn : in std_logic_vector(DataWidth - 1 downto 0);
- DOut : out std_logic_vector(DataWidth - 1 downto 0)
- );
-end SSRAM;
-
-architecture behaviour of SSRAM is
-
- type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
- signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
- signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
- signal B : std_logic_vector(AddrWidth - 1 downto 0);
-
-begin
-
- process (Clk)
- begin
- if Clk'event and Clk = '1' then
- if (CE_n nor WE_n) = '1' then
- RAM(to_integer(unsigned(B))) <= DIn;
- end if;
- A_r <= A;
- B <= A;
- end if;
- end process;
-
- DOut <= RAM(to_integer(unsigned(A_r)))
--- pragma translate_off
- when not is_x(A_r) else (others => '-')
--- pragma translate_on
- ;
-end;
diff --git a/t80/SSRAM2.vhd b/t80/SSRAM2.vhd
deleted file mode 100644
index 98c0c2c..0000000
--- a/t80/SSRAM2.vhd
+++ /dev/null
@@ -1,92 +0,0 @@
---
--- Inferrable Synchronous SRAM for Leonardo synthesis, no write through!
---
--- Version : 0236
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t51/
---
--- Limitations :
---
--- File history :
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity SSRAM is
- generic(
- AddrWidth : integer := 16;
- DataWidth : integer := 8
- );
- port(
- Clk : in std_logic;
- CE_n : in std_logic;
- WE_n : in std_logic;
- A : in std_logic_vector(AddrWidth - 1 downto 0);
- DIn : in std_logic_vector(DataWidth - 1 downto 0);
- DOut : out std_logic_vector(DataWidth - 1 downto 0)
- );
-end SSRAM;
-
-architecture behaviour of SSRAM is
-
- type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
- signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
- signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
-
-begin
-
- process (Clk)
- begin
- if Clk'event and Clk = '1' then
--- pragma translate_off
- if not is_x(A) then
--- pragma translate_on
- DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0))));
--- pragma translate_off
- end if;
--- pragma translate_on
- if CE_n = '0' and WE_n = '0' then
- RAM(to_integer(unsigned(A_r))) <= DIn;
- end if;
- A_r <= A;
- end if;
- end process;
-
-end;
diff --git a/t80/SSRAMX.vhd b/t80/SSRAMX.vhd
deleted file mode 100644
index 474a6ff..0000000
--- a/t80/SSRAMX.vhd
+++ /dev/null
@@ -1,132 +0,0 @@
---
--- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes)
---
--- Version : 0247
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t51/
---
--- Limitations :
---
--- File history :
---
--- 0240 : Initial release
---
--- 0242 : Changed RAMB4_S8 to map by name
---
--- 0247 : Added RAMB4_S8 component declaration
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity SSRAM is
- generic(
- AddrWidth : integer := 11;
- DataWidth : integer := 8
- );
- port(
- Clk : in std_logic;
- CE_n : in std_logic;
- WE_n : in std_logic;
- A : in std_logic_vector(AddrWidth - 1 downto 0);
- DIn : in std_logic_vector(DataWidth - 1 downto 0);
- DOut : out std_logic_vector(DataWidth - 1 downto 0)
- );
-end SSRAM;
-
-architecture rtl of SSRAM is
-
- component RAMB4_S8
- port(
- DO : out std_logic_vector(7 downto 0);
- ADDR : in std_logic_vector(8 downto 0);
- CLK : in std_ulogic;
- DI : in std_logic_vector(7 downto 0);
- EN : in std_ulogic;
- RST : in std_ulogic;
- WE : in std_ulogic);
- end component;
-
- constant RAMs : integer := (2 ** AddrWidth) / 512;
-
- type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0);
-
- signal bRAMOut : bRAMOut_a;
- signal biA_r : integer;
- signal A_r : unsigned(A'left downto 0);
- signal A_i : std_logic_vector(8 downto 0);
- signal WEA : std_logic_vector(RAMs - 1 downto 0);
-
-begin
-
- process (Clk)
- begin
- if Clk'event and Clk = '1' then
- A_r <= unsigned(A);
- end if;
- end process;
-
- biA_r <= to_integer(A_r(A'left downto 9));
- A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0);
-
- bG1: for I in 0 to RAMs - 1 generate
- begin
- WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0';
- BSSRAM : RAMB4_S8
- port map(
- DI => DIn,
- EN => '1',
- WE => WEA(I),
- RST => '0',
- CLK => Clk,
- ADDR => A_i,
- DO => bRAMOut(I));
- end generate;
-
- process (biA_r, bRAMOut)
- begin
- DOut <= bRAMOut(0);
- for I in 1 to RAMs - 1 loop
- if biA_r = I then
- DOut <= bRAMOut(I);
- end if;
- end loop;
- end process;
-
-end;
diff --git a/t80/T16450.vhd b/t80/T16450.vhd
deleted file mode 100644
index ad266c2..0000000
--- a/t80/T16450.vhd
+++ /dev/null
@@ -1,459 +0,0 @@
---
--- 16450 compatible UART with synchronous bus interface
--- RClk/BaudOut is XIn enable instead of actual clock
---
--- Version : 0249b
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0208 : First release
---
--- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer
--- Added modem status and break detection
--- Added support for 1.5 and 2 stop bits
---
--- 0249b : Fixed loopback break generation bugs found by Andy Dyer
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity T16450 is
- port(
- MR_n : in std_logic;
- XIn : in std_logic;
- RClk : in std_logic;
- CS_n : in std_logic;
- Rd_n : in std_logic;
- Wr_n : in std_logic;
- A : in std_logic_vector(2 downto 0);
- D_In : in std_logic_vector(7 downto 0);
- D_Out : out std_logic_vector(7 downto 0);
- SIn : in std_logic;
- CTS_n : in std_logic;
- DSR_n : in std_logic;
- RI_n : in std_logic;
- DCD_n : in std_logic;
- SOut : out std_logic;
- RTS_n : out std_logic;
- DTR_n : out std_logic;
- OUT1_n : out std_logic;
- OUT2_n : out std_logic;
- BaudOut : out std_logic;
- Intr : out std_logic
- );
-end T16450;
-
-architecture rtl of T16450 is
-
- signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register
- signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register
- signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register
- signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register
- signal LCR : std_logic_vector(7 downto 0); -- Line Control Register
- signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register
- signal LSR : std_logic_vector(7 downto 0); -- Line Status Register
- signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register
- signal SCR : std_logic_vector(7 downto 0); -- Scratch Register
- signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS)
- signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS)
-
- signal DM0 : std_logic_vector(7 downto 0);
- signal DM1 : std_logic_vector(7 downto 0);
-
- signal MSR_In : std_logic_vector(3 downto 0);
-
- signal Bit_Phase : unsigned(3 downto 0);
- signal Brk_Cnt : unsigned(3 downto 0);
- signal RX_Filtered : std_logic;
- signal RX_ShiftReg : std_logic_vector(7 downto 0);
- signal RX_Bit_Cnt : integer range 0 to 11;
- signal RX_Parity : std_logic;
- signal RXD : std_logic;
-
- signal TX_Tick : std_logic;
- signal TX_ShiftReg : std_logic_vector(7 downto 0);
- signal TX_Bit_Cnt : integer range 0 to 11;
- signal TX_Parity : std_logic;
- signal TX_Next_Is_Stop : std_logic;
- signal TX_Stop_Bit : std_logic;
- signal TXD : std_logic;
-
-begin
-
- DTR_n <= MCR(4) or not MCR(0);
- RTS_n <= MCR(4) or not MCR(1);
- OUT1_n <= MCR(4) or not MCR(2);
- OUT2_n <= MCR(4) or not MCR(3);
- SOut <= MCR(4) or (TXD and not LCR(6));
- RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6));
-
- Intr <= not IIR(0);
-
- -- Registers
- DM0 <= DLL when LCR(7) = '1' else RBR;
- DM1 <= DLM when LCR(7) = '1' else IER;
- with A select
- D_Out <=
- DM0 when "000",
- DM1 when "001",
- IIR when "010",
- LCR when "011",
- MCR when "100",
- LSR when "101",
- MSR when "110",
- SCR when others;
- process (MR_n, XIn)
- begin
- if MR_n = '0' then
- THR <= "00000000";
- IER <= "00000000";
- LCR <= "00000000";
- MCR <= "00000000";
- MSR(3 downto 0) <= "0000";
- SCR <= "00000000"; -- ??
- DLL <= "00000000"; -- ??
- DLM <= "00000000"; -- ??
- elsif XIn'event and XIn = '1' then
- if Wr_n = '0' and CS_n = '0' then
- case A is
- when "000" =>
- if LCR(7) = '1' then
- DLL <= D_In;
- else
- THR <= D_In;
- end if;
- when "001" =>
- if LCR(7) = '1' then
- DLM <= D_In;
- else
- IER(3 downto 0) <= D_In(3 downto 0);
- end if;
- when "011" =>
- LCR <= D_In;
- when "100" =>
- MCR <= D_In;
- when "111" =>
- SCR <= D_In;
- when others =>
- end case;
- end if;
- if Rd_n = '0' and CS_n = '0' and A = "110" then
- MSR(3 downto 0) <= "0000";
- end if;
- if MSR(4) /= MSR_In(0) then
- MSR(0) <= '1';
- end if;
- if MSR(5) /= MSR_In(1) then
- MSR(1) <= '1';
- end if;
- if MSR(6) = '0' and MSR_In(2) = '1' then
- MSR(2) <= '1';
- end if;
- if MSR(7) /= MSR_In(3) then
- MSR(3) <= '1';
- end if;
- end if;
- end process;
- process (XIn)
- begin
- if XIn'event and XIn = '1' then
- if MCR(4) = '0' then
- MSR(4) <= MSR_In(0);
- MSR(5) <= MSR_In(1);
- MSR(6) <= MSR_In(2);
- MSR(7) <= MSR_In(3);
- else
- MSR(4) <= MCR(1);
- MSR(5) <= MCR(0);
- MSR(6) <= MCR(2);
- MSR(7) <= MCR(3);
- end if;
- MSR_In(0) <= CTS_n;
- MSR_In(1) <= DSR_n;
- MSR_In(2) <= RI_n;
- MSR_In(3) <= DCD_n;
- end if;
- end process;
-
- IIR(7 downto 3) <= "00000";
- IIR(2 downto 0) <=
- "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else
- "100" when (IER(0) and LSR(0)) = '1' else
- "010" when (IER(1) and LSR(5)) = '1' else
- "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or
- (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else
- "001";
-
- -- Baud x 16 clock generator
- process (MR_n, XIn)
- variable Baud_Cnt : unsigned(15 downto 0);
- begin
- if MR_n = '0' then
- Baud_Cnt := "0000000000000000";
- BaudOut <= '0';
- elsif XIn'event and XIn = '1' then
- if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then
- Baud_Cnt(15 downto 8) := unsigned(DLM);
- Baud_Cnt(7 downto 0) := unsigned(DLL);
- BaudOut <= '1';
- else
- Baud_Cnt := Baud_Cnt - 1;
- BaudOut <= '0';
- end if;
- end if;
- end process;
-
- -- Input filter
- process (MR_n, XIn)
- variable Samples : std_logic_vector(1 downto 0);
- begin
- if MR_n = '0' then
- Samples := "11";
- RX_Filtered <= '1';
- elsif XIn'event and XIn = '1' then
- if RClk = '1' then
- Samples(1) := Samples(0);
- Samples(0) := RXD;
- end if;
- if Samples = "00" then
- RX_Filtered <= '0';
- end if;
- if Samples = "11" then
- RX_Filtered <= '1';
- end if;
- end if;
- end process;
-
- -- Receive state machine
- process (MR_n, XIn)
- begin
- if MR_n = '0' then
- RBR <= "00000000";
- LSR(4 downto 0) <= "00000";
- Bit_Phase <= "0000";
- Brk_Cnt <= "0000";
- RX_ShiftReg(7 downto 0) <= "00000000";
- RX_Bit_Cnt <= 0;
- RX_Parity <= '0';
- elsif XIn'event and XIn = '1' then
- if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then
- LSR(0) <= '0'; -- DR
- end if;
- if A = "101" and Rd_n = '0' and CS_n = '0' then
- LSR(4) <= '0'; -- BI
- LSR(3) <= '0'; -- FE
- LSR(2) <= '0'; -- PE
- LSR(1) <= '0'; -- OE
- end if;
- if RClk = '1' then
- if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then
- Bit_Phase <= "0000";
- else
- Bit_Phase <= Bit_Phase + 1;
- end if;
- if Bit_Phase = "1111" then
- if RX_Filtered = '1' then
- Brk_Cnt <= "0000";
- else
- Brk_Cnt <= Brk_Cnt + 1;
- end if;
- if Brk_Cnt = "1100" then
- LSR(4) <= '1'; -- BI
- end if;
- end if;
- if RX_Bit_Cnt = 0 then
- if Bit_Phase = "0111" then
- RX_Bit_Cnt <= RX_Bit_Cnt + 1;
- RX_Parity <= not LCR(4); -- EPS
- end if;
- elsif Bit_Phase = "1111" then
- RX_Bit_Cnt <= RX_Bit_Cnt + 1;
- if RX_Bit_Cnt = 10 then -- Parity stop bit
- RX_Bit_Cnt <= 0;
- LSR(0) <= '1'; -- UART Receive complete
- LSR(3) <= not RX_Filtered; -- Framing error
- elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
- (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
- (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
- (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity
- RX_Bit_Cnt <= 0;
- if LCR(3) = '1' then -- PEN
- RX_Bit_Cnt <= 10;
- if LCR(5) = '1' then -- Stick parity
- if RX_Filtered = LCR(4) then
- LSR(2) <= '1';
- end if;
- else
- if RX_Filtered /= RX_Parity then
- LSR(2) <= '1';
- end if;
- end if;
- else
- LSR(0) <= '1'; -- UART Receive complete
- LSR(3) <= not RX_Filtered; -- Framing error
- end if;
- RBR <= RX_ShiftReg(7 downto 0);
- LSR(1) <= LSR(0);
- if A = "101" and Rd_n = '0' and CS_n = '0' then
- LSR(1) <= '0';
- end if;
- else
- RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1);
- RX_ShiftReg(7) <= RX_Filtered;
- if LCR(1 downto 0) = "10" then
- RX_ShiftReg(7) <= '0';
- RX_ShiftReg(6) <= RX_Filtered;
- end if;
- if LCR(1 downto 0) = "01" then
- RX_ShiftReg(7) <= '0';
- RX_ShiftReg(6) <= '0';
- RX_ShiftReg(5) <= RX_Filtered;
- end if;
- if LCR(1 downto 0) = "00" then
- RX_ShiftReg(7) <= '0';
- RX_ShiftReg(6) <= '0';
- RX_ShiftReg(5) <= '0';
- RX_ShiftReg(4) <= RX_Filtered;
- end if;
- RX_Parity <= RX_Filtered xor RX_Parity;
- end if;
- end if;
- end if;
- end if;
- end process;
-
- -- Transmit bit tick
- process (MR_n, XIn)
- variable TX_Cnt : unsigned(4 downto 0);
- begin
- if MR_n = '0' then
- TX_Cnt := "00000";
- TX_Tick <= '0';
- elsif XIn'event and XIn = '1' then
- TX_Tick <= '0';
- if RClk = '1' then
- TX_Cnt := TX_Cnt + 1;
- if LCR(2) = '1' and TX_Stop_Bit = '1' then
- if LCR(1 downto 0) = "00" then
- if TX_Cnt = "10111" then
- TX_Tick <= '1';
- TX_Cnt(3 downto 0) := "0000";
- end if;
- else
- if TX_Cnt = "11111" then
- TX_Tick <= '1';
- TX_Cnt(3 downto 0) := "0000";
- end if;
- end if;
- else
- TX_Cnt(4) := '1';
- if TX_Cnt(3 downto 0) = "1111" then
- TX_Tick <= '1';
- end if;
- end if;
- end if;
- end if;
- end process;
-
- -- Transmit state machine
- process (MR_n, XIn)
- begin
- if MR_n = '0' then
- LSR(7 downto 5) <= "011";
- TX_Bit_Cnt <= 0;
- TX_ShiftReg <= (others => '0');
- TXD <= '1';
- TX_Parity <= '0';
- TX_Next_Is_Stop <= '0';
- TX_Stop_Bit <= '0';
- elsif XIn'event and XIn = '1' then
- if TX_Tick = '1' then
- TX_Next_Is_Stop <= '0';
- TX_Stop_Bit <= TX_Next_Is_Stop;
- case TX_Bit_Cnt is
- when 0 =>
- if LSR(5) <= '0' then -- THRE
- TX_Bit_Cnt <= 1;
- end if;
- TXD <= '1';
- when 1 => -- Start bit
- TX_ShiftReg(7 downto 0) <= THR;
- LSR(5) <= '1'; -- THRE
- TXD <= '0';
- TX_Parity <= not LCR(4); -- EPS
- TX_Bit_Cnt <= TX_Bit_Cnt + 1;
- when 10 => -- Parity bit
- TXD <= TX_Parity;
- if LCR(5) = '1' then -- Stick parity
- TXD <= not LCR(4);
- end if;
- TX_Bit_Cnt <= 0;
- TX_Next_Is_Stop <= '1';
- when others =>
- TX_Bit_Cnt <= TX_Bit_Cnt + 1;
- if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
- (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
- (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
- (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then
- TX_Bit_Cnt <= 0;
- if LCR(3) = '1' then -- PEN
- TX_Bit_Cnt <= 10;
- else
- TX_Next_Is_Stop <= '1';
- end if;
- LSR(6) <= '1'; -- TEMT
- end if;
- TXD <= TX_ShiftReg(0);
- TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1);
- TX_Parity <= TX_ShiftReg(0) xor TX_Parity;
- end case;
- end if;
- if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then
- LSR(5) <= '0'; -- THRE
- LSR(6) <= '0'; -- TEMT
- end if;
- end if;
- end process;
-
-end;
diff --git a/t80/T80.vhd b/t80/T80.vhd
deleted file mode 100644
index e63c25a..0000000
--- a/t80/T80.vhd
+++ /dev/null
@@ -1,1078 +0,0 @@
---
--- Z80 compatible microprocessor core
---
--- Version : 0247
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0208 : First complete release
---
--- 0210 : Fixed wait and halt
---
--- 0211 : Fixed Refresh addition and IM 1
---
--- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
---
--- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
---
--- 0235 : Added clock enable and IM 2 fix by Mike Johnson
---
--- 0237 : Changed 8080 I/O address output, added IntE output
---
--- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
---
--- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
---
--- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
---
--- 0247 : Fixed bus req/ack cycle
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-use work.T80_Pack.all;
-
-entity T80 is
- generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- CEN : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- IORQ : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- RETI_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DInst : in std_logic_vector(7 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0);
- MC : out std_logic_vector(2 downto 0);
- TS : out std_logic_vector(2 downto 0);
- IntCycle_n : out std_logic;
- IntE : out std_logic;
- Stop : out std_logic
- );
-end T80;
-
-architecture rtl of T80 is
-
- constant aNone : std_logic_vector(2 downto 0) := "111";
- constant aBC : std_logic_vector(2 downto 0) := "000";
- constant aDE : std_logic_vector(2 downto 0) := "001";
- constant aXY : std_logic_vector(2 downto 0) := "010";
- constant aIOA : std_logic_vector(2 downto 0) := "100";
- constant aSP : std_logic_vector(2 downto 0) := "101";
- constant aZI : std_logic_vector(2 downto 0) := "110";
-
- -- Registers
- signal ACC, F : std_logic_vector(7 downto 0);
- signal Ap, Fp : std_logic_vector(7 downto 0);
- signal I : std_logic_vector(7 downto 0);
- signal R : unsigned(7 downto 0);
- signal SP, PC : unsigned(15 downto 0);
- signal RegDIH : std_logic_vector(7 downto 0);
- signal RegDIL : std_logic_vector(7 downto 0);
- signal RegBusA : std_logic_vector(15 downto 0);
- signal RegBusB : std_logic_vector(15 downto 0);
- signal RegBusC : std_logic_vector(15 downto 0);
- signal RegAddrA_r : std_logic_vector(2 downto 0);
- signal RegAddrA : std_logic_vector(2 downto 0);
- signal RegAddrB_r : std_logic_vector(2 downto 0);
- signal RegAddrB : std_logic_vector(2 downto 0);
- signal RegAddrC : std_logic_vector(2 downto 0);
- signal RegWEH : std_logic;
- signal RegWEL : std_logic;
- signal Alternate : std_logic;
-
- -- Help Registers
- signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register
- signal IR : std_logic_vector(7 downto 0); -- Instruction register
- signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
- signal RegBusA_r : std_logic_vector(15 downto 0);
-
- signal ID16 : signed(15 downto 0);
- signal Save_Mux : std_logic_vector(7 downto 0);
-
- signal TState : unsigned(2 downto 0);
- signal MCycle : std_logic_vector(2 downto 0);
- signal IntE_FF1 : std_logic;
- signal IntE_FF2 : std_logic;
- signal Halt_FF : std_logic;
- signal BusReq_s : std_logic;
- signal BusAck : std_logic;
- signal ClkEn : std_logic;
- signal NMI_s : std_logic;
- signal INT_s : std_logic;
- signal IStatus : std_logic_vector(1 downto 0);
-
- signal DI_Reg : std_logic_vector(7 downto 0);
- signal T_Res : std_logic;
- signal XY_State : std_logic_vector(1 downto 0);
- signal Pre_XY_F_M : std_logic_vector(2 downto 0);
- signal NextIs_XY_Fetch : std_logic;
- signal XY_Ind : std_logic;
- signal No_BTR : std_logic;
- signal BTR_r : std_logic;
- signal Auto_Wait : std_logic;
- signal Auto_Wait_t1 : std_logic;
- signal Auto_Wait_t2 : std_logic;
- signal IncDecZ : std_logic;
-
- -- ALU signals
- signal BusB : std_logic_vector(7 downto 0);
- signal BusA : std_logic_vector(7 downto 0);
- signal ALU_Q : std_logic_vector(7 downto 0);
- signal F_Out : std_logic_vector(7 downto 0);
-
- -- Registered micro code outputs
- signal Read_To_Reg_r : std_logic_vector(4 downto 0);
- signal Arith16_r : std_logic;
- signal Z16_r : std_logic;
- signal ALU_Op_r : std_logic_vector(3 downto 0);
- signal Save_ALU_r : std_logic;
- signal PreserveC_r : std_logic;
- signal MCycles : std_logic_vector(2 downto 0);
-
- -- Micro code outputs
- signal MCycles_d : std_logic_vector(2 downto 0);
- signal TStates : std_logic_vector(2 downto 0);
- signal IntCycle : std_logic;
- signal NMICycle : std_logic;
- signal Inc_PC : std_logic;
- signal Inc_WZ : std_logic;
- signal IncDec_16 : std_logic_vector(3 downto 0);
- signal Prefix : std_logic_vector(1 downto 0);
- signal Read_To_Acc : std_logic;
- signal Read_To_Reg : std_logic;
- signal Set_BusB_To : std_logic_vector(3 downto 0);
- signal Set_BusA_To : std_logic_vector(3 downto 0);
- signal ALU_Op : std_logic_vector(3 downto 0);
- signal Save_ALU : std_logic;
- signal PreserveC : std_logic;
- signal Arith16 : std_logic;
- signal Set_Addr_To : std_logic_vector(2 downto 0);
- signal Jump : std_logic;
- signal JumpE : std_logic;
- signal JumpXY : std_logic;
- signal Call : std_logic;
- signal RstP : std_logic;
- signal LDZ : std_logic;
- signal LDW : std_logic;
- signal LDSPHL : std_logic;
- signal IORQ_i : std_logic;
- signal Special_LD : std_logic_vector(2 downto 0);
- signal ExchangeDH : std_logic;
- signal ExchangeRp : std_logic;
- signal ExchangeAF : std_logic;
- signal ExchangeRS : std_logic;
- signal I_DJNZ : std_logic;
- signal I_CPL : std_logic;
- signal I_CCF : std_logic;
- signal I_SCF : std_logic;
- signal I_RETI : std_logic;
- signal I_RETN : std_logic;
- signal I_BT : std_logic;
- signal I_BC : std_logic;
- signal I_BTR : std_logic;
- signal I_RLD : std_logic;
- signal I_RRD : std_logic;
- signal I_INRC : std_logic;
- signal SetDI : std_logic;
- signal SetEI : std_logic;
- signal IMode : std_logic_vector(1 downto 0);
- signal Halt : std_logic;
-
-begin
-
- mcode : T80_MCode
- generic map(
- Mode => Mode,
- Flag_C => Flag_C,
- Flag_N => Flag_N,
- Flag_P => Flag_P,
- Flag_X => Flag_X,
- Flag_H => Flag_H,
- Flag_Y => Flag_Y,
- Flag_Z => Flag_Z,
- Flag_S => Flag_S)
- port map(
- IR => IR,
- ISet => ISet,
- MCycle => MCycle,
- F => F,
- NMICycle => NMICycle,
- IntCycle => IntCycle,
- MCycles => MCycles_d,
- TStates => TStates,
- Prefix => Prefix,
- Inc_PC => Inc_PC,
- Inc_WZ => Inc_WZ,
- IncDec_16 => IncDec_16,
- Read_To_Acc => Read_To_Acc,
- Read_To_Reg => Read_To_Reg,
- Set_BusB_To => Set_BusB_To,
- Set_BusA_To => Set_BusA_To,
- ALU_Op => ALU_Op,
- Save_ALU => Save_ALU,
- PreserveC => PreserveC,
- Arith16 => Arith16,
- Set_Addr_To => Set_Addr_To,
- IORQ => IORQ_i,
- Jump => Jump,
- JumpE => JumpE,
- JumpXY => JumpXY,
- Call => Call,
- RstP => RstP,
- LDZ => LDZ,
- LDW => LDW,
- LDSPHL => LDSPHL,
- Special_LD => Special_LD,
- ExchangeDH => ExchangeDH,
- ExchangeRp => ExchangeRp,
- ExchangeAF => ExchangeAF,
- ExchangeRS => ExchangeRS,
- I_DJNZ => I_DJNZ,
- I_CPL => I_CPL,
- I_CCF => I_CCF,
- I_SCF => I_SCF,
- I_RETI => I_RETI,
- I_RETN => I_RETN,
- I_BT => I_BT,
- I_BC => I_BC,
- I_BTR => I_BTR,
- I_RLD => I_RLD,
- I_RRD => I_RRD,
- I_INRC => I_INRC,
- SetDI => SetDI,
- SetEI => SetEI,
- IMode => IMode,
- Halt => Halt,
- NoRead => NoRead,
- Write => Write);
-
- alu : T80_ALU
- generic map(
- Mode => Mode,
- Flag_C => Flag_C,
- Flag_N => Flag_N,
- Flag_P => Flag_P,
- Flag_X => Flag_X,
- Flag_H => Flag_H,
- Flag_Y => Flag_Y,
- Flag_Z => Flag_Z,
- Flag_S => Flag_S)
- port map(
- Arith16 => Arith16_r,
- Z16 => Z16_r,
- ALU_Op => ALU_Op_r,
- IR => IR(5 downto 0),
- ISet => ISet,
- BusA => BusA,
- BusB => BusB,
- F_In => F,
- Q => ALU_Q,
- F_Out => F_Out);
-
- ClkEn <= CEN and not BusAck;
-
- T_Res <= '1' when TState = unsigned(TStates) else '0';
-
- NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
- ((Set_Addr_To = aXY) or
- (MCycle = "001" and IR = "11001011") or
- (MCycle = "001" and IR = "00110110")) else '0';
-
- Save_Mux <= BusB when ExchangeRp = '1' else
- DI_Reg when Save_ALU_r = '0' else
- ALU_Q;
-
- process (RESET_n, CLK_n)
- begin
- if RESET_n = '0' then
- PC <= (others => '0'); -- Program Counter
- A <= (others => '0');
- TmpAddr <= (others => '0');
- IR <= "00000000";
- ISet <= "00";
- XY_State <= "00";
- IStatus <= "00";
- MCycles <= "000";
- DO <= "00000000";
-
- ACC <= (others => '1');
- F <= (others => '1');
- Ap <= (others => '1');
- Fp <= (others => '1');
- I <= (others => '0');
- R <= (others => '0');
- SP <= (others => '1');
- Alternate <= '0';
-
- Read_To_Reg_r <= "00000";
- F <= (others => '1');
- Arith16_r <= '0';
- BTR_r <= '0';
- Z16_r <= '0';
- ALU_Op_r <= "0000";
- Save_ALU_r <= '0';
- PreserveC_r <= '0';
- XY_Ind <= '0';
-
- elsif CLK_n'event and CLK_n = '1' then
-
- if ClkEn = '1' then
-
- ALU_Op_r <= "0000";
- Save_ALU_r <= '0';
- Read_To_Reg_r <= "00000";
-
- MCycles <= MCycles_d;
-
- if IMode /= "11" then
- IStatus <= IMode;
- end if;
-
- Arith16_r <= Arith16;
- PreserveC_r <= PreserveC;
- if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
- Z16_r <= '1';
- else
- Z16_r <= '0';
- end if;
-
- if MCycle = "001" and TState(2) = '0' then
- -- MCycle = 1 and TState = 1, 2, or 3
-
- if TState = 2 and Wait_n = '1' then
- if Mode < 2 then
- A(7 downto 0) <= std_logic_vector(R);
- A(15 downto 8) <= I;
- R(6 downto 0) <= R(6 downto 0) + 1;
- end if;
-
- if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
- PC <= PC + 1;
- end if;
-
- if IntCycle = '1' and IStatus = "01" then
- IR <= "11111111";
- elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
- IR <= "00000000";
- else
- IR <= DInst;
- end if;
-
- ISet <= "00";
- if Prefix /= "00" then
- if Prefix = "11" then
- if IR(5) = '1' then
- XY_State <= "10";
- else
- XY_State <= "01";
- end if;
- else
- if Prefix = "10" then
- XY_State <= "00";
- XY_Ind <= '0';
- end if;
- ISet <= Prefix;
- end if;
- else
- XY_State <= "00";
- XY_Ind <= '0';
- end if;
- end if;
-
- else
- -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
-
- if MCycle = "110" then
- XY_Ind <= '1';
- if Prefix = "01" then
- ISet <= "01";
- end if;
- end if;
-
- if T_Res = '1' then
- BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
- if Jump = '1' then
- A(15 downto 8) <= DI_Reg;
- A(7 downto 0) <= TmpAddr(7 downto 0);
- PC(15 downto 8) <= unsigned(DI_Reg);
- PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
- elsif JumpXY = '1' then
- A <= RegBusC;
- PC <= unsigned(RegBusC);
- elsif Call = '1' or RstP = '1' then
- A <= TmpAddr;
- PC <= unsigned(TmpAddr);
- elsif MCycle = MCycles and NMICycle = '1' then
- A <= "0000000001100110";
- PC <= "0000000001100110";
- elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
- A(15 downto 8) <= I;
- A(7 downto 0) <= TmpAddr(7 downto 0);
- PC(15 downto 8) <= unsigned(I);
- PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
- else
- case Set_Addr_To is
- when aXY =>
- if XY_State = "00" then
- A <= RegBusC;
- else
- if NextIs_XY_Fetch = '1' then
- A <= std_logic_vector(PC);
- else
- A <= TmpAddr;
- end if;
- end if;
- when aIOA =>
- if Mode = 3 then
- -- Memory map I/O on GBZ80
- A(15 downto 8) <= (others => '1');
- elsif Mode = 2 then
- -- Duplicate I/O address on 8080
- A(15 downto 8) <= DI_Reg;
- else
- A(15 downto 8) <= ACC;
- end if;
- A(7 downto 0) <= DI_Reg;
- when aSP =>
- A <= std_logic_vector(SP);
- when aBC =>
- if Mode = 3 and IORQ_i = '1' then
- -- Memory map I/O on GBZ80
- A(15 downto 8) <= (others => '1');
- A(7 downto 0) <= RegBusC(7 downto 0);
- else
- A <= RegBusC;
- end if;
- when aDE =>
- A <= RegBusC;
- when aZI =>
- if Inc_WZ = '1' then
- A <= std_logic_vector(unsigned(TmpAddr) + 1);
- else
- A(15 downto 8) <= DI_Reg;
- A(7 downto 0) <= TmpAddr(7 downto 0);
- end if;
- when others =>
- A <= std_logic_vector(PC);
- end case;
- end if;
-
- Save_ALU_r <= Save_ALU;
- ALU_Op_r <= ALU_Op;
-
- if I_CPL = '1' then
- -- CPL
- ACC <= not ACC;
- F(Flag_Y) <= not ACC(5);
- F(Flag_H) <= '1';
- F(Flag_X) <= not ACC(3);
- F(Flag_N) <= '1';
- end if;
- if I_CCF = '1' then
- -- CCF
- F(Flag_C) <= not F(Flag_C);
- F(Flag_Y) <= ACC(5);
- F(Flag_H) <= F(Flag_C);
- F(Flag_X) <= ACC(3);
- F(Flag_N) <= '0';
- end if;
- if I_SCF = '1' then
- -- SCF
- F(Flag_C) <= '1';
- F(Flag_Y) <= ACC(5);
- F(Flag_H) <= '0';
- F(Flag_X) <= ACC(3);
- F(Flag_N) <= '0';
- end if;
- end if;
-
- if TState = 2 and Wait_n = '1' then
- if ISet = "01" and MCycle = "111" then
- IR <= DInst;
- end if;
- if JumpE = '1' then
- PC <= unsigned(signed(PC) + signed(DI_Reg));
- elsif Inc_PC = '1' then
- PC <= PC + 1;
- end if;
- if BTR_r = '1' then
- PC <= PC - 2;
- end if;
- if RstP = '1' then
- TmpAddr <= (others =>'0');
- TmpAddr(5 downto 3) <= IR(5 downto 3);
- end if;
- end if;
- if TState = 3 and MCycle = "110" then
- TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
- end if;
-
- if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
- if IncDec_16(2 downto 0) = "111" then
- if IncDec_16(3) = '1' then
- SP <= SP - 1;
- else
- SP <= SP + 1;
- end if;
- end if;
- end if;
-
- if LDSPHL = '1' then
- SP <= unsigned(RegBusC);
- end if;
- if ExchangeAF = '1' then
- Ap <= ACC;
- ACC <= Ap;
- Fp <= F;
- F <= Fp;
- end if;
- if ExchangeRS = '1' then
- Alternate <= not Alternate;
- end if;
- end if;
-
- if TState = 3 then
- if LDZ = '1' then
- TmpAddr(7 downto 0) <= DI_Reg;
- end if;
- if LDW = '1' then
- TmpAddr(15 downto 8) <= DI_Reg;
- end if;
-
- if Special_LD(2) = '1' then
- case Special_LD(1 downto 0) is
- when "00" =>
- ACC <= I;
- F(Flag_P) <= IntE_FF2;
- when "01" =>
- ACC <= std_logic_vector(R);
- F(Flag_P) <= IntE_FF2;
- when "10" =>
- I <= ACC;
- when others =>
- R <= unsigned(ACC);
- end case;
- end if;
- end if;
-
- if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
- if Mode = 3 then
- F(6) <= F_Out(6);
- F(5) <= F_Out(5);
- F(7) <= F_Out(7);
- if PreserveC_r = '0' then
- F(4) <= F_Out(4);
- end if;
- else
- F(7 downto 1) <= F_Out(7 downto 1);
- if PreserveC_r = '0' then
- F(Flag_C) <= F_Out(0);
- end if;
- end if;
- end if;
- if T_Res = '1' and I_INRC = '1' then
- F(Flag_H) <= '0';
- F(Flag_N) <= '0';
- if DI_Reg(7 downto 0) = "00000000" then
- F(Flag_Z) <= '1';
- else
- F(Flag_Z) <= '0';
- end if;
- F(Flag_S) <= DI_Reg(7);
- F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
- DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
- end if;
-
- if TState = 1 and Auto_Wait_t1 = '0' then
- DO <= BusB;
- if I_RLD = '1' then
- DO(3 downto 0) <= BusA(3 downto 0);
- DO(7 downto 4) <= BusB(3 downto 0);
- end if;
- if I_RRD = '1' then
- DO(3 downto 0) <= BusB(7 downto 4);
- DO(7 downto 4) <= BusA(3 downto 0);
- end if;
- end if;
-
- if T_Res = '1' then
- Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
- Read_To_Reg_r(4) <= Read_To_Reg;
- if Read_To_Acc = '1' then
- Read_To_Reg_r(3 downto 0) <= "0111";
- Read_To_Reg_r(4) <= '1';
- end if;
- end if;
-
- if TState = 1 and I_BT = '1' then
- F(Flag_X) <= ALU_Q(3);
- F(Flag_Y) <= ALU_Q(1);
- F(Flag_H) <= '0';
- F(Flag_N) <= '0';
- end if;
- if I_BC = '1' or I_BT = '1' then
- F(Flag_P) <= IncDecZ;
- end if;
-
- if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
- (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
- case Read_To_Reg_r is
- when "10111" =>
- ACC <= Save_Mux;
- when "10110" =>
- DO <= Save_Mux;
- when "11000" =>
- SP(7 downto 0) <= unsigned(Save_Mux);
- when "11001" =>
- SP(15 downto 8) <= unsigned(Save_Mux);
- when "11011" =>
- F <= Save_Mux;
- when others =>
- end case;
- end if;
-
- end if;
-
- end if;
-
- end process;
-
----------------------------------------------------------------------------
---
--- BC('), DE('), HL('), IX and IY
---
----------------------------------------------------------------------------
- process (CLK_n)
- begin
- if CLK_n'event and CLK_n = '1' then
- if ClkEn = '1' then
- -- Bus A / Write
- RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
- if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
- RegAddrA_r <= XY_State(1) & "11";
- end if;
-
- -- Bus B
- RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
- if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
- RegAddrB_r <= XY_State(1) & "11";
- end if;
-
- -- Address from register
- RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
- -- Jump (HL), LD SP,HL
- if (JumpXY = '1' or LDSPHL = '1') then
- RegAddrC <= Alternate & "10";
- end if;
- if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
- RegAddrC <= XY_State(1) & "11";
- end if;
-
- if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
- IncDecZ <= F_Out(Flag_Z);
- end if;
- if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
- if ID16 = 0 then
- IncDecZ <= '0';
- else
- IncDecZ <= '1';
- end if;
- end if;
-
- RegBusA_r <= RegBusA;
- end if;
- end if;
- end process;
-
- RegAddrA <=
- -- 16 bit increment/decrement
- Alternate & IncDec_16(1 downto 0) when (TState = 2 or
- (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
- XY_State(1) & "11" when (TState = 2 or
- (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
- -- EX HL,DL
- Alternate & "10" when ExchangeDH = '1' and TState = 3 else
- Alternate & "01" when ExchangeDH = '1' and TState = 4 else
- -- Bus A / Write
- RegAddrA_r;
-
- RegAddrB <=
- -- EX HL,DL
- Alternate & "01" when ExchangeDH = '1' and TState = 3 else
- -- Bus B
- RegAddrB_r;
-
- ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
- signed(RegBusA) + 1;
-
- process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
- ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
- begin
- RegWEH <= '0';
- RegWEL <= '0';
- if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
- (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
- case Read_To_Reg_r is
- when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
- RegWEH <= not Read_To_Reg_r(0);
- RegWEL <= Read_To_Reg_r(0);
- when others =>
- end case;
- end if;
-
- if ExchangeDH = '1' and (TState = 3 or TState = 4) then
- RegWEH <= '1';
- RegWEL <= '1';
- end if;
-
- if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
- case IncDec_16(1 downto 0) is
- when "00" | "01" | "10" =>
- RegWEH <= '1';
- RegWEL <= '1';
- when others =>
- end case;
- end if;
- end process;
-
- process (Save_Mux, RegBusB, RegBusA_r, ID16,
- ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
- begin
- RegDIH <= Save_Mux;
- RegDIL <= Save_Mux;
-
- if ExchangeDH = '1' and TState = 3 then
- RegDIH <= RegBusB(15 downto 8);
- RegDIL <= RegBusB(7 downto 0);
- end if;
- if ExchangeDH = '1' and TState = 4 then
- RegDIH <= RegBusA_r(15 downto 8);
- RegDIL <= RegBusA_r(7 downto 0);
- end if;
-
- if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
- RegDIH <= std_logic_vector(ID16(15 downto 8));
- RegDIL <= std_logic_vector(ID16(7 downto 0));
- end if;
- end process;
-
- Regs : T80_Reg
- port map(
- Clk => CLK_n,
- CEN => ClkEn,
- WEH => RegWEH,
- WEL => RegWEL,
- AddrA => RegAddrA,
- AddrB => RegAddrB,
- AddrC => RegAddrC,
- DIH => RegDIH,
- DIL => RegDIL,
- DOAH => RegBusA(15 downto 8),
- DOAL => RegBusA(7 downto 0),
- DOBH => RegBusB(15 downto 8),
- DOBL => RegBusB(7 downto 0),
- DOCH => RegBusC(15 downto 8),
- DOCL => RegBusC(7 downto 0));
-
----------------------------------------------------------------------------
---
--- Buses
---
----------------------------------------------------------------------------
- process (CLK_n)
- begin
- if CLK_n'event and CLK_n = '1' then
- if ClkEn = '1' then
- case Set_BusB_To is
- when "0111" =>
- BusB <= ACC;
- when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
- if Set_BusB_To(0) = '1' then
- BusB <= RegBusB(7 downto 0);
- else
- BusB <= RegBusB(15 downto 8);
- end if;
- when "0110" =>
- BusB <= DI_Reg;
- when "1000" =>
- BusB <= std_logic_vector(SP(7 downto 0));
- when "1001" =>
- BusB <= std_logic_vector(SP(15 downto 8));
- when "1010" =>
- BusB <= "00000001";
- when "1011" =>
- BusB <= F;
- when "1100" =>
- BusB <= std_logic_vector(PC(7 downto 0));
- when "1101" =>
- BusB <= std_logic_vector(PC(15 downto 8));
- when "1110" =>
- BusB <= "00000000";
- when others =>
- BusB <= "--------";
- end case;
-
- case Set_BusA_To is
- when "0111" =>
- BusA <= ACC;
- when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
- if Set_BusA_To(0) = '1' then
- BusA <= RegBusA(7 downto 0);
- else
- BusA <= RegBusA(15 downto 8);
- end if;
- when "0110" =>
- BusA <= DI_Reg;
- when "1000" =>
- BusA <= std_logic_vector(SP(7 downto 0));
- when "1001" =>
- BusA <= std_logic_vector(SP(15 downto 8));
- when "1010" =>
- BusA <= "00000000";
- when others =>
- BusB <= "--------";
- end case;
- end if;
- end if;
- end process;
-
----------------------------------------------------------------------------
---
--- Generate external control signals
---
----------------------------------------------------------------------------
- process (RESET_n,CLK_n)
- begin
- if RESET_n = '0' then
- RFSH_n <= '1';
- elsif CLK_n'event and CLK_n = '1' then
- if CEN = '1' then
- if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
- RFSH_n <= '0';
- else
- RFSH_n <= '1';
- end if;
- end if;
- end if;
- end process;
-
- MC <= std_logic_vector(MCycle);
- TS <= std_logic_vector(TState);
- DI_Reg <= DI;
- HALT_n <= not Halt_FF;
- BUSAK_n <= not BusAck;
- IntCycle_n <= not IntCycle;
- IntE <= IntE_FF1;
- IORQ <= IORQ_i;
- Stop <= I_DJNZ;
-
--------------------------------------------------------------------------
---
--- Syncronise inputs
---
--------------------------------------------------------------------------
- process (RESET_n, CLK_n)
- variable OldNMI_n : std_logic;
- begin
- if RESET_n = '0' then
- BusReq_s <= '0';
- INT_s <= '0';
- NMI_s <= '0';
- OldNMI_n := '0';
- elsif CLK_n'event and CLK_n = '1' then
- if CEN = '1' then
- BusReq_s <= not BUSRQ_n;
- INT_s <= not INT_n;
- if NMICycle = '1' then
- NMI_s <= '0';
- elsif NMI_n = '0' and OldNMI_n = '1' then
- NMI_s <= '1';
- end if;
- OldNMI_n := NMI_n;
- end if;
- end if;
- end process;
-
--------------------------------------------------------------------------
---
--- Main state machine
---
--------------------------------------------------------------------------
- process (RESET_n, CLK_n)
- begin
- if RESET_n = '0' then
- MCycle <= "001";
- TState <= "000";
- Pre_XY_F_M <= "000";
- Halt_FF <= '0';
- BusAck <= '0';
- NMICycle <= '0';
- IntCycle <= '0';
- IntE_FF1 <= '0';
- IntE_FF2 <= '0';
- No_BTR <= '0';
- Auto_Wait_t1 <= '0';
- Auto_Wait_t2 <= '0';
- M1_n <= '1';
- RETI_n <= '1';
- elsif CLK_n'event and CLK_n = '1' then
- if CEN = '1' then
- if T_Res = '1' then
- Auto_Wait_t1 <= '0';
- else
- Auto_Wait_t1 <= Auto_Wait or IORQ_i;
- end if;
- Auto_Wait_t2 <= Auto_Wait_t1 and not T_Res;
- No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
- (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
- (I_BTR and (not IR(4) or F(Flag_Z)));
- RETI_n <= not I_RETI;
- if TState = 2 then
- if SetEI = '1' then
- IntE_FF1 <= '1';
- IntE_FF2 <= '1';
- end if;
- if I_RETN = '1' then
- IntE_FF1 <= IntE_FF2;
- end if;
- end if;
- if TState = 3 then
- if SetDI = '1' then
- IntE_FF1 <= '0';
- IntE_FF2 <= '0';
- end if;
- end if;
- if IntCycle = '1' or NMICycle = '1' then
- Halt_FF <= '0';
- end if;
- if MCycle = "001" and TState = 2 and Wait_n = '1' then
- M1_n <= '1';
- end if;
- if BusReq_s = '1' and BusAck = '1' then
- else
- BusAck <= '0';
- if TState = 2 and Wait_n = '0' then
- elsif T_Res = '1' then
- if Halt = '1' then
- Halt_FF <= '1';
- end if;
- if BusReq_s = '1' then
- BusAck <= '1';
- else
- TState <= "001";
- if NextIs_XY_Fetch = '1' then
- MCycle <= "110";
- Pre_XY_F_M <= MCycle;
- if IR = "00110110" and Mode = 0 then
- Pre_XY_F_M <= "010";
- end if;
- elsif (MCycle = "111") or
- (MCycle = "110" and Mode = 1 and ISet /= "01") then
- MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
- elsif (MCycle = MCycles) or
- No_BTR = '1' or
- (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
- M1_n <= '0';
- MCycle <= "001";
- IntCycle <= '0';
- NMICycle <= '0';
- if NMI_s = '1' and Prefix = "00" then
- NMICycle <= '1';
- IntE_FF1 <= '0';
- elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
- IntCycle <= '1';
- IntE_FF1 <= '0';
- IntE_FF2 <= '0';
- end if;
- else
- MCycle <= std_logic_vector(unsigned(MCycle) + 1);
- end if;
- end if;
- else
- if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor
- (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then
- TState <= TState + 1;
- end if;
- end if;
- end if;
- if TState = 0 then
- M1_n <= '0';
- end if;
- end if;
- end if;
- end process;
-
- process (IntCycle, NMICycle, MCycle)
- begin
- Auto_Wait <= '0';
- if IntCycle = '1' or NMICycle = '1' then
- if MCycle = "001" then
- Auto_Wait <= '1';
- end if;
- end if;
- end process;
-
-end;
diff --git a/t80/T8080se.vhd b/t80/T8080se.vhd
deleted file mode 100644
index 2b6d28f..0000000
--- a/t80/T8080se.vhd
+++ /dev/null
@@ -1,185 +0,0 @@
---
--- 8080 compatible microprocessor core, synchronous top level with clock enable
--- Different timing than the original 8080
--- Inputs needs to be synchronous and outputs may glitch
---
--- Version : 0242
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
--- STACK status output not supported
---
--- File history :
---
--- 0237 : First version
---
--- 0238 : Updated for T80 interface change
---
--- 0240 : Updated for T80 interface change
---
--- 0242 : Updated for T80 interface change
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-use work.T80_Pack.all;
-
-entity T8080se is
- generic(
- Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2
- );
- port(
- RESET_n : in std_logic;
- CLK : in std_logic;
- CLKEN : in std_logic;
- READY : in std_logic;
- HOLD : in std_logic;
- INT : in std_logic;
- INTE : out std_logic;
- DBIN : out std_logic;
- SYNC : out std_logic;
- VAIT : out std_logic;
- HLDA : out std_logic;
- WR_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0)
- );
-end T8080se;
-
-architecture rtl of T8080se is
-
- signal IntCycle_n : std_logic;
- signal NoRead : std_logic;
- signal Write : std_logic;
- signal IORQ : std_logic;
- signal INT_n : std_logic;
- signal HALT_n : std_logic;
- signal BUSRQ_n : std_logic;
- signal BUSAK_n : std_logic;
- signal DO_i : std_logic_vector(7 downto 0);
- signal DI_Reg : std_logic_vector(7 downto 0);
- signal MCycle : std_logic_vector(2 downto 0);
- signal TState : std_logic_vector(2 downto 0);
- signal One : std_logic;
-
-begin
-
- INT_n <= not INT;
- BUSRQ_n <= HOLD;
- HLDA <= not BUSAK_n;
- SYNC <= '1' when TState = "001" else '0';
- VAIT <= '1' when TState = "010" else '0';
- One <= '1';
-
- DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA
- DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n
- DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!!
- DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA
- DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT
- DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1
- DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP
- DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR
-
- u0 : T80
- generic map(
- Mode => Mode,
- IOWait => 0)
- port map(
- CEN => CLKEN,
- M1_n => open,
- IORQ => IORQ,
- NoRead => NoRead,
- Write => Write,
- RFSH_n => open,
- HALT_n => HALT_n,
- WAIT_n => READY,
- INT_n => INT_n,
- NMI_n => One,
- RESET_n => RESET_n,
- BUSRQ_n => One,
- BUSAK_n => BUSAK_n,
- CLK_n => CLK,
- A => A,
- DInst => DI,
- DI => DI_Reg,
- DO => DO_i,
- MC => MCycle,
- TS => TState,
- IntCycle_n => IntCycle_n,
- IntE => INTE);
-
- process (RESET_n, CLK)
- begin
- if RESET_n = '0' then
- DBIN <= '0';
- WR_n <= '1';
- DI_Reg <= "00000000";
- elsif CLK'event and CLK = '1' then
- if CLKEN = '1' then
- DBIN <= '0';
- WR_n <= '1';
- if MCycle = "001" then
- if TState = "001" or (TState = "010" and READY = '0') then
- DBIN <= IntCycle_n;
- end if;
- else
- if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then
- DBIN <= '1';
- end if;
- if T2Write = 0 then
- if TState = "010" and Write = '1' then
- WR_n <= '0';
- end if;
- else
- if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then
- WR_n <= '0';
- end if;
- end if;
- end if;
- if TState = "010" and READY = '1' then
- DI_Reg <= DI;
- end if;
- end if;
- end if;
- end process;
-
-end;
diff --git a/t80/T80_ALU.vhd b/t80/T80_ALU.vhd
deleted file mode 100644
index 86fddce..0000000
--- a/t80/T80_ALU.vhd
+++ /dev/null
@@ -1,351 +0,0 @@
---
--- Z80 compatible microprocessor core
---
--- Version : 0247
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
---
--- 0238 : Fixed zero flag for 16 bit SBC and ADC
---
--- 0240 : Added GB operations
---
--- 0242 : Cleanup
---
--- 0247 : Cleanup
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity T80_ALU is
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- Arith16 : in std_logic;
- Z16 : in std_logic;
- ALU_Op : in std_logic_vector(3 downto 0);
- IR : in std_logic_vector(5 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- BusA : in std_logic_vector(7 downto 0);
- BusB : in std_logic_vector(7 downto 0);
- F_In : in std_logic_vector(7 downto 0);
- Q : out std_logic_vector(7 downto 0);
- F_Out : out std_logic_vector(7 downto 0)
- );
-end T80_ALU;
-
-architecture rtl of T80_ALU is
-
- procedure AddSub(A : std_logic_vector;
- B : std_logic_vector;
- Sub : std_logic;
- Carry_In : std_logic;
- signal Res : out std_logic_vector;
- signal Carry : out std_logic) is
- variable B_i : unsigned(A'length - 1 downto 0);
- variable Res_i : unsigned(A'length + 1 downto 0);
- begin
- if Sub = '1' then
- B_i := not unsigned(B);
- else
- B_i := unsigned(B);
- end if;
- Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
- Carry <= Res_i(A'length + 1);
- Res <= std_logic_vector(Res_i(A'length downto 1));
- end;
-
- -- AddSub variables (temporary signals)
- signal UseCarry : std_logic;
- signal Carry7_v : std_logic;
- signal Overflow_v : std_logic;
- signal HalfCarry_v : std_logic;
- signal Carry_v : std_logic;
- signal Q_v : std_logic_vector(7 downto 0);
-
- signal BitMask : std_logic_vector(7 downto 0);
-
-begin
-
- with IR(5 downto 3) select BitMask <= "00000001" when "000",
- "00000010" when "001",
- "00000100" when "010",
- "00001000" when "011",
- "00010000" when "100",
- "00100000" when "101",
- "01000000" when "110",
- "10000000" when others;
-
- UseCarry <= not ALU_Op(2) and ALU_Op(0);
- AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
- AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
- AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
- OverFlow_v <= Carry_v xor Carry7_v;
-
- process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
- variable Q_t : std_logic_vector(7 downto 0);
- variable DAA_Q : unsigned(8 downto 0);
- begin
- Q_t := "--------";
- F_Out <= F_In;
- DAA_Q := "---------";
- case ALU_Op is
- when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
- F_Out(Flag_N) <= '0';
- F_Out(Flag_C) <= '0';
- case ALU_OP(2 downto 0) is
- when "000" | "001" => -- ADD, ADC
- Q_t := Q_v;
- F_Out(Flag_C) <= Carry_v;
- F_Out(Flag_H) <= HalfCarry_v;
- F_Out(Flag_P) <= OverFlow_v;
- when "010" | "011" | "111" => -- SUB, SBC, CP
- Q_t := Q_v;
- F_Out(Flag_N) <= '1';
- F_Out(Flag_C) <= not Carry_v;
- F_Out(Flag_H) <= not HalfCarry_v;
- F_Out(Flag_P) <= OverFlow_v;
- when "100" => -- AND
- Q_t(7 downto 0) := BusA and BusB;
- F_Out(Flag_H) <= '1';
- when "101" => -- XOR
- Q_t(7 downto 0) := BusA xor BusB;
- F_Out(Flag_H) <= '0';
- when others => -- OR "110"
- Q_t(7 downto 0) := BusA or BusB;
- F_Out(Flag_H) <= '0';
- end case;
- if ALU_Op(2 downto 0) = "111" then -- CP
- F_Out(Flag_X) <= BusB(3);
- F_Out(Flag_Y) <= BusB(5);
- else
- F_Out(Flag_X) <= Q_t(3);
- F_Out(Flag_Y) <= Q_t(5);
- end if;
- if Q_t(7 downto 0) = "00000000" then
- F_Out(Flag_Z) <= '1';
- if Z16 = '1' then
- F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
- end if;
- else
- F_Out(Flag_Z) <= '0';
- end if;
- F_Out(Flag_S) <= Q_t(7);
- case ALU_Op(2 downto 0) is
- when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
- when others =>
- F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
- Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
- end case;
- if Arith16 = '1' then
- F_Out(Flag_S) <= F_In(Flag_S);
- F_Out(Flag_Z) <= F_In(Flag_Z);
- F_Out(Flag_P) <= F_In(Flag_P);
- end if;
- when "1100" =>
- -- DAA
- F_Out(Flag_H) <= F_In(Flag_H);
- F_Out(Flag_C) <= F_In(Flag_C);
- DAA_Q(7 downto 0) := unsigned(BusA);
- DAA_Q(8) := '0';
- if F_In(Flag_N) = '0' then
- -- After addition
- -- Alow > 9 or H = 1
- if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
- if (DAA_Q(3 downto 0) > 9) then
- F_Out(Flag_H) <= '1';
- else
- F_Out(Flag_H) <= '0';
- end if;
- DAA_Q := DAA_Q + 6;
- end if;
- -- new Ahigh > 9 or C = 1
- if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
- DAA_Q := DAA_Q + 96; -- 0x60
- end if;
- else
- -- After subtraction
- if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
- if DAA_Q(3 downto 0) > 5 then
- F_Out(Flag_H) <= '0';
- end if;
- DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
- end if;
- if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
- DAA_Q := DAA_Q - 352; -- 0x160
- end if;
- end if;
- F_Out(Flag_X) <= DAA_Q(3);
- F_Out(Flag_Y) <= DAA_Q(5);
- F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
- Q_t := std_logic_vector(DAA_Q(7 downto 0));
- if DAA_Q(7 downto 0) = "00000000" then
- F_Out(Flag_Z) <= '1';
- else
- F_Out(Flag_Z) <= '0';
- end if;
- F_Out(Flag_S) <= DAA_Q(7);
- F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
- DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
- when "1101" | "1110" =>
- -- RLD, RRD
- Q_t(7 downto 4) := BusA(7 downto 4);
- if ALU_Op(0) = '1' then
- Q_t(3 downto 0) := BusB(7 downto 4);
- else
- Q_t(3 downto 0) := BusB(3 downto 0);
- end if;
- F_Out(Flag_H) <= '0';
- F_Out(Flag_N) <= '0';
- F_Out(Flag_X) <= Q_t(3);
- F_Out(Flag_Y) <= Q_t(5);
- if Q_t(7 downto 0) = "00000000" then
- F_Out(Flag_Z) <= '1';
- else
- F_Out(Flag_Z) <= '0';
- end if;
- F_Out(Flag_S) <= Q_t(7);
- F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
- Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
- when "1001" =>
- -- BIT
- Q_t(7 downto 0) := BusB and BitMask;
- F_Out(Flag_S) <= Q_t(7);
- if Q_t(7 downto 0) = "00000000" then
- F_Out(Flag_Z) <= '1';
- F_Out(Flag_P) <= '1';
- else
- F_Out(Flag_Z) <= '0';
- F_Out(Flag_P) <= '0';
- end if;
- F_Out(Flag_H) <= '1';
- F_Out(Flag_N) <= '0';
- F_Out(Flag_X) <= '0';
- F_Out(Flag_Y) <= '0';
- if IR(2 downto 0) /= "110" then
- F_Out(Flag_X) <= BusB(3);
- F_Out(Flag_Y) <= BusB(5);
- end if;
- when "1010" =>
- -- SET
- Q_t(7 downto 0) := BusB or BitMask;
- when "1011" =>
- -- RES
- Q_t(7 downto 0) := BusB and not BitMask;
- when "1000" =>
- -- ROT
- case IR(5 downto 3) is
- when "000" => -- RLC
- Q_t(7 downto 1) := BusA(6 downto 0);
- Q_t(0) := BusA(7);
- F_Out(Flag_C) <= BusA(7);
- when "010" => -- RL
- Q_t(7 downto 1) := BusA(6 downto 0);
- Q_t(0) := F_In(Flag_C);
- F_Out(Flag_C) <= BusA(7);
- when "001" => -- RRC
- Q_t(6 downto 0) := BusA(7 downto 1);
- Q_t(7) := BusA(0);
- F_Out(Flag_C) <= BusA(0);
- when "011" => -- RR
- Q_t(6 downto 0) := BusA(7 downto 1);
- Q_t(7) := F_In(Flag_C);
- F_Out(Flag_C) <= BusA(0);
- when "100" => -- SLA
- Q_t(7 downto 1) := BusA(6 downto 0);
- Q_t(0) := '0';
- F_Out(Flag_C) <= BusA(7);
- when "110" => -- SLL (Undocumented) / SWAP
- if Mode = 3 then
- Q_t(7 downto 4) := BusA(3 downto 0);
- Q_t(3 downto 0) := BusA(7 downto 4);
- F_Out(Flag_C) <= '0';
- else
- Q_t(7 downto 1) := BusA(6 downto 0);
- Q_t(0) := '1';
- F_Out(Flag_C) <= BusA(7);
- end if;
- when "101" => -- SRA
- Q_t(6 downto 0) := BusA(7 downto 1);
- Q_t(7) := BusA(7);
- F_Out(Flag_C) <= BusA(0);
- when others => -- SRL
- Q_t(6 downto 0) := BusA(7 downto 1);
- Q_t(7) := '0';
- F_Out(Flag_C) <= BusA(0);
- end case;
- F_Out(Flag_H) <= '0';
- F_Out(Flag_N) <= '0';
- F_Out(Flag_X) <= Q_t(3);
- F_Out(Flag_Y) <= Q_t(5);
- F_Out(Flag_S) <= Q_t(7);
- if Q_t(7 downto 0) = "00000000" then
- F_Out(Flag_Z) <= '1';
- else
- F_Out(Flag_Z) <= '0';
- end if;
- F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
- Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
- if ISet = "00" then
- F_Out(Flag_P) <= F_In(Flag_P);
- F_Out(Flag_S) <= F_In(Flag_S);
- F_Out(Flag_Z) <= F_In(Flag_Z);
- end if;
- when others =>
- null;
- end case;
- Q <= Q_t;
- end process;
-
-end;
diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd
deleted file mode 100644
index 138b20e..0000000
--- a/t80/T80_MCode.vhd
+++ /dev/null
@@ -1,1937 +0,0 @@
---
--- Z80 compatible microprocessor core
---
--- Version : 0242
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0208 : First complete release
---
--- 0211 : Fixed IM 1
---
--- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
---
--- 0235 : Added IM 2 fix by Mike Johnson
---
--- 0238 : Added NoRead signal
---
--- 0238b: Fixed instruction timing for POP and DJNZ
---
--- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
---
--- 0242 : Fixed I/O instruction timing, cleanup
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity T80_MCode is
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- IR : in std_logic_vector(7 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- MCycle : in std_logic_vector(2 downto 0);
- F : in std_logic_vector(7 downto 0);
- NMICycle : in std_logic;
- IntCycle : in std_logic;
- MCycles : out std_logic_vector(2 downto 0);
- TStates : out std_logic_vector(2 downto 0);
- Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
- Inc_PC : out std_logic;
- Inc_WZ : out std_logic;
- IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
- Read_To_Reg : out std_logic;
- Read_To_Acc : out std_logic;
- Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
- Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
- ALU_Op : out std_logic_vector(3 downto 0);
- -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
- Save_ALU : out std_logic;
- PreserveC : out std_logic;
- Arith16 : out std_logic;
- Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
- IORQ : out std_logic;
- Jump : out std_logic;
- JumpE : out std_logic;
- JumpXY : out std_logic;
- Call : out std_logic;
- RstP : out std_logic;
- LDZ : out std_logic;
- LDW : out std_logic;
- LDSPHL : out std_logic;
- Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
- ExchangeDH : out std_logic;
- ExchangeRp : out std_logic;
- ExchangeAF : out std_logic;
- ExchangeRS : out std_logic;
- I_DJNZ : out std_logic;
- I_CPL : out std_logic;
- I_CCF : out std_logic;
- I_SCF : out std_logic;
- I_RETI : out std_logic;
- I_RETN : out std_logic;
- I_BT : out std_logic;
- I_BC : out std_logic;
- I_BTR : out std_logic;
- I_RLD : out std_logic;
- I_RRD : out std_logic;
- I_INRC : out std_logic;
- SetDI : out std_logic;
- SetEI : out std_logic;
- IMode : out std_logic_vector(1 downto 0);
- Halt : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic
- );
-end T80_MCode;
-
-architecture rtl of T80_MCode is
-
- constant aNone : std_logic_vector(2 downto 0) := "111";
- constant aBC : std_logic_vector(2 downto 0) := "000";
- constant aDE : std_logic_vector(2 downto 0) := "001";
- constant aXY : std_logic_vector(2 downto 0) := "010";
- constant aIOA : std_logic_vector(2 downto 0) := "100";
- constant aSP : std_logic_vector(2 downto 0) := "101";
- constant aZI : std_logic_vector(2 downto 0) := "110";
--- constant aNone : std_logic_vector(2 downto 0) := "000";
--- constant aXY : std_logic_vector(2 downto 0) := "001";
--- constant aIOA : std_logic_vector(2 downto 0) := "010";
--- constant aSP : std_logic_vector(2 downto 0) := "011";
--- constant aBC : std_logic_vector(2 downto 0) := "100";
--- constant aDE : std_logic_vector(2 downto 0) := "101";
--- constant aZI : std_logic_vector(2 downto 0) := "110";
-
- function is_cc_true(
- F : std_logic_vector(7 downto 0);
- cc : bit_vector(2 downto 0)
- ) return boolean is
- begin
- if Mode = 3 then
- case cc is
- when "000" => return F(7) = '0'; -- NZ
- when "001" => return F(7) = '1'; -- Z
- when "010" => return F(4) = '0'; -- NC
- when "011" => return F(4) = '1'; -- C
- when "100" => return false;
- when "101" => return false;
- when "110" => return false;
- when "111" => return false;
- end case;
- else
- case cc is
- when "000" => return F(6) = '0'; -- NZ
- when "001" => return F(6) = '1'; -- Z
- when "010" => return F(0) = '0'; -- NC
- when "011" => return F(0) = '1'; -- C
- when "100" => return F(2) = '0'; -- PO
- when "101" => return F(2) = '1'; -- PE
- when "110" => return F(7) = '0'; -- P
- when "111" => return F(7) = '1'; -- M
- end case;
- end if;
- end;
-
-begin
-
- process (IR, ISet, MCycle, F, NMICycle, IntCycle)
- variable DDD : std_logic_vector(2 downto 0);
- variable SSS : std_logic_vector(2 downto 0);
- variable DPair : std_logic_vector(1 downto 0);
- variable IRB : bit_vector(7 downto 0);
- begin
- DDD := IR(5 downto 3);
- SSS := IR(2 downto 0);
- DPair := IR(5 downto 4);
- IRB := to_bitvector(IR);
-
- MCycles <= "001";
- if MCycle = "001" then
- TStates <= "100";
- else
- TStates <= "011";
- end if;
- Prefix <= "00";
- Inc_PC <= '0';
- Inc_WZ <= '0';
- IncDec_16 <= "0000";
- Read_To_Acc <= '0';
- Read_To_Reg <= '0';
- Set_BusB_To <= "0000";
- Set_BusA_To <= "0000";
- ALU_Op <= "0" & IR(5 downto 3);
- Save_ALU <= '0';
- PreserveC <= '0';
- Arith16 <= '0';
- IORQ <= '0';
- Set_Addr_To <= aNone;
- Jump <= '0';
- JumpE <= '0';
- JumpXY <= '0';
- Call <= '0';
- RstP <= '0';
- LDZ <= '0';
- LDW <= '0';
- LDSPHL <= '0';
- Special_LD <= "000";
- ExchangeDH <= '0';
- ExchangeRp <= '0';
- ExchangeAF <= '0';
- ExchangeRS <= '0';
- I_DJNZ <= '0';
- I_CPL <= '0';
- I_CCF <= '0';
- I_SCF <= '0';
- I_RETI <= '0';
- I_RETN <= '0';
- I_BT <= '0';
- I_BC <= '0';
- I_BTR <= '0';
- I_RLD <= '0';
- I_RRD <= '0';
- I_INRC <= '0';
- SetDI <= '0';
- SetEI <= '0';
- IMode <= "11";
- Halt <= '0';
- NoRead <= '0';
- Write <= '0';
-
- case ISet is
- when "00" =>
-
-------------------------------------------------------------------------------
---
--- Unprefixed instructions
---
-------------------------------------------------------------------------------
-
- case IRB is
--- 8 BIT LOAD GROUP
- when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
- |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
- |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
- |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
- |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
- |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
- |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
- -- LD r,r'
- Set_BusB_To(2 downto 0) <= SSS;
- ExchangeRp <= '1';
- Set_BusA_To(2 downto 0) <= DDD;
- Read_To_Reg <= '1';
- when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" =>
- -- LD r,n
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_BusA_To(2 downto 0) <= DDD;
- Read_To_Reg <= '1';
- when others => null;
- end case;
- when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" =>
- -- LD r,(HL)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- Set_BusA_To(2 downto 0) <= DDD;
- Read_To_Reg <= '1';
- when others => null;
- end case;
- when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" =>
- -- LD (HL),r
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusB_To(3) <= '0';
- when 2 =>
- Write <= '1';
- when others => null;
- end case;
- when "00110110" =>
- -- LD (HL),n
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_Addr_To <= aXY;
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusB_To(3) <= '0';
- when 3 =>
- Write <= '1';
- when others => null;
- end case;
- when "00001010" =>
- -- LD A,(BC)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- when 2 =>
- Read_To_Acc <= '1';
- when others => null;
- end case;
- when "00011010" =>
- -- LD A,(DE)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aDE;
- when 2 =>
- Read_To_Acc <= '1';
- when others => null;
- end case;
- when "00111010" =>
- if Mode = 3 then
- -- LDD A,(HL)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- Read_To_Acc <= '1';
- IncDec_16 <= "1110";
- when others => null;
- end case;
- else
- -- LD A,(nn)
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- when 4 =>
- Read_To_Acc <= '1';
- when others => null;
- end case;
- end if;
- when "00000010" =>
- -- LD (BC),A
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- Set_BusB_To <= "0111";
- when 2 =>
- Write <= '1';
- when others => null;
- end case;
- when "00010010" =>
- -- LD (DE),A
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aDE;
- Set_BusB_To <= "0111";
- when 2 =>
- Write <= '1';
- when others => null;
- end case;
- when "00110010" =>
- if Mode = 3 then
- -- LDD (HL),A
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- Set_BusB_To <= "0111";
- when 2 =>
- Write <= '1';
- IncDec_16 <= "1110";
- when others => null;
- end case;
- else
- -- LD (nn),A
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- Set_BusB_To <= "0111";
- when 4 =>
- Write <= '1';
- when others => null;
- end case;
- end if;
-
--- 16 BIT LOAD GROUP
- when "00000001"|"00010001"|"00100001"|"00110001" =>
- -- LD dd,nn
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Read_To_Reg <= '1';
- if DPAIR = "11" then
- Set_BusA_To(3 downto 0) <= "1000";
- else
- Set_BusA_To(2 downto 1) <= DPAIR;
- Set_BusA_To(0) <= '1';
- end if;
- when 3 =>
- Inc_PC <= '1';
- Read_To_Reg <= '1';
- if DPAIR = "11" then
- Set_BusA_To(3 downto 0) <= "1001";
- else
- Set_BusA_To(2 downto 1) <= DPAIR;
- Set_BusA_To(0) <= '0';
- end if;
- when others => null;
- end case;
- when "00101010" =>
- if Mode = 3 then
- -- LDI A,(HL)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- Read_To_Acc <= '1';
- IncDec_16 <= "0110";
- when others => null;
- end case;
- else
- -- LD HL,(nn)
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- when 4 =>
- Set_BusA_To(2 downto 0) <= "101"; -- L
- Read_To_Reg <= '1';
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- when 5 =>
- Set_BusA_To(2 downto 0) <= "100"; -- H
- Read_To_Reg <= '1';
- when others => null;
- end case;
- end if;
- when "00100010" =>
- if Mode = 3 then
- -- LDI (HL),A
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- Set_BusB_To <= "0111";
- when 2 =>
- Write <= '1';
- IncDec_16 <= "0110";
- when others => null;
- end case;
- else
- -- LD (nn),HL
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- Set_BusB_To <= "0101"; -- L
- when 4 =>
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- Write <= '1';
- Set_BusB_To <= "0100"; -- H
- when 5 =>
- Write <= '1';
- when others => null;
- end case;
- end if;
- when "11111001" =>
- -- LD SP,HL
- TStates <= "110";
- LDSPHL <= '1';
- when "11000101"|"11010101"|"11100101"|"11110101" =>
- -- PUSH qq
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- IncDec_16 <= "1111";
- Set_Addr_TO <= aSP;
- if DPAIR = "11" then
- Set_BusB_To <= "0111";
- else
- Set_BusB_To(2 downto 1) <= DPAIR;
- Set_BusB_To(0) <= '0';
- Set_BusB_To(3) <= '0';
- end if;
- when 2 =>
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- if DPAIR = "11" then
- Set_BusB_To <= "1011";
- else
- Set_BusB_To(2 downto 1) <= DPAIR;
- Set_BusB_To(0) <= '1';
- Set_BusB_To(3) <= '0';
- end if;
- Write <= '1';
- when 3 =>
- Write <= '1';
- when others => null;
- end case;
- when "11000001"|"11010001"|"11100001"|"11110001" =>
- -- POP qq
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aSP;
- when 2 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- Read_To_Reg <= '1';
- if DPAIR = "11" then
- Set_BusA_To(3 downto 0) <= "1011";
- else
- Set_BusA_To(2 downto 1) <= DPAIR;
- Set_BusA_To(0) <= '1';
- end if;
- when 3 =>
- IncDec_16 <= "0111";
- Read_To_Reg <= '1';
- if DPAIR = "11" then
- Set_BusA_To(3 downto 0) <= "0111";
- else
- Set_BusA_To(2 downto 1) <= DPAIR;
- Set_BusA_To(0) <= '0';
- end if;
- when others => null;
- end case;
-
--- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP
- when "11101011" =>
- if Mode /= 3 then
- -- EX DE,HL
- ExchangeDH <= '1';
- end if;
- when "00001000" =>
- if Mode = 3 then
- -- LD (nn),SP
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- Set_BusB_To <= "1000";
- when 4 =>
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- Write <= '1';
- Set_BusB_To <= "1001";
- when 5 =>
- Write <= '1';
- when others => null;
- end case;
- elsif Mode < 2 then
- -- EX AF,AF'
- ExchangeAF <= '1';
- end if;
- when "11011001" =>
- if Mode = 3 then
- -- RETI
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_TO <= aSP;
- when 2 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- LDZ <= '1';
- when 3 =>
- Jump <= '1';
- IncDec_16 <= "0111";
- I_RETI <= '1';
- SetEI <= '1';
- when others => null;
- end case;
- elsif Mode < 2 then
- -- EXX
- ExchangeRS <= '1';
- end if;
- when "11100011" =>
- if Mode /= 3 then
- -- EX (SP),HL
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aSP;
- when 2 =>
- Read_To_Reg <= '1';
- Set_BusA_To <= "0101";
- Set_BusB_To <= "0101";
- Set_Addr_To <= aSP;
- when 3 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- TStates <= "100";
- Write <= '1';
- when 4 =>
- Read_To_Reg <= '1';
- Set_BusA_To <= "0100";
- Set_BusB_To <= "0100";
- Set_Addr_To <= aSP;
- when 5 =>
- IncDec_16 <= "1111";
- TStates <= "101";
- Write <= '1';
- when others => null;
- end case;
- end if;
-
--- 8 BIT ARITHMETIC AND LOGICAL GROUP
- when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
- |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
- |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
- |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
- |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
- |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
- |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
- |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
- -- ADD A,r
- -- ADC A,r
- -- SUB A,r
- -- SBC A,r
- -- AND A,r
- -- OR A,r
- -- XOR A,r
- -- CP A,r
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusA_To(2 downto 0) <= "111";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
- -- ADD A,(HL)
- -- ADC A,(HL)
- -- SUB A,(HL)
- -- SBC A,(HL)
- -- AND A,(HL)
- -- OR A,(HL)
- -- XOR A,(HL)
- -- CP A,(HL)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusA_To(2 downto 0) <= "111";
- when others => null;
- end case;
- when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
- -- ADD A,n
- -- ADC A,n
- -- SUB A,n
- -- SBC A,n
- -- AND A,n
- -- OR A,n
- -- XOR A,n
- -- CP A,n
- MCycles <= "010";
- if MCycle = "010" then
- Inc_PC <= '1';
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusA_To(2 downto 0) <= "111";
- end if;
- when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" =>
- -- INC r
- Set_BusB_To <= "1010";
- Set_BusA_To(2 downto 0) <= DDD;
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- PreserveC <= '1';
- ALU_Op <= "0000";
- when "00110100" =>
- -- INC (HL)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- TStates <= "100";
- Set_Addr_To <= aXY;
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- PreserveC <= '1';
- ALU_Op <= "0000";
- Set_BusB_To <= "1010";
- Set_BusA_To(2 downto 0) <= DDD;
- when 3 =>
- Write <= '1';
- when others => null;
- end case;
- when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" =>
- -- DEC r
- Set_BusB_To <= "1010";
- Set_BusA_To(2 downto 0) <= DDD;
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- PreserveC <= '1';
- ALU_Op <= "0010";
- when "00110101" =>
- -- DEC (HL)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- when 2 =>
- TStates <= "100";
- Set_Addr_To <= aXY;
- ALU_Op <= "0010";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- PreserveC <= '1';
- Set_BusB_To <= "1010";
- Set_BusA_To(2 downto 0) <= DDD;
- when 3 =>
- Write <= '1';
- when others => null;
- end case;
-
--- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS
- when "00100111" =>
- -- DAA
- Set_BusA_To(2 downto 0) <= "111";
- Read_To_Reg <= '1';
- ALU_Op <= "1100";
- Save_ALU <= '1';
- when "00101111" =>
- -- CPL
- I_CPL <= '1';
- when "00111111" =>
- -- CCF
- I_CCF <= '1';
- when "00110111" =>
- -- SCF
- I_SCF <= '1';
- when "00000000" =>
- if NMICycle = '1' then
- -- NMI
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1101";
- when 2 =>
- TStates <= "100";
- Write <= '1';
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1100";
- when 3 =>
- TStates <= "100";
- Write <= '1';
- when others => null;
- end case;
- elsif IntCycle = '1' then
- -- INT (IM 2)
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- LDZ <= '1';
- TStates <= "101";
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1101";
- when 2 =>
- TStates <= "100";
- Write <= '1';
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1100";
- when 3 =>
- TStates <= "100";
- Write <= '1';
- when 4 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 5 =>
- Jump <= '1';
- when others => null;
- end case;
- else
- -- NOP
- end if;
- when "01110110" =>
- -- HALT
- Halt <= '1';
- when "11110011" =>
- -- DI
- SetDI <= '1';
- when "11111011" =>
- -- EI
- SetEI <= '1';
-
--- 16 BIT ARITHMETIC GROUP
- when "00001001"|"00011001"|"00101001"|"00111001" =>
- -- ADD HL,ss
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- NoRead <= '1';
- ALU_Op <= "0000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusA_To(2 downto 0) <= "101";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '1';
- when others =>
- Set_BusB_To <= "1000";
- end case;
- TStates <= "100";
- Arith16 <= '1';
- when 3 =>
- NoRead <= '1';
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0001";
- Set_BusA_To(2 downto 0) <= "100";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- when others =>
- Set_BusB_To <= "1001";
- end case;
- Arith16 <= '1';
- when others =>
- end case;
- when "00000011"|"00010011"|"00100011"|"00110011" =>
- -- INC ss
- TStates <= "110";
- IncDec_16(3 downto 2) <= "01";
- IncDec_16(1 downto 0) <= DPair;
- when "00001011"|"00011011"|"00101011"|"00111011" =>
- -- DEC ss
- TStates <= "110";
- IncDec_16(3 downto 2) <= "11";
- IncDec_16(1 downto 0) <= DPair;
-
--- ROTATE AND SHIFT GROUP
- when "00000111"
- -- RLCA
- |"00010111"
- -- RLA
- |"00001111"
- -- RRCA
- |"00011111" =>
- -- RRA
- Set_BusA_To(2 downto 0) <= "111";
- ALU_Op <= "1000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
-
--- JUMP GROUP
- when "11000011" =>
- -- JP nn
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Inc_PC <= '1';
- Jump <= '1';
- when others => null;
- end case;
- when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
- if IR(5) = '1' and Mode = 3 then
- case IRB(4 downto 3) is
- when "00" =>
- -- LD ($FF00+C),A
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- Set_BusB_To <= "0111";
- when 2 =>
- Write <= '1';
- IORQ <= '1';
- when others =>
- end case;
- when "01" =>
- -- LD (nn),A
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- Set_BusB_To <= "0111";
- when 4 =>
- Write <= '1';
- when others => null;
- end case;
- when "10" =>
- -- LD A,($FF00+C)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- when 2 =>
- Read_To_Acc <= '1';
- IORQ <= '1';
- when others =>
- end case;
- when "11" =>
- -- LD A,(nn)
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- when 4 =>
- Read_To_Acc <= '1';
- when others => null;
- end case;
- end case;
- else
- -- JP cc,nn
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Inc_PC <= '1';
- if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
- Jump <= '1';
- end if;
- when others => null;
- end case;
- end if;
- when "00011000" =>
- if Mode /= 2 then
- -- JR e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
- when "00111000" =>
- if Mode /= 2 then
- -- JR C,e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- if F(Flag_C) = '0' then
- MCycles <= "010";
- end if;
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
- when "00110000" =>
- if Mode /= 2 then
- -- JR NC,e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- if F(Flag_C) = '1' then
- MCycles <= "010";
- end if;
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
- when "00101000" =>
- if Mode /= 2 then
- -- JR Z,e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- if F(Flag_Z) = '0' then
- MCycles <= "010";
- end if;
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
- when "00100000" =>
- if Mode /= 2 then
- -- JR NZ,e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- if F(Flag_Z) = '1' then
- MCycles <= "010";
- end if;
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
- when "11101001" =>
- -- JP (HL)
- JumpXY <= '1';
- when "00010000" =>
- if Mode = 3 then
- I_DJNZ <= '1';
- elsif Mode < 2 then
- -- DJNZ,e
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- I_DJNZ <= '1';
- Set_BusB_To <= "1010";
- Set_BusA_To(2 downto 0) <= "000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0010";
- when 2 =>
- I_DJNZ <= '1';
- Inc_PC <= '1';
- when 3 =>
- NoRead <= '1';
- JumpE <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end if;
-
--- CALL AND RETURN GROUP
- when "11001101" =>
- -- CALL nn
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- IncDec_16 <= "1111";
- Inc_PC <= '1';
- TStates <= "100";
- Set_Addr_To <= aSP;
- LDW <= '1';
- Set_BusB_To <= "1101";
- when 4 =>
- Write <= '1';
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1100";
- when 5 =>
- Write <= '1';
- Call <= '1';
- when others => null;
- end case;
- when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
- if IR(5) = '0' or Mode /= 3 then
- -- CALL cc,nn
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Inc_PC <= '1';
- LDW <= '1';
- if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
- IncDec_16 <= "1111";
- Set_Addr_TO <= aSP;
- TStates <= "100";
- Set_BusB_To <= "1101";
- else
- MCycles <= "011";
- end if;
- when 4 =>
- Write <= '1';
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1100";
- when 5 =>
- Write <= '1';
- Call <= '1';
- when others => null;
- end case;
- end if;
- when "11001001" =>
- -- RET
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- Set_Addr_TO <= aSP;
- when 2 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- LDZ <= '1';
- when 3 =>
- Jump <= '1';
- IncDec_16 <= "0111";
- when others => null;
- end case;
- when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
- if IR(5) = '1' and Mode = 3 then
- case IRB(4 downto 3) is
- when "00" =>
- -- LD ($FF00+nn),A
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_Addr_To <= aIOA;
- Set_BusB_To <= "0111";
- when 3 =>
- Write <= '1';
- when others => null;
- end case;
- when "01" =>
- -- ADD SP,n
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- ALU_Op <= "0000";
- Inc_PC <= '1';
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusA_To <= "1000";
- Set_BusB_To <= "0110";
- when 3 =>
- NoRead <= '1';
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0001";
- Set_BusA_To <= "1001";
- Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
- when others =>
- end case;
- when "10" =>
- -- LD A,($FF00+nn)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_Addr_To <= aIOA;
- when 3 =>
- Read_To_Acc <= '1';
- when others => null;
- end case;
- when "11" =>
- -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- when 4 =>
- Set_BusA_To(2 downto 0) <= "101"; -- L
- Read_To_Reg <= '1';
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- when 5 =>
- Set_BusA_To(2 downto 0) <= "100"; -- H
- Read_To_Reg <= '1';
- when others => null;
- end case;
- end case;
- else
- -- RET cc
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
- Set_Addr_TO <= aSP;
- else
- MCycles <= "001";
- end if;
- TStates <= "101";
- when 2 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- LDZ <= '1';
- when 3 =>
- Jump <= '1';
- IncDec_16 <= "0111";
- when others => null;
- end case;
- end if;
- when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
- -- RST p
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1101";
- when 2 =>
- Write <= '1';
- IncDec_16 <= "1111";
- Set_Addr_To <= aSP;
- Set_BusB_To <= "1100";
- when 3 =>
- Write <= '1';
- RstP <= '1';
- when others => null;
- end case;
-
--- INPUT AND OUTPUT GROUP
- when "11011011" =>
- if Mode /= 3 then
- -- IN A,(n)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_Addr_To <= aIOA;
- when 3 =>
- Read_To_Acc <= '1';
- IORQ <= '1';
- when others => null;
- end case;
- end if;
- when "11010011" =>
- if Mode /= 3 then
- -- OUT (n),A
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- Set_Addr_To <= aIOA;
- Set_BusB_To <= "0111";
- when 3 =>
- Write <= '1';
- IORQ <= '1';
- when others => null;
- end case;
- end if;
-
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- MULTIBYTE INSTRUCTIONS
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-
- when "11001011" =>
- if Mode /= 2 then
- Prefix <= "01";
- end if;
-
- when "11101101" =>
- if Mode < 2 then
- Prefix <= "10";
- end if;
-
- when "11011101"|"11111101" =>
- if Mode < 2 then
- Prefix <= "11";
- end if;
-
- end case;
-
- when "01" =>
-
-------------------------------------------------------------------------------
---
--- CB prefixed instructions
---
-------------------------------------------------------------------------------
-
- Set_BusA_To(2 downto 0) <= IR(2 downto 0);
- Set_BusB_To(2 downto 0) <= IR(2 downto 0);
-
- case IRB is
- when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111"
- |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111"
- |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111"
- |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111"
- |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111"
- |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111"
- |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111"
- |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" =>
- -- RLC r
- -- RL r
- -- RRC r
- -- RR r
- -- SLA r
- -- SRA r
- -- SRL r
- -- SLL r (Undocumented) / SWAP r
- if MCycle = "001" then
- ALU_Op <= "1000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- end if;
- when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" =>
- -- RLC (HL)
- -- RL (HL)
- -- RRC (HL)
- -- RR (HL)
- -- SRA (HL)
- -- SRL (HL)
- -- SLA (HL)
- -- SLL (HL) (Undocumented) / SWAP (HL)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 | 7 =>
- Set_Addr_To <= aXY;
- when 2 =>
- ALU_Op <= "1000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_Addr_To <= aXY;
- TStates <= "100";
- when 3 =>
- Write <= '1';
- when others =>
- end case;
- when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
- |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
- |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
- |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
- |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
- |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
- |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111"
- |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
- -- BIT b,r
- if MCycle = "001" then
- Set_BusB_To(2 downto 0) <= IR(2 downto 0);
- ALU_Op <= "1001";
- end if;
- when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" =>
- -- BIT b,(HL)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 | 7 =>
- Set_Addr_To <= aXY;
- when 2 =>
- ALU_Op <= "1001";
- TStates <= "100";
- when others =>
- end case;
- when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111"
- |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111"
- |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111"
- |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111"
- |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111"
- |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111"
- |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111"
- |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" =>
- -- SET b,r
- if MCycle = "001" then
- ALU_Op <= "1010";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- end if;
- when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
- -- SET b,(HL)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 | 7 =>
- Set_Addr_To <= aXY;
- when 2 =>
- ALU_Op <= "1010";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_Addr_To <= aXY;
- TStates <= "100";
- when 3 =>
- Write <= '1';
- when others =>
- end case;
- when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
- |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
- |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
- |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
- |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
- |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
- |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
- |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
- -- RES b,r
- if MCycle = "001" then
- ALU_Op <= "1011";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- end if;
- when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
- -- RES b,(HL)
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 | 7 =>
- Set_Addr_To <= aXY;
- when 2 =>
- ALU_Op <= "1011";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_Addr_To <= aXY;
- TStates <= "100";
- when 3 =>
- Write <= '1';
- when others =>
- end case;
- end case;
-
- when others =>
-
-------------------------------------------------------------------------------
---
--- ED prefixed instructions
---
-------------------------------------------------------------------------------
-
- case IRB is
- when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111"
- |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111"
- |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111"
- |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111"
- |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111"
- |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111"
- |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111"
- |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111"
-
-
- |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111"
- |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111"
- |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111"
- |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111"
- | "10100100"|"10100101"|"10100110"|"10100111"
- | "10101100"|"10101101"|"10101110"|"10101111"
- | "10110100"|"10110101"|"10110110"|"10110111"
- | "10111100"|"10111101"|"10111110"|"10111111"
- |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
- |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
- |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
- |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
- |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
- |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111"
- |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111"
- |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
- null; -- NOP, undocumented
- when "01111110"|"01111111" =>
- -- NOP, undocumented
- null;
--- 8 BIT LOAD GROUP
- when "01010111" =>
- -- LD A,I
- Special_LD <= "100";
- TStates <= "101";
- when "01011111" =>
- -- LD A,R
- Special_LD <= "101";
- TStates <= "101";
- when "01000111" =>
- -- LD I,A
- Special_LD <= "110";
- TStates <= "101";
- when "01001111" =>
- -- LD R,A
- Special_LD <= "111";
- TStates <= "101";
--- 16 BIT LOAD GROUP
- when "01001011"|"01011011"|"01101011"|"01111011" =>
- -- LD dd,(nn)
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- when 4 =>
- Read_To_Reg <= '1';
- if IR(5 downto 4) = "11" then
- Set_BusA_To <= "1000";
- else
- Set_BusA_To(2 downto 1) <= IR(5 downto 4);
- Set_BusA_To(0) <= '1';
- end if;
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- when 5 =>
- Read_To_Reg <= '1';
- if IR(5 downto 4) = "11" then
- Set_BusA_To <= "1001";
- else
- Set_BusA_To(2 downto 1) <= IR(5 downto 4);
- Set_BusA_To(0) <= '0';
- end if;
- when others => null;
- end case;
- when "01000011"|"01010011"|"01100011"|"01110011" =>
- -- LD (nn),dd
- MCycles <= "101";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Inc_PC <= '1';
- LDZ <= '1';
- when 3 =>
- Set_Addr_To <= aZI;
- Inc_PC <= '1';
- LDW <= '1';
- if IR(5 downto 4) = "11" then
- Set_BusB_To <= "1000";
- else
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '1';
- Set_BusB_To(3) <= '0';
- end if;
- when 4 =>
- Inc_WZ <= '1';
- Set_Addr_To <= aZI;
- Write <= '1';
- if IR(5 downto 4) = "11" then
- Set_BusB_To <= "1001";
- else
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '0';
- Set_BusB_To(3) <= '0';
- end if;
- when 5 =>
- Write <= '1';
- when others => null;
- end case;
- when "10100000" | "10101000" | "10110000" | "10111000" =>
- -- LDI, LDD, LDIR, LDDR
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- IncDec_16 <= "1100"; -- BC
- when 2 =>
- Set_BusB_To <= "0110";
- Set_BusA_To(2 downto 0) <= "111";
- ALU_Op <= "0000";
- Set_Addr_To <= aDE;
- if IR(3) = '0' then
- IncDec_16 <= "0110"; -- IX
- else
- IncDec_16 <= "1110";
- end if;
- when 3 =>
- I_BT <= '1';
- TStates <= "101";
- Write <= '1';
- if IR(3) = '0' then
- IncDec_16 <= "0101"; -- DE
- else
- IncDec_16 <= "1101";
- end if;
- when 4 =>
- NoRead <= '1';
- TStates <= "101";
- when others => null;
- end case;
- when "10100001" | "10101001" | "10110001" | "10111001" =>
- -- CPI, CPD, CPIR, CPDR
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aXY;
- IncDec_16 <= "1100"; -- BC
- when 2 =>
- Set_BusB_To <= "0110";
- Set_BusA_To(2 downto 0) <= "111";
- ALU_Op <= "0111";
- Save_ALU <= '1';
- PreserveC <= '1';
- if IR(3) = '0' then
- IncDec_16 <= "0110";
- else
- IncDec_16 <= "1110";
- end if;
- when 3 =>
- NoRead <= '1';
- I_BC <= '1';
- TStates <= "101";
- when 4 =>
- NoRead <= '1';
- TStates <= "101";
- when others => null;
- end case;
- when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" =>
- -- NEG
- Alu_OP <= "0010";
- Set_BusB_To <= "0111";
- Set_BusA_To <= "1010";
- Read_To_Acc <= '1';
- Save_ALU <= '1';
- when "01000110"|"01001110"|"01100110"|"01101110" =>
- -- IM 0
- IMode <= "00";
- when "01010110"|"01110110" =>
- -- IM 1
- IMode <= "01";
- when "01011110"|"01110111" =>
- -- IM 2
- IMode <= "10";
--- 16 bit arithmetic
- when "01001010"|"01011010"|"01101010"|"01111010" =>
- -- ADC HL,ss
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- NoRead <= '1';
- ALU_Op <= "0001";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusA_To(2 downto 0) <= "101";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '1';
- when others =>
- Set_BusB_To <= "1000";
- end case;
- TStates <= "100";
- when 3 =>
- NoRead <= '1';
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0001";
- Set_BusA_To(2 downto 0) <= "100";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '0';
- when others =>
- Set_BusB_To <= "1001";
- end case;
- when others =>
- end case;
- when "01000010"|"01010010"|"01100010"|"01110010" =>
- -- SBC HL,ss
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- NoRead <= '1';
- ALU_Op <= "0011";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusA_To(2 downto 0) <= "101";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- Set_BusB_To(0) <= '1';
- when others =>
- Set_BusB_To <= "1000";
- end case;
- TStates <= "100";
- when 3 =>
- NoRead <= '1';
- ALU_Op <= "0011";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- Set_BusA_To(2 downto 0) <= "100";
- case to_integer(unsigned(IR(5 downto 4))) is
- when 0|1|2 =>
- Set_BusB_To(2 downto 1) <= IR(5 downto 4);
- when others =>
- Set_BusB_To <= "1001";
- end case;
- when others =>
- end case;
- when "01101111" =>
- -- RLD
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- NoRead <= '1';
- Set_Addr_To <= aXY;
- when 3 =>
- Read_To_Reg <= '1';
- Set_BusB_To(2 downto 0) <= "110";
- Set_BusA_To(2 downto 0) <= "111";
- ALU_Op <= "1101";
- TStates <= "100";
- Set_Addr_To <= aXY;
- Save_ALU <= '1';
- when 4 =>
- I_RLD <= '1';
- Write <= '1';
- when others =>
- end case;
- when "01100111" =>
- -- RRD
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 2 =>
- Set_Addr_To <= aXY;
- when 3 =>
- Read_To_Reg <= '1';
- Set_BusB_To(2 downto 0) <= "110";
- Set_BusA_To(2 downto 0) <= "111";
- ALU_Op <= "1110";
- TStates <= "100";
- Set_Addr_To <= aXY;
- Save_ALU <= '1';
- when 4 =>
- I_RRD <= '1';
- Write <= '1';
- when others =>
- end case;
- when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" =>
- -- RETI, RETN
- MCycles <= "011";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_TO <= aSP;
- when 2 =>
- IncDec_16 <= "0111";
- Set_Addr_To <= aSP;
- LDZ <= '1';
- when 3 =>
- Jump <= '1';
- IncDec_16 <= "0111";
- I_RETI <= IR(3);
- I_RETN <= not IR(3);
- when others => null;
- end case;
- when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" =>
- -- IN r,(C)
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- when 2 =>
- IORQ <= '1';
- if IR(5 downto 3) /= "110" then
- Read_To_Reg <= '1';
- Set_BusA_To(2 downto 0) <= IR(5 downto 3);
- end if;
- I_INRC <= '1';
- when others =>
- end case;
- when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" =>
- -- OUT (C),r
- -- OUT (C),0
- MCycles <= "010";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- Set_BusB_To(2 downto 0) <= IR(5 downto 3);
- if IR(5 downto 3) = "110" then
- Set_BusB_To(3) <= '1';
- end if;
- when 2 =>
- Write <= '1';
- IORQ <= '1';
- when others =>
- end case;
- when "10100010" | "10101010" | "10110010" | "10111010" =>
- -- INI, IND, INIR, INDR
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- Set_Addr_To <= aBC;
- Set_BusB_To <= "1010";
- Set_BusA_To <= "0000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0010";
- when 2 =>
- IORQ <= '1';
- Set_BusB_To <= "0110";
- Set_Addr_To <= aXY;
- when 3 =>
- if IR(3) = '0' then
- IncDec_16 <= "0110";
- else
- IncDec_16 <= "1110";
- end if;
- TStates <= "100";
- Write <= '1';
- I_BTR <= '1';
- when 4 =>
- NoRead <= '1';
- TStates <= "101";
- when others => null;
- end case;
- when "10100011" | "10101011" | "10110011" | "10111011" =>
- -- OUTI, OUTD, OTIR, OTDR
- MCycles <= "100";
- case to_integer(unsigned(MCycle)) is
- when 1 =>
- TStates <= "101";
- Set_Addr_To <= aXY;
- Set_BusB_To <= "1010";
- Set_BusA_To <= "0000";
- Read_To_Reg <= '1';
- Save_ALU <= '1';
- ALU_Op <= "0010";
- when 2 =>
- Set_BusB_To <= "0110";
- Set_Addr_To <= aBC;
- when 3 =>
- if IR(3) = '0' then
- IncDec_16 <= "0110";
- else
- IncDec_16 <= "1110";
- end if;
- IORQ <= '1';
- Write <= '1';
- I_BTR <= '1';
- when 4 =>
- NoRead <= '1';
- TStates <= "101";
- when others => null;
- end case;
- end case;
-
- end case;
-
- if Mode = 1 then
- if MCycle = "001" then
--- TStates <= "100";
- else
- TStates <= "011";
- end if;
- end if;
-
- if Mode = 3 then
- if MCycle = "001" then
--- TStates <= "100";
- else
- TStates <= "100";
- end if;
- end if;
-
- if Mode < 2 then
- if MCycle = "110" then
- Inc_PC <= '1';
- if Mode = 1 then
- Set_Addr_To <= aXY;
- TStates <= "100";
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusB_To(3) <= '0';
- end if;
- if IRB = "00110110" or IRB = "11001011" then
- Set_Addr_To <= aNone;
- end if;
- end if;
- if MCycle = "111" then
- if Mode = 0 then
- TStates <= "101";
- end if;
- if ISet /= "01" then
- Set_Addr_To <= aXY;
- end if;
- Set_BusB_To(2 downto 0) <= SSS;
- Set_BusB_To(3) <= '0';
- if IRB = "00110110" or ISet = "01" then
- -- LD (HL),n
- Inc_PC <= '1';
- else
- NoRead <= '1';
- end if;
- end if;
- end if;
-
- end process;
-
-end;
diff --git a/t80/T80_Pack.vhd b/t80/T80_Pack.vhd
deleted file mode 100644
index a9b2bb9..0000000
--- a/t80/T80_Pack.vhd
+++ /dev/null
@@ -1,210 +0,0 @@
---
--- Z80 compatible microprocessor core
---
--- Version : 0242
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-
-package T80_Pack is
-
- component T80
- generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- CEN : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- IORQ : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- RETI_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DInst : in std_logic_vector(7 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0);
- MC : out std_logic_vector(2 downto 0);
- TS : out std_logic_vector(2 downto 0);
- IntCycle_n : out std_logic;
- IntE : out std_logic;
- Stop : out std_logic
- );
- end component;
-
- component T80_Reg
- port(
- Clk : in std_logic;
- CEN : in std_logic;
- WEH : in std_logic;
- WEL : in std_logic;
- AddrA : in std_logic_vector(2 downto 0);
- AddrB : in std_logic_vector(2 downto 0);
- AddrC : in std_logic_vector(2 downto 0);
- DIH : in std_logic_vector(7 downto 0);
- DIL : in std_logic_vector(7 downto 0);
- DOAH : out std_logic_vector(7 downto 0);
- DOAL : out std_logic_vector(7 downto 0);
- DOBH : out std_logic_vector(7 downto 0);
- DOBL : out std_logic_vector(7 downto 0);
- DOCH : out std_logic_vector(7 downto 0);
- DOCL : out std_logic_vector(7 downto 0)
- );
- end component;
-
- component T80_MCode
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- IR : in std_logic_vector(7 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- MCycle : in std_logic_vector(2 downto 0);
- F : in std_logic_vector(7 downto 0);
- NMICycle : in std_logic;
- IntCycle : in std_logic;
- MCycles : out std_logic_vector(2 downto 0);
- TStates : out std_logic_vector(2 downto 0);
- Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
- Inc_PC : out std_logic;
- Inc_WZ : out std_logic;
- IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
- Read_To_Reg : out std_logic;
- Read_To_Acc : out std_logic;
- Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
- Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
- ALU_Op : out std_logic_vector(3 downto 0);
- -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
- Save_ALU : out std_logic;
- PreserveC : out std_logic;
- Arith16 : out std_logic;
- Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
- IORQ : out std_logic;
- Jump : out std_logic;
- JumpE : out std_logic;
- JumpXY : out std_logic;
- Call : out std_logic;
- RstP : out std_logic;
- LDZ : out std_logic;
- LDW : out std_logic;
- LDSPHL : out std_logic;
- Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
- ExchangeDH : out std_logic;
- ExchangeRp : out std_logic;
- ExchangeAF : out std_logic;
- ExchangeRS : out std_logic;
- I_DJNZ : out std_logic;
- I_CPL : out std_logic;
- I_CCF : out std_logic;
- I_SCF : out std_logic;
- I_RETI : out std_logic;
- I_RETN : out std_logic;
- I_BT : out std_logic;
- I_BC : out std_logic;
- I_BTR : out std_logic;
- I_RLD : out std_logic;
- I_RRD : out std_logic;
- I_INRC : out std_logic;
- SetDI : out std_logic;
- SetEI : out std_logic;
- IMode : out std_logic_vector(1 downto 0);
- Halt : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic
- );
- end component;
-
- component T80_ALU
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- Arith16 : in std_logic;
- Z16 : in std_logic;
- ALU_Op : in std_logic_vector(3 downto 0);
- IR : in std_logic_vector(5 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- BusA : in std_logic_vector(7 downto 0);
- BusB : in std_logic_vector(7 downto 0);
- F_In : in std_logic_vector(7 downto 0);
- Q : out std_logic_vector(7 downto 0);
- F_Out : out std_logic_vector(7 downto 0)
- );
- end component;
-
-end;
diff --git a/t80/T80_Reg.vhd b/t80/T80_Reg.vhd
deleted file mode 100644
index 828485f..0000000
--- a/t80/T80_Reg.vhd
+++ /dev/null
@@ -1,105 +0,0 @@
---
--- T80 Registers, technology independent
---
--- Version : 0244
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t51/
---
--- Limitations :
---
--- File history :
---
--- 0242 : Initial release
---
--- 0244 : Changed to single register file
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity T80_Reg is
- port(
- Clk : in std_logic;
- CEN : in std_logic;
- WEH : in std_logic;
- WEL : in std_logic;
- AddrA : in std_logic_vector(2 downto 0);
- AddrB : in std_logic_vector(2 downto 0);
- AddrC : in std_logic_vector(2 downto 0);
- DIH : in std_logic_vector(7 downto 0);
- DIL : in std_logic_vector(7 downto 0);
- DOAH : out std_logic_vector(7 downto 0);
- DOAL : out std_logic_vector(7 downto 0);
- DOBH : out std_logic_vector(7 downto 0);
- DOBL : out std_logic_vector(7 downto 0);
- DOCH : out std_logic_vector(7 downto 0);
- DOCL : out std_logic_vector(7 downto 0)
- );
-end T80_Reg;
-
-architecture rtl of T80_Reg is
-
- type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
- signal RegsH : Register_Image(0 to 7);
- signal RegsL : Register_Image(0 to 7);
-
-begin
-
- process (Clk)
- begin
- if Clk'event and Clk = '1' then
- if CEN = '1' then
- if WEH = '1' then
- RegsH(to_integer(unsigned(AddrA))) <= DIH;
- end if;
- if WEL = '1' then
- RegsL(to_integer(unsigned(AddrA))) <= DIL;
- end if;
- end if;
- end if;
- end process;
-
- DOAH <= RegsH(to_integer(unsigned(AddrA)));
- DOAL <= RegsL(to_integer(unsigned(AddrA)));
- DOBH <= RegsH(to_integer(unsigned(AddrB)));
- DOBL <= RegsL(to_integer(unsigned(AddrB)));
- DOCH <= RegsH(to_integer(unsigned(AddrC)));
- DOCL <= RegsL(to_integer(unsigned(AddrC)));
-
-end;
diff --git a/t80/T80_RegX.vhd b/t80/T80_RegX.vhd
deleted file mode 100644
index 11396be..0000000
--- a/t80/T80_RegX.vhd
+++ /dev/null
@@ -1,167 +0,0 @@
---
--- T80 Registers for Xilinx Select RAM
---
--- Version : 0244
---
--- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t51/
---
--- Limitations :
---
--- File history :
---
--- 0242 : Initial release
---
--- 0244 : Removed UNISIM library and added componet declaration
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-entity T80_Reg is
- port(
- Clk : in std_logic;
- CEN : in std_logic;
- WEH : in std_logic;
- WEL : in std_logic;
- AddrA : in std_logic_vector(2 downto 0);
- AddrB : in std_logic_vector(2 downto 0);
- AddrC : in std_logic_vector(2 downto 0);
- DIH : in std_logic_vector(7 downto 0);
- DIL : in std_logic_vector(7 downto 0);
- DOAH : out std_logic_vector(7 downto 0);
- DOAL : out std_logic_vector(7 downto 0);
- DOBH : out std_logic_vector(7 downto 0);
- DOBL : out std_logic_vector(7 downto 0);
- DOCH : out std_logic_vector(7 downto 0);
- DOCL : out std_logic_vector(7 downto 0)
- );
-end T80_Reg;
-
-architecture rtl of T80_Reg is
-
- component RAM16X1D
- port(
- DPO : out std_ulogic;
- SPO : out std_ulogic;
- A0 : in std_ulogic;
- A1 : in std_ulogic;
- A2 : in std_ulogic;
- A3 : in std_ulogic;
- D : in std_ulogic;
- DPRA0 : in std_ulogic;
- DPRA1 : in std_ulogic;
- DPRA2 : in std_ulogic;
- DPRA3 : in std_ulogic;
- WCLK : in std_ulogic;
- WE : in std_ulogic);
- end component;
-
- signal ENH : std_logic;
- signal ENL : std_logic;
-
-begin
-
- ENH <= CEN and WEH;
- ENL <= CEN and WEL;
-
- bG1: for I in 0 to 7 generate
- begin
- Reg1H : RAM16X1D
- port map(
- DPO => DOBH(i),
- SPO => DOAH(i),
- A0 => AddrA(0),
- A1 => AddrA(1),
- A2 => AddrA(2),
- A3 => '0',
- D => DIH(i),
- DPRA0 => AddrB(0),
- DPRA1 => AddrB(1),
- DPRA2 => AddrB(2),
- DPRA3 => '0',
- WCLK => Clk,
- WE => ENH);
- Reg1L : RAM16X1D
- port map(
- DPO => DOBL(i),
- SPO => DOAL(i),
- A0 => AddrA(0),
- A1 => AddrA(1),
- A2 => AddrA(2),
- A3 => '0',
- D => DIL(i),
- DPRA0 => AddrB(0),
- DPRA1 => AddrB(1),
- DPRA2 => AddrB(2),
- DPRA3 => '0',
- WCLK => Clk,
- WE => ENL);
- Reg2H : RAM16X1D
- port map(
- DPO => DOCH(i),
- SPO => open,
- A0 => AddrA(0),
- A1 => AddrA(1),
- A2 => AddrA(2),
- A3 => '0',
- D => DIH(i),
- DPRA0 => AddrC(0),
- DPRA1 => AddrC(1),
- DPRA2 => AddrC(2),
- DPRA3 => '0',
- WCLK => Clk,
- WE => ENH);
- Reg2L : RAM16X1D
- port map(
- DPO => DOCL(i),
- SPO => open,
- A0 => AddrA(0),
- A1 => AddrA(1),
- A2 => AddrA(2),
- A3 => '0',
- D => DIL(i),
- DPRA0 => AddrC(0),
- DPRA1 => AddrC(1),
- DPRA2 => AddrC(2),
- DPRA3 => '0',
- WCLK => Clk,
- WE => ENL);
- end generate;
-
-end;
diff --git a/t80/T80a.vhd b/t80/T80a.vhd
deleted file mode 100644
index b3d7611..0000000
--- a/t80/T80a.vhd
+++ /dev/null
@@ -1,255 +0,0 @@
---
--- Z80 compatible microprocessor core, asynchronous top level
---
--- Version : 0247
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0208 : First complete release
---
--- 0211 : Fixed interrupt cycle
---
--- 0235 : Updated for T80 interface change
---
--- 0238 : Updated for T80 interface change
---
--- 0240 : Updated for T80 interface change
---
--- 0242 : Updated for T80 interface change
---
--- 0247 : Fixed bus req/ack cycle
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-use work.T80_Pack.all;
-
-entity T80a is
- generic(
- Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- MREQ_n : out std_logic;
- IORQ_n : out std_logic;
- RD_n : out std_logic;
- WR_n : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- RETI_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- D : inout std_logic_vector(7 downto 0)
- );
-end T80a;
-
-architecture rtl of T80a is
-
- signal CEN : std_logic;
- signal Reset_s : std_logic;
- signal IntCycle_n : std_logic;
- signal IORQ : std_logic;
- signal NoRead : std_logic;
- signal Write : std_logic;
- signal MREQ : std_logic;
- signal MReq_Inhibit : std_logic;
- signal Req_Inhibit : std_logic;
- signal RD : std_logic;
- signal MREQ_n_i : std_logic;
- signal IORQ_n_i : std_logic;
- signal RD_n_i : std_logic;
- signal WR_n_i : std_logic;
- signal RFSH_n_i : std_logic;
- signal BUSAK_n_i : std_logic;
- signal A_i : std_logic_vector(15 downto 0);
- signal DO : std_logic_vector(7 downto 0);
- signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
- signal Wait_s : std_logic;
- signal MCycle : std_logic_vector(2 downto 0);
- signal TState : std_logic_vector(2 downto 0);
-
-begin
-
- CEN <= '1';
-
- BUSAK_n <= BUSAK_n_i;
- MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
- RD_n_i <= not RD or Req_Inhibit;
-
- MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
- IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
- RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
- WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
- RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
- A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
- D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
-
- process (RESET_n, CLK_n)
- begin
- if RESET_n = '0' then
- Reset_s <= '0';
- elsif CLK_n'event and CLK_n = '1' then
- Reset_s <= '1';
- end if;
- end process;
-
- u0 : T80
- generic map(
- Mode => Mode,
- IOWait => 1)
- port map(
- CEN => CEN,
- M1_n => M1_n,
- IORQ => IORQ,
- NoRead => NoRead,
- Write => Write,
- RFSH_n => RFSH_n_i,
- HALT_n => HALT_n,
- WAIT_n => Wait_s,
- INT_n => INT_n,
- NMI_n => NMI_n,
- RESET_n => Reset_s,
- BUSRQ_n => BUSRQ_n,
- BUSAK_n => BUSAK_n_i,
- RETI_n => RETI_n,
- CLK_n => CLK_n,
- A => A_i,
- DInst => D,
- DI => DI_Reg,
- DO => DO,
- MC => MCycle,
- TS => TState,
- IntCycle_n => IntCycle_n);
-
- process (CLK_n)
- begin
- if CLK_n'event and CLK_n = '0' then
- Wait_s <= WAIT_n;
- if TState = "011" and BUSAK_n_i = '1' then
- DI_Reg <= to_x01(D);
- end if;
- end if;
- end process;
-
- process (Reset_s,CLK_n)
- begin
- if Reset_s = '0' then
- WR_n_i <= '1';
- elsif CLK_n'event and CLK_n = '1' then
- WR_n_i <= '1';
- if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
- WR_n_i <= not Write;
- end if;
- end if;
- end process;
-
- process (Reset_s,CLK_n)
- begin
- if Reset_s = '0' then
- Req_Inhibit <= '0';
- elsif CLK_n'event and CLK_n = '1' then
- if MCycle = "001" and TState = "010" then
- Req_Inhibit <= '1';
- else
- Req_Inhibit <= '0';
- end if;
- end if;
- end process;
-
- process (Reset_s,CLK_n)
- begin
- if Reset_s = '0' then
- MReq_Inhibit <= '0';
- elsif CLK_n'event and CLK_n = '0' then
- if MCycle = "001" and TState = "010" then
- MReq_Inhibit <= '1';
- else
- MReq_Inhibit <= '0';
- end if;
- end if;
- end process;
-
- process(Reset_s,CLK_n)
- begin
- if Reset_s = '0' then
- RD <= '0';
- IORQ_n_i <= '1';
- MREQ <= '0';
- elsif CLK_n'event and CLK_n = '0' then
-
- if MCycle = "001" then
- if TState = "001" then
- RD <= IntCycle_n;
- MREQ <= IntCycle_n;
- IORQ_n_i <= IntCycle_n;
- end if;
- if TState = "011" then
- RD <= '0';
- IORQ_n_i <= '1';
- MREQ <= '1';
- end if;
- if TState = "100" then
- MREQ <= '0';
- end if;
- else
- if TState = "001" and NoRead = '0' then
- RD <= not Write;
- IORQ_n_i <= not IORQ;
- MREQ <= not IORQ;
- end if;
- if TState = "011" then
- RD <= '0';
- IORQ_n_i <= '1';
- MREQ <= '0';
- end if;
- end if;
- end if;
- end process;
-
-end;
diff --git a/t80/T80s.vhd b/t80/T80s.vhd
deleted file mode 100644
index 960b729..0000000
--- a/t80/T80s.vhd
+++ /dev/null
@@ -1,192 +0,0 @@
---
--- Z80 compatible microprocessor core, synchronous top level
--- Different timing than the original z80
--- Inputs needs to be synchronous and outputs may glitch
---
--- Version : 0242
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0208 : First complete release
---
--- 0210 : Fixed read with wait
---
--- 0211 : Fixed interrupt cycle
---
--- 0235 : Updated for T80 interface change
---
--- 0236 : Added T2Write generic
---
--- 0237 : Fixed T2Write with wait state
---
--- 0238 : Updated for T80 interface change
---
--- 0240 : Updated for T80 interface change
---
--- 0242 : Updated for T80 interface change
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-use work.T80_Pack.all;
-
-entity T80s is
- generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
- IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- MREQ_n : out std_logic;
- IORQ_n : out std_logic;
- RD_n : out std_logic;
- WR_n : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- RETI_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0)
- );
-end T80s;
-
-architecture rtl of T80s is
-
- signal CEN : std_logic;
- signal IntCycle_n : std_logic;
- signal NoRead : std_logic;
- signal Write : std_logic;
- signal IORQ : std_logic;
- signal DI_Reg : std_logic_vector(7 downto 0);
- signal MCycle : std_logic_vector(2 downto 0);
- signal TState : std_logic_vector(2 downto 0);
-
-begin
-
- CEN <= '1';
-
- u0 : T80
- generic map(
- Mode => Mode,
- IOWait => IOWait)
- port map(
- CEN => CEN,
- M1_n => M1_n,
- IORQ => IORQ,
- NoRead => NoRead,
- Write => Write,
- RFSH_n => RFSH_n,
- HALT_n => HALT_n,
- WAIT_n => Wait_n,
- INT_n => INT_n,
- NMI_n => NMI_n,
- RESET_n => RESET_n,
- BUSRQ_n => BUSRQ_n,
- BUSAK_n => BUSAK_n,
- RETI_n => RETI_n,
- CLK_n => CLK_n,
- A => A,
- DInst => DI,
- DI => DI_Reg,
- DO => DO,
- MC => MCycle,
- TS => TState,
- IntCycle_n => IntCycle_n);
-
- process (RESET_n, CLK_n)
- begin
- if RESET_n = '0' then
- RD_n <= '1';
- WR_n <= '1';
- IORQ_n <= '1';
- MREQ_n <= '1';
- DI_Reg <= "00000000";
- elsif CLK_n'event and CLK_n = '1' then
- RD_n <= '1';
- WR_n <= '1';
- IORQ_n <= '1';
- MREQ_n <= '1';
- if MCycle = "001" then
- if TState = "001" or (TState = "010" and Wait_n = '0') then
- RD_n <= not IntCycle_n;
- MREQ_n <= not IntCycle_n;
- IORQ_n <= IntCycle_n;
- end if;
- if TState = "011" then
- MREQ_n <= '0';
- end if;
- else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
- RD_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- if T2Write = 0 then
- if TState = "010" and Write = '1' then
- WR_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
- WR_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- end if;
- end if;
- if TState = "010" and Wait_n = '1' then
- DI_Reg <= DI;
- end if;
- end if;
- end process;
-
-end;
diff --git a/t80/T80se.vhd b/t80/T80se.vhd
deleted file mode 100644
index 279967d..0000000
--- a/t80/T80se.vhd
+++ /dev/null
@@ -1,186 +0,0 @@
---
--- Z80 compatible microprocessor core, synchronous top level with clock enable
--- Different timing than the original z80
--- Inputs needs to be synchronous and outputs may glitch
---
--- Version : 0242
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
--- 0235 : First release
---
--- 0236 : Added T2Write generic
---
--- 0237 : Fixed T2Write with wait state
---
--- 0238 : Updated for T80 interface change
---
--- 0240 : Updated for T80 interface change
---
--- 0242 : Updated for T80 interface change
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-use work.T80_Pack.all;
-
-entity T80se is
- generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
- IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- CLKEN : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- MREQ_n : out std_logic;
- IORQ_n : out std_logic;
- RD_n : out std_logic;
- WR_n : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- RETI_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0)
- );
-end T80se;
-
-architecture rtl of T80se is
-
- signal IntCycle_n : std_logic;
- signal NoRead : std_logic;
- signal Write : std_logic;
- signal IORQ : std_logic;
- signal DI_Reg : std_logic_vector(7 downto 0);
- signal MCycle : std_logic_vector(2 downto 0);
- signal TState : std_logic_vector(2 downto 0);
-
-begin
-
- u0 : T80
- generic map(
- Mode => Mode,
- IOWait => IOWait)
- port map(
- CEN => CLKEN,
- M1_n => M1_n,
- IORQ => IORQ,
- NoRead => NoRead,
- Write => Write,
- RFSH_n => RFSH_n,
- HALT_n => HALT_n,
- WAIT_n => Wait_n,
- INT_n => INT_n,
- NMI_n => NMI_n,
- RESET_n => RESET_n,
- BUSRQ_n => BUSRQ_n,
- BUSAK_n => BUSAK_n,
- RETI_n => RETI_n,
- CLK_n => CLK_n,
- A => A,
- DInst => DI,
- DI => DI_Reg,
- DO => DO,
- MC => MCycle,
- TS => TState,
- IntCycle_n => IntCycle_n);
-
- process (RESET_n, CLK_n)
- begin
- if RESET_n = '0' then
- RD_n <= '1';
- WR_n <= '1';
- IORQ_n <= '1';
- MREQ_n <= '1';
- DI_Reg <= "00000000";
- elsif CLK_n'event and CLK_n = '1' then
- if CLKEN = '1' then
- RD_n <= '1';
- WR_n <= '1';
- IORQ_n <= '1';
- MREQ_n <= '1';
- if MCycle = "001" then
- if TState = "001" or (TState = "010" and Wait_n = '0') then
- RD_n <= not IntCycle_n;
- MREQ_n <= not IntCycle_n;
- IORQ_n <= IntCycle_n;
- end if;
- if TState = "011" then
- MREQ_n <= '0';
- end if;
- else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
- RD_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- if T2Write = 0 then
- if TState = "010" and Write = '1' then
- WR_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
- WR_n <= '0';
- IORQ_n <= not IORQ;
- MREQ_n <= IORQ;
- end if;
- end if;
- end if;
- if TState = "010" and Wait_n = '1' then
- DI_Reg <= DI;
- end if;
- end if;
- end if;
- end process;
-
-end;
diff --git a/tv80/tv80_alu.v b/tv80/tv80_alu.v
new file mode 100644
index 0000000..2f015e2
--- /dev/null
+++ b/tv80/tv80_alu.v
@@ -0,0 +1,442 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80_alu (/*AUTOARG*/
+ // Outputs
+ Q, F_Out,
+ // Inputs
+ Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In
+ );
+
+ parameter Mode = 0;
+ parameter Flag_C = 0;
+ parameter Flag_N = 1;
+ parameter Flag_P = 2;
+ parameter Flag_X = 3;
+ parameter Flag_H = 4;
+ parameter Flag_Y = 5;
+ parameter Flag_Z = 6;
+ parameter Flag_S = 7;
+
+ input Arith16;
+ input Z16;
+ input [3:0] ALU_Op ;
+ input [5:0] IR;
+ input [1:0] ISet;
+ input [7:0] BusA;
+ input [7:0] BusB;
+ input [7:0] F_In;
+ output [7:0] Q;
+ output [7:0] F_Out;
+ reg [7:0] Q;
+ reg [7:0] F_Out;
+
+ function [4:0] AddSub4;
+ input [3:0] A;
+ input [3:0] B;
+ input Sub;
+ input Carry_In;
+ begin
+ AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
+ end
+ endfunction // AddSub4
+
+ function [3:0] AddSub3;
+ input [2:0] A;
+ input [2:0] B;
+ input Sub;
+ input Carry_In;
+ begin
+ AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
+ end
+ endfunction // AddSub4
+
+ function [1:0] AddSub1;
+ input A;
+ input B;
+ input Sub;
+ input Carry_In;
+ begin
+ AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
+ end
+ endfunction // AddSub4
+
+ // AddSub variables (temporary signals)
+ reg UseCarry;
+ reg Carry7_v;
+ reg OverFlow_v;
+ reg HalfCarry_v;
+ reg Carry_v;
+ reg [7:0] Q_v;
+
+ reg [7:0] BitMask;
+
+
+ always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR)
+ begin
+ case (IR[5:3])
+ 3'b000 : BitMask = 8'b00000001;
+ 3'b001 : BitMask = 8'b00000010;
+ 3'b010 : BitMask = 8'b00000100;
+ 3'b011 : BitMask = 8'b00001000;
+ 3'b100 : BitMask = 8'b00010000;
+ 3'b101 : BitMask = 8'b00100000;
+ 3'b110 : BitMask = 8'b01000000;
+ default: BitMask = 8'b10000000;
+ endcase // case(IR[5:3])
+
+ UseCarry = ~ ALU_Op[2] && ALU_Op[0];
+ { HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) );
+ { Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v);
+ { Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v);
+ OverFlow_v = Carry_v ^ Carry7_v;
+ end // always @ *
+
+ reg [7:0] Q_t;
+ reg [8:0] DAA_Q;
+
+ always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB
+ or Carry_v or F_In or HalfCarry_v or IR or ISet
+ or OverFlow_v or Q_v or Z16)
+ begin
+ Q_t = 8'hxx;
+ DAA_Q = {9{1'bx}};
+
+ F_Out = F_In;
+ case (ALU_Op)
+ 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 :
+ begin
+ F_Out[Flag_N] = 1'b0;
+ F_Out[Flag_C] = 1'b0;
+
+ case (ALU_Op[2:0])
+
+ 3'b000, 3'b001 : // ADD, ADC
+ begin
+ Q_t = Q_v;
+ F_Out[Flag_C] = Carry_v;
+ F_Out[Flag_H] = HalfCarry_v;
+ F_Out[Flag_P] = OverFlow_v;
+ end
+
+ 3'b010, 3'b011, 3'b111 : // SUB, SBC, CP
+ begin
+ Q_t = Q_v;
+ F_Out[Flag_N] = 1'b1;
+ F_Out[Flag_C] = ~ Carry_v;
+ F_Out[Flag_H] = ~ HalfCarry_v;
+ F_Out[Flag_P] = OverFlow_v;
+ end
+
+ 3'b100 : // AND
+ begin
+ Q_t[7:0] = BusA & BusB;
+ F_Out[Flag_H] = 1'b1;
+ end
+
+ 3'b101 : // XOR
+ begin
+ Q_t[7:0] = BusA ^ BusB;
+ F_Out[Flag_H] = 1'b0;
+ end
+
+ default : // OR 3'b110
+ begin
+ Q_t[7:0] = BusA | BusB;
+ F_Out[Flag_H] = 1'b0;
+ end
+
+ endcase // case(ALU_OP[2:0])
+
+ if (ALU_Op[2:0] == 3'b111 )
+ begin // CP
+ F_Out[Flag_X] = BusB[3];
+ F_Out[Flag_Y] = BusB[5];
+ end
+ else
+ begin
+ F_Out[Flag_X] = Q_t[3];
+ F_Out[Flag_Y] = Q_t[5];
+ end
+
+ if (Q_t[7:0] == 8'b00000000 )
+ begin
+ F_Out[Flag_Z] = 1'b1;
+ if (Z16 == 1'b1 )
+ begin
+ F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC
+ end
+ end
+ else
+ begin
+ F_Out[Flag_Z] = 1'b0;
+ end // else: !if(Q_t[7:0] == 8'b00000000 )
+
+ F_Out[Flag_S] = Q_t[7];
+ case (ALU_Op[2:0])
+ 3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP
+ ;
+
+ default :
+ F_Out[Flag_P] = ~(^Q_t);
+ endcase // case(ALU_Op[2:0])
+
+ if (Arith16 == 1'b1 )
+ begin
+ F_Out[Flag_S] = F_In[Flag_S];
+ F_Out[Flag_Z] = F_In[Flag_Z];
+ F_Out[Flag_P] = F_In[Flag_P];
+ end
+ end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111
+
+ 4'b1100 :
+ begin
+ // DAA
+ F_Out[Flag_H] = F_In[Flag_H];
+ F_Out[Flag_C] = F_In[Flag_C];
+ DAA_Q[7:0] = BusA;
+ DAA_Q[8] = 1'b0;
+ if (F_In[Flag_N] == 1'b0 )
+ begin
+ // After addition
+ // Alow > 9 || H == 1
+ if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
+ begin
+ if ((DAA_Q[3:0] > 9) )
+ begin
+ F_Out[Flag_H] = 1'b1;
+ end
+ else
+ begin
+ F_Out[Flag_H] = 1'b0;
+ end
+ DAA_Q = DAA_Q + 6;
+ end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
+
+ // new Ahigh > 9 || C == 1
+ if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 )
+ begin
+ DAA_Q = DAA_Q + 96; // 0x60
+ end
+ end
+ else
+ begin
+ // After subtraction
+ if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
+ begin
+ if (DAA_Q[3:0] > 5 )
+ begin
+ F_Out[Flag_H] = 1'b0;
+ end
+ DAA_Q[7:0] = DAA_Q[7:0] - 6;
+ end
+ if (BusA > 153 || F_In[Flag_C] == 1'b1 )
+ begin
+ DAA_Q = DAA_Q - 352; // 0x160
+ end
+ end // else: !if(F_In[Flag_N] == 1'b0 )
+
+ F_Out[Flag_X] = DAA_Q[3];
+ F_Out[Flag_Y] = DAA_Q[5];
+ F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8];
+ Q_t = DAA_Q[7:0];
+
+ if (DAA_Q[7:0] == 8'b00000000 )
+ begin
+ F_Out[Flag_Z] = 1'b1;
+ end
+ else
+ begin
+ F_Out[Flag_Z] = 1'b0;
+ end
+
+ F_Out[Flag_S] = DAA_Q[7];
+ F_Out[Flag_P] = ~ (^DAA_Q);
+ end // case: 4'b1100
+
+ 4'b1101, 4'b1110 :
+ begin
+ // RLD, RRD
+ Q_t[7:4] = BusA[7:4];
+ if (ALU_Op[0] == 1'b1 )
+ begin
+ Q_t[3:0] = BusB[7:4];
+ end
+ else
+ begin
+ Q_t[3:0] = BusB[3:0];
+ end
+ F_Out[Flag_H] = 1'b0;
+ F_Out[Flag_N] = 1'b0;
+ F_Out[Flag_X] = Q_t[3];
+ F_Out[Flag_Y] = Q_t[5];
+ if (Q_t[7:0] == 8'b00000000 )
+ begin
+ F_Out[Flag_Z] = 1'b1;
+ end
+ else
+ begin
+ F_Out[Flag_Z] = 1'b0;
+ end
+ F_Out[Flag_S] = Q_t[7];
+ F_Out[Flag_P] = ~(^Q_t);
+ end // case: when 4'b1101, 4'b1110
+
+ 4'b1001 :
+ begin
+ // BIT
+ Q_t[7:0] = BusB & BitMask;
+ F_Out[Flag_S] = Q_t[7];
+ if (Q_t[7:0] == 8'b00000000 )
+ begin
+ F_Out[Flag_Z] = 1'b1;
+ F_Out[Flag_P] = 1'b1;
+ end
+ else
+ begin
+ F_Out[Flag_Z] = 1'b0;
+ F_Out[Flag_P] = 1'b0;
+ end
+ F_Out[Flag_H] = 1'b1;
+ F_Out[Flag_N] = 1'b0;
+ F_Out[Flag_X] = 1'b0;
+ F_Out[Flag_Y] = 1'b0;
+ if (IR[2:0] != 3'b110 )
+ begin
+ F_Out[Flag_X] = BusB[3];
+ F_Out[Flag_Y] = BusB[5];
+ end
+ end // case: when 4'b1001
+
+ 4'b1010 :
+ // SET
+ Q_t[7:0] = BusB | BitMask;
+
+ 4'b1011 :
+ // RES
+ Q_t[7:0] = BusB & ~ BitMask;
+
+ 4'b1000 :
+ begin
+ // ROT
+ case (IR[5:3])
+ 3'b000 : // RLC
+ begin
+ Q_t[7:1] = BusA[6:0];
+ Q_t[0] = BusA[7];
+ F_Out[Flag_C] = BusA[7];
+ end
+
+ 3'b010 : // RL
+ begin
+ Q_t[7:1] = BusA[6:0];
+ Q_t[0] = F_In[Flag_C];
+ F_Out[Flag_C] = BusA[7];
+ end
+
+ 3'b001 : // RRC
+ begin
+ Q_t[6:0] = BusA[7:1];
+ Q_t[7] = BusA[0];
+ F_Out[Flag_C] = BusA[0];
+ end
+
+ 3'b011 : // RR
+ begin
+ Q_t[6:0] = BusA[7:1];
+ Q_t[7] = F_In[Flag_C];
+ F_Out[Flag_C] = BusA[0];
+ end
+
+ 3'b100 : // SLA
+ begin
+ Q_t[7:1] = BusA[6:0];
+ Q_t[0] = 1'b0;
+ F_Out[Flag_C] = BusA[7];
+ end
+
+ 3'b110 : // SLL (Undocumented) / SWAP
+ begin
+ if (Mode == 3 )
+ begin
+ Q_t[7:4] = BusA[3:0];
+ Q_t[3:0] = BusA[7:4];
+ F_Out[Flag_C] = 1'b0;
+ end
+ else
+ begin
+ Q_t[7:1] = BusA[6:0];
+ Q_t[0] = 1'b1;
+ F_Out[Flag_C] = BusA[7];
+ end // else: !if(Mode == 3 )
+ end // case: 3'b110
+
+ 3'b101 : // SRA
+ begin
+ Q_t[6:0] = BusA[7:1];
+ Q_t[7] = BusA[7];
+ F_Out[Flag_C] = BusA[0];
+ end
+
+ default : // SRL
+ begin
+ Q_t[6:0] = BusA[7:1];
+ Q_t[7] = 1'b0;
+ F_Out[Flag_C] = BusA[0];
+ end
+ endcase // case(IR[5:3])
+
+ F_Out[Flag_H] = 1'b0;
+ F_Out[Flag_N] = 1'b0;
+ F_Out[Flag_X] = Q_t[3];
+ F_Out[Flag_Y] = Q_t[5];
+ F_Out[Flag_S] = Q_t[7];
+ if (Q_t[7:0] == 8'b00000000 )
+ begin
+ F_Out[Flag_Z] = 1'b1;
+ end
+ else
+ begin
+ F_Out[Flag_Z] = 1'b0;
+ end
+ F_Out[Flag_P] = ~(^Q_t);
+
+ if (ISet == 2'b00 )
+ begin
+ F_Out[Flag_P] = F_In[Flag_P];
+ F_Out[Flag_S] = F_In[Flag_S];
+ F_Out[Flag_Z] = F_In[Flag_Z];
+ end
+ end // case: 4'b1000
+
+
+ default :
+ ;
+
+ endcase // case(ALU_Op)
+
+ Q = Q_t;
+ end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
+
+endmodule // T80_ALU
diff --git a/tv80/tv80_core.v b/tv80/tv80_core.v
new file mode 100755
index 0000000..4090eb8
--- /dev/null
+++ b/tv80/tv80_core.v
@@ -0,0 +1,1360 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80_core (/*AUTOARG*/
+ // Outputs
+ m1_n, iorq, no_read, write, rfsh_n, halt_n, busak_n, reti_n, A, do, mc, ts,
+ intcycle_n, IntE, stop,
+ // Inputs
+ reset_n, clk, cen, wait_n, int_n, nmi_n, busrq_n, dinst, di
+ );
+ // Beginning of automatic inputs (from unused autoinst inputs)
+ // End of automatics
+
+ parameter Mode = 1; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
+ parameter Flag_C = 0;
+ parameter Flag_N = 1;
+ parameter Flag_P = 2;
+ parameter Flag_X = 3;
+ parameter Flag_H = 4;
+ parameter Flag_Y = 5;
+ parameter Flag_Z = 6;
+ parameter Flag_S = 7;
+
+ input reset_n;
+ input clk;
+ input cen;
+ input wait_n;
+ input int_n;
+ input nmi_n;
+ input busrq_n;
+ output m1_n;
+ output iorq;
+ output no_read;
+ output write;
+ output rfsh_n;
+ output halt_n;
+ output busak_n;
+ output reti_n;
+ output [15:0] A;
+ input [7:0] dinst;
+ input [7:0] di;
+ output [7:0] do;
+ output [6:0] mc;
+ output [6:0] ts;
+ output intcycle_n;
+ output IntE;
+ output stop;
+
+ reg m1_n;
+ reg reti_n;
+ reg iorq;
+ reg rfsh_n;
+ reg halt_n;
+ reg busak_n;
+ reg [15:0] A;
+ reg [7:0] do;
+ reg [6:0] mc;
+ reg [6:0] ts;
+ reg intcycle_n;
+ reg IntE;
+ reg stop;
+
+ parameter aNone = 3'b111;
+ parameter aBC = 3'b000;
+ parameter aDE = 3'b001;
+ parameter aXY = 3'b010;
+ parameter aIOA = 3'b100;
+ parameter aSP = 3'b101;
+ parameter aZI = 3'b110;
+
+ // Registers
+ reg [7:0] ACC, F;
+ reg [7:0] Ap, Fp;
+ reg [7:0] I;
+ reg [7:0] R;
+ reg [15:0] SP, PC;
+ reg [7:0] RegDIH;
+ reg [7:0] RegDIL;
+ wire [15:0] RegBusA;
+ wire [15:0] RegBusB;
+ wire [15:0] RegBusC;
+ reg [2:0] RegAddrA_r;
+ reg [2:0] RegAddrA;
+ reg [2:0] RegAddrB_r;
+ reg [2:0] RegAddrB;
+ reg [2:0] RegAddrC;
+ reg RegWEH;
+ reg RegWEL;
+ reg Alternate;
+
+ // Help Registers
+ reg [15:0] TmpAddr; // Temporary address register
+ reg [7:0] IR; // Instruction register
+ reg [1:0] ISet; // Instruction set selector
+ reg [15:0] RegBusA_r;
+
+ reg [15:0] ID16;
+ reg [7:0] Save_Mux;
+
+ reg [6:0] tstate;
+ reg [6:0] mcycle;
+ reg last_mcycle, last_tstate;
+ reg IntE_FF1;
+ reg IntE_FF2;
+ reg Halt_FF;
+ reg BusReq_s;
+ reg BusAck;
+ reg ClkEn;
+ reg NMI_s;
+ reg INT_s;
+ reg [1:0] IStatus;
+
+ reg [7:0] DI_Reg;
+ reg T_Res;
+ reg [1:0] XY_State;
+ reg [2:0] Pre_XY_F_M;
+ reg NextIs_XY_Fetch;
+ reg XY_Ind;
+ reg No_BTR;
+ reg BTR_r;
+ reg Auto_Wait;
+ reg Auto_Wait_t1;
+ reg Auto_Wait_t2;
+ reg IncDecZ;
+
+ // ALU signals
+ reg [7:0] BusB;
+ reg [7:0] BusA;
+ wire [7:0] ALU_Q;
+ wire [7:0] F_Out;
+
+ // Registered micro code outputs
+ reg [4:0] Read_To_Reg_r;
+ reg Arith16_r;
+ reg Z16_r;
+ reg [3:0] ALU_Op_r;
+ reg Save_ALU_r;
+ reg PreserveC_r;
+ reg [2:0] mcycles;
+
+ // Micro code outputs
+ wire [2:0] mcycles_d;
+ wire [2:0] tstates;
+ reg IntCycle;
+ reg NMICycle;
+ wire Inc_PC;
+ wire Inc_WZ;
+ wire [3:0] IncDec_16;
+ wire [1:0] Prefix;
+ wire Read_To_Acc;
+ wire Read_To_Reg;
+ wire [3:0] Set_BusB_To;
+ wire [3:0] Set_BusA_To;
+ wire [3:0] ALU_Op;
+ wire Save_ALU;
+ wire PreserveC;
+ wire Arith16;
+ wire [2:0] Set_Addr_To;
+ wire Jump;
+ wire JumpE;
+ wire JumpXY;
+ wire Call;
+ wire RstP;
+ wire LDZ;
+ wire LDW;
+ wire LDSPHL;
+ wire iorq_i;
+ wire [2:0] Special_LD;
+ wire ExchangeDH;
+ wire ExchangeRp;
+ wire ExchangeAF;
+ wire ExchangeRS;
+ wire I_DJNZ;
+ wire I_CPL;
+ wire I_CCF;
+ wire I_SCF;
+ wire I_RETI;
+ wire I_RETN;
+ wire I_BT;
+ wire I_BC;
+ wire I_BTR;
+ wire I_RLD;
+ wire I_RRD;
+ wire I_INRC;
+ wire SetDI;
+ wire SetEI;
+ wire [1:0] IMode;
+ wire Halt;
+
+ reg [15:0] PC16;
+ reg [15:0] PC16_B;
+ reg [15:0] SP16, SP16_A, SP16_B;
+ reg [15:0] ID16_B;
+ reg Oldnmi_n;
+
+ tv80_mcode #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_mcode
+ (
+ .IR (IR),
+ .ISet (ISet),
+ .MCycle (mcycle),
+ .F (F),
+ .NMICycle (NMICycle),
+ .IntCycle (IntCycle),
+ .MCycles (mcycles_d),
+ .TStates (tstates),
+ .Prefix (Prefix),
+ .Inc_PC (Inc_PC),
+ .Inc_WZ (Inc_WZ),
+ .IncDec_16 (IncDec_16),
+ .Read_To_Acc (Read_To_Acc),
+ .Read_To_Reg (Read_To_Reg),
+ .Set_BusB_To (Set_BusB_To),
+ .Set_BusA_To (Set_BusA_To),
+ .ALU_Op (ALU_Op),
+ .Save_ALU (Save_ALU),
+ .PreserveC (PreserveC),
+ .Arith16 (Arith16),
+ .Set_Addr_To (Set_Addr_To),
+ .IORQ (iorq_i),
+ .Jump (Jump),
+ .JumpE (JumpE),
+ .JumpXY (JumpXY),
+ .Call (Call),
+ .RstP (RstP),
+ .LDZ (LDZ),
+ .LDW (LDW),
+ .LDSPHL (LDSPHL),
+ .Special_LD (Special_LD),
+ .ExchangeDH (ExchangeDH),
+ .ExchangeRp (ExchangeRp),
+ .ExchangeAF (ExchangeAF),
+ .ExchangeRS (ExchangeRS),
+ .I_DJNZ (I_DJNZ),
+ .I_CPL (I_CPL),
+ .I_CCF (I_CCF),
+ .I_SCF (I_SCF),
+ .I_RETI (I_RETI),
+ .I_RETN (I_RETN),
+ .I_BT (I_BT),
+ .I_BC (I_BC),
+ .I_BTR (I_BTR),
+ .I_RLD (I_RLD),
+ .I_RRD (I_RRD),
+ .I_INRC (I_INRC),
+ .SetDI (SetDI),
+ .SetEI (SetEI),
+ .IMode (IMode),
+ .Halt (Halt),
+ .NoRead (no_read),
+ .Write (write)
+ );
+
+ tv80_alu #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_alu
+ (
+ .Arith16 (Arith16_r),
+ .Z16 (Z16_r),
+ .ALU_Op (ALU_Op_r),
+ .IR (IR[5:0]),
+ .ISet (ISet),
+ .BusA (BusA),
+ .BusB (BusB),
+ .F_In (F),
+ .Q (ALU_Q),
+ .F_Out (F_Out)
+ );
+
+ function [6:0] number_to_bitvec;
+ input [2:0] num;
+ begin
+ case (num)
+ 1 : number_to_bitvec = 7'b0000001;
+ 2 : number_to_bitvec = 7'b0000010;
+ 3 : number_to_bitvec = 7'b0000100;
+ 4 : number_to_bitvec = 7'b0001000;
+ 5 : number_to_bitvec = 7'b0010000;
+ 6 : number_to_bitvec = 7'b0100000;
+ 7 : number_to_bitvec = 7'b1000000;
+ default : number_to_bitvec = 7'bx;
+ endcase // case(num)
+ end
+ endfunction // number_to_bitvec
+
+ always @(/*AUTOSENSE*/mcycle or mcycles or tstate or tstates)
+ begin
+ case (mcycles)
+ 1 : last_mcycle = mcycle[0];
+ 2 : last_mcycle = mcycle[1];
+ 3 : last_mcycle = mcycle[2];
+ 4 : last_mcycle = mcycle[3];
+ 5 : last_mcycle = mcycle[4];
+ 6 : last_mcycle = mcycle[5];
+ 7 : last_mcycle = mcycle[6];
+ default : last_mcycle = 1'bx;
+ endcase // case(mcycles)
+
+ case (tstates)
+ 0 : last_tstate = tstate[0];
+ 1 : last_tstate = tstate[1];
+ 2 : last_tstate = tstate[2];
+ 3 : last_tstate = tstate[3];
+ 4 : last_tstate = tstate[4];
+ 5 : last_tstate = tstate[5];
+ 6 : last_tstate = tstate[6];
+ default : last_tstate = 1'bx;
+ endcase
+ end // always @ (...
+
+
+ always @(/*AUTOSENSE*/ALU_Q or BusAck or BusB or DI_Reg
+ or ExchangeRp or IR or Save_ALU_r or Set_Addr_To or XY_Ind
+ or XY_State or cen or last_tstate or mcycle)
+ begin
+ ClkEn = cen && ~ BusAck;
+
+ if (last_tstate)
+ T_Res = 1'b1;
+ else T_Res = 1'b0;
+
+ if (XY_State != 2'b00 && XY_Ind == 1'b0 &&
+ ((Set_Addr_To == aXY) ||
+ (mcycle[0] && IR == 8'b11001011) ||
+ (mcycle[0] && IR == 8'b00110110)))
+ NextIs_XY_Fetch = 1'b1;
+ else
+ NextIs_XY_Fetch = 1'b0;
+
+ if (ExchangeRp)
+ Save_Mux = BusB;
+ else if (!Save_ALU_r)
+ Save_Mux = DI_Reg;
+ else
+ Save_Mux = ALU_Q;
+ end // always @ *
+
+ always @ (posedge clk)
+ begin
+ if (reset_n == 1'b0 )
+ begin
+ PC <= #1 0; // Program Counter
+ A <= #1 0;
+ TmpAddr <= #1 0;
+ IR <= #1 8'b00000000;
+ ISet <= #1 2'b00;
+ XY_State <= #1 2'b00;
+ IStatus <= #1 2'b00;
+ mcycles <= #1 3'b000;
+ do <= #1 8'b00000000;
+
+ ACC <= #1 8'hFF;
+ F <= #1 8'hFF;
+ Ap <= #1 8'hFF;
+ Fp <= #1 8'hFF;
+ I <= #1 0;
+ `ifdef TV80_REFRESH
+ R <= #1 0;
+ `endif
+ SP <= #1 16'hFFFF;
+ Alternate <= #1 1'b0;
+
+ Read_To_Reg_r <= #1 5'b00000;
+ Arith16_r <= #1 1'b0;
+ BTR_r <= #1 1'b0;
+ Z16_r <= #1 1'b0;
+ ALU_Op_r <= #1 4'b0000;
+ Save_ALU_r <= #1 1'b0;
+ PreserveC_r <= #1 1'b0;
+ XY_Ind <= #1 1'b0;
+ end
+ else
+ begin
+
+ if (ClkEn == 1'b1 )
+ begin
+
+ ALU_Op_r <= #1 4'b0000;
+ Save_ALU_r <= #1 1'b0;
+ Read_To_Reg_r <= #1 5'b00000;
+
+ mcycles <= #1 mcycles_d;
+
+ if (IMode != 2'b11 )
+ begin
+ IStatus <= #1 IMode;
+ end
+
+ Arith16_r <= #1 Arith16;
+ PreserveC_r <= #1 PreserveC;
+ if (ISet == 2'b10 && ALU_Op[2] == 1'b0 && ALU_Op[0] == 1'b1 && mcycle[2] )
+ begin
+ Z16_r <= #1 1'b1;
+ end
+ else
+ begin
+ Z16_r <= #1 1'b0;
+ end
+
+ if (mcycle[0] && (tstate[1] | tstate[2] | tstate[3] ))
+ begin
+ // mcycle == 1 && tstate == 1, 2, || 3
+ if (tstate[2] && wait_n == 1'b1 )
+ begin
+ `ifdef TV80_REFRESH
+ if (Mode < 2 )
+ begin
+ A[7:0] <= #1 R;
+ A[15:8] <= #1 I;
+ R[6:0] <= #1 R[6:0] + 1;
+ end
+ `endif
+ if (Jump == 1'b0 && Call == 1'b0 && NMICycle == 1'b0 && IntCycle == 1'b0 && ~ (Halt_FF == 1'b1 || Halt == 1'b1) )
+ begin
+ PC <= #1 PC16;
+ end
+
+ if (IntCycle == 1'b1 && IStatus == 2'b01 )
+ begin
+ IR <= #1 8'b11111111;
+ end
+ else if (Halt_FF == 1'b1 || (IntCycle == 1'b1 && IStatus == 2'b10) || NMICycle == 1'b1 )
+ begin
+ IR <= #1 8'b00000000;
+ end
+ else
+ begin
+ IR <= #1 dinst;
+ end
+
+ ISet <= #1 2'b00;
+ if (Prefix != 2'b00 )
+ begin
+ if (Prefix == 2'b11 )
+ begin
+ if (IR[5] == 1'b1 )
+ begin
+ XY_State <= #1 2'b10;
+ end
+ else
+ begin
+ XY_State <= #1 2'b01;
+ end
+ end
+ else
+ begin
+ if (Prefix == 2'b10 )
+ begin
+ XY_State <= #1 2'b00;
+ XY_Ind <= #1 1'b0;
+ end
+ ISet <= #1 Prefix;
+ end
+ end
+ else
+ begin
+ XY_State <= #1 2'b00;
+ XY_Ind <= #1 1'b0;
+ end
+ end // if (tstate == 2 && wait_n == 1'b1 )
+
+
+ end
+ else
+ begin
+ // either (mcycle > 1) OR (mcycle == 1 AND tstate > 3)
+
+ if (mcycle[5] )
+ begin
+ XY_Ind <= #1 1'b1;
+ if (Prefix == 2'b01 )
+ begin
+ ISet <= #1 2'b01;
+ end
+ end
+
+ if (T_Res == 1'b1 )
+ begin
+ BTR_r <= #1 (I_BT || I_BC || I_BTR) && ~ No_BTR;
+ if (Jump == 1'b1 )
+ begin
+ A[15:8] <= #1 DI_Reg;
+ A[7:0] <= #1 TmpAddr[7:0];
+ PC[15:8] <= #1 DI_Reg;
+ PC[7:0] <= #1 TmpAddr[7:0];
+ end
+ else if (JumpXY == 1'b1 )
+ begin
+ A <= #1 RegBusC;
+ PC <= #1 RegBusC;
+ end else if (Call == 1'b1 || RstP == 1'b1 )
+ begin
+ A <= #1 TmpAddr;
+ PC <= #1 TmpAddr;
+ end
+ else if (last_mcycle && NMICycle == 1'b1 )
+ begin
+ A <= #1 16'b0000000001100110;
+ PC <= #1 16'b0000000001100110;
+ end
+ else if (mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 )
+ begin
+ A[15:8] <= #1 I;
+ A[7:0] <= #1 TmpAddr[7:0];
+ PC[15:8] <= #1 I;
+ PC[7:0] <= #1 TmpAddr[7:0];
+ end
+ else
+ begin
+ case (Set_Addr_To)
+ aXY :
+ begin
+ if (XY_State == 2'b00 )
+ begin
+ A <= #1 RegBusC;
+ end
+ else
+ begin
+ if (NextIs_XY_Fetch == 1'b1 )
+ begin
+ A <= #1 PC;
+ end
+ else
+ begin
+ A <= #1 TmpAddr;
+ end
+ end // else: !if(XY_State == 2'b00 )
+ end // case: aXY
+
+ aIOA :
+ begin
+ if (Mode == 3 )
+ begin
+ // Memory map I/O on GBZ80
+ A[15:8] <= #1 8'hFF;
+ end
+ else if (Mode == 2 )
+ begin
+ // Duplicate I/O address on 8080
+ A[15:8] <= #1 DI_Reg;
+ end
+ else
+ begin
+ A[15:8] <= #1 ACC;
+ end
+ A[7:0] <= #1 DI_Reg;
+ end // case: aIOA
+
+
+ aSP :
+ begin
+ A <= #1 SP;
+ end
+
+ aBC :
+ begin
+ if (Mode == 3 && iorq_i == 1'b1 )
+ begin
+ // Memory map I/O on GBZ80
+ A[15:8] <= #1 8'hFF;
+ A[7:0] <= #1 RegBusC[7:0];
+ end
+ else
+ begin
+ A <= #1 RegBusC;
+ end
+ end // case: aBC
+
+ aDE :
+ begin
+ A <= #1 RegBusC;
+ end
+
+ aZI :
+ begin
+ if (Inc_WZ == 1'b1 )
+ begin
+ A <= #1 TmpAddr + 1;
+ end
+ else
+ begin
+ A[15:8] <= #1 DI_Reg;
+ A[7:0] <= #1 TmpAddr[7:0];
+ end
+ end // case: aZI
+
+ default :
+ begin
+ A <= #1 PC;
+ end
+ endcase // case(Set_Addr_To)
+
+ end // else: !if(mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 )
+
+
+ Save_ALU_r <= #1 Save_ALU;
+ ALU_Op_r <= #1 ALU_Op;
+
+ if (I_CPL == 1'b1 )
+ begin
+ // CPL
+ ACC <= #1 ~ ACC;
+ F[Flag_Y] <= #1 ~ ACC[5];
+ F[Flag_H] <= #1 1'b1;
+ F[Flag_X] <= #1 ~ ACC[3];
+ F[Flag_N] <= #1 1'b1;
+ end
+ if (I_CCF == 1'b1 )
+ begin
+ // CCF
+ F[Flag_C] <= #1 ~ F[Flag_C];
+ F[Flag_Y] <= #1 ACC[5];
+ F[Flag_H] <= #1 F[Flag_C];
+ F[Flag_X] <= #1 ACC[3];
+ F[Flag_N] <= #1 1'b0;
+ end
+ if (I_SCF == 1'b1 )
+ begin
+ // SCF
+ F[Flag_C] <= #1 1'b1;
+ F[Flag_Y] <= #1 ACC[5];
+ F[Flag_H] <= #1 1'b0;
+ F[Flag_X] <= #1 ACC[3];
+ F[Flag_N] <= #1 1'b0;
+ end
+ end // if (T_Res == 1'b1 )
+
+
+ if (tstate[2] && wait_n == 1'b1 )
+ begin
+ if (ISet == 2'b01 && mcycle[6] )
+ begin
+ IR <= #1 dinst;
+ end
+ if (JumpE == 1'b1 )
+ begin
+ PC <= #1 PC16;
+ end
+ else if (Inc_PC == 1'b1 )
+ begin
+ //PC <= #1 PC + 1;
+ PC <= #1 PC16;
+ end
+ if (BTR_r == 1'b1 )
+ begin
+ //PC <= #1 PC - 2;
+ PC <= #1 PC16;
+ end
+ if (RstP == 1'b1 )
+ begin
+ TmpAddr <= #1 { 10'h0, IR[5:3], 3'h0 };
+ //TmpAddr <= #1 (others =>1'b0);
+ //TmpAddr[5:3] <= #1 IR[5:3];
+ end
+ end
+ if (tstate[3] && mcycle[5] )
+ begin
+ TmpAddr <= #1 SP16;
+ end
+
+ if ((tstate[2] && wait_n == 1'b1) || (tstate[4] && mcycle[0]) )
+ begin
+ if (IncDec_16[2:0] == 3'b111 )
+ begin
+ SP <= #1 SP16;
+ end
+ end
+
+ if (LDSPHL == 1'b1 )
+ begin
+ SP <= #1 RegBusC;
+ end
+ if (ExchangeAF == 1'b1 )
+ begin
+ Ap <= #1 ACC;
+ ACC <= #1 Ap;
+ Fp <= #1 F;
+ F <= #1 Fp;
+ end
+ if (ExchangeRS == 1'b1 )
+ begin
+ Alternate <= #1 ~ Alternate;
+ end
+ end // else: !if(mcycle == 3'b001 && tstate(2) == 1'b0 )
+
+
+ if (tstate[3] )
+ begin
+ if (LDZ == 1'b1 )
+ begin
+ TmpAddr[7:0] <= #1 DI_Reg;
+ end
+ if (LDW == 1'b1 )
+ begin
+ TmpAddr[15:8] <= #1 DI_Reg;
+ end
+
+ if (Special_LD[2] == 1'b1 )
+ begin
+ case (Special_LD[1:0])
+ 2'b00 :
+ begin
+ ACC <= #1 I;
+ F[Flag_P] <= #1 IntE_FF2;
+ end
+
+ 2'b01 :
+ begin
+ ACC <= #1 R;
+ F[Flag_P] <= #1 IntE_FF2;
+ end
+
+ 2'b10 :
+ I <= #1 ACC;
+
+ `ifdef TV80_REFRESH
+ default :
+ R <= #1 ACC;
+ `else
+ default : ;
+ `endif
+ endcase
+ end
+ end // if (tstate == 3 )
+
+
+ if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 )
+ begin
+ if (Mode == 3 )
+ begin
+ F[6] <= #1 F_Out[6];
+ F[5] <= #1 F_Out[5];
+ F[7] <= #1 F_Out[7];
+ if (PreserveC_r == 1'b0 )
+ begin
+ F[4] <= #1 F_Out[4];
+ end
+ end
+ else
+ begin
+ F[7:1] <= #1 F_Out[7:1];
+ if (PreserveC_r == 1'b0 )
+ begin
+ F[Flag_C] <= #1 F_Out[0];
+ end
+ end
+ end // if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 )
+
+ if (T_Res == 1'b1 && I_INRC == 1'b1 )
+ begin
+ F[Flag_H] <= #1 1'b0;
+ F[Flag_N] <= #1 1'b0;
+ if (DI_Reg[7:0] == 8'b00000000 )
+ begin
+ F[Flag_Z] <= #1 1'b1;
+ end
+ else
+ begin
+ F[Flag_Z] <= #1 1'b0;
+ end
+ F[Flag_S] <= #1 DI_Reg[7];
+ F[Flag_P] <= #1 ~ (^DI_Reg[7:0]);
+ end // if (T_Res == 1'b1 && I_INRC == 1'b1 )
+
+
+ if (tstate[1] && Auto_Wait_t1 == 1'b0 )
+ begin
+ do <= #1 BusB;
+ if (I_RLD == 1'b1 )
+ begin
+ do[3:0] <= #1 BusA[3:0];
+ do[7:4] <= #1 BusB[3:0];
+ end
+ if (I_RRD == 1'b1 )
+ begin
+ do[3:0] <= #1 BusB[7:4];
+ do[7:4] <= #1 BusA[3:0];
+ end
+ end
+
+ if (T_Res == 1'b1 )
+ begin
+ Read_To_Reg_r[3:0] <= #1 Set_BusA_To;
+ Read_To_Reg_r[4] <= #1 Read_To_Reg;
+ if (Read_To_Acc == 1'b1 )
+ begin
+ Read_To_Reg_r[3:0] <= #1 4'b0111;
+ Read_To_Reg_r[4] <= #1 1'b1;
+ end
+ end
+
+ if (tstate[1] && I_BT == 1'b1 )
+ begin
+ F[Flag_X] <= #1 ALU_Q[3];
+ F[Flag_Y] <= #1 ALU_Q[1];
+ F[Flag_H] <= #1 1'b0;
+ F[Flag_N] <= #1 1'b0;
+ end
+ if (I_BC == 1'b1 || I_BT == 1'b1 )
+ begin
+ F[Flag_P] <= #1 IncDecZ;
+ end
+
+ if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||
+ (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) )
+ begin
+ case (Read_To_Reg_r)
+ 5'b10111 :
+ ACC <= #1 Save_Mux;
+ 5'b10110 :
+ do <= #1 Save_Mux;
+ 5'b11000 :
+ SP[7:0] <= #1 Save_Mux;
+ 5'b11001 :
+ SP[15:8] <= #1 Save_Mux;
+ 5'b11011 :
+ F <= #1 Save_Mux;
+ endcase
+ end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||...
+ end // if (ClkEn == 1'b1 )
+ end // else: !if(reset_n == 1'b0 )
+ end
+
+
+ //-------------------------------------------------------------------------
+ //
+ // BC('), DE('), HL('), IX && IY
+ //
+ //-------------------------------------------------------------------------
+ always @ (posedge clk)
+ begin
+ if (ClkEn == 1'b1 )
+ begin
+ // Bus A / Write
+ RegAddrA_r <= #1 { Alternate, Set_BusA_To[2:1] };
+ if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusA_To[2:1] == 2'b10 )
+ begin
+ RegAddrA_r <= #1 { XY_State[1], 2'b11 };
+ end
+
+ // Bus B
+ RegAddrB_r <= #1 { Alternate, Set_BusB_To[2:1] };
+ if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusB_To[2:1] == 2'b10 )
+ begin
+ RegAddrB_r <= #1 { XY_State[1], 2'b11 };
+ end
+
+ // Address from register
+ RegAddrC <= #1 { Alternate, Set_Addr_To[1:0] };
+ // Jump (HL), LD SP,HL
+ if ((JumpXY == 1'b1 || LDSPHL == 1'b1) )
+ begin
+ RegAddrC <= #1 { Alternate, 2'b10 };
+ end
+ if (((JumpXY == 1'b1 || LDSPHL == 1'b1) && XY_State != 2'b00) || (mcycle[5]) )
+ begin
+ RegAddrC <= #1 { XY_State[1], 2'b11 };
+ end
+
+ if (I_DJNZ == 1'b1 && Save_ALU_r == 1'b1 && Mode < 2 )
+ begin
+ IncDecZ <= #1 F_Out[Flag_Z];
+ end
+ if ((tstate[2] || (tstate[3] && mcycle[0])) && IncDec_16[2:0] == 3'b100 )
+ begin
+ if (ID16 == 0 )
+ begin
+ IncDecZ <= #1 1'b0;
+ end
+ else
+ begin
+ IncDecZ <= #1 1'b1;
+ end
+ end
+
+ RegBusA_r <= #1 RegBusA;
+ end
+
+ end // always @ (posedge clk)
+
+
+ always @(/*AUTOSENSE*/Alternate or ExchangeDH or IncDec_16
+ or RegAddrA_r or RegAddrB_r or XY_State or mcycle or tstate)
+ begin
+ if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && XY_State == 2'b00)
+ RegAddrA = { Alternate, IncDec_16[1:0] };
+ else if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && IncDec_16[1:0] == 2'b10)
+ RegAddrA = { XY_State[1], 2'b11 };
+ else if (ExchangeDH == 1'b1 && tstate[3])
+ RegAddrA = { Alternate, 2'b10 };
+ else if (ExchangeDH == 1'b1 && tstate[4])
+ RegAddrA = { Alternate, 2'b01 };
+ else
+ RegAddrA = RegAddrA_r;
+
+ if (ExchangeDH == 1'b1 && tstate[3])
+ RegAddrB = { Alternate, 2'b01 };
+ else
+ RegAddrB = RegAddrB_r;
+ end // always @ *
+
+
+ always @(/*AUTOSENSE*/ALU_Op_r or Auto_Wait_t1 or ExchangeDH
+ or IncDec_16 or Read_To_Reg_r or Save_ALU_r or mcycle
+ or tstate or wait_n)
+ begin
+ RegWEH = 1'b0;
+ RegWEL = 1'b0;
+ if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||
+ (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) )
+ begin
+ case (Read_To_Reg_r)
+ 5'b10000 , 5'b10001 , 5'b10010 , 5'b10011 , 5'b10100 , 5'b10101 :
+ begin
+ RegWEH = ~ Read_To_Reg_r[0];
+ RegWEL = Read_To_Reg_r[0];
+ end
+ endcase // case(Read_To_Reg_r)
+
+ end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||...
+
+
+ if (ExchangeDH == 1'b1 && (tstate[3] || tstate[4]) )
+ begin
+ RegWEH = 1'b1;
+ RegWEL = 1'b1;
+ end
+
+ if (IncDec_16[2] == 1'b1 && ((tstate[2] && wait_n == 1'b1 && mcycle != 3'b001) || (tstate[3] && mcycle[0])) )
+ begin
+ case (IncDec_16[1:0])
+ 2'b00 , 2'b01 , 2'b10 :
+ begin
+ RegWEH = 1'b1;
+ RegWEL = 1'b1;
+ end
+ endcase
+ end
+ end // always @ *
+
+
+ always @(/*AUTOSENSE*/ExchangeDH or ID16 or IncDec_16 or RegBusA_r
+ or RegBusB or Save_Mux or mcycle or tstate)
+ begin
+ RegDIH = Save_Mux;
+ RegDIL = Save_Mux;
+
+ if (ExchangeDH == 1'b1 && tstate[3] )
+ begin
+ RegDIH = RegBusB[15:8];
+ RegDIL = RegBusB[7:0];
+ end
+ else if (ExchangeDH == 1'b1 && tstate[4] )
+ begin
+ RegDIH = RegBusA_r[15:8];
+ RegDIL = RegBusA_r[7:0];
+ end
+ else if (IncDec_16[2] == 1'b1 && ((tstate[2] && mcycle != 3'b001) || (tstate[3] && mcycle[0])) )
+ begin
+ RegDIH = ID16[15:8];
+ RegDIL = ID16[7:0];
+ end
+ end
+
+ tv80_reg i_reg
+ (
+ .clk (clk),
+ .CEN (ClkEn),
+ .WEH (RegWEH),
+ .WEL (RegWEL),
+ .AddrA (RegAddrA),
+ .AddrB (RegAddrB),
+ .AddrC (RegAddrC),
+ .DIH (RegDIH),
+ .DIL (RegDIL),
+ .DOAH (RegBusA[15:8]),
+ .DOAL (RegBusA[7:0]),
+ .DOBH (RegBusB[15:8]),
+ .DOBL (RegBusB[7:0]),
+ .DOCH (RegBusC[15:8]),
+ .DOCL (RegBusC[7:0])
+ );
+
+ //-------------------------------------------------------------------------
+ //
+ // Buses
+ //
+ //-------------------------------------------------------------------------
+
+ always @ (posedge clk)
+ begin
+ if (ClkEn == 1'b1 )
+ begin
+ case (Set_BusB_To)
+ 4'b0111 :
+ BusB <= #1 ACC;
+ 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 :
+ begin
+ if (Set_BusB_To[0] == 1'b1 )
+ begin
+ BusB <= #1 RegBusB[7:0];
+ end
+ else
+ begin
+ BusB <= #1 RegBusB[15:8];
+ end
+ end
+ 4'b0110 :
+ BusB <= #1 DI_Reg;
+ 4'b1000 :
+ BusB <= #1 SP[7:0];
+ 4'b1001 :
+ BusB <= #1 SP[15:8];
+ 4'b1010 :
+ BusB <= #1 8'b00000001;
+ 4'b1011 :
+ BusB <= #1 F;
+ 4'b1100 :
+ BusB <= #1 PC[7:0];
+ 4'b1101 :
+ BusB <= #1 PC[15:8];
+ 4'b1110 :
+ BusB <= #1 8'b00000000;
+ default :
+ BusB <= #1 8'hxx;
+ endcase
+
+ case (Set_BusA_To)
+ 4'b0111 :
+ BusA <= #1 ACC;
+ 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 :
+ begin
+ if (Set_BusA_To[0] == 1'b1 )
+ begin
+ BusA <= #1 RegBusA[7:0];
+ end
+ else
+ begin
+ BusA <= #1 RegBusA[15:8];
+ end
+ end
+ 4'b0110 :
+ BusA <= #1 DI_Reg;
+ 4'b1000 :
+ BusA <= #1 SP[7:0];
+ 4'b1001 :
+ BusA <= #1 SP[15:8];
+ 4'b1010 :
+ BusA <= #1 8'b00000000;
+ default :
+ BusB <= #1 8'hxx;
+ endcase
+ end
+ end
+
+ //-------------------------------------------------------------------------
+ //
+ // Generate external control signals
+ //
+ //-------------------------------------------------------------------------
+`ifdef TV80_REFRESH
+ always @ (posedge clk)
+ begin
+ if (reset_n == 1'b0 )
+ begin
+ rfsh_n <= #1 1'b1;
+ end
+ else
+ begin
+ if (cen == 1'b1 )
+ begin
+ if (mcycle[0] && ((tstate[2] && wait_n == 1'b1) || tstate[3]) )
+ begin
+ rfsh_n <= #1 1'b0;
+ end
+ else
+ begin
+ rfsh_n <= #1 1'b1;
+ end
+ end
+ end
+ end
+`endif
+
+ always @(/*AUTOSENSE*/BusAck or Halt_FF or I_DJNZ or IntCycle
+ or IntE_FF1 or di or iorq_i or mcycle or tstate)
+ begin
+ mc = mcycle;
+ ts = tstate;
+ DI_Reg = di;
+ halt_n = ~ Halt_FF;
+ busak_n = ~ BusAck;
+ intcycle_n = ~ IntCycle;
+ IntE = IntE_FF1;
+ iorq = iorq_i;
+ stop = I_DJNZ;
+ end
+
+ //-----------------------------------------------------------------------
+ //
+ // Syncronise inputs
+ //
+ //-----------------------------------------------------------------------
+
+ always @ (posedge clk)
+ begin : sync_inputs
+
+ if (reset_n == 1'b0 )
+ begin
+ BusReq_s <= #1 1'b0;
+ INT_s <= #1 1'b0;
+ NMI_s <= #1 1'b0;
+ Oldnmi_n <= #1 1'b0;
+ end
+ else
+ begin
+ if (cen == 1'b1 )
+ begin
+ BusReq_s <= #1 ~ busrq_n;
+ INT_s <= #1 ~ int_n;
+ if (NMICycle == 1'b1 )
+ begin
+ NMI_s <= #1 1'b0;
+ end
+ else if (nmi_n == 1'b0 && Oldnmi_n == 1'b1 )
+ begin
+ NMI_s <= #1 1'b1;
+ end
+ Oldnmi_n <= #1 nmi_n;
+ end
+ end
+ end
+
+ //-----------------------------------------------------------------------
+ //
+ // Main state machine
+ //
+ //-----------------------------------------------------------------------
+
+ always @ (posedge clk)
+ begin
+ if (reset_n == 1'b0 )
+ begin
+ mcycle <= #1 7'b0000001;
+ tstate <= #1 7'b0000001;
+ Pre_XY_F_M <= #1 3'b000;
+ Halt_FF <= #1 1'b0;
+ BusAck <= #1 1'b0;
+ NMICycle <= #1 1'b0;
+ IntCycle <= #1 1'b0;
+ IntE_FF1 <= #1 1'b0;
+ IntE_FF2 <= #1 1'b0;
+ No_BTR <= #1 1'b0;
+ Auto_Wait_t1 <= #1 1'b0;
+ Auto_Wait_t2 <= #1 1'b0;
+ m1_n <= #1 1'b1;
+ reti_n <= #1 1'b1;
+ end
+ else
+ begin
+ if (cen == 1'b1 )
+ begin
+ if (T_Res == 1'b1 )
+ begin
+ Auto_Wait_t1 <= #1 1'b0;
+ end
+ else
+ begin
+ Auto_Wait_t1 <= #1 Auto_Wait || iorq_i;
+ end
+ Auto_Wait_t2 <= #1 Auto_Wait_t1 & ~T_Res;
+ No_BTR <= #1 (I_BT && (~ IR[4] || ~ F[Flag_P])) ||
+ (I_BC && (~ IR[4] || F[Flag_Z] || ~ F[Flag_P])) ||
+ (I_BTR && (~ IR[4] || F[Flag_Z]));
+ reti_n <= ~I_RETI;
+ if (tstate[2] )
+ begin
+ if (SetEI == 1'b1 )
+ begin
+ IntE_FF1 <= #1 1'b1;
+ IntE_FF2 <= #1 1'b1;
+ end
+ if (I_RETN == 1'b1 )
+ begin
+ IntE_FF1 <= #1 IntE_FF2;
+ end
+ end
+ if (tstate[3] )
+ begin
+ if (SetDI == 1'b1 )
+ begin
+ IntE_FF1 <= #1 1'b0;
+ IntE_FF2 <= #1 1'b0;
+ end
+ end
+ if (IntCycle == 1'b1 || NMICycle == 1'b1 )
+ begin
+ Halt_FF <= #1 1'b0;
+ end
+ if (mcycle[0] && tstate[2] && wait_n == 1'b1 )
+ begin
+ m1_n <= #1 1'b1;
+ end
+ if (BusReq_s == 1'b1 && BusAck == 1'b1 )
+ begin
+ end
+ else
+ begin
+ BusAck <= #1 1'b0;
+ if (tstate[2] && wait_n == 1'b0 )
+ begin
+ end
+ else if (T_Res == 1'b1 )
+ begin
+ if (Halt == 1'b1 )
+ begin
+ Halt_FF <= #1 1'b1;
+ end
+ if (BusReq_s == 1'b1 )
+ begin
+ BusAck <= #1 1'b1;
+ end
+ else
+ begin
+ tstate <= #1 7'b0000010;
+ if (NextIs_XY_Fetch == 1'b1 )
+ begin
+ mcycle <= #1 7'b0100000;
+ Pre_XY_F_M <= #1 mcycle;
+ if (IR == 8'b00110110 && Mode == 0 )
+ begin
+ Pre_XY_F_M <= #1 3'b010;
+ end
+ end
+ else if ((mcycle[6]) || (mcycle[5] && Mode == 1 && ISet != 2'b01) )
+ begin
+ mcycle <= #1 number_to_bitvec(Pre_XY_F_M + 1);
+ end
+ else if ((last_mcycle) ||
+ No_BTR == 1'b1 ||
+ (mcycle[1] && I_DJNZ == 1'b1 && IncDecZ == 1'b1) )
+ begin
+ m1_n <= #1 1'b0;
+ mcycle <= #1 7'b0000001;
+ IntCycle <= #1 1'b0;
+ NMICycle <= #1 1'b0;
+ if (NMI_s == 1'b1 && Prefix == 2'b00 )
+ begin
+ NMICycle <= #1 1'b1;
+ IntE_FF1 <= #1 1'b0;
+ end
+ else if ((IntE_FF1 == 1'b1 && INT_s == 1'b1) && Prefix == 2'b00 && SetEI == 1'b0 )
+ begin
+ IntCycle <= #1 1'b1;
+ IntE_FF1 <= #1 1'b0;
+ IntE_FF2 <= #1 1'b0;
+ end
+ end
+ else
+ begin
+ mcycle <= #1 { mcycle[5:0], mcycle[6] };
+ end
+ end
+ end
+ else
+ begin // verilog has no "nor" operator
+ if ( ~(Auto_Wait == 1'b1 && Auto_Wait_t2 == 1'b0) &&
+ ~(IOWait == 1 && iorq_i == 1'b1 && Auto_Wait_t1 == 1'b0) )
+ begin
+ tstate <= #1 { tstate[5:0], tstate[6] };
+ end
+ end
+ end
+ if (tstate[0])
+ begin
+ m1_n <= #1 1'b0;
+ end
+ end
+ end
+ end
+
+ always @(/*AUTOSENSE*/BTR_r or DI_Reg or IncDec_16 or JumpE or PC
+ or RegBusA or RegBusC or SP or tstate)
+ begin
+ if (JumpE == 1'b1 )
+ begin
+ PC16_B = { {8{DI_Reg[7]}}, DI_Reg };
+ end
+ else if (BTR_r == 1'b1 )
+ begin
+ PC16_B = -2;
+ end
+ else
+ begin
+ PC16_B = 1;
+ end
+
+ if (tstate[3])
+ begin
+ SP16_A = RegBusC;
+ SP16_B = { {8{DI_Reg[7]}}, DI_Reg };
+ end
+ else
+ begin
+ // suspect that ID16 and SP16 could be shared
+ SP16_A = SP;
+
+ if (IncDec_16[3] == 1'b1)
+ SP16_B = -1;
+ else
+ SP16_B = 1;
+ end
+
+ if (IncDec_16[3])
+ ID16_B = -1;
+ else
+ ID16_B = 1;
+
+ ID16 = RegBusA + ID16_B;
+ PC16 = PC + PC16_B;
+ SP16 = SP16_A + SP16_B;
+ end // always @ *
+
+
+ always @(/*AUTOSENSE*/IntCycle or NMICycle or mcycle)
+ begin
+ Auto_Wait = 1'b0;
+ if (IntCycle == 1'b1 || NMICycle == 1'b1 )
+ begin
+ if (mcycle[0] )
+ begin
+ Auto_Wait = 1'b1;
+ end
+ end
+ end // always @ *
+
+// synopsys dc_script_begin
+// set_attribute current_design "revision" "$Id: tv80_core.v,v 1.5 2005/01/26 18:55:47 ghutchis Exp $" -type string -quiet
+// synopsys dc_script_end
+endmodule // T80
+
diff --git a/tv80/tv80_mcode.v b/tv80/tv80_mcode.v
new file mode 100644
index 0000000..d3c609b
--- /dev/null
+++ b/tv80/tv80_mcode.v
@@ -0,0 +1,2657 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80_mcode
+ (/*AUTOARG*/
+ // Outputs
+ MCycles, TStates, Prefix, Inc_PC, Inc_WZ, IncDec_16, Read_To_Reg,
+ Read_To_Acc, Set_BusA_To, Set_BusB_To, ALU_Op, Save_ALU, PreserveC,
+ Arith16, Set_Addr_To, IORQ, Jump, JumpE, JumpXY, Call, RstP, LDZ,
+ LDW, LDSPHL, Special_LD, ExchangeDH, ExchangeRp, ExchangeAF,
+ ExchangeRS, I_DJNZ, I_CPL, I_CCF, I_SCF, I_RETI, I_RETN, I_BT, I_BC, I_BTR,
+ I_RLD, I_RRD, I_INRC, SetDI, SetEI, IMode, Halt, NoRead, Write,
+ // Inputs
+ IR, ISet, MCycle, F, NMICycle, IntCycle
+ );
+
+ parameter Mode = 0;
+ parameter Flag_C = 0;
+ parameter Flag_N = 1;
+ parameter Flag_P = 2;
+ parameter Flag_X = 3;
+ parameter Flag_H = 4;
+ parameter Flag_Y = 5;
+ parameter Flag_Z = 6;
+ parameter Flag_S = 7;
+
+ input [7:0] IR;
+ input [1:0] ISet ;
+ input [6:0] MCycle ;
+ input [7:0] F ;
+ input NMICycle ;
+ input IntCycle ;
+ output [2:0] MCycles ;
+ output [2:0] TStates ;
+ output [1:0] Prefix ; // None,BC,ED,DD/FD
+ output Inc_PC ;
+ output Inc_WZ ;
+ output [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc
+ output Read_To_Reg ;
+ output Read_To_Acc ;
+ output [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
+ output [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
+ output [3:0] ALU_Op ;
+ output Save_ALU ;
+ output PreserveC ;
+ output Arith16 ;
+ output [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI
+ output IORQ ;
+ output Jump ;
+ output JumpE ;
+ output JumpXY ;
+ output Call ;
+ output RstP ;
+ output LDZ ;
+ output LDW ;
+ output LDSPHL ;
+ output [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None
+ output ExchangeDH ;
+ output ExchangeRp ;
+ output ExchangeAF ;
+ output ExchangeRS ;
+ output I_DJNZ ;
+ output I_CPL ;
+ output I_CCF ;
+ output I_SCF ;
+ output I_RETI ;
+ output I_RETN ;
+ output I_BT ;
+ output I_BC ;
+ output I_BTR ;
+ output I_RLD ;
+ output I_RRD ;
+ output I_INRC ;
+ output SetDI ;
+ output SetEI ;
+ output [1:0] IMode ;
+ output Halt ;
+ output NoRead ;
+ output Write ;
+
+ // regs
+ reg [2:0] MCycles ;
+ reg [2:0] TStates ;
+ reg [1:0] Prefix ; // None,BC,ED,DD/FD
+ reg Inc_PC ;
+ reg Inc_WZ ;
+ reg [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc
+ reg Read_To_Reg ;
+ reg Read_To_Acc ;
+ reg [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
+ reg [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
+ reg [3:0] ALU_Op ;
+ reg Save_ALU ;
+ reg PreserveC ;
+ reg Arith16 ;
+ reg [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI
+ reg IORQ ;
+ reg Jump ;
+ reg JumpE ;
+ reg JumpXY ;
+ reg Call ;
+ reg RstP ;
+ reg LDZ ;
+ reg LDW ;
+ reg LDSPHL ;
+ reg [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None
+ reg ExchangeDH ;
+ reg ExchangeRp ;
+ reg ExchangeAF ;
+ reg ExchangeRS ;
+ reg I_DJNZ ;
+ reg I_CPL ;
+ reg I_CCF ;
+ reg I_SCF ;
+ reg I_RETI ;
+ reg I_RETN ;
+ reg I_BT ;
+ reg I_BC ;
+ reg I_BTR ;
+ reg I_RLD ;
+ reg I_RRD ;
+ reg I_INRC ;
+ reg SetDI ;
+ reg SetEI ;
+ reg [1:0] IMode ;
+ reg Halt ;
+ reg NoRead ;
+ reg Write ;
+
+ parameter aNone = 3'b111;
+ parameter aBC = 3'b000;
+ parameter aDE = 3'b001;
+ parameter aXY = 3'b010;
+ parameter aIOA = 3'b100;
+ parameter aSP = 3'b101;
+ parameter aZI = 3'b110;
+ // constant aNone : std_logic_vector[2:0] = 3'b000;
+ // constant aXY : std_logic_vector[2:0] = 3'b001;
+ // constant aIOA : std_logic_vector[2:0] = 3'b010;
+ // constant aSP : std_logic_vector[2:0] = 3'b011;
+ // constant aBC : std_logic_vector[2:0] = 3'b100;
+ // constant aDE : std_logic_vector[2:0] = 3'b101;
+ // constant aZI : std_logic_vector[2:0] = 3'b110;
+
+ function is_cc_true;
+ input [7:0] F;
+ input [2:0] cc;
+ begin
+ if (Mode == 3 )
+ begin
+ case (cc)
+ 3'b000 : is_cc_true = F[7] == 1'b0; // NZ
+ 3'b001 : is_cc_true = F[7] == 1'b1; // Z
+ 3'b010 : is_cc_true = F[4] == 1'b0; // NC
+ 3'b011 : is_cc_true = F[4] == 1'b1; // C
+ 3'b100 : is_cc_true = 0;
+ 3'b101 : is_cc_true = 0;
+ 3'b110 : is_cc_true = 0;
+ 3'b111 : is_cc_true = 0;
+ endcase
+ end
+ else
+ begin
+ case (cc)
+ 3'b000 : is_cc_true = F[6] == 1'b0; // NZ
+ 3'b001 : is_cc_true = F[6] == 1'b1; // Z
+ 3'b010 : is_cc_true = F[0] == 1'b0; // NC
+ 3'b011 : is_cc_true = F[0] == 1'b1; // C
+ 3'b100 : is_cc_true = F[2] == 1'b0; // PO
+ 3'b101 : is_cc_true = F[2] == 1'b1; // PE
+ 3'b110 : is_cc_true = F[7] == 1'b0; // P
+ 3'b111 : is_cc_true = F[7] == 1'b1; // M
+ endcase
+ end
+ end
+ endfunction // is_cc_true
+
+
+ reg [2:0] DDD;
+ reg [2:0] SSS;
+ reg [1:0] DPAIR;
+
+ always @ (/*AUTOSENSE*/F or IR or ISet or IntCycle or MCycle
+ or NMICycle)
+ begin
+ DDD = IR[5:3];
+ SSS = IR[2:0];
+ DPAIR = IR[5:4];
+
+ MCycles = 3'b001;
+ if (MCycle[0] )
+ begin
+ TStates = 3'b100;
+ end
+ else
+ begin
+ TStates = 3'b011;
+ end
+ Prefix = 2'b00;
+ Inc_PC = 1'b0;
+ Inc_WZ = 1'b0;
+ IncDec_16 = 4'b0000;
+ Read_To_Acc = 1'b0;
+ Read_To_Reg = 1'b0;
+ Set_BusB_To = 4'b0000;
+ Set_BusA_To = 4'b0000;
+ ALU_Op = { 1'b0, IR[5:3] };
+ Save_ALU = 1'b0;
+ PreserveC = 1'b0;
+ Arith16 = 1'b0;
+ IORQ = 1'b0;
+ Set_Addr_To = aNone;
+ Jump = 1'b0;
+ JumpE = 1'b0;
+ JumpXY = 1'b0;
+ Call = 1'b0;
+ RstP = 1'b0;
+ LDZ = 1'b0;
+ LDW = 1'b0;
+ LDSPHL = 1'b0;
+ Special_LD = 3'b000;
+ ExchangeDH = 1'b0;
+ ExchangeRp = 1'b0;
+ ExchangeAF = 1'b0;
+ ExchangeRS = 1'b0;
+ I_DJNZ = 1'b0;
+ I_CPL = 1'b0;
+ I_CCF = 1'b0;
+ I_SCF = 1'b0;
+ I_RETI = 1'b0;
+ I_RETN = 1'b0;
+ I_BT = 1'b0;
+ I_BC = 1'b0;
+ I_BTR = 1'b0;
+ I_RLD = 1'b0;
+ I_RRD = 1'b0;
+ I_INRC = 1'b0;
+ SetDI = 1'b0;
+ SetEI = 1'b0;
+ IMode = 2'b11;
+ Halt = 1'b0;
+ NoRead = 1'b0;
+ Write = 1'b0;
+
+ case (ISet)
+ 2'b00 :
+ begin
+
+ //----------------------------------------------------------------------------
+ //
+ // Unprefixed instructions
+ //
+ //----------------------------------------------------------------------------
+
+ casex (IR)
+ // 8 BIT LOAD GROUP
+ 8'b01xxxxxx :
+ begin
+ if (IR[5:0] == 6'b110110)
+ Halt = 1'b1;
+ else if (IR[2:0] == 3'b110)
+ begin
+ // LD r,(HL)
+ MCycles = 3'b010;
+ if (MCycle[0])
+ Set_Addr_To = aXY;
+ if (MCycle[1])
+ begin
+ Set_BusA_To[2:0] = DDD;
+ Read_To_Reg = 1'b1;
+ end
+ end // if (IR[2:0] == 3'b110)
+ else if (IR[5:3] == 3'b110)
+ begin
+ // LD (HL),r
+ MCycles = 3'b010;
+ if (MCycle[0])
+ begin
+ Set_Addr_To = aXY;
+ Set_BusB_To[2:0] = SSS;
+ Set_BusB_To[3] = 1'b0;
+ end
+ if (MCycle[1])
+ Write = 1'b1;
+ end // if (IR[5:3] == 3'b110)
+ else
+ begin
+ Set_BusB_To[2:0] = SSS;
+ ExchangeRp = 1'b1;
+ Set_BusA_To[2:0] = DDD;
+ Read_To_Reg = 1'b1;
+ end // else: !if(IR[5:3] == 3'b110)
+ end // case: 8'b01xxxxxx
+
+ 8'b00xxx110 :
+ begin
+ if (IR[5:3] == 3'b110)
+ begin
+ // LD (HL),n
+ MCycles = 3'b011;
+ if (MCycle[1])
+ begin
+ Inc_PC = 1'b1;
+ Set_Addr_To = aXY;
+ Set_BusB_To[2:0] = SSS;
+ Set_BusB_To[3] = 1'b0;
+ end
+ if (MCycle[2])
+ Write = 1'b1;
+ end // if (IR[5:3] == 3'b110)
+ else
+ begin
+ // LD r,n
+ MCycles = 3'b010;
+ if (MCycle[1])
+ begin
+ Inc_PC = 1'b1;
+ Set_BusA_To[2:0] = DDD;
+ Read_To_Reg = 1'b1;
+ end
+ end
+ end
+
+ 8'b00001010 :
+ begin
+ // LD A,(BC)
+ MCycles = 3'b010;
+ if (MCycle[0])
+ Set_Addr_To = aBC;
+ if (MCycle[1])
+ Read_To_Acc = 1'b1;
+ end // case: 8'b00001010
+
+ 8'b00011010 :
+ begin
+ // LD A,(DE)
+ MCycles = 3'b010;
+ if (MCycle[0])
+ Set_Addr_To = aDE;
+ if (MCycle[1])
+ Read_To_Acc = 1'b1;
+ end // case: 8'b00011010
+
+ 8'b00111010 :
+ begin
+ if (Mode == 3 )
+ begin
+ // LDD A,(HL)
+ MCycles = 3'b010;
+ if (MCycle[0])
+ Set_Addr_To = aXY;
+ if (MCycle[1])
+ begin
+ Read_To_Acc = 1'b1;
+ IncDec_16 = 4'b1110;
+ end
+ end
+ else
+ begin
+ // LD A,(nn)
+ MCycles = 3'b100;
+ if (MCycle[1])
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ if (MCycle[2])
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ end
+ if (MCycle[3])
+ begin
+ Read_To_Acc = 1'b1;
+ end
+ end // else: !if(Mode == 3 )
+ end // case: 8'b00111010
+
+ 8'b00000010 :
+ begin
+ // LD (BC),A
+ MCycles = 3'b010;
+ if (MCycle[0])
+ begin
+ Set_Addr_To = aBC;
+ Set_BusB_To = 4'b0111;
+ end
+ if (MCycle[1])
+ begin
+ Write = 1'b1;
+ end
+ end // case: 8'b00000010
+
+ 8'b00010010 :
+ begin
+ // LD (DE),A
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aDE;
+ Set_BusB_To = 4'b0111;
+ end
+ MCycle[1] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b00010010
+
+ 8'b00110010 :
+ begin
+ if (Mode == 3 )
+ begin
+ // LDD (HL),A
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aXY;
+ Set_BusB_To = 4'b0111;
+ end
+ MCycle[1] :
+ begin
+ Write = 1'b1;
+ IncDec_16 = 4'b1110;
+ end
+ default :;
+ endcase // case(MCycle)
+
+ end
+ else
+ begin
+ // LD (nn),A
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ Set_BusB_To = 4'b0111;
+ end
+ MCycle[3] :
+ begin
+ Write = 1'b1;
+ end
+ default :;
+ endcase
+ end // else: !if(Mode == 3 )
+ end // case: 8'b00110010
+
+
+ // 16 BIT LOAD GROUP
+ 8'b00000001,8'b00010001,8'b00100001,8'b00110001 :
+ begin
+ // LD dd,nn
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ Read_To_Reg = 1'b1;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusA_To[3:0] = 4'b1000;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = DPAIR;
+ Set_BusA_To[0] = 1'b1;
+ end
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ Inc_PC = 1'b1;
+ Read_To_Reg = 1'b1;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusA_To[3:0] = 4'b1001;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = DPAIR;
+ Set_BusA_To[0] = 1'b0;
+ end
+ end // case: 3
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b00000001,8'b00010001,8'b00100001,8'b00110001
+
+ 8'b00101010 :
+ begin
+ if (Mode == 3 )
+ begin
+ // LDI A,(HL)
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ Read_To_Acc = 1'b1;
+ IncDec_16 = 4'b0110;
+ end
+
+ default :;
+ endcase
+ end
+ else
+ begin
+ // LD HL,(nn)
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ end
+ MCycle[3] :
+ begin
+ Set_BusA_To[2:0] = 3'b101; // L
+ Read_To_Reg = 1'b1;
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ end
+ MCycle[4] :
+ begin
+ Set_BusA_To[2:0] = 3'b100; // H
+ Read_To_Reg = 1'b1;
+ end
+ default :;
+ endcase
+ end // else: !if(Mode == 3 )
+ end // case: 8'b00101010
+
+ 8'b00100010 :
+ begin
+ if (Mode == 3 )
+ begin
+ // LDI (HL),A
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aXY;
+ Set_BusB_To = 4'b0111;
+ end
+ MCycle[1] :
+ begin
+ Write = 1'b1;
+ IncDec_16 = 4'b0110;
+ end
+ default :;
+ endcase
+ end
+ else
+ begin
+ // LD (nn),HL
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ Set_BusB_To = 4'b0101; // L
+ end
+
+ MCycle[3] :
+ begin
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ Write = 1'b1;
+ Set_BusB_To = 4'b0100; // H
+ end
+ MCycle[4] :
+ Write = 1'b1;
+ default :;
+ endcase
+ end // else: !if(Mode == 3 )
+ end // case: 8'b00100010
+
+ 8'b11111001 :
+ begin
+ // LD SP,HL
+ TStates = 3'b110;
+ LDSPHL = 1'b1;
+ end
+
+ 8'b11xx0101 :
+ begin
+ // PUSH qq
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusB_To = 4'b0111;
+ end
+ else
+ begin
+ Set_BusB_To[2:1] = DPAIR;
+ Set_BusB_To[0] = 1'b0;
+ Set_BusB_To[3] = 1'b0;
+ end
+ end // case: 1
+
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusB_To = 4'b1011;
+ end
+ else
+ begin
+ Set_BusB_To[2:1] = DPAIR;
+ Set_BusB_To[0] = 1'b1;
+ Set_BusB_To[3] = 1'b0;
+ end
+ Write = 1'b1;
+ end // case: 2
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11000101,8'b11010101,8'b11100101,8'b11110101
+
+ 8'b11xx0001 :
+ begin
+ // POP qq
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aSP;
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ Read_To_Reg = 1'b1;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusA_To[3:0] = 4'b1011;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = DPAIR;
+ Set_BusA_To[0] = 1'b1;
+ end
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ IncDec_16 = 4'b0111;
+ Read_To_Reg = 1'b1;
+ if (DPAIR == 2'b11 )
+ begin
+ Set_BusA_To[3:0] = 4'b0111;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = DPAIR;
+ Set_BusA_To[0] = 1'b0;
+ end
+ end // case: 3
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11000001,8'b11010001,8'b11100001,8'b11110001
+
+
+ // EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP
+ 8'b11101011 :
+ begin
+ if (Mode != 3 )
+ begin
+ // EX DE,HL
+ ExchangeDH = 1'b1;
+ end
+ end
+
+ 8'b00001000 :
+ begin
+ if (Mode == 3 )
+ begin
+ // LD (nn),SP
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ Set_BusB_To = 4'b1000;
+ end
+
+ MCycle[3] :
+ begin
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ Write = 1'b1;
+ Set_BusB_To = 4'b1001;
+ end
+
+ MCycle[4] :
+ Write = 1'b1;
+ default :;
+ endcase
+ end
+ else if (Mode < 2 )
+ begin
+ // EX AF,AF'
+ ExchangeAF = 1'b1;
+ end
+ end // case: 8'b00001000
+
+ 8'b11011001 :
+ begin
+ if (Mode == 3 )
+ begin
+ // RETI
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aSP;
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Jump = 1'b1;
+ IncDec_16 = 4'b0111;
+ I_RETI = 1'b1;
+ I_RETN = 1'b1;
+ SetEI = 1'b1;
+ end
+ default :;
+ endcase
+ end
+ else if (Mode < 2 )
+ begin
+ // EXX
+ ExchangeRS = 1'b1;
+ end
+ end // case: 8'b11011001
+
+ 8'b11100011 :
+ begin
+ if (Mode != 3 )
+ begin
+ // EX (SP),HL
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aSP;
+ MCycle[1] :
+ begin
+ Read_To_Reg = 1'b1;
+ Set_BusA_To = 4'b0101;
+ Set_BusB_To = 4'b0101;
+ Set_Addr_To = aSP;
+ end
+ MCycle[2] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ TStates = 3'b100;
+ Write = 1'b1;
+ end
+ MCycle[3] :
+ begin
+ Read_To_Reg = 1'b1;
+ Set_BusA_To = 4'b0100;
+ Set_BusB_To = 4'b0100;
+ Set_Addr_To = aSP;
+ end
+ MCycle[4] :
+ begin
+ IncDec_16 = 4'b1111;
+ TStates = 3'b101;
+ Write = 1'b1;
+ end
+
+ default :;
+ endcase
+ end // if (Mode != 3 )
+ end // case: 8'b11100011
+
+
+ // 8 BIT ARITHMETIC AND LOGICAL GROUP
+ 8'b10xxxxxx :
+ begin
+ if (IR[2:0] == 3'b110)
+ begin
+ // ADD A,(HL)
+ // ADC A,(HL)
+ // SUB A,(HL)
+ // SBC A,(HL)
+ // AND A,(HL)
+ // OR A,(HL)
+ // XOR A,(HL)
+ // CP A,(HL)
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusB_To[2:0] = SSS;
+ Set_BusA_To[2:0] = 3'b111;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // if (IR[2:0] == 3'b110)
+ else
+ begin
+ // ADD A,r
+ // ADC A,r
+ // SUB A,r
+ // SBC A,r
+ // AND A,r
+ // OR A,r
+ // XOR A,r
+ // CP A,r
+ Set_BusB_To[2:0] = SSS;
+ Set_BusA_To[2:0] = 3'b111;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ end // else: !if(IR[2:0] == 3'b110)
+ end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,...
+
+ 8'b11xxx110 :
+ begin
+ // ADD A,n
+ // ADC A,n
+ // SUB A,n
+ // SBC A,n
+ // AND A,n
+ // OR A,n
+ // XOR A,n
+ // CP A,n
+ MCycles = 3'b010;
+ if (MCycle[1] )
+ begin
+ Inc_PC = 1'b1;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusB_To[2:0] = SSS;
+ Set_BusA_To[2:0] = 3'b111;
+ end
+ end
+
+ 8'b00xxx100 :
+ begin
+ if (IR[5:3] == 3'b110)
+ begin
+ // INC (HL)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ TStates = 3'b100;
+ Set_Addr_To = aXY;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ PreserveC = 1'b1;
+ ALU_Op = 4'b0000;
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To[2:0] = DDD;
+ end // case: 2
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b00110100
+ else
+ begin
+ // INC r
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To[2:0] = DDD;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ PreserveC = 1'b1;
+ ALU_Op = 4'b0000;
+ end
+ end
+
+ 8'b00xxx101 :
+ begin
+ if (IR[5:3] == 3'b110)
+ begin
+ // DEC (HL)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ TStates = 3'b100;
+ Set_Addr_To = aXY;
+ ALU_Op = 4'b0010;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ PreserveC = 1'b1;
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To[2:0] = DDD;
+ end // case: 2
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end
+ else
+ begin
+ // DEC r
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To[2:0] = DDD;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ PreserveC = 1'b1;
+ ALU_Op = 4'b0010;
+ end
+ end
+
+ // GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS
+ 8'b00100111 :
+ begin
+ // DAA
+ Set_BusA_To[2:0] = 3'b111;
+ Read_To_Reg = 1'b1;
+ ALU_Op = 4'b1100;
+ Save_ALU = 1'b1;
+ end
+
+ 8'b00101111 :
+ // CPL
+ I_CPL = 1'b1;
+
+ 8'b00111111 :
+ // CCF
+ I_CCF = 1'b1;
+
+ 8'b00110111 :
+ // SCF
+ I_SCF = 1'b1;
+
+ 8'b00000000 :
+ begin
+ if (NMICycle == 1'b1 )
+ begin
+ // NMI
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1101;
+ end
+
+ MCycle[1] :
+ begin
+ TStates = 3'b100;
+ Write = 1'b1;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1100;
+ end
+
+ MCycle[2] :
+ begin
+ TStates = 3'b100;
+ Write = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+
+ end
+ else if (IntCycle == 1'b1 )
+ begin
+ // INT (IM 2)
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ LDZ = 1'b1;
+ TStates = 3'b101;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1101;
+ end
+
+ MCycle[1] :
+ begin
+ TStates = 3'b100;
+ Write = 1'b1;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1100;
+ end
+
+ MCycle[2] :
+ begin
+ TStates = 3'b100;
+ Write = 1'b1;
+ end
+
+ MCycle[3] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[4] :
+ Jump = 1'b1;
+ default :;
+ endcase
+ end
+ end // case: 8'b00000000
+
+ 8'b11110011 :
+ // DI
+ SetDI = 1'b1;
+
+ 8'b11111011 :
+ // EI
+ SetEI = 1'b1;
+
+ // 16 BIT ARITHMETIC GROUP
+ 8'b00001001,8'b00011001,8'b00101001,8'b00111001 :
+ begin
+ // ADD HL,ss
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ NoRead = 1'b1;
+ ALU_Op = 4'b0000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusA_To[2:0] = 3'b101;
+ case (IR[5:4])
+ 0,1,2 :
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b1;
+ end
+
+ default :
+ Set_BusB_To = 4'b1000;
+ endcase // case(IR[5:4])
+
+ TStates = 3'b100;
+ Arith16 = 1'b1;
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0001;
+ Set_BusA_To[2:0] = 3'b100;
+ case (IR[5:4])
+ 0,1,2 :
+ Set_BusB_To[2:1] = IR[5:4];
+ default :
+ Set_BusB_To = 4'b1001;
+ endcase
+ Arith16 = 1'b1;
+ end // case: 3
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b00001001,8'b00011001,8'b00101001,8'b00111001
+
+ 8'b00000011,8'b00010011,8'b00100011,8'b00110011 :
+ begin
+ // INC ss
+ TStates = 3'b110;
+ IncDec_16[3:2] = 2'b01;
+ IncDec_16[1:0] = DPAIR;
+ end
+
+ 8'b00001011,8'b00011011,8'b00101011,8'b00111011 :
+ begin
+ // DEC ss
+ TStates = 3'b110;
+ IncDec_16[3:2] = 2'b11;
+ IncDec_16[1:0] = DPAIR;
+ end
+
+ // ROTATE AND SHIFT GROUP
+ 8'b00000111,
+ // RLCA
+ 8'b00010111,
+ // RLA
+ 8'b00001111,
+ // RRCA
+ 8'b00011111 :
+ // RRA
+ begin
+ Set_BusA_To[2:0] = 3'b111;
+ ALU_Op = 4'b1000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ end // case: 8'b00000111,...
+
+
+ // JUMP GROUP
+ 8'b11000011 :
+ begin
+ // JP nn
+ MCycles = 3'b011;
+ if (MCycle[1])
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ if (MCycle[2])
+ begin
+ Inc_PC = 1'b1;
+ Jump = 1'b1;
+ end
+
+ end // case: 8'b11000011
+
+ 8'b11xxx010 :
+ begin
+ if (IR[5] == 1'b1 && Mode == 3 )
+ begin
+ case (IR[4:3])
+ 2'b00 :
+ begin
+ // LD ($FF00+C),A
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aBC;
+ Set_BusB_To = 4'b0111;
+ end
+ MCycle[1] :
+ begin
+ Write = 1'b1;
+ IORQ = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b00
+
+ 2'b01 :
+ begin
+ // LD (nn),A
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ Set_BusB_To = 4'b0111;
+ end
+
+ MCycle[3] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: default :...
+
+ 2'b10 :
+ begin
+ // LD A,($FF00+C)
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aBC;
+ MCycle[1] :
+ begin
+ Read_To_Acc = 1'b1;
+ IORQ = 1'b1;
+ end
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b10
+
+ 2'b11 :
+ begin
+ // LD A,(nn)
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ end
+ MCycle[3] :
+ Read_To_Acc = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end
+ endcase
+ end
+ else
+ begin
+ // JP cc,nn
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Inc_PC = 1'b1;
+ if (is_cc_true(F, IR[5:3]) )
+ begin
+ Jump = 1'b1;
+ end
+ end
+
+ default :;
+ endcase
+ end // else: !if(DPAIR == 2'b11 )
+ end // case: 8'b11000010,8'b11001010,8'b11010010,8'b11011010,8'b11100010,8'b11101010,8'b11110010,8'b11111010
+
+ 8'b00011000 :
+ begin
+ if (Mode != 2 )
+ begin
+ // JR e
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ Inc_PC = 1'b1;
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ JumpE = 1'b1;
+ TStates = 3'b101;
+ end
+ default :;
+ endcase
+ end // if (Mode != 2 )
+ end // case: 8'b00011000
+
+ // Conditional relative jumps (JR [C/NC/Z/NZ], e)
+ 8'b001xx000 :
+ begin
+ if (Mode != 2 )
+ begin
+ MCycles = 3'd3;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+
+ case (IR[4:3])
+ 0 : MCycles = (F[Flag_Z]) ? 3'd2 : 3'd3;
+ 1 : MCycles = (!F[Flag_Z]) ? 3'd2 : 3'd3;
+ 2 : MCycles = (F[Flag_C]) ? 3'd2 : 3'd3;
+ 3 : MCycles = (!F[Flag_C]) ? 3'd2 : 3'd3;
+ endcase
+ end
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ JumpE = 1'b1;
+ TStates = 3'd5;
+ end
+ default :;
+ endcase
+ end // if (Mode != 2 )
+ end // case: 8'b00111000
+
+ 8'b11101001 :
+ // JP (HL)
+ JumpXY = 1'b1;
+
+ 8'b00010000 :
+ begin
+ if (Mode == 3 )
+ begin
+ I_DJNZ = 1'b1;
+ end
+ else if (Mode < 2 )
+ begin
+ // DJNZ,e
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ I_DJNZ = 1'b1;
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To[2:0] = 3'b000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0010;
+ end
+ MCycle[1] :
+ begin
+ I_DJNZ = 1'b1;
+ Inc_PC = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ JumpE = 1'b1;
+ TStates = 3'b101;
+ end
+ default :;
+ endcase
+ end // if (Mode < 2 )
+ end // case: 8'b00010000
+
+
+ // CALL AND RETURN GROUP
+ 8'b11001101 :
+ begin
+ // CALL nn
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ IncDec_16 = 4'b1111;
+ Inc_PC = 1'b1;
+ TStates = 3'b100;
+ Set_Addr_To = aSP;
+ LDW = 1'b1;
+ Set_BusB_To = 4'b1101;
+ end
+ MCycle[3] :
+ begin
+ Write = 1'b1;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1100;
+ end
+ MCycle[4] :
+ begin
+ Write = 1'b1;
+ Call = 1'b1;
+ end
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11001101
+
+ 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100 :
+ begin
+ if (IR[5] == 1'b0 || Mode != 3 )
+ begin
+ // CALL cc,nn
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ if (is_cc_true(F, IR[5:3]) )
+ begin
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ TStates = 3'b100;
+ Set_BusB_To = 4'b1101;
+ end
+ else
+ begin
+ MCycles = 3'b011;
+ end // else: !if(is_cc_true(F, IR[5:3]) )
+ end // case: 3
+
+ MCycle[3] :
+ begin
+ Write = 1'b1;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1100;
+ end
+
+ MCycle[4] :
+ begin
+ Write = 1'b1;
+ Call = 1'b1;
+ end
+
+ default :;
+ endcase
+ end // if (IR[5] == 1'b0 || Mode != 3 )
+ end // case: 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100
+
+ 8'b11001001 :
+ begin
+ // RET
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ Set_Addr_To = aSP;
+ end
+
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Jump = 1'b1;
+ IncDec_16 = 4'b0111;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11001001
+
+ 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 :
+ begin
+ if (IR[5] == 1'b1 && Mode == 3 )
+ begin
+ case (IR[4:3])
+ 2'b00 :
+ begin
+ // LD ($FF00+nn),A
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ Set_Addr_To = aIOA;
+ Set_BusB_To = 4'b0111;
+ end
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b00
+
+ 2'b01 :
+ begin
+ // ADD SP,n
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ ALU_Op = 4'b0000;
+ Inc_PC = 1'b1;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusA_To = 4'b1000;
+ Set_BusB_To = 4'b0110;
+ end
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0001;
+ Set_BusA_To = 4'b1001;
+ Set_BusB_To = 4'b1110; // Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b01
+
+ 2'b10 :
+ begin
+ // LD A,($FF00+nn)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ Set_Addr_To = aIOA;
+ end
+
+ MCycle[2] :
+ Read_To_Acc = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b10
+
+ 2'b11 :
+ begin
+ // LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ end
+
+ MCycle[3] :
+ begin
+ Set_BusA_To[2:0] = 3'b101; // L
+ Read_To_Reg = 1'b1;
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ end
+
+ MCycle[4] :
+ begin
+ Set_BusA_To[2:0] = 3'b100; // H
+ Read_To_Reg = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 2'b11
+
+ endcase // case(IR[4:3])
+
+ end
+ else
+ begin
+ // RET cc
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ if (is_cc_true(F, IR[5:3]) )
+ begin
+ Set_Addr_To = aSP;
+ end
+ else
+ begin
+ MCycles = 3'b001;
+ end
+ TStates = 3'b101;
+ end // case: 1
+
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ LDZ = 1'b1;
+ end
+ MCycle[2] :
+ begin
+ Jump = 1'b1;
+ IncDec_16 = 4'b0111;
+ end
+ default :;
+ endcase
+ end // else: !if(IR[5] == 1'b1 && Mode == 3 )
+ end // case: 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000
+
+ 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 :
+ begin
+ // RST p
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1101;
+ end
+
+ MCycle[1] :
+ begin
+ Write = 1'b1;
+ IncDec_16 = 4'b1111;
+ Set_Addr_To = aSP;
+ Set_BusB_To = 4'b1100;
+ end
+
+ MCycle[2] :
+ begin
+ Write = 1'b1;
+ RstP = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111
+
+ // INPUT AND OUTPUT GROUP
+ 8'b11011011 :
+ begin
+ if (Mode != 3 )
+ begin
+ // IN A,(n)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ Set_Addr_To = aIOA;
+ end
+
+ MCycle[2] :
+ begin
+ Read_To_Acc = 1'b1;
+ IORQ = 1'b1;
+ end
+
+ default :;
+ endcase
+ end // if (Mode != 3 )
+ end // case: 8'b11011011
+
+ 8'b11010011 :
+ begin
+ if (Mode != 3 )
+ begin
+ // OUT (n),A
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ Set_Addr_To = aIOA;
+ Set_BusB_To = 4'b0111;
+ end
+
+ MCycle[2] :
+ begin
+ Write = 1'b1;
+ IORQ = 1'b1;
+ end
+
+ default :;
+ endcase
+ end // if (Mode != 3 )
+ end // case: 8'b11010011
+
+
+ //----------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
+ // MULTIBYTE INSTRUCTIONS
+ //----------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
+
+ 8'b11001011 :
+ begin
+ if (Mode != 2 )
+ begin
+ Prefix = 2'b01;
+ end
+ end
+
+ 8'b11101101 :
+ begin
+ if (Mode < 2 )
+ begin
+ Prefix = 2'b10;
+ end
+ end
+
+ 8'b11011101,8'b11111101 :
+ begin
+ if (Mode < 2 )
+ begin
+ Prefix = 2'b11;
+ end
+ end
+
+ endcase // case(IR)
+ end // case: 2'b00
+
+
+ 2'b01 :
+ begin
+
+
+ //----------------------------------------------------------------------------
+ //
+ // CB prefixed instructions
+ //
+ //----------------------------------------------------------------------------
+
+ Set_BusA_To[2:0] = IR[2:0];
+ Set_BusB_To[2:0] = IR[2:0];
+
+ case (IR)
+ 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,
+ 8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010111,
+ 8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001111,
+ 8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011111,
+ 8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100111,
+ 8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101111,
+ 8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110111,
+ 8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111111 :
+ begin
+ // RLC r
+ // RL r
+ // RRC r
+ // RR r
+ // SLA r
+ // SRA r
+ // SRL r
+ // SLL r (Undocumented) / SWAP r
+ if (MCycle[0] ) begin
+ ALU_Op = 4'b1000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ end
+ end // case: 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,...
+
+ 8'b00xxx110 :
+ begin
+ // RLC (HL)
+ // RL (HL)
+ // RRC (HL)
+ // RR (HL)
+ // SRA (HL)
+ // SRL (HL)
+ // SLA (HL)
+ // SLL (HL) (Undocumented) / SWAP (HL)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0], MCycle[6] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ ALU_Op = 4'b1000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_Addr_To = aXY;
+ TStates = 3'b100;
+ end
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b00000110,8'b00010110,8'b00001110,8'b00011110,8'b00101110,8'b00111110,8'b00100110,8'b00110110
+
+ 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,
+ 8'b01001000,8'b01001001,8'b01001010,8'b01001011,8'b01001100,8'b01001101,8'b01001111,
+ 8'b01010000,8'b01010001,8'b01010010,8'b01010011,8'b01010100,8'b01010101,8'b01010111,
+ 8'b01011000,8'b01011001,8'b01011010,8'b01011011,8'b01011100,8'b01011101,8'b01011111,
+ 8'b01100000,8'b01100001,8'b01100010,8'b01100011,8'b01100100,8'b01100101,8'b01100111,
+ 8'b01101000,8'b01101001,8'b01101010,8'b01101011,8'b01101100,8'b01101101,8'b01101111,
+ 8'b01110000,8'b01110001,8'b01110010,8'b01110011,8'b01110100,8'b01110101,8'b01110111,
+ 8'b01111000,8'b01111001,8'b01111010,8'b01111011,8'b01111100,8'b01111101,8'b01111111 :
+ begin
+ // BIT b,r
+ if (MCycle[0] )
+ begin
+ Set_BusB_To[2:0] = IR[2:0];
+ ALU_Op = 4'b1001;
+ end
+ end // case: 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,...
+
+ 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 :
+ begin
+ // BIT b,(HL)
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0], MCycle[6] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ ALU_Op = 4'b1001;
+ TStates = 3'b100;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110
+
+ 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,
+ 8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001111,
+ 8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010111,
+ 8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011111,
+ 8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100111,
+ 8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101111,
+ 8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110111,
+ 8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111111 :
+ begin
+ // SET b,r
+ if (MCycle[0] )
+ begin
+ ALU_Op = 4'b1010;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ end
+ end // case: 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,...
+
+ 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 :
+ begin
+ // SET b,(HL)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0], MCycle[6] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ ALU_Op = 4'b1010;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_Addr_To = aXY;
+ TStates = 3'b100;
+ end
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110
+
+ 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,
+ 8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001111,
+ 8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010111,
+ 8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011111,
+ 8'b10100000,8'b10100001,8'b10100010,8'b10100011,8'b10100100,8'b10100101,8'b10100111,
+ 8'b10101000,8'b10101001,8'b10101010,8'b10101011,8'b10101100,8'b10101101,8'b10101111,
+ 8'b10110000,8'b10110001,8'b10110010,8'b10110011,8'b10110100,8'b10110101,8'b10110111,
+ 8'b10111000,8'b10111001,8'b10111010,8'b10111011,8'b10111100,8'b10111101,8'b10111111 :
+ begin
+ // RES b,r
+ if (MCycle[0] )
+ begin
+ ALU_Op = 4'b1011;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ end
+ end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,...
+
+ 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 :
+ begin
+ // RES b,(HL)
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0], MCycle[6] :
+ Set_Addr_To = aXY;
+ MCycle[1] :
+ begin
+ ALU_Op = 4'b1011;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_Addr_To = aXY;
+ TStates = 3'b100;
+ end
+
+ MCycle[2] :
+ Write = 1'b1;
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110
+
+ endcase // case(IR)
+ end // case: 2'b01
+
+
+ default :
+ begin : default_ed_block
+
+ //----------------------------------------------------------------------------
+ //
+ // ED prefixed instructions
+ //
+ //----------------------------------------------------------------------------
+
+ case (IR)
+ /*
+ * Undocumented NOP instructions commented out to reduce size of mcode
+ *
+ 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000110,8'b00000111
+ ,8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001110,8'b00001111
+ ,8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010110,8'b00010111
+ ,8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011110,8'b00011111
+ ,8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100110,8'b00100111
+ ,8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101110,8'b00101111
+ ,8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110110,8'b00110111
+ ,8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111110,8'b00111111
+
+
+ ,8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000110,8'b10000111
+ ,8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001110,8'b10001111
+ ,8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010110,8'b10010111
+ ,8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011110,8'b10011111
+ , 8'b10100100,8'b10100101,8'b10100110,8'b10100111
+ , 8'b10101100,8'b10101101,8'b10101110,8'b10101111
+ , 8'b10110100,8'b10110101,8'b10110110,8'b10110111
+ , 8'b10111100,8'b10111101,8'b10111110,8'b10111111
+ ,8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000110,8'b11000111
+ ,8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001110,8'b11001111
+ ,8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010110,8'b11010111
+ ,8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011110,8'b11011111
+ ,8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100110,8'b11100111
+ ,8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101110,8'b11101111
+ ,8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110110,8'b11110111
+ ,8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111110,8'b11111111 :
+ ; // NOP, undocumented
+
+ 8'b01111110,8'b01111111 :
+ // NOP, undocumented
+ ;
+ */
+
+ // 8 BIT LOAD GROUP
+ 8'b01010111 :
+ begin
+ // LD A,I
+ Special_LD = 3'b100;
+ TStates = 3'b101;
+ end
+
+ 8'b01011111 :
+ begin
+ // LD A,R
+ Special_LD = 3'b101;
+ TStates = 3'b101;
+ end
+
+ 8'b01000111 :
+ begin
+ // LD I,A
+ Special_LD = 3'b110;
+ TStates = 3'b101;
+ end
+
+ 8'b01001111 :
+ begin
+ // LD R,A
+ Special_LD = 3'b111;
+ TStates = 3'b101;
+ end
+
+ // 16 BIT LOAD GROUP
+ 8'b01001011,8'b01011011,8'b01101011,8'b01111011 :
+ begin
+ // LD dd,(nn)
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ end
+
+ MCycle[3] :
+ begin
+ Read_To_Reg = 1'b1;
+ if (IR[5:4] == 2'b11 )
+ begin
+ Set_BusA_To = 4'b1000;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = IR[5:4];
+ Set_BusA_To[0] = 1'b1;
+ end
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ end // case: 4
+
+ MCycle[4] :
+ begin
+ Read_To_Reg = 1'b1;
+ if (IR[5:4] == 2'b11 )
+ begin
+ Set_BusA_To = 4'b1001;
+ end
+ else
+ begin
+ Set_BusA_To[2:1] = IR[5:4];
+ Set_BusA_To[0] = 1'b0;
+ end
+ end // case: 5
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01001011,8'b01011011,8'b01101011,8'b01111011
+
+
+ 8'b01000011,8'b01010011,8'b01100011,8'b01110011 :
+ begin
+ // LD (nn),dd
+ MCycles = 3'b101;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ Inc_PC = 1'b1;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Set_Addr_To = aZI;
+ Inc_PC = 1'b1;
+ LDW = 1'b1;
+ if (IR[5:4] == 2'b11 )
+ begin
+ Set_BusB_To = 4'b1000;
+ end
+ else
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b1;
+ Set_BusB_To[3] = 1'b0;
+ end
+ end // case: 3
+
+ MCycle[3] :
+ begin
+ Inc_WZ = 1'b1;
+ Set_Addr_To = aZI;
+ Write = 1'b1;
+ if (IR[5:4] == 2'b11 )
+ begin
+ Set_BusB_To = 4'b1001;
+ end
+ else
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b0;
+ Set_BusB_To[3] = 1'b0;
+ end
+ end // case: 4
+
+ MCycle[4] :
+ begin
+ Write = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01000011,8'b01010011,8'b01100011,8'b01110011
+
+ 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 :
+ begin
+ // LDI, LDD, LDIR, LDDR
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aXY;
+ IncDec_16 = 4'b1100; // BC
+ end
+
+ MCycle[1] :
+ begin
+ Set_BusB_To = 4'b0110;
+ Set_BusA_To[2:0] = 3'b111;
+ ALU_Op = 4'b0000;
+ Set_Addr_To = aDE;
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0110; // IX
+ end
+ else
+ begin
+ IncDec_16 = 4'b1110;
+ end
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ I_BT = 1'b1;
+ TStates = 3'b101;
+ Write = 1'b1;
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0101; // DE
+ end
+ else
+ begin
+ IncDec_16 = 4'b1101;
+ end
+ end // case: 3
+
+ MCycle[3] :
+ begin
+ NoRead = 1'b1;
+ TStates = 3'b101;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000
+
+ 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 :
+ begin
+ // CPI, CPD, CPIR, CPDR
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aXY;
+ IncDec_16 = 4'b1100; // BC
+ end
+
+ MCycle[1] :
+ begin
+ Set_BusB_To = 4'b0110;
+ Set_BusA_To[2:0] = 3'b111;
+ ALU_Op = 4'b0111;
+ Save_ALU = 1'b1;
+ PreserveC = 1'b1;
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0110;
+ end
+ else
+ begin
+ IncDec_16 = 4'b1110;
+ end
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ I_BC = 1'b1;
+ TStates = 3'b101;
+ end
+
+ MCycle[3] :
+ begin
+ NoRead = 1'b1;
+ TStates = 3'b101;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001
+
+ 8'b01000100,8'b01001100,8'b01010100,8'b01011100,8'b01100100,8'b01101100,8'b01110100,8'b01111100 :
+ begin
+ // NEG
+ ALU_Op = 4'b0010;
+ Set_BusB_To = 4'b0111;
+ Set_BusA_To = 4'b1010;
+ Read_To_Acc = 1'b1;
+ Save_ALU = 1'b1;
+ end
+
+ 8'b01000110,8'b01001110,8'b01100110,8'b01101110 :
+ begin
+ // IM 0
+ IMode = 2'b00;
+ end
+
+ 8'b01010110,8'b01110110 :
+ // IM 1
+ IMode = 2'b01;
+
+ 8'b01011110,8'b01110111 :
+ // IM 2
+ IMode = 2'b10;
+
+ // 16 bit arithmetic
+ 8'b01001010,8'b01011010,8'b01101010,8'b01111010 :
+ begin
+ // ADC HL,ss
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ NoRead = 1'b1;
+ ALU_Op = 4'b0001;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusA_To[2:0] = 3'b101;
+ case (IR[5:4])
+ 0,1,2 :
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b1;
+ end
+ default :
+ Set_BusB_To = 4'b1000;
+ endcase
+ TStates = 3'b100;
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0001;
+ Set_BusA_To[2:0] = 3'b100;
+ case (IR[5:4])
+ 0,1,2 :
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b0;
+ end
+ default :
+ Set_BusB_To = 4'b1001;
+ endcase // case(IR[5:4])
+ end // case: 3
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01001010,8'b01011010,8'b01101010,8'b01111010
+
+ 8'b01000010,8'b01010010,8'b01100010,8'b01110010 :
+ begin
+ // SBC HL,ss
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ NoRead = 1'b1;
+ ALU_Op = 4'b0011;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusA_To[2:0] = 3'b101;
+ case (IR[5:4])
+ 0,1,2 :
+ begin
+ Set_BusB_To[2:1] = IR[5:4];
+ Set_BusB_To[0] = 1'b1;
+ end
+ default :
+ Set_BusB_To = 4'b1000;
+ endcase
+ TStates = 3'b100;
+ end // case: 2
+
+ MCycle[2] :
+ begin
+ NoRead = 1'b1;
+ ALU_Op = 4'b0011;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ Set_BusA_To[2:0] = 3'b100;
+ case (IR[5:4])
+ 0,1,2 :
+ Set_BusB_To[2:1] = IR[5:4];
+ default :
+ Set_BusB_To = 4'b1001;
+ endcase
+ end // case: 3
+
+ default :;
+
+ endcase // case(MCycle)
+ end // case: 8'b01000010,8'b01010010,8'b01100010,8'b01110010
+
+ 8'b01101111 :
+ begin
+ // RLD
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ begin
+ NoRead = 1'b1;
+ Set_Addr_To = aXY;
+ end
+
+ MCycle[2] :
+ begin
+ Read_To_Reg = 1'b1;
+ Set_BusB_To[2:0] = 3'b110;
+ Set_BusA_To[2:0] = 3'b111;
+ ALU_Op = 4'b1101;
+ TStates = 3'b100;
+ Set_Addr_To = aXY;
+ Save_ALU = 1'b1;
+ end
+
+ MCycle[3] :
+ begin
+ I_RLD = 1'b1;
+ Write = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01101111
+
+ 8'b01100111 :
+ begin
+ // RRD
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[1] :
+ Set_Addr_To = aXY;
+ MCycle[2] :
+ begin
+ Read_To_Reg = 1'b1;
+ Set_BusB_To[2:0] = 3'b110;
+ Set_BusA_To[2:0] = 3'b111;
+ ALU_Op = 4'b1110;
+ TStates = 3'b100;
+ Set_Addr_To = aXY;
+ Save_ALU = 1'b1;
+ end
+
+ MCycle[3] :
+ begin
+ I_RRD = 1'b1;
+ Write = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01100111
+
+ 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 :
+ begin
+ // RETI, RETN
+ MCycles = 3'b011;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aSP;
+
+ MCycle[1] :
+ begin
+ IncDec_16 = 4'b0111;
+ Set_Addr_To = aSP;
+ LDZ = 1'b1;
+ end
+
+ MCycle[2] :
+ begin
+ Jump = 1'b1;
+ IncDec_16 = 4'b0111;
+ I_RETI = IR[3];
+ I_RETN = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101
+
+ 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 :
+ begin
+ // IN r,(C)
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ Set_Addr_To = aBC;
+
+ MCycle[1] :
+ begin
+ IORQ = 1'b1;
+ if (IR[5:3] != 3'b110 )
+ begin
+ Read_To_Reg = 1'b1;
+ Set_BusA_To[2:0] = IR[5:3];
+ end
+ I_INRC = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000
+
+ 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 :
+ begin
+ // OUT (C),r
+ // OUT (C),0
+ MCycles = 3'b010;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aBC;
+ Set_BusB_To[2:0] = IR[5:3];
+ if (IR[5:3] == 3'b110 )
+ begin
+ Set_BusB_To[3] = 1'b1;
+ end
+ end
+
+ MCycle[1] :
+ begin
+ Write = 1'b1;
+ IORQ = 1'b1;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001
+
+ 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 :
+ begin
+ // INI, IND, INIR, INDR
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ Set_Addr_To = aBC;
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To = 4'b0000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0010;
+ end
+
+ MCycle[1] :
+ begin
+ IORQ = 1'b1;
+ Set_BusB_To = 4'b0110;
+ Set_Addr_To = aXY;
+ end
+
+ MCycle[2] :
+ begin
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0110;
+ end
+ else
+ begin
+ IncDec_16 = 4'b1110;
+ end
+ TStates = 3'b100;
+ Write = 1'b1;
+ I_BTR = 1'b1;
+ end // case: 3
+
+ MCycle[3] :
+ begin
+ NoRead = 1'b1;
+ TStates = 3'b101;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010
+
+ 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 :
+ begin
+ // OUTI, OUTD, OTIR, OTDR
+ MCycles = 3'b100;
+ case (1'b1) // MCycle
+ MCycle[0] :
+ begin
+ TStates = 3'b101;
+ Set_Addr_To = aXY;
+ Set_BusB_To = 4'b1010;
+ Set_BusA_To = 4'b0000;
+ Read_To_Reg = 1'b1;
+ Save_ALU = 1'b1;
+ ALU_Op = 4'b0010;
+ end
+
+ MCycle[1] :
+ begin
+ Set_BusB_To = 4'b0110;
+ Set_Addr_To = aBC;
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0110;
+ end
+ else
+ begin
+ IncDec_16 = 4'b1110;
+ end
+ end
+
+ MCycle[2] :
+ begin
+ if (IR[3] == 1'b0 )
+ begin
+ IncDec_16 = 4'b0010;
+ end
+ else
+ begin
+ IncDec_16 = 4'b1010;
+ end
+ IORQ = 1'b1;
+ Write = 1'b1;
+ I_BTR = 1'b1;
+ end // case: 3
+
+ MCycle[3] :
+ begin
+ NoRead = 1'b1;
+ TStates = 3'b101;
+ end
+
+ default :;
+ endcase // case(MCycle)
+ end // case: 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011
+
+ endcase // case(IR)
+ end // block: default_ed_block
+ endcase // case(ISet)
+
+ if (Mode == 1 )
+ begin
+ if (MCycle[0] )
+ begin
+ //TStates = 3'b100;
+ end
+ else
+ begin
+ TStates = 3'b011;
+ end
+ end
+
+ if (Mode == 3 )
+ begin
+ if (MCycle[0] )
+ begin
+ //TStates = 3'b100;
+ end
+ else
+ begin
+ TStates = 3'b100;
+ end
+ end
+
+ if (Mode < 2 )
+ begin
+ if (MCycle[5] )
+ begin
+ Inc_PC = 1'b1;
+ if (Mode == 1 )
+ begin
+ Set_Addr_To = aXY;
+ TStates = 3'b100;
+ Set_BusB_To[2:0] = SSS;
+ Set_BusB_To[3] = 1'b0;
+ end
+ if (IR == 8'b00110110 || IR == 8'b11001011 )
+ begin
+ Set_Addr_To = aNone;
+ end
+ end
+ if (MCycle[6] )
+ begin
+ if (Mode == 0 )
+ begin
+ TStates = 3'b101;
+ end
+ if (ISet != 2'b01 )
+ begin
+ Set_Addr_To = aXY;
+ end
+ Set_BusB_To[2:0] = SSS;
+ Set_BusB_To[3] = 1'b0;
+ if (IR == 8'b00110110 || ISet == 2'b01 )
+ begin
+ // LD (HL),n
+ Inc_PC = 1'b1;
+ end
+ else
+ begin
+ NoRead = 1'b1;
+ end
+ end
+ end // if (Mode < 2 )
+
+ end // always @ (IR, ISet, MCycle, F, NMICycle, IntCycle)
+
+ // synopsys dc_script_begin
+ // set_attribute current_design "revision" "$Id: tv80_mcode.v,v 1.6 2005/12/13 19:17:09 ghutchis Exp $" -type string -quiet
+ // synopsys dc_script_end
+endmodule // T80_MCode
diff --git a/tv80/tv80_reg.v b/tv80/tv80_reg.v
new file mode 100644
index 0000000..8218407
--- /dev/null
+++ b/tv80/tv80_reg.v
@@ -0,0 +1,71 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80_reg (/*AUTOARG*/
+ // Outputs
+ DOBH, DOAL, DOCL, DOBL, DOCH, DOAH,
+ // Inputs
+ AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL
+ );
+ input [2:0] AddrC;
+ output [7:0] DOBH;
+ input [2:0] AddrA;
+ input [2:0] AddrB;
+ input [7:0] DIH;
+ output [7:0] DOAL;
+ output [7:0] DOCL;
+ input [7:0] DIL;
+ output [7:0] DOBL;
+ output [7:0] DOCH;
+ output [7:0] DOAH;
+ input clk, CEN, WEH, WEL;
+
+ reg [7:0] RegsH [0:7];
+ reg [7:0] RegsL [0:7];
+
+ always @(posedge clk)
+ begin
+ if (CEN)
+ begin
+ if (WEH) RegsH[AddrA] <= DIH;
+ if (WEL) RegsL[AddrA] <= DIL;
+ end
+ end
+
+ assign DOAH = RegsH[AddrA];
+ assign DOAL = RegsL[AddrA];
+ assign DOBH = RegsH[AddrB];
+ assign DOBL = RegsL[AddrB];
+ assign DOCH = RegsH[AddrC];
+ assign DOCL = RegsL[AddrC];
+
+ // break out ram bits for waveform debug
+ wire [7:0] H = RegsH[2];
+ wire [7:0] L = RegsL[2];
+
+// synopsys dc_script_begin
+// set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004/05/16 17:39:57 ghutchis Exp $" -type string -quiet
+// synopsys dc_script_end
+endmodule
+
diff --git a/tv80/tv80n.v b/tv80/tv80n.v
new file mode 100644
index 0000000..be302b0
--- /dev/null
+++ b/tv80/tv80n.v
@@ -0,0 +1,182 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// Negative-edge based wrapper allows memory wait_n signal to work
+// correctly without resorting to asynchronous logic.
+
+module tv80n (/*AUTOARG*/
+ // Outputs
+ m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do,
+ // Inputs
+ reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
+ );
+
+ parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
+ parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
+
+
+ input reset_n;
+ input clk;
+ input wait_n;
+ input int_n;
+ input nmi_n;
+ input busrq_n;
+ output m1_n;
+ output mreq_n;
+ output iorq_n;
+ output rd_n;
+ output wr_n;
+ output rfsh_n;
+ output halt_n;
+ output busak_n;
+ output [15:0] A;
+ input [7:0] di;
+ output [7:0] do;
+
+ reg mreq_n;
+ reg iorq_n;
+ reg rd_n;
+ reg wr_n;
+ reg nxt_mreq_n;
+ reg nxt_iorq_n;
+ reg nxt_rd_n;
+ reg nxt_wr_n;
+
+ wire cen;
+ wire intcycle_n;
+ wire no_read;
+ wire write;
+ wire iorq;
+ reg [7:0] di_reg;
+ wire [6:0] mcycle;
+ wire [6:0] tstate;
+
+ assign cen = 1;
+
+ tv80_core #(Mode, IOWait) i_tv80_core
+ (
+ .cen (cen),
+ .m1_n (m1_n),
+ .iorq (iorq),
+ .no_read (no_read),
+ .write (write),
+ .rfsh_n (rfsh_n),
+ .halt_n (halt_n),
+ .wait_n (wait_n),
+ .int_n (int_n),
+ .nmi_n (nmi_n),
+ .reset_n (reset_n),
+ .busrq_n (busrq_n),
+ .busak_n (busak_n),
+ .clk (clk),
+ .IntE (),
+ .stop (),
+ .A (A),
+ .dinst (di),
+ .di (di_reg),
+ .do (do),
+ .mc (mcycle),
+ .ts (tstate),
+ .intcycle_n (intcycle_n)
+ );
+
+ always @*
+ begin
+ nxt_mreq_n = 1;
+ nxt_rd_n = 1;
+ nxt_iorq_n = 1;
+ nxt_wr_n = 1;
+
+ if (mcycle[0])
+ begin
+ if (tstate[1] || tstate[2])
+ begin
+ nxt_rd_n = ~ intcycle_n;
+ nxt_mreq_n = ~ intcycle_n;
+ nxt_iorq_n = intcycle_n;
+ end
+ end // if (mcycle[0])
+ else
+ begin
+ if ((tstate[1] || tstate[2]) && !no_read && !write)
+ begin
+ nxt_rd_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ if (T2Write == 0)
+ begin
+ if (tstate[2] && write)
+ begin
+ nxt_wr_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ end
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && !wait_n)) && write)
+ begin
+ nxt_wr_n = 1'b0;
+ nxt_iorq_n = ~ iorq;
+ nxt_mreq_n = iorq;
+ end
+ end // else: !if(T2write == 0)
+ end // else: !if(mcycle[0])
+ end // always @ *
+
+ always @(negedge clk)
+ begin
+ if (!reset_n)
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ end
+ else
+ begin
+ rd_n <= #1 nxt_rd_n;
+ wr_n <= #1 nxt_wr_n;
+ iorq_n <= #1 nxt_iorq_n;
+ mreq_n <= #1 nxt_mreq_n;
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+ always @(posedge clk)
+ begin
+ if (!reset_n)
+ begin
+ di_reg <= #1 0;
+ end
+ else
+ begin
+ if (tstate[2] && wait_n == 1'b1)
+ di_reg <= #1 di;
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk)
+
+endmodule // t80n
+
diff --git a/tv80/tv80s.v b/tv80/tv80s.v
new file mode 100755
index 0000000..4e5df19
--- /dev/null
+++ b/tv80/tv80s.v
@@ -0,0 +1,162 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80s (/*AUTOARG*/
+ // Outputs
+ m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do,
+ // Inputs
+ reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
+ );
+
+ parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
+ parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
+
+
+ input reset_n;
+ input clk;
+ input wait_n;
+ input int_n;
+ input nmi_n;
+ input busrq_n;
+ output m1_n;
+ output mreq_n;
+ output iorq_n;
+ output rd_n;
+ output wr_n;
+ output rfsh_n;
+ output halt_n;
+ output busak_n;
+ output [15:0] A;
+ input [7:0] di;
+ output [7:0] do;
+
+ reg mreq_n;
+ reg iorq_n;
+ reg rd_n;
+ reg wr_n;
+
+ wire cen;
+ wire intcycle_n;
+ wire no_read;
+ wire write;
+ wire iorq;
+ reg [7:0] di_reg;
+ wire [6:0] mcycle;
+ wire [6:0] tstate;
+
+ assign cen = 1;
+
+ tv80_core #(Mode, IOWait) i_tv80_core
+ (
+ .cen (cen),
+ .m1_n (m1_n),
+ .iorq (iorq),
+ .no_read (no_read),
+ .write (write),
+ .rfsh_n (rfsh_n),
+ .halt_n (halt_n),
+ .wait_n (wait_n),
+ .int_n (int_n),
+ .nmi_n (nmi_n),
+ .reset_n (reset_n),
+ .busrq_n (busrq_n),
+ .busak_n (busak_n),
+ .clk (clk),
+ .IntE (),
+ .stop (),
+ .A (A),
+ .dinst (di),
+ .di (di_reg),
+ .do (do),
+ .mc (mcycle),
+ .ts (tstate),
+ .intcycle_n (intcycle_n)
+ );
+
+ always @(posedge clk)
+ begin
+ if (!reset_n)
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ di_reg <= #1 0;
+ end
+ else
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ if (mcycle[0])
+ begin
+ if (tstate[1] || (tstate[2] && wait_n == 1'b0))
+ begin
+ rd_n <= #1 ~ intcycle_n;
+ mreq_n <= #1 ~ intcycle_n;
+ iorq_n <= #1 intcycle_n;
+ end
+ `ifdef TV80_REFRESH
+ if (tstate[3])
+ mreq_n <= #1 1'b0;
+ `endif
+ end // if (mcycle[0])
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0)
+ begin
+ rd_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ if (T2Write == 0)
+ begin
+ if (tstate[2] && write == 1'b1)
+ begin
+ wr_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ end
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1)
+ begin
+ wr_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ end // else: !if(T2write == 0)
+
+ end // else: !if(mcycle[0])
+
+ if (tstate[2] && wait_n == 1'b1)
+ di_reg <= #1 di;
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+endmodule // t80s
+
diff --git a/tv80/tv80se.v b/tv80/tv80se.v
new file mode 100755
index 0000000..d9530ff
--- /dev/null
+++ b/tv80/tv80se.v
@@ -0,0 +1,163 @@
+//
+// TV80 8-Bit Microprocessor Core
+// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
+//
+// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module tv80se (/*AUTOARG*/
+ // Outputs
+ m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, reti_n, A, do,
+ // Inputs
+ reset_n, clk, cen, wait_n, int_n, nmi_n, busrq_n, di
+ );
+
+ parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
+ parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
+
+
+ input reset_n;
+ input clk;
+ input cen;
+ input wait_n;
+ input int_n;
+ input nmi_n;
+ input busrq_n;
+ output m1_n;
+ output mreq_n;
+ output iorq_n;
+ output rd_n;
+ output wr_n;
+ output rfsh_n;
+ output halt_n;
+ output busak_n;
+ output reti_n;
+ output [15:0] A;
+ input [7:0] di;
+ output [7:0] do;
+
+ reg mreq_n;
+ reg iorq_n;
+ reg rd_n;
+ reg wr_n;
+
+ wire cen;
+ wire intcycle_n;
+ wire no_read;
+ wire write;
+ wire iorq;
+ reg [7:0] di_reg;
+ wire [6:0] mcycle;
+ wire [6:0] tstate;
+
+ tv80_core #(Mode, IOWait) i_tv80_core
+ (
+ .cen (cen),
+ .m1_n (m1_n),
+ .iorq (iorq),
+ .no_read (no_read),
+ .write (write),
+ .rfsh_n (rfsh_n),
+ .halt_n (halt_n),
+ .wait_n (wait_n),
+ .int_n (int_n),
+ .nmi_n (nmi_n),
+ .reset_n (reset_n),
+ .busrq_n (busrq_n),
+ .busak_n (busak_n),
+ .reti_n (reti_n),
+ .clk (clk),
+ .IntE (),
+ .stop (),
+ .A (A),
+ .dinst (di),
+ .di (di_reg),
+ .do (do),
+ .mc (mcycle),
+ .ts (tstate),
+ .intcycle_n (intcycle_n)
+ );
+
+ always @(posedge clk)
+ begin
+ if (!reset_n)
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ di_reg <= #1 0;
+ end
+ else if (cen)
+ begin
+ rd_n <= #1 1'b1;
+ wr_n <= #1 1'b1;
+ iorq_n <= #1 1'b1;
+ mreq_n <= #1 1'b1;
+ if (mcycle[0])
+ begin
+ if (tstate[1] || (tstate[2] && wait_n == 1'b0))
+ begin
+ rd_n <= #1 ~ intcycle_n;
+ mreq_n <= #1 ~ intcycle_n;
+ iorq_n <= #1 intcycle_n;
+ end
+ `ifdef TV80_REFRESH
+ if (tstate[3])
+ mreq_n <= #1 1'b0;
+ `endif
+ end // if (mcycle[0])
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0)
+ begin
+ rd_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ if (T2Write == 0)
+ begin
+ if (tstate[2] && write == 1'b1)
+ begin
+ wr_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ end
+ else
+ begin
+ if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1)
+ begin
+ wr_n <= #1 1'b0;
+ iorq_n <= #1 ~ iorq;
+ mreq_n <= #1 iorq;
+ end
+ end // else: !if(T2write == 0)
+
+ end // else: !if(mcycle[0])
+
+ if (tstate[2] && wait_n == 1'b1)
+ di_reg <= #1 di;
+ end // else if (clken)
+ end // always @ (posedge clk or negedge reset_n)
+
+endmodule // t80s
+