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/>. --
|
-- --
|
-- --
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
|
-- 03.11.2019 TG insert TrapV from TH
|
|
-- 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
|
-- 30.10.2019 TG bugfix RTR in 68020-mode
|
-- 30.10.2019 TG bugfix RTR in 68020-mode
|
-- 30.10.2019 TG bugfix BFINS again
|
-- 30.10.2019 TG bugfix BFINS again
|
-- 19.10.2019 TG insert some bugfixes from apolkosnik
|
-- 19.10.2019 TG insert some bugfixes from apolkosnik
|
Line 84... |
Line 86... |
generic(
|
generic(
|
SR_Read : integer:= 1; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
SR_Read : integer:= 1; --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:= 1; --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:= 1; --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 := 1; --0=>16Bit, 1=>32Bit, 2=>switchable with CPU(1), 3=>no MUL,
|
MUL_Hardware : integer := 1; --0=>no, 1=>yes,
|
MUL_Hardware : integer := 0; --0=>no, 1=>yes,
|
DIV_Mode : integer := 1; --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,
|
BarrelShifter : 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)
|
BitField : integer := 1 --0=>no, 1=>yes, 2=>switchable with CPU(1)
|
-- SR_Read : integer:= 0; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
-- SR_Read : integer:= 0; --0=>user, 1=>privileged, 2=>switchable with CPU(0)
|
-- VBR_Stackframe : integer:= 0; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
|
-- VBR_Stackframe : integer:= 0; --0=>no, 1=>yes/extended, 2=>switchable with CPU(0)
|
Line 144... |
Line 146... |
|
|
signal opcode : std_logic_vector(15 downto 0);
|
signal opcode : std_logic_vector(15 downto 0);
|
signal exe_opcode : std_logic_vector(15 downto 0);
|
signal exe_opcode : std_logic_vector(15 downto 0);
|
signal sndOPC : std_logic_vector(15 downto 0);
|
signal sndOPC : std_logic_vector(15 downto 0);
|
|
|
|
signal exe_pc : std_logic_vector(31 downto 0);--TH
|
|
signal last_opc_pc : std_logic_vector(31 downto 0);--TH
|
signal last_opc_read : std_logic_vector(15 downto 0);
|
signal last_opc_read : std_logic_vector(15 downto 0);
|
signal registerin : std_logic_vector(31 downto 0);
|
signal registerin : std_logic_vector(31 downto 0);
|
signal reg_QA : std_logic_vector(31 downto 0);
|
signal reg_QA : std_logic_vector(31 downto 0);
|
signal reg_QB : std_logic_vector(31 downto 0);
|
signal reg_QB : std_logic_vector(31 downto 0);
|
signal Wwrena,Lwrena : bit;
|
signal Wwrena,Lwrena : bit;
|
Line 686... |
Line 690... |
ELSIF clkena_lw='1' THEN
|
ELSIF clkena_lw='1' THEN
|
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 --???
|
exec_write_back <= '1';
|
exec_write_back <= '1';
|
END IF;
|
END IF;
|
|
|
|
IF exec(save_OP2)='1' THEN
|
|
use_direct_data <= '1';
|
|
END IF;
|
IF set_direct_data='1' THEN
|
IF set_direct_data='1' THEN
|
direct_data <= '1';
|
direct_data <= '1';
|
use_direct_data <= '1';
|
use_direct_data <= '1';
|
ELSIF endOPC='1' THEN
|
ELSIF endOPC='1' THEN
|
use_direct_data <= '0';
|
use_direct_data <= '0';
|
Line 729... |
Line 736... |
|
|
IF writePC='1' THEN
|
IF writePC='1' THEN
|
data_write_tmp <= TG68_PC;
|
data_write_tmp <= TG68_PC;
|
ELSIF exec(writePC_add)='1' THEN
|
ELSIF exec(writePC_add)='1' THEN
|
data_write_tmp <= TG68_PC_add;
|
data_write_tmp <= TG68_PC_add;
|
ELSIF micro_state=trap0 THEN
|
-- paste and copy form TH ---------
|
data_write_tmp(15 downto 0) <= trap_vector(15 downto 0);
|
elsif micro_state=trap00 THEN
|
|
data_write_tmp <= exe_pc; --TH
|
|
elsif micro_state = trap0 then
|
|
-- this is only active for 010+ since in 000 writePC is
|
|
-- true in state trap0
|
|
if trap_trace='1' or set_exec(opcTRAPV) = '1' then
|
|
-- stack frame format #2
|
|
data_write_tmp(15 downto 0) <= "0010" & trap_vector(11 downto 0); --TH
|
|
else
|
|
data_write_tmp(15 downto 0) <= "0000" & trap_vector(11 downto 0);
|
|
end if;
|
|
------------------------------------
|
|
-- ELSIF micro_state=trap0 THEN
|
|
-- data_write_tmp(15 downto 0) <= trap_vector(15 downto 0);
|
ELSIF exec(hold_dwr)='1' THEN
|
ELSIF exec(hold_dwr)='1' THEN
|
data_write_tmp <= data_write_tmp;
|
data_write_tmp <= data_write_tmp;
|
ELSIF exec(exg)='1' THEN
|
ELSIF exec(exg)='1' THEN
|
data_write_tmp <= OP1out;
|
data_write_tmp <= OP1out;
|
ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN -- ist for pea
|
ELSIF exec(get_ea_now)='1' AND ea_only='1' THEN -- ist for pea
|
Line 1042... |
Line 1062... |
IF micro_state=trap0 AND IPL_autovector='0' THEN
|
IF micro_state=trap0 AND IPL_autovector='0' THEN
|
IPL_vec <= last_data_read(7 downto 0); -- TH
|
IPL_vec <= last_data_read(7 downto 0); -- TH
|
END IF;
|
END IF;
|
IF state="00" THEN
|
IF state="00" THEN
|
last_opc_read <= data_read(15 downto 0);
|
last_opc_read <= data_read(15 downto 0);
|
|
last_opc_pc <= tg68_pc;--TH
|
END IF;
|
END IF;
|
IF setopcode='1' THEN
|
IF setopcode='1' THEN
|
trap_interrupt <= '0';
|
trap_interrupt <= '0';
|
trap_trace <= '0';
|
trap_trace <= '0';
|
TG68_PC_word <= '0';
|
TG68_PC_word <= '0';
|
Line 1128... |
Line 1149... |
END IF;
|
END IF;
|
|
|
IF setopcode='1' AND berr='0' THEN
|
IF setopcode='1' AND berr='0' THEN
|
IF state="00" THEN
|
IF state="00" THEN
|
opcode <= data_read(15 downto 0);
|
opcode <= data_read(15 downto 0);
|
|
exe_pc <= tg68_pc;--TH
|
ELSE
|
ELSE
|
opcode <= last_opc_read(15 downto 0);
|
opcode <= last_opc_read(15 downto 0);
|
|
exe_pc <= last_opc_pc;--TH
|
END IF;
|
END IF;
|
nextpass <= '0';
|
nextpass <= '0';
|
ELSIF setinterrupt='1' OR setopcode='1' THEN
|
ELSIF setinterrupt='1' OR setopcode='1' THEN
|
opcode <= X"4E71"; --nop
|
opcode <= X"4E71"; --nop
|
nextpass <= '0';
|
nextpass <= '0';
|
Line 1311... |
Line 1334... |
-- 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,
|
datatype, interrupt, c_out, trapmake, rot_cnt, brief, addr, trap_trapv,
|
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 1385... |
Line 1408... |
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 trapmake='1' AND trapd='0' THEN
|
IF trapmake='1' AND trapd='0' THEN
|
|
-- paste and copy form TH ---------
|
|
if trap_trapv = '1' and (VBR_Stackframe = 1 or (cpu(0) = '1' and VBR_Stackframe = 2)) then
|
|
next_micro_state <= trap00;
|
|
else
|
next_micro_state <= trap0;
|
next_micro_state <= trap0;
|
|
end if;
|
|
------------------------------------
|
|
-- next_micro_state <= trap0;
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN
|
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
|
Line 1403... |
Line 1433... |
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
|
|
-- paste and copy form TH ---------
|
|
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;
|
next_micro_state <= trap0;
|
|
end if;
|
|
------------------------------------
|
|
-- next_micro_state <= trap0;
|
-- IF cpu(0)='0' THEN
|
-- IF cpu(0)='0' THEN
|
-- 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 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
|
|
set(changeMode) <= '1';
|
|
end if;
|
|
setstate <= "01";
|
|
end if;
|
|
|
IF setexecOPC='1' AND FlagsSR(5)/=preSVmode THEN
|
IF setexecOPC='1' AND FlagsSR(5)/=preSVmode THEN
|
set(changeMode) <= '1';
|
set(changeMode) <= '1';
|
-- setstate <= "01";
|
-- setstate <= "01";
|
-- next_micro_state <= nop;
|
-- next_micro_state <= nop;
|
Line 2228... |
Line 2279... |
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';
|
Line 2343... |
Line 2395... |
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
-- 0111 ----------------------------------------------------------------------------
|
-- 0111 ----------------------------------------------------------------------------
|
WHEN "0111" => --moveq
|
WHEN "0111" => --moveq
|
-- IF opcode(8)='0' THEN -- Cloanto's Amiga Forver ROMs have mangled moveq instructions with a 1 here...
|
|
datatype <= "10"; --Long
|
datatype <= "10"; --Long
|
set_exec(Regwrena) <= '1';
|
set_exec(Regwrena) <= '1';
|
set_exec(opcMOVEQ) <= '1';
|
set_exec(opcMOVEQ) <= '1';
|
set_exec(opcMOVE) <= '1';
|
set_exec(opcMOVE) <= '1';
|
dest_hbits <= '1';
|
dest_hbits <= '1';
|
-- ELSE
|
|
-- trap_illegal <= '1';
|
|
-- trapmake <= '1';
|
|
-- END IF;
|
|
|
|
---- 1000 ----------------------------------------------------------------------------
|
---- 1000 ----------------------------------------------------------------------------
|
WHEN "1000" => --or
|
WHEN "1000" => --or
|
IF opcode(7 downto 6)="11" THEN --divu, divs
|
IF opcode(7 downto 6)="11" THEN --divu, divs
|
IF DIV_Mode/=3 THEN
|
IF DIV_Mode/=3 THEN
|
Line 3060... |
Line 3107... |
set(postadd) <= '1';
|
set(postadd) <= '1';
|
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 ---------
|
|
when trap00 => -- TRAP format #2
|
|
next_micro_state <= trap0;
|
|
set(presub) <= '1';
|
|
setstackaddr <='1';
|
|
setstate <= "11";
|
|
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 VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2) THEN --68010
|
Line 3076... |
Line 3131... |
writePC <= '1';
|
writePC <= '1';
|
END IF;
|
END IF;
|
datatype <= "10";
|
datatype <= "10";
|
next_micro_state <= trap2;
|
next_micro_state <= trap2;
|
END IF;
|
END IF;
|
|
|
WHEN trap1 => -- TRAP
|
WHEN trap1 => -- TRAP
|
IF trap_interrupt='1' OR trap_trace='1' THEN
|
IF trap_interrupt='1' OR trap_trace='1' THEN
|
writePC <= '1';
|
writePC <= '1';
|
END IF;
|
END IF;
|
set(presub) <= '1';
|
set(presub) <= '1';
|
Line 3103... |
Line 3159... |
datatype <= "10";
|
datatype <= "10";
|
set(direct_delta) <= '1';
|
set(direct_delta) <= '1';
|
set(directPC) <= '1';
|
set(directPC) <= '1';
|
setstate <= "10";
|
setstate <= "10";
|
next_micro_state <= nopnop;
|
next_micro_state <= nopnop;
|
|
|
WHEN trap4 => -- TRAP
|
WHEN trap4 => -- TRAP
|
set(presub) <= '1';
|
set(presub) <= '1';
|
setstackaddr <='1';
|
setstackaddr <='1';
|
setstate <= "11";
|
setstate <= "11";
|
datatype <= "01";
|
datatype <= "01";
|
Line 3236... |
Line 3291... |
next_micro_state <= mul2;
|
next_micro_state <= mul2;
|
WHEN mul2 => -- mulu
|
WHEN mul2 => -- mulu
|
setstate <="01";
|
setstate <="01";
|
IF rot_cnt="00001" THEN
|
IF rot_cnt="00001" THEN
|
next_micro_state <= mul_end1;
|
next_micro_state <= mul_end1;
|
|
|
ELSE
|
ELSE
|
next_micro_state <= mul2;
|
next_micro_state <= mul2;
|
END IF;
|
END IF;
|
WHEN mul_end1 => -- mulu
|
WHEN mul_end1 => -- mulu
|
|
IF opcode(15)='0' THEN
|
|
set(save_OP2) <= '1';
|
|
END IF;
|
datatype <= "10";
|
datatype <= "10";
|
set(opcMULU) <= '1';
|
set(opcMULU) <= '1';
|
IF opcode(15)='0' AND (MUL_Mode=1 OR MUL_Mode=2) THEN
|
IF opcode(15)='0' AND (MUL_Mode=1 OR MUL_Mode=2) THEN
|
dest_2ndHbits <= '1';
|
dest_2ndHbits <= '1';
|
-- source_2ndLbits <= '1';--???
|
|
set(write_lowlong) <= '1';
|
set(write_lowlong) <= '1';
|
IF sndOPC(10)='1' THEN
|
IF sndOPC(10)='1' THEN
|
setstate <="01";
|
setstate <="01";
|
next_micro_state <= mul_end2;
|
next_micro_state <= mul_end2;
|
END IF;
|
END IF;
|