From 671775685285072074376165b6b2039c2bba494e Mon Sep 17 00:00:00 2001 From: Bruno Duarte Gouveia Date: Sat, 3 Nov 2018 00:40:04 +0000 Subject: [PATCH 1/5] fixed some opcode timings and reset div when reseting gameboy --- t80/T80_MCode.vhd | 189 ++++++++++++++++++++++++++++++++-------------- timer.v | 7 +- 2 files changed, 139 insertions(+), 57 deletions(-) diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd index f2b602c..bce26be 100644 --- a/t80/T80_MCode.vhd +++ b/t80/T80_MCode.vhd @@ -515,34 +515,66 @@ begin LDSPHL <= '1'; 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"; @@ -606,7 +638,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; @@ -851,9 +883,13 @@ begin -- 16 BIT ARITHMETIC GROUP when "00001001"|"00011001"|"00101001"|"00111001" => -- ADD HL,ss - MCycles <= "011"; + if Mode = 3 then + MCycles <= "010"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is - when 2 => + when 1 => NoRead <= '1'; ALU_Op <= "0000"; Read_To_Reg <= '1'; @@ -868,7 +904,7 @@ begin end case; TStates <= "100"; Arith16 <= '1'; - when 3 => + when 2 => NoRead <= '1'; Read_To_Reg <= '1'; Save_ALU <= '1'; @@ -885,9 +921,19 @@ begin end case; 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"; @@ -911,7 +957,11 @@ begin -- 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'; @@ -1108,7 +1158,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'; @@ -1133,7 +1187,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'; @@ -1162,19 +1220,36 @@ begin end if; when "11001001" => -- RET - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - 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 => + 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 @@ -1192,7 +1267,7 @@ begin end case; when "01" => -- ADD SP,n - MCycles <= "011"; + MCycles <= "100"; case to_integer(unsigned(MCycle)) is when 2 => ALU_Op <= "0000"; @@ -1222,7 +1297,7 @@ begin when others => null; end case; when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! //shoud be mcycles=011, n is signed MCycles <= "101"; case to_integer(unsigned(MCycle)) is when 2 => @@ -1266,7 +1341,11 @@ begin end if; when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => -- RST p - MCycles <= "011"; + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; case to_integer(unsigned(MCycle)) is when 1 => TStates <= "101"; @@ -1537,7 +1616,7 @@ begin when others => null; end case; end if; - + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => -- RES b,(HL) MCycles <= "011"; diff --git a/timer.v b/timer.v index cef7041..4b47495 100644 --- a/timer.v +++ b/timer.v @@ -22,7 +22,6 @@ module timer ( input reset, input clk, // 4 Mhz cpu clock - output reg irq, // cpu register interface @@ -52,7 +51,10 @@ always @(posedge clk or posedge resetdiv) if(resetdiv) clk_div <= 10'd6; else - clk_div <= clk_div + 10'd1; + if (reset) + clk_div <= 10'd6; + else + clk_div <= clk_div + 10'd1; reg [7:0] div; reg [7:0] tma; @@ -65,6 +67,7 @@ always @(posedge clk) begin tma <= 0; tac <= 0; irq <= 0; + div <= 0; end else begin irq <= 0; From a108c3c11cc041800fc10abb32899bca32fafcc4 Mon Sep 17 00:00:00 2001 From: Bruno Duarte Gouveia Date: Sat, 3 Nov 2018 16:13:43 +0000 Subject: [PATCH 2/5] fixed F flag so that 4 lowest bits always return 0 --- t80/T80.vhd | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/t80/T80.vhd b/t80/T80.vhd index a8ddd9b..310b9d2 100644 --- a/t80/T80.vhd +++ b/t80/T80.vhd @@ -366,7 +366,11 @@ begin DO <= "00000000"; ACC <= (others => '1'); - F <= (others => '1'); + if Mode = 3 then + F <= "11110000"; + else + F <= (others => '1'); + end if; Ap <= (others => '1'); Fp <= (others => '1'); I <= (others => '0'); @@ -698,7 +702,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 From d515cb8127f1d52131c568b7c7af7cf09ceeffd8 Mon Sep 17 00:00:00 2001 From: Bruno Duarte Gouveia Date: Mon, 5 Nov 2018 13:42:03 +0000 Subject: [PATCH 3/5] trigger interrupt earlier, on negedge --- gb.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gb.v b/gb.v index c814cb7..424847b 100644 --- a/gb.v +++ b/gb.v @@ -177,7 +177,7 @@ wire irq_n = !(ie_r & if_r); reg [4:0] if_r; reg [4:0] ie_r; // writing $ffff sets the irq enable mask -always @(posedge clk) begin +always @(negedge clk) begin //negedge to trigger interrupt earlier reg old_ack = 0; if(reset) begin From 03cfb9364ac582c42d5c702b665cb00a3c69a3d2 Mon Sep 17 00:00:00 2001 From: Bruno Duarte Gouveia Date: Mon, 5 Nov 2018 13:46:38 +0000 Subject: [PATCH 4/5] ld hl,sp+dd instruction redone(probably not the "right" way) Moved things arround for LDHLSP added Flags, should be ok --- t80/T80.vhd | 31 ++++++++++++++++++++++++++++--- t80/T80_MCode.vhd | 28 +++++++++++----------------- t80/T80_Pack.vhd | 1 + 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/t80/T80.vhd b/t80/T80.vhd index 310b9d2..acb4c90 100644 --- a/t80/T80.vhd +++ b/t80/T80.vhd @@ -150,6 +150,7 @@ architecture rtl of T80 is -- Help Registers signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address 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); @@ -223,6 +224,7 @@ architecture rtl of T80 is signal LDZ : std_logic; signal LDW : std_logic; signal LDSPHL : std_logic; + signal LDHLSP : std_logic; signal IORQ_i : std_logic; signal Special_LD : std_logic_vector(2 downto 0); signal ExchangeDH : std_logic; @@ -292,6 +294,7 @@ begin LDZ => LDZ, LDW => LDW, LDSPHL => LDSPHL, + LDHLSP => LDHLSP, Special_LD => Special_LD, ExchangeDH => ExchangeDH, ExchangeRp => ExchangeRp, @@ -397,6 +400,14 @@ begin Read_To_Reg_r <= "00000"; MCycles <= MCycles_d; + + if LDHLSP = '1' and TState = 1 then + TmpAddr <= std_logic_vector(SP xor unsigned(Save_Mux) xor unsigned(TmpAddr2)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= TmpAddr(4); + F(Flag_C) <= TmpAddr(8); + end if; if Mode = 3 then IStatus <= "10"; @@ -592,6 +603,7 @@ begin end if; end if; end if; + if LDSPHL = '1' then SP <= unsigned(RegBusC); @@ -777,6 +789,8 @@ begin -- EX HL,DL Alternate & "10" when ExchangeDH = '1' and TState = 3 else Alternate & "01" when ExchangeDH = '1' and TState = 4 else + -- LDHLSP + "010" when LDHLSP = '1' and TState = 4 else -- Bus A / Write RegAddrA_r; @@ -790,7 +804,7 @@ begin signed(RegBusA) + 1; process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + ExchangeDH, IncDec_16, MCycle, TState, Wait_n,LDHLSP) begin RegWEH <= '0'; RegWEL <= '0'; @@ -808,6 +822,11 @@ begin 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 @@ -820,11 +839,17 @@ begin end process; process (Save_Mux, RegBusB, RegBusA_r, ID16, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP) begin RegDIH <= Save_Mux; RegDIL <= Save_Mux; - + + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux))); + 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); diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd index bce26be..d117837 100644 --- a/t80/T80_MCode.vhd +++ b/t80/T80_MCode.vhd @@ -121,9 +121,10 @@ entity T80_MCode is JumpXY : out std_logic; Call : out std_logic; RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; LDSPHL : out std_logic; + LDHLSP : 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; @@ -223,6 +224,7 @@ begin LDZ <= '0'; LDW <= '0'; LDSPHL <= '0'; + LDHLSP <= '0'; Special_LD <= "000"; ExchangeDH <= '0'; ExchangeRp <= '0'; @@ -1297,24 +1299,16 @@ begin when others => null; end case; when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! //shoud be mcycles=011, n is signed - MCycles <= "101"; + -- LD HL,SP+n + MCycles <= "011"; case to_integer(unsigned(MCycle)) is + when 1 => + Inc_PC <= '1'; when 2 => - Inc_PC <= '1'; - LDZ <= '1'; + LDHLSP <= '1'; + Inc_PC <= '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; diff --git a/t80/T80_Pack.vhd b/t80/T80_Pack.vhd index 26ff6b2..147901d 100644 --- a/t80/T80_Pack.vhd +++ b/t80/T80_Pack.vhd @@ -173,6 +173,7 @@ package T80_Pack is LDZ : out std_logic; LDW : out std_logic; LDSPHL : out std_logic; + LDHLSP : 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; From 61b8f537d87a7c8298cacd3f421528a6dcdc85d2 Mon Sep 17 00:00:00 2001 From: Bruno Duarte Gouveia Date: Mon, 5 Nov 2018 23:21:38 +0000 Subject: [PATCH 5/5] re-did ADD SP,+/-dd, still need to check if F flag is correct --- t80/T80.vhd | 15 +++++++++++++++ t80/T80_MCode.vhd | 17 +++++------------ t80/T80_Pack.vhd | 1 + 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/t80/T80.vhd b/t80/T80.vhd index acb4c90..f70728a 100644 --- a/t80/T80.vhd +++ b/t80/T80.vhd @@ -151,6 +151,7 @@ architecture rtl of T80 is -- Help Registers signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register + signal TmpAddr3 : 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); @@ -225,6 +226,7 @@ architecture rtl of T80 is 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; @@ -295,6 +297,7 @@ begin LDW => LDW, LDSPHL => LDSPHL, LDHLSP => LDHLSP, + ADDSPdd => ADDSPdd, Special_LD => Special_LD, ExchangeDH => ExchangeDH, ExchangeRp => ExchangeRp, @@ -408,6 +411,14 @@ begin F(Flag_H) <= TmpAddr(4); F(Flag_C) <= TmpAddr(8); end if; + + if ADDSPdd = '1' and TState = 4 then + TmpAddr3 <= std_logic_vector(SP xor unsigned(Save_Mux) xor unsigned(TmpAddr)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= TmpAddr3(4); + F(Flag_C) <= TmpAddr3(8); + end if; if Mode = 3 then IStatus <= "10"; @@ -604,6 +615,10 @@ begin end if; end if; + if ADDSPdd = '1' and TState = 2 then + TmpAddr<=std_logic_vector(SP); + SP <= unsigned(signed(SP)+signed(Save_Mux)); + end if; if LDSPHL = '1' then SP <= unsigned(RegBusC); diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd index d117837..125d3df 100644 --- a/t80/T80_MCode.vhd +++ b/t80/T80_MCode.vhd @@ -125,6 +125,7 @@ entity T80_MCode is 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; @@ -225,6 +226,7 @@ begin LDW <= '0'; LDSPHL <= '0'; LDHLSP <= '0'; + ADDSPdd <= '0'; Special_LD <= "000"; ExchangeDH <= '0'; ExchangeRp <= '0'; @@ -1272,19 +1274,10 @@ begin 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"; + -- Inc_PC <= '1'; 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" => diff --git a/t80/T80_Pack.vhd b/t80/T80_Pack.vhd index 147901d..f41ce1f 100644 --- a/t80/T80_Pack.vhd +++ b/t80/T80_Pack.vhd @@ -174,6 +174,7 @@ package T80_Pack is 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;