mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
Merge pull request #4 from brNX/opcodetimings
Opcode timings, ADD SP,dd and LD HL,SP+dd, F Register
This commit is contained in:
2
gb.v
2
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
|
||||
|
||||
59
t80/T80.vhd
59
t80/T80.vhd
@@ -150,6 +150,8 @@ 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);
|
||||
@@ -223,6 +225,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;
|
||||
@@ -292,6 +296,8 @@ begin
|
||||
LDZ => LDZ,
|
||||
LDW => LDW,
|
||||
LDSPHL => LDSPHL,
|
||||
LDHLSP => LDHLSP,
|
||||
ADDSPdd => ADDSPdd,
|
||||
Special_LD => Special_LD,
|
||||
ExchangeDH => ExchangeDH,
|
||||
ExchangeRp => ExchangeRp,
|
||||
@@ -366,7 +372,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');
|
||||
@@ -393,6 +403,22 @@ 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 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";
|
||||
@@ -588,6 +614,11 @@ begin
|
||||
end if;
|
||||
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);
|
||||
@@ -698,7 +729,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
|
||||
@@ -768,6 +804,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;
|
||||
|
||||
@@ -781,7 +819,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';
|
||||
@@ -799,6 +837,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
|
||||
@@ -811,11 +854,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);
|
||||
|
||||
@@ -121,9 +121,11 @@ 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;
|
||||
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;
|
||||
@@ -223,6 +225,8 @@ begin
|
||||
LDZ <= '0';
|
||||
LDW <= '0';
|
||||
LDSPHL <= '0';
|
||||
LDHLSP <= '0';
|
||||
ADDSPdd <= '0';
|
||||
Special_LD <= "000";
|
||||
ExchangeDH <= '0';
|
||||
ExchangeRp <= '0';
|
||||
@@ -515,34 +519,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 +642,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 +887,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 +908,7 @@ begin
|
||||
end case;
|
||||
TStates <= "100";
|
||||
Arith16 <= '1';
|
||||
when 3 =>
|
||||
when 2 =>
|
||||
NoRead <= '1';
|
||||
Read_To_Reg <= '1';
|
||||
Save_ALU <= '1';
|
||||
@@ -885,9 +925,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 +961,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 +1162,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 +1191,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 +1224,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,22 +1271,13 @@ 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";
|
||||
-- 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" =>
|
||||
@@ -1222,24 +1292,16 @@ 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 =>
|
||||
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;
|
||||
@@ -1266,7 +1328,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 +1603,7 @@ begin
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
|
||||
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
|
||||
-- RES b,(HL)
|
||||
MCycles <= "011";
|
||||
|
||||
@@ -173,6 +173,8 @@ package T80_Pack 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;
|
||||
|
||||
7
timer.v
7
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user