1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-05 15:44:40 +00:00

C64: [T65] unstable undocumented opcode fixes

This commit is contained in:
Gyorgy Szombathelyi
2020-04-29 01:43:02 +02:00
parent c8d7084e2c
commit ae220f263d
2 changed files with 58 additions and 7 deletions

View File

@@ -1,6 +1,10 @@
-- ****
-- T65(b) core. In an effort to merge and maintain bug fixes ....
--
-- Ver 315 SzGy April 2020
-- Reduced the IRQ detection delay when RDY is not asserted (NMI?)
-- Undocumented opcodes behavior change during not RDY and page boundary crossing (VICE tests - cpu/sha, cpu/shs, cpu/shxy)
--
-- Ver 313 WoS January 2015
-- Fixed issue that NMI has to be first if issued the same time as a BRK instruction is latched in
-- Now all Lorenz CPU tests on FPGAARCADE C64 core (sources used: SVN version 1021) are OK! :D :D :D
@@ -176,6 +180,8 @@ architecture rtl of T65 is
signal IR : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal DO_r : std_logic_vector(7 downto 0);
signal Mode_r : std_logic_vector(1 downto 0);
signal ALU_Op_r : T_ALU_Op;
signal Write_Data_r : T_Write_Data;
@@ -209,6 +215,7 @@ architecture rtl of T65 is
signal Write_Data : T_Write_Data;
signal Jump : std_logic_vector(1 downto 0);
signal BAAdd : std_logic_vector(1 downto 0);
signal BAQuirk : std_logic_vector(1 downto 0);
signal BreakAtNA : std_logic;
signal ADAdd : std_logic;
signal AddY : std_logic;
@@ -231,6 +238,7 @@ architecture rtl of T65 is
signal Res_n_i : std_logic;
signal Res_n_d : std_logic;
signal rdy_mod : std_logic; -- RDY signal turned off during the instruction
signal really_rdy : std_logic;
signal WRn_i : std_logic;
@@ -268,6 +276,7 @@ begin
IR => IR,
MCycle => MCycle,
P => P,
Rdy_mod => rdy_mod,
--outputs
LCycle => LCycle,
ALU_Op => ALU_Op,
@@ -276,6 +285,7 @@ begin
Write_Data => Write_Data,
Jump => Jump,
BAAdd => BAAdd,
BAQuirk => BAQuirk,
BreakAtNA => BreakAtNA,
ADAdd => ADAdd,
AddY => AddY,
@@ -341,6 +351,13 @@ begin
elsif Clk'event and Clk = '1' then
if (Enable = '1') then
-- some instructions behavior changed by the Rdy line. Detect this at the correct cycles.
if MCycle = "000" then
rdy_mod <= '0';
elsif ((MCycle = "011" and IR /= x"93") or (MCycle = "100" and IR = x"93")) and Rdy = '0' then
rdy_mod <= '1';
end if;
if (really_rdy = '1') then
WRn_i <= not Write or RstCycle;
@@ -534,7 +551,13 @@ begin
when "11" =>
-- BA Adj
if BAL(8) = '1' then
BAH <= std_logic_vector(unsigned(BAH) + 1);
-- Handle quirks with some undocumented opcodes crossing page boundary
case BAQuirk is
when "00" => BAH <= std_logic_vector(unsigned(BAH) + 1); -- no quirk
when "01" => BAH <= std_logic_vector(unsigned(BAH) + 1) and DO_r;
when "10" => BAH <= DO_r;
when others => null;
end case;
end if;
when others =>
end case;
@@ -612,8 +635,10 @@ begin
-- This is the P that gets pushed on stack with correct B flag. I'm not sure if NMI also clears B, but I guess it does.
PwithB<=(P and x"ef") when (IRQCycle='1' or NMICycle='1') else P;
DO <= DO_r;
with Write_Data_r select
DO <=
DO_r <=
DL when Write_Data_DL,
ABC(7 downto 0) when Write_Data_ABC,
X(7 downto 0) when Write_Data_X,

View File

