diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c index 479a953..313c87a 100644 --- a/firmware/AtomBusMon.c +++ b/firmware/AtomBusMon.c @@ -14,7 +14,7 @@ * VERSION and NAME are used in the start-up message ********************************************************/ -#define VERSION "0.994" +#define VERSION "0.996" #if defined(CPU_Z80) #define NAME "ICE-Z80" @@ -922,7 +922,7 @@ void writeIOByteInc() { addr_t disMem(addr_t addr) { loadAddr(addr); - return disassemble(addr); + return disassemble(addr, MODE_NORMAL); } void genericDump(char *params, data_t (*readFunc)()) { @@ -1526,7 +1526,7 @@ void doCmdDis(char *params) { memAddr = startAddr; loadAddr(memAddr); do { - memAddr = disassemble(memAddr); + memAddr = disassemble(memAddr, MODE_DIS_CMD); i++; } while ((!endAddr && i < 10) || (endAddr && memAddr > startAddr && memAddr <= endAddr)); } diff --git a/firmware/dis.h b/firmware/dis.h index 33e42f7..8c60c04 100644 --- a/firmware/dis.h +++ b/firmware/dis.h @@ -6,6 +6,10 @@ #define PDC_DDR DDRA #define PDC_DIN PINA -addr_t disassemble(addr_t addr); +#define MODE_NORMAL 0 +#define MODE_DIS_CMD 1 + +addr_t disassemble(addr_t addr, uint8_t m); + #endif diff --git a/firmware/dis6502.c b/firmware/dis6502.c index 9b0a655..328436e 100644 --- a/firmware/dis6502.c +++ b/firmware/dis6502.c @@ -167,7 +167,7 @@ static const unsigned char dopaddr[256] PROGMEM = /*F0*/ BRA, INDY, IMP, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP }; -addr_t disassemble(addr_t addr) +addr_t disassemble(addr_t addr, uint8_t m) { char buffer[40]; diff --git a/firmware/dis65c02.c b/firmware/dis65c02.c index 2b06f47..d4ad91e 100644 --- a/firmware/dis65c02.c +++ b/firmware/dis65c02.c @@ -187,7 +187,7 @@ static const unsigned char dopaddr[256] PROGMEM = /*F0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP }; -addr_t disassemble(addr_t addr) +addr_t disassemble(addr_t addr, uint8_t m) { char buffer[40]; diff --git a/firmware/dis6809.c b/firmware/dis6809.c index 31725ce..454b3ce 100644 --- a/firmware/dis6809.c +++ b/firmware/dis6809.c @@ -647,7 +647,7 @@ static char *strcc(char *ptr, uint8_t val) { /* disassemble one instruction at address addr and return the address of the next instruction */ -addr_t disassemble(addr_t addr) { +addr_t disassemble(addr_t addr, uint8_t m) { uint8_t d = get_memb(addr); uint8_t s; int8_t i; diff --git a/firmware/disz80.c b/firmware/disz80.c index 98ae840..a65dfe5 100644 --- a/firmware/disz80.c +++ b/firmware/disz80.c @@ -530,9 +530,9 @@ static const unsigned char cmd_ED40[192] PROGMEM = { NOP,0,0 }; -static const char word_EX_HALT[] PROGMEM = "**HALT**"; -static const char word_EX_INT[] PROGMEM = "**INT**"; -static const char word_EX_NMI[] PROGMEM = "**NMI**"; +static const char msg_HALT[] PROGMEM = "**HALT**\n"; +static const char msg_INT[] PROGMEM = "**INT**\n"; +static const char msg_NMI[] PROGMEM = "**NMI**\n"; unsigned char cmd_halt[] = { HALT,0,0 }; unsigned char cmd_nop[] = { NOP,0,0 }; @@ -887,12 +887,15 @@ char * disassem (char *ptr, unsigned int *ip) { return ptr; } -addr_t disassemble(addr_t addr) { +addr_t disassemble(addr_t addr, uint8_t m) { static char buffer[64]; char *ptr; addr_t addr2 = addr; + // Ignore the current CPU state in the disassemble connamd + uint8_t pdc = (m == MODE_DIS_CMD) ? 0 : PDC_DIN; + // 0123456789012345678901234567890123456789 // AAAA : HH HH HH HH : LD RR,($XXXX) @@ -905,17 +908,18 @@ addr_t disassemble(addr_t addr) { // Opcode ptr = buffer + 21; - if (PDC_DIN & 0x80) { - strcpy_P(ptr, PSTR("**HALT**")); - } else if (PDC_DIN & 0x40) { - strcpy(ptr, PSTR("**NMI**")); - } else if (PDC_DIN & 0x20) { - strcpy(ptr, PSTR("**INT**")); + + if (pdc & 0x80) { + strcpy_P(ptr, msg_HALT); + } else if (pdc & 0x40) { + strcpy(ptr, msg_NMI); + } else if (pdc & 0x20) { + strcpy(ptr, msg_INT); } else { ptr = disassem(ptr, &addr2); + *ptr++ = '\n'; + *ptr++ = '\0'; } - *ptr++ = '\n'; - *ptr++ = '\0'; // Hex loadAddr(addr); diff --git a/src/T80/T80.vhd b/src/T80/T80.vhd index ed57ca6..24025a3 100644 --- a/src/T80/T80.vhd +++ b/src/T80/T80.vhd @@ -21,7 +21,7 @@ -- **** -- Z80 compatible microprocessor core -- --- Version : 0247 +-- Version : 0250 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- All rights reserved -- @@ -73,14 +73,14 @@ -- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode -- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM -- 0247 : Fixed bus req/ack cycle +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.STD_LOGIC_UNSIGNED.all; - -use work.all; +use work.T80_Pack.all; entity T80 is generic( @@ -120,6 +120,7 @@ entity T80 is NMICycle_n : out std_logic; IntE : out std_logic; Stop : out std_logic; + R800_mode : in std_logic := '0'; out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A @@ -129,136 +130,6 @@ entity T80 is end T80; architecture rtl of T80 is - component T80_MCode - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - XY_State : in std_logic_vector(1 downto 0); - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - SetWZ : out std_logic_vector(1 downto 0); - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - XYbit_undoc : out std_logic - ); - end component; - - component T80_ALU - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - WZ : in std_logic_vector(15 downto 0); - XY_State : in std_logic_vector(1 downto 0); - ALU_Op : in std_logic_vector(3 downto 0); - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); - end component; - - component T80_Reg - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0); - DOR : out std_logic_vector(127 downto 0); - DIRSet : in std_logic; - DIR : in std_logic_vector(127 downto 0) - ); - end component; - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; -- Registers signal ACC, F : std_logic_vector(7 downto 0); @@ -283,9 +154,13 @@ architecture rtl of T80 is -- Help Registers signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register + signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register signal IR : std_logic_vector(7 downto 0); -- Instruction register signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector signal RegBusA_r : std_logic_vector(15 downto 0); + signal MULU_Prod32 : std_logic_vector(31 downto 0); + signal MULU_tmp : std_logic_vector(31 downto 0); + signal MULU_Fakt1 : std_logic_vector(15 downto 0); signal ID16 : signed(15 downto 0); signal Save_Mux : std_logic_vector(7 downto 0); @@ -295,8 +170,8 @@ architecture rtl of T80 is signal IntE_FF1 : std_logic; signal IntE_FF2 : std_logic; signal Halt_FF : std_logic; - signal BusReq_s : std_logic; - signal BusAck : std_logic; + signal BusReq_s : std_logic := '0'; + signal BusAck : std_logic := '0'; signal ClkEn : std_logic; signal NMI_s : std_logic; signal IStatus : std_logic_vector(1 downto 0); @@ -344,6 +219,7 @@ architecture rtl of T80 is signal Set_BusA_To : std_logic_vector(3 downto 0); signal ALU_Op : std_logic_vector(3 downto 0); signal Save_ALU : std_logic; + signal Rot_Akku : std_logic; signal PreserveC : std_logic; signal Arith16 : std_logic; signal Set_Addr_To : std_logic_vector(2 downto 0); @@ -355,6 +231,8 @@ architecture rtl of T80 is signal LDZ : std_logic; signal LDW : std_logic; signal LDSPHL : std_logic; + signal LDHLSP : std_logic; + signal ADDSPdd : std_logic; signal IORQ_i : std_logic; signal Special_LD : std_logic_vector(2 downto 0); signal ExchangeDH : std_logic; @@ -373,14 +251,16 @@ architecture rtl of T80 is signal I_RRD : std_logic; signal I_RXDD : std_logic; signal I_INRC : std_logic; + signal I_MULUB : std_logic; + signal I_MULU : std_logic; signal SetWZ : std_logic_vector(1 downto 0); signal SetDI : std_logic; signal SetEI : std_logic; signal IMode : std_logic_vector(1 downto 0); signal Halt : std_logic; signal XYbit_undoc : std_logic; + signal No_PC : std_logic; signal DOR : std_logic_vector(127 downto 0); - signal IVector : std_logic_vector(7 downto 0); begin @@ -419,6 +299,7 @@ begin Set_BusA_To => Set_BusA_To, ALU_Op => ALU_Op, Save_ALU => Save_ALU, + Rot_Akku => Rot_Akku, PreserveC => PreserveC, Arith16 => Arith16, Set_Addr_To => Set_Addr_To, @@ -431,6 +312,8 @@ begin LDZ => LDZ, LDW => LDW, LDSPHL => LDSPHL, + LDHLSP => LDHLSP, + ADDSPdd => ADDSPdd, Special_LD => Special_LD, ExchangeDH => ExchangeDH, ExchangeRp => ExchangeRp, @@ -447,6 +330,8 @@ begin I_RLD => I_RLD, I_RRD => I_RRD, I_INRC => I_INRC, + I_MULUB => I_MULUB, + I_MULU => I_MULU, SetWZ => SetWZ, SetDI => SetDI, SetEI => SetEI, @@ -454,6 +339,8 @@ begin Halt => Halt, NoRead => NoRead, Write => Write, + R800_mode => R800_mode, + No_PC => No_PC, XYbit_undoc => XYbit_undoc); alu : T80_ALU @@ -473,6 +360,7 @@ begin WZ => WZ, XY_State=> XY_State, ALU_Op => ALU_Op_r, + Rot_Akku => Rot_Akku, IR => IR(5 downto 0), ISet => ISet, BusA => BusA, @@ -497,6 +385,8 @@ begin process (RESET_n, CLK_n) variable n : std_logic_vector(7 downto 0); variable ioq : std_logic_vector(8 downto 0); + variable temp_c : unsigned(8 downto 0); + variable temp_h : unsigned(4 downto 0); begin if RESET_n = '0' then PC <= (others => '0'); -- Program Counter @@ -511,6 +401,11 @@ begin ACC <= (others => '1'); F <= (others => '1'); + if Mode = 3 then + ACC <= (others => '0'); + F <= "11110000"; + end if; + Ap <= (others => '1'); Fp <= (others => '1'); I <= (others => '0'); @@ -539,7 +434,7 @@ begin R <= unsigned(DIR(47 downto 40)); SP <= unsigned(DIR(63 downto 48)); PC <= unsigned(DIR(79 downto 64)); - A <= DIR(79 downto 64); + A <= DIR(79 downto 64); IStatus <= DIR(209 downto 208); elsif ClkEn = '1' then @@ -549,7 +444,27 @@ begin MCycles <= MCycles_d; - if IMode /= "11" then + if LDHLSP = '1' and MCycle = "011" and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if ADDSPdd = '1' and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if Mode = 3 then + IStatus <= "10"; + elsif IMode /= "11" then IStatus <= IMode; end if; @@ -579,16 +494,15 @@ begin IR <= "11111111"; elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then IR <= "00000000"; - -- DMB: It's important to catch the interrupt vector at - -- the start of T3, not the middle as the old code - -- (using WZ) did. This caused a issue with the Z80 - -- Second Processor on the GODIL due to the pullups - -- (esp on D0) - IVector <= DInst; else IR <= DInst; end if; + if Mode <= 1 and IntCycle = '1' and IStatus = "10" then + -- IM2 vector address low byte from bus + WZ(7 downto 0) <= DInst; + end if; + ISet <= "00"; if Prefix /= "00" then if Prefix = "11" then @@ -636,11 +550,12 @@ begin elsif MCycle = MCycles and NMICycle = '1' then A <= "0000000001100110"; PC <= "0000000001100110"; - elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + elsif ((Mode /= 3 and MCycle = "011") or (Mode = 3 and MCycle = "100")) + and IntCycle = '1' and IStatus = "10" then A(15 downto 8) <= I; - A(7 downto 0) <= IVector; + A(7 downto 0) <= WZ(7 downto 0); PC(15 downto 8) <= unsigned(I); - PC(7 downto 0) <= unsigned(IVector); + PC(7 downto 0) <= unsigned(WZ(7 downto 0)); else case Set_Addr_To is when aXY => @@ -700,7 +615,12 @@ begin end if; end if; when others => - A <= std_logic_vector(PC); + if ISet = "10" and IR(7 downto 4) = x"B" and IR(2 downto 1) = "01" and MCycle = 3 and No_BTR = '0' then + -- INIR, INDR, OTIR, OTDR + A <= RegBusA_r; + elsif No_PC = '0' or No_BTR = '1' or (I_DJNZ = '1' and IncDecZ = '1') or Mode > 1 then + A <= std_logic_vector(PC); + end if; end case; end if; @@ -711,29 +631,50 @@ begin Save_ALU_r <= Save_ALU; ALU_Op_r <= ALU_Op; - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; + if Mode = 3 then + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_H) <= '1'; + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + else + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; end if; end if; @@ -784,6 +725,11 @@ begin end if; end if; + if ADDSPdd = '1' and TState = 2 then + WZ <= std_logic_vector(SP); + SP <= unsigned(signed(SP)+signed(Save_Mux)); + end if; + if LDSPHL = '1' then SP <= unsigned(RegBusC); end if; @@ -931,7 +877,12 @@ begin when "11001" => SP(15 downto 8) <= unsigned(Save_Mux); when "11011" => - F <= Save_Mux; + if Mode = 3 then + F(7 downto 4) <= Save_Mux(7 downto 4); + F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0 + else + F <= Save_Mux; + end if; when others => end case; if XYbit_undoc='1' then @@ -942,6 +893,42 @@ begin end if; end process; +--------------------------------------------------------------------------- +-- +-- Multiply +-- +--------------------------------------------------------------------------- + process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32) + begin + + MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16))); + MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4); + + if rising_edge(CLK_n) then + if ClkEn = '1' then + if T_Res='1' then + if I_MULUB='1' then + MULU_Prod32(7 downto 0) <= ACC; + MULU_Prod32(15 downto 8) <= "--------"; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1(7 downto 0) <= "00000000"; + if Set_BusB_To(0) = '1' then + MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0); + else + MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8); + end if; + else + MULU_Prod32(15 downto 0) <= RegBusA; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1 <= RegBusB; + end if; + else + MULU_Prod32 <= MULU_tmp; + end if; + end if; + end if; + end process; + --------------------------------------------------------------------------- -- -- BC('), DE('), HL('), IX and IY @@ -997,7 +984,9 @@ begin (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else -- EX HL,DL Alternate & "10" when ExchangeDH = '1' and TState = 3 else - Alternate & "01" when ExchangeDH = '1' and TState = 4 else + Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else + -- LDHLSP + "010" when LDHLSP = '1' and TState = 4 else -- Bus A / Write RegAddrA_r; @@ -1010,8 +999,8 @@ begin ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else signed(RegBusA) + 1; - process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP) begin RegWEH <= '0'; RegWEL <= '0'; @@ -1025,11 +1014,21 @@ begin end case; end if; + if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write + RegWEH <= '1'; + RegWEL <= '1'; + end if; + if ExchangeDH = '1' and (TState = 3 or TState = 4) then RegWEH <= '1'; RegWEL <= '1'; end if; + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then case IncDec_16(1 downto 0) is when "00" | "01" | "10" => @@ -1040,12 +1039,29 @@ begin end if; end process; - process (Save_Mux, RegBusB, RegBusA_r, ID16, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux))); + + process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2) begin RegDIH <= Save_Mux; RegDIL <= Save_Mux; + if I_MULU = '1' then + if T_Res = '1' then + RegDIH <= MULU_Prod32(31 downto 24); + RegDIL <= MULU_Prod32(23 downto 16); + else + RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write + RegDIL <= MULU_tmp(7 downto 0); + end if; + end if; + + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + RegDIH <= TmpAddr2(15 downto 8); + RegDIL <= TmpAddr2(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 3 then RegDIH <= RegBusB(15 downto 8); RegDIL <= RegBusB(7 downto 0); @@ -1176,13 +1192,12 @@ begin TS <= std_logic_vector(TState); DI_Reg <= DI; HALT_n <= not Halt_FF; - BUSAK_n <= not BusAck; + BUSAK_n <= not (BusAck and RESET_n); IntCycle_n <= not IntCycle; NMICycle_n <= not NMICycle; IntE <= IntE_FF1; IORQ <= IORQ_i; Stop <= I_DJNZ; - ------------------------------------------------------------------------- -- -- Main state machine @@ -1196,7 +1211,7 @@ begin TState <= "000"; Pre_XY_F_M <= "000"; Halt_FF <= '0'; - BusAck <= '0'; + --BusAck <= '0'; NMICycle <= '0'; IntCycle <= '0'; IntE_FF1 <= '0'; @@ -1205,10 +1220,9 @@ begin Auto_Wait_t1 <= '0'; Auto_Wait_t2 <= '0'; M1_n <= '1'; - BusReq_s <= '0'; + --BusReq_s <= '0'; NMI_s <= '0'; elsif rising_edge(CLK_n) then - if DIRSet = '1' then IntE_FF2 <= DIR(211); IntE_FF1 <= DIR(210); @@ -1256,13 +1270,20 @@ begin BusAck <= '0'; if TState = 2 and Wait_n = '0' then elsif T_Res = '1' then - if Halt = '1' then + if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0 Halt_FF <= '1'; end if; if BusReq_s = '1' then BusAck <= '1'; else TState <= "001"; + if (IntCycle = '1' and Mode = 3) then -- GB: read interrupt at MCycle 3 + if (MCycle = "010") then + M1_n <= '0'; + else + M1_n <= '1'; + end if; + end if; if NextIs_XY_Fetch = '1' then MCycle <= "110"; Pre_XY_F_M <= MCycle; @@ -1284,6 +1305,8 @@ begin IntCycle <= '1'; IntE_FF1 <= '0'; IntE_FF2 <= '0'; + elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then + Halt_FF <= '0'; end if; else MCycle <= std_logic_vector(unsigned(MCycle) + 1); diff --git a/src/T80/T80_ALU.vhd b/src/T80/T80_ALU.vhd index a9438ae..1192e0b 100644 --- a/src/T80/T80_ALU.vhd +++ b/src/T80/T80_ALU.vhd @@ -89,6 +89,7 @@ entity T80_ALU is WZ : in std_logic_vector(15 downto 0); XY_State : in std_logic_vector(1 downto 0); ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; IR : in std_logic_vector(5 downto 0); ISet : in std_logic_vector(1 downto 0); BusA : in std_logic_vector(7 downto 0); @@ -158,7 +159,7 @@ begin end if; end process; - process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, WZ, XY_State) + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State) variable Q_t : std_logic_vector(7 downto 0); variable DAA_Q : unsigned(8 downto 0); begin @@ -220,35 +221,64 @@ begin end if; when "1100" => -- DAA - F_Out(Flag_H) <= F_In(Flag_H); - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if (DAA_Q(3 downto 0) > 9) then - F_Out(Flag_H) <= '1'; - else - F_Out(Flag_H) <= '0'; + if Mode = 3 then + F_Out(Flag_H) <= '0'; + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if F_In(Flag_H) = '1' then + DAA_Q := DAA_Q - 6; + if F_In(Flag_C) = '0' then + DAA_Q(8) := '0'; + end if; + end if; + if F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 96; -- 0x60 end if; - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 end if; else - -- After subtraction - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if DAA_Q(3 downto 0) > 5 then - F_Out(Flag_H) <= '0'; + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 end if; - DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; - end if; - if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 352; -- 0x160 end if; end if; F_Out(Flag_X) <= DAA_Q(3); @@ -368,6 +398,9 @@ begin F_Out(Flag_S) <= F_In(Flag_S); F_Out(Flag_Z) <= F_In(Flag_Z); end if; + if Mode = 3 and Rot_Akku = '1' then + F_Out(Flag_Z) <= '0'; + end if; when others => null; end case; diff --git a/src/T80/T80_MCode.vhd b/src/T80/T80_MCode.vhd index 0d1fbab..eadf1af 100644 --- a/src/T80/T80_MCode.vhd +++ b/src/T80/T80_MCode.vhd @@ -19,7 +19,7 @@ -- **** -- Z80 compatible microprocessor core -- --- Version : 0242 +-- Version : 0250 -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- All rights reserved -- @@ -69,11 +69,13 @@ -- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes -- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR -- 0242 : Fixed I/O instruction timing, cleanup +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; +use work.T80_Pack.all; entity T80_MCode is generic( @@ -108,6 +110,7 @@ entity T80_MCode is ALU_Op : out std_logic_vector(3 downto 0); -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None Save_ALU : out std_logic; + Rot_Akku : out std_logic; PreserveC : out std_logic; Arith16 : out std_logic; Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI @@ -120,6 +123,8 @@ entity T80_MCode is LDZ : out std_logic; LDW : out std_logic; LDSPHL : out std_logic; + LDHLSP : out std_logic; + ADDSPdd : out std_logic; Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None ExchangeDH : out std_logic; ExchangeRp : out std_logic; @@ -136,6 +141,8 @@ entity T80_MCode is I_RLD : out std_logic; I_RRD : out std_logic; I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; SetWZ : out std_logic_vector(1 downto 0); SetDI : out std_logic; SetEI : out std_logic; @@ -143,20 +150,14 @@ entity T80_MCode is Halt : out std_logic; NoRead : out std_logic; Write : out std_logic; + R800_mode : in std_logic; + No_PC : out std_logic; XYbit_undoc : out std_logic ); end T80_MCode; architecture rtl of T80_MCode is - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; - function is_cc_true( F : std_logic_vector(7 downto 0); cc : bit_vector(2 downto 0) @@ -164,10 +165,10 @@ architecture rtl of T80_MCode is begin if Mode = 3 then case cc is - when "000" => return F(Flag_S) = '0'; -- NZ - when "001" => return F(Flag_S) = '1'; -- Z - when "010" => return F(Flag_H) = '0'; -- NC - when "011" => return F(Flag_H) = '1'; -- C + when "000" => return F(Flag_Z) = '0'; -- NZ + when "001" => return F(Flag_Z) = '1'; -- Z + when "010" => return F(Flag_C) = '0'; -- NC + when "011" => return F(Flag_C) = '1'; -- C when "100" => return false; when "101" => return false; when "110" => return false; @@ -189,7 +190,7 @@ architecture rtl of T80_MCode is begin - process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State) + process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode) variable DDD : std_logic_vector(2 downto 0); variable SSS : std_logic_vector(2 downto 0); variable DPair : std_logic_vector(1 downto 0); @@ -216,6 +217,7 @@ begin Set_BusA_To <= "0000"; ALU_Op <= "0" & IR(5 downto 3); Save_ALU <= '0'; + Rot_Akku <= '0'; PreserveC <= '0'; Arith16 <= '0'; IORQ <= '0'; @@ -228,6 +230,8 @@ begin LDZ <= '0'; LDW <= '0'; LDSPHL <= '0'; + LDHLSP <= '0'; + ADDSPdd <= '0'; Special_LD <= "000"; ExchangeDH <= '0'; ExchangeRp <= '0'; @@ -244,12 +248,15 @@ begin I_RLD <= '0'; I_RRD <= '0'; I_INRC <= '0'; + I_MULUB <= '0'; + I_MULU <= '0'; SetDI <= '0'; SetEI <= '0'; IMode <= "11"; Halt <= '0'; NoRead <= '0'; Write <= '0'; + No_PC <= '0'; XYbit_undoc <= '0'; SetWZ <= "00"; @@ -520,38 +527,76 @@ begin end if; when "11111001" => -- LD SP,HL - TStates <= "110"; - LDSPHL <= '1'; + if Mode = 3 then + MCycles <= "010"; + if MCycle = "010" then + LDSPHL <= '1'; + end if; + else + TStates <= "110"; + LDSPHL <= '1'; + end if; when "11000101"|"11010101"|"11100101"|"11110101" => -- PUSH qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 2 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 3 => - Write <= '1'; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 3 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 4 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; when "11000001"|"11010001"|"11100001"|"11110001" => -- POP qq MCycles <= "011"; @@ -615,7 +660,7 @@ begin when "11011001" => if Mode = 3 then -- RETI - MCycles <= "011"; + MCycles <= "100"; case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_TO <= aSP; @@ -626,7 +671,7 @@ begin when 3 => Jump <= '1'; IncDec_16 <= "0111"; - I_RETN <= '1'; + --I_RETN <= '1'; SetEI <= '1'; when others => null; end case; @@ -643,81 +688,28 @@ begin Set_Addr_To <= aSP; when 2 => Read_To_Reg <= '1'; - Set_BusA_To <= "0101"; -- L, target of Read_To_Reg - Set_BusB_To <= "0101"; -- L, input of ALU + Set_BusA_To <= "0101"; + Set_BusB_To <= "0101"; Set_Addr_To <= aSP; - LDZ <= '1'; -- also load Z + LDZ <= '1'; when 3 => - IncDec_16 <= "0111"; -- Increment SP + IncDec_16 <= "0111"; Set_Addr_To <= aSP; TStates <= "100"; Write <= '1'; when 4 => Read_To_Reg <= '1'; - Set_BusA_To <= "0100"; -- H, target of Read_To_Reg - Set_BusB_To <= "0100"; -- H, input of ALU + Set_BusA_To <= "0100"; + Set_BusB_To <= "0100"; Set_Addr_To <= aSP; - LDW <= '1'; -- also load Z + LDW <= '1'; when 5 => - IncDec_16 <= "1111"; -- Decrement SP + IncDec_16 <= "1111"; TStates <= "101"; Write <= '1'; when others => null; end case; - end if; - --- The T80 implementation does: --- --- (4) M1 fetch --- (3) M2 Read (SP) -> L, Z --- L -> ALU --- (4) M3 Write ALU result -> (SP) --- SP++ --- (3) M4 Read (SP) -> H, W --- H -> ALU --- (5) M5 Write ALU result -> (SP) --- SP-- --- --- The Z80 does --- (4) M1 fetch --- (3) M2 Read (SP) -> Z --- SP++ --- (4) M3 Read (SP) -> W --- (3) M4 Write H -> (SP) --- SP-- --- (5) M5 Write L -> (SP) --- --- and somehow WZ -> HL at the end! --- --- Attempt at a new version. --- --- case to_integer(unsigned(MCycle)) is --- when 1 => --- Set_Addr_To <= aSP; --- when 2 => --- IncDec_16 <= "0111"; --- Read_To_Reg <= '1'; --- Set_BusA_To <= "0101"; --- Set_BusB_To <= "0101"; --- Set_Addr_To <= aSP; --- LDZ <= '1'; --- when 3 => --- Read_To_Reg <= '1'; --- Set_BusA_To <= "0100"; --- Set_BusB_To <= "0100"; --- Set_Addr_To <= aSP; --- TStates <= "100"; --- LDW <= '1'; --- when 4 => --- IncDec_16 <= "1111"; --- Set_Addr_To <= aSP; --- Write <= '1'; --- when 5 => --- TStates <= "101"; --- Write <= '1'; --- when others => null; --- end case; --- end if; + end if; -- 8 BIT ARITHMETIC AND LOGICAL GROUP when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" @@ -869,30 +861,50 @@ begin end case; elsif IntCycle = '1' then -- INT (IM 2) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - LDZ <= '1'; - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - --TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - --TStates <= "100"; - Write <= '1'; - when 4 => - Inc_PC <= '1'; - LDZ <= '1'; - when 5 => - Jump <= '1'; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "110"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + when 3 => -- GB: interrupt is acknowledged on MCycle 3 + LDZ <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 4 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + --TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + --TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + end if; else -- NOP end if; @@ -909,49 +921,108 @@ begin -- 16 BIT ARITHMETIC GROUP when "00001001"|"00011001"|"00101001"|"00111001" => -- ADD HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + when 2 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; when others => - Set_BusB_To <= "1000"; end case; - TStates <= "100"; - Arith16 <= '1'; - SetWZ <= "11"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; when others => - Set_BusB_To <= "1001"; end case; - Arith16 <= '1'; - when others => - end case; + end if; when "00000011"|"00010011"|"00100011"|"00110011" => -- INC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + end if; when "00001011"|"00011011"|"00101011"|"00111011" => -- DEC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + end if; -- ROTATE AND SHIFT GROUP when "00000111" @@ -965,12 +1036,17 @@ begin Set_BusA_To(2 downto 0) <= "111"; ALU_Op <= "1000"; Read_To_Reg <= '1'; + Rot_Akku <= '1'; Save_ALU <= '1'; -- JUMP GROUP when "11000011" => -- JP nn - MCycles <= "011"; + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -978,7 +1054,9 @@ begin when 3 => Inc_PC <= '1'; Jump <= '1'; - LDW <= '1'; + if Mode /= 3 then + LDW <= '1'; + end if; when others => null; end case; when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => @@ -991,9 +1069,9 @@ begin when 1 => Set_Addr_To <= aBC; Set_BusB_To <= "0111"; + IORQ <= '1'; --TH must be earlier to be stable when address is generated when 2 => Write <= '1'; - IORQ <= '1'; when others => end case; when "01" => @@ -1017,9 +1095,9 @@ begin case to_integer(unsigned(MCycle)) is when 1 => Set_Addr_To <= aBC; + IORQ <= '1'; --TH must be earlier to be stable when address is generated when 2 => Read_To_Acc <= '1'; - IORQ <= '1'; when others => end case; when "11" => @@ -1039,16 +1117,24 @@ begin end case; else -- JP cc,nn - MCycles <= "011"; + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; LDZ <= '1'; when 3 => - LDW <= '1'; + if Mode /= 3 then + LDW <= '1'; + end if; Inc_PC <= '1'; if is_cc_true(F, to_bitvector(IR(5 downto 3))) then Jump <= '1'; + elsif Mode = 3 then + MCycles <= "011"; end if; when others => null; end case; @@ -1060,6 +1146,7 @@ begin case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; + No_PC <= '1'; when 3 => NoRead <= '1'; JumpE <= '1'; @@ -1076,6 +1163,8 @@ begin Inc_PC <= '1'; if F(Flag_C) = '0' then MCycles <= "010"; + else + No_PC <= '1'; end if; when 3 => NoRead <= '1'; @@ -1093,6 +1182,8 @@ begin Inc_PC <= '1'; if F(Flag_C) = '1' then MCycles <= "010"; + else + No_PC <= '1'; end if; when 3 => NoRead <= '1'; @@ -1110,6 +1201,8 @@ begin Inc_PC <= '1'; if F(Flag_Z) = '0' then MCycles <= "010"; + else + No_PC <= '1'; end if; when 3 => NoRead <= '1'; @@ -1127,6 +1220,8 @@ begin Inc_PC <= '1'; if F(Flag_Z) = '1' then MCycles <= "010"; + else + No_PC <= '1'; end if; when 3 => NoRead <= '1'; @@ -1138,9 +1233,15 @@ begin when "11101001" => -- JP (HL) JumpXY <= '1'; - when "00010000" => - if Mode = 3 then + when "00010000" => + if Mode = 3 then -- STOP and skip next byte + MCycles <= "010"; I_DJNZ <= '1'; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when others => null; + end case; elsif Mode < 2 then -- DJNZ,e MCycles <= "011"; @@ -1156,6 +1257,7 @@ begin when 2 => I_DJNZ <= '1'; Inc_PC <= '1'; + No_PC <= '1'; when 3 => NoRead <= '1'; JumpE <= '1'; @@ -1167,7 +1269,11 @@ begin -- CALL AND RETURN GROUP when "11001101" => -- CALL nn - MCycles <= "101"; + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -1192,7 +1298,11 @@ begin when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => if IR(5) = '0' or Mode /= 3 then -- CALL cc,nn - MCycles <= "101"; + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; case to_integer(unsigned(MCycle)) is when 2 => Inc_PC <= '1'; @@ -1221,20 +1331,36 @@ begin end if; when "11001001" => -- RET - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - --TStates <= "101"; - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_TO <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + --TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => if IR(5) = '1' and Mode = 3 then case IRB(4 downto 3) is @@ -1252,22 +1378,11 @@ begin end case; when "01" => -- ADD SP,n - MCycles <= "011"; + MCycles <= "100"; case to_integer(unsigned(MCycle)) is - when 2 => - ALU_Op <= "0000"; - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To <= "1000"; - Set_BusB_To <= "0110"; when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To <= "1001"; - Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + Inc_PC <= '1'; + ADDSPdd <= '1'; when others => end case; when "10" => @@ -1282,67 +1397,100 @@ begin when others => null; end case; when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! - MCycles <= "101"; + -- LD HL,SP+n + MCycles <= "011"; case to_integer(unsigned(MCycle)) is + when 1 => + Inc_PC <= '1'; when 2 => + LDHLSP <= '1'; Inc_PC <= '1'; - LDZ <= '1'; when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; + LDHLSP <= '1'; when others => null; end case; end case; else -- RET cc - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "001"; - end if; - TStates <= "101"; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; + if Mode = 3 then + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "010"; + end if; + TStates <= "101"; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; end if; when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => -- RST p - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 3 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 4 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + end if; -- INPUT AND OUTPUT GROUP when "11011011" => @@ -1642,16 +1790,16 @@ begin | "10101100"|"10101101"|"10101110"|"10101111" | "10110100"|"10110101"|"10110110"|"10110111" | "10111100"|"10111101"|"10111110"|"10111111" - |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111" |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => null; -- NOP, undocumented - when "01111110"|"01111111" => + when "01110111"|"01111111" => -- NOP, undocumented null; -- 8 BIT LOAD GROUP @@ -1762,6 +1910,7 @@ begin else IncDec_16 <= "1101"; end if; + No_PC <= '1'; when 4 => NoRead <= '1'; TStates <= "101"; @@ -1785,10 +1934,12 @@ begin else IncDec_16 <= "1110"; end if; + No_PC <= '1'; when 3 => NoRead <= '1'; I_BC <= '1'; TStates <= "101"; + No_PC <= '1'; when 4 => NoRead <= '1'; TStates <= "101"; @@ -1807,7 +1958,7 @@ begin when "01010110"|"01110110" => -- IM 1 IMode <= "01"; - when "01011110"|"01110111" => + when "01011110"|"01111110" => -- IM 2 IMode <= "10"; -- 16 bit arithmetic @@ -1815,6 +1966,8 @@ begin -- ADC HL,ss MCycles <= "011"; case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; when 2 => NoRead <= '1'; ALU_Op <= "0001"; @@ -1830,6 +1983,7 @@ begin end case; TStates <= "100"; SetWZ <= "11"; + No_PC <= '1'; when 3 => NoRead <= '1'; Read_To_Reg <= '1'; @@ -1849,6 +2003,8 @@ begin -- SBC HL,ss MCycles <= "011"; case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; when 2 => NoRead <= '1'; ALU_Op <= "0011"; @@ -1864,6 +2020,7 @@ begin end case; TStates <= "100"; SetWZ <= "11"; + No_PC <= '1'; when 3 => NoRead <= '1'; ALU_Op <= "0011"; @@ -1890,6 +2047,7 @@ begin Set_BusA_To(2 downto 0) <= "111"; ALU_Op <= "1101"; Save_ALU <= '1'; + No_PC <= '1'; when 3 => TStates <= "100"; I_RLD <= '1'; @@ -1911,6 +2069,7 @@ begin Set_BusA_To(2 downto 0) <= "111"; ALU_Op <= "1110"; Save_ALU <= '1'; + No_PC <= '1'; when 3 => TStates <= "100"; I_RRD <= '1'; @@ -2032,6 +2191,46 @@ begin TStates <= "101"; when others => null; end case; + when "11000001"|"11001001"|"11010001"|"11011001" => + --R800 MULUB + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + I_MULUB <= '1'; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + Set_BusB_To(3) <= '0'; + when 2 => + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; + when "11000011"|"11110011" => + --R800 MULUW + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + if DPAIR = "11" then + Set_BusB_To(3 downto 0) <= "1000"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + Set_BusA_To(2 downto 0) <= "100"; + when 2 => + TStates <= "101"; + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; end case; end case; @@ -2064,6 +2263,9 @@ begin if IRB = "00110110" or IRB = "11001011" then Set_Addr_To <= aNone; end if; + if not (IRB = "00110110" or ISet = "01") then + No_PC <= '1'; + end if; end if; if MCycle = "111" then if Mode = 0 then diff --git a/src/T80/T80_Pack.vhd b/src/T80/T80_Pack.vhd index 0b2cfa9..e5186ab 100644 --- a/src/T80/T80_Pack.vhd +++ b/src/T80/T80_Pack.vhd @@ -11,7 +11,7 @@ -- -- Z80 compatible microprocessor core -- --- Version : 0242 +-- Version : 0250 -- -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- @@ -84,7 +84,7 @@ package T80_Pack is port( RESET_n : in std_logic; CLK_n : in std_logic; - CEN : in std_logic; + CEN : in std_logic; WAIT_n : in std_logic; INT_n : in std_logic; NMI_n : in std_logic; @@ -96,16 +96,18 @@ package T80_Pack is RFSH_n : out std_logic; HALT_n : out std_logic; BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); + A : out std_logic_vector(15 downto 0); DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); IntCycle_n : out std_logic; NMICycle_n : out std_logic; IntE : out std_logic; Stop : out std_logic; + R800_mode : in std_logic := '0'; + out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A DIRSet : in std_logic := '0'; DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A @@ -114,24 +116,24 @@ package T80_Pack is component T80_Reg port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0); - DOR : out std_logic_vector(127 downto 0); - DIRSet : in std_logic; - DIR : in std_logic_vector(127 downto 0) + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0); + DOR : out std_logic_vector(127 downto 0); + DIRSet : in std_logic; + DIR : in std_logic_vector(127 downto 0) ); end component; @@ -168,6 +170,7 @@ package T80_Pack is ALU_Op : out std_logic_vector(3 downto 0); -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None Save_ALU : out std_logic; + Rot_Akku : out std_logic; PreserveC : out std_logic; Arith16 : out std_logic; Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI @@ -181,7 +184,7 @@ package T80_Pack is LDW : out std_logic; LDSPHL : out std_logic; LDHLSP : out std_logic; - ADDSPdd : out std_logic; + ADDSPdd : out std_logic; Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None ExchangeDH : out std_logic; ExchangeRp : out std_logic; @@ -198,12 +201,17 @@ package T80_Pack is I_RLD : out std_logic; I_RRD : out std_logic; I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; + SetWZ : out std_logic_vector(1 downto 0); SetDI : out std_logic; SetEI : out std_logic; IMode : out std_logic_vector(1 downto 0); Halt : out std_logic; NoRead : out std_logic; Write : out std_logic; + R800_mode : in std_logic; + No_PC : out std_logic; XYbit_undoc : out std_logic ); end component; @@ -223,7 +231,10 @@ package T80_Pack is port( Arith16 : in std_logic; Z16 : in std_logic; + WZ : in std_logic_vector(15 downto 0); + XY_State : in std_logic_vector(1 downto 0); ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; IR : in std_logic_vector(5 downto 0); ISet : in std_logic_vector(1 downto 0); BusA : in std_logic_vector(7 downto 0); diff --git a/src/T80/T80a.vhd b/src/T80/T80a.vhd index f225df2..36f012f 100644 --- a/src/T80/T80a.vhd +++ b/src/T80/T80a.vhd @@ -203,7 +203,7 @@ begin begin if CLK_n'event and CLK_n = '0' then if CEN = '1' then - Wait_s <= WAIT_n; + Wait_s <= WAIT_n or (IORQ_n_i and MREQ_n_i); if TState = "011" and BUSAK_n_i = '1' then DI_Reg <= to_x01(Din); end if;