mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-26 03:51:07 +00:00
T80: update to latest
This commit is contained in:
202
common/CPU/T80/GBse.vhd
Normal file
202
common/CPU/T80/GBse.vhd
Normal file
@@ -0,0 +1,202 @@
|
||||
-- ****
|
||||
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||
--
|
||||
--
|
||||
-- Ver 300 started tidyup
|
||||
-- MikeJ March 2005
|
||||
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||
--
|
||||
-- ****
|
||||
--
|
||||
-- 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 : 0240
|
||||
--
|
||||
-- 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 GBse is
|
||||
generic(
|
||||
T2Write : integer := 1; -- 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;
|
||||
STOP : 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 GBse;
|
||||
|
||||
architecture rtl of GBse 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 => 3,
|
||||
IOWait => IOWait,
|
||||
Flag_S => 0,
|
||||
Flag_P => 0,
|
||||
Flag_X => 0,
|
||||
Flag_Y => 0,
|
||||
Flag_C => 4,
|
||||
Flag_H => 5,
|
||||
Flag_N => 6,
|
||||
Flag_Z => 7
|
||||
)
|
||||
port map(
|
||||
CEN => CLKEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
RFSH_n => RFSH_n,
|
||||
HALT_n => HALT_n,
|
||||
Stop => STOP,
|
||||
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_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;
|
||||
@@ -2,6 +2,11 @@
|
||||
-- ****
|
||||
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||
-- accurate timings.
|
||||
--
|
||||
-- Version 351.
|
||||
-- Merged Gameboy fixes from Bruno Duarte Gouveia (brNX)
|
||||
-- Passes Blargg's test ROMs
|
||||
--
|
||||
-- Version 350.
|
||||
-- Copyright (c) 2018 Sorgelig
|
||||
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||
@@ -21,7 +26,7 @@
|
||||
-- ****
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
-- Version : 0250
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
-- All rights reserved
|
||||
--
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) GBse.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80pa.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80se.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80a.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80as.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80sed.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T8080se.vhd ]
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-- ****
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0247
|
||||
-- Version : 0250
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
-- All rights reserved
|
||||
--
|
||||
@@ -73,6 +73,7 @@
|
||||
-- 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
|
||||
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
@@ -118,6 +119,7 @@ entity T80 is
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic;
|
||||
R800_mode : in std_logic := '0';
|
||||
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
|
||||
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||
|
||||
@@ -151,9 +153,13 @@ architecture rtl of T80 is
|
||||
|
||||
-- Help Registers
|
||||
signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register
|
||||
signal TmpAddr2 : 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 MULU_Prod32 : std_logic_vector(31 downto 0);
|
||||
signal MULU_tmp : std_logic_vector(31 downto 0);
|
||||
signal MULU_Fakt1 : std_logic_vector(15 downto 0);
|
||||
|
||||
signal ID16 : signed(15 downto 0);
|
||||
signal Save_Mux : std_logic_vector(7 downto 0);
|
||||
@@ -212,6 +218,7 @@ architecture rtl of T80 is
|
||||
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 Rot_Akku : std_logic;
|
||||
signal PreserveC : std_logic;
|
||||
signal Arith16 : std_logic;
|
||||
signal Set_Addr_To : std_logic_vector(2 downto 0);
|
||||
@@ -223,6 +230,8 @@ architecture rtl of T80 is
|
||||
signal LDZ : std_logic;
|
||||
signal LDW : std_logic;
|
||||
signal LDSPHL : std_logic;
|
||||
signal LDHLSP : std_logic;
|
||||
signal ADDSPdd : std_logic;
|
||||
signal IORQ_i : std_logic;
|
||||
signal Special_LD : std_logic_vector(2 downto 0);
|
||||
signal ExchangeDH : std_logic;
|
||||
@@ -241,6 +250,8 @@ architecture rtl of T80 is
|
||||
signal I_RRD : std_logic;
|
||||
signal I_RXDD : std_logic;
|
||||
signal I_INRC : std_logic;
|
||||
signal I_MULUB : std_logic;
|
||||
signal I_MULU : std_logic;
|
||||
signal SetWZ : std_logic_vector(1 downto 0);
|
||||
signal SetDI : std_logic;
|
||||
signal SetEI : std_logic;
|
||||
@@ -249,6 +260,11 @@ architecture rtl of T80 is
|
||||
signal XYbit_undoc : std_logic;
|
||||
signal DOR : std_logic_vector(127 downto 0);
|
||||
|
||||
signal ABus : std_logic_vector(15 downto 0);
|
||||
signal ABus_last : std_logic_vector(15 downto 0);
|
||||
signal NoRead_int : std_logic;
|
||||
signal Write_int : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
REG <= IntE_FF2 & IntE_FF1 & IStatus & DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0'
|
||||
@@ -286,6 +302,7 @@ begin
|
||||
Set_BusA_To => Set_BusA_To,
|
||||
ALU_Op => ALU_Op,
|
||||
Save_ALU => Save_ALU,
|
||||
Rot_Akku => Rot_Akku,
|
||||
PreserveC => PreserveC,
|
||||
Arith16 => Arith16,
|
||||
Set_Addr_To => Set_Addr_To,
|
||||
@@ -298,6 +315,8 @@ begin
|
||||
LDZ => LDZ,
|
||||
LDW => LDW,
|
||||
LDSPHL => LDSPHL,
|
||||
LDHLSP => LDHLSP,
|
||||
ADDSPdd => ADDSPdd,
|
||||
Special_LD => Special_LD,
|
||||
ExchangeDH => ExchangeDH,
|
||||
ExchangeRp => ExchangeRp,
|
||||
@@ -314,14 +333,17 @@ begin
|
||||
I_RLD => I_RLD,
|
||||
I_RRD => I_RRD,
|
||||
I_INRC => I_INRC,
|
||||
I_MULUB => I_MULUB,
|
||||
I_MULU => I_MULU,
|
||||
SetWZ => SetWZ,
|
||||
SetDI => SetDI,
|
||||
SetEI => SetEI,
|
||||
IMode => IMode,
|
||||
Halt => Halt,
|
||||
NoRead => NoRead,
|
||||
Write => Write,
|
||||
XYbit_undoc => XYbit_undoc);
|
||||
NoRead => NoRead_int,
|
||||
Write => Write_int,
|
||||
XYbit_undoc => XYbit_undoc,
|
||||
R800_mode => R800_mode);
|
||||
|
||||
alu : T80_ALU
|
||||
generic map(
|
||||
@@ -340,6 +362,7 @@ begin
|
||||
WZ => WZ,
|
||||
XY_State=> XY_State,
|
||||
ALU_Op => ALU_Op_r,
|
||||
Rot_Akku => Rot_Akku,
|
||||
IR => IR(5 downto 0),
|
||||
ISet => ISet,
|
||||
BusA => BusA,
|
||||
@@ -364,10 +387,12 @@ begin
|
||||
process (RESET_n, CLK_n)
|
||||
variable n : std_logic_vector(7 downto 0);
|
||||
variable ioq : std_logic_vector(8 downto 0);
|
||||
variable temp_c : unsigned(8 downto 0);
|
||||
variable temp_h : unsigned(4 downto 0);
|
||||
begin
|
||||
if RESET_n = '0' then
|
||||
PC <= (others => '0'); -- Program Counter
|
||||
A <= (others => '0');
|
||||
ABus <= (others => '0');
|
||||
WZ <= (others => '0');
|
||||
IR <= "00000000";
|
||||
ISet <= "00";
|
||||
@@ -378,6 +403,11 @@ begin
|
||||
|
||||
ACC <= (others => '1');
|
||||
F <= (others => '1');
|
||||
if Mode = 3 then
|
||||
ACC <= (others => '0');
|
||||
F <= "11110000";
|
||||
end if;
|
||||
|
||||
Ap <= (others => '1');
|
||||
Fp <= (others => '1');
|
||||
I <= (others => '0');
|
||||
@@ -406,7 +436,7 @@ begin
|
||||
R <= unsigned(DIR(47 downto 40));
|
||||
SP <= unsigned(DIR(63 downto 48));
|
||||
PC <= unsigned(DIR(79 downto 64));
|
||||
A <= DIR(79 downto 64);
|
||||
ABus <= DIR(79 downto 64);
|
||||
IStatus <= DIR(209 downto 208);
|
||||
|
||||
elsif ClkEn = '1' then
|
||||
@@ -416,7 +446,27 @@ begin
|
||||
|
||||
MCycles <= MCycles_d;
|
||||
|
||||
if IMode /= "11" then
|
||||
if LDHLSP = '1' and MCycle = "011" and TState = 1 then
|
||||
temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux);
|
||||
temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0));
|
||||
F(Flag_Z) <= '0';
|
||||
F(Flag_N) <= '0';
|
||||
F(Flag_H) <= temp_h(4);
|
||||
F(Flag_C) <= temp_c(8);
|
||||
end if;
|
||||
|
||||
if ADDSPdd = '1' and TState = 1 then
|
||||
temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux);
|
||||
temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0));
|
||||
F(Flag_Z) <= '0';
|
||||
F(Flag_N) <= '0';
|
||||
F(Flag_H) <= temp_h(4);
|
||||
F(Flag_C) <= temp_c(8);
|
||||
end if;
|
||||
|
||||
if Mode = 3 then
|
||||
IStatus <= "10";
|
||||
elsif IMode /= "11" then
|
||||
IStatus <= IMode;
|
||||
end if;
|
||||
|
||||
@@ -433,8 +483,8 @@ begin
|
||||
|
||||
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;
|
||||
ABus(7 downto 0) <= std_logic_vector(R);
|
||||
ABus(15 downto 8) <= I;
|
||||
R(6 downto 0) <= R(6 downto 0) + 1;
|
||||
end if;
|
||||
|
||||
@@ -484,57 +534,57 @@ begin
|
||||
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) <= WZ(7 downto 0);
|
||||
ABus(15 downto 8) <= DI_Reg;
|
||||
ABus(7 downto 0) <= WZ(7 downto 0);
|
||||
PC(15 downto 8) <= unsigned(DI_Reg);
|
||||
PC(7 downto 0) <= unsigned(WZ(7 downto 0));
|
||||
elsif JumpXY = '1' then
|
||||
A <= RegBusC;
|
||||
ABus <= RegBusC;
|
||||
PC <= unsigned(RegBusC);
|
||||
elsif Call = '1' or RstP = '1' then
|
||||
A <= WZ;
|
||||
ABus <= WZ;
|
||||
PC <= unsigned(WZ);
|
||||
elsif MCycle = MCycles and NMICycle = '1' then
|
||||
A <= "0000000001100110";
|
||||
ABus <= "0000000001100110";
|
||||
PC <= "0000000001100110";
|
||||
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
|
||||
A(15 downto 8) <= I;
|
||||
A(7 downto 0) <= WZ(7 downto 0);
|
||||
ABus(15 downto 8) <= I;
|
||||
ABus(7 downto 0) <= WZ(7 downto 0);
|
||||
PC(15 downto 8) <= unsigned(I);
|
||||
PC(7 downto 0) <= unsigned(WZ(7 downto 0));
|
||||
else
|
||||
case Set_Addr_To is
|
||||
when aXY =>
|
||||
if XY_State = "00" then
|
||||
A <= RegBusC;
|
||||
ABus <= RegBusC;
|
||||
else
|
||||
if NextIs_XY_Fetch = '1' then
|
||||
A <= std_logic_vector(PC);
|
||||
ABus <= std_logic_vector(PC);
|
||||
else
|
||||
A <= WZ;
|
||||
ABus <= WZ;
|
||||
end if;
|
||||
end if;
|
||||
when aIOA =>
|
||||
if Mode = 3 then
|
||||
-- Memory map I/O on GBZ80
|
||||
A(15 downto 8) <= (others => '1');
|
||||
ABus(15 downto 8) <= (others => '1');
|
||||
elsif Mode = 2 then
|
||||
-- Duplicate I/O address on 8080
|
||||
A(15 downto 8) <= DI_Reg;
|
||||
ABus(15 downto 8) <= DI_Reg;
|
||||
else
|
||||
A(15 downto 8) <= ACC;
|
||||
ABus(15 downto 8) <= ACC;
|
||||
end if;
|
||||
A(7 downto 0) <= DI_Reg;
|
||||
ABus(7 downto 0) <= DI_Reg;
|
||||
WZ <= (ACC & DI_Reg) + "1";
|
||||
when aSP =>
|
||||
A <= std_logic_vector(SP);
|
||||
ABus <= 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);
|
||||
ABus(15 downto 8) <= (others => '1');
|
||||
ABus(7 downto 0) <= RegBusC(7 downto 0);
|
||||
else
|
||||
A <= RegBusC;
|
||||
ABus <= RegBusC;
|
||||
if SetWZ = "01" then
|
||||
WZ <= RegBusC + "1";
|
||||
end if;
|
||||
@@ -544,24 +594,24 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
when aDE =>
|
||||
A <= RegBusC;
|
||||
ABus <= RegBusC;
|
||||
if SetWZ = "10" then
|
||||
WZ(7 downto 0) <= RegBusC(7 downto 0) + "1";
|
||||
WZ(15 downto 8) <= ACC;
|
||||
end if;
|
||||
when aZI =>
|
||||
if Inc_WZ = '1' then
|
||||
A <= std_logic_vector(unsigned(WZ) + 1);
|
||||
ABus <= std_logic_vector(unsigned(WZ) + 1);
|
||||
else
|
||||
A(15 downto 8) <= DI_Reg;
|
||||
A(7 downto 0) <= WZ(7 downto 0);
|
||||
ABus(15 downto 8) <= DI_Reg;
|
||||
ABus(7 downto 0) <= WZ(7 downto 0);
|
||||
if SetWZ = "10" then
|
||||
WZ(7 downto 0) <= WZ(7 downto 0) + "1";
|
||||
WZ(15 downto 8) <= ACC;
|
||||
end if;
|
||||
end if;
|
||||
when others =>
|
||||
A <= std_logic_vector(PC);
|
||||
ABus <= std_logic_vector(PC);
|
||||
end case;
|
||||
end if;
|
||||
|
||||
@@ -572,33 +622,54 @@ begin
|
||||
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';
|
||||
if Mode = 3 then
|
||||
if I_CPL = '1' then
|
||||
-- CPL
|
||||
ACC <= not ACC;
|
||||
F(Flag_H) <= '1';
|
||||
F(Flag_N) <= '1';
|
||||
end if;
|
||||
if I_CCF = '1' then
|
||||
-- CCF
|
||||
F(Flag_C) <= not F(Flag_C);
|
||||
F(Flag_H) <= '0';
|
||||
F(Flag_N) <= '0';
|
||||
end if;
|
||||
if I_SCF = '1' then
|
||||
-- SCF
|
||||
F(Flag_C) <= '1';
|
||||
F(Flag_H) <= '0';
|
||||
F(Flag_N) <= '0';
|
||||
end if;
|
||||
else
|
||||
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;
|
||||
end if;
|
||||
|
||||
if (TState = 2 and I_BTR = '1' and IR(0) = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then
|
||||
if (TState = 2 and I_BTR = '1' and IR(0) = '1' and Wait_n = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then
|
||||
ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0)));
|
||||
F(Flag_N) <= DI_Reg(7);
|
||||
F(Flag_C) <= ioq(8);
|
||||
@@ -645,6 +716,11 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if ADDSPdd = '1' and TState = 2 and Wait_n = '1' then
|
||||
WZ <= std_logic_vector(SP);
|
||||
SP <= unsigned(signed(SP)+signed(Save_Mux));
|
||||
end if;
|
||||
|
||||
if LDSPHL = '1' then
|
||||
SP <= unsigned(RegBusC);
|
||||
end if;
|
||||
@@ -792,7 +868,12 @@ begin
|
||||
when "11001" =>
|
||||
SP(15 downto 8) <= unsigned(Save_Mux);
|
||||
when "11011" =>
|
||||
F <= Save_Mux;
|
||||
if Mode = 3 then
|
||||
F(7 downto 4) <= Save_Mux(7 downto 4);
|
||||
F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0
|
||||
else
|
||||
F <= Save_Mux;
|
||||
end if;
|
||||
when others =>
|
||||
end case;
|
||||
if XYbit_undoc='1' then
|
||||
@@ -803,6 +884,42 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
--
|
||||
-- Multiply
|
||||
--
|
||||
---------------------------------------------------------------------------
|
||||
process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32)
|
||||
begin
|
||||
|
||||
MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16)));
|
||||
MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4);
|
||||
|
||||
if rising_edge(CLK_n) then
|
||||
if ClkEn = '1' then
|
||||
if T_Res='1' then
|
||||
if I_MULUB='1' then
|
||||
MULU_Prod32(7 downto 0) <= ACC;
|
||||
MULU_Prod32(15 downto 8) <= "--------";
|
||||
MULU_Prod32(31 downto 16) <= X"0000";
|
||||
MULU_Fakt1(7 downto 0) <= "00000000";
|
||||
if Set_BusB_To(0) = '1' then
|
||||
MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0);
|
||||
else
|
||||
MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8);
|
||||
end if;
|
||||
else
|
||||
MULU_Prod32(15 downto 0) <= RegBusA;
|
||||
MULU_Prod32(31 downto 16) <= X"0000";
|
||||
MULU_Fakt1 <= RegBusB;
|
||||
end if;
|
||||
else
|
||||
MULU_Prod32 <= MULU_tmp;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
--
|
||||
-- BC('), DE('), HL('), IX and IY
|
||||
@@ -837,7 +954,7 @@ begin
|
||||
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 ((TState = 2 and Wait_n = '1') or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
|
||||
if ID16 = 0 then
|
||||
IncDecZ <= '0';
|
||||
else
|
||||
@@ -858,7 +975,9 @@ begin
|
||||
(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
|
||||
Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else
|
||||
-- LDHLSP
|
||||
"010" when LDHLSP = '1' and TState = 4 else
|
||||
-- Bus A / Write
|
||||
RegAddrA_r;
|
||||
|
||||
@@ -871,8 +990,8 @@ begin
|
||||
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)
|
||||
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res,
|
||||
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP)
|
||||
begin
|
||||
RegWEH <= '0';
|
||||
RegWEL <= '0';
|
||||
@@ -886,11 +1005,21 @@ begin
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write
|
||||
RegWEH <= '1';
|
||||
RegWEL <= '1';
|
||||
end if;
|
||||
|
||||
if ExchangeDH = '1' and (TState = 3 or TState = 4) then
|
||||
RegWEH <= '1';
|
||||
RegWEL <= '1';
|
||||
end if;
|
||||
|
||||
if LDHLSP = '1' and MCycle = "010" and 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" =>
|
||||
@@ -901,12 +1030,29 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Save_Mux, RegBusB, RegBusA_r, ID16,
|
||||
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
|
||||
TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux)));
|
||||
|
||||
process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res,
|
||||
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2)
|
||||
begin
|
||||
RegDIH <= Save_Mux;
|
||||
RegDIL <= Save_Mux;
|
||||
|
||||
if I_MULU = '1' then
|
||||
if T_Res = '1' then
|
||||
RegDIH <= MULU_Prod32(31 downto 24);
|
||||
RegDIL <= MULU_Prod32(23 downto 16);
|
||||
else
|
||||
RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write
|
||||
RegDIL <= MULU_tmp(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if LDHLSP = '1' and MCycle = "010" and TState = 4 then
|
||||
RegDIH <= TmpAddr2(15 downto 8);
|
||||
RegDIL <= TmpAddr2(7 downto 0);
|
||||
end if;
|
||||
|
||||
if ExchangeDH = '1' and TState = 3 then
|
||||
RegDIH <= RegBusB(15 downto 8);
|
||||
RegDIL <= RegBusB(7 downto 0);
|
||||
@@ -916,7 +1062,7 @@ begin
|
||||
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
|
||||
if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001" and Wait_n = '1') 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;
|
||||
@@ -1029,6 +1175,9 @@ begin
|
||||
else
|
||||
RFSH_n <= '1';
|
||||
end if;
|
||||
if (TState = 1 and (NoRead_int = '0' and IORQ_i = '0')) or (TState = 3 and MCycle = "001") then
|
||||
ABus_last <= ABus;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -1042,6 +1191,10 @@ begin
|
||||
IntE <= IntE_FF1;
|
||||
IORQ <= IORQ_i;
|
||||
Stop <= I_DJNZ;
|
||||
NoRead <= NoRead_int;
|
||||
Write <= Write_int;
|
||||
A <= ABus when (Mode > 1) or (NoRead_int = '0' or Write_int = '1') else ABus_last;
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
--
|
||||
@@ -1090,7 +1243,7 @@ begin
|
||||
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)));
|
||||
if TState = 2 then
|
||||
if TState = 2 and Wait_n = '1' then
|
||||
if SetEI = '1' then
|
||||
IntE_FF1 <= '1';
|
||||
IntE_FF2 <= '1';
|
||||
@@ -1116,7 +1269,7 @@ begin
|
||||
BusAck <= '0';
|
||||
if TState = 2 and Wait_n = '0' then
|
||||
elsif T_Res = '1' then
|
||||
if Halt = '1' then
|
||||
if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0
|
||||
Halt_FF <= '1';
|
||||
end if;
|
||||
if BusReq_s = '1' then
|
||||
@@ -1144,6 +1297,8 @@ begin
|
||||
IntCycle <= '1';
|
||||
IntE_FF1 <= '0';
|
||||
IntE_FF2 <= '0';
|
||||
elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then
|
||||
Halt_FF <= '0';
|
||||
end if;
|
||||
else
|
||||
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
|
||||
|
||||
@@ -89,6 +89,7 @@ entity T80_ALU is
|
||||
WZ : in std_logic_vector(15 downto 0);
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
Rot_Akku : in std_logic;
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
@@ -158,7 +159,7 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, WZ, XY_State)
|
||||
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State)
|
||||
variable Q_t : std_logic_vector(7 downto 0);
|
||||
variable DAA_Q : unsigned(8 downto 0);
|
||||
begin
|
||||
@@ -220,35 +221,64 @@ begin
|
||||
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';
|
||||
if Mode = 3 then
|
||||
F_Out(Flag_H) <= '0';
|
||||
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
|
||||
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 F_In(Flag_H) = '1' then
|
||||
DAA_Q := DAA_Q - 6;
|
||||
if F_In(Flag_C) = '0' then
|
||||
DAA_Q(8) := '0';
|
||||
end if;
|
||||
end if;
|
||||
if F_In(Flag_C) = '1' then
|
||||
DAA_Q := DAA_Q - 96; -- 0x60
|
||||
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';
|
||||
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;
|
||||
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);
|
||||
@@ -368,6 +398,9 @@ begin
|
||||
F_Out(Flag_S) <= F_In(Flag_S);
|
||||
F_Out(Flag_Z) <= F_In(Flag_Z);
|
||||
end if;
|
||||
if Mode = 3 and Rot_Akku = '1' then
|
||||
F_Out(Flag_Z) <= '0';
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
-- ****
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
-- Version : 0250
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
-- All rights reserved
|
||||
--
|
||||
@@ -69,6 +69,7 @@
|
||||
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
|
||||
-- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR
|
||||
-- 0242 : Fixed I/O instruction timing, cleanup
|
||||
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
@@ -109,6 +110,7 @@ entity T80_MCode is
|
||||
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;
|
||||
Rot_Akku : 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
|
||||
@@ -121,6 +123,8 @@ entity T80_MCode is
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
LDHLSP : out std_logic;
|
||||
ADDSPdd : 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;
|
||||
@@ -137,6 +141,8 @@ entity T80_MCode is
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
I_MULUB : out std_logic;
|
||||
I_MULU : out std_logic;
|
||||
SetWZ : out std_logic_vector(1 downto 0);
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
@@ -144,7 +150,8 @@ entity T80_MCode is
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
XYbit_undoc : out std_logic;
|
||||
R800_mode : in std_logic
|
||||
);
|
||||
end T80_MCode;
|
||||
|
||||
@@ -157,10 +164,10 @@ architecture rtl of T80_MCode is
|
||||
begin
|
||||
if Mode = 3 then
|
||||
case cc is
|
||||
when "000" => return F(Flag_S) = '0'; -- NZ
|
||||
when "001" => return F(Flag_S) = '1'; -- Z
|
||||
when "010" => return F(Flag_H) = '0'; -- NC
|
||||
when "011" => return F(Flag_H) = '1'; -- C
|
||||
when "000" => return F(Flag_Z) = '0'; -- NZ
|
||||
when "001" => return F(Flag_Z) = '1'; -- Z
|
||||
when "010" => return F(Flag_C) = '0'; -- NC
|
||||
when "011" => return F(Flag_C) = '1'; -- C
|
||||
when "100" => return false;
|
||||
when "101" => return false;
|
||||
when "110" => return false;
|
||||
@@ -182,7 +189,7 @@ architecture rtl of T80_MCode is
|
||||
|
||||
begin
|
||||
|
||||
process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State)
|
||||
process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode)
|
||||
variable DDD : std_logic_vector(2 downto 0);
|
||||
variable SSS : std_logic_vector(2 downto 0);
|
||||
variable DPair : std_logic_vector(1 downto 0);
|
||||
@@ -209,6 +216,7 @@ begin
|
||||
Set_BusA_To <= "0000";
|
||||
ALU_Op <= "0" & IR(5 downto 3);
|
||||
Save_ALU <= '0';
|
||||
Rot_Akku <= '0';
|
||||
PreserveC <= '0';
|
||||
Arith16 <= '0';
|
||||
IORQ <= '0';
|
||||
@@ -221,6 +229,8 @@ begin
|
||||
LDZ <= '0';
|
||||
LDW <= '0';
|
||||
LDSPHL <= '0';
|
||||
LDHLSP <= '0';
|
||||
ADDSPdd <= '0';
|
||||
Special_LD <= "000";
|
||||
ExchangeDH <= '0';
|
||||
ExchangeRp <= '0';
|
||||
@@ -237,6 +247,8 @@ begin
|
||||
I_RLD <= '0';
|
||||
I_RRD <= '0';
|
||||
I_INRC <= '0';
|
||||
I_MULUB <= '0';
|
||||
I_MULU <= '0';
|
||||
SetDI <= '0';
|
||||
SetEI <= '0';
|
||||
IMode <= "11";
|
||||
@@ -513,38 +525,76 @@ begin
|
||||
end if;
|
||||
when "11111001" =>
|
||||
-- LD SP,HL
|
||||
TStates <= "110";
|
||||
LDSPHL <= '1';
|
||||
if Mode = 3 then
|
||||
MCycles <= "010";
|
||||
if MCycle = "010" then
|
||||
LDSPHL <= '1';
|
||||
end if;
|
||||
else
|
||||
TStates <= "110";
|
||||
LDSPHL <= '1';
|
||||
end if;
|
||||
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;
|
||||
if Mode = 3 then
|
||||
MCycles <= "100";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
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 3 =>
|
||||
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 4 =>
|
||||
Write <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
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;
|
||||
end if;
|
||||
when "11000001"|"11010001"|"11100001"|"11110001" =>
|
||||
-- POP qq
|
||||
MCycles <= "011";
|
||||
@@ -608,7 +658,7 @@ begin
|
||||
when "11011001" =>
|
||||
if Mode = 3 then
|
||||
-- RETI
|
||||
MCycles <= "011";
|
||||
MCycles <= "100";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
Set_Addr_TO <= aSP;
|
||||
@@ -619,7 +669,7 @@ begin
|
||||
when 3 =>
|
||||
Jump <= '1';
|
||||
IncDec_16 <= "0111";
|
||||
I_RETN <= '1';
|
||||
--I_RETN <= '1';
|
||||
SetEI <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
@@ -809,30 +859,50 @@ begin
|
||||
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;
|
||||
if mode = 3 then
|
||||
MCycles <= "100";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
LDZ <= '1';
|
||||
TStates <= "110";
|
||||
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';
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
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;
|
||||
end if;
|
||||
else
|
||||
-- NOP
|
||||
end if;
|
||||
@@ -849,49 +919,105 @@ begin
|
||||
-- 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';
|
||||
if Mode = 3 then
|
||||
MCycles <= "010";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
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';
|
||||
SetWZ <= "11";
|
||||
when 2 =>
|
||||
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 =>
|
||||
Set_BusB_To <= "1000";
|
||||
end case;
|
||||
TStates <= "100";
|
||||
Arith16 <= '1';
|
||||
SetWZ <= "11";
|
||||
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);
|
||||
else
|
||||
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';
|
||||
SetWZ <= "11";
|
||||
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 =>
|
||||
Set_BusB_To <= "1001";
|
||||
end case;
|
||||
Arith16 <= '1';
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
when "00000011"|"00010011"|"00100011"|"00110011" =>
|
||||
-- INC ss
|
||||
TStates <= "110";
|
||||
IncDec_16(3 downto 2) <= "01";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
if Mode = 3 then
|
||||
MCycles <= "010";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
IncDec_16(3 downto 2) <= "01";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
when others =>
|
||||
end case;
|
||||
else
|
||||
TStates <= "110";
|
||||
IncDec_16(3 downto 2) <= "01";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
end if;
|
||||
when "00001011"|"00011011"|"00101011"|"00111011" =>
|
||||
-- DEC ss
|
||||
TStates <= "110";
|
||||
IncDec_16(3 downto 2) <= "11";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
if Mode = 3 then
|
||||
MCycles <= "010";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
IncDec_16(3 downto 2) <= "11";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
when others =>
|
||||
end case;
|
||||
else
|
||||
TStates <= "110";
|
||||
IncDec_16(3 downto 2) <= "11";
|
||||
IncDec_16(1 downto 0) <= DPair;
|
||||
end if;
|
||||
|
||||
-- ROTATE AND SHIFT GROUP
|
||||
when "00000111"
|
||||
@@ -905,12 +1031,17 @@ begin
|
||||
Set_BusA_To(2 downto 0) <= "111";
|
||||
ALU_Op <= "1000";
|
||||
Read_To_Reg <= '1';
|
||||
Rot_Akku <= '1';
|
||||
Save_ALU <= '1';
|
||||
|
||||
-- JUMP GROUP
|
||||
when "11000011" =>
|
||||
-- JP nn
|
||||
MCycles <= "011";
|
||||
if Mode = 3 then
|
||||
MCycles <= "100";
|
||||
else
|
||||
MCycles <= "011";
|
||||
end if;
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Inc_PC <= '1';
|
||||
@@ -918,7 +1049,9 @@ begin
|
||||
when 3 =>
|
||||
Inc_PC <= '1';
|
||||
Jump <= '1';
|
||||
LDW <= '1';
|
||||
if Mode /= 3 then
|
||||
LDW <= '1';
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
|
||||
@@ -931,9 +1064,9 @@ begin
|
||||
when 1 =>
|
||||
Set_Addr_To <= aBC;
|
||||
Set_BusB_To <= "0111";
|
||||
IORQ <= '1'; --TH must be earlier to be stable when address is generated
|
||||
when 2 =>
|
||||
Write <= '1';
|
||||
IORQ <= '1';
|
||||
when others =>
|
||||
end case;
|
||||
when "01" =>
|
||||
@@ -957,9 +1090,9 @@ begin
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
Set_Addr_To <= aBC;
|
||||
IORQ <= '1'; --TH must be earlier to be stable when address is generated
|
||||
when 2 =>
|
||||
Read_To_Acc <= '1';
|
||||
IORQ <= '1';
|
||||
when others =>
|
||||
end case;
|
||||
when "11" =>
|
||||
@@ -979,16 +1112,24 @@ begin
|
||||
end case;
|
||||
else
|
||||
-- JP cc,nn
|
||||
MCycles <= "011";
|
||||
if Mode = 3 then
|
||||
MCycles <= "100";
|
||||
else
|
||||
MCycles <= "011";
|
||||
end if;
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Inc_PC <= '1';
|
||||
LDZ <= '1';
|
||||
when 3 =>
|
||||
LDW <= '1';
|
||||
if Mode /= 3 then
|
||||
LDW <= '1';
|
||||
end if;
|
||||
Inc_PC <= '1';
|
||||
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
||||
Jump <= '1';
|
||||
elsif Mode = 3 then
|
||||
MCycles <= "011";
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
@@ -1078,9 +1219,15 @@ begin
|
||||
when "11101001" =>
|
||||
-- JP (HL)
|
||||
JumpXY <= '1';
|
||||
when "00010000" =>
|
||||
if Mode = 3 then
|
||||
when "00010000" =>
|
||||
if Mode = 3 then -- STOP and skip next byte
|
||||
MCycles <= "010";
|
||||
I_DJNZ <= '1';
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Inc_PC <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
elsif Mode < 2 then
|
||||
-- DJNZ,e
|
||||
MCycles <= "011";
|
||||
@@ -1107,7 +1254,11 @@ begin
|
||||
-- CALL AND RETURN GROUP
|
||||
when "11001101" =>
|
||||
-- CALL nn
|
||||
MCycles <= "101";
|
||||
if Mode = 3 then
|
||||
MCycles <= "110";
|
||||
else
|
||||
MCycles <= "101";
|
||||
end if;
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Inc_PC <= '1';
|
||||
@@ -1132,7 +1283,11 @@ begin
|
||||
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
|
||||
if IR(5) = '0' or Mode /= 3 then
|
||||
-- CALL cc,nn
|
||||
MCycles <= "101";
|
||||
if Mode = 3 then
|
||||
MCycles <= "110";
|
||||
else
|
||||
MCycles <= "101";
|
||||
end if;
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Inc_PC <= '1';
|
||||
@@ -1161,20 +1316,36 @@ begin
|
||||
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;
|
||||
if Mode = 3 then
|
||||
MCycles <= "100";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
Set_Addr_TO <= aSP;
|
||||
when 3 =>
|
||||
IncDec_16 <= "0111";
|
||||
Set_Addr_To <= aSP;
|
||||
LDZ <= '1';
|
||||
when 4 =>
|
||||
Jump <= '1';
|
||||
IncDec_16 <= "0111";
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
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;
|
||||
end if;
|
||||
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
|
||||
if IR(5) = '1' and Mode = 3 then
|
||||
case IRB(4 downto 3) is
|
||||
@@ -1192,22 +1363,11 @@ begin
|
||||
end case;
|
||||
when "01" =>
|
||||
-- ADD SP,n
|
||||
MCycles <= "011";
|
||||
MCycles <= "100";
|
||||
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 !!!!!!!!!!!!!!!!!!!!!
|
||||
Inc_PC <= '1';
|
||||
ADDSPdd <= '1';
|
||||
when others =>
|
||||
end case;
|
||||
when "10" =>
|
||||
@@ -1222,67 +1382,100 @@ begin
|
||||
when others => null;
|
||||
end case;
|
||||
when "11" =>
|
||||
-- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
|
||||
MCycles <= "101";
|
||||
-- LD HL,SP+n
|
||||
MCycles <= "011";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
Inc_PC <= '1';
|
||||
when 2 =>
|
||||
LDHLSP <= '1';
|
||||
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';
|
||||
LDHLSP <= '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;
|
||||
if Mode = 3 then
|
||||
MCycles <= "101";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
||||
Set_Addr_TO <= aSP;
|
||||
else
|
||||
MCycles <= "010";
|
||||
end if;
|
||||
TStates <= "101";
|
||||
when 3 =>
|
||||
IncDec_16 <= "0111";
|
||||
Set_Addr_To <= aSP;
|
||||
LDZ <= '1';
|
||||
when 4 =>
|
||||
Jump <= '1';
|
||||
IncDec_16 <= "0111";
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
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;
|
||||
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;
|
||||
if Mode = 3 then
|
||||
MCycles <= "100";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 2 =>
|
||||
TStates <= "101";
|
||||
IncDec_16 <= "1111";
|
||||
Set_Addr_To <= aSP;
|
||||
Set_BusB_To <= "1101";
|
||||
when 3 =>
|
||||
Write <= '1';
|
||||
IncDec_16 <= "1111";
|
||||
Set_Addr_To <= aSP;
|
||||
Set_BusB_To <= "1100";
|
||||
when 4 =>
|
||||
Write <= '1';
|
||||
RstP <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
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;
|
||||
end if;
|
||||
|
||||
-- INPUT AND OUTPUT GROUP
|
||||
when "11011011" =>
|
||||
@@ -1582,16 +1775,16 @@ begin
|
||||
| "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"
|
||||
|"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111"
|
||||
|"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|
||||
|"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|
||||
|"11011000"| "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"
|
||||
|"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111"
|
||||
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
|
||||
null; -- NOP, undocumented
|
||||
when "01111110"|"01111111" =>
|
||||
when "01110111"|"01111111" =>
|
||||
-- NOP, undocumented
|
||||
null;
|
||||
-- 8 BIT LOAD GROUP
|
||||
@@ -1747,7 +1940,7 @@ begin
|
||||
when "01010110"|"01110110" =>
|
||||
-- IM 1
|
||||
IMode <= "01";
|
||||
when "01011110"|"01110111" =>
|
||||
when "01011110"|"01111110" =>
|
||||
-- IM 2
|
||||
IMode <= "10";
|
||||
-- 16 bit arithmetic
|
||||
@@ -1972,6 +2165,46 @@ begin
|
||||
TStates <= "101";
|
||||
when others => null;
|
||||
end case;
|
||||
when "11000001"|"11001001"|"11010001"|"11011001" =>
|
||||
--R800 MULUB
|
||||
if R800_mode = '1' then
|
||||
MCycles <= "010";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
NoRead <= '1';
|
||||
I_MULUB <= '1';
|
||||
Set_BusB_To(2 downto 0) <= IR(5 downto 3);
|
||||
Set_BusB_To(3) <= '0';
|
||||
when 2 =>
|
||||
NoRead <= '1';
|
||||
I_MULU <= '1';
|
||||
Set_BusA_To(2 downto 0) <= "100";
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
when "11000011"|"11110011" =>
|
||||
--R800 MULUW
|
||||
if R800_mode = '1' then
|
||||
MCycles <= "010";
|
||||
case to_integer(unsigned(MCycle)) is
|
||||
when 1 =>
|
||||
NoRead <= '1';
|
||||
if DPAIR = "11" then
|
||||
Set_BusB_To(3 downto 0) <= "1000";
|
||||
else
|
||||
Set_BusB_To(2 downto 1) <= DPAIR;
|
||||
Set_BusB_To(0) <= '0';
|
||||
Set_BusB_To(3) <= '0';
|
||||
end if;
|
||||
Set_BusA_To(2 downto 0) <= "100";
|
||||
when 2 =>
|
||||
TStates <= "101";
|
||||
NoRead <= '1';
|
||||
I_MULU <= '1';
|
||||
Set_BusA_To(2 downto 0) <= "100";
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end case;
|
||||
|
||||
end case;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
--
|
||||
-- Z80 compatible microprocessor core
|
||||
--
|
||||
-- Version : 0242
|
||||
-- Version : 0250
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
@@ -105,6 +105,7 @@ package T80_Pack is
|
||||
IntCycle_n : out std_logic;
|
||||
IntE : out std_logic;
|
||||
Stop : out std_logic;
|
||||
R800_mode : in std_logic := '0';
|
||||
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
|
||||
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||
DIRSet : in std_logic := '0';
|
||||
@@ -168,6 +169,7 @@ package T80_Pack is
|
||||
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;
|
||||
Rot_Akku : 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
|
||||
@@ -180,6 +182,8 @@ package T80_Pack is
|
||||
LDZ : out std_logic;
|
||||
LDW : out std_logic;
|
||||
LDSPHL : out std_logic;
|
||||
LDHLSP : out std_logic;
|
||||
ADDSPdd : 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;
|
||||
@@ -196,6 +200,8 @@ package T80_Pack is
|
||||
I_RLD : out std_logic;
|
||||
I_RRD : out std_logic;
|
||||
I_INRC : out std_logic;
|
||||
I_MULUB : out std_logic;
|
||||
I_MULU : out std_logic;
|
||||
SetWZ : out std_logic_vector(1 downto 0);
|
||||
SetDI : out std_logic;
|
||||
SetEI : out std_logic;
|
||||
@@ -203,7 +209,8 @@ package T80_Pack is
|
||||
Halt : out std_logic;
|
||||
NoRead : out std_logic;
|
||||
Write : out std_logic;
|
||||
XYbit_undoc : out std_logic
|
||||
XYbit_undoc : out std_logic;
|
||||
R800_mode : in std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
@@ -225,6 +232,7 @@ package T80_Pack is
|
||||
WZ : in std_logic_vector(15 downto 0);
|
||||
XY_State : in std_logic_vector(1 downto 0);
|
||||
ALU_Op : in std_logic_vector(3 downto 0);
|
||||
Rot_Akku : in std_logic;
|
||||
IR : in std_logic_vector(5 downto 0);
|
||||
ISet : in std_logic_vector(1 downto 0);
|
||||
BusA : in std_logic_vector(7 downto 0);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
--
|
||||
-- Z80 compatible microprocessor core, asynchronous top level
|
||||
--
|
||||
-- Version : 0247
|
||||
-- Version : 0250
|
||||
--
|
||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||
--
|
||||
@@ -67,6 +67,11 @@
|
||||
--
|
||||
-- 0247 : Fixed bus req/ack cycle
|
||||
--
|
||||
-- 0247a: 7th of September, 2003 by Kazuhiro Tsujikawa (tujikawa@hat.hi-ho.ne.jp)
|
||||
-- Fixed IORQ_n, RD_n, WR_n bus timing
|
||||
--
|
||||
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
|
||||
--
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
@@ -75,10 +80,12 @@ use work.T80_Pack.all;
|
||||
|
||||
entity T80a is
|
||||
generic(
|
||||
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
IOWait : integer := 1 -- 0 => Single I/O cycle, 1 => Std I/O cycle
|
||||
);
|
||||
port(
|
||||
RESET_n : in std_logic;
|
||||
R800_mode : in std_logic;
|
||||
CLK_n : in std_logic;
|
||||
WAIT_n : in std_logic;
|
||||
INT_n : in std_logic;
|
||||
@@ -92,8 +99,8 @@ entity T80a is
|
||||
RFSH_n : out std_logic;
|
||||
HALT_n : out std_logic;
|
||||
BUSAK_n : out std_logic;
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
D : inout std_logic_vector(7 downto 0)
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
D : inout std_logic_vector(7 downto 0)
|
||||
);
|
||||
end T80a;
|
||||
|
||||
@@ -107,12 +114,14 @@ architecture rtl of T80a is
|
||||
signal Write : std_logic;
|
||||
signal MREQ : std_logic;
|
||||
signal MReq_Inhibit : std_logic;
|
||||
signal IReq_Inhibit : std_logic; -- 0247a
|
||||
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 WR_n_j : std_logic; -- 0247a
|
||||
signal RFSH_n_i : std_logic;
|
||||
signal BUSAK_n_i : std_logic;
|
||||
signal A_i : std_logic_vector(15 downto 0);
|
||||
@@ -129,11 +138,12 @@ begin
|
||||
BUSAK_n <= BUSAK_n_i;
|
||||
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
|
||||
RD_n_i <= not RD or Req_Inhibit;
|
||||
WR_n_j <= WR_n_i; -- 0247a
|
||||
|
||||
MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
|
||||
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
|
||||
IORQ_n <= IORQ_n_i or IReq_Inhibit when BUSAK_n_i = '1' else 'Z'; -- 0247a
|
||||
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
|
||||
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
|
||||
WR_n <= WR_n_j when BUSAK_n_i = '1' else 'Z'; -- 0247a
|
||||
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');
|
||||
@@ -150,8 +160,9 @@ begin
|
||||
u0 : T80
|
||||
generic map(
|
||||
Mode => Mode,
|
||||
IOWait => 1)
|
||||
IOWait => IOWait)
|
||||
port map(
|
||||
R800_mode => R800_mode,
|
||||
CEN => CEN,
|
||||
M1_n => M1_n,
|
||||
IORQ => IORQ,
|
||||
@@ -184,24 +195,40 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
process (CLK_n) -- 0247a
|
||||
begin
|
||||
if CLK_n'event and CLK_n = '1' then
|
||||
IReq_Inhibit <= not IORQ;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n) -- 0247a
|
||||
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;
|
||||
elsif CLK_n'event and CLK_n = '0' then
|
||||
if (IORQ = '0') then
|
||||
if TState = "010" then
|
||||
WR_n_i <= not Write;
|
||||
elsif Tstate = "011" then
|
||||
WR_n_i <= '1';
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and IORQ_n_i = '0' then
|
||||
WR_n_i <= not Write;
|
||||
elsif Tstate = "011" then
|
||||
WR_n_i <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (Reset_s,CLK_n)
|
||||
process (Reset_s,CLK_n) -- 0247a
|
||||
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
|
||||
if MCycle = "001" and TState = "010" and wait_s = '1' then
|
||||
Req_Inhibit <= '1';
|
||||
else
|
||||
Req_Inhibit <= '0';
|
||||
@@ -246,9 +273,13 @@ begin
|
||||
end if;
|
||||
else
|
||||
if TState = "001" and NoRead = '0' then
|
||||
RD <= not Write;
|
||||
IORQ_n_i <= not IORQ;
|
||||
MREQ <= not IORQ;
|
||||
if IORQ = '0' then
|
||||
RD <= not Write;
|
||||
elsif IORQ_n_i = '0' then
|
||||
RD <= not Write;
|
||||
end if;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
RD <= '0';
|
||||
|
||||
@@ -83,6 +83,7 @@ entity T80pa is
|
||||
A : out std_logic_vector(15 downto 0);
|
||||
DI : in std_logic_vector(7 downto 0);
|
||||
DO : out std_logic_vector(7 downto 0);
|
||||
R800_mode : in std_logic := '0';
|
||||
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||
DIRSet : in std_logic := '0';
|
||||
DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||
@@ -101,12 +102,9 @@ architecture rtl of T80pa is
|
||||
signal MCycle : std_logic_vector(2 downto 0);
|
||||
signal TState : std_logic_vector(2 downto 0);
|
||||
signal CEN_pol : std_logic;
|
||||
signal A_int : std_logic_vector(15 downto 0);
|
||||
signal A_last : std_logic_vector(15 downto 0);
|
||||
signal CEN : std_logic;
|
||||
begin
|
||||
|
||||
A <= A_int when NoRead = '0' or Write = '1' else A_last;
|
||||
CEN <= CEN_p and not CEN_pol;
|
||||
BUSAK_n <= BUSAK;
|
||||
|
||||
@@ -130,7 +128,7 @@ begin
|
||||
BUSRQ_n => BUSRQ_n,
|
||||
BUSAK_n => BUSAK,
|
||||
CLK_n => CLK,
|
||||
A => A_int,
|
||||
A => A,
|
||||
DInst => DI, -- valid at beginning of T3
|
||||
DI => DI_Reg, -- latched at middle of T3
|
||||
DO => DO,
|
||||
@@ -138,6 +136,7 @@ begin
|
||||
MC => MCycle,
|
||||
TS => TState,
|
||||
OUT0 => OUT0,
|
||||
R800_mode => R800_mode,
|
||||
IntCycle_n => IntCycle_n,
|
||||
DIRSet => DIRSet,
|
||||
DIR => DIR
|
||||
@@ -183,7 +182,6 @@ begin
|
||||
RD_n <= not IntCycle_n;
|
||||
MREQ_n <= not IntCycle_n;
|
||||
IORQ_n <= IntCycleD_n(1);
|
||||
A_last <= A_int;
|
||||
end if;
|
||||
if TState = "011" then
|
||||
IntCycleD_n <= "11";
|
||||
@@ -198,7 +196,6 @@ begin
|
||||
if TState = "001" then
|
||||
RD_n <= Write;
|
||||
MREQ_n <= '0';
|
||||
A_last <= A_int;
|
||||
end if;
|
||||
end if;
|
||||
if TState = "010" then
|
||||
|
||||
Reference in New Issue
Block a user