⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu65xx_fast.vhd

📁 FPGA64的VHDL源代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
-- -----------------------------------------------------------------------
--
--                                 FPGA 64
--
--     A fully functional commodore 64 implementation in a single FPGA
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/fpga64.html
-- -----------------------------------------------------------------------
--
-- Table driven, cycle exact 6502/6510 core
--
-- -----------------------------------------------------------------------

library IEEE;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.ALL;

-- -----------------------------------------------------------------------

-- Store Zp    (3) => fetch, cycle2, cycleEnd
-- Store Zp,x  (4) => fetch, cycle2, preWrite, cycleEnd
-- Read  Zp,x  (4) => fetch, cycle2, cycleRead, cycleRead2
-- Rmw   Zp,x  (6) => fetch, cycle2, cycleRead, cycleRead2, cycleRmw, cycleEnd
-- Store Abs   (4) => fetch, cycle2, cycle3, cycleEnd
-- Store Abs,x (5) => fetch, cycle2, cycle3, preWrite, cycleEnd
-- Rts         (6) => fetch, cycle2, cycle3, cycleRead, cycleJump, cycleIncrEnd
-- Rti         (6) => fetch, cycle2, stack1, stack2, stack3, cycleJump
-- Jsr         (6) => fetch, cycle2, .. cycle5, cycle6, cycleJump
-- Jmp abs     (-) => fetch, cycle2, .., cycleJump
-- Jmp (ind)   (-) => fetch, cycle2, .., cycleJump
-- Brk / irq   (6) => fetch, cycle2, stack2, stack3, stack4
-- -----------------------------------------------------------------------

architecture fast of cpu65xx is
-- Statemachine
	type cpuCycles is (
		opcodeFetch,  -- New opcode is read and registers updated
		cycle2,
		cycle3,
		cyclePreIndirect,
		cycleIndirect,
		cycleBranchTaken,
		cycleBranchPage,
		cyclePreRead,     -- Cycle before read while doing zeropage indexed addressing.
		cycleRead,        -- Read cycle
		cycleRead2,       -- Second read cycle after page-boundary crossing.
		cycleRmw,         -- Calculate ALU output for read-modify-write instr.		
		cyclePreWrite,    -- Cycle before write when doing indexed addressing.
		cycleWrite,       -- Write cycle for zeropage or absolute addressing.
		cycleStack1,
		cycleStack2,
		cycleStack3,
		cycleStack4,
		cycleJump,	      -- Last cycle of Jsr, Jmp. Next fetch address is target addr.
		cycleEnd
	);
	signal theCpuCycle : cpuCycles;
	signal nextCpuCycle : cpuCycles;
	signal updateRegisters : boolean;
	signal processIrq : std_logic;
	signal nmiReg: std_logic;
	signal nmiEdge: std_logic;
	signal irqReg : std_logic; -- Delay IRQ input with one clock cycle.
	signal soReg : std_logic; -- SO pin edge detection

