-- -- initial model : -- Rcsid[] = "$Id: i8085.vhd,v 3.1 1993/12/29 01:23:52 tdx Exp $"; -- -- -- Corrected behavioral model of GL85 (Clone of 8085 microprocessor) -- Created by: Alex Miczo -- -- Corrected by: Celine Poloce (08/1994) -- MACAO Team of ERM/PHASE -- Email: yann@sobel.u-strasbg.fr -- ----- ENTITY DECLARATION library ieee; use ieee.std_logic_1164.all; entity I8085_erm is port(X1 : in std_ulogic; RESETOUT, SOD : out std_ulogic; SID, TRAP, RST75, RST65, RST55, INTR: in std_ulogic; INTABAR : out std_ulogic; ADDRESS_OUT : out std_ulogic_vector(15 downto 0); S0,ALE,WRBAR, RDBAR,S1,IOMBAR: out std_ulogic; READY, RESETINBAR : in std_ulogic; CLKOUT : out std_ulogic; HLDA : out std_logic:='Z'; HOLD : in std_ulogic; ID : in std_ulogic_vector (7 downto 0) ); end I8085_erm; ----- ARCHITECTURE DECLARATION use work.conversion.all; architecture BEHAVIOR of I8085_erm is signal TSTATES : std_ulogic_vector (3 downto 0); signal MCYCLE : std_ulogic_vector (2 downto 0); signal WR_MOD, HOLDFF, INTEFF : std_logic:='Z'; signal RESETOUTFF : std_ulogic; signal BIMC, VINT : logic_state; signal HLTAFF : std_logic:='Z'; signal Z, S, P, CY, AC : std_ulogic; signal ACC, -- ACC is the accumulator ACT, -- ACT is the temp accumulator TEMP, IR, -- instruction register DBUF, -- buffer the input data (ID) MAR, -- outputs to address bus A(15 downto 8) MDR, -- outputs to address/data bus AD(7 downto 0) B, C, D, E, H, L, Z_reg, W_reg : std_ulogic_vector (7 downto 0); signal SP, PC : std_ulogic_vector (15 downto 0); signal T6, T5, T4, T3, T2, T1, THOLD, TWAIT, THALT: std_ulogic; signal M5, M4, M3, M2, M1: std_ulogic; signal reset_delayed: std_ulogic; signal RD1, RD2, WR1: std_ulogic; signal FETCH_F_WZ: std_ulogic; signal IRBIT3, IRBIT0: std_ulogic; signal DDD, SSS : std_ulogic_vector(2 downto 0); signal DPAIR, IGROUP : std_ulogic_vector(1 downto 0); signal last_MC : std_ulogic_vector(2 downto 0); signal CC_TEST : std_ulogic; signal M75FF, M65FF, M55FF : std_ulogic; signal TRAPFF: std_logic:='Z'; signal PRIO_ENCODE : std_ulogic_vector (2 downto 0); signal RST75FF: std_logic:='Z'; signal CC6: std_logic:='Z'; signal INA,INTA : std_ulogic; signal EI_ENABLE, EI_FF : std_ulogic; signal BIMCB: std_ulogic; begin process(RESETINBAR,X1) variable ALU_OUT : std_ulogic_vector (8 downto 0); variable B16BCTR : std_ulogic_vector (15 downto 0); variable INTRFF : std_ulogic; variable LAST_OP : integer; variable SOD_FF : std_ulogic; variable HRSTTYPE : integer; variable HRST_temp : std_ulogic_vector(7 downto 0); variable temp_MOV : std_ulogic_vector(7 downto 0); variable temp_D : std_ulogic_vector(7 downto 0); variable temp_E : std_ulogic_vector(7 downto 0); variable END_INST_flag : std_ulogic; variable common,wrinm2,wrinm3 : std_ulogic; variable DAD_inst : std_ulogic; begin -- -- FOR debug only case bit2int(TSTATES) is when 0 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 1 => T1<='0';T2<='1';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 2 => T1<='1';T2<='0';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 3 => T1<='1';T2<='1';T3<='0';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 4 => T1<='1';T2<='1';T3<='1';T4<='0';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 5 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='0';T6<='1';TWAIT<='1';THALT<='1';THOLD<='1'; when 6 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='1';T6<='0';TWAIT<='1';THALT<='1';THOLD<='1'; when 7 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='0';THALT<='1';THOLD<='1'; when 8 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='0';THOLD<='1'; when 9 => T1<='1';T2<='1';T3<='1';T4<='1';T5<='1';T6<='1';TWAIT<='1';THALT<='1';THOLD<='0'; when others => NULL; end case; case bit2int(MCYCLE) is when 1 =>M1<='0';M2<='1';M3<='1';M4<='1';M5<='1'; when 2 =>M1<='1';M2<='0';M3<='1';M4<='1';M5<='1'; when 3 =>M1<='1';M2<='1';M3<='0';M4<='1';M5<='1'; when 4 =>M1<='1';M2<='1';M3<='1';M4<='0';M5<='1'; when 5 =>M1<='1';M2<='1';M3<='1';M4<='1';M5<='0'; when others => NULL; end case; -- FOR debug only -- if(reset_delayed = '0') then MCYCLE <= ('0','0','1'); RESETOUTFF <= '0'; elsif (x1='1' and not (x1'stable)) then --up_edge(X1) then RESETOUTFF <= '1'; end if; if(RESETINBAR = '0') then -- clear the flip-flops PC <= (15 downto 0 => '0'); -- Program Counter RD1 <= '0'; RD2 <= '0'; WR1 <= '0'; HOLDFF <= '0'; HLTAFF <= '0'; WR_MOD <= '0'; INTEFF <= '0'; RST75FF <= '0'; TRAPFF <= '0'; INTRFF := '0'; M75FF <= '1'; M65FF <= '1'; M55FF <= '1'; LAST_OP := 99; FETCH_F_WZ <= '0'; SOD_FF := '0'; END_INST_flag := '0'; IR <= "00000000"; DBUF <= "00000000"; ACC <= "00000000"; ACT <= "00000000"; HLDA <= '0'; HRSTTYPE := 0; last_MC <= ('0','0','1'); CC6 <= '0'; CY <= '0'; -- condition codes P <= '0'; AC <= '0'; Z <= '0'; S <= '0'; elsif (x1='1' and not (x1'stable)) then -- Begin processing on positive edge of clock CLKOUT <= '0' after 1 ns; if bit2int(TSTATES) = 1 then ALE <= '1'; end if; --------------------------------------------------------------------------- if bit2int(MCYCLE) = 1 AND (bit2int(TSTATES) = 0 or bit2int(TSTATES) = 1 or bit2int(TSTATES) = 2 or bit2int(TSTATES) = 3) then --======================================================================== -- == ------------------------------------------------------------ == -- Common processing for all OP-CODES -- == -- MCYCLE = 1 -- == -- AND -- == -- TSTATES = 1, 2, or 3 -- == -- Instruction Fetch -- == ------------------------------------------------------------ == -- == --======================================================================== case bit2int(TSTATES) is -- MCYCLE = 1, TSTATES = 1 when 1 => ADDRESS_OUT <= PC after 1 ns; IOMBAR <= INTRFF after 1 ns; -- Cf., interrupt acknowledge timing, p 2-13, MCS 80/85 user's manual S1 <= '1' after 1 ns; S0 <= '1' after 1 ns; -- MCYCLE = 1, TSTATES = 2 when 2 => if not (LAST_OP = 99) then --------------------------- Procedure OP_RUNIN_NEXT_INST; -------------------------------------- case LAST_OP is when 0 => int2bit(ALU_OUT,bit2int(ACT) + bit2int(TEMP)); -- ADD r when 1 => int2bit(ALU_OUT,bit2int(ACT) + bit2int(TEMP) + bit2int(CY)); -- ADC r when 2 => int2bit(ALU_OUT,bit2int(ACT) - bit2int(TEMP)); -- SUB r when 3 => int2bit(ALU_OUT,bit2int(ACT) - bit2int(TEMP) - bit2int(CY)); -- SBB r when 4 => -- ALU_OUT(7 downto 0) := ACT and TEMP; for i in 7 downto 0 loop alu_out(i) := act(i) and temp(i); end loop; when 5 => -- ALU_OUT(7 downto 0) := ACT xor TEMP; for i in 7 downto 0 loop alu_out(i) := act(i) xor temp(i); end loop; when 6 => -- ALU_OUT(7 downto 0) := ACT or TEMP; for i in 7 downto 0 loop alu_out(i):= act(i) or temp(i); end loop; when 7 => int2bit(ALU_OUT,bit2int(ACT) - bit2int(TEMP)); -- CMP when 10|11|12|13 => CY <= ALU_OUT(8); -- when 14 => ALU_OUT(7 downto 0) := TEMP; -- DAA -- when 15 => -- CMA -- when 16 => CY <= 1; -- STC -- when 17 => if (CY = 0) then CY <= 1; else CY <= 0; end if; -- CMC when 20 => ACC(7) <= SID; -- RIM when 30 => if ACC(6) = '1' then SOD_FF := ACC(7); end if; -- SIM when others=> null; end case; -- end of case LAST_OP if (LAST_OP <16) and (not (LAST_OP = 7)) then ACC <= ALU_OUT(7 downto 0); end if; -- setup flags for condition codes Z,S,P,CY,AC if (LAST_OP <10) then -- SET_FLAGS; if bit2int(ALU_OUT) = 0 then Z <= '1'; else Z <= '0'; end if; S <= ALU_OUT(7); CY <= ALU_OUT(8); P <= ALU_OUT(0) XOR ALU_OUT(1) XOR ALU_OUT(2) XOR ALU_OUT(3) XOR ALU_OUT(4) XOR ALU_OUT(5) XOR ALU_OUT(6) XOR ALU_OUT(7); end if; case LAST_OP is when 0|1|2|3 => AC <= ALU_OUT(4) XOR TEMP(4) XOR ACT(4); when 4 => CY <= '0'; AC <= '1'; when 5|6 => CY <= '0'; AC <= '0'; when others =>null; end case; -- LAST_OP --------------------------- end Procedure OP_RUNIN_NEXT_INST; ---------------------------------- end if; if (FETCH_F_WZ = '1') then B16BCTR(15 downto 8) := W_REG(7 downto 0); B16BCTR(7 downto 0) := Z_REG(7 downto 0); inc(B16BCTR); PC <= B16BCTR; FETCH_F_WZ <= '0'; else inc_sig(PC); -- increment Program Counter end if; -- MCYCLE = 1, TSTATES = 3 when 3 => LAST_OP := 99; if HRSTTYPE > 0 then IR <= ('0','0','0','1','0','0','0','0'); else DBUF <= ID; -- DBUS_IN(DBUF); IR <= ID; TEMP <= ID; end if; -- Decode the instruction register IGROUP <= ID(7 downto 6); -- high order two bits select instruction group DDD <= ID(5 downto 3); -- bits 5 downto 3 select destination register DPAIR <= ID(5 downto 4); SSS <= ID(2 downto 0); -- bits 2 downto 0 select source register IRBIT0 <= ID(0); IRBIT3 <= ID(3); when others =>null; end case; -- end of case TSTATES --========================================================================= else -- either (MCYCLE > 1) OR (MCYCLE = 1 AND TSTATES > 3) --========================================================================= -- -- Instruction decode begins here. The high order two bits of the op-code, referred -- to as IGROUP, select the major function. Then, the third, fourth and fifth bits -- of the op-code, referred to as DDD, select the destination, and the rightmost -- three bits of the op-code, referred to as SSS, select the source. The DDD and SSS -- fields either further refine the functionality or select source and destination -- registers for the op-code. -- case bit2int(IGROUP) is when 0 => -- IGROUP = (0,0) case bit2int(SSS) is when 0 => case bit2int(DDD) is -- OP-CODE = 00 DDD 000 (SSS = 000) when 0 => END_INST_flag := '1'; -- NOP last_MC <= ('0','0','1'); when 2 => -- HWRST 0001 0000 case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 4 => W_reg <= (7 downto 0 => '0'); last_MC <= ('0','0','1'); when 5 => dec_sig(SP); when others =>null; end case; when 2 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => int2bit_sig(SP,bit2int(SP) - 1); DBUF <= PC(15 downto 8); ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; WR_MOD <= '1'; -- when 3 => -- WRITE_T3; when others =>null; end case; when 3 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; when 2 => DBUF <= PC(7 downto 0); ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; WR_MOD <= '1'; -- Z_reg := HRSTTYPE*8 + 4; int2bit(HRST_temp,HRSTTYPE); Z_reg(7 downto 3) <= HRST_temp(4 downto 0); Z_reg(2) <= '1'; HRSTTYPE := 0; when 3 => FETCH_F_WZ <= '1'; END_INST_flag := '1'; when others =>null; end case; -- case TSTATES when others =>null; end case; -- case MCYCLE when 4 => -- RIM ACC(0) <= M55FF; ACC(1) <= M65FF; ACC(2) <= M75FF; if(EI_ENABLE = '1') then ACC(3) <= EI_FF; else ACC(3) <= INTEFF; end if; ACC(4) <= RST55; ACC(5) <= RST65; ACC(6) <= RST75FF; LAST_OP := 20; END_INST_flag := '1'; when 6 => -- SIM if ACC(3) = '1' then ACC(0) <= M55FF; ACC(1) <= M65FF; ACC(2) <= M75FF; end if; if ACC(4) = '1' then RST75FF <= '0'; LAST_OP := 30; end if; END_INST_flag := '1'; when 1|3|5|7|8 => END_INST_flag := '1'; when others=>null; end case; -- end of case DDD when 1 => -- OP-CODE = 00 DDD 001 (SSS = 001) case IRBIT3 is -- instruction register, bit 3 when '0' => -- LXI (Load immediate register pair) case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => case bit2int(DPAIR) is when 0 => C <= DBUF; when 1 => E <= DBUF; when 2 => L <= DBUF; when 3 => SP(7 downto 0) <= DBUF; when others =>null; end case; MCYCLE <= ('0','1','1'); when others=>null; end case; when 3 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => case bit2int(DPAIR) is when 0 => B <= DBUF; when 1 => D <= DBUF; when 2 => H <= DBUF; when 3 => SP(15 downto 8) <= DBUF; when others=>null; end case; END_INST_flag := '1'; MCYCLE <= ('0','0','1'); ADDRESS_OUT <= PC after 1 ns; when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when '1' => -- DAD (Double add) case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => case bit2int(DPAIR) is when 0 => ACT <= C; when 1 => ACT <= E; when 2 => ACT <= L; when 3 => ACT <= SP(7 downto 0); when others=>null; end case; -- DPAIR when 2 => int2bit(ALU_OUT, bit2int(ACT) + bit2int(L)); when 3 => L <= ALU_OUT(7 downto 0); CY <= ALU_OUT(8); MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => case bit2int(DPAIR) is when 0 => ACT <= B; when 1 => ACT <= D; when 2 => ACT <= H; when 3 => ACT <= SP(15 downto 8); when others=>null; end case; -- DPAIR when 2 => int2bit(ALU_OUT, bit2int(ACT) + bit2int(H) + bit2int(CY)); when 3 => H <= ALU_OUT(7 downto 0); CY <= ALU_OUT(8); MCYCLE <= ('0','0','1'); END_INST_flag := '1'; when others=>null; end case; -- TSTATES when others=> null; end case; -- MCYCLE when others=>null; end case; -- IRBIT3 when 2 => -- op code = 00 DDD 010 (SSS = 010) case bit2int(DDD) is when 0|2 => -- STAX case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => if(bit2int(DPAIR) = 0) then ADDRESS_OUT(15 downto 8) <= B after 1 ns; ADDRESS_OUT(7 downto 0) <= C after 1 ns; else ADDRESS_OUT(15 downto 8) <= D after 1 ns; ADDRESS_OUT(7 downto 0) <= E after 1 ns; end if; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- HL_READ_T2 ADDRESS_OUT(7 downto 0) <= ACC; when 3 => MCYCLE <= ('0','0','1'); END_INST_flag := '1'; when others=>null; end case; -- end of case TSTATES when others=>null; end case; -- MCYCLE when 1|3 => -- LDAX case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => if(bit2int(DPAIR) = 0) then ADDRESS_OUT(15 downto 8) <= B after 1 ns; ADDRESS_OUT(7 downto 0) <= C after 1 ns; else ADDRESS_OUT(15 downto 8) <= D after 1 ns; ADDRESS_OUT(7 downto 0) <= E after 1 ns; end if; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- HL_READ_T2 ACC <= ID; when 3 => MCYCLE <= ('0','0','1'); END_INST_flag := '1'; when others=>null; end case; -- end of case TSTATES when others=>null; end case; -- MCYCLE when 4|5 => -- SHLD/LHLD case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1 ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 inc_sig(PC); Z_reg <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1 ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 inc_sig(PC); W_reg <= ID; when 3 => MCYCLE <= ('1','0','0'); when others=>null; end case; -- TSTATES when 4 => case bit2int(TSTATES) is when 1 => -- MEM_WZ_WRITE_T1 ADDRESS_OUT(15 downto 8) <= W_reg after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_reg after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => WR_MOD <= '1'; if(irbit3 = '0') then ADDRESS_OUT(7 downto 0) <= L after 1 ns; else L <= ID; end if; B16BCTR(15 downto 8) := W_REG; B16BCTR(7 downto 0) := Z_REG; inc(B16BCTR); when 3 => W_REG <= B16BCTR(15 downto 8); Z_REG <= B16BCTR(7 downto 0); MCYCLE <= ('1','0','1'); when others=>null; end case; -- TSTATES when 5 => case bit2int(TSTATES) is when 1 => -- MEM_WZ_WRITE_T1 ADDRESS_OUT(15 downto 8) <= W_reg after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_reg after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => WR_MOD <= '1'; if(irbit3 = '0') then ADDRESS_OUT(7 downto 0) <= H after 1 ns; else H <= ID; end if; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when 6|7 => -- 6 = STA (store accumulator) -- 7 = LDA (load accumulator) case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1 ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 inc_sig(PC); Z_reg <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1 ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 inc_sig(PC); W_reg <= ID; when 3 => MCYCLE <= ('1','0','0'); when others=>null; end case; -- TSTATES when 4 => case bit2int(TSTATES) is when 1 => -- MEM_WZ_WRITE_T1 ADDRESS_OUT(15 downto 8) <= W_reg after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_reg after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => if(irbit3 = '0') then ADDRESS_OUT(7 downto 0) <= ACC after 1 ns; -- STA else ACC <= ID; -- LDA end if; WR_MOD <= '1'; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE When others=>null; end case; -- end of case DDD when 3 => -- op code = 00 DDD 011 (SSS = 011) case bit2int(TSTATES) is when 4 => case bit2int(DPAIR) is when 0 => B16BCTR(15 downto 8) := B; B16BCTR(7 downto 0) := C; when 1 => B16BCTR(15 downto 8) := D; B16BCTR(7 downto 0) := E; when 2 => B16BCTR(15 downto 8) := H; B16BCTR(7 downto 0) := L; when 3 => B16BCTR := SP; when others=>null; end case; -- end of case DPAIR -- when irbit3 = 0, INX, when 1, DCX if(irbit3 = '0') then inc(B16BCTR); else dec(B16BCTR); end if; when 5 => case bit2int(DPAIR) is when 0 => B <= B16BCTR(15 downto 8); C <= B16BCTR(7 downto 0); when 1 => D <= B16BCTR(15 downto 8); E <= B16BCTR(7 downto 0); when 2 => H <= B16BCTR(15 downto 8); L <= B16BCTR(7 downto 0); when 3 => SP <= B16BCTR; when others=>null; end case; -- end of case DPAIR when 6 => END_INST_flag := '1'; when others=>null; end case; -- end of case TSTATES when 4|5 => -- op code = 00 DDD 10X (SSS = 10X) if bit2int(DDD)=6 then -- memory access case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT(15 downto 8) <= H after 1 ns; ADDRESS_OUT(7 downto 0) <= L after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => if (IRBIT0 = '0') then int2bit(ALU_OUT,bit2int(ID) + 1); else int2bit(ALU_OUT,bit2int(ID) - 1); end if; when 3 => TEMP <= ALU_OUT(7 downto 0); if bit2int(ALU_OUT) = 0 then Z <= '1'; else Z <= '0'; end if; S <= ALU_OUT(7); P <= ALU_OUT(0) XOR ALU_OUT(1) XOR ALU_OUT(2) XOR ALU_OUT(3) XOR ALU_OUT(4) XOR ALU_OUT(5) XOR ALU_OUT(6) XOR ALU_OUT(7); AC <= ALU_OUT(4) XOR TEMP(4) XOR ACT(4); MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT(15 downto 8) <= H after 1 ns; ADDRESS_OUT(7 downto 0) <= L after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => ADDRESS_OUT(7 downto 0) <= TEMP after 1 ns; WR_MOD <= '1'; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE else case bit2int(DDD) is when 0 => ALU_OUT(7 downto 0) := B; when 1 => ALU_OUT(7 downto 0) := C; when 2 => ALU_OUT(7 downto 0) := D; when 3 => ALU_OUT(7 downto 0) := E; when 4 => ALU_OUT(7 downto 0) := H; when 5 => ALU_OUT(7 downto 0) := L; when 7 => ALU_OUT(7 downto 0) := ACC; when others=>null; end case; if (IRBIT0 = '0') then inc(ALU_OUT); else dec(ALU_OUT); end if; case bit2int(DDD) is when 0 => B <= ALU_OUT(7 downto 0); when 1 => C <= ALU_OUT(7 downto 0); when 2 => D <= ALU_OUT(7 downto 0); when 3 => E <= ALU_OUT(7 downto 0); when 4 => H <= ALU_OUT(7 downto 0); when 5 => L <= ALU_OUT(7 downto 0); when 7 => ACC <= ALU_OUT(7 downto 0); when others=>null; end case; if bit2int(ALU_OUT) = 0 then Z <= '1'; else Z <= '0'; end if; S <= ALU_OUT(7); P <= ALU_OUT(0) XOR ALU_OUT(1) XOR ALU_OUT(2) XOR ALU_OUT(3) XOR ALU_OUT(4) XOR ALU_OUT(5) XOR ALU_OUT(6) XOR ALU_OUT(7); AC <= ALU_OUT(4) XOR TEMP(4) XOR ACT(4); END_INST_flag := '1'; end if; -- INR/DCR when 6 => -- MVI (SSS = 6) if (bit2int(DDD) = 6) then -- move 2nd byte of inst. to Memory case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => inc_sig(PC); TEMP <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT(15 downto 8) <= H after 1 ns; ADDRESS_OUT(7 downto 0) <= L after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => ADDRESS_OUT(7 downto 0) <= TEMP after 1 ns; WR_MOD <= '1'; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; When others=>null; end case; else -- move 2nd byte of inst. to designated register case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => inc_sig(PC); DBUF <= ID; when 3 => MCYCLE <= ('0','0','1'); case bit2int(DDD) is when 0 => B <= DBUF; when 1 => C <= DBUF; when 2 => D <= DBUF; when 3 => E <= DBUF; when 4 => H <= DBUF; when 5 => L <= DBUF; when 7 => ACC <= DBUF; when others=>null; end case; -- end of case DDD END_INST_flag := '1'; when others=>null; end case; when others=>null; end case; end if; when 7 => -- (SSS = 7) ROTATE_ETC LAST_OP := bit2int(DDD) + 10; case bit2int(DDD) is when 0 => -- RLC ALU_OUT(7 downto 1) := ACC(6 downto 0); ALU_OUT(0) := ACC(7); when 1 => -- RRC ALU_OUT(6 downto 0) := ACC(7 downto 1); ALU_OUT(7) := ACC(0); when 2 => -- RAL ALU_OUT(8 downto 1) := ACC(7 downto 0); ALU_OUT(0) := CY; when 3 => -- RAR ALU_OUT(6 downto 0) := ACC(7 downto 1); ALU_OUT(7) := CY; when 4 => -- DAA if BIT2INT(ACC(3 downto 0)) > 9 then int2bit(ALU_OUT(7 downto 0),bit2int(ACC) + 6); ALU_OUT(8) := '1'; else ALU_OUT(7 downto 0) := ACC; ALU_OUT(8) := '0'; end if; if BIT2INT(ACC(7 downto 4)) > 9 then int2bit(ALU_OUT(7 downto 0),bit2int(ALU_OUT(7 downto 0)) + 96); -- 96 = 6 x 00010000 ALU_OUT(8) := '1'; else ALU_OUT(8) := '0'; end if; when 5 => int2bit(ALU_OUT,-bit2int(ACC) + 255); -- CMA when 6 => CY <= '1'; -- STC (Set Carry to 1) when 7 => if (CY = '0') then CY <= '1'; else CY <= '0'; end if; -- CMC (Complement Carry) when others=>null; end case; END_INST_flag := '1'; when others=>null; end case; -- end of case SSS when 1 => -- IGROUP = (0,1) MOV, HLT op code = 01 DDD SSS (IR = 01) if (bit2int(SSS) = 6) then if (bit2int(DDD) = 6) then -- HLT instruction case bit2int(TSTATES) is when 4 => MCYCLE <= ('0','1','0'); HLTAFF <= '1'; when 2 => END_INST_flag := '1'; when others=>null; end case; -- end of case TSTATES else -- MOVM instruction (Move from Memory to Reg.) case bit2int(TSTATES) is when 1 => -- MEM_HL_READ_T1 ADDRESS_OUT(15 downto 8) <= H after 1 ns; ADDRESS_OUT(7 downto 0) <= L after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- HL_READ_T2 DBUF <= ID; when 3 => MCYCLE <= ('0','0','1'); END_INST_flag := '1'; case bit2int(DDD) is when 0 => B <= DBUF; when 1 => C <= DBUF; when 2 => D <= DBUF; when 3 => E <= DBUF; when 4 => H <= DBUF; when 5 => L <= DBUF; when 7 => ACC <= DBUF; when others=>null; end case; -- end of case DDD when 4 => MCYCLE <= ('0','1','0'); when others=>null; end case; -- end of case TSTATES end if; elsif bit2int(DDD) = 6 then -- MOVM instruction (move from Reg. to Memory) case bit2int(TSTATES) is when 1 => IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => -- WRITE_T2 WR_MOD <= '1'; ADDRESS_OUT(7 downto 0) <= TEMP; when 3 => MCYCLE <= ('0','0','1'); END_INST_flag := '1'; when 4 => -- SOURCE_REG ADDRESS_OUT(15 downto 8) <= H after 1 ns; -- MEM_HL_WRITE_T1 ADDRESS_OUT(7 downto 0) <= L after 1 ns; MCYCLE <= ('0','1','0'); case bit2int(SSS) is when 0 => TEMP <= B; when 1 => TEMP <= C; when 2 => TEMP <= D; when 3 => TEMP <= E; when 4 => TEMP <= H; when 5 => TEMP <= L; when 7 => TEMP <= ACC; when others=>null; end case; -- case SSS when others=>null; end case; -- end of case TSTATES else -- ((bit2int(DDD)/=6) and (bit2int(SSS)/=6)) then (MOV r1,r2) -- this will be state 4, there is only one MCYCLE case bit2int(SSS) is when 0 => temp_MOV := B; when 1 => temp_MOV := C; when 2 => temp_MOV := D; when 3 => temp_MOV := E; when 4 => temp_MOV := H; when 5 => temp_MOV := L; when 7 => temp_MOV := ACC; when others=>null; end case; -- case SSS case bit2int(DDD) is when 0 => B <= temp_MOV; when 1 => C <= temp_MOV; when 2 => D <= temp_MOV; when 3 => E <= temp_MOV; when 4 => H <= temp_MOV; when 5 => L <= temp_MOV; when 7 => ACC <= temp_MOV; when others=>null; end case; -- end of case DDD END_INST_flag := '1'; end if; -- MOV_HLT (IRGROUP = 01) when 2 => -- IGROUP = (1,0) op code = 10 DDD SSS (IR = 10) (ALU operations) LAST_OP := bit2int(DDD); -- -- The Group 2 instructions complete execution during state T2 of the next instruction. -- The DDD field is used to decode the operation. if NOT(bit2int(SSS) = 6) then case bit2int(SSS) is when 0 => TEMP <= B; when 1 => TEMP <= C; when 2 => TEMP <= D; when 3 => TEMP <= E; when 4 => TEMP <= H; when 5 => TEMP <= L; when 7 => TEMP <= ACC; when others=>null; end case; -- source_reg ACT <= ACC; END_INST_flag := '1'; else -- SSS = 6 => memory fetch case bit2int(TSTATES) is when 1 => ADDRESS_OUT(15 downto 8) <= H after 1 ns; ADDRESS_OUT(7 downto 0) <= L after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => DBUF <= ID; when 3 => TEMP <= DBUF; END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when 4 => ACT <= ACC; -- if TSTATES=4, then MCYCLE must be 1 MCYCLE <= ('0','1','0'); when others=>null; end case; -- TSTATES end if; when 3 => -- IGROUP = (1,1) op code = 11 DDD SSS (IR = 11) case bit2int(SSS) is when 0 => -- RC (Return Conditional) case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 4 => case bit2int(DDD) is when 0 => CC_TEST <= not Z; when 1 => CC_TEST <= Z; when 2 => CC_TEST <= not CY; when 3 => CC_TEST <= CY; when 4 => CC_TEST <= not P; when 5 => CC_TEST <= P; when 6 => CC_TEST <= not S; when 7 => CC_TEST <= S; when others=>null; end case; -- DPAIR when 6 => if (CC_TEST = '0') then END_INST_flag := '1'; else MCYCLE <= ('0','1','0'); end if; when others=>null; end case; -- TSTATES when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 inc_sig(SP); PC(7 downto 0) <= ID; Z_reg <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 inc_sig(SP); PC(15 downto 8) <= ID; W_reg <= ID; when 3 => ADDRESS_OUT(15 downto 8) <= W_REG after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_REG after 1 ns; END_INST_flag := '1'; FETCH_F_WZ <= '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when 1 => -- SSS = 1 case IRBIT3 is when '0' => -- POP rp -- rp - register pair -- rp = 00: BC , rp = 01: DE , rp = 10: HL , rp = 11: PSW case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 DBUF <= ID; -- buffer the input data inc_sig(SP); when 3 => case bit2int(MCYCLE) is when 2 => MCYCLE <= ('0','1','1'); case bit2int(DPAIR) is when 0 => C <= DBUF; when 1 => E <= DBUF; when 2 => L <= DBUF; when 3 => CY <= DBUF(0); P <= DBUF(2); AC <= DBUF(4); Z <= DBUF(6); S <= DBUF(7); when others=>null; end case; when 3 => MCYCLE <= ('0','0','1'); case bit2int(DPAIR) is when 0 => B <= DBUF; when 1 => D <= DBUF; when 2 => H <= DBUF; when 3 => ACC <= DBUF; when others=>null; end case; END_INST_flag := '1'; when others=>null; end case; when 4 => MCYCLE <= ('0','1','0'); -- if TSTATES = 4, MCYCLE must be 1 when others=>null; end case; when '1' => case bit2int(DPAIR) is when 0 => -- RET case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 inc_sig(SP); PC(7 downto 0) <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 inc_sig(SP); PC(15 downto 8) <= ID; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE -- when 1 => -- NOOP when 2 => -- PCHL case bit2int(TSTATES) is when 4 => PC(15 downto 8) <= H; when 5 => PC(7 downto 0) <= L; when others=>null; end case; when 3 => -- SPHL case bit2int(TSTATES) is when 4 => SP(15 downto 8) <= H; when 5 => SP(7 downto 0) <= L; when others=>null; end case; when others=>null; end case; -- end of case DPAIR when others=>null; end case; -- end of case IRBIT3 when 2 => -- Conditional Jump case bit2int(MCYCLE) is when 1 => -- TSTATES = 4 case bit2int(DDD) is when 0 => CC_TEST <= not Z; when 1 => CC_TEST <= Z; when 2 => CC_TEST <= not CY; when 3 => CC_TEST <= CY; when 4 => CC_TEST <= not P; when 5 => CC_TEST <= P; when 6 => CC_TEST <= not S; when 7 => CC_TEST <= S; when others=>null; end case; MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => inc_sig(PC); Z_reg <= ID; -- Byte2 -> Z when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => inc_sig(PC); W_reg <= ID; -- Byte3 -> W when 3 => ADDRESS_OUT(15 downto 8) <= W_REG after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_REG after 1 ns; END_INST_flag := '1'; if(CC_TEST = '1') then FETCH_F_WZ <= '1'; else FETCH_F_WZ <= '0'; end if; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when 3 => case bit2int(DDD) is when 0 => -- JMP case bit2int(MCYCLE) is when 1 => -- TSTATES = 4 MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => inc_sig(PC); Z_reg <= ID; -- Byte2 -> Z when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => inc_sig(PC); W_reg <= ID; -- Byte3 -> W when 3 => ADDRESS_OUT(15 downto 8) <= W_REG after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_REG after 1 ns; END_INST_flag := '1'; FETCH_F_WZ <= '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE -- when 1 => NOOP; when 2|3 => -- IO_OUT/IO_IN case bit2int(MCYCLE) is when 1 => -- TSTATES = 4 MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => inc_sig(PC); Z_reg <= ID; -- Byte2 -> Z W_reg <= ID; -- Byte2 -> W when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => if(irbit3 = '0') then -- OUT instruction ADDRESS_OUT(7 downto 0) <= ACC after 1 ns; else -- IN instruction ACC <= ID after 1 ns; end if; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when 4 => -- XTHL case bit2int(MCYCLE) is when 1 => MCYCLE <= ('0','1','0'); when 2 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 inc_sig(SP); Z_reg <= ID; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2 W_reg <= ID; when 3 => MCYCLE <= ('1','0','0'); when others=>null; end case; -- TSTATES when 4 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => WR_MOD <= '1'; ADDRESS_OUT(7 downto 0) <= H after 1 ns; dec_sig(SP); when 3 => MCYCLE <= ('1','0','1'); when others=>null; end case; -- TSTATES when 5 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '0' after 1 ns; S0 <= '1' after 1 ns; when 2 => WR_MOD <= '1'; ADDRESS_OUT(7 downto 0) <= L after 1 ns; when 3 => L <= Z_reg; H <= W_reg; END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES* when others=>null; end case; -- MCYCLE when 5 => -- XCHG temp_D := D; temp_E := E; D <= H; E <= L; H <= temp_D; L <= temp_E; when 6 => INTEFF <= '0'; -- (DI) disable interrupts when 7 => INTEFF <= '1'; -- (EI) enable interrupts when others=>null; end case; -- end of case DDD when 4 => -- CONDITIONAL CALL case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 4 => dec_sig(SP); case bit2int(DDD) is when 0 => CC_TEST <= not Z; when 1 => CC_TEST <= Z; when 2 => CC_TEST <= not CY; when 3 => CC_TEST <= CY; when 4 => CC_TEST <= not P; when 5 => CC_TEST <= P; when 6 => CC_TEST <= not S; when 7 => CC_TEST <= S; when others=>null; end case; when 5 => MCYCLE <= ('0','1','0'); when others=>null; end case; when 2 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => Z_REG <= DBUF; MCYCLE <= ('0','1','1'); when others=>null; end case; when 3 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => W_REG <= DBUF; MCYCLE <= ('1','0','0'); when others=>null; end case; when 4 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => dec_sig(SP); DBUF <= PC(15 downto 8); WR_MOD <= '1'; when 3 => -- WRITE_T3; ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; MCYCLE <= ('1','0','1'); when others=>null; end case; when 5 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0'after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => DBUF <= PC(7 downto 0); WR_MOD <= '1'; when 3 => -- WRITE_T3; ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; MCYCLE <= ('0','0','1'); if(CC_TEST = '1') then FETCH_F_WZ <= '1'; else FETCH_F_WZ <= '0'; end if; when others=>null; end case; when others=>null; end case; when 5 => -- IGROUP = 3, SSS = 5 case IRBIT3 is when '0' => -- PUSH rp (register pair) case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 5 => dec_sig(SP); -- Compared to 8080 when 6 => -- 8085 uses an additional state, T6 MCYCLE <= ('0','1','0'); ADDRESS_OUT <= SP after 1 ns; when others=>null; end case; when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- RP_PSW_SOURCE case bit2int(DPAIR) is when 0 => ADDRESS_OUT(7 downto 0) <= B(7 downto 0) after 1 ns; when 1 => ADDRESS_OUT(7 downto 0) <= D after 1 ns; when 2 => ADDRESS_OUT(7 downto 0) <= H after 1 ns; when 3 => ADDRESS_OUT(7 downto 0) <= ACC after 1 ns; when others=>null; end case; dec_sig(SP); WR_MOD <= '1'; when 3 => MCYCLE <= ('0','1','1'); ADDRESS_OUT <= SP after 1 ns; when others=>null; end case; when 3 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- RP_PSW_SOURCE(2) case bit2int(DPAIR) is when 0 => ADDRESS_OUT(7 downto 0) <= C after 1 ns; when 1 => ADDRESS_OUT(7 downto 0) <= E after 1 ns; when 2 => ADDRESS_OUT(7 downto 0) <= L after 1 ns; when 3 => ADDRESS_OUT(0) <= CY after 1 ns; -- condition codes ADDRESS_OUT(1) <= '0' after 1 ns; ADDRESS_OUT(2) <= P after 1 ns; ADDRESS_OUT(3) <= '0' after 1 ns; ADDRESS_OUT(4) <= AC after 1 ns; ADDRESS_OUT(5) <= '0' after 1 ns; ADDRESS_OUT(6) <= Z after 1 ns; ADDRESS_OUT(7) <= S after 1 ns; when others=>null; end case; WR_MOD <= '1'; when 3 => END_INST_flag := '1'; MCYCLE <= ('0','0','1'); ADDRESS_OUT <= PC after 1 ns; when others=>null; end case; when others=>null; end case; when '1' => case bit2int(DPAIR) is when 0 => -- CALL case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 4 => dec_sig(SP); when 5 => MCYCLE <= ('0','1','0'); when others=>null; end case; when 2 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => Z_REG <= DBUF; MCYCLE <= ('0','1','1'); when others=>null; end case; when 3 => case bit2int(TSTATES) is when 1 => -- MEM_PC_READ_T1; ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => -- 'PC_READ_T2; inc_sig(PC); DBUF <= ID; when 3 => W_REG <= DBUF; MCYCLE <= ('1','0','0'); when others=>null; end case; when 4 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => dec_sig(SP); DBUF <= PC(15 downto 8); WR_MOD <= '1'; when 3 => -- WRITE_T3; ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; MCYCLE <= ('1','0','1'); when others=>null; end case; when 5 => case bit2int(TSTATES) is when 1 => -- MEM_SP_WRITE_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '0' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => DBUF <= PC(7 downto 0); WR_MOD <= '1'; when 3 => -- WRITE_T3; ADDRESS_OUT(7 downto 0) <= DBUF after 1 ns; MCYCLE <= ('0','0','1'); FETCH_F_WZ <= '1'; when others=>null; end case; when others=>null; end case; -- when 1|2|3 => NOOP; when others=>null; end case; -- end of case DPAIR when others=>null; end case; -- end of case IRBIT3 when 6 => -- SSS = 6 => memory fetch LAST_OP := bit2int(DDD); case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= PC after 1 ns; IOMBAR <= '0' after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; when 2 => inc_sig(PC); DBUF <= ID; when 3 => TEMP <= DBUF; END_INST_flag := '1'; MCYCLE <= ('0','0','1'); when 4 => ACT <= ACC; -- if TSTATES=4, then MCYCLE must be 1 MCYCLE <= ('0','1','0'); when others=>null; end case; -- TSTATES when 7 => -- RST case bit2int(MCYCLE) is when 1 => case bit2int(TSTATES) is when 4 => int2bit_sig(W_reg,0); dec_sig(SP); when 6 => MCYCLE <= ('0','1','0'); when others=>null; end case; -- TSTATES when 2 => case bit2int(TSTATES) is when 1 => -- MEM_SP_READ_T1 ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 dec_sig(SP); ADDRESS_OUT(7 downto 0) <= PC(15 downto 8) after 1 ns; when 3 => MCYCLE <= ('0','1','1'); when others=>null; end case; -- TSTATES when 3 => case bit2int(TSTATES) is when 1 => ADDRESS_OUT <= SP after 1 ns; S1 <= '1' after 1 ns; S0 <= '0' after 1 ns; IOMBAR <= '0' after 1 ns; when 2 => -- SP_READ_T2 ADDRESS_OUT(7 downto 0) <= PC(7 downto 0) after 1 ns; Z_reg(7 downto 6) <= ('0','0'); Z_reg(5 downto 3) <= TEMP(5 downto 3); Z_reg(2 downto 0) <= ('0','0','0'); when 3 => ADDRESS_OUT(15 downto 8) <= W_REG after 1 ns; ADDRESS_OUT(7 downto 0) <= Z_REG after 1 ns; END_INST_flag := '1'; FETCH_F_WZ <= '1'; MCYCLE <= ('0','0','1'); when others=>null; end case; -- TSTATES when others=>null; end case; -- MCYCLE when others=>null; end case; -- end of case SSS when others=>null; end case; -- end of case IGROUP end if; -- (MCYCLE = 1) ELSE (MCYCLE > 1) --------------------------------------------------------------------------- --------------------------------------------------------------------------- end if; -- if RESETINBAR = '0' else if up_edge(X1) -- Compute RDBAR/WRBAR signals if (((((bit2int(IGROUP) = 3) AND (bit2int(DDD) = 1)) AND (bit2int(SSS) = 5)) -- CALL or ((bit2int(IGROUP) = 3) AND (bit2int(SSS) = 7)) -- RST n or (INA = '1') or ((bit2int(IGROUP) = 3) AND (bit2int(SSS) = 5))) -- PUSH rp and (((bit2int(DDD) = 0) or (bit2int(DDD) = 2)) or ((bit2int(DDD) = 4) or (bit2int(DDD) = 6)))) then common := '0'; else common := '1'; end if; if (((common = '0') or (((bit2int(IGROUP) = 1) and (bit2int(DDD) = 7)) and (bit2int(SSS) /= 6))) -- ORA or ((((bit2int(IGROUP) = 0) and (bit2int(DDD) = 0)) and (bit2int(SSS) = 2)) -- STAX B or (((bit2int(IGROUP) = 0) and (bit2int(DDD) = 2)) and (bit2int(SSS) = 2)))) -- STAX D then wrinm2 := '1'; else wrinm2 := '0'; end if; if (((common = '0') or ((bit2int(IGROUP) = 0) and (bit2int(DDD) = 7))) and ((((bit2int(SSS) = 4) or (bit2int(SSS) = 5)) or (bit2int(SSS) = 6)) -- MVI M/DCR M/INR M or (((bit2int(IGROUP) = 3) and (bit2int(DDD) = 2)) and (bit2int(SSS) = 3)))) -- OUT then wrinm3 := '1'; else wrinm3 := '0'; end if; if (bit2int(TSTATES) = 2) then if (x1='0' and not(x1'stable)) then case bit2int(MCYCLE) is when 1 => RD1 <= '1'; RD2 <= '0'; WR1 <= '0'; when 2 => RD1 <= '0'; if(wrinm3 = '0') then RD2 <= '1'; else RD2 <= '0'; end if; if(wrinm3 = '1') then WR1 <= '1'; else WR1 <= '0'; end if; when 3 => RD1 <= '0'; if(wrinm2 = '0') then RD2 <= '1'; else RD2 <= '0'; end if; if(wrinm2 = '1') then WR1 <= '1'; else WR1 <= '0'; end if; when 4 => RD1 <= '0'; if ((((bit2int(IGROUP) = 0) and (bit2int(DDD) = 7)) and (bit2int(SSS) = 2)) -- LDA or (((bit2int(IGROUP) = 0) and (bit2int(DDD) = 5)) and (bit2int(SSS) = 2))) -- LHLD then RD2 <= '1'; else RD2 <= '0'; end if; if ((((bit2int(IGROUP) = 0) and (bit2int(DDD) = 6)) and (bit2int(SSS) = 2)) -- STA or (((bit2int(IGROUP) = 0) and (bit2int(DDD) = 4)) and (bit2int(SSS) = 2))) -- SHLD then WR1 <= '1'; else WR1 <= '0'; end if; when 5 => RD1 <= '0'; if (((bit2int(IGROUP) = 0) and (bit2int(DDD) = 5)) and (bit2int(SSS) = 2)) -- LHLD then RD2 <= '1'; else RD2 <= '0'; end if; if (((bit2int(IGROUP) = 0) and (bit2int(DDD) = 4)) and (bit2int(SSS) = 2)) -- SHLD then WR1 <= '1'; else WR1 <= '0'; end if; when others=>null; end case; -- MCYCLE end if; elsif((bit2int(TSTATES) = 3) and (X1 = '0')) then RD1 <= '0'; RD2 <= '0'; WR1 <= '0'; end if; if (((bit2int(IGROUP) = 0) and (bit2int(SSS) = 1)) and (IRBIT3 = '1')) then -- DAD DAD_inst := '0'; else DAD_inst := '1'; end if; if(bit2int(MCYCLE) = 1) then if(INA = '1') then BIMCB <= '1'; else BIMCB <= '0'; end if; else -- MCYCLE /= 1 if(DAD_inst = '0') then BIMCB <= '1'; else BIMCB <= '0'; end if; end if; RDBAR <= ((BIMCB or INTA) or (not(RD1) and not(RD2))); WRBAR <= not(WR1) or not(DAD_inst); if bit2int(TSTATES) = 1 then ALE <= '0'; if END_INST_flag = '1' then MCYCLE <= ('0','0','1'); END_INST_flag := '0'; -- HW_INTR_PS -- interrupts are sampled during the second clock cycle before M1,T1 end if; end if; CLKOUT <= not(X1) after 1 ns; SOD <= SOD_FF after 5 ns; RESETOUT <= not RESETOUTFF; INTABAR <= not INTA; end process; ------------------------------------------------------------------------- -- This next process computes the T-states (minor state) transitions. -- -- The order of the T-states (and their mapping into -- the gate-level state machine) are as follows -- TX, T1, T2, T3, T4, T5, T6, TW, THALT, TH -- -- M1, M2, M3, M4, M5 ------------------------------------------------------------------------- process(RESETINBAR,X1) variable TT, MAJOR_CYCLE : integer; begin if(RESETINBAR = '0') then reset_delayed <= '0' after 5 ns; elsif (x1='1' and not (x1'stable)) then reset_delayed <= '1' after 5 ns; end if; if(reset_delayed = '0') then TSTATES <= "0000"; end if; if(x1='1' and not (x1'stable)) then -- X1 is the clock signal TT := bit2int(TSTATES); MAJOR_CYCLE := bit2int(MCYCLE); case TT is when 0 => TT := 1; if (fetch_f_wz = '1') then MAR <= W_reg after 1 ns; MDR <= Z_reg after 1 ns; end if; when 9 => if not (HOLD = '1') then if (HLTAFF = '0') then TT := 1; else TT := 8; end if; HOLDFF <= '0'; HLDA <= '0' after 20 ns; end if; when 1 => if (HLTAFF = '1') then TT := 8; else TT := 2; end if; when 2|7 => if ((bit2int(SSS) = 1) and (IRBIT3 = '1') and (bit2int(IGROUP) = 0) -- DAD inst. and ((MAJOR_CYCLE = 2) or (MAJOR_CYCLE = 3))) then BIMC <= 1; else BIMC <= 0; end if; if ((READY = '1') or (BIMC = 1)) then TT := 3; if (HOLD = '1') then HOLDFF <= '1'; else HOLDFF <= '0'; end if; else TT := 7; end if; when 3 => if (HOLDFF = '1') then if WR_MOD = '1' then HLDA <= '1' after 20 ns; -- CK_PERIOD else HLDA <= '1' after 1 ns; end if; end if; if MAJOR_CYCLE = 1 then TT := 4; elsif HOLDFF = '1' then TT := 9; else TT := 1; end if; WR_MOD <= '0'; -- CC6 denotes those op-codes that require six clock cycles during the M1 machine cycle when 4 => if ((bit2int(IGROUP)=0) and (bit2int(SSS)=3)) -- INX/DCX instructions or ((bit2int(IGROUP)=3) and ( (bit2int(SSS)=0) or (bit2int(SSS)=4) or (bit2int(SSS)=5) or (bit2int(SSS)=7) ) ) or (bit2int(IR) = 233) or (bit2int(IR) = 249) then CC6 <= '1'; TT := 5; if HOLD = '1' then HOLDFF <= '1'; HLDA <= '1' after 20 ns; -- CK_PERIOD end if; elsif HOLDFF = '1' then TT := 9; CC6 <= '0'; else TT := 1; CC6 <= '0'; end if; when 5 => TT := 6; when 6 => if HOLDFF = '1' then TT := 9; else TT := 1; end if; when 8 => if HOLD = '1' then TT := 9; HOLDFF <= '1'; elsif VINT = 1 then TT := 1; HLTAFF<='0'; INTEFF <= '0'; VINT<=0; else TT := 8; end if; when others=>null; end case; -- end of case TT int2bit_sig(TSTATES,TT); end if; end process; process(RESETINBAR,X1,INTEFF,TSTATES,MCYCLE) variable PIE: std_ulogic_vector(2 downto 0); variable clock_gate : std_ulogic; begin if(TRAP='1' and not (trap'stable)) then TRAPFF <= '1'; else TRAPFF <= '0'; end if; if(RESETINBAR = '0' or bit2int(PRIO_ENCODE) = 1) then RST75FF <= '0'; elsif(RST75='1' and not (rst75'stable)) then RST75FF <= '1'; end if; if(TRAP = '1' and TRAPFF = '1') then PIE := "000"; elsif INTEFF = '0' then if (M75FF = '0' and RST75FF = '1') then PIE := ('0','0','1'); elsif(M65FF = '0' and RST65 = '1') then PIE := ('0','1','0'); elsif(M55FF = '0' and RST55 = '1') then PIE := ('0','1','1'); elsif(INTR = '1') then PIE := ('1','0','0'); end if; else PIE := ('1','1','1'); end if; if(bit2int(MCYCLE) = 1) then if(bit2int(TSTATES) = 2) then clock_gate := '1'; else clock_gate := '0'; end if; else if CC6 = '1' then if(bit2int(TSTATES) = 5) then clock_gate := '1'; else clock_gate := '0'; end if; else if(bit2int(TSTATES) = 3) then clock_gate := '1'; else clock_gate := '0'; end if; end if; end if; if(RESETINBAR = '0') then PRIO_ENCODE <= ('1','1','1'); INA <= '0'; INTA <= '0'; EI_FF <= '0'; elsif(x1='1' and not (x1'stable)) then if ((((INTEFF = '1') and (bit2int(TSTATES) = 8)) or (bit2int(TSTATES) = 9)) -- THALT or THOLD or (clock_gate = '1')) then PRIO_ENCODE <= PIE; end if; if(bit2int(PRIO_ENCODE) = 4) then INTA <= '1'; INA <= not((PRIO_ENCODE(1)) and PRIO_ENCODE(0)); else INTA <= '0'; INA <= '0'; end if; if(EI_ENABLE = '1') then EI_FF <= INTEFF; end if; end if; if(RESETINBAR = '0') then EI_ENABLE <= '0'; elsif(X1='0' and not (x1'stable)) then if(bit2int(PRIO_ENCODE) = 0) then EI_ENABLE <= '1'; else EI_ENABLE <= '0'; end if; end if; end process; end BEHAVIOR;