Line 1... |
Line 1... |
--##############################################################################
|
--##############################################################################
|
-- light8080 : Intel 8080 binary compatible core
|
-- light8080 : Intel 8080 binary compatible core
|
--##############################################################################
|
--##############################################################################
|
|
-- v1.3 (12 FEB 2012) Fix: General solution to AND, OR, XOR clearing CY,ACY.
|
-- v1.2 (08 jul 2010) Fix: XOR operations were not clearing CY,ACY.
|
-- v1.2 (08 jul 2010) Fix: XOR operations were not clearing CY,ACY.
|
-- v1.1 (20 sep 2008) Microcode bug in INR fixed.
|
-- v1.1 (20 sep 2008) Microcode bug in INR fixed.
|
-- v1.0 (05 nov 2007) First release. Jose A. Ruiz.
|
-- v1.0 (05 nov 2007) First release. Jose A. Ruiz.
|
--
|
--
|
-- This file and all the light8080 project files are freeware (See COPYING.TXT)
|
-- This file and all the light8080 project files are freeware (See COPYING.TXT)
|
Line 57... |
Line 58... |
--##############################################################################
|
--##############################################################################
|
-- All memory and io accesses are synchronous (rising clock edge). Signal vma
|
-- All memory and io accesses are synchronous (rising clock edge). Signal vma
|
-- works as the master memory and io synchronous enable. More specifically:
|
-- works as the master memory and io synchronous enable. More specifically:
|
--
|
--
|
-- * All memory/io control signals (io,rd,wr) are valid only when vma is
|
-- * All memory/io control signals (io,rd,wr) are valid only when vma is
|
-- high. They never activate when vms is inactive.
|
-- high. They never activate when vma is inactive.
|
-- * Signals data_out and address are only valid when vma='1'. The high
|
-- * Signals data_out and address are only valid when vma='1'. The high
|
-- address byte is 0x00 for all io accesses.
|
-- address byte is 0x00 for all io accesses.
|
-- * Signal data_in should be valid by the end of the cycle after vma='1',
|
-- * Signal data_in should be valid by the end of the cycle after vma='1',
|
-- data is clocked in by the rising clock edge.
|
-- data is clocked in by the rising clock edge.
|
--
|
--
|
Line 231... |
Line 232... |
"00001000000000000000110000011111", -- 03c
|
"00001000000000000000110000011111", -- 03c
|
"00000100011000111000001101001110", -- 03d
|
"00000100011000111000001101001110", -- 03d
|
"00001000000000000000110000011111", -- 03e
|
"00001000000000000000110000011111", -- 03e
|
"00000100011000111000001101001111", -- 03f
|
"00000100011000111000001101001111", -- 03f
|
"00001000000000000000110000011111", -- 040
|
"00001000000000000000110000011111", -- 040
|
"00000100011000111000001101000100", -- 041
|
"00000100011000111100001101000100", -- 041
|
"00001000000000000000110000011111", -- 042
|
"00001000000000000000110000011111", -- 042
|
"00000100011000111000001101000101", -- 043
|
"00000100011000111100001101000101", -- 043
|
"00001000000000000000110000011111", -- 044
|
"00001000000000000000110000011111", -- 044
|
"00000100011000111000001101000110", -- 045
|
"00000100011000111100001101000110", -- 045
|
"00001000000000000000110000011111", -- 046
|
"00001000000000000000110000011111", -- 046
|
"00000100011000111000001110001110", -- 047
|
"00000100011000111000001110001110", -- 047
|
"00000000101010000000000000000000", -- 048
|
"00000000101010000000000000000000", -- 048
|
"00000100011000111000001101001100", -- 049
|
"00000100011000111000001101001100", -- 049
|
"00000000101010000000000000000000", -- 04a
|
"00000000101010000000000000000000", -- 04a
|
Line 247... |
Line 248... |
"00000000101010000000000000000000", -- 04c
|
"00000000101010000000000000000000", -- 04c
|
"00000100011000111000001101001110", -- 04d
|
"00000100011000111000001101001110", -- 04d
|
"00000000101010000000000000000000", -- 04e
|
"00000000101010000000000000000000", -- 04e
|
"00000100011000111000001101001111", -- 04f
|
"00000100011000111000001101001111", -- 04f
|
"00000000101010000000000000000000", -- 050
|
"00000000101010000000000000000000", -- 050
|
"00000100011000111000001101000100", -- 051
|
"00000100011000111100001101000100", -- 051
|
"00000000101010000000000000000000", -- 052
|
"00000000101010000000000000000000", -- 052
|
"00000100011000111000001101000101", -- 053
|
"00000100011000111100001101000101", -- 053
|
"00000000101010000000000000000000", -- 054
|
"00000000101010000000000000000000", -- 054
|
"00000100011000111000001101000110", -- 055
|
"00000100011000111100001101000110", -- 055
|
"00000000101010000000000000000000", -- 056
|
"00000000101010000000000000000000", -- 056
|
"00000100011000111000001110001110", -- 057
|
"00000100011000111000001110001110", -- 057
|
"00001000000000000000110000011001", -- 058
|
"00001000000000000000110000011001", -- 058
|
"00000100011000111000001101001100", -- 059
|
"00000100011000111000001101001100", -- 059
|
"00001000000000000000110000011001", -- 05a
|
"00001000000000000000110000011001", -- 05a
|
Line 263... |
Line 264... |
"00001000000000000000110000011001", -- 05c
|
"00001000000000000000110000011001", -- 05c
|
"00000100011000111000001101001110", -- 05d
|
"00000100011000111000001101001110", -- 05d
|
"00001000000000000000110000011001", -- 05e
|
"00001000000000000000110000011001", -- 05e
|
"00000100011000111000001101001111", -- 05f
|
"00000100011000111000001101001111", -- 05f
|
"00001000000000000000110000011001", -- 060
|
"00001000000000000000110000011001", -- 060
|
"00000100011000111000001101000100", -- 061
|
"00000100011000111100001101000100", -- 061
|
"00001000000000000000110000011001", -- 062
|
"00001000000000000000110000011001", -- 062
|
"00000100011000111000001101000101", -- 063
|
"00000100011000111100001101000101", -- 063
|
"00001000000000000000110000011001", -- 064
|
"00001000000000000000110000011001", -- 064
|
"00000100011000111000001101000110", -- 065
|
"00000100011000111100001101000110", -- 065
|
"00001000000000000000110000011001", -- 066
|
"00001000000000000000110000011001", -- 066
|
"00000100011000111000001110001110", -- 067
|
"00000100011000111000001110001110", -- 067
|
"10111100101100000000001001001101", -- 068
|
"10111100101100000000001001001101", -- 068
|
"00000100000000000000000000000000", -- 069
|
"00000100000000000000000000000000", -- 069
|
"00001000000000000000110000011001", -- 06a
|
"00001000000000000000110000011001", -- 06a
|
Line 707... |
Line 708... |
signal inhibit_pc_increment : std_logic; -- avoid PC changes (during INTA)
|
signal inhibit_pc_increment : std_logic; -- avoid PC changes (during INTA)
|
signal rbank_rd_addr: std_logic_vector(3 downto 0); -- rbank rd addr
|
signal rbank_rd_addr: std_logic_vector(3 downto 0); -- rbank rd addr
|
signal rbank_wr_addr: std_logic_vector(3 downto 0); -- rbank wr addr
|
signal rbank_wr_addr: std_logic_vector(3 downto 0); -- rbank wr addr
|
signal DO : std_logic_vector(7 downto 0); -- data output reg
|
signal DO : std_logic_vector(7 downto 0); -- data output reg
|
|
|
-- Register bank as an array of 16 bytes (asynch. LUT ram)
|
-- Register bank as an array of 16 bytes.
|
|
-- This will be implemented as asynchronous LUT RAM in those devices where this
|
|
-- feature is available (Xilinx) and as multiplexed registers where it isn't
|
|
-- (Altera).
|
type t_reg_bank is array(0 to 15) of std_logic_vector(7 downto 0);
|
type t_reg_bank is array(0 to 15) of std_logic_vector(7 downto 0);
|
-- Register bank : BC, DE, HL, AF, [PC, XY, ZW, SP]
|
-- Register bank : BC, DE, HL, AF, [PC, XY, ZW, SP]
|
signal rbank : t_reg_bank;
|
signal rbank : t_reg_bank;
|
|
|
signal flag_reg : std_logic_vector(7 downto 0); -- F register
|
signal flag_reg : std_logic_vector(7 downto 0); -- F register
|
Line 726... |
Line 730... |
signal do_cy_op : std_logic; -- ALU explicit CY operation (CPC, etc.)
|
signal do_cy_op : std_logic; -- ALU explicit CY operation (CPC, etc.)
|
signal do_cy_op_d : std_logic; -- do_cy_op, pipelined
|
signal do_cy_op_d : std_logic; -- do_cy_op, pipelined
|
signal do_cpc : std_logic; -- ALU operation is CPC
|
signal do_cpc : std_logic; -- ALU operation is CPC
|
signal do_cpc_d : std_logic; -- do_cpc, pipelined
|
signal do_cpc_d : std_logic; -- do_cpc, pipelined
|
signal do_daa : std_logic; -- ALU operation is DAA
|
signal do_daa : std_logic; -- ALU operation is DAA
|
signal do_xor : std_logic; -- ALU operation is some XOR (clears CY)
|
signal clear_cy : std_logic; -- Instruction unconditionally clears CY
|
|
signal clear_ac : std_logic; -- Instruction unconditionally clears AC
|
|
signal set_ac : std_logic; -- Instruction unconditionally sets AC
|
signal flag_ac : std_logic; -- new computed half carry flag
|
signal flag_ac : std_logic; -- new computed half carry flag
|
-- flag_aux_cy: new computed half carry flag (used in 16-bit ops)
|
-- flag_aux_cy: new computed half carry flag (used in 16-bit ops)
|
signal flag_aux_cy : std_logic;
|
signal flag_aux_cy : std_logic;
|
signal load_psw : std_logic; -- load F register
|
signal load_psw : std_logic; -- load F register
|
|
|
Line 1122... |
Line 1128... |
flag_pattern <= ucode_field2(9 downto 8);
|
flag_pattern <= ucode_field2(9 downto 8);
|
use_aux_cy <= ucode_field2(19);
|
use_aux_cy <= ucode_field2(19);
|
do_cpc <= ucode_field2(23);
|
do_cpc <= ucode_field2(23);
|
do_cy_op <= ucode_field2(24);
|
do_cy_op <= ucode_field2(24);
|
do_daa <= '1' when ucode_field2(5 downto 2) = "1010" else '0';
|
do_daa <= '1' when ucode_field2(5 downto 2) = "1010" else '0';
|
do_xor <= '1' when ucode_field2(5 downto 0) = "000101" else '0';
|
|
|
-- ucode_field2(14) will be set for those instructions that modify CY and AC
|
|
-- without following the standard rules -- AND, OR and XOR instructions.
|
|
|
|
-- Some instructions will unconditionally clear CY (AND, OR, XOR)
|
|
clear_cy <= ucode_field2(14);
|
|
|
|
-- Some instructions will unconditionally clear AC (OR, XOR)...
|
|
clear_ac <= '1' when ucode_field2(14) = '1' and
|
|
ucode_field2(5 downto 0) /= "000100"
|
|
else '0';
|
|
-- ...and some others unconditionally SET AC (AND)
|
|
set_ac <= '1' when ucode_field2(14) = '1' and
|
|
ucode_field2(5 downto 0) = "000100"
|
|
else '0';
|
|
|
aux_cy_in <= reg_aux_cy when set_aux_cy = '0' else '1';
|
aux_cy_in <= reg_aux_cy when set_aux_cy = '0' else '1';
|
|
|
-- carry input selection: normal or aux (for 16 bit increments)?
|
-- carry input selection: normal or aux (for 16 bit increments)?
|
cy_in <= flag_reg(0) when use_aux_cy = '0' else aux_cy_in;
|
cy_in <= flag_reg(0) when use_aux_cy = '0' else aux_cy_in;
|
Line 1228... |
Line 1248... |
|
|
flag_s <= alu_output(7);
|
flag_s <= alu_output(7);
|
flag_p <= not(alu_output(7) xor alu_output(6) xor alu_output(5) xor alu_output(4) xor
|
flag_p <= not(alu_output(7) xor alu_output(6) xor alu_output(5) xor alu_output(4) xor
|
alu_output(3) xor alu_output(2) xor alu_output(1) xor alu_output(0));
|
alu_output(3) xor alu_output(2) xor alu_output(1) xor alu_output(0));
|
flag_z <= '1' when alu_output=X"00" else '0';
|
flag_z <= '1' when alu_output=X"00" else '0';
|
-- FIXED 08/JUL/2010: XOR was not clearing AC as it should
|
-- AC is either the CY from bit 4 OR 0 if the instruction clears it implicitly
|
--flag_ac <= (arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4));
|
flag_ac <= '1' when set_ac = '1' else
|
flag_ac <= (arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4)) and not do_xor;
|
'0' when clear_ac = '1' else
|
|
(arith_op1(4) xor arith_op2_sgn(4) xor alu_output(4));
|
-- FIXED 08/JUL/2010: XOR was not clearing CY as it should
|
|
--flag_cy_1 <= cy_arith when use_logic = '1' else cy_shifter;
|
-- CY comes from the adder or the shifter, or is 0 if the instruction
|
flag_cy_1 <= '0' when do_xor='1' else
|
-- implicitly clears it.
|
cy_arith when use_logic = '1' and do_xor='0' else
|
flag_cy_1 <= '0' when clear_cy = '1' else
|
|
cy_arith when use_logic = '1' and clear_cy = '0' else
|
cy_shifter;
|
cy_shifter;
|
flag_cy_2 <= not flag_reg(0) when do_cpc='0' else '1'; -- cmc, stc
|
flag_cy_2 <= not flag_reg(0) when do_cpc='0' else '1'; -- cmc, stc
|
flag_cy <= flag_cy_1 when do_cy_op='0' else flag_cy_2;
|
flag_cy <= flag_cy_1 when do_cy_op='0' else flag_cy_2;
|
|
|
flag_aux_cy <= cy_adder;
|
flag_aux_cy <= cy_adder;
|