📄 cpu65xx_fast.vhd
字号:
"0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 5C iNOP abs,x
"1000" & "100010" & readAbsX & aluInT & aluEor, -- 5D EOR abs,x
"0000" & "100011" & rmwAbsX & aluInT & aluLsr, -- 5E LSR abs,x
"1000" & "100011" & rmwAbsX & aluInT & aluSre, -- 5F SRE abs,x
-- AXYS NVDIZC addressing aluInput aluMode
"0000" & "000000" & rts & aluInXXX & aluXXX, -- 60 RTS
"1000" & "110011" & readIndX & aluInT & aluAdc, -- 61 ADC (zp,x)
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 62 *** JAM ***
"1000" & "110011" & rmwIndX & aluInT & aluRra, -- 63 iRRA (zp,x)
"0000" & "000000" & readZp & aluInXXX & aluXXX, -- 64 iNOP zp
"1000" & "110011" & readZp & aluInT & aluAdc, -- 65 ADC zp
"0000" & "100011" & rmwZp & aluInT & aluRor, -- 66 ROR zp
"1000" & "110011" & rmwZp & aluInT & aluRra, -- 67 iRRA zp
"1000" & "100010" & pop & aluInT & aluInp, -- 68 PLA
"1000" & "110011" & immediate & aluInT & aluAdc, -- 69 ADC imm
"1000" & "100011" & implied & aluInA & aluRor, -- 6A ROR accu
"1000" & "110011" & immediate & aluInAT & aluArr, -- 6B iARR imm
"0000" & "000000" & jumpInd & aluInXXX & aluXXX, -- 6C JMP indirect
"1000" & "110011" & readAbs & aluInT & aluAdc, -- 6D ADC abs
"0000" & "100011" & rmwAbs & aluInT & aluRor, -- 6E ROR abs
"1000" & "110011" & rmwAbs & aluInT & aluRra, -- 6F iRRA abs
"0000" & "000000" & relative & aluInXXX & aluXXX, -- 70 BVS
"1000" & "110011" & readIndY & aluInT & aluAdc, -- 71 ADC (zp),y
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 72 *** JAM ***
"1000" & "110011" & rmwIndY & aluInT & aluRra, -- 73 iRRA (zp),y
"0000" & "000000" & readZpX & aluInXXX & aluXXX, -- 74 iNOP zp,x
"1000" & "110011" & readZpX & aluInT & aluAdc, -- 75 ADC zp,x
"0000" & "100011" & rmwZpX & aluInT & aluRor, -- 76 ROR zp,x
"1000" & "110011" & rmwZpX & aluInT & aluRra, -- 77 iRRA zp,x
"0000" & "000100" & implied & aluInSet & aluXXX, -- 78 SEI
"1000" & "110011" & readAbsY & aluInT & aluAdc, -- 79 ADC abs,y
"0000" & "000000" & implied & aluInXXX & aluXXX, -- 7A iNOP implied
"1000" & "110011" & rmwAbsY & aluInT & aluRra, -- 7B iRRA abs,y
"0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 7C iNOP abs,x
"1000" & "110011" & readAbsX & aluInT & aluAdc, -- 7D ADC abs,x
"0000" & "100011" & rmwAbsX & aluInT & aluRor, -- 7E ROR abs,x
"1000" & "110011" & rmwAbsX & aluInT & aluRra, -- 7F iRRA abs,x
-- AXYS NVDIZC addressing aluInput aluMode
"0000" & "000000" & immediate & aluInXXX & aluXXX, -- 80 iNOP imm
"0000" & "000000" & writeIndX & aluInA & aluInp, -- 81 STA (zp,x)
"0000" & "000000" & immediate & aluInXXX & aluXXX, -- 82 iNOP imm
"0000" & "000000" & writeIndX & aluInAX & aluInp, -- 83 iSAX (zp,x)
"0000" & "000000" & writeZp & aluInY & aluInp, -- 84 STY zp
"0000" & "000000" & writeZp & aluInA & aluInp, -- 85 STA zp
"0000" & "000000" & writeZp & aluInX & aluInp, -- 86 STX zp
"0000" & "000000" & writeZp & aluInAX & aluInp, -- 87 iSAX zp
"0010" & "100010" & implied & aluInY & aluDec, -- 88 DEY
"0000" & "000000" & immediate & aluInXXX & aluXXX, -- 84 iNOP imm
"1000" & "100010" & implied & aluInX & aluInp, -- 8A TXA
"1000" & "100010" & immediate & aluInEXT & aluInp, -- 8B iANE imm
"0000" & "000000" & writeAbs & aluInY & aluInp, -- 8C STY abs
"0000" & "000000" & writeAbs & aluInA & aluInp, -- 8D STA abs
"0000" & "000000" & writeAbs & aluInX & aluInp, -- 8E STX abs
"0000" & "000000" & writeAbs & aluInAX & aluInp, -- 8F iSAX abs
"0000" & "000000" & relative & aluInXXX & aluXXX, -- 90 BCC
"0000" & "000000" & writeIndY & aluInA & aluInp, -- 91 STA (zp),y
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 92 *** JAM ***
"0000" & "000000" & writeIndY & aluInAXH & aluInp, -- 93 iAHX (zp),y
"0000" & "000000" & writeZpX & aluInY & aluInp, -- 94 STY zp,x
"0000" & "000000" & writeZpX & aluInA & aluInp, -- 95 STA zp,x
"0000" & "000000" & writeZpY & aluInX & aluInp, -- 96 STX zp,y
"0000" & "000000" & writeZpY & aluInAX & aluInp, -- 97 iSAX zp,y
"1000" & "100010" & implied & aluInY & aluInp, -- 98 TYA
"0000" & "000000" & writeAbsY & aluInA & aluInp, -- 99 STA abs,y
"0001" & "000000" & implied & aluInX & aluInp, -- 9A TXS
"0001" & "000000" & writeAbsY & aluInAXH & aluInp, -- 9B iSHS abs,y
"0000" & "000000" & writeAbsX & aluInYH & aluInp, -- 9C iSHY abs,x
"0000" & "000000" & writeAbsX & aluInA & aluInp, -- 9D STA abs,x
"0000" & "000000" & writeAbsY & aluInXH & aluInp, -- 9E iSHX abs,y
"0000" & "000000" & writeAbsY & aluInAXH & aluInp, -- 9F iAHX abs,y
-- AXYS NVDIZC addressing aluInput aluMode
"0010" & "100010" & immediate & aluInT & aluInp, -- A0 LDY imm
"1000" & "100010" & readIndX & aluInT & aluInp, -- A1 LDA (zp,x)
"0100" & "100010" & immediate & aluInT & aluInp, -- A2 LDX imm
"1100" & "100010" & readIndX & aluInT & aluInp, -- A3 LAX (zp,x)
"0010" & "100010" & readZp & aluInT & aluInp, -- A4 LDY zp
"1000" & "100010" & readZp & aluInT & aluInp, -- A5 LDA zp
"0100" & "100010" & readZp & aluInT & aluInp, -- A6 LDX zp
"1100" & "100010" & readZp & aluInT & aluInp, -- A7 iLAX zp
"0010" & "100010" & implied & aluInA & aluInp, -- A8 TAY
"1000" & "100010" & immediate & aluInT & aluInp, -- A9 LDA imm
"0100" & "100010" & implied & aluInA & aluInp, -- AA TAX
"1100" & "100010" & immediate & aluInET & aluInp, -- AB iLXA imm
"0010" & "100010" & readAbs & aluInT & aluInp, -- AC LDY abs
"1000" & "100010" & readAbs & aluInT & aluInp, -- AD LDA abs
"0100" & "100010" & readAbs & aluInT & aluInp, -- AE LDX abs
"1100" & "100010" & readAbs & aluInT & aluInp, -- AF iLAX abs
"0000" & "000000" & relative & aluInXXX & aluXXX, -- B0 BCS
"1000" & "100010" & readIndY & aluInT & aluInp, -- B1 LDA (zp),y
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- B2 *** JAM ***
"1100" & "100010" & readIndY & aluInT & aluInp, -- B3 iLAX (zp),y
"0010" & "100010" & readZpX & aluInT & aluInp, -- B4 LDY zp,x
"1000" & "100010" & readZpX & aluInT & aluInp, -- B5 LDA zp,x
"0100" & "100010" & readZpY & aluInT & aluInp, -- B6 LDX zp,y
"1100" & "100010" & readZpY & aluInT & aluInp, -- B7 iLAX zp,y
"0000" & "010000" & implied & aluInClr & aluFlg, -- B8 CLV
"1000" & "100010" & readAbsY & aluInT & aluInp, -- B9 LDA abs,y
"0100" & "100010" & implied & aluInS & aluInp, -- BA TSX
"1101" & "100010" & readAbsY & aluInST & aluInp, -- BB iLAS abs,y
"0010" & "100010" & readAbsX & aluInT & aluInp, -- BC LDY abs,x
"1000" & "100010" & readAbsX & aluInT & aluInp, -- BD LDA abs,x
"0100" & "100010" & readAbsY & aluInT & aluInp, -- BE LDX abs,y
"1100" & "100010" & readAbsY & aluInT & aluInp, -- BF iLAX abs,y
-- AXYS NVDIZC addressing aluInput aluMode
"0000" & "100011" & immediate & aluInT & aluCpy, -- C0 CPY imm
"0000" & "100011" & readIndX & aluInT & aluCmp, -- C1 CMP (zp,x)
"0000" & "000000" & immediate & aluInXXX & aluXXX, -- C2 iNOP imm
"0000" & "100011" & rmwIndX & aluInT & aluDcp, -- C3 iDCP (zp,x)
"0000" & "100011" & readZp & aluInT & aluCpy, -- C4 CPY zp
"0000" & "100011" & readZp & aluInT & aluCmp, -- C5 CMP zp
"0000" & "100010" & rmwZp & aluInT & aluDec, -- C6 DEC zp
"0000" & "100011" & rmwZp & aluInT & aluDcp, -- C7 iDCP zp
"0010" & "100010" & implied & aluInY & aluInc, -- C8 INY
"0000" & "100011" & immediate & aluInT & aluCmp, -- C9 CMP imm
"0100" & "100010" & implied & aluInX & aluDec, -- CA DEX
"0100" & "100011" & immediate & aluInT & aluSbx, -- CB SBX imm
"0000" & "100011" & readAbs & aluInT & aluCpy, -- CC CPY abs
"0000" & "100011" & readAbs & aluInT & aluCmp, -- CD CMP abs
"0000" & "100010" & rmwAbs & aluInT & aluDec, -- CE DEC abs
"0000" & "100011" & rmwAbs & aluInT & aluDcp, -- CF iDCP abs
"0000" & "000000" & relative & aluInXXX & aluXXX, -- D0 BNE
"0000" & "100011" & readIndY & aluInT & aluCmp, -- D1 CMP (zp),y
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- D2 *** JAM ***
"0000" & "100011" & rmwIndY & aluInT & aluDcp, -- D3 iDCP (zp),y
"0000" & "000000" & readZpX & aluInXXX & aluXXX, -- D4 iNOP zp,x
"0000" & "100011" & readZpX & aluInT & aluCmp, -- D5 CMP zp,x
"0000" & "100010" & rmwZpX & aluInT & aluDec, -- D6 DEC zp,x
"0000" & "100011" & rmwZpX & aluInT & aluDcp, -- D7 iDCP zp,x
"0000" & "001000" & implied & aluInClr & aluXXX, -- D8 CLD
"0000" & "100011" & readAbsY & aluInT & aluCmp, -- D9 CMP abs,y
"0000" & "000000" & implied & aluInXXX & aluXXX, -- DA iNOP implied
"0000" & "100011" & rmwAbsY & aluInT & aluDcp, -- DB iDCP abs,y
"0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- DC iNOP abs,x
"0000" & "100011" & readAbsX & aluInT & aluCmp, -- DD CMP abs,x
"0000" & "100010" & rmwAbsX & aluInT & aluDec, -- DE DEC abs,x
"0000" & "100011" & rmwAbsX & aluInT & aluDcp, -- DF iDCP abs,x
-- AXYS NVDIZC addressing aluInput aluMode
"0000" & "100011" & immediate & aluInT & aluCpx, -- E0 CPX imm
"1000" & "110011" & readIndX & aluInT & aluSbc, -- E1 SBC (zp,x)
"0000" & "000000" & immediate & aluInXXX & aluXXX, -- E2 iNOP imm
"1000" & "110011" & rmwIndX & aluInT & aluIsc, -- E3 iISC (zp,x)
"0000" & "100011" & readZp & aluInT & aluCpx, -- E4 CPX zp
"1000" & "110011" & readZp & aluInT & aluSbc, -- E5 SBC zp
"0000" & "100010" & rmwZp & aluInT & aluInc, -- E6 INC zp
"1000" & "110011" & rmwZp & aluInT & aluIsc, -- E7 iISC zp
"0100" & "100010" & implied & aluInX & aluInc, -- E8 INX
"1000" & "110011" & immediate & aluInT & aluSbc, -- E9 SBC imm
"0000" & "000000" & implied & aluInXXX & aluXXX, -- EA NOP
"1000" & "110011" & immediate & aluInT & aluSbc, -- EB SBC imm (illegal opc)
"0000" & "100011" & readAbs & aluInT & aluCpx, -- EC CPX abs
"1000" & "110011" & readAbs & aluInT & aluSbc, -- ED SBC abs
"0000" & "100010" & rmwAbs & aluInT & aluInc, -- EE INC abs
"1000" & "110011" & rmwAbs & aluInT & aluIsc, -- EF iISC abs
"0000" & "000000" & relative & aluInXXX & aluXXX, -- F0 BEQ
"1000" & "110011" & readIndY & aluInT & aluSbc, -- F1 SBC (zp),y
"----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- F2 *** JAM ***
"1000" & "110011" & rmwIndY & aluInT & aluIsc, -- F3 iISC (zp),y
"0000" & "000000" & readZpX & aluInXXX & aluXXX, -- F4 iNOP zp,x
"1000" & "110011" & readZpX & aluInT & aluSbc, -- F5 SBC zp,x
"0000" & "100010" & rmwZpX & aluInT & aluInc, -- F6 INC zp,x
"1000" & "110011" & rmwZpX & aluInT & aluIsc, -- F7 iISC zp,x
"0000" & "001000" & implied & aluInSet & aluXXX, -- F8 SED
"1000" & "110011" & readAbsY & aluInT & aluSbc, -- F9 SBC abs,y
"0000" & "000000" & implied & aluInXXX & aluXXX, -- FA iNOP implied
"1000" & "110011" & rmwAbsY & aluInT & aluIsc, -- FB iISC abs,y
"0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- FC iNOP abs,x
"1000" & "110011" & readAbsX & aluInT & aluSbc, -- FD SBC abs,x
"0000" & "100010" & rmwAbsX & aluInT & aluInc, -- FE INC abs,x
"1000" & "110011" & rmwAbsX & aluInT & aluIsc -- FF iISC abs,x
);
signal opcInfo : decodedBitsDef;
signal nextOpcInfo : decodedBitsDef; -- Next opcode (decoded)
signal nextOpcInfoReg : decodedBitsDef; -- Next opcode (decoded) pipelined
signal theOpcode : unsigned(7 downto 0);
signal nextOpcode : unsigned(7 downto 0);
-- Program counter
signal PC : unsigned(15 downto 0); -- Program counter
-- Address generation
type nextAddrDef is (
nextAddrHold,
nextAddrIncr,
nextAddrIncrL, -- Increment low bits only (zeropage accesses)
nextAddrIncrH, -- Increment high bits only (page-boundary)
nextAddrDecrH, -- Decrement high bits (branch backwards)
nextAddrPc,
nextAddrIrq,
nextAddrReset,
nextAddrAbs,
nextAddrAbsIndexed,
nextAddrZeroPage,
nextAddrZPIndexed,
nextAddrStack,
nextAddrRelative
);
signal nextAddr : nextAddrDef;
signal myAddr : unsigned(15 downto 0);
signal myAddrIncr : unsigned(15 downto 0);
signal myAddrIncrH : unsigned(7 downto 0);
signal myAddrDecrH : unsigned(7 downto 0);
signal theWe : std_logic;
signal irqActive : std_logic;
-- Output register
signal doReg : unsigned(7 downto 0);
-- Buffer register
signal T : unsigned(7 downto 0);
-- General registers
signal A: unsigned(7 downto 0); -- Accumulator
signal X: unsigned(7 downto 0); -- Index X
signal Y: unsigned(7 downto 0); -- Index Y
signal S: unsigned(7 downto 0); -- stack pointer
-- Status register
signal C: std_logic; -- Carry
signal Z: std_logic; -- Zero flag
signal I: std_logic; -- Interrupt flag
signal D: std_logic; -- Decimal mode
signal V: std_logic; -- Overflow
signal N: std_logic; -- Negative
-- ALU
-- ALU input
signal aluInput : unsigned(7 downto 0);
signal aluCmpInput : unsigned(7 downto 0);
-- ALU output
signal aluRegisterOut : unsigned(7 downto 0);
signal aluRmwOut : unsigned(7 downto 0);
signal aluC : std_logic;
signal aluZ : std_logic;
signal aluV : std_logic;
signal aluN : std_logic;
-- Pipeline registers
signal aluInputReg : unsigned(7 downto 0);
signal aluCmpInputReg : unsigned(7 downto 0);
signal aluRmwReg : unsigned(7 downto 0);
signal aluNineReg : unsigned(7 downto 0);
signal aluCReg : std_logic;
signal aluZReg : std_logic;
signal aluVReg : std_logic;
signal aluNReg : std_logic;
-- Indexing
signal indexOut : unsigned(8 downto 0);
begin
processAluInput: process(clk, opcInfo, A, X, Y, T, S)
variable temp : unsigned(7 downto 0);
begin
temp := (others => '1');
if opcInfo(opcInA) = '1' then
temp := temp and A;
end if;
if opcInfo(opcInE) = '1' then
temp := temp and (A or X"EE");
end if;
if opcInfo(opcInX) = '1' then
temp := temp and X;
end if;
if opcInfo(opcInY) = '1' then
temp := temp and Y;
end if;
if opcInfo(opcInS) = '1' then
temp := temp and S;
end if;
if opcInfo(opcInT) = '1' then
temp := temp and T;
end if;
if opcInfo(opcInClear) = '1' then
temp := (others => '0');
end if;
if rising_edge(clk) then
aluInputReg <= temp;
end if;
aluInput <= temp;
if pipelineAluMux then
aluInput <= aluInputReg;
end if;
end process;
processCmpInput: process(clk, opcInfo, A, X, Y)
variable temp : unsigned(7 downto 0);
begin
temp := (others => '1');
if opcInfo(opcInCmp) = '1' then
temp := temp and A;
end if;
if opcInfo(opcInCpx) = '1' then
temp := temp and X;
end if;
if opcInfo(opcInCpy) = '1' then
temp := temp and Y;
end if;
if rising_edge(clk) then
aluCmpInputReg <= temp;
end if;
aluCmpInput <= temp;
if pipelineAluMux then
aluCmpInput <= aluCmpInputReg;
end if;
end process;
-- ALU consists of two parts
-- Read-Modify-Write or index instructions: INC/DEC/ASL/LSR/ROR/ROL
-- Accumulator instructions: ADC, SBC, EOR, AND, EOR, ORA
-- Some instructions are both RMW and accumulator so for most
-- instructions the rmw results are routed through accu alu too.
processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V, D, I, Z, C)
variable lowBits: unsigned(5 downto 0);
variable nineBits: unsigned(8 downto 0);
variable rmwBits: unsigned(8 downto 0);
variable varC : std_logic;
variable varZ : std_logic;
variable varV : std_logic;
variable varN : std_logic;
begin
lowBits := (others => '-');
nineBits := (others => '-');
rmwBits := (others => '-');
varV := aluInput(6); -- Default for BIT / PLP / RTI
-- Shift unit
case opcInfo(aluMode1From to aluMode1To) is
when aluModeInp =>
rmwBits := C & aluInput;
when aluModeP =>
rmwBits := C & N & V & '1' & (not irqActive) & D & I & Z & C;
when aluModeInc =>
rmwBits := C & (aluInput + 1);
when aluModeDec =>
rmwBits := C & (aluInput - 1);
when aluModeAsl =>
rmwBits := aluInput & "0";
when aluModeFlg =>
rmwBits := aluInput(0) & aluInput;
when aluModeLsr =>
rmwBits := aluInput(0) & "0" & aluInput(7 downto 1);
when aluModeRol =>
rmwBits := aluInput & C;
when aluModeRoR =>
rmwBits := aluInput(0) & C & aluInput(7 downto 1);
when aluModeAnc =>
rmwBits := (aluInput(7) and A(7)) & aluInput;
when others =>
rmwBits := C & aluInput;
end case;
-- ALU
case opcInfo(aluMode2From to aluMode2To) is
when aluModeAdc =>
lowBits := ("0" & A(3 downto 0) & rmwBits(8)) + ("0" & rmwBits(3 downto 0) & "1");
ninebits := ("0" & A) + ("0" & rmwBits(7 downto 0)) + (B"00000000" & rmwBits(8));
when aluModeSbc =>
lowBits := ("0" & A(3 downto 0) & rmwBits(8)) + ("0" & (not rmwBits(3 downto 0)) & "1");
ninebits := ("0" & A) + ("0" & (not rmwBits(7 downto 0))) + (B"00000000" & rmwBits(8));
when aluModeCmp =>
ninebits := ("0" & aluCmpInput) + ("0" & (not rmwBits(7 downto 0))) + "000000001";
when aluModeAnd =>
ninebits := rmwBits(8) & (A and rmwBits(7 downto 0));
when aluModeEor =>
ninebits := rmwBits(8) & (A xor rmwBits(7 downto 0));
when aluModeOra =>
ninebits := rmwBits(8) & (A or rmwBits(7 downto 0));
when others =>
ninebits := rmwBits;
end case;
if (opcInfo(aluMode1From to aluMode1To) = aluModeFlg) then
varZ := rmwBits(1);
elsif ninebits(7 downto 0) = X"00" then
varZ := '1';
else
varZ := '0';
end if;
case opcInfo(aluMode2From to aluMode2To) is
when aluModeAdc =>
-- decimal mode low bits correction, is done after setting Z flag.
if D = '1' then
if lowBits(5 downto 1) > 9 then
ninebits(3 downto 0) := ninebits(3 downto 0) + 6;
if lowBits(5) = '0' then
ninebits(8 downto 4) := ninebits(8 downto 4) + 1;
end if;
end if;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -