mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-18 23:01:37 +03:00
T80: Sync with latest version.
This commit is contained in:
@ -355,12 +355,7 @@ set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl"
|
|||||||
|
|
||||||
set_global_assignment -name CDF_FILE jtag.cdf
|
set_global_assignment -name CDF_FILE jtag.cdf
|
||||||
set_global_assignment -name QIP_FILE sys/sys.qip
|
set_global_assignment -name QIP_FILE sys/sys.qip
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_Reg.vhd
|
set_global_assignment -name QIP_FILE src/t80/T80.qip
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80s.vhd
|
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zports.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zports.v
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
|
||||||
|
@ -119,7 +119,7 @@ localparam CONF_STR = {
|
|||||||
"O8,CPU Cache,On,Off;",
|
"O8,CPU Cache,On,Off;",
|
||||||
"O9A,#7FFD span,128K,128K Auto,1024K,512K;",
|
"O9A,#7FFD span,128K,128K Auto,1024K,512K;",
|
||||||
"OLN,ZX Palette,Default,B.black,Light,Pale,Dark,Grayscale,Custom;",
|
"OLN,ZX Palette,Default,B.black,Light,Pale,Dark,Grayscale,Custom;",
|
||||||
"OPR,INT Offset,2,3,4,5,6,7,0,1;",
|
"OPR,INT Offset,3,4,5,6,7,0,1,2;",
|
||||||
"-;",
|
"-;",
|
||||||
"OBD,F11 Reset,boot.$C,sys.rom,ROM;",
|
"OBD,F11 Reset,boot.$C,sys.rom,ROM;",
|
||||||
"OEF, bank,TR-DOS,Basic 48,Basic 128,SYS;",
|
"OEF, bank,TR-DOS,Basic 48,Basic 128,SYS;",
|
||||||
@ -144,7 +144,7 @@ assign CMOSCfg[18:16]= (status[18:16]) ? status[18:16] + 3'd2 : 3'd0;
|
|||||||
assign CMOSCfg[20:19]= status[20:19] + 2'd2;
|
assign CMOSCfg[20:19]= status[20:19] + 2'd2;
|
||||||
assign CMOSCfg[23:21]= status[23:21];
|
assign CMOSCfg[23:21]= status[23:21];
|
||||||
assign CMOSCfg[24] = 0;
|
assign CMOSCfg[24] = 0;
|
||||||
assign CMOSCfg[27:25]= status[27:25] + 3'd2;
|
assign CMOSCfg[27:25]= status[27:25] + 3'd3;
|
||||||
|
|
||||||
|
|
||||||
//////////////////// CLOCKS ///////////////////
|
//////////////////// CLOCKS ///////////////////
|
||||||
|
@ -103,15 +103,12 @@ wire cpu_wr_n;
|
|||||||
wire [15:0] cpu_a_bus;
|
wire [15:0] cpu_a_bus;
|
||||||
wire [7:0] cpu_do_bus;
|
wire [7:0] cpu_do_bus;
|
||||||
|
|
||||||
T80s cpu
|
T80pa cpu
|
||||||
(
|
(
|
||||||
.RESET_n(~RESET),
|
.RESET_n(~RESET),
|
||||||
.CLK_n(CLK),
|
.CLK(CLK),
|
||||||
.CEN(CE & ~MEM_WAIT),
|
.CEN_p(CE & ~MEM_WAIT),
|
||||||
.WAIT_n(1),
|
|
||||||
.INT_n(int_n),
|
.INT_n(int_n),
|
||||||
.NMI_n(1),
|
|
||||||
.BUSRQ_n(1),
|
|
||||||
.M1_n(cpu_m1_n),
|
.M1_n(cpu_m1_n),
|
||||||
.MREQ_n(cpu_mreq_n),
|
.MREQ_n(cpu_mreq_n),
|
||||||
.IORQ_n(cpu_iorq_n),
|
.IORQ_n(cpu_iorq_n),
|
||||||
|
7
src/t80/T80.qip
Normal file
7
src/t80/T80.qip
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80_Reg.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80pa.vhd
|
||||||
|
set_global_assignment -name VHDL_FILE src/t80/T80s.vhd
|
260
src/t80/T80.vhd
260
src/t80/T80.vhd
@ -1,10 +1,28 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||||
|
-- accurate timings.
|
||||||
|
-- Version 350.
|
||||||
|
-- Copyright (c) 2018 Sorgelig
|
||||||
|
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
--
|
--
|
||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||||
|
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||||
|
-- Ver 300 started tidyup.
|
||||||
|
--
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
-- Version : 0247
|
-- Version : 0247
|
||||||
--
|
|
||||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||||
--
|
|
||||||
-- All rights reserved
|
-- All rights reserved
|
||||||
--
|
--
|
||||||
-- Redistribution and use in source and synthezised forms, with or without
|
-- Redistribution and use in source and synthezised forms, with or without
|
||||||
@ -45,37 +63,28 @@
|
|||||||
-- File history :
|
-- File history :
|
||||||
--
|
--
|
||||||
-- 0208 : First complete release
|
-- 0208 : First complete release
|
||||||
--
|
|
||||||
-- 0210 : Fixed wait and halt
|
-- 0210 : Fixed wait and halt
|
||||||
--
|
|
||||||
-- 0211 : Fixed Refresh addition and IM 1
|
-- 0211 : Fixed Refresh addition and IM 1
|
||||||
--
|
|
||||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
-- 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
|
-- 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
|
-- 0235 : Added clock enable and IM 2 fix by Mike Johnson
|
||||||
--
|
|
||||||
-- 0237 : Changed 8080 I/O address output, added IntE output
|
-- 0237 : Changed 8080 I/O address output, added IntE output
|
||||||
--
|
|
||||||
-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
|
-- 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
|
-- 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
|
-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
|
||||||
--
|
|
||||||
-- 0247 : Fixed bus req/ack cycle
|
-- 0247 : Fixed bus req/ack cycle
|
||||||
--
|
--
|
||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
|
use IEEE.STD_LOGIC_UNSIGNED.all;
|
||||||
use work.T80_Pack.all;
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80 is
|
entity T80 is
|
||||||
generic(
|
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 := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||||
Flag_C : integer := 0;
|
Flag_C : integer := 0;
|
||||||
Flag_N : integer := 1;
|
Flag_N : integer := 1;
|
||||||
Flag_P : integer := 2;
|
Flag_P : integer := 2;
|
||||||
@ -109,13 +118,7 @@ entity T80 is
|
|||||||
IntCycle_n : out std_logic;
|
IntCycle_n : out std_logic;
|
||||||
IntE : out std_logic;
|
IntE : out std_logic;
|
||||||
Stop : out std_logic;
|
Stop : out std_logic;
|
||||||
|
REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||||
SavePC : out std_logic_vector(15 downto 0);
|
|
||||||
SaveINT : out std_logic_vector(7 downto 0);
|
|
||||||
RestorePC : in std_logic_vector(15 downto 0);
|
|
||||||
RestoreINT : in std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
RestorePC_n : in std_logic
|
|
||||||
);
|
);
|
||||||
end T80;
|
end T80;
|
||||||
|
|
||||||
@ -135,6 +138,7 @@ architecture rtl of T80 is
|
|||||||
signal I : std_logic_vector(7 downto 0);
|
signal I : std_logic_vector(7 downto 0);
|
||||||
signal R : unsigned(7 downto 0);
|
signal R : unsigned(7 downto 0);
|
||||||
signal SP, PC : unsigned(15 downto 0);
|
signal SP, PC : unsigned(15 downto 0);
|
||||||
|
|
||||||
signal RegDIH : std_logic_vector(7 downto 0);
|
signal RegDIH : std_logic_vector(7 downto 0);
|
||||||
signal RegDIL : std_logic_vector(7 downto 0);
|
signal RegDIL : std_logic_vector(7 downto 0);
|
||||||
signal RegBusA : std_logic_vector(15 downto 0);
|
signal RegBusA : std_logic_vector(15 downto 0);
|
||||||
@ -150,7 +154,7 @@ architecture rtl of T80 is
|
|||||||
signal Alternate : std_logic;
|
signal Alternate : std_logic;
|
||||||
|
|
||||||
-- Help Registers
|
-- Help Registers
|
||||||
signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register
|
signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register
|
||||||
signal IR : std_logic_vector(7 downto 0); -- Instruction register
|
signal IR : std_logic_vector(7 downto 0); -- Instruction register
|
||||||
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
|
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
|
||||||
signal RegBusA_r : std_logic_vector(15 downto 0);
|
signal RegBusA_r : std_logic_vector(15 downto 0);
|
||||||
@ -167,7 +171,6 @@ architecture rtl of T80 is
|
|||||||
signal BusAck : std_logic;
|
signal BusAck : std_logic;
|
||||||
signal ClkEn : std_logic;
|
signal ClkEn : std_logic;
|
||||||
signal NMI_s : std_logic;
|
signal NMI_s : std_logic;
|
||||||
signal INT_s : std_logic;
|
|
||||||
signal IStatus : std_logic_vector(1 downto 0);
|
signal IStatus : std_logic_vector(1 downto 0);
|
||||||
|
|
||||||
signal DI_Reg : std_logic_vector(7 downto 0);
|
signal DI_Reg : std_logic_vector(7 downto 0);
|
||||||
@ -240,15 +243,22 @@ architecture rtl of T80 is
|
|||||||
signal I_BTR : std_logic;
|
signal I_BTR : std_logic;
|
||||||
signal I_RLD : std_logic;
|
signal I_RLD : std_logic;
|
||||||
signal I_RRD : std_logic;
|
signal I_RRD : std_logic;
|
||||||
|
signal I_RXDD : std_logic;
|
||||||
signal I_INRC : std_logic;
|
signal I_INRC : std_logic;
|
||||||
|
signal SetWZ : std_logic_vector(1 downto 0);
|
||||||
signal SetDI : std_logic;
|
signal SetDI : std_logic;
|
||||||
signal SetEI : std_logic;
|
signal SetEI : std_logic;
|
||||||
signal IMode : std_logic_vector(1 downto 0);
|
signal IMode : std_logic_vector(1 downto 0);
|
||||||
signal Halt : std_logic;
|
signal Halt : std_logic;
|
||||||
signal XYbit_undoc : std_logic;
|
signal XYbit_undoc : std_logic;
|
||||||
|
signal DOR : std_logic_vector(127 downto 0);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
REG <= DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0'
|
||||||
|
else DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) &
|
||||||
|
std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC;
|
||||||
|
|
||||||
mcode : T80_MCode
|
mcode : T80_MCode
|
||||||
generic map(
|
generic map(
|
||||||
Mode => Mode,
|
Mode => Mode,
|
||||||
@ -308,6 +318,7 @@ begin
|
|||||||
I_RLD => I_RLD,
|
I_RLD => I_RLD,
|
||||||
I_RRD => I_RRD,
|
I_RRD => I_RRD,
|
||||||
I_INRC => I_INRC,
|
I_INRC => I_INRC,
|
||||||
|
SetWZ => SetWZ,
|
||||||
SetDI => SetDI,
|
SetDI => SetDI,
|
||||||
SetEI => SetEI,
|
SetEI => SetEI,
|
||||||
IMode => IMode,
|
IMode => IMode,
|
||||||
@ -330,6 +341,8 @@ begin
|
|||||||
port map(
|
port map(
|
||||||
Arith16 => Arith16_r,
|
Arith16 => Arith16_r,
|
||||||
Z16 => Z16_r,
|
Z16 => Z16_r,
|
||||||
|
WZ => WZ,
|
||||||
|
XY_State=> XY_State,
|
||||||
ALU_Op => ALU_Op_r,
|
ALU_Op => ALU_Op_r,
|
||||||
IR => IR(5 downto 0),
|
IR => IR(5 downto 0),
|
||||||
ISet => ISet,
|
ISet => ISet,
|
||||||
@ -352,15 +365,14 @@ begin
|
|||||||
DI_Reg when Save_ALU_r = '0' else
|
DI_Reg when Save_ALU_r = '0' else
|
||||||
ALU_Q;
|
ALU_Q;
|
||||||
|
|
||||||
process (RESET_n, RestorePC_n, CLK_n)
|
process (RESET_n, CLK_n)
|
||||||
|
variable n : std_logic_vector(7 downto 0);
|
||||||
|
variable ioq : std_logic_vector(8 downto 0);
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if CLK_n'event and CLK_n = '1' then
|
|
||||||
|
|
||||||
if RESET_n = '0' then
|
if RESET_n = '0' then
|
||||||
PC <= (others => '0'); -- Program Counter
|
PC <= (others => '0'); -- Program Counter
|
||||||
A <= (others => '0');
|
A <= (others => '0');
|
||||||
TmpAddr <= (others => '0');
|
WZ <= (others => '0');
|
||||||
IR <= "00000000";
|
IR <= "00000000";
|
||||||
ISet <= "00";
|
ISet <= "00";
|
||||||
XY_State <= "00";
|
XY_State <= "00";
|
||||||
@ -386,13 +398,11 @@ begin
|
|||||||
Save_ALU_r <= '0';
|
Save_ALU_r <= '0';
|
||||||
PreserveC_r <= '0';
|
PreserveC_r <= '0';
|
||||||
XY_Ind <= '0';
|
XY_Ind <= '0';
|
||||||
|
I_RXDD <= '0';
|
||||||
|
|
||||||
elsif RestorePC_n = '0' then
|
elsif rising_edge(CLK_n) then
|
||||||
PC <= unsigned( RestorePC );
|
|
||||||
A <= RestorePC;
|
|
||||||
IStatus <= RestoreInt(1 downto 0);
|
|
||||||
|
|
||||||
elsif ClkEn = '1' then
|
if ClkEn = '1' then
|
||||||
|
|
||||||
ALU_Op_r <= "0000";
|
ALU_Op_r <= "0000";
|
||||||
Save_ALU_r <= '0';
|
Save_ALU_r <= '0';
|
||||||
@ -469,23 +479,23 @@ begin
|
|||||||
BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
|
BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
|
||||||
if Jump = '1' then
|
if Jump = '1' then
|
||||||
A(15 downto 8) <= DI_Reg;
|
A(15 downto 8) <= DI_Reg;
|
||||||
A(7 downto 0) <= TmpAddr(7 downto 0);
|
A(7 downto 0) <= WZ(7 downto 0);
|
||||||
PC(15 downto 8) <= unsigned(DI_Reg);
|
PC(15 downto 8) <= unsigned(DI_Reg);
|
||||||
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
|
PC(7 downto 0) <= unsigned(WZ(7 downto 0));
|
||||||
elsif JumpXY = '1' then
|
elsif JumpXY = '1' then
|
||||||
A <= RegBusC;
|
A <= RegBusC;
|
||||||
PC <= unsigned(RegBusC);
|
PC <= unsigned(RegBusC);
|
||||||
elsif Call = '1' or RstP = '1' then
|
elsif Call = '1' or RstP = '1' then
|
||||||
A <= TmpAddr;
|
A <= WZ;
|
||||||
PC <= unsigned(TmpAddr);
|
PC <= unsigned(WZ);
|
||||||
elsif MCycle = MCycles and NMICycle = '1' then
|
elsif MCycle = MCycles and NMICycle = '1' then
|
||||||
A <= "0000000001100110";
|
A <= "0000000001100110";
|
||||||
PC <= "0000000001100110";
|
PC <= "0000000001100110";
|
||||||
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
|
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
|
||||||
A(15 downto 8) <= I;
|
A(15 downto 8) <= I;
|
||||||
A(7 downto 0) <= TmpAddr(7 downto 0);
|
A(7 downto 0) <= WZ(7 downto 0);
|
||||||
PC(15 downto 8) <= unsigned(I);
|
PC(15 downto 8) <= unsigned(I);
|
||||||
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
|
PC(7 downto 0) <= unsigned(WZ(7 downto 0));
|
||||||
else
|
else
|
||||||
case Set_Addr_To is
|
case Set_Addr_To is
|
||||||
when aXY =>
|
when aXY =>
|
||||||
@ -495,7 +505,7 @@ begin
|
|||||||
if NextIs_XY_Fetch = '1' then
|
if NextIs_XY_Fetch = '1' then
|
||||||
A <= std_logic_vector(PC);
|
A <= std_logic_vector(PC);
|
||||||
else
|
else
|
||||||
A <= TmpAddr;
|
A <= WZ;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when aIOA =>
|
when aIOA =>
|
||||||
@ -509,6 +519,7 @@ begin
|
|||||||
A(15 downto 8) <= ACC;
|
A(15 downto 8) <= ACC;
|
||||||
end if;
|
end if;
|
||||||
A(7 downto 0) <= DI_Reg;
|
A(7 downto 0) <= DI_Reg;
|
||||||
|
WZ <= (ACC & DI_Reg) + "1";
|
||||||
when aSP =>
|
when aSP =>
|
||||||
A <= std_logic_vector(SP);
|
A <= std_logic_vector(SP);
|
||||||
when aBC =>
|
when aBC =>
|
||||||
@ -518,21 +529,40 @@ begin
|
|||||||
A(7 downto 0) <= RegBusC(7 downto 0);
|
A(7 downto 0) <= RegBusC(7 downto 0);
|
||||||
else
|
else
|
||||||
A <= RegBusC;
|
A <= RegBusC;
|
||||||
|
if SetWZ = "01" then
|
||||||
|
WZ <= RegBusC + "1";
|
||||||
|
end if;
|
||||||
|
if SetWZ = "10" then
|
||||||
|
WZ(7 downto 0) <= RegBusC(7 downto 0) + "1";
|
||||||
|
WZ(15 downto 8) <= ACC;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when aDE =>
|
when aDE =>
|
||||||
A <= RegBusC;
|
A <= RegBusC;
|
||||||
|
if SetWZ = "10" then
|
||||||
|
WZ(7 downto 0) <= RegBusC(7 downto 0) + "1";
|
||||||
|
WZ(15 downto 8) <= ACC;
|
||||||
|
end if;
|
||||||
when aZI =>
|
when aZI =>
|
||||||
if Inc_WZ = '1' then
|
if Inc_WZ = '1' then
|
||||||
A <= std_logic_vector(unsigned(TmpAddr) + 1);
|
A <= std_logic_vector(unsigned(WZ) + 1);
|
||||||
else
|
else
|
||||||
A(15 downto 8) <= DI_Reg;
|
A(15 downto 8) <= DI_Reg;
|
||||||
A(7 downto 0) <= TmpAddr(7 downto 0);
|
A(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;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
A <= std_logic_vector(PC);
|
A <= std_logic_vector(PC);
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
if SetWZ = "11" then
|
||||||
|
WZ <= std_logic_vector(ID16);
|
||||||
|
end if;
|
||||||
|
|
||||||
Save_ALU_r <= Save_ALU;
|
Save_ALU_r <= Save_ALU;
|
||||||
ALU_Op_r <= ALU_Op;
|
ALU_Op_r <= ALU_Op;
|
||||||
|
|
||||||
@ -562,12 +592,22 @@ begin
|
|||||||
end if;
|
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
|
||||||
|
ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0)));
|
||||||
|
F(Flag_N) <= DI_Reg(7);
|
||||||
|
F(Flag_C) <= ioq(8);
|
||||||
|
F(Flag_H) <= ioq(8);
|
||||||
|
ioq := (ioq and x"7") xor ('0'&BusA);
|
||||||
|
F(Flag_P) <= not (ioq(0) xor ioq(1) xor ioq(2) xor ioq(3) xor ioq(4) xor ioq(5) xor ioq(6) xor ioq(7));
|
||||||
|
end if;
|
||||||
|
|
||||||
if TState = 2 and Wait_n = '1' then
|
if TState = 2 and Wait_n = '1' then
|
||||||
if ISet = "01" and MCycle = "111" then
|
if ISet = "01" and MCycle = "111" then
|
||||||
IR <= DInst;
|
IR <= DInst;
|
||||||
end if;
|
end if;
|
||||||
if JumpE = '1' then
|
if JumpE = '1' then
|
||||||
PC <= unsigned(signed(PC) + signed(DI_Reg));
|
PC <= unsigned(signed(PC) + signed(DI_Reg));
|
||||||
|
WZ <= std_logic_vector(signed(PC) + signed(DI_Reg));
|
||||||
elsif Inc_PC = '1' then
|
elsif Inc_PC = '1' then
|
||||||
PC <= PC + 1;
|
PC <= PC + 1;
|
||||||
end if;
|
end if;
|
||||||
@ -575,12 +615,18 @@ begin
|
|||||||
PC <= PC - 2;
|
PC <= PC - 2;
|
||||||
end if;
|
end if;
|
||||||
if RstP = '1' then
|
if RstP = '1' then
|
||||||
TmpAddr <= (others =>'0');
|
WZ <= (others =>'0');
|
||||||
TmpAddr(5 downto 3) <= IR(5 downto 3);
|
WZ(5 downto 3) <= IR(5 downto 3);
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
if TState = 3 and MCycle = "110" then
|
if TState = 3 and MCycle = "110" then
|
||||||
TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
|
WZ <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if MCycle = "011" and TState = 4 and No_BTR = '0' then
|
||||||
|
if I_BT = '1' or I_BC = '1' then
|
||||||
|
WZ <= std_logic_vector(PC)-"1";
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
|
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
|
||||||
@ -609,10 +655,10 @@ begin
|
|||||||
|
|
||||||
if TState = 3 then
|
if TState = 3 then
|
||||||
if LDZ = '1' then
|
if LDZ = '1' then
|
||||||
TmpAddr(7 downto 0) <= DI_Reg;
|
WZ(7 downto 0) <= DI_Reg;
|
||||||
end if;
|
end if;
|
||||||
if LDW = '1' then
|
if LDW = '1' then
|
||||||
TmpAddr(15 downto 8) <= DI_Reg;
|
WZ(15 downto 8) <= DI_Reg;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if Special_LD(2) = '1' then
|
if Special_LD(2) = '1' then
|
||||||
@ -628,6 +674,12 @@ begin
|
|||||||
F(Flag_Z) <= '0';
|
F(Flag_Z) <= '0';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
F(Flag_Y) <= I(5);
|
||||||
|
F(Flag_H) <= '0';
|
||||||
|
F(Flag_X) <= I(3);
|
||||||
|
F(Flag_N) <= '0';
|
||||||
|
|
||||||
|
|
||||||
when "01" =>
|
when "01" =>
|
||||||
ACC <= std_logic_vector(R);
|
ACC <= std_logic_vector(R);
|
||||||
F(Flag_P) <= IntE_FF2;
|
F(Flag_P) <= IntE_FF2;
|
||||||
@ -639,6 +691,11 @@ begin
|
|||||||
F(Flag_Z) <= '0';
|
F(Flag_Z) <= '0';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
F(Flag_Y) <= R(5);
|
||||||
|
F(Flag_H) <= '0';
|
||||||
|
F(Flag_X) <= R(3);
|
||||||
|
F(Flag_N) <= '0';
|
||||||
|
|
||||||
when "10" =>
|
when "10" =>
|
||||||
I <= ACC;
|
I <= ACC;
|
||||||
when others =>
|
when others =>
|
||||||
@ -665,6 +722,8 @@ begin
|
|||||||
if T_Res = '1' and I_INRC = '1' then
|
if T_Res = '1' and I_INRC = '1' then
|
||||||
F(Flag_H) <= '0';
|
F(Flag_H) <= '0';
|
||||||
F(Flag_N) <= '0';
|
F(Flag_N) <= '0';
|
||||||
|
F(Flag_X) <= DI_Reg(3);
|
||||||
|
F(Flag_Y) <= DI_Reg(5);
|
||||||
if DI_Reg(7 downto 0) = "00000000" then
|
if DI_Reg(7 downto 0) = "00000000" then
|
||||||
F(Flag_Z) <= '1';
|
F(Flag_Z) <= '1';
|
||||||
else
|
else
|
||||||
@ -676,7 +735,11 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
if TState = 1 and Auto_Wait_t1 = '0' then
|
if TState = 1 and Auto_Wait_t1 = '0' then
|
||||||
|
-- Keep D0 from M3 for RLD/RRD (Sorgelig)
|
||||||
|
I_RXDD <= I_RLD or I_RRD;
|
||||||
|
if I_RXDD='0' then
|
||||||
DO <= BusB;
|
DO <= BusB;
|
||||||
|
end if;
|
||||||
if I_RLD = '1' then
|
if I_RLD = '1' then
|
||||||
DO(3 downto 0) <= BusA(3 downto 0);
|
DO(3 downto 0) <= BusA(3 downto 0);
|
||||||
DO(7 downto 4) <= BusB(3 downto 0);
|
DO(7 downto 4) <= BusB(3 downto 0);
|
||||||
@ -702,6 +765,11 @@ begin
|
|||||||
F(Flag_H) <= '0';
|
F(Flag_H) <= '0';
|
||||||
F(Flag_N) <= '0';
|
F(Flag_N) <= '0';
|
||||||
end if;
|
end if;
|
||||||
|
if TState = 1 and I_BC = '1' then
|
||||||
|
n := ALU_Q - ("0000000" & F_Out(Flag_H));
|
||||||
|
F(Flag_X) <= n(3);
|
||||||
|
F(Flag_Y) <= n(1);
|
||||||
|
end if;
|
||||||
if I_BC = '1' or I_BT = '1' then
|
if I_BC = '1' or I_BT = '1' then
|
||||||
F(Flag_P) <= IncDecZ;
|
F(Flag_P) <= IncDecZ;
|
||||||
end if;
|
end if;
|
||||||
@ -739,7 +807,7 @@ begin
|
|||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
process (CLK_n)
|
process (CLK_n)
|
||||||
begin
|
begin
|
||||||
if CLK_n'event and CLK_n = '1' then
|
if rising_edge(CLK_n) then
|
||||||
if ClkEn = '1' then
|
if ClkEn = '1' then
|
||||||
-- Bus A / Write
|
-- Bus A / Write
|
||||||
RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
|
RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
|
||||||
@ -781,10 +849,10 @@ begin
|
|||||||
|
|
||||||
RegAddrA <=
|
RegAddrA <=
|
||||||
-- 16 bit increment/decrement
|
-- 16 bit increment/decrement
|
||||||
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" and XY_State /= "00" else
|
|
||||||
Alternate & IncDec_16(1 downto 0) when (TState = 2 or
|
Alternate & IncDec_16(1 downto 0) when (TState = 2 or
|
||||||
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) else
|
(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
|
-- EX HL,DL
|
||||||
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
|
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
|
||||||
Alternate & "01" when ExchangeDH = '1' and TState = 4 else
|
Alternate & "01" when ExchangeDH = '1' and TState = 4 else
|
||||||
@ -867,7 +935,8 @@ begin
|
|||||||
DOBH => RegBusB(15 downto 8),
|
DOBH => RegBusB(15 downto 8),
|
||||||
DOBL => RegBusB(7 downto 0),
|
DOBL => RegBusB(7 downto 0),
|
||||||
DOCH => RegBusC(15 downto 8),
|
DOCH => RegBusC(15 downto 8),
|
||||||
DOCL => RegBusC(7 downto 0));
|
DOCL => RegBusC(7 downto 0),
|
||||||
|
DOR => DOR);
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
--
|
--
|
||||||
@ -876,7 +945,7 @@ begin
|
|||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
process (CLK_n)
|
process (CLK_n)
|
||||||
begin
|
begin
|
||||||
if CLK_n'event and CLK_n = '1' then
|
if rising_edge(CLK_n) then
|
||||||
if ClkEn = '1' then
|
if ClkEn = '1' then
|
||||||
case Set_BusB_To is
|
case Set_BusB_To is
|
||||||
when "0111" =>
|
when "0111" =>
|
||||||
@ -925,7 +994,7 @@ begin
|
|||||||
when "1010" =>
|
when "1010" =>
|
||||||
BusA <= "00000000";
|
BusA <= "00000000";
|
||||||
when others =>
|
when others =>
|
||||||
BusB <= "--------";
|
BusA <= "--------";
|
||||||
end case;
|
end case;
|
||||||
if XYbit_undoc='1' then
|
if XYbit_undoc='1' then
|
||||||
BusA <= DI_Reg;
|
BusA <= DI_Reg;
|
||||||
@ -942,11 +1011,10 @@ begin
|
|||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
process (RESET_n,CLK_n)
|
process (RESET_n,CLK_n)
|
||||||
begin
|
begin
|
||||||
if CLK_n'event and CLK_n = '1' then
|
|
||||||
if RESET_n = '0' then
|
if RESET_n = '0' then
|
||||||
RFSH_n <= '1';
|
RFSH_n <= '1';
|
||||||
|
elsif rising_edge(CLK_n) then
|
||||||
elsif CEN = '1' then
|
if CEN = '1' then
|
||||||
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
|
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
|
||||||
RFSH_n <= '0';
|
RFSH_n <= '0';
|
||||||
else
|
else
|
||||||
@ -966,49 +1034,14 @@ begin
|
|||||||
IORQ <= IORQ_i;
|
IORQ <= IORQ_i;
|
||||||
Stop <= I_DJNZ;
|
Stop <= I_DJNZ;
|
||||||
|
|
||||||
SavePC <= std_logic_vector( PC );
|
|
||||||
SaveINT <= "0000" & IntE_FF2 & IntE_FF1 & IStatus when MCycle = "001" and TState = "001" and Prefix = "00" and IntCycle = '0' and NMICycle = '0' else
|
|
||||||
"1111" & IntE_FF2 & IntE_FF1 & IStatus;
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
--
|
|
||||||
-- Syncronise inputs
|
|
||||||
--
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
process (RESET_n, CLK_n)
|
|
||||||
variable OldNMI_n : std_logic;
|
|
||||||
begin
|
|
||||||
if CLK_n'event and CLK_n = '1' then
|
|
||||||
|
|
||||||
if RESET_n = '0' then
|
|
||||||
BusReq_s <= '0';
|
|
||||||
INT_s <= '0';
|
|
||||||
NMI_s <= '0';
|
|
||||||
OldNMI_n := '0';
|
|
||||||
|
|
||||||
elsif 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
|
-- Main state machine
|
||||||
--
|
--
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
process (RESET_n, RestorePC_n, CLK_n)
|
process (RESET_n, CLK_n)
|
||||||
|
variable OldNMI_n : std_logic;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if CLK_n'event and CLK_n = '1' then
|
|
||||||
if RESET_n = '0' then
|
if RESET_n = '0' then
|
||||||
MCycle <= "001";
|
MCycle <= "001";
|
||||||
TState <= "000";
|
TState <= "000";
|
||||||
@ -1023,29 +1056,24 @@ begin
|
|||||||
Auto_Wait_t1 <= '0';
|
Auto_Wait_t1 <= '0';
|
||||||
Auto_Wait_t2 <= '0';
|
Auto_Wait_t2 <= '0';
|
||||||
M1_n <= '1';
|
M1_n <= '1';
|
||||||
|
BusReq_s <= '0';
|
||||||
|
NMI_s <= '0';
|
||||||
|
elsif rising_edge(CLK_n) then
|
||||||
|
|
||||||
elsif RestorePC_n = '0' then
|
if NMI_n = '0' and OldNMI_n = '1' then
|
||||||
MCycle <= "001";
|
NMI_s <= '1';
|
||||||
TState <= "001";
|
end if;
|
||||||
NMICycle <= '0';
|
OldNMI_n := NMI_n;
|
||||||
IntCycle <= '0';
|
|
||||||
IntE_FF1 <= RestoreINT(2);
|
|
||||||
IntE_FF2 <= RestoreINT(3);
|
|
||||||
|
|
||||||
Pre_XY_F_M <= "000";
|
if CEN = '1' then
|
||||||
Halt_FF <= '0';
|
BusReq_s <= not BUSRQ_n;
|
||||||
BusAck <= '0';
|
Auto_Wait_t2 <= Auto_Wait_t1;
|
||||||
No_BTR <= '0';
|
|
||||||
Auto_Wait_t1 <= '0';
|
|
||||||
Auto_Wait_t2 <= '0';
|
|
||||||
|
|
||||||
elsif CEN = '1' then
|
|
||||||
if T_Res = '1' then
|
if T_Res = '1' then
|
||||||
Auto_Wait_t1 <= '0';
|
Auto_Wait_t1 <= '0';
|
||||||
|
Auto_Wait_t2 <= '0';
|
||||||
else
|
else
|
||||||
Auto_Wait_t1 <= Auto_Wait or IORQ_i;
|
Auto_Wait_t1 <= Auto_Wait or IORQ_i;
|
||||||
end if;
|
end if;
|
||||||
Auto_Wait_t2 <= Auto_Wait_t1;
|
|
||||||
No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
|
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_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)));
|
(I_BTR and (not IR(4) or F(Flag_Z)));
|
||||||
@ -1082,32 +1110,28 @@ begin
|
|||||||
BusAck <= '1';
|
BusAck <= '1';
|
||||||
else
|
else
|
||||||
TState <= "001";
|
TState <= "001";
|
||||||
|
|
||||||
if NextIs_XY_Fetch = '1' then
|
if NextIs_XY_Fetch = '1' then
|
||||||
MCycle <= "110";
|
MCycle <= "110";
|
||||||
Pre_XY_F_M <= MCycle;
|
Pre_XY_F_M <= MCycle;
|
||||||
if IR = "00110110" and Mode = 0 then
|
if IR = "00110110" and Mode = 0 then
|
||||||
Pre_XY_F_M <= "010";
|
Pre_XY_F_M <= "010";
|
||||||
end if;
|
end if;
|
||||||
elsif (MCycle = MCycles) or
|
elsif (MCycle = "111") or (MCycle = "110" and Mode = 1 and ISet /= "01") then
|
||||||
No_BTR = '1' or
|
MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
|
||||||
(MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') or
|
elsif (MCycle = MCycles) or No_BTR = '1' or (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
|
||||||
( MCycle = "111" and MCycles= "001" and Pre_XY_F_M = "001" ) then
|
|
||||||
M1_n <= '0';
|
M1_n <= '0';
|
||||||
MCycle <= "001";
|
MCycle <= "001";
|
||||||
IntCycle <= '0';
|
IntCycle <= '0';
|
||||||
NMICycle <= '0';
|
NMICycle <= '0';
|
||||||
if NMI_s = '1' and Prefix = "00" then
|
if NMI_s = '1' and Prefix = "00" then
|
||||||
|
NMI_s <= '0';
|
||||||
NMICycle <= '1';
|
NMICycle <= '1';
|
||||||
IntE_FF1 <= '0';
|
IntE_FF1 <= '0';
|
||||||
elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
|
elsif IntE_FF1 = '1' and INT_n='0' and Prefix = "00" and SetEI = '0' then
|
||||||
IntCycle <= '1';
|
IntCycle <= '1';
|
||||||
IntE_FF1 <= '0';
|
IntE_FF1 <= '0';
|
||||||
IntE_FF2 <= '0';
|
IntE_FF2 <= '0';
|
||||||
end if;
|
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);
|
|
||||||
else
|
else
|
||||||
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
|
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
|
||||||
end if;
|
end if;
|
||||||
|
@ -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;
|
|
@ -1,10 +1,26 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||||
|
-- accurate timings.
|
||||||
|
-- Version 350.
|
||||||
|
-- Copyright (c) 2018 Sorgelig
|
||||||
|
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
--
|
--
|
||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle
|
||||||
|
-- Ver 300 started tidyup
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
-- Version : 0247
|
-- Version : 0247
|
||||||
--
|
|
||||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||||
--
|
|
||||||
-- All rights reserved
|
-- All rights reserved
|
||||||
--
|
--
|
||||||
-- Redistribution and use in source and synthezised forms, with or without
|
-- Redistribution and use in source and synthezised forms, with or without
|
||||||
@ -45,13 +61,9 @@
|
|||||||
-- File history :
|
-- File history :
|
||||||
--
|
--
|
||||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||||
--
|
|
||||||
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
|
||||||
--
|
|
||||||
-- 0240 : Added GB operations
|
-- 0240 : Added GB operations
|
||||||
--
|
|
||||||
-- 0242 : Cleanup
|
-- 0242 : Cleanup
|
||||||
--
|
|
||||||
-- 0247 : Cleanup
|
-- 0247 : Cleanup
|
||||||
--
|
--
|
||||||
|
|
||||||
@ -74,6 +86,8 @@ entity T80_ALU is
|
|||||||
port(
|
port(
|
||||||
Arith16 : in std_logic;
|
Arith16 : in std_logic;
|
||||||
Z16 : in std_logic;
|
Z16 : in std_logic;
|
||||||
|
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);
|
ALU_Op : in std_logic_vector(3 downto 0);
|
||||||
IR : in std_logic_vector(5 downto 0);
|
IR : in std_logic_vector(5 downto 0);
|
||||||
ISet : in std_logic_vector(1 downto 0);
|
ISet : in std_logic_vector(1 downto 0);
|
||||||
@ -93,6 +107,7 @@ architecture rtl of T80_ALU is
|
|||||||
Carry_In : std_logic;
|
Carry_In : std_logic;
|
||||||
signal Res : out std_logic_vector;
|
signal Res : out std_logic_vector;
|
||||||
signal Carry : out std_logic) is
|
signal Carry : out std_logic) is
|
||||||
|
|
||||||
variable B_i : unsigned(A'length - 1 downto 0);
|
variable B_i : unsigned(A'length - 1 downto 0);
|
||||||
variable Res_i : unsigned(A'length + 1 downto 0);
|
variable Res_i : unsigned(A'length + 1 downto 0);
|
||||||
begin
|
begin
|
||||||
@ -101,6 +116,7 @@ architecture rtl of T80_ALU is
|
|||||||
else
|
else
|
||||||
B_i := unsigned(B);
|
B_i := unsigned(B);
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
|
||||||
Carry <= Res_i(A'length + 1);
|
Carry <= Res_i(A'length + 1);
|
||||||
Res <= std_logic_vector(Res_i(A'length downto 1));
|
Res <= std_logic_vector(Res_i(A'length downto 1));
|
||||||
@ -131,9 +147,18 @@ begin
|
|||||||
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(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(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);
|
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)
|
-- bug fix - parity flag is just parity for 8080, also overflow for Z80
|
||||||
|
process (Carry_v, Carry7_v, Q_v)
|
||||||
|
begin
|
||||||
|
if(Mode=2) then
|
||||||
|
OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor
|
||||||
|
Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else
|
||||||
|
OverFlow_v <= Carry_v xor Carry7_v;
|
||||||
|
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)
|
||||||
variable Q_t : std_logic_vector(7 downto 0);
|
variable Q_t : std_logic_vector(7 downto 0);
|
||||||
variable DAA_Q : unsigned(8 downto 0);
|
variable DAA_Q : unsigned(8 downto 0);
|
||||||
begin
|
begin
|
||||||
@ -271,9 +296,10 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
F_Out(Flag_H) <= '1';
|
F_Out(Flag_H) <= '1';
|
||||||
F_Out(Flag_N) <= '0';
|
F_Out(Flag_N) <= '0';
|
||||||
F_Out(Flag_X) <= '0';
|
if IR(2 downto 0) = "110" or XY_State /= "00" then
|
||||||
F_Out(Flag_Y) <= '0';
|
F_Out(Flag_X) <= WZ(11);
|
||||||
if IR(2 downto 0) /= "110" then
|
F_Out(Flag_Y) <= WZ(13);
|
||||||
|
else
|
||||||
F_Out(Flag_X) <= BusB(3);
|
F_Out(Flag_X) <= BusB(3);
|
||||||
F_Out(Flag_Y) <= BusB(5);
|
F_Out(Flag_Y) <= BusB(5);
|
||||||
end if;
|
end if;
|
||||||
@ -347,5 +373,4 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
Q <= Q_t;
|
Q <= Q_t;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||||
|
-- accurate timings.
|
||||||
|
-- Version 350.
|
||||||
|
-- Copyright (c) 2018 Sorgelig
|
||||||
|
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
--
|
--
|
||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||||
|
-- Ver 300 started tidyup
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
-- Version : 0242
|
-- Version : 0242
|
||||||
--
|
|
||||||
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
|
||||||
--
|
|
||||||
-- All rights reserved
|
-- All rights reserved
|
||||||
--
|
--
|
||||||
-- Redistribution and use in source and synthezised forms, with or without
|
-- Redistribution and use in source and synthezised forms, with or without
|
||||||
@ -45,25 +61,20 @@
|
|||||||
-- File history :
|
-- File history :
|
||||||
--
|
--
|
||||||
-- 0208 : First complete release
|
-- 0208 : First complete release
|
||||||
--
|
|
||||||
-- 0211 : Fixed IM 1
|
-- 0211 : Fixed IM 1
|
||||||
--
|
|
||||||
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
|
||||||
--
|
|
||||||
-- 0235 : Added IM 2 fix by Mike Johnson
|
-- 0235 : Added IM 2 fix by Mike Johnson
|
||||||
--
|
|
||||||
-- 0238 : Added NoRead signal
|
-- 0238 : Added NoRead signal
|
||||||
--
|
|
||||||
-- 0238b: Fixed instruction timing for POP and DJNZ
|
-- 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
|
-- 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
|
-- 0242 : Fixed I/O instruction timing, cleanup
|
||||||
--
|
--
|
||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
||||||
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
entity T80_MCode is
|
entity T80_MCode is
|
||||||
generic(
|
generic(
|
||||||
@ -126,6 +137,7 @@ entity T80_MCode is
|
|||||||
I_RLD : out std_logic;
|
I_RLD : out std_logic;
|
||||||
I_RRD : out std_logic;
|
I_RRD : out std_logic;
|
||||||
I_INRC : out std_logic;
|
I_INRC : out std_logic;
|
||||||
|
SetWZ : out std_logic_vector(1 downto 0);
|
||||||
SetDI : out std_logic;
|
SetDI : out std_logic;
|
||||||
SetEI : out std_logic;
|
SetEI : out std_logic;
|
||||||
IMode : out std_logic_vector(1 downto 0);
|
IMode : out std_logic_vector(1 downto 0);
|
||||||
@ -145,13 +157,6 @@ architecture rtl of T80_MCode is
|
|||||||
constant aIOA : std_logic_vector(2 downto 0) := "100";
|
constant aIOA : std_logic_vector(2 downto 0) := "100";
|
||||||
constant aSP : std_logic_vector(2 downto 0) := "101";
|
constant aSP : std_logic_vector(2 downto 0) := "101";
|
||||||
constant aZI : std_logic_vector(2 downto 0) := "110";
|
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(
|
function is_cc_true(
|
||||||
F : std_logic_vector(7 downto 0);
|
F : std_logic_vector(7 downto 0);
|
||||||
@ -160,10 +165,10 @@ architecture rtl of T80_MCode is
|
|||||||
begin
|
begin
|
||||||
if Mode = 3 then
|
if Mode = 3 then
|
||||||
case cc is
|
case cc is
|
||||||
when "000" => return F(7) = '0'; -- NZ
|
when "000" => return F(Flag_S) = '0'; -- NZ
|
||||||
when "001" => return F(7) = '1'; -- Z
|
when "001" => return F(Flag_S) = '1'; -- Z
|
||||||
when "010" => return F(4) = '0'; -- NC
|
when "010" => return F(Flag_H) = '0'; -- NC
|
||||||
when "011" => return F(4) = '1'; -- C
|
when "011" => return F(Flag_H) = '1'; -- C
|
||||||
when "100" => return false;
|
when "100" => return false;
|
||||||
when "101" => return false;
|
when "101" => return false;
|
||||||
when "110" => return false;
|
when "110" => return false;
|
||||||
@ -171,14 +176,14 @@ architecture rtl of T80_MCode is
|
|||||||
end case;
|
end case;
|
||||||
else
|
else
|
||||||
case cc is
|
case cc is
|
||||||
when "000" => return F(6) = '0'; -- NZ
|
when "000" => return F(Flag_Z) = '0'; -- NZ
|
||||||
when "001" => return F(6) = '1'; -- Z
|
when "001" => return F(Flag_Z) = '1'; -- Z
|
||||||
when "010" => return F(0) = '0'; -- NC
|
when "010" => return F(Flag_C) = '0'; -- NC
|
||||||
when "011" => return F(0) = '1'; -- C
|
when "011" => return F(Flag_C) = '1'; -- C
|
||||||
when "100" => return F(2) = '0'; -- PO
|
when "100" => return F(Flag_P) = '0'; -- PO
|
||||||
when "101" => return F(2) = '1'; -- PE
|
when "101" => return F(Flag_P) = '1'; -- PE
|
||||||
when "110" => return F(7) = '0'; -- P
|
when "110" => return F(Flag_S) = '0'; -- P
|
||||||
when "111" => return F(7) = '1'; -- M
|
when "111" => return F(Flag_S) = '1'; -- M
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end;
|
end;
|
||||||
@ -247,6 +252,7 @@ begin
|
|||||||
NoRead <= '0';
|
NoRead <= '0';
|
||||||
Write <= '0';
|
Write <= '0';
|
||||||
XYbit_undoc <= '0';
|
XYbit_undoc <= '0';
|
||||||
|
SetWZ <= "00";
|
||||||
|
|
||||||
case ISet is
|
case ISet is
|
||||||
when "00" =>
|
when "00" =>
|
||||||
@ -371,6 +377,7 @@ begin
|
|||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
Set_BusB_To <= "0111";
|
Set_BusB_To <= "0111";
|
||||||
|
SetWZ <= "10";
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
@ -382,6 +389,7 @@ begin
|
|||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aDE;
|
Set_Addr_To <= aDE;
|
||||||
Set_BusB_To <= "0111";
|
Set_BusB_To <= "0111";
|
||||||
|
SetWZ <= "10";
|
||||||
when 2 =>
|
when 2 =>
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
@ -408,6 +416,7 @@ begin
|
|||||||
LDZ <= '1';
|
LDZ <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
Set_Addr_To <= aZI;
|
Set_Addr_To <= aZI;
|
||||||
|
SetWZ <= "10";
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
Set_BusB_To <= "0111";
|
Set_BusB_To <= "0111";
|
||||||
when 4 =>
|
when 4 =>
|
||||||
@ -638,6 +647,7 @@ begin
|
|||||||
Set_BusA_To <= "0101";
|
Set_BusA_To <= "0101";
|
||||||
Set_BusB_To <= "0101";
|
Set_BusB_To <= "0101";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
|
LDZ <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
IncDec_16 <= "0111";
|
IncDec_16 <= "0111";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
@ -648,6 +658,7 @@ begin
|
|||||||
Set_BusA_To <= "0100";
|
Set_BusA_To <= "0100";
|
||||||
Set_BusB_To <= "0100";
|
Set_BusB_To <= "0100";
|
||||||
Set_Addr_To <= aSP;
|
Set_Addr_To <= aSP;
|
||||||
|
LDW <= '1';
|
||||||
when 5 =>
|
when 5 =>
|
||||||
IncDec_16 <= "1111";
|
IncDec_16 <= "1111";
|
||||||
TStates <= "101";
|
TStates <= "101";
|
||||||
@ -865,6 +876,7 @@ begin
|
|||||||
end case;
|
end case;
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
Arith16 <= '1';
|
Arith16 <= '1';
|
||||||
|
SetWZ <= "11";
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
@ -916,6 +928,7 @@ begin
|
|||||||
when 3 =>
|
when 3 =>
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
|
LDW <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
|
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
|
||||||
@ -982,6 +995,7 @@ begin
|
|||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
LDZ <= '1';
|
LDZ <= '1';
|
||||||
when 3 =>
|
when 3 =>
|
||||||
|
LDW <= '1';
|
||||||
Inc_PC <= '1';
|
Inc_PC <= '1';
|
||||||
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
@ -1363,7 +1377,7 @@ begin
|
|||||||
-- SRL r
|
-- SRL r
|
||||||
-- SLL r (Undocumented) / SWAP r
|
-- SLL r (Undocumented) / SWAP r
|
||||||
if XY_State="00" then
|
if XY_State="00" then
|
||||||
if MCycle = "001" or MCycle = "111" then
|
if MCycle = "001" then
|
||||||
ALU_Op <= "1000";
|
ALU_Op <= "1000";
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
@ -1420,7 +1434,7 @@ begin
|
|||||||
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
|
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
|
||||||
-- BIT b,r
|
-- BIT b,r
|
||||||
if XY_State="00" then
|
if XY_State="00" then
|
||||||
if MCycle = "001" or MCycle = "111" then
|
if MCycle = "001" then
|
||||||
Set_BusB_To(2 downto 0) <= IR(2 downto 0);
|
Set_BusB_To(2 downto 0) <= IR(2 downto 0);
|
||||||
ALU_Op <= "1001";
|
ALU_Op <= "1001";
|
||||||
end if;
|
end if;
|
||||||
@ -1463,24 +1477,6 @@ begin
|
|||||||
ALU_Op <= "1010";
|
ALU_Op <= "1010";
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
else
|
|
||||||
MCycles <= "100";
|
|
||||||
case to_integer(unsigned(MCycle)) is
|
|
||||||
when 7 =>
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
when 2 =>
|
|
||||||
Set_BusB_To(2 downto 0) <= "110";
|
|
||||||
ALU_Op <= "1010";
|
|
||||||
Read_To_Reg <= '1';
|
|
||||||
Save_ALU <= '1';
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
TStates <= "100";
|
|
||||||
when 3 =>
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
when 4 =>
|
|
||||||
Write <= '1';
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
-- SET b,(IX+d),Reg, undocumented
|
-- SET b,(IX+d),Reg, undocumented
|
||||||
@ -1531,24 +1527,6 @@ begin
|
|||||||
ALU_Op <= "1011";
|
ALU_Op <= "1011";
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
else
|
|
||||||
MCycles <= "100";
|
|
||||||
case to_integer(unsigned(MCycle)) is
|
|
||||||
when 7 =>
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
when 2 =>
|
|
||||||
Set_BusB_To(2 downto 0) <= "110";
|
|
||||||
ALU_Op <= "1011";
|
|
||||||
Read_To_Reg <= '1';
|
|
||||||
Save_ALU <= '1';
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
TStates <= "100";
|
|
||||||
when 3 =>
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
when 4 =>
|
|
||||||
Write <= '1';
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
-- RES b,(IX+d),Reg, undocumented
|
-- RES b,(IX+d),Reg, undocumented
|
||||||
@ -1801,6 +1779,7 @@ begin
|
|||||||
Set_BusB_To <= "1000";
|
Set_BusB_To <= "1000";
|
||||||
end case;
|
end case;
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
|
SetWZ <= "11";
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
@ -1834,6 +1813,7 @@ begin
|
|||||||
Set_BusB_To <= "1000";
|
Set_BusB_To <= "1000";
|
||||||
end case;
|
end case;
|
||||||
TStates <= "100";
|
TStates <= "100";
|
||||||
|
SetWZ <= "11";
|
||||||
when 3 =>
|
when 3 =>
|
||||||
NoRead <= '1';
|
NoRead <= '1';
|
||||||
ALU_Op <= "0011";
|
ALU_Op <= "0011";
|
||||||
@ -1849,46 +1829,49 @@ begin
|
|||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "01101111" =>
|
when "01101111" =>
|
||||||
-- RLD
|
-- RLD -- Read in M2, not M3! fixed by Sorgelig
|
||||||
MCycles <= "100";
|
MCycles <= "100";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 1 =>
|
||||||
NoRead <= '1';
|
|
||||||
Set_Addr_To <= aXY;
|
Set_Addr_To <= aXY;
|
||||||
when 3 =>
|
when 2 =>
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Set_BusB_To(2 downto 0) <= "110";
|
Set_BusB_To(2 downto 0) <= "110";
|
||||||
Set_BusA_To(2 downto 0) <= "111";
|
Set_BusA_To(2 downto 0) <= "111";
|
||||||
ALU_Op <= "1101";
|
ALU_Op <= "1101";
|
||||||
TStates <= "100";
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
when 4 =>
|
when 3 =>
|
||||||
|
TStates <= "100";
|
||||||
I_RLD <= '1';
|
I_RLD <= '1';
|
||||||
|
NoRead <= '1';
|
||||||
|
Set_Addr_To <= aXY;
|
||||||
|
when 4 =>
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "01100111" =>
|
when "01100111" =>
|
||||||
-- RRD
|
-- RRD -- Read in M2, not M3! fixed by Sorgelig
|
||||||
MCycles <= "100";
|
MCycles <= "100";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 2 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aXY;
|
Set_Addr_To <= aXY;
|
||||||
when 3 =>
|
when 2 =>
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Set_BusB_To(2 downto 0) <= "110";
|
Set_BusB_To(2 downto 0) <= "110";
|
||||||
Set_BusA_To(2 downto 0) <= "111";
|
Set_BusA_To(2 downto 0) <= "111";
|
||||||
ALU_Op <= "1110";
|
ALU_Op <= "1110";
|
||||||
TStates <= "100";
|
|
||||||
Set_Addr_To <= aXY;
|
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
when 4 =>
|
when 3 =>
|
||||||
|
TStates <= "100";
|
||||||
I_RRD <= '1';
|
I_RRD <= '1';
|
||||||
|
NoRead <= '1';
|
||||||
|
Set_Addr_To <= aXY;
|
||||||
|
when 4 =>
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" =>
|
when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" =>
|
||||||
-- RETI, RETN
|
-- RETI/RETN
|
||||||
MCycles <= "011";
|
MCycles <= "011";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
@ -1900,6 +1883,7 @@ begin
|
|||||||
when 3 =>
|
when 3 =>
|
||||||
Jump <= '1';
|
Jump <= '1';
|
||||||
IncDec_16 <= "0111";
|
IncDec_16 <= "0111";
|
||||||
|
LDW <= '1';
|
||||||
I_RETN <= '1';
|
I_RETN <= '1';
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
@ -1909,6 +1893,7 @@ begin
|
|||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
|
SetWZ <= "01";
|
||||||
when 2 =>
|
when 2 =>
|
||||||
IORQ <= '1';
|
IORQ <= '1';
|
||||||
if IR(5 downto 3) /= "110" then
|
if IR(5 downto 3) /= "110" then
|
||||||
@ -1925,6 +1910,7 @@ begin
|
|||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
|
SetWZ <= "01";
|
||||||
Set_BusB_To(2 downto 0) <= IR(5 downto 3);
|
Set_BusB_To(2 downto 0) <= IR(5 downto 3);
|
||||||
if IR(5 downto 3) = "110" then
|
if IR(5 downto 3) = "110" then
|
||||||
Set_BusB_To(3) <= '1';
|
Set_BusB_To(3) <= '1';
|
||||||
@ -1939,12 +1925,15 @@ begin
|
|||||||
MCycles <= "100";
|
MCycles <= "100";
|
||||||
case to_integer(unsigned(MCycle)) is
|
case to_integer(unsigned(MCycle)) is
|
||||||
when 1 =>
|
when 1 =>
|
||||||
|
TStates <= "101";
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
Set_BusB_To <= "1010";
|
Set_BusB_To <= "1010";
|
||||||
Set_BusA_To <= "0000";
|
Set_BusA_To <= "0000";
|
||||||
Read_To_Reg <= '1';
|
Read_To_Reg <= '1';
|
||||||
Save_ALU <= '1';
|
Save_ALU <= '1';
|
||||||
ALU_Op <= "0010";
|
ALU_Op <= "0010";
|
||||||
|
SetWZ <= "11";
|
||||||
|
IncDec_16(3) <= IR(3);
|
||||||
when 2 =>
|
when 2 =>
|
||||||
IORQ <= '1';
|
IORQ <= '1';
|
||||||
Set_BusB_To <= "0110";
|
Set_BusB_To <= "0110";
|
||||||
@ -1955,7 +1944,6 @@ begin
|
|||||||
else
|
else
|
||||||
IncDec_16 <= "1110";
|
IncDec_16 <= "1110";
|
||||||
end if;
|
end if;
|
||||||
TStates <= "100";
|
|
||||||
Write <= '1';
|
Write <= '1';
|
||||||
I_BTR <= '1';
|
I_BTR <= '1';
|
||||||
when 4 =>
|
when 4 =>
|
||||||
@ -1978,6 +1966,8 @@ begin
|
|||||||
when 2 =>
|
when 2 =>
|
||||||
Set_BusB_To <= "0110";
|
Set_BusB_To <= "0110";
|
||||||
Set_Addr_To <= aBC;
|
Set_Addr_To <= aBC;
|
||||||
|
SetWZ <= "11";
|
||||||
|
IncDec_16(3) <= IR(3);
|
||||||
when 3 =>
|
when 3 =>
|
||||||
if IR(3) = '0' then
|
if IR(3) = '0' then
|
||||||
IncDec_16 <= "0110";
|
IncDec_16 <= "0110";
|
||||||
|
@ -1,3 +1,23 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||||
|
-- accurate timings.
|
||||||
|
-- Version 350.
|
||||||
|
-- Copyright (c) 2018 Sorgelig
|
||||||
|
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
-- T80(b) core. In an effort to merge and maintain bug fixes ....
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
|
||||||
|
-- Ver 300 started tidyup
|
||||||
|
-- MikeJ March 2005
|
||||||
|
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
--
|
--
|
||||||
-- Z80 compatible microprocessor core
|
-- Z80 compatible microprocessor core
|
||||||
--
|
--
|
||||||
@ -53,7 +73,7 @@ package T80_Pack is
|
|||||||
component T80
|
component T80
|
||||||
generic(
|
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 := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
|
IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||||
Flag_C : integer := 0;
|
Flag_C : integer := 0;
|
||||||
Flag_N : integer := 1;
|
Flag_N : integer := 1;
|
||||||
Flag_P : integer := 2;
|
Flag_P : integer := 2;
|
||||||
@ -87,13 +107,7 @@ package T80_Pack is
|
|||||||
IntCycle_n : out std_logic;
|
IntCycle_n : out std_logic;
|
||||||
IntE : out std_logic;
|
IntE : out std_logic;
|
||||||
Stop : out std_logic;
|
Stop : out std_logic;
|
||||||
|
REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||||
SavePC : out std_logic_vector(15 downto 0);
|
|
||||||
SaveINT : out std_logic_vector(7 downto 0);
|
|
||||||
RestorePC : in std_logic_vector(15 downto 0);
|
|
||||||
RestoreINT : in std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
RestorePC_n : in std_logic
|
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
@ -113,7 +127,8 @@ package T80_Pack is
|
|||||||
DOBH : out std_logic_vector(7 downto 0);
|
DOBH : out std_logic_vector(7 downto 0);
|
||||||
DOBL : out std_logic_vector(7 downto 0);
|
DOBL : out std_logic_vector(7 downto 0);
|
||||||
DOCH : out std_logic_vector(7 downto 0);
|
DOCH : out std_logic_vector(7 downto 0);
|
||||||
DOCL : out std_logic_vector(7 downto 0)
|
DOCL : out std_logic_vector(7 downto 0);
|
||||||
|
DOR : out std_logic_vector(127 downto 0)
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
|
|
||||||
@ -178,6 +193,7 @@ package T80_Pack is
|
|||||||
I_RLD : out std_logic;
|
I_RLD : out std_logic;
|
||||||
I_RRD : out std_logic;
|
I_RRD : out std_logic;
|
||||||
I_INRC : out std_logic;
|
I_INRC : out std_logic;
|
||||||
|
SetWZ : out std_logic_vector(1 downto 0);
|
||||||
SetDI : out std_logic;
|
SetDI : out std_logic;
|
||||||
SetEI : out std_logic;
|
SetEI : out std_logic;
|
||||||
IMode : out std_logic_vector(1 downto 0);
|
IMode : out std_logic_vector(1 downto 0);
|
||||||
@ -203,6 +219,8 @@ package T80_Pack is
|
|||||||
port(
|
port(
|
||||||
Arith16 : in std_logic;
|
Arith16 : in std_logic;
|
||||||
Z16 : in std_logic;
|
Z16 : in std_logic;
|
||||||
|
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);
|
ALU_Op : in std_logic_vector(3 downto 0);
|
||||||
IR : in std_logic_vector(5 downto 0);
|
IR : in std_logic_vector(5 downto 0);
|
||||||
ISet : in std_logic_vector(1 downto 0);
|
ISet : in std_logic_vector(1 downto 0);
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- ****
|
||||||
|
-- T80(c) core. Attempt to finish all undocumented features and provide
|
||||||
|
-- accurate timings.
|
||||||
|
-- Version 350.
|
||||||
|
-- Copyright (c) 2018 Sorgelig
|
||||||
|
-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
|
||||||
|
-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
|
||||||
|
-- correct implementation is still unclear.
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
|
-- 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)
|
||||||
|
--
|
||||||
|
-- ****
|
||||||
--
|
--
|
||||||
-- T80 Registers, technology independent
|
-- T80 Registers, technology independent
|
||||||
--
|
--
|
||||||
@ -69,7 +88,8 @@ entity T80_Reg is
|
|||||||
DOBH : out std_logic_vector(7 downto 0);
|
DOBH : out std_logic_vector(7 downto 0);
|
||||||
DOBL : out std_logic_vector(7 downto 0);
|
DOBL : out std_logic_vector(7 downto 0);
|
||||||
DOCH : out std_logic_vector(7 downto 0);
|
DOCH : out std_logic_vector(7 downto 0);
|
||||||
DOCL : out std_logic_vector(7 downto 0)
|
DOCL : out std_logic_vector(7 downto 0);
|
||||||
|
DOR : out std_logic_vector(127 downto 0)
|
||||||
);
|
);
|
||||||
end T80_Reg;
|
end T80_Reg;
|
||||||
|
|
||||||
@ -83,7 +103,7 @@ begin
|
|||||||
|
|
||||||
process (Clk)
|
process (Clk)
|
||||||
begin
|
begin
|
||||||
if Clk'event and Clk = '1' then
|
if rising_edge(Clk) then
|
||||||
if CEN = '1' then
|
if CEN = '1' then
|
||||||
if WEH = '1' then
|
if WEH = '1' then
|
||||||
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
RegsH(to_integer(unsigned(AddrA))) <= DIH;
|
||||||
@ -101,5 +121,6 @@ begin
|
|||||||
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
DOBL <= RegsL(to_integer(unsigned(AddrB)));
|
||||||
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
DOCH <= RegsH(to_integer(unsigned(AddrC)));
|
||||||
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
DOCL <= RegsL(to_integer(unsigned(AddrC)));
|
||||||
|
DOR <= RegsH(7) & RegsL(7) & RegsH(6) & RegsL(6) & RegsH(5) & RegsL(5) & RegsH(4) & RegsL(4) & RegsH(3) & RegsL(3) & RegsH(2) & RegsL(2) & RegsH(1) & RegsL(1) & RegsH(0) & RegsL(0);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
268
src/t80/T80a.vhd
268
src/t80/T80a.vhd
@ -1,268 +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;
|
|
||||||
A : out std_logic_vector(15 downto 0);
|
|
||||||
D : inout std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
SavePC : out std_logic_vector(15 downto 0);
|
|
||||||
SaveINT : out std_logic_vector(7 downto 0);
|
|
||||||
RestorePC : in std_logic_vector(15 downto 0);
|
|
||||||
RestoreINT : in std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
RestorePC_n : in std_logic
|
|
||||||
|
|
||||||
);
|
|
||||||
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,
|
|
||||||
CLK_n => CLK_n,
|
|
||||||
A => A_i,
|
|
||||||
DInst => D,
|
|
||||||
DI => DI_Reg,
|
|
||||||
DO => DO,
|
|
||||||
MC => MCycle,
|
|
||||||
TS => TState,
|
|
||||||
IntCycle_n => IntCycle_n,
|
|
||||||
|
|
||||||
SavePC => SavePC,
|
|
||||||
SaveINT => SaveINT,
|
|
||||||
RestorePC => RestorePC,
|
|
||||||
RestoreINT => RestoreINT,
|
|
||||||
|
|
||||||
RestorePC_n => RestorePC_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;
|
|
211
src/t80/T80pa.vhd
Normal file
211
src/t80/T80pa.vhd
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
--
|
||||||
|
-- Z80 compatible microprocessor core, preudo-asynchronous top level (by Sorgelig)
|
||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
-- File history :
|
||||||
|
--
|
||||||
|
-- v1.0: convert to preudo-asynchronous model with original Z80 timings.
|
||||||
|
--
|
||||||
|
-- v2.0: rewritten for more precise timings.
|
||||||
|
-- support for both CEN_n and CEN_p set to 1. Effective clock will be CLK/2.
|
||||||
|
--
|
||||||
|
-- v2.1: Output Address 0 during non-bus MCycle (fix ZX contention)
|
||||||
|
--
|
||||||
|
-- v2.2: Interrupt acknowledge cycle has been corrected
|
||||||
|
-- WAIT_n is broken in T80.vhd. Simulate correct WAIT_n locally.
|
||||||
|
--
|
||||||
|
-- v2.3: Output last used Address during non-bus MCycle seems more correct.
|
||||||
|
--
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
use work.T80_Pack.all;
|
||||||
|
|
||||||
|
entity T80pa is
|
||||||
|
generic(
|
||||||
|
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
RESET_n : in std_logic;
|
||||||
|
CLK : in std_logic;
|
||||||
|
CEN_p : in std_logic := '1';
|
||||||
|
CEN_n : in std_logic := '1';
|
||||||
|
WAIT_n : in std_logic := '1';
|
||||||
|
INT_n : in std_logic := '1';
|
||||||
|
NMI_n : in std_logic := '1';
|
||||||
|
BUSRQ_n : in std_logic := '1';
|
||||||
|
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;
|
||||||
|
A : out std_logic_vector(15 downto 0);
|
||||||
|
DI : in std_logic_vector(7 downto 0);
|
||||||
|
DO : out std_logic_vector(7 downto 0);
|
||||||
|
REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
|
||||||
|
);
|
||||||
|
end T80pa;
|
||||||
|
|
||||||
|
architecture rtl of T80pa is
|
||||||
|
|
||||||
|
signal IntCycle_n : std_logic;
|
||||||
|
signal IntCycleD_n : std_logic_vector(1 downto 0);
|
||||||
|
signal IORQ : std_logic;
|
||||||
|
signal NoRead : std_logic;
|
||||||
|
signal Write : std_logic;
|
||||||
|
signal BUSAK : std_logic;
|
||||||
|
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
|
||||||
|
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);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
A <= A_int when NoRead = '0' or Write = '1' else A_last;
|
||||||
|
|
||||||
|
BUSAK_n <= BUSAK;
|
||||||
|
|
||||||
|
u0 : T80
|
||||||
|
generic map(
|
||||||
|
Mode => Mode,
|
||||||
|
IOWait => 1
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
CEN => CEN_p and not CEN_pol,
|
||||||
|
M1_n => M1_n,
|
||||||
|
IORQ => IORQ,
|
||||||
|
NoRead => NoRead,
|
||||||
|
Write => Write,
|
||||||
|
RFSH_n => RFSH_n,
|
||||||
|
HALT_n => HALT_n,
|
||||||
|
WAIT_n => '1',
|
||||||
|
INT_n => INT_n,
|
||||||
|
NMI_n => NMI_n,
|
||||||
|
RESET_n => RESET_n,
|
||||||
|
BUSRQ_n => BUSRQ_n,
|
||||||
|
BUSAK_n => BUSAK,
|
||||||
|
CLK_n => CLK,
|
||||||
|
A => A_int,
|
||||||
|
DInst => DI, -- valid at beginning of T3
|
||||||
|
DI => DI_Reg, -- latched at middle of T3
|
||||||
|
DO => DO,
|
||||||
|
REG => REG,
|
||||||
|
MC => MCycle,
|
||||||
|
TS => TState,
|
||||||
|
IntCycle_n => IntCycle_n
|
||||||
|
);
|
||||||
|
|
||||||
|
process(CLK)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK) then
|
||||||
|
if RESET_n = '0' then
|
||||||
|
WR_n <= '1';
|
||||||
|
RD_n <= '1';
|
||||||
|
IORQ_n <= '1';
|
||||||
|
MREQ_n <= '1';
|
||||||
|
DI_Reg <= "00000000";
|
||||||
|
CEN_pol <= '0';
|
||||||
|
elsif CEN_p = '1' and CEN_pol = '0' then
|
||||||
|
CEN_pol <= '1';
|
||||||
|
if MCycle = "001" then
|
||||||
|
if TState = "010" then
|
||||||
|
IORQ_n <= '1';
|
||||||
|
MREQ_n <= '1';
|
||||||
|
RD_n <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if TState = "001" and IORQ = '1' then
|
||||||
|
WR_n <= not Write;
|
||||||
|
RD_n <= Write;
|
||||||
|
IORQ_n <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
elsif CEN_n = '1' and CEN_pol = '1' then
|
||||||
|
if TState = "010" then
|
||||||
|
CEN_pol <= not WAIT_n;
|
||||||
|
else
|
||||||
|
CEN_pol <= '0';
|
||||||
|
end if;
|
||||||
|
if TState = "011" and BUSAK = '1' then
|
||||||
|
DI_Reg <= DI;
|
||||||
|
end if;
|
||||||
|
if MCycle = "001" then
|
||||||
|
if TState = "001" then
|
||||||
|
IntCycleD_n <= IntCycleD_n(0) & IntCycle_n;
|
||||||
|
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";
|
||||||
|
RD_n <= '1';
|
||||||
|
MREQ_n <= '0';
|
||||||
|
end if;
|
||||||
|
if TState = "100" then
|
||||||
|
MREQ_n <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if NoRead = '0' and IORQ = '0' then
|
||||||
|
if TState = "001" then
|
||||||
|
RD_n <= Write;
|
||||||
|
MREQ_n <= '0';
|
||||||
|
A_last <= A_int;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if TState = "010" then
|
||||||
|
WR_n <= not Write;
|
||||||
|
end if;
|
||||||
|
if TState = "011" then
|
||||||
|
WR_n <= '1';
|
||||||
|
RD_n <= '1';
|
||||||
|
IORQ_n <= '1';
|
||||||
|
MREQ_n <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
end;
|
@ -79,11 +79,11 @@ entity T80s is
|
|||||||
port(
|
port(
|
||||||
RESET_n : in std_logic;
|
RESET_n : in std_logic;
|
||||||
CLK_n : in std_logic;
|
CLK_n : in std_logic;
|
||||||
CEN : in std_logic;
|
CEN : in std_logic := '1';
|
||||||
WAIT_n : in std_logic;
|
WAIT_n : in std_logic := '1';
|
||||||
INT_n : in std_logic;
|
INT_n : in std_logic := '1';
|
||||||
NMI_n : in std_logic;
|
NMI_n : in std_logic := '1';
|
||||||
BUSRQ_n : in std_logic;
|
BUSRQ_n : in std_logic := '1';
|
||||||
M1_n : out std_logic;
|
M1_n : out std_logic;
|
||||||
MREQ_n : out std_logic;
|
MREQ_n : out std_logic;
|
||||||
IORQ_n : out std_logic;
|
IORQ_n : out std_logic;
|
||||||
@ -135,14 +135,8 @@ begin
|
|||||||
DO => DO,
|
DO => DO,
|
||||||
MC => MCycle,
|
MC => MCycle,
|
||||||
TS => TState,
|
TS => TState,
|
||||||
IntCycle_n => IntCycle_n,
|
IntCycle_n => IntCycle_n
|
||||||
|
);
|
||||||
SavePC => open,
|
|
||||||
SaveINT => open,
|
|
||||||
RestorePC => (others => '1'),
|
|
||||||
RestoreINT => (others => '1'),
|
|
||||||
|
|
||||||
RestorePC_n => '1' );
|
|
||||||
|
|
||||||
process (RESET_n, CLK_n)
|
process (RESET_n, CLK_n)
|
||||||
begin
|
begin
|
||||||
@ -152,7 +146,7 @@ begin
|
|||||||
IORQ_n <= '1';
|
IORQ_n <= '1';
|
||||||
MREQ_n <= '1';
|
MREQ_n <= '1';
|
||||||
DI_Reg <= "00000000";
|
DI_Reg <= "00000000";
|
||||||
elsif CLK_n'event and CLK_n = '1' then
|
elsif rising_edge(CLK_n) then
|
||||||
if CEN = '1' then
|
if CEN = '1' then
|
||||||
RD_n <= '1';
|
RD_n <= '1';
|
||||||
WR_n <= '1';
|
WR_n <= '1';
|
||||||
@ -193,5 +187,4 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
@ -1,200 +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 := 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;
|
|
||||||
A : out std_logic_vector(15 downto 0);
|
|
||||||
DI : in std_logic_vector(7 downto 0);
|
|
||||||
DO : out std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
SavePC : out std_logic_vector(15 downto 0);
|
|
||||||
SaveINT : out std_logic_vector(7 downto 0);
|
|
||||||
RestorePC : in std_logic_vector(15 downto 0);
|
|
||||||
RestoreINT : in std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
RestorePC_n : in std_logic
|
|
||||||
);
|
|
||||||
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,
|
|
||||||
CLK_n => CLK_n,
|
|
||||||
A => A,
|
|
||||||
DInst => DI,
|
|
||||||
DI => DI_Reg,
|
|
||||||
DO => DO,
|
|
||||||
MC => MCycle,
|
|
||||||
TS => TState,
|
|
||||||
IntCycle_n => IntCycle_n,
|
|
||||||
|
|
||||||
SavePC => SavePC,
|
|
||||||
SaveINT => SaveINT,
|
|
||||||
RestorePC => RestorePC,
|
|
||||||
RestoreINT => RestoreINT,
|
|
||||||
|
|
||||||
RestorePC_n => RestorePC_n );
|
|
||||||
|
|
||||||
|
|
||||||
process (CLK_n)
|
|
||||||
begin
|
|
||||||
if CLK_n'event and CLK_n = '1' then
|
|
||||||
if RESET_n = '0' then
|
|
||||||
RD_n <= '1';
|
|
||||||
WR_n <= '1';
|
|
||||||
IORQ_n <= '1';
|
|
||||||
MREQ_n <= '1';
|
|
||||||
DI_Reg <= "00000000";
|
|
||||||
elsif 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" 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 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 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;
|
|
30
src/tsconf.v
30
src/tsconf.v
@ -329,24 +329,20 @@ zclock TS02
|
|||||||
.turbo(turbo)
|
.turbo(turbo)
|
||||||
);
|
);
|
||||||
|
|
||||||
T80s #(.mode(0), .t2write(1), .iowait(1)) z80_unit
|
T80s CPU
|
||||||
(
|
(
|
||||||
.reset_n((~reset)),
|
.RESET_n(~reset),
|
||||||
.clk_n(zclk),
|
.CLK_n(zclk),
|
||||||
.cen(1),
|
.INT_n(cpu_int_n_TS),
|
||||||
.wait_n(1),
|
.M1_n(cpu_m1_n),
|
||||||
.int_n(cpu_int_n_TS),
|
.MREQ_n(cpu_mreq_n),
|
||||||
.nmi_n(1),
|
.IORQ_n(cpu_iorq_n),
|
||||||
.busrq_n(1),
|
.RD_n(cpu_rd_n),
|
||||||
.m1_n(cpu_m1_n),
|
.WR_n(cpu_wr_n),
|
||||||
.mreq_n(cpu_mreq_n),
|
.RFSH_n(cpu_rfsh_n),
|
||||||
.iorq_n(cpu_iorq_n),
|
.A(cpu_a_bus),
|
||||||
.rd_n(cpu_rd_n),
|
.DI(cpu_di_bus),
|
||||||
.wr_n(cpu_wr_n),
|
.DO(cpu_do_bus)
|
||||||
.rfsh_n(cpu_rfsh_n),
|
|
||||||
.a(cpu_a_bus),
|
|
||||||
.di(cpu_di_bus),
|
|
||||||
.do(cpu_do_bus)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
zsignals TS04
|
zsignals TS04
|
||||||
|
Reference in New Issue
Block a user