--------------------------------------------------
-- Model        :   8051 Behavioral Model,
--                  VHDL Entity mc8051.ir_decoder.interface
--
-- Author       :   Michael Mayer (mrmayer@computer.org),
--                  Dr. Hardy J. Pottinger,
--                  Department of Electrical Engineering
--                  University of Missouri - Rolla
--
-- Created at   :   09/19/98 20:02:06
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
LIBRARY mc8051 ;
USE mc8051.cpu_pack.all;
USE mc8051.synth_pack.all;

ENTITY ir_decoder IS
   PORT( 
      alu_second_result : IN     std_logic ;
      cpu_rst : IN     std_logic ;
      cy : IN     std_logic ;
      int_clk : IN     std_logic ;
      ir : IN     std_logic_vector( 7 DOWNTO 0 )  ;
      new_ir : IN     std_logic ;
      alu_cmd : OUT    std_logic_vector( 3 DOWNTO 0 )  ;
      data_alu : OUT    std_logic_vector( 2 DOWNTO 0 )  ;
      data_dest : OUT    std_logic_vector( 2 DOWNTO 0 )  ;
      data_t1 : OUT    std_logic_vector( 2 DOWNTO 0 )  ;
      data_t2 : OUT    std_logic_vector( 2 DOWNTO 0 )  ;
      dest_cmd : OUT    std_logic_vector( 3 DOWNTO 0 )  ;
      read_latch : OUT    std_logic ;
      set_ac_ov : OUT    std_logic ;
      set_cy : OUT    std_logic ;
      t1_cmd : OUT    std_logic_vector( 3 DOWNTO 0 )  ;
      t2_cmd : OUT    std_logic_vector( 3 DOWNTO 0 )  ;
      two_dests : OUT    std_logic ;
      use_acc_0 : OUT    std_logic ;
      use_cy : OUT    std_logic
   );

-- Declarations

END ir_decoder ;
--
-- VHDL Architecture mc8051.ir_decoder.spec
--
-- Created:
--          by - mrmayer.UNKNOWN (eceultra20.ece.umr.edu)
--          at - 23:24:26 09/02/98
--
-- Generated by Mentor Graphics' Renoir(TM) 3.0 (Build 110)
--
architecture spec of ir_decoder is

   SIGNAL cy_int : std_logic;
   SIGNAL ir_10  : bit_vector(7 DOWNTO 0);
BEGIN

--t1, t2, alu, and dest each get 4 bits of cmd + 3 bits of data.
--this means we need a 8bit (opcode) to 16 bit (4x4 cmds) converter
--and then driver for the 12 bits (4x3) of data

-- latch with new_ir
cy_int    <= cy WHEN new_ir = '1' ELSE cy_int;
ir_10     <= To_bitvector (ir);
read_latch <= '0';   -- ALL ARE CONSIDERED READ PINS!!!

p1 : PROCESS (int_clk) IS
BEGIN

