Updated to later T65 core; added read command; tidied up register display; update version to 0.24

Change-Id: I932eb0caa8f800989346f98f038b9c43814abaef
This commit is contained in:
David Banks 2015-06-17 11:17:12 +01:00
parent 664c3194c4
commit e075d54924
6 changed files with 2479 additions and 2008 deletions

View File

@ -113,10 +113,10 @@ char *triggerStrings[NUM_TRIGGERS] = {
};
#define VERSION "0.23"
#define VERSION "0.24"
#ifdef EMBEDDED_6502
#define NUM_CMDS 23
#define NUM_CMDS 24
#else
#define NUM_CMDS 19
#endif
@ -171,6 +171,7 @@ char *cmdStrings[NUM_CMDS] = {
"regs",
"mem",
"dis",
"read",
"write",
#endif
"reset",
@ -467,13 +468,12 @@ void doCmdReset(char *params) {
#ifdef EMBEDDED_6502
void doCmdRegs(char *params) {
log0("A=%02x; ", hwRead8(OFFSET_REG_A));
log0("X=%02x; ", hwRead8(OFFSET_REG_X));
log0("Y=%02x; ", hwRead8(OFFSET_REG_Y));
log0("P=%02x; ", hwRead8(OFFSET_REG_P));
log0("SP=%04x; ", hwRead16(OFFSET_REG_SPL));
log0("PC=%04x; ", hwRead16(OFFSET_REG_PCL));
log0("\n");
log0("A=%02X; ", hwRead8(OFFSET_REG_A));
log0("X=%02X; ", hwRead8(OFFSET_REG_X));
log0("Y=%02X; ", hwRead8(OFFSET_REG_Y));
log0("P=%02X; ", hwRead8(OFFSET_REG_P));
log0("SP=01%02X; ", hwRead8(OFFSET_REG_SPL));
log0("PC=%04X\n", hwRead16(OFFSET_REG_PCL));
}
void doCmdMem(char *params) {
@ -507,6 +507,15 @@ void doCmdWrite(char *params) {
writeMem(addr, data);
}
void doCmdRead(char *params) {
unsigned int addr;
sscanf(params, "%x", &addr);
unsigned int data;
data = readMem(addr);
log0("Rd: %04X = %X\n", addr, data);
writeMem(addr, data);
}
#endif
void doCmdTrace(char *params) {
@ -775,6 +784,7 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = {
doCmdRegs,
doCmdMem,
doCmdDis,
doCmdRead,
doCmdWrite,
#endif
doCmdReset,

View File

@ -126,9 +126,9 @@ begin
Abort_n => '1',
SO_n => SO_n,
Res_n => Res_n,
Enable => '1',
Enable => Rdy_int,
Clk => cpu_clk,
Rdy => Rdy_int,
Rdy => '1',
IRQ_n => IRQ_n_sync,
NMI_n => NMI_n_sync,
R_W_n => R_W_n_int,

940
src/T6502/T65.vhd Executable file → Normal file

File diff suppressed because it is too large Load Diff

330
src/T6502/T65_ALU.vhd Executable file → Normal file
View File

@ -2,6 +2,8 @@
-- T65(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 303 ost(ML) July 2014
-- ALU opcodes to vhdl types
-- Ver 300 Bugfixes by ehenciak added
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
@ -62,199 +64,201 @@ use IEEE.numeric_std.all;
use work.T65_Pack.all;
entity T65_ALU is
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
Op : in std_logic_vector(3 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
Op : in T_ALU_OP;
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
end T65_ALU;
architecture rtl of T65_ALU is
-- AddSub variables (temporary signals)
signal ADC_Z : std_logic;
signal ADC_C : std_logic;
signal ADC_V : std_logic;
signal ADC_N : std_logic;
signal ADC_Q : std_logic_vector(7 downto 0);
signal SBC_Z : std_logic;
signal SBC_C : std_logic;
signal SBC_V : std_logic;
signal SBC_N : std_logic;
signal SBC_Q : std_logic_vector(7 downto 0);
-- AddSub variables (temporary signals)
signal ADC_Z : std_logic;
signal ADC_C : std_logic;
signal ADC_V : std_logic;
signal ADC_N : std_logic;
signal ADC_Q : std_logic_vector(7 downto 0);
signal SBC_Z : std_logic;
signal SBC_C : std_logic;
signal SBC_V : std_logic;
signal SBC_N : std_logic;
signal SBC_Q : std_logic_vector(7 downto 0);
begin
process (P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(6 downto 0);
variable C : std_logic;
begin
AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7);
AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
process (P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(6 downto 0);
variable C : std_logic;
begin
AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7);
AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
-- pragma translate_off
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
-- pragma translate_on
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
ADC_Z <= '1';
else
ADC_Z <= '0';
end if;
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
ADC_Z <= '1';
else
ADC_Z <= '0';
end if;
if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AL(6 downto 1) := AL(6 downto 1) + 6;
end if;
if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AL(6 downto 1) := AL(6 downto 1) + 6;
end if;
C := AL(6) or AL(5);
AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
C := AL(6) or AL(5);
AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
ADC_N <= AH(4);
ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7));
ADC_N <= AH(4);
ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7));
-- pragma translate_off
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
-- pragma translate_on
if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AH(6 downto 1) := AH(6 downto 1) + 6;
end if;
if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AH(6 downto 1) := AH(6 downto 1) + 6;
end if;
ADC_C <= AH(6) or AH(5);
ADC_C <= AH(6) or AH(5);
ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
process (Op, P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(5 downto 0);
variable C : std_logic;
begin
C := P_In(Flag_C) or not Op(0);
AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6);
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6);
process (Op, P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(5 downto 0);
variable C : std_logic;
variable CT : std_logic;
begin
CT:='0';
if( Op=ALU_OP_AND or --"0001" These OpCodes used to have LSB set
Op=ALU_OP_ADC or --"0011"
Op=ALU_OP_EQ2 or --"0101"
Op=ALU_OP_SBC or --"0111"
Op=ALU_OP_ROL or --"1001"
Op=ALU_OP_ROR or --"1011"
Op=ALU_OP_EQ3 or --"1101"
Op=ALU_OP_INC --"1111"
) then
CT:='1';
end if;
C := P_In(Flag_C) or not CT;--was: or not Op(0);
AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6);
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6);
-- pragma translate_off
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "000000"; end if;
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "000000"; end if;
-- pragma translate_on
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
SBC_Z <= '1';
else
SBC_Z <= '0';
end if;
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
SBC_Z <= '1';
else
SBC_Z <= '0';
end if;
SBC_C <= not AH(5);
SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7));
SBC_N <= AH(4);
SBC_C <= not AH(5);
SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7));
SBC_N <= AH(4);
if P_In(Flag_D) = '1' then
if AL(5) = '1' then
AL(5 downto 1) := AL(5 downto 1) - 6;
end if;
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6);
if AH(5) = '1' then
AH(5 downto 1) := AH(5 downto 1) - 6;
end if;
end if;
if P_In(Flag_D) = '1' then
if AL(5) = '1' then
AL(5 downto 1) := AL(5 downto 1) - 6;
end if;
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6);
if AH(5) = '1' then
AH(5 downto 1) := AH(5 downto 1) - 6;
end if;
end if;
SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
process (Op, P_In, BusA, BusB,
ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q,
SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q)
variable Q_t : std_logic_vector(7 downto 0);
begin
-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
P_Out <= P_In;
Q_t := BusA;
case Op(3 downto 0) is
when "0000" =>
-- ORA
Q_t := BusA or BusB;
when "0001" =>
-- AND
Q_t := BusA and BusB;
when "0010" =>
-- EOR
Q_t := BusA xor BusB;
when "0011" =>
-- ADC
P_Out(Flag_V) <= ADC_V;
P_Out(Flag_C) <= ADC_C;
Q_t := ADC_Q;
when "0101" | "1101" =>
-- LDA
when "0110" =>
-- CMP
P_Out(Flag_C) <= SBC_C;
when "0111" =>
-- SBC
P_Out(Flag_V) <= SBC_V;
P_Out(Flag_C) <= SBC_C;
Q_t := SBC_Q;
when "1000" =>
-- ASL
Q_t := BusA(6 downto 0) & "0";
P_Out(Flag_C) <= BusA(7);
when "1001" =>
-- ROL
Q_t := BusA(6 downto 0) & P_In(Flag_C);
P_Out(Flag_C) <= BusA(7);
when "1010" =>
-- LSR
Q_t := "0" & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when "1011" =>
-- ROR
Q_t := P_In(Flag_C) & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when "1100" =>
-- BIT
P_Out(Flag_V) <= BusB(6);
when "1110" =>
-- DEC
Q_t := std_logic_vector(unsigned(BusA) - 1);
when "1111" =>
-- INC
Q_t := std_logic_vector(unsigned(BusA) + 1);
when others =>
end case;
process (Op, P_In, BusA, BusB,
ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q,
SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q)
variable Q_t : std_logic_vector(7 downto 0);
begin
-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
P_Out <= P_In;
Q_t := BusA;
case Op is
when ALU_OP_OR=>
Q_t := BusA or BusB;
when ALU_OP_AND=>
Q_t := BusA and BusB;
when ALU_OP_EOR=>
Q_t := BusA xor BusB;
when ALU_OP_ADC=>
P_Out(Flag_V) <= ADC_V;
P_Out(Flag_C) <= ADC_C;
Q_t := ADC_Q;
when ALU_OP_EQ2|ALU_OP_EQ3=>
-- LDA
when ALU_OP_CMP=>
P_Out(Flag_C) <= SBC_C;
when ALU_OP_SBC=>
P_Out(Flag_V) <= SBC_V;
P_Out(Flag_C) <= SBC_C;
Q_t := SBC_Q;
when ALU_OP_ASL=>
Q_t := BusA(6 downto 0) & "0";
P_Out(Flag_C) <= BusA(7);
when ALU_OP_ROL=>
Q_t := BusA(6 downto 0) & P_In(Flag_C);
P_Out(Flag_C) <= BusA(7);
when ALU_OP_LSR=>
Q_t := "0" & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when ALU_OP_ROR=>
Q_t := P_In(Flag_C) & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when ALU_OP_BIT=>
P_Out(Flag_V) <= BusB(6);
when ALU_OP_DEC=>
Q_t := std_logic_vector(unsigned(BusA) - 1);
when ALU_OP_INC=>
Q_t := std_logic_vector(unsigned(BusA) + 1);
when others =>
--EQ1,EQ2,EQ3 passes BusA to Q_t
end case;
case Op(3 downto 0) is
when "0011" =>
P_Out(Flag_N) <= ADC_N;
P_Out(Flag_Z) <= ADC_Z;
when "0110" | "0111" =>
P_Out(Flag_N) <= SBC_N;
P_Out(Flag_Z) <= SBC_Z;
when "0100" =>
when "1100" =>
P_Out(Flag_N) <= BusB(7);
if (BusA and BusB) = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
when others =>
P_Out(Flag_N) <= Q_t(7);
if Q_t = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
end case;
case Op is
when ALU_OP_ADC=>
P_Out(Flag_N) <= ADC_N;
P_Out(Flag_Z) <= ADC_Z;
when ALU_OP_CMP|ALU_OP_SBC=>
P_Out(Flag_N) <= SBC_N;
P_Out(Flag_Z) <= SBC_Z;
when ALU_OP_EQ1=>
when ALU_OP_BIT=>
P_Out(Flag_N) <= BusB(7);
if (BusA and BusB) = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
when others =>
P_Out(Flag_N) <= Q_t(7);
if Q_t = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
end case;
Q <= Q_t;
end process;
Q <= Q_t;
end process;
end;