-- Opcode decoding
	constant opcUpdateA    : integer := 0;
	constant opcUpdateX    : integer := 1;
	constant opcUpdateY    : integer := 2;
	constant opcUpdateS    : integer := 3;
	constant opcUpdateN    : integer := 4;
	constant opcUpdateV    : integer := 5;
	constant opcUpdateD    : integer := 6;
	constant opcUpdateI    : integer := 7;
	constant opcUpdateZ    : integer := 8;
	constant opcUpdateC    : integer := 9;

	constant opcSecondByte : integer := 10;
	constant opcAbsolute   : integer := 11;
	constant opcZeroPage   : integer := 12;
	constant opcIndirect   : integer := 13;
	constant opcStackAddr  : integer := 14; -- Push/Pop address
	constant opcStackData  : integer := 15; -- Push/Pop status/data
	constant opcJump       : integer := 16;
	constant opcBranch     : integer := 17;
	constant indexX        : integer := 18;
	constant indexY        : integer := 19;
	constant opcStackUp    : integer := 20;
	constant opcWrite      : integer := 21;
	constant opcRmw        : integer := 22;
	constant opcIncrAfter  : integer := 23; -- Insert extra cycle to increment PC (RTS)
	constant opcRti        : integer := 24;
	constant opcIRQ        : integer := 25;

	constant opcInA        : integer := 26;
	constant opcInE        : integer := 27;
	constant opcInX        : integer := 28;
	constant opcInY        : integer := 29;
	constant opcInS        : integer := 30;
	constant opcInT        : integer := 31;
	constant opcInH        : integer := 32;
	constant opcInClear    : integer := 33;
	constant aluMode1From  : integer := 34;
	--
	constant aluMode1To    : integer := 37;
	constant aluMode2From  : integer := 38;
	--
	constant aluMode2To    : integer := 40;
	--
	constant opcInCmp      : integer := 41;
	constant opcInCpx      : integer := 42;
	constant opcInCpy      : integer := 43;
	

	subtype addrDef is unsigned(0 to 15);
	--
	--               is Interrupt  -----------------+
	--          instruction is RTI ----------------+|
	--    PC++ on last cycle (RTS) ---------------+||
	--                      RMW    --------------+|||
	--                     Write   -------------+||||
	--               Pop/Stack up -------------+|||||
	--                    Branch   ---------+  ||||||
	--                      Jump ----------+|  ||||||
	--            Push or Pop data -------+||  ||||||
	--            Push or Pop addr ------+|||  ||||||
	--                   Indirect  -----+||||  ||||||
	--                    ZeroPage ----+|||||  ||||||
	--                    Absolute ---+||||||  ||||||
	--              PC++ on cycle2 --+|||||||  ||||||
	--                               |AZI||JBXY|WM|||
	constant immediate : addrDef := "1000000000000000";
	constant implied   : addrDef := "0000000000000000";
	-- Zero page
	constant readZp    : addrDef := "1010000000000000";
	constant writeZp   : addrDef := "1010000000010000";
	constant rmwZp     : addrDef := "1010000000001000";
	-- Zero page indexed
	constant readZpX   : addrDef := "1010000010000000";
	constant writeZpX  : addrDef := "1010000010010000";
	constant rmwZpX    : addrDef := "1010000010001000";
	constant readZpY   : addrDef := "1010000001000000";
	constant writeZpY  : addrDef := "1010000001010000";
	constant rmwZpY    : addrDef := "1010000001001000";
	-- Zero page indirect
	constant readIndX  : addrDef := "1001000010000000";
	constant writeIndX : addrDef := "1001000010010000";
	constant rmwIndX   : addrDef := "1001000010001000";
	constant readIndY  : addrDef := "1001000001000000";
	constant writeIndY : addrDef := "1001000001010000";
	constant rmwIndY   : addrDef := "1001000001001000";
	--                               |AZI||JBXY|WM||
	-- Absolute
	constant readAbs   : addrDef := "1100000000000000";	
	constant writeAbs  : addrDef := "1100000000010000";	
	constant rmwAbs    : addrDef := "1100000000001000";	
	constant readAbsX  : addrDef := "1100000010000000";	
	constant writeAbsX : addrDef := "1100000010010000";	
	constant rmwAbsX   : addrDef := "1100000010001000";	
	constant readAbsY  : addrDef := "1100000001000000";	
	constant writeAbsY : addrDef := "1100000001010000";	
	constant rmwAbsY   : addrDef := "1100000001001000";	
	-- PHA PHP
	constant push      : addrDef := "0000010000000000";
	-- PLA PLP
	constant pop       : addrDef := "0000010000100000";
	-- Jumps
	constant jsr       : addrDef := "1000101000000000";
	constant jumpAbs   : addrDef := "1000001000000000";
	constant jumpInd   : addrDef := "1100001000000000";
	constant relative  : addrDef := "1000000100000000";
	-- Specials
	constant rts       : addrDef := "0000101000100100";
	constant rti       : addrDef := "0000111000100010";
	constant brk       : addrDef := "1000111000000001";