two_dests <= '0';
CASE ir_10 IS
  WHEN "00000000" | "10100101" => --NOP, reserved
       t1_cmd      <= zeros;       data_t1 <= "000";
       t2_cmd      <= zeros;       data_t2 <= "000";
       alu_cmd     <= pass_tmp1;
       dest_cmd    <= nothing;

  WHEN "00000001" | "00100001" | "01000001" | "01100001" | 
       "10000001" | "10100001" | "11000001" | "11100001" |    --  AJMP
       "00010001" | "00110001" | "01010001" | "01110001" | 
       "10010001" | "10110001" | "11010001" | "11110001" |    --  ACALL
       "00000010" | "00010010" | "00100010" | "00110010" =>   --  LJMP, LCALL, RET, RETI
           t1_cmd      <= nothing; 
           t2_cmd      <= nothing;
           alu_cmd     <= pass_tmp1;
           data_alu    <= "000";
           dest_cmd    <= nothing;   -- pass result to data_gb

  WHEN "11000000" =>   --  PUSH C0
       t1_cmd      <= direct_T;      data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1; 
       dest_cmd    <= wr_at_sp; 

  WHEN "11010000" =>   --  POP D0
       t1_cmd      <= rd_at_sp; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;   data_alu    <= "000";
       dest_cmd    <= direct_T;      data_dest <= "001"; 

  WHEN "00000011" =>   -- RR (03) 
       t1_cmd      <= nothing;
       t2_cmd      <= use_acc;
       alu_cmd     <= rotate;   data_alu <= rr_instr; 
       use_cy      <= '0';
       dest_cmd    <= use_acc;

  WHEN "00010011" =>   -- RRC (13)
       t1_cmd      <= nothing;
       t2_cmd      <= use_acc;
       alu_cmd     <= rotate;   data_alu <= rr_instr;
       use_cy      <= '1';
       dest_cmd    <= use_acc;

  WHEN "00100011" =>   -- RL (23)
       t1_cmd      <= nothing;
       t2_cmd      <= use_acc;
       alu_cmd     <= rotate;   data_alu <= rl_instr;
       use_cy      <= '0';
       dest_cmd    <= use_acc;

  WHEN "00110011" =>   --  RLC (33)
       t1_cmd      <= nothing;
       t2_cmd      <= use_acc;
       alu_cmd     <= rotate;   data_alu <= rl_instr;
       use_cy      <= '1';
       dest_cmd    <= use_acc;

  WHEN "00000100" =>   --  INC A "04"  
       t1_cmd      <= use_acc;
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_inc; 
       dest_cmd    <= use_acc; 

  WHEN "00000101" =>   --   INC direct_T "05"
       t1_cmd      <= direct_T;     data_t1 <= "001";   -- use byte 1
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_inc; 
       --dest_cmd    <= direct_T;     data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "00000110" | "00000111" =>   --   INC @Ri "06" - "07"
       t1_cmd      <= indirect_T;   data_t1 <= "00"&ir(0);
       t2_cmd      <= nothing; 
       alu_cmd     <= pass_tmp1;  data_alu <= t1_inc; 
       --dest_cmd    <= indirect_T;   data_dest <= "00"&ir(0);
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "00001000" | "00001001" | "00001010" | "00001011" |
       "00001100" | "00001101" | "00001110" | "00001111" =>   
       --  INC Rn 08-0F
       t1_cmd      <= use_reg;    data_t1 <= ir(2 DOWNTO 0); 
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_inc; 
       --dest_cmd    <= use_reg;    data_dest <= ir(2 DOWNTO 0);
       dest_cmd    <= same_as_t1;

  WHEN "00010100" =>   --  DEC A "14"
       t1_cmd      <= use_acc;
       t2_cmd      <= nothing; 
       alu_cmd     <= pass_tmp1;  data_alu <= t1_dec; 
       dest_cmd    <= use_acc; 

  WHEN "00010101" =>   --   DEC direct_T "15"
       t1_cmd      <= direct_T;     data_t2 <= "001";   -- use byte 1
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_dec; 
       --dest_cmd    <= direct_T;     data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "00010110" | "00010111" =>   --   DEC @Ri "16" - "17"
       t1_cmd      <= indirect_T;   data_t2 <= "00"&ir(0); 
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_dec;
       --dest_cmd    <= indirect_T;   data_dest <= "00"&ir(0);
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "00011000" | "00011001" | "00011010" | "00011011" |
       "00011100" | "00011101" | "00011110" | "00011111" =>
       --  DEC Rn 18-1F
       t1_cmd      <= use_reg;    data_t2 <= ir(2 DOWNTO 0); 
       t2_cmd      <= nothing;
       alu_cmd     <= pass_tmp1;  data_alu <= t1_dec;
       --dest_cmd    <= use_reg;    data_dest <= ir(2 DOWNTO 0);
       dest_cmd    <= same_as_t1;

  WHEN "00100100" =>   --  ADD A,#data  "24"
       t1_cmd      <= immed;      data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= add_instr;  data_alu <= "000";
       set_cy <= '1';   set_ac_ov <= '1';
       dest_cmd    <= use_acc; 

  WHEN "00100101" =>   --   ADD A,direct_T "25"
       t1_cmd      <= direct_T;     data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;  data_alu <= "000";
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "00100110" | "00100111" =>  --   ADD A,@Ri "26" - "27"
       t1_cmd      <= indirect_T;   data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;  data_alu <= "000";
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "00101000" | "00101001" | "00101010" | "00101011" |
       "00101100" | "00101101" | "00101110" | "00101111" =>
       --  ADD A,Rn 28-2F
       t1_cmd      <= use_reg;    data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;  data_alu <= "000";
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "00110100" =>   --  ADDC #data "34"
       t1_cmd      <= immed;      data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= add_instr;
       IF cy_int = '1' THEN data_alu <= t1_inc;
       ELSE                 data_alu <= "000";
       END IF;
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc; 

  WHEN "00110101" =>   --   ADDC direct_T "35"
       t1_cmd      <= direct_T;    data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '1' THEN data_alu <= t1_inc;
       ELSE                 data_alu <= "000";
       END IF;
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "00110110" | "00110111" =>   --   ADDC @Ri "36" - "37"
       t1_cmd      <= indirect_T;  data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '1' THEN data_alu <= t1_inc;
       ELSE                 data_alu <= "000";
       END IF;
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "00111000" | "00111001" | "00111010" | "00111011" |
       "00111100" | "00111101" | "00111110" | "00111111" =>
        --  ADDC Rn 38-3F
       t1_cmd      <= use_reg;   data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '1' THEN data_alu <= t1_inc;
       ELSE                 data_alu <= "000";
       END IF;
       set_cy <= '1';  set_ac_ov <= '1';
       dest_cmd    <= use_acc;

  WHEN "01000010" =>   --  ORL direct_T,A "42"
       t1_cmd      <= direct_T;   data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01000011" =>   --  ORL direct_T,#data "43"
       t1_cmd      <= immed;  data_t1 <= "010" ;
       t2_cmd      <= direct_T;  data_t1 <= "001";  
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01000100" =>   --  ORL A, #data "44"
       t1_cmd      <= immed;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= use_acc; 

  WHEN "01000101" =>   --  ORL A,direct_T "45"
       t1_cmd      <= direct_T; data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= use_acc;

  WHEN "01000110" | "01000111" =>   --   ORL A,@Ri  "46" - "47"
       t1_cmd      <= indirect_T; data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= use_acc;

  WHEN "01001000" | "01001001" | "01001010" | "01001011" |
       "01001100" | "01001101" | "01001110" | "01001111" =>   --  ORL 48-4F
       t1_cmd      <= use_reg;  data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= orl_instr;
       dest_cmd    <= use_acc;

  WHEN "01010010" =>   --  ANL direct_T,A "52"
       t1_cmd      <= direct_T;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01010011" =>   --  ANL "53"
       t1_cmd      <= immed;  data_t1 <= "010" ;
       t2_cmd      <= direct_T;  data_t2 <= "001";  
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01010100" =>   --  ANL "54"
       t1_cmd      <= immed;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= use_acc; 

  WHEN "01010101" =>   --   ANL "55"
       t1_cmd      <= direct_T; data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= use_acc;

  WHEN "01010110" | "01010111" =>   --   ANL "56" - "57"
       t1_cmd      <= indirect_T; data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;  data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= use_acc;

  WHEN "01011000" | "01011001" | "01011010" | "01011011" |
       "01011100" | "01011101" | "01011110" | "01011111"  =>   --  ANL 58-5F
       t1_cmd      <= use_reg;  data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;  data_alu <= ir(6 DOWNTO 4); --"101"
       dest_cmd    <= use_acc;

  WHEN "01100010" =>   --  XRL "62"
       t1_cmd      <= direct_T;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;  data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01100011" =>   --  XRL "63"
       t1_cmd      <= immed;  data_t1 <= "010" ;
       t2_cmd      <= direct_T;  data_t2 <= "001";  
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= same_as_t1; 
       read_latch  <= '1';

  WHEN "01100100" =>   --  XRL "64"
       t1_cmd      <= immed;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= use_acc; 

  WHEN "01100101" =>   --   XRL "65"
       t1_cmd      <= direct_T; data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= use_acc;

  WHEN "01100110" | "01100111" =>   --   XRL "66" - "67"
       t1_cmd      <= indirect_T; data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= use_acc;

  WHEN "01101000" | "01101001" | "01101010" | "01101011" |
       "01101100" | "01101101" | "01101110" | "01101111" =>   --  XRL 68-6F
       t1_cmd      <= use_reg;  data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= logic;   data_alu <= ir(6 DOWNTO 4); --"110"
       dest_cmd    <= use_acc;

  WHEN "00010000" =>   --  JBC "10"
       t1_cmd      <= bit_addr;   data_t1   <= "001";
       t2_cmd      <= nothing;
       alu_cmd     <= clr_bit;    data_alu  <= mov_instr;
       use_cy      <= '0';   
       --dest_cmd    <= bit_addr;   data_dest <= "001";
       dest_cmd    <= same_as_t1;
 
  WHEN "00100000" =>   --  JB "20"     
       t1_cmd      <= bit_addr;   data_t1     <= "001";
       t2_cmd      <= nothing;
       alu_cmd     <= bit_logic;  data_alu    <= mov_instr;
       use_cy      <= '0';   
       dest_cmd    <= nothing;

  WHEN "00110000" =>   --  JNB "30"     
       t1_cmd      <= bit_addr;   data_t1 <= "001";
       t2_cmd      <= nothing;
       alu_cmd     <= cpl_bit_logic;  data_alu    <= mov_instr;
       use_cy      <= '0';   
       dest_cmd    <= nothing;

  WHEN "01000000" =>   --  JC "40"     
       t1_cmd      <= nothing; 
       t2_cmd      <= nothing;
       alu_cmd     <= bit_logic;        data_alu    <= mov_instr;
       use_cy      <= '1';
       dest_cmd    <= nothing;
 
  WHEN "01010000" =>   --  JNC "50"     
       t1_cmd      <= nothing;
       t2_cmd      <= nothing;
       alu_cmd     <= cpl_bit_logic;    data_alu    <= mov_instr;
       use_cy      <= '1';
       dest_cmd    <= nothing;

  WHEN "01100000" =>   --  JZ "60"     
       t1_cmd      <= zeros; 
       t2_cmd      <= use_acc;
       alu_cmd     <= compare_1_2;      data_alu    <= "000";
       dest_cmd    <= nothing;
 
  WHEN "01110000" =>   --  JNZ "70"     
       t1_cmd      <= zeros; 
       t2_cmd      <= use_acc;
       alu_cmd     <= pass_tmp1;       data_alu    <= "000";
       dest_cmd    <= nothing;
 
  WHEN "01110010" =>   --   ORL C, bit "72"
       t1_cmd      <= bit_addr;   data_t1 <= "001";
       t2_cmd      <= zeros; 
       alu_cmd     <= bit_logic;  data_alu <= orl_instr;
       set_cy      <= '1';
       dest_cmd    <= nothing; 
 
  WHEN "10000010" =>   --   ANL C, bit "82"
       t1_cmd      <= bit_addr;   data_t1 <= "001";
       t2_cmd      <= zeros; 
       alu_cmd     <= bit_logic;  data_alu <= anl_instr;
       set_cy      <= '1';
       dest_cmd    <= nothing;
 
  WHEN "10100000" =>   --   ORL C, /bit "A0"
       t1_cmd      <= bit_addr;   data_t1 <= "001";
       t2_cmd      <= zeros; 
       alu_cmd     <= cpl_bit_logic;  data_alu <= orl_instr;
       set_cy      <= '1';
       dest_cmd    <= nothing;
 
  WHEN "10110000" =>   --   ANL C, bit "B0"
       t1_cmd      <= bit_addr;   data_t1 <= "001";
       t2_cmd      <= zeros; 
       alu_cmd     <= cpl_bit_logic;  data_alu <= anl_instr;
       set_cy      <= '1';
       dest_cmd    <= nothing;

  WHEN "01110100" =>   --  MOV A,#data 74     
       t1_cmd      <= immed;     data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1; data_alu <= "000";
       dest_cmd    <= use_acc; 

  WHEN "01110101" =>   --  MOV 75     
       t1_cmd      <= immed;     data_t1 <= "010"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1; 
       dest_cmd    <= direct_T;    data_dest <= "001";
 
  WHEN "01110110" | "01110111" =>   --  MOV 76-7     
       t1_cmd      <= immed;     data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;   data_alu <= "000";
       dest_cmd    <= indirect_T;  data_dest <="00"&ir(0); 

  WHEN "01111000" | "01111001" | "01111010" | "01111011" |
       "01111100" | "01111101" | "01111110" | "01111111" =>   --  MOV 78-F 
       t1_cmd      <= immed;     data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1; data_alu <= "000";
       dest_cmd    <= use_reg;   data_dest <= ir(2 DOWNTO 0); 

  WHEN "10000000" =>   --  SJMP rel 80
       t1_cmd      <= zeros;
       t2_cmd      <= zeros;
       alu_cmd     <= compare_1_2;
       dest_cmd    <= nothing; 

  WHEN "10000101" =>   --  MOV direct_T, direct_T 85     
       t1_cmd      <= direct_T;    data_t1 <= "001";
       t2_cmd      <= nothing; 
       alu_cmd     <= pass_tmp1;
       dest_cmd    <= direct_T;    data_dest <= "010"; 

  WHEN "10000110" | "10000111" =>   --  MOV direct_T,ARi 86-7   
       t1_cmd      <= indirect_T;    data_t1 <= "00"&ir(0);
       t2_cmd      <= nothing; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= direct_T;    data_dest <= "001"; 

  WHEN "10001000" | "10001001" | "10001010" | "10001011" |
       "10001100" | "10001101" | "10001110" | "10001111" =>   --  MOV 88-F
       t1_cmd      <= use_reg;    data_t1 <= ir(2 DOWNTO 0); 
       t2_cmd      <= nothing; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= direct_T;    data_dest <= "001"; 

  WHEN "10010010" =>   --  MOV bit, C 92     
       t1_cmd      <= bit_addr;   data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       use_cy      <= '1';
       alu_cmd     <= bit_logic;  data_alu <= mov_instr;
       --dest_cmd    <= bit_addr;   data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';
 
  WHEN "10100010" =>   --  MOV C, bit A2     
       t1_cmd      <= bit_addr;   data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= bit_logic;  data_alu <= mov_instr;
       set_cy      <= '1';
       dest_cmd    <= nothing; 

  WHEN "10110010" =>   --  CPL bit B2     
       t1_cmd      <= bit_addr;   data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= cpl_bit_logic;  data_alu <= mov_instr;
       --dest_cmd    <= bit_addr;   data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';
 
  WHEN "11000010" =>   --  CLR bit C2
       t1_cmd      <= bit_addr;   data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= clr_bit; 
       --dest_cmd    <= bit_addr;   data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';
 
  WHEN "11010010" =>   --  SET bit D2
       t1_cmd      <= bit_addr;   data_t1 <= "001"; 
       t2_cmd      <= zeros; 
       alu_cmd     <= set_bit; 
       --dest_cmd    <= bit_addr;   data_dest <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "10110011" =>   --  CPL Cy 
       t1_cmd      <= zeros; 
       t2_cmd      <= zeros; 
       use_cy      <= '1';     set_cy      <= '1';
       alu_cmd     <= cpl_bit_logic;  data_alu <= mov_instr;
       dest_cmd    <= nothing;

  WHEN "11000011" =>   --  CLR Cy
       t1_cmd      <= zeros;
       t2_cmd      <= zeros; 
       use_cy      <= '1';     set_cy      <= '1';
       alu_cmd     <= clr_bit; 
       dest_cmd    <= nothing;

  WHEN "11010011" =>   --  SET Cy
       t1_cmd      <= zeros;
       t2_cmd      <= zeros; 
       use_cy      <= '1';     set_cy      <= '1';
       alu_cmd     <= set_bit; 
       dest_cmd    <= nothing;

  WHEN "10010100" =>   --  SUBB "94"
       t1_cmd      <= immed;  data_t1 <= "001" ;
       t2_cmd      <= use_acc;
       alu_cmd     <= add_instr;
       IF cy_int = '0' THEN         -- no borrow needed
          data_alu <= "101";        -- cpl & inc (2's complement)
       ELSE
          data_alu <= "100";        -- cpl but don't inc to make it 2's cpl - 1
       END IF;
       set_cy      <= '1';          set_ac_ov <= '1';
       dest_cmd    <= use_acc; 

  WHEN "10010101" =>   --   SUBB "95"
       t1_cmd      <= direct_T; data_t1 <= "001";   -- use byte 
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '0' THEN         -- no borrow needed
          data_alu <= "101";        -- cpl & inc (2's complement)
       ELSE
          data_alu <= "100";        -- cpl but don't inc to make it 2's cpl - 1
       END IF;
       set_cy <= '1';  set_ac_ov <= '1';
       use_cy      <= '1';
       dest_cmd    <= use_acc;

  WHEN "10010110" | "10010111" =>   --   SUBB "96" - "97"
       t1_cmd      <= indirect_T;     data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '0' THEN         -- no borrow needed
          data_alu <= "101";        -- cpl & inc (2's complement)
       ELSE
          data_alu <= "100";        -- cpl but don't inc to make it 2's cpl - 1
       END IF;
       set_cy <= '1';               set_ac_ov <= '1';
       use_cy      <= '1';
       dest_cmd    <= use_acc;

  WHEN "10011000" | "10011001" | "10011010" | "10011011" |
       "10011100" | "10011101" | "10011110" | "10011111" =>   --  SUBB 98-9F
       t1_cmd      <= use_reg;       data_t1 <= ir(2 DOWNTO 0);
       t2_cmd      <= use_acc; 
       alu_cmd     <= add_instr;
       IF cy_int = '0' THEN          -- no borrow needed
          data_alu <= "101";         -- cpl & inc (2's complement)
       ELSE
          data_alu <= "100";         -- cpl but don't inc to make it 2's cpl - 1
       END IF;
       set_cy <= '1';                set_ac_ov <= '1';
       use_cy      <= '1';
       dest_cmd    <= use_acc;

  WHEN "10100110" | "10100111" =>    --  MOV  A6-7
       t1_cmd      <= direct_T;        data_t1 <= "001";
       t2_cmd      <= zeros;
       alu_cmd     <= pass_tmp1;     data_alu    <= "000";
       dest_cmd    <= indirect_T;      data_dest <= "00"&ir(0);

  WHEN "10101000" | "10101001" | "10101010" | "10101011" |
       "10101100" | "10101101" | "10101110" | "10101111" =>   --  MOV A8-AF
       t1_cmd      <= direct_T;        data_t1 <= "001"; 
       t2_cmd      <= zeros;
       alu_cmd     <= pass_tmp1;     data_alu    <= "000";
       dest_cmd    <= use_reg;       data_dest <= ir(2 DOWNTO 0);
 
  WHEN "10110100" =>                 --  CJNE A,#data,rel B4
       t1_cmd      <= immed;         data_t1     <= "001";
       t2_cmd      <= use_acc;
       alu_cmd     <= pass_tmp1;     data_alu    <= "000";
       dest_cmd    <= nothing; 

  WHEN "10110101" =>                 --  CJNE B5
       t1_cmd      <= direct_T;        data_t1     <= "001";
       t2_cmd      <= use_acc;
       alu_cmd     <= pass_tmp1;     data_alu    <= "000";
       dest_cmd     <= nothing; 

  WHEN "10110110" | "10110111" =>    --  CJNE B6-7
       t1_cmd      <= indirect_T;      data_t1     <= "00"&ir(0);
       t2_cmd      <= immed;         data_t2     <= "001"; 
       alu_cmd     <= pass_tmp1;     data_alu    <= "000";  
       dest_cmd     <= nothing; 

  WHEN "10111000" | "10111001" | "10111010" | "10111011" |
       "10111100" | "10111101" | "10111110" | "10111111" => -- CJNE B8-F
       t1_cmd      <= use_reg;     data_t1     <= ir(2 DOWNTO 0); 
       t2_cmd      <= immed;       data_t2     <= "001"; 
       alu_cmd     <= pass_tmp1;   data_alu    <= "000";
       dest_cmd    <= nothing; 

  WHEN "11000100" =>               --   SWAP C4 
       t1_cmd      <= zeros;
       t2_cmd      <= use_acc; 
       alu_cmd     <= rotate;      data_alu <= swap_instr;
       dest_cmd    <= use_acc;

  WHEN "11000101" =>   --   XCH C5
       t1_cmd      <= direct_T;      data_t1 <= "001";
       t2_cmd      <= use_acc;
       IF alu_second_result = '1' THEN 
           alu_cmd     <= pass_tmp1;
           dest_cmd    <= use_acc;
       ELSE  
           alu_cmd <= pass_tmp2; 
          --dest_cmd    <= direct_T;
           dest_cmd    <= same_as_t1;
       END IF;
       data_alu    <= "000";
       data_dest   <= "001";
       two_dests   <= '1';

  WHEN "11000110" | "11000111"  =>   --  XCH C6-7
       t1_cmd      <= indirect_T;    data_t1 <= "00"&ir(0);
       t2_cmd      <= use_acc;
       IF alu_second_result = '1' THEN
           alu_cmd     <= pass_tmp1;
           dest_cmd    <= use_acc;
       ELSE
           alu_cmd     <= pass_tmp2;
           --dest_cmd    <= indirect_T;
           dest_cmd    <= same_as_t1;
       END IF;
       data_alu    <= "000";
       data_dest   <= "00"&ir(0);
       two_dests   <= '1';

  WHEN "11001000" | "11001001" | "11001010" | "11001011" |
       "11001100" | "11001101" | "11001110" | "11001111" =>   --   XCH C8-F
       t1_cmd      <= use_reg;     data_t1 <= ir(2 DOWNTO 0); 
       t2_cmd      <= use_acc;
       IF alu_second_result = '1' THEN
           alu_cmd     <= pass_tmp1;
           dest_cmd    <= use_acc;
       ELSE
           alu_cmd     <= pass_tmp2;
           --dest_cmd    <= use_reg;
           dest_cmd    <= same_as_t1;
       END IF;
       data_alu    <= "000";
       data_dest   <= ir(2 DOWNTO 0);
       two_dests   <= '1';

  WHEN "11010110" | "11010111" =>   --   XCHD  A,@Ri D6-7
       t1_cmd      <= indirect_T;    data_t1 <= "00"&ir(0); 
       t2_cmd      <= use_acc;
       -- swap the lower nibbles
       IF alu_second_result = '1' THEN
           alu_cmd     <= rotate;
           dest_cmd    <= use_acc;
       ELSE
           alu_cmd     <= xchd1;
           --dest_cmd    <= indirect_T;
           dest_cmd    <= same_as_t1;
       END IF;
       data_alu    <= xchd2;
       data_dest   <= "00"&ir(0);
       two_dests   <= '1';

  WHEN "11010101" =>   --  DJNZ direct_T,rel  D5
       t1_cmd      <= direct_T;     data_t2     <= "001";
       t2_cmd      <= zeros;
       alu_cmd     <= pass_tmp1;  data_alu    <= t1_dec; 
       --dest_cmd    <= direct_T;     data_dest   <= "001";
       dest_cmd    <= same_as_t1;
       read_latch  <= '1';

  WHEN "11011000" | "11011001" | "11011010" | "11011011" |
       "11011100" | "11011101" | "11011110" | "11011111" =>   --  DJNZ Rn D8-F
       t1_cmd      <= use_reg;    data_t1     <= ir(2 DOWNTO 0);
       t2_cmd      <= zeros;
       alu_cmd     <= pass_tmp1;  data_alu    <= t1_dec; 
       --dest_cmd    <= use_reg;    data_dest   <= ir(2 DOWNTO 0); 
       dest_cmd    <= same_as_t1;
 
  WHEN "11100100" =>   --   CLR A E4
       t1_cmd      <= zeros;
       t2_cmd      <= zeros;
       alu_cmd     <= pass_tmp1;
       dest_cmd    <= use_acc;

  WHEN "11110100"  =>   --  CPL A F4
       t1_cmd      <= zeros;
       t2_cmd      <= use_acc;
       alu_cmd     <= logic;      data_alu <= cpl_instr;
       dest_cmd    <= use_acc;

  WHEN "11100101" =>   --  MOV E5     
       t1_cmd      <= direct_T;     data_t1 <= "001";
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= use_acc;
 
  WHEN "11100110" | "11100111" =>   --  MOV E6-7   
       t1_cmd      <= indirect_T;    data_t1 <= "00"&ir(0);
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= use_acc;
 
  WHEN "11101000" | "11101001" | "11101010" | "11101011" |
       "11101100" | "11101101" | "11101110" | "11101111" =>   --  MOV E8-F
       t1_cmd      <= use_reg;     data_t1 <= ir(2 DOWNTO 0); 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= use_acc;

  WHEN "11110101" =>   --  MOV F5     
       t1_cmd      <= use_acc;
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= direct_T;      data_dest <= "001";

  WHEN "11110110" | "11110111" =>   --  MOV F6-7   
       t1_cmd      <= use_acc; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= indirect_T;    data_dest <= "00"&ir(0);

  WHEN "11111000" | "11111001" | "11111010" | "11111011" |
       "11111100" | "11111101" | "11111110" | "11111111" =>   --  MOV F8-F
       t1_cmd      <= use_acc; 
       t2_cmd      <= zeros; 
       alu_cmd     <= pass_tmp1;  
       dest_cmd    <= use_reg;    data_dest <= ir(2 DOWNTO 0); 

  WHEN "10010011" | "10000011" =>    -- MOVC
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "11100010" | "11100011" =>    -- MOVX A,@Ri
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;
       
  WHEN "11100000" =>                 -- MOVX A,@DPTR
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "11110010" | "11110011" =>    -- MOVX @Ri,A
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "11110000" =>                 -- MOVX @DPTR,A
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  -- THE FOLLOWING SIX INSTRUCTIONS ARE NOT IMPLEMENTED

  WHEN "10010000" =>                 -- MOV DPTR, #data16
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "01110011" =>                 -- JMP @A + DPTR
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "10100011" =>                 -- INC DPTR
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "10100100" => -- MUL
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;  

WHEN "10000100" => -- DIV
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  WHEN "11010100" => -- DA
       t1_cmd   <= nothing;
       t2_cmd   <= nothing;
       alu_cmd  <= pass_tmp1;
       dest_cmd <= nothing;

  -- EVERYTHING EXCEPT THESE LAST SIX SHOULD BE IMPLEMENTED

  END CASE;
END PROCESS p1;
END ARCHITECTURE spec;





<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>