Line 1... |
Line 1... |
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- --
|
-- --
|
-- This is the 68000 software compatible Kernal of TG68 --
|
-- This is the 68000 software compatible Kernal of TG68 --
|
-- --
|
-- --
|
-- Copyright (c) 2007 Tobias Gubener <tobiflex@opencores.org> --
|
-- Copyright (c) 2007-2010 Tobias Gubener <tobiflex@opencores.org> --
|
-- --
|
-- --
|
-- 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/>. --
|
-- --
|
-- --
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
--
|
--
|
|
-- Revision 1.08 2010/06/14
|
|
-- Bugfix Movem with regmask==xFFFF
|
|
-- Add missing Illegal $4AFC
|
|
--
|
|
-- Revision 1.07 2009/10/02
|
|
-- Bugfix Movem with regmask==x0000
|
|
--
|
-- Revision 1.06 2009/02/10
|
-- Revision 1.06 2009/02/10
|
-- Bugfix shift and rotations opcodes when the bitcount and the data are in the same register:
|
-- Bugfix shift and rotations opcodes when the bitcount and the data are in the same register:
|
-- Example lsr.l D2,D2
|
-- Example lsr.l D2,D2
|
-- Thanks to Peter Graf for report
|
-- Thanks to Peter Graf for report
|
--
|
--
|
Line 53... |
Line 60... |
-- Add CHK INSTRUCTION
|
-- Add CHK INSTRUCTION
|
-- full decode ILLEGAL INSTRUCTIONS
|
-- full decode ILLEGAL INSTRUCTIONS
|
-- Add FC Output
|
-- Add FC Output
|
-- add odd Address test
|
-- add odd Address test
|
-- add TRACE
|
-- add TRACE
|
-- Movem with regmask==x0000
|
|
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
Line 236... |
Line 242... |
signal movem_addr : std_logic;
|
signal movem_addr : std_logic;
|
signal movem_regaddr : std_logic_vector(3 downto 0);
|
signal movem_regaddr : std_logic_vector(3 downto 0);
|
signal movem_mask : std_logic_vector(15 downto 0);
|
signal movem_mask : std_logic_vector(15 downto 0);
|
signal set_get_movem_mask : std_logic;
|
signal set_get_movem_mask : std_logic;
|
signal get_movem_mask : std_logic;
|
signal get_movem_mask : std_logic;
|
|
signal maskzero : std_logic;
|
|
signal test_maskzero : std_logic;
|
signal movem_muxa : std_logic_vector(7 downto 0);
|
signal movem_muxa : std_logic_vector(7 downto 0);
|
signal movem_muxb : std_logic_vector(3 downto 0);
|
signal movem_muxb : std_logic_vector(3 downto 0);
|
signal movem_muxc : std_logic_vector(1 downto 0);
|
signal movem_muxc : std_logic_vector(1 downto 0);
|
signal movem_presub : std_logic;
|
signal movem_presub : std_logic;
|
signal save_memaddr : std_logic;
|
signal save_memaddr : std_logic;
|
Line 648... |
Line 656... |
rot_cnt <="000001";
|
rot_cnt <="000001";
|
rot_nop <= '0';
|
rot_nop <= '0';
|
get_extendedOPC <= '0';
|
get_extendedOPC <= '0';
|
get_bitnumber <= '0';
|
get_bitnumber <= '0';
|
get_movem_mask <= '0';
|
get_movem_mask <= '0';
|
|
test_maskzero <= '0';
|
movepl <= '0';
|
movepl <= '0';
|
movepw <= '0';
|
movepw <= '0';
|
test_delay <= "000";
|
test_delay <= "000";
|
PCmarker <= '0';
|
PCmarker <= '0';
|
ELSIF rising_edge(clk) THEN
|
ELSIF rising_edge(clk) THEN
|
IF clkena_in='1' THEN
|
IF clkena_in='1' THEN
|
get_extendedOPC <= set_get_extendedOPC;
|
get_extendedOPC <= set_get_extendedOPC;
|
get_bitnumber <= set_get_bitnumber;
|
get_bitnumber <= set_get_bitnumber;
|
get_movem_mask <= set_get_movem_mask;
|
get_movem_mask <= set_get_movem_mask;
|
|
test_maskzero <= get_movem_mask;
|
setstate_delay <= setstate;
|
setstate_delay <= setstate;
|
|
|
TG68_PC_dec <= TG68_PC_dec(0)&set_TG68_PC_dec;
|
TG68_PC_dec <= TG68_PC_dec(0)&set_TG68_PC_dec;
|
IF directPC='1' AND clkena='1' THEN
|
IF directPC='1' AND clkena='1' THEN
|
TG68_PC <= data_read;
|
TG68_PC <= data_read;
|
Line 1003... |
Line 1013... |
END PROCESS;
|
END PROCESS;
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Write Reg
|
-- Write Reg
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
PROCESS (clkena, OP1in, datatype, presub, postadd, endOPC, regwrena, state, execOPC, last_data_read, movem_addr, rf_dest_addr, reg_QA)
|
PROCESS (clkena, OP1in, datatype, presub, postadd, endOPC, regwrena, state, execOPC, last_data_read, movem_addr, rf_dest_addr, reg_QA, maskzero)
|
BEGIN
|
BEGIN
|
Lwrena <= '0';
|
Lwrena <= '0';
|
Hwrena <= '0';
|
Hwrena <= '0';
|
registerin <= OP1in;
|
registerin <= OP1in;
|
|
|
IF (presub='1' OR postadd='1') AND endOPC='0' THEN -- -(An)+
|
IF (presub='1' OR postadd='1') AND endOPC='0' THEN -- -(An)+
|
Hwrena <= '1';
|
Hwrena <= '1';
|
Lwrena <= '1';
|
Lwrena <= '1';
|
ELSIF Regwrena='1' THEN --read (mem)
|
ELSIF Regwrena='1' AND maskzero='0' THEN --read (mem)
|
Lwrena <= '1';
|
Lwrena <= '1';
|
CASE datatype IS
|
CASE datatype IS
|
WHEN "00" => --BYTE
|
WHEN "00" => --BYTE
|
registerin(15 downto 8) <= reg_QA(15 downto 8);
|
registerin(15 downto 8) <= reg_QA(15 downto 8);
|
WHEN "01" => --WORD
|
WHEN "01" => --WORD
|
Line 1191... |
Line 1201... |
END PROCESS;
|
END PROCESS;
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- execute opcode
|
-- execute opcode
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
PROCESS (clk, reset, OP2out, opcode, fetchOPC, decodeOPC, execOPC, endOPC, nextpass, condition, set_V_flag, trapmake, trapd, interrupt, trap_interrupt,
|
PROCESS (clk, reset, OP2out, opcode, fetchOPC, decodeOPC, execOPC, endOPC, nextpass, condition, set_V_flag, trapmake, trapd, interrupt, trap_interrupt, rot_nop,
|
Z_error, c_in, rot_cnt, one_bit_in, bit_number_reg, bit_number, ea_only, get_ea_now, ea_build, datatype, exec_write_back, get_extendedOPC,
|
Z_error, c_in, rot_cnt, one_bit_in, bit_number_reg, bit_number, ea_only, get_ea_now, ea_build, datatype, exec_write_back, get_extendedOPC,
|
Flags, SVmode, movem_addr, movem_busy, getbrief, set_exec_AND, set_exec_OR, set_exec_EOR, TG68_PC_dec, c_out, OP1out, micro_state)
|
Flags, SVmode, movem_addr, movem_busy, getbrief, set_exec_AND, set_exec_OR, set_exec_EOR, TG68_PC_dec, c_out, OP1out, micro_state)
|
BEGIN
|
BEGIN
|
TG68_PC_br8 <= '0';
|
TG68_PC_br8 <= '0';
|
TG68_PC_brw <= '0';
|
TG68_PC_brw <= '0';
|
Line 1865... |
Line 1875... |
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
|
WHEN "101"=> --tst, tas
|
WHEN "101"=> --tst, tas
|
|
IF opcode(7 downto 2)="111111" THEN --4AFC illegal
|
|
trap_illegal <= '1';
|
|
trapmake <= '1';
|
|
ELSE
|
IF decodeOPC='1' THEN
|
IF decodeOPC='1' THEN
|
ea_build <= '1';
|
ea_build <= '1';
|
END IF;
|
END IF;
|
IF execOPC='1' THEN
|
IF execOPC='1' THEN
|
dest_hbits <= '1'; --for Flags
|
dest_hbits <= '1'; --for Flags
|
Line 1884... |
Line 1898... |
datatype <= "00"; --Byte
|
datatype <= "00"; --Byte
|
IF execOPC='1' AND endOPC='1' THEN
|
IF execOPC='1' AND endOPC='1' THEN
|
regwrena <= '1';
|
regwrena <= '1';
|
END IF;
|
END IF;
|
END IF;
|
END IF;
|
|
END IF;
|
-- WHEN "110"=>
|
-- WHEN "110"=>
|
WHEN "111"=> --4EXX
|
WHEN "111"=> --4EXX
|
IF opcode(7)='1' THEN --jsr, jmp
|
IF opcode(7)='1' THEN --jsr, jmp
|
datatype <= "10";
|
datatype <= "10";
|
ea_only <= '1';
|
ea_only <= '1';
|
Line 3183... |
Line 3198... |
("0000"&movem_mask(12))+("0000"&movem_mask(13))+("0000"&movem_mask(14))+("0000"&movem_mask(15));
|
("0000"&movem_mask(12))+("0000"&movem_mask(13))+("0000"&movem_mask(14))+("0000"&movem_mask(15));
|
|
|
IF reset = '0' THEN
|
IF reset = '0' THEN
|
movem_busy <= '0';
|
movem_busy <= '0';
|
movem_addr <= '0';
|
movem_addr <= '0';
|
|
maskzero <= '0';
|
ELSIF rising_edge(clk) THEN
|
ELSIF rising_edge(clk) THEN
|
IF clkena_in='1' AND get_movem_mask='1' THEN
|
IF clkena_in='1' AND get_movem_mask='1' THEN
|
movem_mask <= data_read(15 downto 0);
|
movem_mask <= data_read(15 downto 0);
|
END IF;
|
END IF;
|
|
IF clkena_in='1' AND test_maskzero='1' THEN
|
|
IF movem_mask=X"0000" THEN
|
|
maskzero <= '1';
|
|
END IF;
|
|
END IF;
|
|
IF clkena_in='1' AND endOPC='1' THEN
|
|
maskzero <= '0';
|
|
END IF;
|
IF clkena='1' THEN
|
IF clkena='1' THEN
|
IF set_movem_busy='1' THEN
|
IF set_movem_busy='1' THEN
|
IF movem_bits(3 downto 1) /= "000" OR opcode(10)='0' THEN
|
IF movem_bits(4 downto 1) /= "0000" OR opcode(10)='0' THEN
|
movem_busy <= '1';
|
movem_busy <= '1';
|
END IF;
|
END IF;
|
movem_addr <= '1';
|
movem_addr <= '1';
|
END IF;
|
END IF;
|
IF movem_addr='1' THEN
|
IF movem_addr='1' THEN
|