From 10f96bb44dd6f3da270cceefb20a46e7dc3e8c7c Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Thu, 6 Sep 2018 02:41:13 +0200 Subject: [PATCH] C64: use only the T65 CPU --- cores/c64/rtl/cpu65xx_e.vhd | 49 - cores/c64/rtl/cpu65xx_fast.vhd | 1565 ------------------------------ cores/c64/rtl/cpu_6510.vhd | 126 +-- cores/c64/rtl/fpga64_sid_iec.vhd | 15 +- cores/c64/rtl/t65/T65.vhd | 5 +- 5 files changed, 50 insertions(+), 1710 deletions(-) delete mode 100644 cores/c64/rtl/cpu65xx_e.vhd delete mode 100644 cores/c64/rtl/cpu65xx_fast.vhd diff --git a/cores/c64/rtl/cpu65xx_e.vhd b/cores/c64/rtl/cpu65xx_e.vhd deleted file mode 100644 index 27166e7..0000000 --- a/cores/c64/rtl/cpu65xx_e.vhd +++ /dev/null @@ -1,49 +0,0 @@ --- ----------------------------------------------------------------------- --- --- 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 --- ----------------------------------------------------------------------- --- --- Interface to 6502/6510 core --- --- ----------------------------------------------------------------------- - -library IEEE; -use ieee.std_logic_1164.ALL; -use ieee.numeric_std.ALL; - --- ----------------------------------------------------------------------- - -entity cpu65xx is - generic ( - pipelineOpcode : boolean; - pipelineAluMux : boolean; - pipelineAluOut : boolean - ); - port ( - clk : in std_logic; - enable : in std_logic; - reset : in std_logic; - nmi_n : in std_logic; - nmi_ack : out std_logic; - irq_n : in std_logic; - so_n : in std_logic := '1'; - - di : in unsigned(7 downto 0); - do : out unsigned(7 downto 0); - addr : out unsigned(15 downto 0); - we : out std_logic; - - debugOpcode : out unsigned(7 downto 0); - debugPc : out unsigned(15 downto 0); - debugA : out unsigned(7 downto 0); - debugX : out unsigned(7 downto 0); - debugY : out unsigned(7 downto 0); - debugS : out unsigned(7 downto 0) - ); -end cpu65xx; \ No newline at end of file diff --git a/cores/c64/rtl/cpu65xx_fast.vhd b/cores/c64/rtl/cpu65xx_fast.vhd deleted file mode 100644 index a387b37..0000000 --- a/cores/c64/rtl/cpu65xx_fast.vhd +++ /dev/null @@ -1,1565 +0,0 @@ --- ----------------------------------------------------------------------- --- --- 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 - "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; - end if; - when others => - null; - end case; - - if (opcInfo(aluMode1From to aluMode1To) = aluModeBit) - or (opcInfo(aluMode1From to aluMode1To) = aluModeFlg) then - varN := rmwBits(7); - else - varN := nineBits(7); - end if; - varC := ninebits(8); - if opcInfo(aluMode2From to aluMode2To) = aluModeArr then - varC := aluInput(7); - varV := aluInput(7) xor aluInput(6); - end if; - - case opcInfo(aluMode2From to aluMode2To) is - when aluModeAdc => - -- decimal mode high bits correction, is done after setting Z and N flags - varV := (A(7) xor ninebits(7)) and (rmwBits(7) xor ninebits(7)); - if D = '1' then - if ninebits(8 downto 4) > 9 then - ninebits(8 downto 4) := ninebits(8 downto 4) + 6; - varC := '1'; - end if; - end if; - when aluModeSbc => - varV := (A(7) xor ninebits(7)) and ((not rmwBits(7)) xor ninebits(7)); - if D = '1' then - -- Check for borrow (lower 4 bits) - if lowBits(5) = '0' then - ninebits(3 downto 0) := ninebits(3 downto 0) - 6; - end if; - -- Check for borrow (upper 4 bits) - if ninebits(8) = '0' then - ninebits(8 downto 4) := ninebits(8 downto 4) - 6; - end if; - end if; - when aluModeArr => - if D = '1' then - if (("0" & aluInput(3 downto 0)) + ("0000" & aluInput(0))) > 5 then - ninebits(3 downto 0) := ninebits(3 downto 0) + 6; - end if; - if (("0" & aluInput(7 downto 4)) + ("0000" & aluInput(4))) > 5 then - ninebits(8 downto 4) := ninebits(8 downto 4) + 6; - varC := '1'; - else - varC := '0'; - end if; - end if; - when others => - null; - end case; - - if rising_edge(clk) then - aluRmwReg <= rmwBits(7 downto 0); - aluNineReg <= ninebits(7 downto 0); - aluCReg <= varC; - aluZReg <= varZ; - aluVReg <= varV; - aluNReg <= varN; - end if; - - aluRmwOut <= rmwBits(7 downto 0); - aluRegisterOut <= ninebits(7 downto 0); - aluC <= varC; - aluZ <= varZ; - aluV <= varV; - aluN <= varN; - if pipelineAluOut then - aluRmwOut <= aluRmwReg; - aluRegisterOut <= aluNineReg; - aluC <= aluCReg; - aluZ <= aluZReg; - aluV <= aluVReg; - aluN <= aluNReg; - end if; - end process; - -calcInterrupt: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - if theCpuCycle = cycleStack4 - or reset = '1' then - nmiReg <= '1'; - end if; - - if nextCpuCycle /= cycleBranchTaken - and nextCpuCycle /= opcodeFetch then - irqReg <= irq_n; - nmiEdge <= nmi_n; - if (nmiEdge = '1') and (nmi_n = '0') then - nmiReg <= '0'; - end if; - end if; - -- The 'or opcInfo(opcSetI)' prevents NMI immediately after BRK or IRQ. - -- Presumably this is done in the real 6502/6510 to prevent a double IRQ. - processIrq <= not ((nmiReg and (irqReg or I)) or opcInfo(opcIRQ)); - end if; - end if; - end process; - -calcNextOpcode: process(clk, di, reset, processIrq) - variable myNextOpcode : unsigned(7 downto 0); - begin - -- Next opcode is read from input unless a reset or IRQ is pending. - myNextOpcode := di; - if reset = '1' then - myNextOpcode := X"4C"; - elsif processIrq = '1' then - myNextOpcode := X"00"; - end if; - - nextOpcode <= myNextOpcode; - end process; - - nextOpcInfo <= opcodeInfoTable(to_integer(nextOpcode)); - process(clk) - begin - if rising_edge(clk) then - nextOpcInfoReg <= nextOpcInfo; - end if; - end process; - - -- Read bits and flags from opcodeInfoTable and store in opcInfo. - -- This info is used to control the execution of the opcode. -calcOpcInfo: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - if (reset = '1') or (theCpuCycle = opcodeFetch) then - opcInfo <= nextOpcInfo; - if pipelineOpcode then - opcInfo <= nextOpcInfoReg; - end if; - end if; - end if; - end if; - end process; - -calcTheOpcode: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - if theCpuCycle = opcodeFetch then - irqActive <= '0'; - if processIrq = '1' then - irqActive <= '1'; - end if; - -- Fetch opcode - theOpcode <= nextOpcode; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- State machine --- ----------------------------------------------------------------------- - process(enable, theCpuCycle, opcInfo) - begin - updateRegisters <= false; - if enable = '1' then - if opcInfo(opcRti) = '1' then - if theCpuCycle = cycleRead then - updateRegisters <= true; - end if; - elsif theCpuCycle = opcodeFetch then - updateRegisters <= true; - end if; - end if; - end process; - - debugOpcode <= theOpcode; - process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - theCpuCycle <= nextCpuCycle; - end if; - if reset = '1' then - theCpuCycle <= cycle2; - end if; - end if; - end process; - - -- Determine the next cpu cycle. After the last cycle we always - -- go to opcodeFetch to get the next opcode. -calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C, Z) - begin - nextCpuCycle <= opcodeFetch; - - case theCpuCycle is - when opcodeFetch => - nextCpuCycle <= cycle2; - when cycle2 => - if opcInfo(opcBranch) = '1' then - if (N = theOpcode(5) and theOpcode(7 downto 6) = "00") - or (V = theOpcode(5) and theOpcode(7 downto 6) = "01") - or (C = theOpcode(5) and theOpcode(7 downto 6) = "10") - or (Z = theOpcode(5) and theOpcode(7 downto 6) = "11") then - -- Branch condition is true - nextCpuCycle <= cycleBranchTaken; - end if; - elsif (opcInfo(opcStackUp) = '1') then - nextCpuCycle <= cycleStack1; - elsif opcInfo(opcStackAddr) = '1' - and opcInfo(opcStackData) = '1' then - nextCpuCycle <= cycleStack2; - elsif opcInfo(opcStackAddr) = '1' then - nextCpuCycle <= cycleStack1; - elsif opcInfo(opcStackData) = '1' then - nextCpuCycle <= cycleWrite; - elsif opcInfo(opcAbsolute) = '1' then - nextCpuCycle <= cycle3; - elsif opcInfo(opcIndirect) = '1' then - if opcInfo(indexX) = '1' then - nextCpuCycle <= cyclePreIndirect; - else - nextCpuCycle <= cycleIndirect; - end if; - elsif opcInfo(opcZeroPage) = '1' then - if opcInfo(opcWrite) = '1' then - if (opcInfo(indexX) = '1') - or (opcInfo(indexY) = '1') then - nextCpuCycle <= cyclePreWrite; - else - nextCpuCycle <= cycleWrite; - end if; - else - if (opcInfo(indexX) = '1') - or (opcInfo(indexY) = '1') then - nextCpuCycle <= cyclePreRead; - else - nextCpuCycle <= cycleRead2; - end if; - end if; - elsif opcInfo(opcJump) = '1' then - nextCpuCycle <= cycleJump; - end if; - when cycle3 => - nextCpuCycle <= cycleRead; - if opcInfo(opcWrite) = '1' then - if (opcInfo(indexX) = '1') - or (opcInfo(indexY) = '1') then - nextCpuCycle <= cyclePreWrite; - else - nextCpuCycle <= cycleWrite; - end if; - end if; - if (opcInfo(opcIndirect) = '1') - and (opcInfo(indexX) = '1') then - if opcInfo(opcWrite) = '1' then - nextCpuCycle <= cycleWrite; - else - nextCpuCycle <= cycleRead2; - end if; - end if; - when cyclePreIndirect => - nextCpuCycle <= cycleIndirect; - when cycleIndirect => - nextCpuCycle <= cycle3; - when cycleBranchTaken => - if indexOut(8) /= T(7) then - -- Page boundary crossing during branch. - nextCpuCycle <= cycleBranchPage; - end if; - when cyclePreRead => - if opcInfo(opcZeroPage) = '1' then - nextCpuCycle <= cycleRead2; - end if; - when cycleRead => - if opcInfo(opcJump) = '1' then - nextCpuCycle <= cycleJump; - elsif indexOut(8) = '1' then - -- Page boundary crossing while indexed addressing. - nextCpuCycle <= cycleRead2; - elsif opcInfo(opcRmw) = '1' then - nextCpuCycle <= cycleRmw; - if opcInfo(indexX) = '1' - or opcInfo(indexY) = '1' then - -- 6510 needs extra cycle for indexed addressing - -- combined with RMW indexing - nextCpuCycle <= cycleRead2; - end if; - end if; - when cycleRead2 => - if opcInfo(opcRmw) = '1' then - nextCpuCycle <= cycleRmw; - end if; - when cycleRmw => - nextCpuCycle <= cycleWrite; - when cyclePreWrite => - nextCpuCycle <= cycleWrite; - when cycleStack1 => - nextCpuCycle <= cycleRead; - if opcInfo(opcStackAddr) = '1' then - nextCpuCycle <= cycleStack2; - end if; - when cycleStack2 => - nextCpuCycle <= cycleStack3; - if opcInfo(opcRti) = '1' then - nextCpuCycle <= cycleRead; - end if; - if opcInfo(opcStackData) = '0' - and opcInfo(opcStackUp) = '1' then - nextCpuCycle <= cycleJump; - end if; - when cycleStack3 => - nextCpuCycle <= cycleRead; - if opcInfo(opcStackData) = '0' - or opcInfo(opcStackUp) = '1' then - nextCpuCycle <= cycleJump; - elsif opcInfo(opcStackAddr) = '1' then - nextCpuCycle <= cycleStack4; - end if; - when cycleStack4 => - nextCpuCycle <= cycleRead; - when cycleJump => - if opcInfo(opcIncrAfter) = '1' then - -- Insert extra cycle - nextCpuCycle <= cycleEnd; - end if; - when others => - null; - end case; - end process; - --- ----------------------------------------------------------------------- --- T register --- ----------------------------------------------------------------------- -calcT: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - case theCpuCycle is - when cycle2 => - T <= di; - when cycleStack1 | cycleStack2 => - if opcInfo(opcStackUp) = '1' then - -- Read from stack - T <= di; - end if; - when cycleIndirect | cycleRead | cycleRead2 => - T <= di; - when others => - null; - end case; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- A register --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateA) = '1' then - A <= aluRegisterOut; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- X register --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateX) = '1' then - X <= aluRegisterOut; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- Y register --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateY) = '1' then - Y <= aluRegisterOut; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- C flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateC) = '1' then - C <= aluC; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- Z flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateZ) = '1' then - Z <= aluZ; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- I flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateI) = '1' then - I <= aluInput(2); - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- D flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateD) = '1' then - D <= aluInput(3); - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- V flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateV) = '1' then - V <= aluV; - end if; - end if; - if enable = '1' then - if soReg = '1' and so_n = '0' then - V <= '1'; - end if; - soReg <= so_n; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- N flag --- ----------------------------------------------------------------------- - process(clk) - begin - if rising_edge(clk) then - if updateRegisters then - if opcInfo(opcUpdateN) = '1' then - N <= aluN; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- Stack pointer --- ----------------------------------------------------------------------- - process(clk) - variable sIncDec : unsigned(7 downto 0); - variable updateFlag : boolean; - begin - if rising_edge(clk) then - - if opcInfo(opcStackUp) = '1' then - sIncDec := S + 1; - else - sIncDec := S - 1; - end if; - - if enable = '1' then - updateFlag := false; - case nextCpuCycle is - when cycleStack1 => - if (opcInfo(opcStackUp) = '1') - or (opcInfo(opcStackData) = '1') then - updateFlag := true; - end if; - when cycleStack2 => - updateFlag := true; - when cycleStack3 => - updateFlag := true; - when cycleStack4 => - updateFlag := true; - when cycleRead => - if opcInfo(opcRti) = '1' then - updateFlag := true; - end if; - when cycleWrite => - if opcInfo(opcStackData) = '1' then - updateFlag := true; - end if; - when others => - null; - end case; - if updateFlag then - S <= sIncDec; - end if; - end if; - if updateRegisters then - if opcInfo(opcUpdateS) = '1' then - S <= aluRegisterOut; - end if; - end if; - end if; - end process; - --- ----------------------------------------------------------------------- --- Data out --- ----------------------------------------------------------------------- ---calcDo: process(cpuNo, theCpuCycle, aluOut, PC, T) -calcDo: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - doReg <= aluRmwOut; - if opcInfo(opcInH) = '1' then - -- For illegal opcodes SHA, SHX, SHY, SHS - doReg <= aluRmwOut and myAddrIncrH; - end if; - - case nextCpuCycle is - when cycleStack2 => - if opcInfo(opcIRQ) = '1' - and irqActive = '0' then - doReg <= myAddrIncr(15 downto 8); - else - doReg <= PC(15 downto 8); - end if; - when cycleStack3 => - doReg <= PC(7 downto 0); - when cycleRmw => --- do <= T; -- Read-modify-write write old value first. - doReg <= di; -- Read-modify-write write old value first. - when others => null; - end case; - end if; - end if; - end process; - do <= doReg; - - - --- ----------------------------------------------------------------------- --- Write enable --- ----------------------------------------------------------------------- -calcWe: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - theWe <= '0'; - case nextCpuCycle is - when cycleStack1 => - if opcInfo(opcStackUp) = '0' - and ((opcInfo(opcStackAddr) = '0') - or (opcInfo(opcStackData) = '1')) then - theWe <= '1'; - end if; - when cycleStack2 | cycleStack3 | cycleStack4 => - if opcInfo(opcStackUp) = '0' then - theWe <= '1'; - end if; - when cycleRmw => - theWe <= '1'; - when cycleWrite => - theWe <= '1'; - when others => - null; - end case; - end if; - end if; - end process; - we <= theWe; - --- ----------------------------------------------------------------------- --- Program counter --- ----------------------------------------------------------------------- -calcPC: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - case theCpuCycle is - when opcodeFetch => - PC <= myAddr; - when cycle2 => - if irqActive = '0' then - if opcInfo(opcSecondByte) = '1' then - PC <= myAddrIncr; - else - PC <= myAddr; - end if; - end if; - when cycle3 => - if opcInfo(opcAbsolute) = '1' then - PC <= myAddrIncr; - end if; - when others => - null; - end case; - end if; - end if; - end process; - debugPc <= PC; - --- ----------------------------------------------------------------------- --- Address generation --- ----------------------------------------------------------------------- -calcNextAddr: process(theCpuCycle, opcInfo, indexOut, T, reset) - begin - nextAddr <= nextAddrIncr; - case theCpuCycle is - when cycle2 => - if opcInfo(opcStackAddr) = '1' - or opcInfo(opcStackData) = '1' then - nextAddr <= nextAddrStack; - elsif opcInfo(opcAbsolute) = '1' then - nextAddr <= nextAddrIncr; - elsif opcInfo(opcZeroPage) = '1' then - nextAddr <= nextAddrZeroPage; - elsif opcInfo(opcIndirect) = '1' then - nextAddr <= nextAddrZeroPage; - elsif opcInfo(opcSecondByte) = '1' then - nextAddr <= nextAddrIncr; - else - nextAddr <= nextAddrHold; - end if; - when cycle3 => - if (opcInfo(opcIndirect) = '1') - and (opcInfo(indexX) = '1') then - nextAddr <= nextAddrAbs; - else - nextAddr <= nextAddrAbsIndexed; - end if; - when cyclePreIndirect => - nextAddr <= nextAddrZPIndexed; - when cycleIndirect => - nextAddr <= nextAddrIncrL; - when cycleBranchTaken => - nextAddr <= nextAddrRelative; - when cycleBranchPage => - if T(7) = '0' then - nextAddr <= nextAddrIncrH; - else - nextAddr <= nextAddrDecrH; - end if; - when cyclePreRead => - nextAddr <= nextAddrZPIndexed; - when cycleRead => - nextAddr <= nextAddrPc; - if opcInfo(opcJump) = '1' then - -- Emulate 6510 bug, jmp(xxFF) fetches from same page. - -- Replace with nextAddrIncr if emulating 65C02 or later cpu. - nextAddr <= nextAddrIncrL; - elsif indexOut(8) = '1' then - nextAddr <= nextAddrIncrH; - elsif opcInfo(opcRmw) = '1' then - nextAddr <= nextAddrHold; - end if; - when cycleRead2 => - nextAddr <= nextAddrPc; - if opcInfo(opcRmw) = '1' then - nextAddr <= nextAddrHold; - end if; - when cycleRmw => - nextAddr <= nextAddrHold; - when cyclePreWrite => - nextAddr <= nextAddrHold; - if opcInfo(opcZeroPage) = '1' then - nextAddr <= nextAddrZPIndexed; - elsif indexOut(8) = '1' then - nextAddr <= nextAddrIncrH; - end if; - when cycleWrite => - nextAddr <= nextAddrPc; - when cycleStack1 => - nextAddr <= nextAddrStack; - when cycleStack2 => - nextAddr <= nextAddrStack; - when cycleStack3 => - nextAddr <= nextAddrStack; - if opcInfo(opcStackData) = '0' then - nextAddr <= nextAddrPc; - end if; - when cycleStack4 => - nextAddr <= nextAddrIrq; - when cycleJump => - nextAddr <= nextAddrAbs; - when others => - null; - end case; - if reset = '1' then - nextAddr <= nextAddrReset; - end if; - end process; - -indexAlu: process(opcInfo, myAddr, T, X, Y) - begin - if opcInfo(indexX) = '1' then - indexOut <= (B"0" & T) + (B"0" & X); - elsif opcInfo(indexY) = '1' then - indexOut <= (B"0" & T) + (B"0" & Y); - elsif opcInfo(opcBranch) = '1' then - indexOut <= (B"0" & T) + (B"0" & myAddr(7 downto 0)); - else - indexOut <= B"0" & T; - end if; - end process; - -calcAddr: process(clk) - begin - if rising_edge(clk) then - if enable = '1' then - case nextAddr is - when nextAddrIncr => myAddr <= myAddrIncr; - when nextAddrIncrL => myAddr(7 downto 0) <= myAddrIncr(7 downto 0); - when nextAddrIncrH => myAddr(15 downto 8) <= myAddrIncrH; - when nextAddrDecrH => myAddr(15 downto 8) <= myAddrDecrH; - when nextAddrPc => myAddr <= PC; - when nextAddrIrq => - myAddr <= X"FFFE"; - if nmiReg = '0' then - myAddr <= X"FFFA"; - end if; - when nextAddrReset => myAddr <= X"FFFC"; - when nextAddrAbs => myAddr <= di & T; - when nextAddrAbsIndexed => myAddr <= di & indexOut(7 downto 0); - when nextAddrZeroPage => myAddr <= "00000000" & di; - when nextAddrZPIndexed => myAddr <= "00000000" & indexOut(7 downto 0); - when nextAddrStack => myAddr <= "00000001" & S; - when nextAddrRelative => myAddr(7 downto 0) <= indexOut(7 downto 0); - when others => null; - end case; - end if; - end if; - end process; - - myAddrIncr <= myAddr + 1; - myAddrIncrH <= myAddr(15 downto 8) + 1; - myAddrDecrH <= myAddr(15 downto 8) - 1; - - addr <= myAddr; - - debugA <= A; - debugX <= X; - debugY <= Y; - debugS <= S; - -end architecture; - - diff --git a/cores/c64/rtl/cpu_6510.vhd b/cores/c64/rtl/cpu_6510.vhd index a1a8d2b..135b06d 100644 --- a/cores/c64/rtl/cpu_6510.vhd +++ b/cores/c64/rtl/cpu_6510.vhd @@ -21,103 +21,65 @@ use ieee.numeric_std.ALL; -- ----------------------------------------------------------------------- entity cpu_6510 is - generic ( - pipelineOpcode : boolean; - pipelineAluMux : boolean; - pipelineAluOut : boolean - ); port ( - clk : in std_logic; - enable : in std_logic; - reset : in std_logic; - nmi_n : in std_logic; + clk : in std_logic; + enable : in std_logic; + reset : in std_logic; + nmi_n : in std_logic; nmi_ack : out std_logic; - irq_n : in std_logic; + irq_n : in std_logic; - di : in unsigned(7 downto 0); - do : out unsigned(7 downto 0); - addr : out unsigned(15 downto 0); - we : out std_logic; + di : in unsigned(7 downto 0); + do : out unsigned(7 downto 0); + addr : out unsigned(15 downto 0); + we : out std_logic; - diIO : in unsigned(7 downto 0); - doIO : out unsigned(7 downto 0); - - debugOpcode : out unsigned(7 downto 0); - debugPc : out unsigned(15 downto 0); - debugA : out unsigned(7 downto 0); - debugX : out unsigned(7 downto 0); - debugY : out unsigned(7 downto 0); - debugS : out unsigned(7 downto 0) + diIO : in unsigned(7 downto 0); + doIO : out unsigned(7 downto 0) ); end cpu_6510; -- ----------------------------------------------------------------------- architecture rtl of cpu_6510 is - signal localA : unsigned(15 downto 0); - signal localDi : unsigned(7 downto 0); - signal localDo : unsigned(7 downto 0); + signal localA : std_logic_vector(23 downto 0); + signal localDi : std_logic_vector(7 downto 0); + signal localDo : std_logic_vector(7 downto 0); signal localWe : std_logic; - signal currentIO : unsigned(7 downto 0); - signal ioDir : unsigned(7 downto 0); - signal ioData : unsigned(7 downto 0); + signal currentIO : std_logic_vector(7 downto 0); + signal ioDir : std_logic_vector(7 downto 0); + signal ioData : std_logic_vector(7 downto 0); signal accessIO : std_logic; begin - cpuInstance: entity work.cpu65xx(fast) - generic map ( - pipelineOpcode => pipelineOpcode, - pipelineAluMux => pipelineAluMux, - pipelineAluOut => pipelineAluOut - ) - port map ( - clk => clk, - enable => enable, - reset => reset, - nmi_n => nmi_n, - nmi_ack => nmi_ack, - irq_n => irq_n, - di => localDi, - do => localDo, - addr => localA, - we => localWe, + cpu: work.T65 + port map( + Mode => "00", + Res_n => not reset, + Enable => enable, + Clk => clk, + Rdy => '1', + Abort_n => '1', + IRQ_n => irq_n, + NMI_n => nmi_n, + SO_n => '1', + R_W_n => localWe, + A => localA, + DI => localDi, + DO => localDo, + NMI_ack => nmi_ack + ); + + accessIO <= '1' when localA(15 downto 1) = X"000"&"000" else '0'; + localDi <= localDo when localWe = '0' else std_logic_vector(di) when accessIO = '0' else ioDir when localA(0) = '0' else currentIO; - debugOpcode => debugOpcode, - debugPc => debugPc, - debugA => debugA, - debugX => debugX, - debugY => debugY, - debugS => debugS - ); - - process(localA) - begin - accessIO <= '0'; - if localA(15 downto 1) = 0 then - accessIO <= '1'; - end if; - end process; - - process(di, localA, ioDir, currentIO, accessIO) - begin - localDi <= di; - if accessIO = '1' then - if localA(0) = '0' then - localDi <= ioDir; - else - localDi <= currentIO; - end if; - end if; - end process; - process(clk) begin if rising_edge(clk) then if accessIO = '1' then - if localWe = '1' - and enable = '1' then + if localWe = '0' and enable = '1' then if localA(0) = '0' then ioDir <= localDo; else @@ -130,12 +92,12 @@ begin end if; end if; end process; - + process(ioDir, ioData, diIO) begin for i in 0 to 7 loop if ioDir(i) = '0' then - currentIO(i) <= diIO(i); + currentIO(i) <= std_logic(diIO(i)); else currentIO(i) <= ioData(i); end if; @@ -143,8 +105,8 @@ begin end process; -- Cunnect zee wires - addr <= localA; - do <= localDo; - we <= localWe; - doIO <= currentIO; + addr <= unsigned(localA(15 downto 0)); + do <= unsigned(localDo); + we <= not localWe; + doIO <= unsigned(currentIO); end architecture; diff --git a/cores/c64/rtl/fpga64_sid_iec.vhd b/cores/c64/rtl/fpga64_sid_iec.vhd index 6ca3a3d..ef4eb48 100644 --- a/cores/c64/rtl/fpga64_sid_iec.vhd +++ b/cores/c64/rtl/fpga64_sid_iec.vhd @@ -633,11 +633,7 @@ sid_8580 : sid8580 -- 6510 CPU -- ----------------------------------------------------------------------- cpu: entity work.cpu_6510 - generic map ( - pipelineOpcode => false, - pipelineAluMux => false, - pipelineAluOut => false - ) + port map ( clk => clk32, reset => reset, @@ -652,14 +648,7 @@ sid_8580 : sid8580 we => cpuWe, diIO => "00010111", - doIO => cpuIO, - - debugOpcode => open, - debugPc => open, - debugA => open, - debugX => open, - debugY => open, - debugS => open + doIO => cpuIO ); -- ----------------------------------------------------------------------- diff --git a/cores/c64/rtl/t65/T65.vhd b/cores/c64/rtl/t65/T65.vhd index d6aba9c..6aa472a 100755 --- a/cores/c64/rtl/t65/T65.vhd +++ b/cores/c64/rtl/t65/T65.vhd @@ -152,7 +152,8 @@ entity T65 is DO : out std_logic_vector(7 downto 0); -- 6502 registers (MSB) PC, SP, P, Y, X, A (LSB) Regs : out std_logic_vector(63 downto 0); - DEBUG : out T_t65_dbg + DEBUG : out T_t65_dbg; + NMI_ack : out std_logic ); end T65; @@ -236,6 +237,8 @@ architecture rtl of T65 is signal NMI_entered : std_logic; begin + NMI_ack <= NMIAct; + -- gate Rdy with read/write to make an "OK, it's really OK to stop the processor really_rdy <= Rdy or not(WRn_i); Sync <= '1' when MCycle = "000" else '0';