--	constant        : unsigned(0 to 0) := "0";
	constant xxxxxxxx  : addrDef := "----------0---00";
	
	-- A = accu
	-- E = Accu | 0xEE (for ANE, LXA)
	-- X = index X
	-- Y = index Y
	-- S = Stack pointer
	-- H = indexH
	-- 
	--                                       AEXYSTHc
	constant aluInA   : unsigned(0 to 7) := "10000000";
	constant aluInE   : unsigned(0 to 7) := "01000000";
	constant aluInEXT : unsigned(0 to 7) := "01100100";
	constant aluInET  : unsigned(0 to 7) := "01000100";
	constant aluInX   : unsigned(0 to 7) := "00100000";
	constant aluInXH  : unsigned(0 to 7) := "00100010";
	constant aluInY   : unsigned(0 to 7) := "00010000";
	constant aluInYH  : unsigned(0 to 7) := "00010010";
	constant aluInS   : unsigned(0 to 7) := "00001000";
	constant aluInT   : unsigned(0 to 7) := "00000100";
	constant aluInAX  : unsigned(0 to 7) := "10100000";
	constant aluInAXH : unsigned(0 to 7) := "10100010";
	constant aluInAT  : unsigned(0 to 7) := "10000100";
	constant aluInXT  : unsigned(0 to 7) := "00100100";
	constant aluInST  : unsigned(0 to 7) := "00001100";
	constant aluInSet : unsigned(0 to 7) := "00000000";
	constant aluInClr : unsigned(0 to 7) := "00000001";
	constant aluInXXX : unsigned(0 to 7) := "--------";
	
	-- Most of the aluModes are just like the opcodes.
	-- aluModeInp -> input is output. calculate N and Z
	-- aluModeCmp -> Compare for CMP, CPX, CPY
	-- aluModeFlg -> input to flags needed for PLP, RTI and CLC, SEC, CLV
	-- aluModeInc -> for INC but also INX, INY
	-- aluModeDec -> for DEC but also DEX, DEY

	subtype aluMode1 is unsigned(0 to 3);
	subtype aluMode2 is unsigned(0 to 2);
	subtype aluMode is unsigned(0 to 9);

	-- Logic/Shift ALU
	constant aluModeInp : aluMode1 := "0000";
	constant aluModeP   : aluMode1 := "0001";
	constant aluModeInc : aluMode1 := "0010";
	constant aluModeDec : aluMode1 := "0011";
	constant aluModeFlg : aluMode1 := "0100";
	constant aluModeBit : aluMode1 := "0101";
	-- 0110
	-- 0111
	constant aluModeLsr : aluMode1 := "1000";
	constant aluModeRor : aluMode1 := "1001";
	constant aluModeAsl : aluMode1 := "1010";
	constant aluModeRol : aluMode1 := "1011";
	-- 1100
	-- 1101
	-- 1110
	constant aluModeAnc : aluMode1 := "1111";

	-- Arithmetic ALU
	constant aluModePss : aluMode2 := "000";
	constant aluModeCmp : aluMode2 := "001";
	constant aluModeAdc : aluMode2 := "010";
	constant aluModeSbc : aluMode2 := "011";
	constant aluModeAnd : aluMode2 := "100";
	constant aluModeOra : aluMode2 := "101";
	constant aluModeEor : aluMode2 := "110";
	constant aluModeArr : aluMode2 := "111";


	constant aluInp  : aluMode := aluModeInp & aluModePss & "---";
	constant aluP    : aluMode := aluModeP   & aluModePss & "---";
	constant aluInc  : aluMode := aluModeInc & aluModePss & "---";
	constant aluDec  : aluMode := aluModeDec & aluModePss & "---";
	constant aluFlg  : aluMode := aluModeFlg & aluModePss & "---";
	constant aluBit  : aluMode := aluModeBit & aluModeAnd & "---";
	constant aluRor  : aluMode := aluModeRor & aluModePss & "---";
	constant aluLsr  : aluMode := aluModeLsr & aluModePss & "---";
	constant aluRol  : aluMode := aluModeRol & aluModePss & "---";
	constant aluAsl  : aluMode := aluModeAsl & aluModePss & "---";

	constant aluCmp  : aluMode := aluModeInp & aluModeCmp & "100";
	constant aluCpx  : aluMode := aluModeInp & aluModeCmp & "010";
	constant aluCpy  : aluMode := aluModeInp & aluModeCmp & "001";
	constant aluAdc  : aluMode := aluModeInp & aluModeAdc & "---";
	constant aluSbc  : aluMode := aluModeInp & aluModeSbc & "---";
	constant aluAnd  : aluMode := aluModeInp & aluModeAnd & "---";
	constant aluOra  : aluMode := aluModeInp & aluModeOra & "---";
	constant aluEor  : aluMode := aluModeInp & aluModeEor & "---";
	
	constant aluSlo  : aluMode := aluModeAsl & aluModeOra & "---";
	constant aluSre  : aluMode := aluModeLsr & aluModeEor & "---";
	constant aluRra  : aluMode := aluModeRor & aluModeAdc & "---";
	constant aluRla  : aluMode := aluModeRol & aluModeAnd & "---";
	constant aluDcp  : aluMode := aluModeDec & aluModeCmp & "100";
	constant aluIsc  : aluMode := aluModeInc & aluModeSbc & "---";
	constant aluAnc  : aluMode := aluModeAnc & aluModeAnd & "---";
	constant aluArr  : aluMode := aluModeRor & aluModeArr & "---";
	constant aluSbx  : aluMode := aluModeInp & aluModeCmp & "110";
	
	constant aluXXX  : aluMode := (others => '-');


	-- Stack operations. Push/Pop/None
	constant stackInc : unsigned(0 to 0) := "0";
	constant stackDec : unsigned(0 to 0) := "1";
	constant stackXXX : unsigned(0 to 0) := "-";

	subtype decodedBitsDef is unsigned(0 to 43);
	type opcodeInfoTableDef is array(0 to 255) of decodedBitsDef;
	constant opcodeInfoTable : opcodeInfoTableDef := (
	-- +------- Update register A
	-- |+------ Update register X
	-- ||+----- Update register Y
	-- |||+---- Update register S
	-- ||||       +-- Update Flags
	-- ||||       |   
	-- ||||      _|__ 
	-- ||||     /    \
	-- AXYS     NVDIZC    addressing  aluInput  aluMode
	  "0000" & "000100" & brk       & aluInXXX & aluP,   -- 00 BRK
	  "1000" & "100010" & readIndX  & aluInT   & aluOra, -- 01 ORA (zp,x)
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 02 *** JAM ***
	  "1000" & "100011" & rmwIndX   & aluInT   & aluSlo, -- 03 iSLO (zp,x)
	  "0000" & "000000" & readZp    & aluInXXX & aluXXX, -- 04 iNOP zp
	  "1000" & "100010" & readZp    & aluInT   & aluOra, -- 05 ORA zp
	  "0000" & "100011" & rmwZp     & aluInT   & aluAsl, -- 06 ASL zp
	  "1000" & "100011" & rmwZp     & aluInT   & aluSlo, -- 07 iSLO zp
	  "0000" & "000000" & push      & aluInXXX & aluP,   -- 08 PHP
	  "1000" & "100010" & immediate & aluInT   & aluOra, -- 09 ORA imm
	  "1000" & "100011" & implied   & aluInA   & aluAsl, -- 0A ASL accu
	  "1000" & "100011" & immediate & aluInT   & aluAnc, -- 0B iANC imm
	  "0000" & "000000" & readAbs   & aluInXXX & aluXXX, -- 0C iNOP abs
	  "1000" & "100010" & readAbs   & aluInT   & aluOra, -- 0D ORA abs
	  "0000" & "100011" & rmwAbs    & aluInT   & aluAsl, -- 0E ASL abs
	  "1000" & "100011" & rmwAbs    & aluInT   & aluSlo, -- 0F iSLO abs
	  "0000" & "000000" & relative  & aluInXXX & aluXXX, -- 10 BPL
	  "1000" & "100010" & readIndY  & aluInT   & aluOra, -- 11 ORA (zp),y
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 12 *** JAM ***
	  "1000" & "100011" & rmwIndY   & aluInT   & aluSlo, -- 13 iSLO (zp),y
	  "0000" & "000000" & readZpX   & aluInXXX & aluXXX, -- 14 iNOP zp,x
	  "1000" & "100010" & readZpX   & aluInT   & aluOra, -- 15 ORA zp,x
	  "0000" & "100011" & rmwZpX    & aluInT   & aluAsl, -- 16 ASL zp,x
	  "1000" & "100011" & rmwZpX    & aluInT   & aluSlo, -- 17 iSLO zp,x
	  "0000" & "000001" & implied   & aluInClr & aluFlg, -- 18 CLC
	  "1000" & "100010" & readAbsY  & aluInT   & aluOra, -- 19 ORA abs,y
	  "0000" & "000000" & implied   & aluInXXX & aluXXX, -- 1A iNOP implied
	  "1000" & "100011" & rmwAbsY   & aluInT   & aluSlo, -- 1B iSLO abs,y
	  "0000" & "000000" & readAbsX  & aluInXXX & aluXXX, -- 1C iNOP abs,x
	  "1000" & "100010" & readAbsX  & aluInT   & aluOra, -- 1D ORA abs,x
	  "0000" & "100011" & rmwAbsX   & aluInT   & aluAsl, -- 1E ASL abs,x
	  "1000" & "100011" & rmwAbsX   & aluInT   & aluSlo, -- 1F iSLO abs,x
	-- AXYS     NVDIZC    addressing  aluInput  aluMode
	  "0000" & "000000" & jsr       & aluInXXX & aluXXX, -- 20 JSR
	  "1000" & "100010" & readIndX  & aluInT   & aluAnd, -- 21 AND (zp,x)
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 22 *** JAM ***
	  "1000" & "100011" & rmwIndX   & aluInT   & aluRla, -- 23 iRLA (zp,x)
	  "0000" & "110010" & readZp    & aluInT   & aluBit, -- 24 BIT zp
	  "1000" & "100010" & readZp    & aluInT   & aluAnd, -- 25 AND zp
	  "0000" & "100011" & rmwZp     & aluInT   & aluRol, -- 26 ROL zp
	  "1000" & "100011" & rmwZp     & aluInT   & aluRla, -- 27 iRLA zp
	  "0000" & "111111" & pop       & aluInT   & aluFlg, -- 28 PLP
	  "1000" & "100010" & immediate & aluInT   & aluAnd, -- 29 AND imm
	  "1000" & "100011" & implied   & aluInA   & aluRol, -- 2A ROL accu
	  "1000" & "100011" & immediate & aluInT   & aluAnc, -- 2B iANC imm
	  "0000" & "110010" & readAbs   & aluInT   & aluBit, -- 2C BIT abs
	  "1000" & "100010" & readAbs   & aluInT   & aluAnd, -- 2D AND abs
	  "0000" & "100011" & rmwAbs    & aluInT   & aluRol, -- 2E ROL abs
	  "1000" & "100011" & rmwAbs    & aluInT   & aluRla, -- 2F iRLA abs
	  "0000" & "000000" & relative  & aluInXXX & aluXXX, -- 30 BMI
	  "1000" & "100010" & readIndY  & aluInT   & aluAnd, -- 31 AND (zp),y
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 32 *** JAM ***
	  "1000" & "100011" & rmwIndY   & aluInT   & aluRla, -- 33 iRLA (zp),y
	  "0000" & "000000" & readZpX   & aluInXXX & aluXXX, -- 34 iNOP zp,x
	  "1000" & "100010" & readZpX   & aluInT   & aluAnd, -- 35 AND zp,x
	  "0000" & "100011" & rmwZpX    & aluInT   & aluRol, -- 36 ROL zp,x
	  "1000" & "100011" & rmwZpX    & aluInT   & aluRla, -- 37 iRLA zp,x
	  "0000" & "000001" & implied   & aluInSet & aluFlg, -- 38 SEC
	  "1000" & "100010" & readAbsY  & aluInT   & aluAnd, -- 39 AND abs,y
	  "0000" & "000000" & implied   & aluInXXX & aluXXX, -- 3A iNOP implied
	  "1000" & "100011" & rmwAbsY   & aluInT   & aluRla, -- 3B iRLA abs,y
	  "0000" & "000000" & readAbsX  & aluInXXX & aluXXX, -- 3C iNOP abs,x
	  "1000" & "100010" & readAbsX  & aluInT   & aluAnd, -- 3D AND abs,x
	  "0000" & "100011" & rmwAbsX   & aluInT   & aluRol, -- 3E ROL abs,x
	  "1000" & "100011" & rmwAbsX   & aluInT   & aluRla, -- 3F iRLA abs,x
	-- AXYS     NVDIZC    addressing  aluInput  aluMode
	  "0000" & "111111" & rti       & aluInT   & aluFlg, -- 40 RTI
	  "1000" & "100010" & readIndX  & aluInT   & aluEor, -- 41 EOR (zp,x)
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 42 *** JAM ***
	  "1000" & "100011" & rmwIndX   & aluInT   & aluSre, -- 43 iSRE (zp,x)
	  "0000" & "000000" & readZp    & aluInXXX & aluXXX, -- 44 iNOP zp
	  "1000" & "100010" & readZp    & aluInT   & aluEor, -- 45 EOR zp
	  "0000" & "100011" & rmwZp     & aluInT   & aluLsr, -- 46 LSR zp
	  "1000" & "100011" & rmwZp     & aluInT   & aluSre, -- 47 iSRE zp
	  "0000" & "000000" & push      & aluInA   & aluInp, -- 48 PHA
	  "1000" & "100010" & immediate & aluInT   & aluEor, -- 49 EOR imm
	  "1000" & "100011" & implied   & aluInA   & aluLsr, -- 4A LSR accu
	  "1000" & "100011" & immediate & aluInAT  & aluLsr, -- 4B iALR imm
	  "0000" & "000000" & jumpAbs   & aluInXXX & aluXXX, -- 4C JMP abs
	  "1000" & "100010" & readAbs   & aluInT   & aluEor, -- 4D EOR abs
	  "0000" & "100011" & rmwAbs    & aluInT   & aluLsr, -- 4E LSR abs
	  "1000" & "100011" & rmwAbs    & aluInT   & aluSre, -- 4F iSRE abs
	  "0000" & "000000" & relative  & aluInXXX & aluXXX, -- 50 BVC
	  "1000" & "100010" & readIndY  & aluInT   & aluEor, -- 51 EOR (zp),y
	  "----" & "------" & xxxxxxxx  & aluInXXX & aluXXX, -- 52 *** JAM ***
	  "1000" & "100011" & rmwIndY   & aluInT   & aluSre, -- 53 iSRE (zp),y
	  "0000" & "000000" & readZpX   & aluInXXX & aluXXX, -- 54 iNOP zp,x
	  "1000" & "100010" & readZpX   & aluInT   & aluEor, -- 55 EOR zp,x
	  "0000" & "100011" & rmwZpX    & aluInT   & aluLsr, -- 56 LSR zp,x
	  "1000" & "100011" & rmwZpX    & aluInT   & aluSre, -- 57 SRE zp,x
	  "0000" & "000100" & implied   & aluInClr & aluXXX, -- 58 CLI
	  "1000" & "100010" & readAbsY  & aluInT   & aluEor, -- 59 EOR abs,y
	  "0000" & "000000" & implied   & aluInXXX & aluXXX, -- 5A iNOP implied
	  "1000" & "100011" & rmwAbsY   & aluInT   & aluSre, -- 5B iSRE abs,y

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -