Project

General

Profile

« Previous | Next » 

Revision 214

Added by markw almost 11 years ago

Upgraded to latest version of Peter Wendrichs core. Thanks Peter!

View differences:

common/a8core/cpu_6510.vhd
pipelineOpcode : boolean;
pipelineAluMux : boolean;
pipelineAluOut : boolean;
emulate_bitfade : boolean
emulate_bitfade : boolean;
emulate_01_write : boolean
);
port (
clk : in std_logic;
......
d : in unsigned(7 downto 0);
q : out unsigned(7 downto 0);
vic_last_data : in unsigned(7 downto 0) := (others => '1');
diIO : in unsigned(7 downto 0);
doIO : out unsigned(7 downto 0);
debugOpcode : out unsigned(7 downto 0);
debugJam : out std_logic;
debugPc : out unsigned(15 downto 0);
debugA : out unsigned(7 downto 0);
debugX : out unsigned(7 downto 0);
......
signal ioDir : unsigned(7 downto 0);
signal ioData : unsigned(7 downto 0);
signal accessIO : std_logic;
signal accessing_IO : boolean;
signal ioFade : unsigned(7 downto 0) := (others => '0');
begin
cpuInstance: entity work.cpu_65xx
......
we => localWe,
debugOpcode => debugOpcode,
debugJam => debugJam,
debugPc => debugPc,
debugA => debugA,
debugX => debugX,
......
debug_flags => debug_flags
);
process(localA)
begin
accessIO <= '0';
if localA(15 downto 1) = 0 then
accessIO <= '1';
end if;
end process;
accessing_IO <= localA(15 downto 1) = 0;
process(d, localA, ioDir, currentIO, accessIO)
process(d, localA, ioDir, currentIO, accessing_IO)
begin
localD <= d;
if accessIO = '1' then
if accessing_IO then
if localA(0) = '0' then
localD <= ioDir;
else
......
process(clk)
begin
if rising_edge(clk) then
if accessIO = '1' then
if accessing_IO then
if localWe = '1'
and enable = '1' then
if localA(0) = '0' then
......
end if;
end process;
process(ioDir, ioData, diIO)
process(ioDir, ioData, diIO, ioFade)
begin
for i in 0 to 7 loop
if ioDir(i) = '0' then
......
-- Cunnect zee wires
a <= localA;
q <= localQ;
q <= vic_last_data when (emulate_01_write and accessing_IO) else localQ;
we <= localWe;
doIO <= currentIO;
debug_io <= "00" & (ioData(5 downto 0) or (not ioDir(5 downto 0)));
common/a8core/cpu_65xx_a.vhd
library IEEE;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.ALL;
-- -----------------------------------------------------------------------
......
constant opcIncrAfter : integer := 23; -- Insert extra cycle to increment PC (RTS)
constant opcRti : integer := 24;
constant opcIRQ : integer := 25;
constant opcJAM : integer := 26;
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 opcInA : integer := 27;
constant opcInE : integer := 28;
constant opcInX : integer := 29;
constant opcInY : integer := 30;
constant opcInS : integer := 31;
constant opcInT : integer := 32;
constant opcInH : integer := 33;
constant opcInClear : integer := 34;
constant aluMode1From : integer := 35;
--
constant aluMode1To : integer := 37;
constant aluMode2From : integer := 38;
constant aluMode1To : integer := 38;
constant aluMode2From : integer := 39;
--
constant aluMode2To : integer := 40;
constant aluMode2To : integer := 41;
--
constant opcInCmp : integer := 41;
constant opcInCpx : integer := 42;
constant opcInCpy : integer := 43;
constant opcInCmp : integer := 42;
constant opcInCpx : integer := 43;
constant opcInCpy : integer := 44;
subtype addrDef is unsigned(0 to 15);
subtype addrDef is unsigned(0 to 16);
--
-- 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";
-- is JAM ------------------+
-- 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 := "10000000000000000";
constant implied : addrDef := "00000000000000000";
-- Zero page
constant readZp : addrDef := "1010000000000000";
constant writeZp : addrDef := "1010000000010000";
constant rmwZp : addrDef := "1010000000001000";
constant readZp : addrDef := "10100000000000000";
constant writeZp : addrDef := "10100000000100000";
constant rmwZp : addrDef := "10100000000010000";
-- 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";
constant readZpX : addrDef := "10100000100000000";
constant writeZpX : addrDef := "10100000100100000";
constant rmwZpX : addrDef := "10100000100010000";
constant readZpY : addrDef := "10100000010000000";
constant writeZpY : addrDef := "10100000010100000";
constant rmwZpY : addrDef := "10100000010010000";
-- 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";
constant readIndX : addrDef := "10010000100000000";
constant writeIndX : addrDef := "10010000100100000";
constant rmwIndX : addrDef := "10010000100010000";
constant readIndY : addrDef := "10010000010000000";
constant writeIndY : addrDef := "10010000010100000";
constant rmwIndY : addrDef := "10010000010010000";
-- |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";
constant readAbs : addrDef := "11000000000000000";
constant writeAbs : addrDef := "11000000000100000";
constant rmwAbs : addrDef := "11000000000010000";
constant readAbsX : addrDef := "11000000100000000";
constant writeAbsX : addrDef := "11000000100100000";
constant rmwAbsX : addrDef := "11000000100010000";
constant readAbsY : addrDef := "11000000010000000";
constant writeAbsY : addrDef := "11000000010100000";
constant rmwAbsY : addrDef := "11000000010010000";
-- PHA PHP
constant push : addrDef := "0000010000000000";
constant push : addrDef := "00000100000000000";
-- PLA PLP
constant pop : addrDef := "0000010000100000";
constant pop : addrDef := "00000100001000000";
-- Jumps
constant jsr : addrDef := "1000101000000000";
constant jumpAbs : addrDef := "1000001000000000";
constant jumpInd : addrDef := "1100001000000000";
constant relative : addrDef := "1000000100000000";
constant jsr : addrDef := "10001010000000000";
constant jumpAbs : addrDef := "10000010000000000";
constant jumpInd : addrDef := "11000010000000000";
constant relative : addrDef := "10000001000000000";
-- Specials
constant rts : addrDef := "0000101000100100";
constant rti : addrDef := "0000111000100010";
constant brk : addrDef := "1000111000000001";
constant rts : addrDef := "00001010001001000";
constant rti : addrDef := "00001110001000100";
constant brk : addrDef := "10001110000000010";
constant xxxxxxxx : addrDef := "0---------0---001";
-- constant : unsigned(0 to 0) := "0";
constant xxxxxxxx : addrDef := "----------0---00";
-- A = accu
-- E = Accu | 0xEE (for ANE, LXA)
......
constant stackDec : unsigned(0 to 0) := "1";
constant stackXXX : unsigned(0 to 0) := "-";
subtype decodedBitsDef is unsigned(0 to 43);
subtype decodedBitsDef is unsigned(0 to 44);
type opcodeInfoTableDef is array(0 to 255) of decodedBitsDef;
constant opcodeInfoTable : opcodeInfoTableDef := (
-- +------- Update register A
......
"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 & aluInAX & aluInp, -- 9F iAHX 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)
......
"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 & aluAnd, -- AB iLXA imm - MWW:change for Atari800 CPU
--"1100" & "100010" & immediate & aluInET & aluInp, -- AB iLXA imm
"1100" & "100010" & immediate & aluInET & aluAnd, -- AB iLXA imm - MWW:change for Atari800 CPU
"0010" & "100010" & readAbs & aluInT & aluInp, -- AC LDY abs
"1000" & "100010" & readAbs & aluInT & aluInp, -- AD LDA abs
"0100" & "100010" & readAbs & aluInT & aluInp, -- AE LDX abs
......
-- Indexing
signal indexOut : unsigned(8 downto 0);
-- JAM
signal jam_flag : std_logic := '0';
begin
processAluInput: process(clk, opcInfo, A, X, Y, T, S)
variable temp : unsigned(7 downto 0);
......
-- 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, Nreg, Vreg, Dreg, Ireg, Zreg, Creg)
processAlu: process(clk,
opcInfo, aluInput, aluInputReg, aluCmpInput, aluCmpInputReg, aluNineReg,
A, T, irqActive, Nreg, Vreg, Dreg, Ireg, Zreg, Creg, aluNreg, aluVreg, aluZreg, aluCreg)
variable lowBits: unsigned(5 downto 0);
variable nineBits: unsigned(8 downto 0);
variable rmwBits: unsigned(8 downto 0);
......
begin
if rising_edge(clk) then
if (enable = '1') then -- and (halt = '0') then
irqReg <= irq_n;
nmiEdge <= nmi_n;
if (nmiEdge = '1') and (nmi_n = '0') then
nmiReg <= '0';
end if;
if theCpuCycle = cycleStack4 -- MWW
or reset = '1' then
nmiReg <= '1';
end if;
if theCpuCycle = cycleStack4
or reset = '1' then
nmiReg <= '1';
end if;
if halt = '0' then
if theCpuCycle /= cycleBranchTaken then
-- The 'or opcInfo(opcSetI)' prevents NMI immediately after BRK or IRQ.
......
nextOpcode <= myNextOpcode;
end process;
nextOpcInfo <= opcodeInfoTable(to_integer(to_01(nextOpcode, '0')));
nextOpcInfo <= opcodeInfoTable(to_integer(to_01(nextOpcode,'0')));
process(clk)
begin
if rising_edge(clk) then
......
if rising_edge(clk) then
if (enable = '1') and (halt = '0') then
theCpuCycle <= nextCpuCycle;
debugJam <= jam_flag;
end if;
if reset = '1' then
theCpuCycle <= cycle2;
debugJam <= '0';
end if;
end if;
end process;
......
-- go to opcodeFetch to get the next opcode.
calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, Nreg, Vreg, Creg, Zreg)
begin
jam_flag <= '0';
nextCpuCycle <= opcodeFetch;
case theCpuCycle is
when opcodeFetch =>
nextCpuCycle <= cycle2;
when cycle2 =>
if opcInfo(opcBranch) = '1' then
if enable_jam and (opcInfo(opcJAM) = '1') then
nextCpuCycle <= cycle2;
jam_flag <= '1';
-- Stay in cycle2
elsif opcInfo(opcBranch) = '1' then
if (Nreg = theOpcode(5) and theOpcode(7 downto 6) = "00")
or (Vreg = theOpcode(5) and theOpcode(7 downto 6) = "01")
or (Creg = theOpcode(5) and theOpcode(7 downto 6) = "10")
......
Ireg <= '1';
end if;
end if;
if enable = '1' and reset = '1' then
Ireg <= '1';
end if;
end if;
end process;
......
if rising_edge(clk) then
if (enable = '1') and (halt = '0') then
doReg <= aluRmwOut;
if opcInfo(opcInH) = '1' then
if opcInfo(opcInH) = '1' and (halt_dly = '0') then
-- For illegal opcodes SHA, SHX, SHY, SHS
doReg <= aluRmwOut and myAddrIncrH;
end if;
common/a8core/cpu_65xx_e.vhd
entity cpu_65xx is
generic (
enable_jam : boolean := true;
pipelineOpcode : boolean;
pipelineAluMux : boolean;
pipelineAluOut : boolean
......
we : out std_logic;
debugOpcode : out unsigned(7 downto 0);
debugJam : out std_logic;
debugPc : out unsigned(15 downto 0);
debugA : out unsigned(7 downto 0);
debugX : out unsigned(7 downto 0);

Also available in: Unified diff