-- -- Rcsid[] = "$Id: i8085.vhd,v 2.1 1993/10/06 00:56:57 alex Exp $"; -- -- -- Behavioral model of GL85 (Clone of 8085 microprocessor) -- Created by: Alex Miczo -- ----- ENTITY DECLARATION entity I8085 is port(X1 : in bit; RESETOUT, SOD : out bit; SID, TRAP, RST75, RST65, RST55, INTR: in bit; INTABAR : out Bit; ADDRESS_OUT : out logic_vector(15 downto 0); S0,ALE,WRBAR, RDBAR,S1,IOMBAR: out bit; READY, RESETINBAR : in bit; CLKOUT, HLDA : out Bit; HOLD : in bit; ID : in logic_vector (7 downto 0) ); end I8085; ----- ARCHITECTURE DECLARATION architecture BEHAVIOR of I8085 is signal TSTATES : logic_vector (3 downto 0); signal MCYCLE : logic_vector (2 downto 0); signal WR_MOD, HOLDFF, INTEFF : logic_state; signal RESETOUTFF : logic_state; signal BIMC, VINT : logic_state; signal HLTAFF : Bit; signal Z, S, P, CY, AC : Bit; 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 : logic_vector (7 downto 0); signal SP, PC : logic_vector (15 downto 0); signal T6, T5, T4, T3, T2, T1, THOLD, TWAIT, THALT: bit; signal M5, M4, M3, M2, M1: bit; signal reset_delayed: bit; signal RD1, RD2, WR1: bit; signal FETCH_F_WZ: bit; signal IRBIT3, IRBIT0: bit; signal DDD, SSS : logic_vector(2 downto 0); signal DPAIR, IGROUP : logic_vector(1 downto 0); signal last_MC : logic_vector(2 downto 0); signal CC_TEST : bit; signal M75FF, M65FF, M55FF : bit; signal TRAPFF: bit; signal PRIO_ENCODE : logic_vector (2 downto 0); signal RST75FF: bit; signal CC6: bit; signal INA,INTA : bit; signal EI_ENABLE, EI_FF : bit; signal BIMCB: bit; begin process(RESETINBAR,X1) variable ALU_OUT : logic_vector (8 downto 0); variable B16BCTR : logic_vector (15 downto 0); variable INTRFF, LAST_OP : integer; variable SOD_FF : bit; variable HRSTTYPE : integer; variable HRST_temp : logic_vector(7 downto 0); variable temp_MOV : logic_vector(7 downto 0); variable temp_D : logic_vector(7 downto 0); variable temp_E : logic_vector(7 downto 0); variable END_INST_flag : bit; variable common,wrinm2,wrinm3 : bit; variable DAD_inst : bit; 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 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 <= (0,0,0,0,0,0,0,0); DBUF <= (0,0,0,0,0,0,0,0); ACC <= (0,0,0,0,0,0,0,0); ACT <= (0,0,0,0,0,0,0,0); HLDA <= '0'; HRSTTYPE := '0'; last_MC <= (0,0,1); CC6 <= '0'; CY <= '0'; -- condition codes P <= '0'; AC <= '0'; Z <= '0'; S <= '0'; elsif up_edge(X1) 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; if ACT(7) = '1' and TEMP(7) = '1' then ALU_OUT(7) := '1'; else ALU_OUT(7) := '0'; end if; if ACT(6) = '1' and TEMP(6) = '1' then ALU_OUT(6) := '1'; else ALU_OUT(6) := '0'; end if; if ACT(5) = '1' and TEMP(5) = '1' then ALU_OUT(5) := '1'; else ALU_OUT(5) := '0'; end if; if ACT(4) = '1' and TEMP(4) = '1' then ALU_OUT(4) := '1'; else ALU_OUT(4) := '0'; end if; if ACT(3) = '1' and TEMP(3) = '1' then ALU_OUT(3) := '1'; else ALU_OUT(3) := '0'; end if; if ACT(2) = '1' and TEMP(2) = '1' then ALU_OUT(2) := '1'; else ALU_OUT(2) := '0'; end if; if ACT(1) = '1' and TEMP(1) = '1' then ALU_OUT(1) := '1'; else ALU_OUT(1) := '0'; end if; if ACT(0) = '1' and TEMP(0) = '1' then ALU_OUT(0) := '1'; else ALU_OUT(0) := '0'; end if; when 5 => -- ALU_OUT(7 downto 0) := ACT xor TEMP; if ACT(7) = '1' and TEMP(7) = '0' or ACT(7) = '0' and TEMP(7) = '1' then ALU_OUT(7) := '1'; else ALU_OUT(7) := '0'; end if; if ACT(6) = '1' and TEMP(6) = '0' or ACT(6) = '0' and TEMP(6) = '1' then ALU_OUT(6) := '1'; else ALU_OUT(6) := '0'; end if; if ACT(5) = '1' and TEMP(5) = '0' or ACT(5) = '0' and TEMP(5) = '1' then ALU_OUT(5) := '1'; else ALU_OUT(5) := '0'; end if; if ACT(4) = '1' and TEMP(4) = '0' or ACT(4) = '0' and TEMP(4) = '1' then ALU_OUT(4) := '1'; else ALU_OUT(4) := '0'; end if; if ACT(3) = '1' and TEMP(3) = '0' or ACT(3) = '0' and TEMP(3) = '1' then ALU_OUT(3) := '1'; else ALU_OUT(3) := '0'; end if; if ACT(2) = '1' and TEMP(2) = '0' or ACT(2) = '0' and TEMP(2) = '1' then ALU_OUT(2) := '1'; else ALU_OUT(2) := '0'; end if; if ACT(1) = '1' and TEMP(1) = '0' or ACT(1) = '0' and TEMP(1) = '1' then ALU_OUT(1) := '1'; else ALU_OUT(1) := '0'; end if; if ACT(0) = '1' and TEMP(0) = '0' or ACT(0) = '0' and TEMP(0) = '1' then ALU_OUT(0) := '1'; else ALU_OUT(0) := '0'; end if; when 6 => -- ALU_OUT(7 downto 0) := ACT or TEMP; if ACT(7) = '1' or TEMP(7) = '1' then ALU_OUT(7) := '1'; else ALU_OUT(7) := '0'; end if; if ACT(6) = '1' or TEMP(6) = '1' then ALU_OUT(6) := '1'; else ALU_OUT(6) := '0'; end if; if ACT(5) = '1' or TEMP(5) = '1' then ALU_OUT(5) := '1'; else ALU_OUT(5) := '0'; end if; if ACT(4) = '1' or TEMP(4) = '1' then ALU_OUT(4) := '1'; else ALU_OUT(4) := '0'; end if; if ACT(3) = '1' or TEMP(3) = '1' then ALU_OUT(3) := '1'; else ALU_OUT(3) := '0'; end if; if ACT(2) = '1' or TEMP(2) = '1' then ALU_OUT(2) := '1'; else ALU_OUT(2) := '0'; end if; if ACT(1) = '1' or TEMP(1) = '1' then ALU_OUT(1) := '1'; else ALU_OUT(1) := '0'; end if; if ACT(0) = '1' or TEMP(0) = '1' then ALU_OUT(0) := '1'; else ALU_OUT(0) := '0'; end if; 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 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; 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(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); 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(SP); 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(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; 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'; end case; -- case TSTATES 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'; 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(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; end case; MCYCLE <= (0,1,1); 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(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; end case; END_INST_flag := '1'; MCYCLE <= (0,0,1); ADDRESS_OUT <= PC after 1 ns; end case; -- TSTATES 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); 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); 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); 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'; end case; -- TSTATES end case; -- MCYCLE 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'; end case; -- end of case TSTATES 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'; end case; -- end of case TSTATES 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(PC); Z_reg <= ID; when 3 => MCYCLE <= (0,1,1); 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(PC); W_reg <= ID; when 3 => MCYCLE <= (1,0,0); 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); 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); end case; -- TSTATES 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(PC); Z_reg <= ID; when 3 => MCYCLE <= (0,1,1); 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(PC); W_reg <= ID; when 3 => MCYCLE <= (1,0,0); 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); end case; -- TSTATES end case; -- MCYCLE 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; 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; end case; -- end of case DPAIR when 6 => END_INST_flag := '1'; 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); 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); end case; -- TSTATES 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; 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); 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(PC); TEMP <= ID; when 3 => MCYCLE <= (0,1,1); 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); end case; 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(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; end case; -- end of case DDD END_INST_flag := '1'; end case; 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) end case; END_INST_flag := '1'; 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'; 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; end case; -- end of case DDD when 4 => MCYCLE <= (0,1,0); 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; end case; -- case SSS 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; 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; 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; 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); 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; end case; -- DPAIR when 6 => if (CC_TEST = '0') then END_INST_flag := '1'; else MCYCLE <= (0,1,0); end if; 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(SP); PC(7 downto 0) <= ID; Z_reg <= ID; when 3 => MCYCLE <= (0,1,1); 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(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); end case; -- TSTATES 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(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); 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; end case; END_INST_flag := '1'; end case; when 4 => MCYCLE <= (0,1,0); -- if TSTATES = 4, MCYCLE must be 1 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(SP); PC(7 downto 0) <= ID; when 3 => MCYCLE <= (0,1,1); 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(SP); PC(15 downto 8) <= ID; when 3 => END_INST_flag := '1'; MCYCLE <= (0,0,1); end case; -- TSTATES 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; end case; when 3 => -- SPHL case bit2int(TSTATES) is when 4 => SP(15 downto 8) <= H; when 5 => SP(7 downto 0) <= L; end case; end case; -- end of case DPAIR 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; 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(PC); Z_reg <= ID; -- Byte2 -> Z when 3 => MCYCLE <= (0,1,1); 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(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