@@ -61,6 +61,7 @@ entity T65_MCode is
IR : in std_logic_vector(7 downto 0);
MCycle : in T_Lcycle;
P : in std_logic_vector(7 downto 0);
Rdy_mod : in std_logic;
LCycle : out T_Lcycle;
ALU_Op : out T_ALU_Op;
Set_BusA_To : out T_Set_BusA_To; -- DI,A,X,Y,S,P,DA,DAO,DAX,AAX
@@ -68,6 +69,7 @@ entity T65_MCode is
Write_Data : out T_Write_Data; -- DL,A,X,Y,S,P,PCL,PCH,AX,AXB,XB,YB
Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel
BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj
BAQuirk : out std_logic_vector(1 downto 0); -- None,And,Copy
BreakAtNA : out std_logic;
ADAdd : out std_logic;
AddY : out std_logic;
@@ -106,7 +108,7 @@ begin
not P(Flag_Z) when "110",
P(Flag_Z) when others;
process (IR, MCycle, P, Branch, Mode)
process (IR, MCycle, P, Branch, Mode, Rdy_mod)
begin
lCycle <= Cycle_1;
Set_BusA_To <= Set_BusA_To_ABC;
@@ -114,6 +116,7 @@ begin
Write_Data <= Write_Data_DL;
Jump <= (others => '0');
BAAdd <= "00";
BAQuirk <= "00";
BreakAtNA <= '0';
ADAdd <= '0';
PCAdd <= '0';
@@ -140,14 +143,22 @@ begin
when "00" => -- IR: $80,$84,$88,$8C,$90,$94,$98,$9C
Set_BusA_To <= Set_BusA_To_Y;
if IR(4 downto 2)="111" then -- SYA ($9C)
Write_Data <= Write_Data_YB;
if Rdy_mod = '0' then
Write_Data <= Write_Data_YB;
else
Write_Data <= Write_Data_Y;
end if;
else
Write_Data <= Write_Data_Y;
end if;
when "10" => -- IR: $82,$86,$8A,$8E,$92,$96,$9A,$9E
Set_BusA_To <= Set_BusA_To_X;
if IR(4 downto 2)="111" then -- SXA ($9E)
Write_Data <= Write_Data_XB;
if Rdy_mod = '0' then
Write_Data <= Write_Data_XB;
else
Write_Data <= Write_Data_X;
end if;
else
Write_Data <= Write_Data_X;
end if;
@@ -159,7 +170,11 @@ begin
Set_BusA_To <= Set_BusA_To_ABC;
end if;
if IR(4 downto 2)="111" or IR(4 downto 2)="110" or IR(4 downto 2)="100" then -- SHA ($9F, $93), SHS ($9B)
Write_Data <= Write_Data_AXB;
if Rdy_mod = '0' then
Write_Data <= Write_Data_AXB;
else
Write_Data <= Write_Data_AX;
end if;
else
Write_Data <= Write_Data_AX;
end if;
@@ -843,6 +858,9 @@ begin
BAAdd <= "11"; -- BA Adj
if IR(7 downto 5) = "100" then
Write <= '1';
if IR(3 downto 0) = x"3" then
BAQuirk <= "10"; -- COPY
end if;
elsif IR(1)='0' or IR=x"B3" then -- Dont do this on $x3, except undoc LAXiy $B3 (says real CPU and Lorenz tests)
BreakAtNA <= '1';
end if;
@@ -956,6 +974,9 @@ begin
BAAdd <= "11"; -- BA adj
if IR(7 downto 5) = "100" then--99/9b
Write <= '1';
if IR(3 downto 0) = x"B" then
BAQuirk <= "01"; -- AND
end if;
elsif IR(1)='0' or IR=x"BB" then -- Dont do this on $xB, except undoc $BB (says real CPU and Lorenz tests)
BreakAtNA <= '1';
end if;
@@ -1045,8 +1066,13 @@ begin
Set_Addr_To <= Set_Addr_To_BA;
when Cycle_3 =>
BAAdd <= "11"; -- BA adj
if IR(7 downto 5) = "100" then -- ($9E,$9F)
if IR(7 downto 5) = "100" then -- ($9C,$9D,$9E,$9F)
Write <= '1';
case IR(1 downto 0) is
when "00"|"10" => BAQuirk <= "01"; -- AND
when "11" => BAQuirk <= "10"; -- COPY
when others => null;
end case;
else
BreakAtNA <= '1';
end if;