Line 85... |
Line 85... |
-- : This setting also sets I bit at startup so that any
|
-- : This setting also sets I bit at startup so that any
|
-- : initialization code may be run in an ISR context, initially
|
-- : initialization code may be run in an ISR context, initially
|
-- : bypassing memory protection. Init code should clear the I bit
|
-- : bypassing memory protection. Init code should clear the I bit
|
-- : when done;
|
-- : when done;
|
-- :
|
-- :
|
|
-- : Unsigned_Index_Offsets alters the way offsets are added to
|
|
-- : [Rn+1:Rn] during LDO/STO instructions. The original, defeault
|
|
-- : behavior treats these offsets as signed values, allowing
|
|
-- : instructions to offset by -128 to +127 from [Rn+1:Rn].
|
|
-- : Setting this generic to TRUE will switch to unsigned offsets,
|
|
-- : switching the range to 0 to 255 instead.
|
|
-- :
|
-- : Default_Interrupt_Mask sets the intial/reset value of the
|
-- : Default_Interrupt_Mask sets the intial/reset value of the
|
-- : interrupt mask. To remain true to the original core, which
|
-- : interrupt mask. To remain true to the original core, which
|
-- : had no interrupt mask, this should be set to x"FF". Otherwise
|
-- : had no interrupt mask, this should be set to x"FF". Otherwise
|
-- : it can be initialized to any value. Note that Enable_NMI
|
-- : it can be initialized to any value. Note that Enable_NMI
|
-- : will logically force the LSB high.
|
-- : will logically force the LSB high.
|
Line 335... |
Line 342... |
constant INT_VECTOR_4 : std_logic_vector(3 downto 0) := x"8";
|
constant INT_VECTOR_4 : std_logic_vector(3 downto 0) := x"8";
|
constant INT_VECTOR_5 : std_logic_vector(3 downto 0) := x"A";
|
constant INT_VECTOR_5 : std_logic_vector(3 downto 0) := x"A";
|
constant INT_VECTOR_6 : std_logic_vector(3 downto 0) := x"C";
|
constant INT_VECTOR_6 : std_logic_vector(3 downto 0) := x"C";
|
constant INT_VECTOR_7 : std_logic_vector(3 downto 0) := x"E";
|
constant INT_VECTOR_7 : std_logic_vector(3 downto 0) := x"E";
|
|
|
|
signal IDX_Offset_SX : std_logic := '0';
|
|
|
signal IDX_Offset : ADDRESS_TYPE := x"0000";
|
signal IDX_Offset : ADDRESS_TYPE := x"0000";
|
|
|
|
signal IDX_Sel_l : std_logic_vector(2 downto 0) := "000";
|
|
signal IDX_Sel_h : std_logic_vector(2 downto 0) := "000";
|
|
|
signal IDX_Reg_l : integer := 0;
|
signal IDX_Reg_l : integer := 0;
|
signal IDX_Reg_h : integer := 0;
|
signal IDX_Reg_h : integer := 0;
|
|
|
signal IDX_NoOffset_Calc : ADDRESS_TYPE := x"0000";
|
signal IDX_NoOffset_Calc : ADDRESS_TYPE := x"0000";
|
signal IDX_Offset_Calc : ADDRESS_TYPE := x"0000";
|
signal IDX_Offset_Calc : ADDRESS_TYPE := x"0000";
|
Line 386... |
Line 398... |
|
|
-- Address selection logic based on current CPU state. This is combinatorial,
|
-- Address selection logic based on current CPU state. This is combinatorial,
|
-- as adding pipeline registration would add a clock cycle to every instr,
|
-- as adding pipeline registration would add a clock cycle to every instr,
|
-- without really adding the Fmax to compensate.
|
-- without really adding the Fmax to compensate.
|
Address_Logic: process(CPU_State, Operand1, Operand2, IDX_NoOffset_Calc,
|
Address_Logic: process(CPU_State, Operand1, Operand2, IDX_NoOffset_Calc,
|
IDX_Offset_Calc, ISR_Addr_Offset, Stack_Ptr, Program_Ctr )
|
IDX_Offset_Calc, ISR_Addr_Offset, Stack_Ptr,
|
|
Program_Ctr )
|
begin
|
begin
|
case( CPU_State )is
|
case( CPU_State )is
|
|
|
when LDA_C2 | STA_C2 =>
|
when LDA_C2 | STA_C2 =>
|
Open8_Bus.Address <= Operand2 & Operand1;
|
Open8_Bus.Address <= Operand2 & Operand1;
|
Line 402... |
Line 415... |
Open8_Bus.Address <= IDX_Offset_Calc;
|
Open8_Bus.Address <= IDX_Offset_Calc;
|
|
|
when ISR_C1 | ISR_C2 =>
|
when ISR_C1 | ISR_C2 =>
|
Open8_Bus.Address <= ISR_Addr_Base & ISR_Addr_Offset;
|
Open8_Bus.Address <= ISR_Addr_Base & ISR_Addr_Offset;
|
|
|
when PSH_C1 | POP_C1 | ISR_C3 | JSR_C1 | JSR_C2 | RTS_C1 | RTS_C2 | RTS_C3 =>
|
when PSH_C1 | POP_C1 |
|
|
ISR_C3 | JSR_C1 | JSR_C2 |
|
|
RTS_C1 | RTS_C2 | RTS_C3 =>
|
Open8_Bus.Address <= Stack_Ptr;
|
Open8_Bus.Address <= Stack_Ptr;
|
|
|
when others =>
|
when others =>
|
Open8_Bus.Address <= Program_Ctr;
|
Open8_Bus.Address <= Program_Ctr;
|
|
|
Line 416... |
Line 431... |
-- The original model treated the offset to LDO/STO as a signed value
|
-- The original model treated the offset to LDO/STO as a signed value
|
-- allowing access to locations -128 to +127 from [Rn+1:Rn]. This isn't
|
-- allowing access to locations -128 to +127 from [Rn+1:Rn]. This isn't
|
-- always helpful, so the generic allows the CPU to use unsigned math
|
-- always helpful, so the generic allows the CPU to use unsigned math
|
-- for the offsets. This makes the range 0 to +255 instead.
|
-- for the offsets. This makes the range 0 to +255 instead.
|
|
|
Unsigned_Idx_Offsets : if( Unsigned_Index_Offsets )generate
|
IDX_Offset_SX <= '0' when Unsigned_Index_Offsets else Operand1(7);
|
IDX_Offset(15 downto 8) <= (others => '0');
|
|
IDX_Offset(7 downto 0) <= Operand1;
|
|
end generate;
|
|
|
|
Signed_Idx_Offsets: if( not Unsigned_Index_Offsets )generate
|
IDX_Offset(15 downto 8) <= (others => IDX_Offset_SX);
|
IDX_Offset(15 downto 8) <= (others => Operand1(7));
|
|
IDX_Offset(7 downto 0) <= Operand1;
|
IDX_Offset(7 downto 0) <= Operand1;
|
end generate;
|
|
|
|
-- Enable_Auto_Increment uses the LSB to determine whether or not to
|
-- Enable_Auto_Increment uses the LSB to determine whether or not to
|
-- do the auto-increment, so we need to lock the LSB for each operand
|
-- do the auto-increment, so we need to lock the LSB for each operand
|
-- if it is enabled. This forces [ODD:EVEN] pairing.
|
-- if it is enabled. This forces [ODD:EVEN] pairing.
|
|
|
Auto_Incr_Set: if( Enable_Auto_Increment )generate
|
IDX_Sel_l <= (SubOp(2 downto 1) & '0') when Enable_Auto_Increment else
|
IDX_Reg_l <= conv_integer(SubOp(2 downto 1) & '0');
|
SubOp;
|
IDX_Reg_h <= conv_integer(SubOp(2 downto 1) & '1');
|
|
end generate;
|
IDX_Sel_h <= (SubOp(2 downto 1) & '1') when Enable_Auto_Increment else
|
|
SubOp_p1;
|
Auto_Incr_Not_Set: if( not Enable_Auto_Increment )generate
|
|
IDX_Reg_l <= conv_integer(SubOp);
|
IDX_Reg_l <= conv_integer(IDX_Sel_l);
|
IDX_Reg_h <= conv_integer(SubOp_p1);
|
IDX_Reg_h <= conv_integer(IDX_Sel_h);
|
end generate;
|
|
|
|
-- Pipeline registers for the indexed and indexed with offset addresses.
|
-- Pipeline registers for the indexed and indexed with offset addresses.
|
Idx_Addr_Calc_proc: process( Clock, Reset )
|
Idx_Addr_Calc_proc: process( Clock, Reset )
|
variable Reg, Reg_1 : integer range 0 to 7 := 0;
|
variable Reg, Reg_1 : integer range 0 to 7 := 0;
|
begin
|
begin
|