2274
src/T6502/T65_MCode.vhd Executable file → Normal file

File diff suppressed because it is too large Load Diff

157
src/T6502/T65_Pack.vhd Executable file → Normal file
View File

@ -2,6 +2,8 @@
-- T65(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 303 ost(ML) July 2014
-- "magic" constants converted to vhdl types
-- Ver 300 Bugfixes by ehenciak added
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
@ -59,59 +61,110 @@ use IEEE.std_logic_1164.all;
package T65_Pack is
constant Flag_C : integer := 0;
constant Flag_Z : integer := 1;
constant Flag_I : integer := 2;
constant Flag_D : integer := 3;
constant Flag_B : integer := 4;
constant Flag_1 : integer := 5;
constant Flag_V : integer := 6;
constant Flag_N : integer := 7;
constant Flag_C : integer := 0;
constant Flag_Z : integer := 1;
constant Flag_I : integer := 2;
constant Flag_D : integer := 3;
constant Flag_B : integer := 4;
constant Flag_1 : integer := 5;
constant Flag_V : integer := 6;
constant Flag_N : integer := 7;
component T65_MCode
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
IR : in std_logic_vector(7 downto 0);
MCycle : in std_logic_vector(2 downto 0);
P : in std_logic_vector(7 downto 0);
LCycle : out std_logic_vector(2 downto 0);
ALU_Op : out std_logic_vector(3 downto 0);
Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P
Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA
Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH
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
BreakAtNA : out std_logic;
ADAdd : out std_logic;
AddY : out std_logic;
PCAdd : out std_logic;
Inc_S : out std_logic;
Dec_S : out std_logic;
LDA : out std_logic;
LDP : out std_logic;
LDX : out std_logic;
LDY : out std_logic;
LDS : out std_logic;
LDDI : out std_logic;
LDALU : out std_logic;
LDAD : out std_logic;
LDBAL : out std_logic;
LDBAH : out std_logic;
SaveP : out std_logic;
Write : out std_logic
);
end component;
type T_Set_BusA_To is
(
Set_BusA_To_DI,
Set_BusA_To_ABC,
Set_BusA_To_X,
Set_BusA_To_Y,
Set_BusA_To_S,
Set_BusA_To_P,
Set_BusA_To_DONTCARE
);
type T_Set_Addr_To is
(
Set_Addr_To_S,
Set_Addr_To_AD,
Set_Addr_To_PBR,
Set_Addr_To_BA
);
type T_Write_Data is
(
Write_Data_DL,
Write_Data_ABC,
Write_Data_X,
Write_Data_Y,
Write_Data_S,
Write_Data_P,
Write_Data_PCL,
Write_Data_PCH,
Write_Data_DONTCARE
);
type T_ALU_OP is
(
ALU_OP_OR, --"0000"
ALU_OP_AND, --"0001"
ALU_OP_EOR, --"0010"
ALU_OP_ADC, --"0011"
ALU_OP_EQ1, --"0100" EQ1 does not change N,Z flags, EQ2/3 does.
ALU_OP_EQ2, --"0101"Not sure yet whats the difference between EQ2&3. They seem to do the same ALU op
ALU_OP_CMP, --"0110"
ALU_OP_SBC, --"0111"
ALU_OP_ASL, --"1000"
ALU_OP_ROL, --"1001"
ALU_OP_LSR, --"1010"
ALU_OP_ROR, --"1011"
ALU_OP_BIT, --"1100"
ALU_OP_EQ3, --"1101"
ALU_OP_DEC, --"1110"
ALU_OP_INC, --"1111"
ALU_OP_UNDEF--"----"--may be replaced with any?
);
component T65_ALU
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
Op : in std_logic_vector(3 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
end component;
component T65_MCode
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
IR : in std_logic_vector(7 downto 0);
MCycle : in std_logic_vector(2 downto 0);
P : in std_logic_vector(7 downto 0);
LCycle : out std_logic_vector(2 downto 0);
ALU_Op : out T_ALU_Op;
Set_BusA_To : out T_Set_BusA_To;-- DI,A,X,Y,S,P
Set_Addr_To : out T_Set_Addr_To;-- PC Adder,S,AD,BA
Write_Data : out T_Write_Data;-- DL,A,X,Y,S,P,PCL,PCH
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
BreakAtNA : out std_logic;
ADAdd : out std_logic;
AddY : out std_logic;
PCAdd : out std_logic;
Inc_S : out std_logic;
Dec_S : out std_logic;
LDA : out std_logic;
LDP : out std_logic;
LDX : out std_logic;
LDY : out std_logic;
LDS : out std_logic;
LDDI : out std_logic;
LDALU : out std_logic;
LDAD : out std_logic;
LDBAL : out std_logic;
LDBAH : out std_logic;
SaveP : out std_logic;
ALUmore : out std_logic;
Write : out std_logic
);
end component;
component T65_ALU
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
Op : in T_ALU_Op;
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
end component;
end;