Line 106... |
Line 106... |
-- : behavior treats these offsets as signed values, allowing
|
-- : behavior treats these offsets as signed values, allowing
|
-- : instructions to offset by -128 to +127 from [Rn+1:Rn].
|
-- : instructions to offset by -128 to +127 from [Rn+1:Rn].
|
-- : Setting this generic to TRUE will switch to unsigned offsets,
|
-- : Setting this generic to TRUE will switch to unsigned offsets,
|
-- : switching the range to 0 to 255 instead.
|
-- : switching the range to 0 to 255 instead.
|
-- :
|
-- :
|
|
-- : Rotate_Ignores_Carry alters the ROL and ROR instructions to
|
|
-- : not rotate through, or alter, the carry bit. When enabled,
|
|
-- : ROL performs Rn <= Rn<<1 and ROR performs Rn <= 1>>Rn. Note
|
|
-- : that unlike the original instructions, the C bit is not
|
|
-- : altered.
|
|
-- :
|
-- : 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 264... |
Line 270... |
-- Seth Henry 10/23/20 Moved CPU internal constants to o8_cpu.vhd. Also
|
-- Seth Henry 10/23/20 Moved CPU internal constants to o8_cpu.vhd. Also
|
-- removed Stack_Xfer_Flag, which specified the CPU
|
-- removed Stack_Xfer_Flag, which specified the CPU
|
-- flag used to alter the RSP instruction, making it
|
-- flag used to alter the RSP instruction, making it
|
-- a constant instead (PSR_GP4). This eliminated the
|
-- a constant instead (PSR_GP4). This eliminated the
|
-- need to expose an internal constant externally
|
-- need to expose an internal constant externally
|
|
-- Seth Henry 05/01/21 Added the Rotate_Ignores_Carry generic, which
|
|
-- alters the ROR and ROL instructions to behave more
|
|
-- like expected by not rotating through the C flag
|
|
|
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;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
Line 287... |
Line 296... |
Enable_NMI : boolean := true; -- Force INTR0 enabled
|
Enable_NMI : boolean := true; -- Force INTR0 enabled
|
Sequential_Interrupts : boolean := false; -- Interruptable ISRs
|
Sequential_Interrupts : boolean := false; -- Interruptable ISRs
|
RTI_Ignores_GP_Flags : boolean := false; -- RTI sets all flags
|
RTI_Ignores_GP_Flags : boolean := false; -- RTI sets all flags
|
Supervisor_Mode : boolean := false; -- I bit is restricted
|
Supervisor_Mode : boolean := false; -- I bit is restricted
|
Unsigned_Index_Offsets : boolean := false; -- Offsets are signed
|
Unsigned_Index_Offsets : boolean := false; -- Offsets are signed
|
|
Rotate_Ignores_Carry : boolean := false; -- Rotate thru Carry
|
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
|
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
|
Clock_Frequency : real -- Clock Frequency
|
Clock_Frequency : real -- Clock Frequency
|
);
|
);
|
port(
|
port(
|
Clock : in std_logic;
|
Clock : in std_logic;
|
Line 1557... |
Line 1567... |
Temp(7 downto 0) := Regfile(0) xor Regfile(Index);
|
Temp(7 downto 0) := Regfile(0) xor Regfile(Index);
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
Flags(PSR_N) <= Temp(7);
|
Flags(PSR_N) <= Temp(7);
|
Regfile(0) <= Temp(7 downto 0);
|
Regfile(0) <= Temp(7 downto 0);
|
|
|
when ALU_ROL => -- Rn = Rn<<1,C : Flags N,C,Z
|
when ALU_ROL => -- Varies based on config
|
|
if( Rotate_Ignores_Carry )then
|
|
-- Rn = Rn<<1 : Flags N,Z
|
|
Temp(7 downto 0) := Regfile(Index)(6 downto 0) & Regfile(Index)(7);
|
|
else
|
|
-- Rn = Rn<<1,C : Flags N,C,Z
|
Temp := Regfile(Index) & Flags(PSR_C);
|
Temp := Regfile(Index) & Flags(PSR_C);
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
|
Flags(PSR_C) <= Temp(8);
|
Flags(PSR_C) <= Temp(8);
|
|
end if;
|
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
Flags(PSR_N) <= Temp(7);
|
Flags(PSR_N) <= Temp(7);
|
Regfile(Index) <= Temp(7 downto 0);
|
Regfile(Index) <= Temp(7 downto 0);
|
|
|
when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z
|
when ALU_ROR => -- Varies based on config
|
|
if( Rotate_Ignores_Carry )then
|
|
-- Rn = Rn>>1 : Flags N,Z
|
|
Temp(7 downto 0) := Regfile(Index)(0) & Regfile(Index)(7 downto 1);
|
|
else
|
|
-- Rn = C,Rn>>1 : Flags N,C,Z
|
Temp := Regfile(Index)(0) & Flags(PSR_C) &
|
Temp := Regfile(Index)(0) & Flags(PSR_C) &
|
Regfile(Index)(7 downto 1);
|
Regfile(Index)(7 downto 1);
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
|
Flags(PSR_C) <= Temp(8);
|
Flags(PSR_C) <= Temp(8);
|
|
end if;
|
|
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
|
Flags(PSR_N) <= Temp(7);
|
Flags(PSR_N) <= Temp(7);
|
Regfile(Index) <= Temp(7 downto 0);
|
Regfile(Index) <= Temp(7 downto 0);
|
|
|
when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z
|
when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z
|
Sum := ("0" & Regfile(Index)) +
|
Sum := ("0" & Regfile(Index)) +
|