Line 19... |
Line 19... |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
|
-- --
|
-- --
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
|
-- 10.11.2019 TG inset TRAPcc
|
|
-- 08.11.2019 TG bugfix movem in 68020 mode
|
|
-- 06.11.2019 TG bugfix CHK
|
|
-- 06.11.2019 TG bugfix flags and stackframe DIVU
|
-- 04.11.2019 TG insert RTE from TH
|
-- 04.11.2019 TG insert RTE from TH
|
-- 03.11.2019 TG insert TrapV from TH
|
-- 03.11.2019 TG insert TrapV from TH
|
-- 03.11.2019 TG bugfix MUL 64Bit
|
-- 03.11.2019 TG bugfix MUL 64Bit
|
-- 03.11.2019 TG rework barrel shifter - some other tweaks
|
-- 03.11.2019 TG rework barrel shifter - some other tweaks
|
-- 02.11.2019 TG bugfig N-Flag and Z-Flag for DIV
|
-- 02.11.2019 TG bugfig N-Flag and Z-Flag for DIV
|
Line 63... |
Line 67... |
|
|
-- CAS, CAS2
|
-- CAS, CAS2
|
-- CHK2
|
-- CHK2
|
-- CMP2
|
-- CMP2
|
-- cpXXX Coprozessor stuff
|
-- cpXXX Coprozessor stuff
|
-- TRAPcc
|
|
|
|
-- done 020:
|
-- done 020:
|
|
-- TRAPcc
|
-- PACK
|
-- PACK
|
-- UNPK
|
-- UNPK
|
-- Bitfields
|
-- Bitfields
|
-- address modes
|
-- address modes
|
-- long bra
|
-- long bra
|
Line 83... |
Line 87... |
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use work.TG68K_Pack.all;
|
use work.TG68K_Pack.all;
|
|
|
entity TG68KdotC_Kernel is
|
entity TG68KdotC_Kernel is
|
generic(
|
generic(
|
SR_Read : integer:= 1; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
SR_Read : integer:= 2; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
VBR_Stackframe : integer:= 1; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
|
VBR_Stackframe : integer:= 2; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
|
extAddr_Mode : integer:= 1; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
extAddr_Mode : integer:= 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
MUL_Mode : integer := 1; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
MUL_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
MUL_Hardware : integer := 0; --0=>no, 1=>yes,
|
DIV_Mode : integer := 2; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
|
DIV_Mode : integer := 1; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
|
BitField : integer := 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
BarrelShifter : integer := 2; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
|
BitField : integer := 1 --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
BarrelShifter : integer := 1; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
-- SR_Read : integer:= 0; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
MUL_Hardware : integer := 1 --0=>no, 1=>yes,
|
-- VBR_Stackframe : integer:= 0; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
|
|
-- extAddr_Mode : integer:= 0; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
|
-- MUL_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
|
-- MUL_Hardware : integer := 1; --0=>no, 1=>yes,
|
|
-- DIV_Mode : integer := 0; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no DIV,
|
|
-- BarrelShifter : integer := 0; --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
|
-- BitField : integer := 0 --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
|
);
|
);
|
port(clk : in std_logic;
|
port(clk : in std_logic;
|
nReset : in std_logic; --low active
|
nReset : in std_logic; --low active
|
clkena_in : in std_logic:='1';
|
clkena_in : in std_logic:='1';
|
data_in : in std_logic_vector(15 downto 0);
|
data_in : in std_logic_vector(15 downto 0);
|
Line 128... |
Line 125... |
end TG68KdotC_Kernel;
|
end TG68KdotC_Kernel;
|
|
|
architecture logic of TG68KdotC_Kernel is
|
architecture logic of TG68KdotC_Kernel is
|
|
|
|
|
|
signal use_VBR_Stackframe : std_logic;
|
|
|
signal syncReset : std_logic_vector(3 downto 0);
|
signal syncReset : std_logic_vector(3 downto 0);
|
signal Reset : std_logic;
|
signal Reset : std_logic;
|
signal clkena_lw : std_logic;
|
signal clkena_lw : std_logic;
|
signal TG68_PC : std_logic_vector(31 downto 0);
|
signal TG68_PC : std_logic_vector(31 downto 0);
|
signal tmp_TG68_PC : std_logic_vector(31 downto 0);
|
signal tmp_TG68_PC : std_logic_vector(31 downto 0);
|
Line 255... |
Line 254... |
signal trap_trace : bit;
|
signal trap_trace : bit;
|
signal trap_1010 : bit;
|
signal trap_1010 : bit;
|
signal trap_1111 : bit;
|
signal trap_1111 : bit;
|
signal trap_trap : bit;
|
signal trap_trap : bit;
|
signal trap_trapv : bit;
|
signal trap_trapv : bit;
|
|
signal trap_trapcc : bit;
|
signal trap_interrupt : bit;
|
signal trap_interrupt : bit;
|
signal trapmake : bit;
|
signal trapmake : bit;
|
signal trapd : bit;
|
signal trapd : bit;
|
signal trap_SR : std_logic_vector(7 downto 0);
|
signal trap_SR : std_logic_vector(7 downto 0);
|
signal make_trace : std_logic;
|
signal make_trace : std_logic;
|
signal make_berr : std_logic;
|
signal make_berr : std_logic;
|
|
signal useStackframe2 : std_logic;
|
|
|
signal set_stop : bit;
|
signal set_stop : bit;
|
signal stop : bit;
|
signal stop : bit;
|
signal trap_vector : std_logic_vector(31 downto 0);
|
signal trap_vector : std_logic_vector(31 downto 0);
|
signal trap_vector_vbr : std_logic_vector(31 downto 0);
|
signal trap_vector_vbr : std_logic_vector(31 downto 0);
|
Line 423... |
Line 424... |
IF clkena_in='1' THEN
|
IF clkena_in='1' THEN
|
syncReset <= syncReset(2 downto 0)&'1';
|
syncReset <= syncReset(2 downto 0)&'1';
|
Reset <= NOT syncReset(3);
|
Reset <= NOT syncReset(3);
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
IF rising_edge(clk) THEN
|
|
IF VBR_Stackframe=1 or (cpu(0)='1' and VBR_Stackframe=2) THEN
|
|
use_VBR_Stackframe<='1';
|
|
ELSE
|
|
use_VBR_Stackframe<='0';
|
|
END IF;
|
|
END IF;
|
END PROCESS;
|
END PROCESS;
|
|
|
PROCESS (clk, long_done, last_data_in, data_in, addr, long_start, memmaskmux, memread, memmask, data_read)
|
PROCESS (clk, long_done, last_data_in, data_in, addr, long_start, memmaskmux, memread, memmask, data_read)
|
BEGIN
|
BEGIN
|
IF memmaskmux(4)='0' THEN
|
IF memmaskmux(4)='0' THEN
|
Line 687... |
Line 695... |
exec_write_back <= '0';
|
exec_write_back <= '0';
|
direct_data <= '0';
|
direct_data <= '0';
|
use_direct_data <= '0';
|
use_direct_data <= '0';
|
Z_error <= '0';
|
Z_error <= '0';
|
ELSIF clkena_lw='1' THEN
|
ELSIF clkena_lw='1' THEN
|
|
useStackframe2<='0';
|
direct_data <= '0';
|
direct_data <= '0';
|
IF state="11" THEN
|
IF state="11" THEN
|
exec_write_back <= '0';
|
exec_write_back <= '0';
|
ELSIF setstate="10" AND write_back='1' THEN
|
ELSIF setstate="10" AND write_back='1' THEN
|
-- elsif setstate = "10" and write_back = '1' and next_micro_state = idle then --???
|
-- ELSIF setstate = "10" AND write_back = '1' AND next_micro_state = idle THEN --this shut be a fix for pinball
|
|
-- --but it destory pack -(ax),-(ay) and unpack
|
exec_write_back <= '1';
|
exec_write_back <= '1';
|
END IF;
|
END IF;
|
|
|
IF exec(hold_OP2)='1' THEN
|
IF exec(hold_OP2)='1' THEN
|
use_direct_data <= '1';
|
use_direct_data <= '1';
|
Line 740... |
Line 750... |
ELSIF exec(writePC_add)='1' THEN
|
ELSIF exec(writePC_add)='1' THEN
|
data_write_tmp <= TG68_PC_add;
|
data_write_tmp <= TG68_PC_add;
|
-- paste and copy form TH ---------
|
-- paste and copy form TH ---------
|
elsif micro_state=trap00 THEN
|
elsif micro_state=trap00 THEN
|
data_write_tmp <= exe_pc; --TH
|
data_write_tmp <= exe_pc; --TH
|
|
useStackframe2<='1';
|
elsif micro_state = trap0 then
|
elsif micro_state = trap0 then
|
-- this is only active for 010+ since in 000 writePC is
|
-- this is only active for 010+ since in 000 writePC is
|
-- true in state trap0
|
-- true in state trap0
|
if trap_trace='1' or set_exec(opcTRAPV) = '1' then
|
-- if trap_trace='1' or set_exec(opcTRAPV)='1' or Z_error='1' then
|
|
IF useStackframe2='1' THEN
|
-- stack frame format #2
|
-- stack frame format #2
|
data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
|
data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
|
else
|
else
|
data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
|
data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
|
end if;
|
end if;
|
Line 804... |
Line 816... |
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- MEM_IO
|
-- MEM_IO
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatype, interrupt, rIPL_nr, IPL_vec,
|
PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatype, interrupt, rIPL_nr, IPL_vec,
|
memaddr_reg, reg_QA, use_base, VBR, last_data_read, trap_vector, exec, set, cpu)
|
memaddr_reg, reg_QA, use_base, VBR, last_data_read, trap_vector, exec, set, cpu, use_VBR_Stackframe)
|
BEGIN
|
BEGIN
|
|
|
IF rising_edge(clk) THEN
|
IF rising_edge(clk) THEN
|
IF clkena_lw='1' THEN
|
IF clkena_lw='1' THEN
|
trap_vector(31 downto 10) <= (others => '0');
|
trap_vector(31 downto 10) <= (others => '0');
|
Line 819... |
Line 831... |
trap_vector(9 downto 0) <= "00" & X"0C";
|
trap_vector(9 downto 0) <= "00" & X"0C";
|
END IF;
|
END IF;
|
IF trap_illegal='1' THEN
|
IF trap_illegal='1' THEN
|
trap_vector(9 downto 0) <= "00" & X"10";
|
trap_vector(9 downto 0) <= "00" & X"10";
|
END IF;
|
END IF;
|
IF z_error='1' THEN
|
IF set_Z_error='1' THEN
|
trap_vector(9 downto 0) <= "00" & X"14";
|
trap_vector(9 downto 0) <= "00" & X"14";
|
END IF;
|
END IF;
|
IF exec(trap_chk)='1' THEN
|
IF exec(trap_chk)='1' THEN
|
trap_vector(9 downto 0) <= "00" & X"18";
|
trap_vector(9 downto 0) <= "00" & X"18";
|
END IF;
|
END IF;
|
Line 848... |
Line 860... |
IF trap_interrupt='1' or set_vectoraddr = '1' THEN
|
IF trap_interrupt='1' or set_vectoraddr = '1' THEN
|
trap_vector(9 downto 0) <= IPL_vec & "00"; --TH
|
trap_vector(9 downto 0) <= IPL_vec & "00"; --TH
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN
|
IF use_VBR_Stackframe='1' THEN
|
trap_vector_vbr <= trap_vector;
|
|
ELSE
|
|
trap_vector_vbr <= trap_vector+VBR;
|
trap_vector_vbr <= trap_vector+VBR;
|
|
ELSE
|
|
trap_vector_vbr <= trap_vector;
|
END IF;
|
END IF;
|
|
|
memaddr_a(4 downto 0) <= "00000";
|
memaddr_a(4 downto 0) <= "00000";
|
memaddr_a(7 downto 5) <= (OTHERS=>memaddr_a(4));
|
memaddr_a(7 downto 5) <= (OTHERS=>memaddr_a(4));
|
memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7));
|
memaddr_a(15 downto 8) <= (OTHERS=>memaddr_a(7));
|
Line 931... |
Line 943... |
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- PC Calc + fetch opcode
|
-- PC Calc + fetch opcode
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec,
|
PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec,
|
PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, interrupt, tmp_TG68_PC, TG68_PC)
|
PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, trap_trapcc, interrupt, tmp_TG68_PC, TG68_PC)
|
BEGIN
|
BEGIN
|
|
|
PC_dataa <= TG68_PC;
|
PC_dataa <= TG68_PC;
|
IF TG68_PC_brw = '1' THEN
|
IF TG68_PC_brw = '1' THEN
|
PC_dataa <= tmp_TG68_PC;
|
PC_dataa <= tmp_TG68_PC;
|
Line 1130... |
Line 1142... |
writePCbig <= set_writePCbig OR writePCbig;
|
writePCbig <= set_writePCbig OR writePCbig;
|
END IF;
|
END IF;
|
IF decodeOPC='1' OR exec(ld_rot_cnt)='1' OR rot_cnt/="000001" THEN
|
IF decodeOPC='1' OR exec(ld_rot_cnt)='1' OR rot_cnt/="000001" THEN
|
rot_cnt <= set_rot_cnt;
|
rot_cnt <= set_rot_cnt;
|
END IF;
|
END IF;
|
-- IF setstate(1)='1' AND set_datatype="00" THEN
|
|
-- byte <= '1';
|
|
-- END IF;
|
|
|
|
IF set_Suppress_Base='1' THEN
|
IF set_Suppress_Base='1' THEN
|
Suppress_Base <= '1';
|
Suppress_Base <= '1';
|
ELSIF setstate(1)='1' OR (ea_only='1' AND set(get_ea_now)='1') THEN
|
ELSIF setstate(1)='1' OR (ea_only='1' AND set(get_ea_now)='1') THEN
|
Suppress_Base <= '0';
|
Suppress_Base <= '0';
|
Line 1166... |
Line 1175... |
IF setnextpass='1' OR regdirectsource='1' THEN
|
IF setnextpass='1' OR regdirectsource='1' THEN
|
nextpass <= '1';
|
nextpass <= '1';
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
|
-- why do not I need this ??? What are the immediate data for ???
|
|
-- IF trap_trapcc='1' THEN
|
|
-- IF opcode(2 downto 0)="100" THEN
|
|
-- exe_pc <= (others => '0');
|
|
-- ELSE
|
|
-- exe_pc <= last_data_read;
|
|
-- END IF;
|
|
-- END IF;
|
|
|
IF decodeOPC='1' OR interrupt='1' THEN
|
IF decodeOPC='1' OR interrupt='1' THEN
|
trap_SR <= FlagsSR;
|
trap_SR <= FlagsSR;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
Line 1335... |
Line 1353... |
-- decode opcode
|
-- decode opcode
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, decodeOPC, state, setexecOPC, Flags, FlagsSR, direct_data, build_logical,
|
PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, decodeOPC, state, setexecOPC, Flags, FlagsSR, direct_data, build_logical,
|
build_bcd, set_Z_error, trapd, movem_run, last_data_read, set, set_V_Flag, z_error, trap_trace, trap_interrupt,
|
build_bcd, set_Z_error, trapd, movem_run, last_data_read, set, set_V_Flag, z_error, trap_trace, trap_interrupt,
|
SVmode, preSVmode, stop, long_done, ea_only, setstate, execOPC, exec_write_back, exe_datatype,
|
SVmode, preSVmode, stop, long_done, ea_only, setstate, execOPC, exec_write_back, exe_datatype,
|
datatype, interrupt, c_out, trapmake, rot_cnt, brief, addr, trap_trapv, last_data_in,
|
datatype, interrupt, c_out, trapmake, rot_cnt, brief, addr, trap_trapv, trap_trapcc, last_data_in, use_VBR_Stackframe,
|
long_start, set_datatype, sndOPC, set_exec, exec, ea_build_now, reg_QA, reg_QB, make_berr, trap_berr)
|
long_start, set_datatype, sndOPC, set_exec, exec, ea_build_now, reg_QA, reg_QB, make_berr, trap_berr)
|
BEGIN
|
BEGIN
|
TG68_PC_brw <= '0';
|
TG68_PC_brw <= '0';
|
setstate <= "00";
|
setstate <= "00";
|
Regwrena_now <= '0';
|
Regwrena_now <= '0';
|
Line 1372... |
Line 1390... |
trap_priv <='0';
|
trap_priv <='0';
|
trap_1010 <='0';
|
trap_1010 <='0';
|
trap_1111 <='0';
|
trap_1111 <='0';
|
trap_trap <='0';
|
trap_trap <='0';
|
trap_trapv <= '0';
|
trap_trapv <= '0';
|
|
trap_trapcc <= '0';
|
trapmake <='0';
|
trapmake <='0';
|
set_vectoraddr <='0';
|
set_vectoraddr <='0';
|
writeSR <= '0';
|
writeSR <= '0';
|
set_stop <= '0';
|
set_stop <= '0';
|
-- illegal_write_mode <= '0';
|
-- illegal_write_mode <= '0';
|
Line 1408... |
Line 1427... |
WHEN "00" => datatype <= "00"; --Byte
|
WHEN "00" => datatype <= "00"; --Byte
|
WHEN "01" => datatype <= "01"; --Word
|
WHEN "01" => datatype <= "01"; --Word
|
WHEN OTHERS => datatype <= "10"; --Long
|
WHEN OTHERS => datatype <= "10"; --Long
|
END CASE;
|
END CASE;
|
|
|
|
IF interrupt='1' AND trap_berr='1' THEN
|
|
next_micro_state <= trap0;
|
|
IF preSVmode='0' THEN
|
|
set(changeMode) <= '1';
|
|
END IF;
|
|
setstate <= "01";
|
|
END IF;
|
IF trapmake='1' AND trapd='0' THEN
|
IF trapmake='1' AND trapd='0' THEN
|
-- paste and copy form TH ---------
|
IF use_VBR_Stackframe='1' AND (trap_trapv='1' OR set_Z_error='1' OR exec(opcCHK)='1') THEN
|
if trap_trapv = '1' and (VBR_Stackframe = 1 or (cpu(0) = '1' and VBR_Stackframe = 2)) then
|
|
next_micro_state <= trap00;
|
next_micro_state <= trap00;
|
else
|
else
|
next_micro_state <= trap0;
|
next_micro_state <= trap0;
|
end if;
|
end if;
|
------------------------------------
|
IF use_VBR_Stackframe='0' THEN
|
-- next_micro_state <= trap0;
|
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN
|
|
set(writePC_add) <= '1';
|
set(writePC_add) <= '1';
|
-- set_datatype <= "10";
|
-- set_datatype <= "10";
|
END IF;
|
END IF;
|
IF preSVmode='0' THEN
|
IF preSVmode='0' THEN
|
set(changeMode) <= '1';
|
set(changeMode) <= '1';
|
END IF;
|
END IF;
|
setstate <= "01";
|
setstate <= "01";
|
END IF;
|
END IF;
|
IF interrupt='1' AND trap_berr='1' THEN
|
|
next_micro_state <= trap0;
|
|
IF preSVmode='0' THEN
|
|
set(changeMode) <= '1';
|
|
END IF;
|
|
setstate <= "01";
|
|
END IF;
|
|
IF micro_state=int1 OR (interrupt='1' AND trap_trace='1') THEN
|
IF micro_state=int1 OR (interrupt='1' AND trap_trace='1') THEN
|
-- paste and copy form TH ---------
|
-- paste and copy form TH ---------
|
if trap_trace='1' AND (VBR_Stackframe=1 or (cpu(0)='1' AND VBR_Stackframe=2)) then
|
if trap_trace='1' AND use_VBR_Stackframe='1' then
|
next_micro_state <= trap00; --TH
|
next_micro_state <= trap00; --TH
|
else
|
else
|
next_micro_state <= trap0;
|
next_micro_state <= trap0;
|
end if;
|
end if;
|
------------------------------------
|
------------------------------------
|
Line 1451... |
Line 1467... |
set(changeMode) <= '1';
|
set(changeMode) <= '1';
|
END IF;
|
END IF;
|
setstate <= "01";
|
setstate <= "01";
|
END IF;
|
END IF;
|
if micro_state = int1 or (interrupt = '1' and trap_trace = '1') then
|
if micro_state = int1 or (interrupt = '1' and trap_trace = '1') then
|
if trap_trace='1' AND (VBR_Stackframe=1 or (cpu(0)='1' AND VBR_Stackframe=2)) then
|
|
next_micro_state <= trap00; --TH
|
|
else
|
|
next_micro_state <= trap0;
|
|
end if;
|
|
-- if cpu(0)='0' then
|
|
-- set_datatype <= "10";
|
|
-- end if;
|
|
if preSVmode = '0' then
|
if preSVmode = '0' then
|
set(changeMode) <= '1';
|
set(changeMode) <= '1';
|
end if;
|
end if;
|
setstate <= "01";
|
setstate <= "01";
|
end if;
|
end if;
|
Line 1781... |
Line 1789... |
trapmake <= '1';
|
trapmake <= '1';
|
END IF;
|
END IF;
|
ELSIF cpu(1)='1' THEN --chk long for 68020
|
ELSIF cpu(1)='1' THEN --chk long for 68020
|
datatype <= "10"; --Long
|
datatype <= "10"; --Long
|
set(trap_chk) <= '1';
|
set(trap_chk) <= '1';
|
IF (c_out(2)='1' OR OP1out(31)='1' OR OP2out(31)='1') AND exec(opcCHK)='1' THEN
|
IF (c_out(2)='0' OR OP1out(31)='1' OR OP2out(31)='1') AND exec(opcCHK)='1' THEN
|
trapmake <= '1';
|
trapmake <= '1';
|
END IF;
|
END IF;
|
ELSE
|
ELSE
|
trap_illegal <= '1'; -- chk long for 68020
|
trap_illegal <= '1'; -- chk long for 68020
|
trapmake <= '1';
|
trapmake <= '1';
|
Line 2280... |
Line 2288... |
set(directPC) <= '1';
|
set(directPC) <= '1';
|
next_micro_state <= nopnop;
|
next_micro_state <= nopnop;
|
END IF;
|
END IF;
|
|
|
WHEN "1110110" => --trapv
|
WHEN "1110110" => --trapv
|
set_exec(opcTRAPV) <= '1'; --TH
|
|
IF decodeOPC='1' THEN
|
IF decodeOPC='1' THEN
|
setstate <= "01";
|
setstate <= "01";
|
END IF;
|
END IF;
|
IF Flags(1)='1' AND state="01" THEN
|
IF Flags(1)='1' AND state="01" THEN
|
trap_trapv <= '1';
|
trap_trapv <= '1';
|
trapmake <= '1';
|
trapmake <= '1';
|
END IF;
|
END IF;
|
|
|
WHEN "1111010"|"1111011" => --movec
|
WHEN "1111010"|"1111011" => --movec
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN
|
IF cpu="00" THEN
|
trap_illegal <= '1';
|
trap_illegal <= '1';
|
trapmake <= '1';
|
trapmake <= '1';
|
ELSIF SVmode='0' THEN
|
ELSIF SVmode='0' THEN
|
trap_priv <= '1';
|
trap_priv <= '1';
|
trapmake <= '1';
|
trapmake <= '1';
|
Line 2326... |
Line 2333... |
END CASE;
|
END CASE;
|
END IF;
|
END IF;
|
--
|
--
|
---- 0101 ----------------------------------------------------------------------------
|
---- 0101 ----------------------------------------------------------------------------
|
WHEN "0101" => --subq, addq
|
WHEN "0101" => --subq, addq
|
|
|
IF opcode(7 downto 6)="11" THEN --dbcc
|
IF opcode(7 downto 6)="11" THEN --dbcc
|
IF opcode(5 downto 3)="001" THEN --dbcc
|
IF opcode(5 downto 3)="001" THEN --dbcc
|
IF decodeOPC='1' THEN
|
IF decodeOPC='1' THEN
|
next_micro_state <= dbcc1;
|
next_micro_state <= dbcc1;
|
set(OP2out_one) <= '1';
|
set(OP2out_one) <= '1';
|
data_is_source <= '1';
|
data_is_source <= '1';
|
END IF;
|
END IF;
|
|
ELSIF opcode(5 downto 3)="111" AND (opcode(2 downto 1)="01" OR opcode(2 downto 0)="100") THEN --trapcc
|
|
IF cpu(1)='1' THEN -- only 68020+
|
|
IF opcode(2 downto 1)="01" THEN
|
|
IF decodeOPC='1' THEN
|
|
IF opcode(0)='1' THEN --long
|
|
set(longaktion) <= '1';
|
|
END IF;
|
|
next_micro_state <= nop;
|
|
END IF;
|
|
ELSE
|
|
IF decodeOPC='1' THEN
|
|
setstate <= "01";
|
|
END IF;
|
|
END IF;
|
|
trap_trapcc<='1';
|
|
IF exe_condition='1' AND decodeOPC='0' THEN
|
|
trap_trapv <= '1';
|
|
trapmake <= '1';
|
|
END IF;
|
|
ELSE
|
|
trap_illegal <= '1';
|
|
trapmake <= '1';
|
|
END IF;
|
ELSE --Scc
|
ELSE --Scc
|
datatype <= "00"; --Byte
|
datatype <= "00"; --Byte
|
ea_build_now <= '1';
|
ea_build_now <= '1';
|
write_back <= '1';
|
write_back <= '1';
|
set_exec(opcScc) <= '1';
|
set_exec(opcScc) <= '1';
|
Line 3018... |
Line 3047... |
WHEN movem1 => --movem
|
WHEN movem1 => --movem
|
IF last_data_read(15 downto 0)/=X"0000" THEN
|
IF last_data_read(15 downto 0)/=X"0000" THEN
|
setstate <="01";
|
setstate <="01";
|
IF opcode(5 downto 3)="100" THEN
|
IF opcode(5 downto 3)="100" THEN
|
set(mem_addsub) <= '1';
|
set(mem_addsub) <= '1';
|
|
IF cpu(1)='1' THEN
|
|
set(Regwrena) <= '1'; --tg
|
|
END IF;
|
END IF;
|
END IF;
|
next_micro_state <= movem2;
|
next_micro_state <= movem2;
|
END IF;
|
END IF;
|
WHEN movem2 => --movem
|
WHEN movem2 => --movem
|
IF movem_run='0' THEN
|
IF movem_run='0' THEN
|
Line 3109... |
Line 3141... |
next_micro_state <= unlink2;
|
next_micro_state <= unlink2;
|
WHEN unlink2 => -- unlink
|
WHEN unlink2 => -- unlink
|
set(ea_data_OP2) <= '1';
|
set(ea_data_OP2) <= '1';
|
|
|
-- paste and copy form TH ---------
|
-- paste and copy form TH ---------
|
when trap00 => -- TRAP format #2
|
WHEN trap00 => -- TRAP format #2
|
next_micro_state <= trap0;
|
next_micro_state <= trap0;
|
set(presub) <= '1';
|
set(presub) <= '1';
|
setstackaddr <='1';
|
setstackaddr <='1';
|
setstate <= "11";
|
setstate <= "11";
|
datatype <= "10";
|
datatype <= "10";
|
------------------------------------
|
------------------------------------
|
WHEN trap0 => -- TRAP
|
WHEN trap0 => -- TRAP
|
set(presub) <= '1';
|
set(presub) <= '1';
|
setstackaddr <='1';
|
setstackaddr <='1';
|
setstate <= "11";
|
setstate <= "11";
|
IF VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN --68010
|
IF use_VBR_Stackframe='1' THEN --68010
|
set(writePC_add) <= '1';
|
set(writePC_add) <= '1';
|
datatype <= "01";
|
datatype <= "01";
|
-- set_datatype <= "10";
|
-- set_datatype <= "10";
|
next_micro_state <= trap1;
|
next_micro_state <= trap1;
|
ELSE
|
ELSE
|
Line 3195... |
Line 3227... |
datatype <= "10";
|
datatype <= "10";
|
setstate <= "10";
|
setstate <= "10";
|
set(postadd) <= '1';
|
set(postadd) <= '1';
|
setstackaddr <= '1';
|
setstackaddr <= '1';
|
set(directPC) <= '1';
|
set(directPC) <= '1';
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) OR opcode(2)='1' THEN --opcode(2)='1' => opcode is RTR
|
IF use_VBR_Stackframe='0' OR opcode(2)='1' THEN --opcode(2)='1' => opcode is RTR
|
set(update_FC) <= '1';
|
set(update_FC) <= '1';
|
set(direct_delta) <= '1';
|
set(direct_delta) <= '1';
|
END IF;
|
END IF;
|
next_micro_state <= rte2;
|
next_micro_state <= rte2;
|
WHEN rte2 => -- RTE
|
WHEN rte2 => -- RTE
|
datatype <= "01";
|
datatype <= "01";
|
set(update_FC) <= '1';
|
set(update_FC) <= '1';
|
IF (VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2)) AND opcode(2)='0' THEN
|
IF use_VBR_Stackframe='1' AND opcode(2)='0' THEN
|
-- 010+ reads another word
|
-- 010+ reads another word
|
setstate <= "10";
|
setstate <= "10";
|
set(postadd) <= '1';
|
set(postadd) <= '1';
|
setstackaddr <= '1';
|
setstackaddr <= '1';
|
next_micro_state <= rte3;
|
next_micro_state <= rte3;
|
Line 3428... |
Line 3460... |
|
|
movec_data <= (others => '0');
|
movec_data <= (others => '0');
|
case brief(11 downto 0) is
|
case brief(11 downto 0) is
|
when X"002" => movec_data <= "0000000000000000000000000000" & (CACR AND "0011");
|
when X"002" => movec_data <= "0000000000000000000000000000" & (CACR AND "0011");
|
|
|
when X"801" => --if VBR_Stackframe=1 or (cpu(0)='1' and VBR_Stackframe=2) then
|
when X"801" =>
|
movec_data <= VBR;
|
movec_data <= VBR;
|
--end if;
|
--end if;
|
when others => NULL;
|
when others => NULL;
|
end case;
|
end case;
|
end process;
|
end process;
|