OpenCores
URL https://opencores.org/ocsvn/v6502/v6502/trunk

Subversion Repositories v6502

[/] [v6502/] [trunk/] [pr.vhd] - Rev 6

Compare with Previous | Blame | View Log

library IEEE;
use IEEE.std_logic_1164.all;  -- defines std_logic types
use IEEE.STD_LOGIC_unsigned.all;
use IEEE.STD_LOGIC_arith.all;
 
-- 8 bit processor status register P
-- NV1BDIZC    
-- 76543210
-- ||||||||
-- ||||||||--- C = carry/borrow flag
-- |||||||---- Z = zero flag
-- ||||||----- I = interrupt mask
-- |||||------ D = decimal/binary alu mode
-- ||||------- B = break opcode flag
-- |||-------- 1 = always "1'
-- ||--------- V = overflow flag
-- |---------- N = negative flag
entity pr is
  port(      clk:  in STD_LOGIC;                        -- clock
             clr:  in STD_LOGIC;                        -- clear
           fwait:  in STD_LOGIC; 
               n:  in STD_LOGIC;                        -- N input
               v:  in STD_LOGIC;                        -- V input
               z:  in STD_LOGIC;                        -- Z input
               c:  in STD_LOGIC;                        -- C input
               b:  in STD_LOGIC;                        -- B input
              sv:  in STD_LOGIC;                        -- set overflow (by external pin SO) 
          acr_in:  in STD_LOGIC;                        -- auxiliary carry in   
              fc:  in STD_LOGIC_VECTOR(3 downto 0);     -- function code 
             din:  in STD_LOGIC_VECTOR(7 downto 0);     -- input
            dout: out STD_LOGIC_VECTOR(7 downto 0);     -- output
         acr_out: out STD_LOGIC                         -- auxiliary carry out   
      );        
end pr;
 
architecture rtl of pr is
constant NOP_P: STD_LOGIC_VECTOR(3 downto 0) := "0000"; -- PR no operation
constant PLD_P: STD_LOGIC_VECTOR(3 downto 0) := "0001"; -- PR load
constant FLD_P: STD_LOGIC_VECTOR(3 downto 0) := "0010"; -- NZ load
constant FLC_P: STD_LOGIC_VECTOR(3 downto 0) := "0011"; -- NZC load
constant FLV_P: STD_LOGIC_VECTOR(3 downto 0) := "0100"; -- NVZC load
constant SEC_P: STD_LOGIC_VECTOR(3 downto 0) := "0101"; -- 1 => C 
constant CLC_P: STD_LOGIC_VECTOR(3 downto 0) := "0110"; -- 0 => C 
constant SEI_P: STD_LOGIC_VECTOR(3 downto 0) := "0111"; -- 1 => I 
constant CLI_P: STD_LOGIC_VECTOR(3 downto 0) := "1000"; -- 0 => I 
constant SED_P: STD_LOGIC_VECTOR(3 downto 0) := "1001"; -- 1 => D 
constant CLD_P: STD_LOGIC_VECTOR(3 downto 0) := "1010"; -- 0 => D 
constant CLV_P: STD_LOGIC_VECTOR(3 downto 0) := "1011"; -- 0 => V 
constant AUC_P: STD_LOGIC_VECTOR(3 downto 0) := "1100"; -- auc => ACR 
constant HAC_P: STD_LOGIC_VECTOR(3 downto 0) := "1101"; -- hold ACR 
constant SID_P: STD_LOGIC_VECTOR(3 downto 0) := "1110"; -- 1 => I/D 
constant LDZ_P: STD_LOGIC_VECTOR(3 downto 0) := "1111"; -- Z load
 
signal  reg: STD_LOGIC_VECTOR(7 downto 0);
signal  acr: STD_LOGIC;                                                   -- carry/borrow used for effectve address calculation 
signal i_so: STD_LOGIC;
 
begin
  i_so <= reg(6) when sv = '1' else '1';                                  -- logic for external pin SO
  process(clk)
    begin
      if (clk'event and clk = '1') then
        if fwait = '1' then
          reg <= reg;
        else
          if clr = '1' then
            reg <= "00100100";
            acr <= '0';
          else
            case fc is
              when PLD_P  => reg(7 downto 6) <= din(7 downto 6);                      -- load NV1BDIZC 
                             reg(5)          <= '1';
                             reg(4 downto 0) <= din(4 downto 0);
                             acr <= '0';   
              when FLD_P  => reg <= n & reg(6) & '1' & reg(4 downto 2) & z & reg(0);  -- load NZ
                             acr <= '0';   
              when FLC_P  => reg <= n & reg(6) & '1' & reg(4 downto 2) & z & c;       -- load NZC
                             acr <= '0';   
              when FLV_P  => reg <= n & v & '1' & reg(4 downto 2) & z & c;            -- load NZCV
                             acr <= '0';   
              when SEC_P  => reg <= reg or  "00000001";                               -- 1 => C
                             acr <= acr;   
              when CLC_P  => reg <= reg and "11111110";                               -- 0 => C
                             acr <= acr;   
              when CLI_P  => reg <= reg and "11111011";                               -- 0 => I
                             acr <= acr;   
              when SED_P  => reg <= reg or  "00001000";                               -- 1 => D
                             acr <= acr;   
              when CLD_P  => reg <= reg and "11110111";                               -- 0 => D
                             acr <= acr;   
				  when LDZ_P  => reg(1) <= z;                                             -- z => Z
                             reg(7 downto 2) <= reg(7 downto 2);
			                    reg(0) <= reg(0);						  
              when SEI_P  => reg(7 downto 5) <= reg(7 downto 5); 
                             reg(4) <= reg(4);
                             reg(3) <= reg(3);
                             reg(2) <= '1';                                           -- 1 => I
                             reg(1 downto 0) <= reg(1 downto 0);           
                             acr <= acr;   
              when SID_P  => reg(7 downto 5) <= reg(7 downto 5);                      -- set I and clear D decimal flag (used by interrupt sequence)
                             reg(4) <= b;                                             -- 1 => B (if BRK)
                             reg(3) <= '0';                                           -- 0 -> D                                 
                             reg(2) <= '1';                                           -- 1 => I
                             reg(1 downto 0) <= reg(1 downto 0);           
                             acr <= acr;   
              when CLV_P  => reg <= reg and "10111111";                               -- 0 => V
                             acr <= acr;   
              when AUC_P  => acr    <= acr_in;                                        -- store auxiliary carry (ACR)
                             reg    <= reg;               
              when HAC_P  => acr    <= acr;                                           -- holds auxiliary carry (ACR)
                             reg    <= reg;               
              when others => reg(7) <= reg(7);                             
                             reg(6) <= i_so;                                          -- set overflow by pin SO
                             reg(5 downto 0) <= reg(5 downto 0);  
                             acr    <= '0';
            end case;
          end if;    
        end if;
      end if;  
  end process;
  dout <= reg;
  acr_out <= acr;
end rtl;
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.