Line 1... |
Line 1... |
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- --
|
-- --
|
-- Copyright (c) 2009-2018 Tobias Gubener --
|
-- Copyright (c) 2009-2019 Tobias Gubener --
|
-- Subdesign fAMpIGA by TobiFlex --
|
|
-- Patches by MikeJ, Till Harbaum, Rok Krajnk, ... --
|
-- Patches by MikeJ, Till Harbaum, Rok Krajnk, ... --
|
|
-- Subdesign fAMpIGA by TobiFlex --
|
-- --
|
-- --
|
-- This source file is free software: you can redistribute it and/or modify --
|
-- This source file is free software: you can redistribute it and/or modify --
|
-- it under the terms of the GNU Lesser General Public License as published --
|
-- it under the terms of the GNU Lesser General Public License as published --
|
-- by the Free Software Foundation, either version 3 of the License, or --
|
-- by the Free Software Foundation, either version 3 of the License, or --
|
-- (at your option) any later version. --
|
-- (at your option) any later version. --
|
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/>. --
|
-- --
|
-- --
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
|
-- 30.10.2019 TG bugfix RTR in 68020-mode
|
|
-- 30.10.2019 TG bugfix BFINS again
|
|
-- 19.10.2019 TG insert some bugfixes from apolkosnik
|
-- 05.12.2018 TG insert RTD opcode
|
-- 05.12.2018 TG insert RTD opcode
|
-- 03.12.2018 TG insert barrel shifter
|
-- 03.12.2018 TG insert barrel shifter
|
-- 01.11.2017 TG bugfix V-Flag for ASL/ASR - thanks Peter Graf
|
-- 01.11.2017 TG bugfix V-Flag for ASL/ASR - thanks Peter Graf
|
-- 29.05.2017 TG decode 0x4AFB as illegal, needed for QL BKP - thanks Peter Graf
|
-- 29.05.2017 TG decode 0x4AFB as illegal, needed for QL BKP - thanks Peter Graf
|
-- 21.05.2017 TG insert generic for hardware multiplier for MULU & MULS
|
-- 21.05.2017 TG insert generic for hardware multiplier for MULU & MULS
|
Line 100... |
Line 103... |
data_in : in std_logic_vector(15 downto 0);
|
data_in : in std_logic_vector(15 downto 0);
|
IPL : in std_logic_vector(2 downto 0):="111";
|
IPL : in std_logic_vector(2 downto 0):="111";
|
IPL_autovector : in std_logic:='0';
|
IPL_autovector : in std_logic:='0';
|
berr : in std_logic:='0'; -- only 68000 Stackpointer dummy
|
berr : in std_logic:='0'; -- only 68000 Stackpointer dummy
|
CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet)
|
CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet)
|
addr : buffer std_logic_vector(31 downto 0);
|
addr_out : out std_logic_vector(31 downto 0);
|
data_write : out std_logic_vector(15 downto 0);
|
data_write : out std_logic_vector(15 downto 0);
|
nWr : out std_logic;
|
nWr : out std_logic;
|
nUDS, nLDS : out std_logic;
|
nUDS, nLDS : out std_logic;
|
busstate : out std_logic_vector(1 downto 0); -- 00-> fetch code 10->read data 11->write data 01->no memaccess
|
busstate : out std_logic_vector(1 downto 0); -- 00-> fetch code 10->read data 11->write data 01->no memaccess
|
nResetOut : out std_logic;
|
nResetOut : out std_logic;
|
Line 112... |
Line 115... |
--
|
--
|
clr_berr : out std_logic;
|
clr_berr : out std_logic;
|
-- for debug
|
-- for debug
|
skipFetch : out std_logic;
|
skipFetch : out std_logic;
|
-- regin : buffer std_logic_vector(31 downto 0)
|
-- regin : buffer std_logic_vector(31 downto 0)
|
-- regin_out : out std_logic_vector(31 downto 0);
|
regin_out : out std_logic_vector(31 downto 0);
|
CACR_out : out std_logic_vector( 3 downto 0);
|
CACR_out : out std_logic_vector( 3 downto 0);
|
VBR_out : out std_logic_vector(31 downto 0)
|
VBR_out : out std_logic_vector(31 downto 0)
|
);
|
);
|
end TG68KdotC_Kernel;
|
end TG68KdotC_Kernel;
|
|
|
Line 159... |
Line 162... |
signal RDindex_A : integer range 0 to 15;
|
signal RDindex_A : integer range 0 to 15;
|
signal RDindex_B : integer range 0 to 15;
|
signal RDindex_B : integer range 0 to 15;
|
signal WR_AReg : std_logic;
|
signal WR_AReg : std_logic;
|
|
|
|
|
|
signal addr : std_logic_vector(31 downto 0);
|
signal memaddr_reg : std_logic_vector(31 downto 0);
|
signal memaddr_reg : std_logic_vector(31 downto 0);
|
signal memaddr_delta : std_logic_vector(31 downto 0);
|
signal memaddr_delta : std_logic_vector(31 downto 0);
|
signal use_base : bit;
|
signal use_base : bit;
|
|
|
signal ea_data : std_logic_vector(31 downto 0);
|
signal ea_data : std_logic_vector(31 downto 0);
|
signal OP1out, OP2out : std_logic_vector(31 downto 0);
|
signal OP1out : std_logic_vector(31 downto 0);
|
|
signal OP2out : std_logic_vector(31 downto 0);
|
signal OP1outbrief : std_logic_vector(15 downto 0);
|
signal OP1outbrief : std_logic_vector(15 downto 0);
|
signal OP1in : std_logic_vector(31 downto 0);
|
signal OP1in : std_logic_vector(31 downto 0);
|
signal ALUout : std_logic_vector(31 downto 0);
|
signal ALUout : std_logic_vector(31 downto 0);
|
signal data_write_tmp : std_logic_vector(31 downto 0);
|
signal data_write_tmp : std_logic_vector(31 downto 0);
|
signal data_write_muxin : std_logic_vector(31 downto 0);
|
signal data_write_muxin : std_logic_vector(31 downto 0);
|
Line 205... |
Line 210... |
signal execOPC : bit;
|
signal execOPC : bit;
|
signal setexecOPC : bit;
|
signal setexecOPC : bit;
|
signal endOPC : bit;
|
signal endOPC : bit;
|
signal setendOPC : bit;
|
signal setendOPC : bit;
|
signal Flags : std_logic_vector(7 downto 0); -- ...XNZVC
|
signal Flags : std_logic_vector(7 downto 0); -- ...XNZVC
|
signal FlagsSR : std_logic_vector(7 downto 0); -- T.S..III
|
signal FlagsSR : std_logic_vector(7 downto 0); -- T.S.0III
|
signal SRin : std_logic_vector(7 downto 0);
|
signal SRin : std_logic_vector(7 downto 0);
|
signal exec_DIRECT : bit;
|
signal exec_DIRECT : bit;
|
signal exec_tas : std_logic;
|
signal exec_tas : std_logic;
|
signal set_exec_tas : std_logic;
|
signal set_exec_tas : std_logic;
|
|
|
Line 387... |
Line 392... |
end if;
|
end if;
|
end process;
|
end process;
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Bus control
|
-- Bus control
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
|
regin_out <= regin;
|
|
|
|
|
nWr <= '0' WHEN state="11" ELSE '1';
|
nWr <= '0' WHEN state="11" ELSE '1';
|
busstate <= state;
|
busstate <= state;
|
nResetOut <= '0' WHEN exec(opcRESET)='1' ELSE '1';
|
nResetOut <= '0' WHEN exec(opcRESET)='1' ELSE '1';
|
|
|
-- does shift for byte access. note active low me
|
-- does shift for byte access. note active low me
|
Line 565... |
Line 573... |
IF exec(movem_action) ='1' THEN
|
IF exec(movem_action) ='1' THEN
|
rf_dest_addr <= rf_source_addrd;
|
rf_dest_addr <= rf_source_addrd;
|
ELSIF set(briefext)='1' THEN
|
ELSIF set(briefext)='1' THEN
|
rf_dest_addr <= brief(15 downto 12);
|
rf_dest_addr <= brief(15 downto 12);
|
ELSIF set(get_bfoffset)='1' THEN
|
ELSIF set(get_bfoffset)='1' THEN
|
|
IF opcode(15 downto 12)="1110" THEN
|
|
rf_dest_addr <= '0'&sndOPC(8 downto 6);
|
|
ELSE
|
rf_dest_addr <= sndOPC(9 downto 6);
|
rf_dest_addr <= sndOPC(9 downto 6);
|
|
END IF;
|
ELSIF dest_2ndHbits='1' THEN
|
ELSIF dest_2ndHbits='1' THEN
|
rf_dest_addr <= sndOPC(15 downto 12);
|
rf_dest_addr <= '0'&sndOPC(14 downto 12);
|
ELSIF set(write_reminder)='1' THEN
|
ELSIF set(write_reminder)='1' THEN
|
rf_dest_addr <= sndOPC(3 downto 0);
|
rf_dest_addr <= '0'&sndOPC(2 downto 0);
|
ELSIF setstackaddr='1' THEN
|
ELSIF setstackaddr='1' THEN
|
rf_dest_addr <= "1111";
|
rf_dest_addr <= "1111";
|
ELSIF dest_hbits='1' THEN
|
ELSIF dest_hbits='1' THEN
|
rf_dest_addr <= dest_areg&opcode(11 downto 9);
|
rf_dest_addr <= dest_areg&opcode(11 downto 9);
|
ELSE
|
ELSE
|
Line 595... |
Line 607... |
rf_source_addr <= movem_regaddr XOR "1111";
|
rf_source_addr <= movem_regaddr XOR "1111";
|
ELSE
|
ELSE
|
rf_source_addr <= movem_regaddr;
|
rf_source_addr <= movem_regaddr;
|
END IF;
|
END IF;
|
ELSIF source_2ndLbits='1' THEN
|
ELSIF source_2ndLbits='1' THEN
|
rf_source_addr <= sndOPC(3 downto 0);
|
rf_source_addr <= '0'&sndOPC(2 downto 0);
|
ELSIF source_2ndHbits='1' THEN
|
ELSIF source_2ndHbits='1' THEN
|
rf_source_addr <= sndOPC(15 downto 12);
|
rf_source_addr <= '0'&sndOPC(14 downto 12);
|
ELSIF source_lowbits='1' THEN
|
ELSIF source_lowbits='1' THEN
|
rf_source_addr <= source_areg&opcode(2 downto 0);
|
rf_source_addr <= source_areg&opcode(2 downto 0);
|
ELSIF exec(linksp)='1' THEN
|
ELSIF exec(linksp)='1' THEN
|
rf_source_addr <= "1111";
|
rf_source_addr <= "1111";
|
ELSE
|
ELSE
|
Line 885... |
Line 897... |
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
-- if access done, and not aligned, don't increment
|
-- if access done, and not aligned, don't increment
|
addr <= memaddr_reg+memaddr_delta;
|
addr <= memaddr_reg+memaddr_delta;
|
|
addr_out <= memaddr_reg + memaddr_delta;
|
|
|
IF use_base='0' THEN
|
IF use_base='0' THEN
|
memaddr_reg <= (others=>'0');
|
memaddr_reg <= (others=>'0');
|
ELSE
|
ELSE
|
memaddr_reg <= reg_QA;
|
memaddr_reg <= reg_QA;
|
END IF;
|
END IF;
|
Line 1208... |
Line 1222... |
bf_width(4 downto 0) <= sndOPC(4 downto 0)-1;
|
bf_width(4 downto 0) <= sndOPC(4 downto 0)-1;
|
END IF;
|
END IF;
|
bf_bhits <= bf_width+bf_offset;
|
bf_bhits <= bf_width+bf_offset;
|
set_oddout <= NOT bf_bhits(3);
|
set_oddout <= NOT bf_bhits(3);
|
|
|
|
|
|
-- bf_loffset is used for the shifted_bitmask
|
IF opcode(10 downto 8)="111" THEN --INS
|
IF opcode(10 downto 8)="111" THEN --INS
|
bf_loffset <= 32-bf_shift;
|
bf_loffset <= 32-bf_shift;
|
ELSE
|
ELSE
|
bf_loffset <= bf_shift;
|
bf_loffset <= bf_shift;
|
END IF;
|
END IF;
|
bf_loffset(5) <= '0';
|
bf_loffset(5) <= '0';
|
-- IF set_exec(exec_BS)='1' THEN
|
|
-- bf_width(4 downto 0)<="01111";
|
|
-- bf_loffset(4 downto 0) <= "00000";
|
|
-- END IF;
|
|
|
|
IF opcode(4 downto 3)="00" THEN
|
IF opcode(4 downto 3)="00" THEN
|
IF opcode(10 downto 8)="111" THEN --INS
|
IF opcode(10 downto 8)="111" THEN --INS
|
bf_shift <= bf_bhits+1;
|
bf_shift <= bf_bhits+1;
|
ELSE
|
ELSE
|
bf_shift <= 31-bf_bhits;
|
bf_shift <= 31-bf_bhits;
|
END IF;
|
END IF;
|
bf_shift(5) <= '0';
|
bf_shift(5) <= '0';
|
ELSE
|
ELSE
|
IF opcode(10 downto 8)="111" THEN --INS
|
IF opcode(10 downto 8)="111" THEN --INS
|
bf_shift <= "011"&("001"+bf_bhits(2 downto 0));
|
bf_shift <= "011001"+("000"&bf_bhits(2 downto 0));
|
|
bf_shift(5) <= '0';
|
ELSE
|
ELSE
|
bf_shift <= "000"&("111"-bf_bhits(2 downto 0));
|
bf_shift <= "000"&("111"-bf_bhits(2 downto 0));
|
END IF;
|
END IF;
|
bf_offset(4 downto 3) <= "00";
|
bf_offset(4 downto 3) <= "00";
|
END IF;
|
END IF;
|
Line 1273... |
Line 1286... |
IF Reset='1' THEN
|
IF Reset='1' THEN
|
FlagsSR(5) <= '1';
|
FlagsSR(5) <= '1';
|
FC(2) <= '1';
|
FC(2) <= '1';
|
SVmode <= '1';
|
SVmode <= '1';
|
preSVmode <= '1';
|
preSVmode <= '1';
|
FlagsSR(2 downto 0) <= "111";
|
FlagsSR(3 downto 0) <= "0111";
|
make_trace <= '0';
|
make_trace <= '0';
|
ELSIF clkena_lw = '1' THEN
|
ELSIF clkena_lw = '1' THEN
|
IF setopcode='1' THEN
|
IF setopcode='1' THEN
|
make_trace <= FlagsSR(7);
|
make_trace <= FlagsSR(7);
|
IF set(changeMode)='1' THEN
|
IF set(changeMode)='1' THEN
|
Line 1301... |
Line 1314... |
FlagsSR <= data_read(15 downto 8);
|
FlagsSR <= data_read(15 downto 8);
|
END IF;
|
END IF;
|
IF interrupt='1' AND trap_interrupt='1' THEN
|
IF interrupt='1' AND trap_interrupt='1' THEN
|
FlagsSR(2 downto 0) <=rIPL_nr;
|
FlagsSR(2 downto 0) <=rIPL_nr;
|
END IF;
|
END IF;
|
-- IF exec(to_CCR)='1' AND exec(to_SR)='1' THEN
|
|
IF exec(to_SR)='1' THEN
|
IF exec(to_SR)='1' THEN
|
FlagsSR(7 downto 0) <= SRin; --SR
|
FlagsSR(7 downto 0) <= SRin; --SR
|
FC(2) <= SRin(5);
|
FC(2) <= SRin(5);
|
-- END IF;
|
|
ELSIF exec(update_FC)='1' THEN
|
ELSIF exec(update_FC)='1' THEN
|
FC(2) <= FlagsSR(5);
|
FC(2) <= FlagsSR(5);
|
END IF;
|
END IF;
|
IF interrupt='1' THEN
|
IF interrupt='1' THEN
|
FC(2) <= '1';
|
FC(2) <= '1';
|
END IF;
|
END IF;
|
|
FlagsSR(3) <= '0';
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END PROCESS;
|
END PROCESS;
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
Line 1764... |
Line 1776... |
ELSE
|
ELSE
|
CASE opcode(11 downto 9) IS
|
CASE opcode(11 downto 9) IS
|
WHEN "000"=>
|
WHEN "000"=>
|
IF opcode(7 downto 6)="11" THEN --move from SR
|
IF opcode(7 downto 6)="11" THEN --move from SR
|
IF SR_Read=0 OR (cpu(0)='0' AND SR_Read=2) OR SVmode='1' THEN
|
IF SR_Read=0 OR (cpu(0)='0' AND SR_Read=2) OR SVmode='1' THEN
|
-- IF SVmode='1' THEN
|
|
ea_build_now <= '1';
|
ea_build_now <= '1';
|
set_exec(opcMOVESR) <= '1';
|
set_exec(opcMOVESR) <= '1';
|
datatype <= "01";
|
datatype <= "01";
|
write_back <='1'; -- im 68000 wird auch erst gelesen
|
write_back <='1'; -- im 68000 wird auch erst gelesen
|
IF cpu(0)='1' AND state="10" THEN
|
IF cpu(0)='1' AND state="10" THEN
|
Line 3136... |
Line 3147... |
WHEN rte1 => -- RTE
|
WHEN rte1 => -- RTE
|
datatype <= "10";
|
datatype <= "10";
|
setstate <= "10";
|
setstate <= "10";
|
set(postadd) <= '1';
|
set(postadd) <= '1';
|
setstackaddr <= '1';
|
setstackaddr <= '1';
|
IF VBR_Stackframe=0 OR (cpu(0)='0' AND VBR_Stackframe=2) THEN
|
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
|
set(update_FC) <= '1';
|
set(update_FC) <= '1';
|
set(direct_delta) <= '1';
|
set(direct_delta) <= '1';
|
END IF;
|
END IF;
|
set(directPC) <= '1';
|
|
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) THEN
|
IF (VBR_Stackframe=1 OR (cpu(0)='1' AND VBR_Stackframe=2)) AND opcode(2)='0' THEN
|
setstate <= "10";
|
setstate <= "10";
|
set(postadd) <= '1';
|
set(postadd) <= '1';
|
setstackaddr <= '1';
|
setstackaddr <= '1';
|
next_micro_state <= rte3;
|
next_micro_state <= rte3;
|
ELSE
|
ELSE
|