Project

General

Profile

« Previous | Next » 

Revision 7

Added by markw about 11 years ago

Cleaned up ZPU into slightly more generic form, though still clearly atari core targetted. Added inital tb, though needs rom to verify more. MIST sector side removed, but should be possible with external changes. Now ZPU instead has lots of GPIO.

View differences:

zpu_config_regs.vhdl
use ieee.numeric_std.all;
ENTITY zpu_config_regs IS
GENERIC
(
platform : integer := 1 -- So ROM can detect which type of system...
);
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
ENABLE_179 : in std_logic;
POKEY_ENABLE : in std_logic;
ADDR : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
CPU_DATA_IN : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
WR_EN : IN STD_LOGIC;
-- SWITCHES
SWITCH : in std_logic_vector(9 downto 0); -- already synchronized
KEY : in std_logic_vector(3 downto 0); -- already synchronized
-- GENERIC INPUT REGS (need to synchronize upstream...)
IN1 : in std_logic_vector(31 downto 0);
IN2 : in std_logic_vector(31 downto 0);
IN3 : in std_logic_vector(31 downto 0);
IN4 : in std_logic_vector(31 downto 0);
-- LEDS
LEDG : out std_logic_vector(7 downto 0);
LEDR : out std_logic_vector(9 downto 0);
-- GENERIC OUTPUT REGS
OUT1 : out std_logic_vector(31 downto 0);
OUT2 : out std_logic_vector(31 downto 0);
OUT3 : out std_logic_vector(31 downto 0);
OUT4 : out std_logic_vector(31 downto 0);
-- SDCARD
SDCARD_CLK : out std_logic;
......
-- ATARI interface (in future we can also turbo load by directly hitting memory...)
SIO_DATA_IN : out std_logic;
SIO_COMMAND_OUT : in std_logic;
SIO_COMMAND : in std_logic;
SIO_DATA_OUT : in std_logic;
-- CPU interface
DATA_OUT : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
PAUSE_ZPU : out std_logic;
-- SYSTEM CONFIG SETTINGS (legacy from switches - hardcoded to start with, then much fancier)
PAL : OUT STD_LOGIC;
USE_SDRAM : OUT STD_LOGIC;
RAM_SELECT : OUT STD_LOGIC_VECTOR(2 downto 0);
VGA : OUT STD_LOGIC;
COMPOSITE_ON_HSYNC : OUT STD_LOGIC;
GPIO_ENABLE : OUT STD_LOGIC;
ROM_SELECT : out stD_logic_vector(1 downto 0);
-- sector buffer
sector : out std_logic_vector(31 downto 0);
sector_request : out std_logic;
sector_ready : in std_logic;
-- system reset/halt
PLL_LOCKED : IN STD_LOGIC; -- pll locked
REQUEST_RESET_ZPU : in std_logic; -- from keyboard (f12 to start with)
RESET_6502 : OUT STD_LOGIC; -- i.e. cpu reset - 6502
RESET_ZPU : OUT STD_LOGIC; -- i.e. cpu reset - zpu
RESET_N : OUT STD_LOGIC; -- i.e. reset line on flip flops
PAUSE_6502 : out std_logic;
THROTTLE_COUNT_6502 : out std_logic_vector(5 downto 0);
ZPU_HEX : out std_logic_vector(15 downto 0)
-- -- synchronize async inputs
-- locked_synchronizer : synchronizer
-- port map (clk=>clk, raw=>LOCKED, sync=>LOCKED_REG);
PAUSE_ZPU : out std_logic
);
END zpu_config_regs;
ARCHITECTURE vhdl OF zpu_config_regs IS
COMPONENT complete_address_decoder IS
generic (width : natural := 4);
PORT
(
addr_in : in std_logic_vector(width-1 downto 0);
addr_decoded : out std_logic_vector((2**width)-1 downto 0)
);
END component;
component pokey IS
PORT
(
CLK : IN STD_LOGIC;
--ENABLE_179 :in std_logic;
CPU_MEMORY_READY :in std_logic;
ANTIC_MEMORY_READY :in std_logic;
ADDR : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DATA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
WR_EN : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
-- keyboard interface
keyboard_scan : out std_logic_vector(5 downto 0);
keyboard_response : in std_logic_vector(1 downto 0);
-- pots - go high as capacitor charges
POT_IN : in std_logic_vector(7 downto 0);
-- sio interface
SIO_IN1 : IN std_logic;
SIO_IN2 : IN std_logic;
SIO_IN3 : IN std_logic;
DATA_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
CHANNEL_0_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
CHANNEL_1_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
CHANNEL_2_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
CHANNEL_3_OUT : OUT STD_LOGIC_VECTOR(3 downto 0);
IRQ_N_OUT : OUT std_logic;
SIO_OUT1 : OUT std_logic;
SIO_OUT2 : OUT std_logic;
SIO_OUT3 : OUT std_logic;
SIO_CLOCK : INOUT std_logic; -- TODO, should not use internally
POT_RESET : out std_logic
);
END component;
function vectorize(s: std_logic) return std_logic_vector is
variable v: std_logic_vector(0 downto 0);
begin
......
signal addr_decoded : std_logic_vector(15 downto 0);
signal config_6502_next : std_logic_vector(7 downto 0);
signal config_6502_reg : std_logic_vector(7 downto 0);
signal ram_select_next : std_logic_vector(2 downto 0);
signal ram_select_reg : std_logic_vector(2 downto 0);
signal rom_select_next : std_logic_vector(1 downto 0);
signal rom_select_reg : std_logic_vector(1 downto 0);
signal gpio_enable_next : std_logic;
signal gpio_enable_reg : std_logic;
signal out1_next : std_logic_vector(31 downto 0);
signal out1_reg : std_logic_vector(31 downto 0);
signal out2_next : std_logic_vector(31 downto 0);
signal out2_reg : std_logic_vector(31 downto 0);
signal out3_next : std_logic_vector(31 downto 0);
signal out3_reg : std_logic_vector(31 downto 0);
signal out4_next : std_logic_vector(31 downto 0);
signal out4_reg : std_logic_vector(31 downto 0);
signal pause_next : std_logic_vector(31 downto 0);
signal pause_reg : std_logic_vector(31 downto 0);
signal paused_next : std_logic;
signal paused_reg : std_logic;
signal ledg_next : std_logic_vector(7 downto 0);
signal ledg_reg : std_logic_vector(7 downto 0);
signal ledr_next : std_logic_vector(9 downto 0);
signal ledr_reg : std_logic_vector(9 downto 0);
signal reset_n_next : std_logic;
signal reset_n_reg : std_logic;
signal reset_6502_cpu_next : std_logic;
signal reset_6502_cpu_reg : std_logic;
signal reset_zpu_next : std_logic;
signal reset_zpu_reg : std_logic;
signal spi_miso : std_logic;
signal spi_mosi : std_logic;
signal spi_busy : std_logic;
......
signal spi_addr_next : std_logic;
signal spi_addr_reg : std_logic;
signal spi_addr_reg_integer : integer;
signal spi_speed_next : std_logic_vector(7 downto 0);
signal spi_speed_reg : std_logic_vector(7 downto 0);
signal spi_speed_reg_integer : integer;
signal zpu_hex_next : std_logic_vector(15 downto 0);
signal zpu_hex_reg : std_logic_vector(15 downto 0);
signal pokey_data_out : std_logic_vector(7 downto 0);
signal sector_next : std_logic_vector(31 downto 0);
signal sector_reg : std_logic_vector(31 downto 0);
signal sector_request_next : std_logic;
signal sector_request_reg : std_logic; -- cleared when ready asserted
signal wr_en_pokey : std_logic;
signal spi_addr_reg_integer : integer;
signal spi_speed_reg_integer : integer;
signal wr_en_pokey : std_logic;
signal pause_next : std_logic_vector(31 downto 0);
signal pause_reg : std_logic_vector(31 downto 0);
signal paused_next : std_logic;
signal paused_reg : std_logic;
begin
-- register
process(clk,pll_locked)
process(clk,reset_n)
begin
if (clk'event and clk='1') then
if (pll_locked = '0') then
config_6502_reg <= "1"&"0"&"001111"; -- reset_6502, halt_6502, run_every 16 cycles
rom_select_reg <= "01";
ram_select_reg <= "010";
gpio_enable_reg <= '0';
pause_reg <= (others=>'0');
paused_reg <= '0';
ledg_reg <= (others=>'0');
ledr_reg <= (others=>'0');
spi_addr_reg <= '1';
spi_speed_reg <= X"80";
zpu_hex_reg <= X"b007";
reset_n_reg <= '0';
reset_zpu_reg <= '1';
reset_6502_cpu_reg <= '1';
sector_reg <= (others=>'0');
sector_request_reg <= '0';
else
config_6502_reg <= config_6502_next;
rom_select_reg <= rom_select_next;
ram_select_reg <= ram_select_next;
gpio_enable_reg <= gpio_enable_next;
pause_reg <= pause_next;
paused_reg <= paused_next;
ledg_reg <= ledg_next;
ledr_reg <= ledr_next;
spi_addr_reg <= spi_addr_next;
spi_speed_reg <= spi_speed_next;
zpu_hex_reg <= zpu_hex_next;
reset_n_reg <= reset_n_next;
reset_zpu_reg <= reset_zpu_next;
reset_6502_cpu_reg <= reset_6502_cpu_next;
sector_reg <= sector_next;
sector_request_reg <= sector_request_next;
end if;
if (reset_n='0') then
out1_reg <= (others=>'0');
out2_reg <= (others=>'0');
out3_reg <= (others=>'0');
out4_reg <= (others=>'0');
spi_addr_reg <= '1';
spi_speed_reg <= X"80";
pause_reg <= (others=>'0');
paused_reg <= '0';
elsif (clk'event and clk='1') then
out1_reg <= out1_next;
out2_reg <= out2_next;
out3_reg <= out3_next;
out4_reg <= out4_next;
spi_addr_reg <= spi_addr_next;
spi_speed_reg <= spi_speed_next;
pause_reg <= pause_next;
paused_reg <= paused_next;
end if;
end process;
-- decode address
decode_addr1 : complete_address_decoder
decode_addr1 : entity work.complete_address_decoder
generic map(width=>4)
port map (addr_in=>addr(3 downto 0), addr_decoded=>addr_decoded);
......
-- uart - another Pokey! Running at atari frequency.
wr_en_pokey <= addr(4) and wr_en;
uart1 : pokey
port map (clk=>clk,CPU_MEMORY_READY=>enable_179,ANTIC_MEMORY_READY=>enable_179,addr=>addr(3 downto 0),data_in=>cpu_data_in(7 downto 0),wr_en=>wr_en_pokey,
reset_n=>pll_locked,keyboard_response=>"11",pot_in=>X"00",
pokey1 : entity work.pokey
port map (clk=>clk,CPU_MEMORY_READY=>pokey_enable,ANTIC_MEMORY_READY=>pokey_enable,addr=>addr(3 downto 0),data_in=>cpu_data_in(7 downto 0),wr_en=>wr_en_pokey,
reset_n=>reset_n,keyboard_response=>"11",pot_in=>X"00",
sio_in1=>sio_data_out,sio_in2=>'1',sio_in3=>'1', -- TODO, pokey dir...
data_out=>pokey_data_out,
sio_out1=>sio_data_in);
-- hardware regs for ZPU
--
-- KEYS -> all for ZPU. SWITCHES -> all for ZPU
-- i.e. zpu must control: rom/ram select, turbo, 6502 reset, scandoubler, rom wait states, pal/ntsc, gpio enable, sdram vs sram
-- these need storing somewhere...
-- TODO - volume output from here
-- TODO - hex digits register
-- TODO - if we take over antic we need to point antic to alternative RAM!
-- TODO - if we take over antic we need to point it back at the original display list... e.g. freeze, store state, restore state...
-- TODO - reset pokey and pia interrupts too?
--
-- virtual joystick button -> keyboard (windows key?)
-- reset -> keyboard -> f12 -> zpu reset. Then zpu controls 6502 reset.
--
-- important todo -> speed up clearing ram. e.g. 32-bit sram write. Only clear bit we need to.
--
-- STEP 1 -> joystick -> keyboard (DONE)
-- STEP 2 -> hardcode switch inputs to 65XE, PAL, non scandoubled (DONE)
-- STEP 3 -> 6502 reset (DONE))/turbo under zpu control (DONE)
-- STEP 4 -> zpu starts 6502 on key1 (DONE)
-- STEP 5 -> simple OSD! ok, just make antic display mode 2 on reset with hello world, joystick to select... (CLOSE)
--
-- CONFIG_ATARI:
-- R/W: 0-5: run every n cycles (0-63), 6: pause, 7: reset
-- R/W(8-11 bits) - XX 00=64k,01=128K,10=320K Compy,11=320K Rambo
-- R/W(12-15 bits) - XX 00=XL, 01=XL turbo, 10=OS B/debugger, 11=OS B turbo
-- R/W(16-20 bits) - XXXG= G:0=GPIO_OFF,1=GPIO_ON(ISH!)
-- PAUSE (DONE) -- W: 0-31:wait for n cycles
-- SWITCH (DONE)
-- R: 0-9 - switches
-- KEY (DONE)
-- R: 0-3 - keys
-- LEDG (DONE)
-- R/W: 0-9
-- LEDR (DONE)
-- R/W: 0-9
-- 0-3: GENERIC INPUT (RO)
-- 4-7: GENERIC OUTPUT (R/W)
-- 8: PAUSE
-- 9: SPI_DATA
-- SPI_DATA (DONE)
-- W - write data (starts transmission)
-- R - read data (wait for complete first)
-- 10: SPI_STATE
-- SPI_STATE/SPI_CTRL (DONE)
-- R: 0=busy
-- W: 0=select_n, speed
-- 11: SIO
-- SIO
-- R: 0=CMD
-- 12: TYPE
-- FPGA board (DONE)
-- R(32 bits) 0=DE1
-- HEX digits
-- W(16 bits)
-- SECTOR
-- W(32 bits) - write here initiates a request_reset_zpu
-- R: 0=request_active
-- TODO, ROM select, RAM select etc etc
-- TODO firmware with OSD!
-- 16-31: POKEY! Low bytes only... i.e. pokey reg every 4 bytes...
-- Writes to registers
process(cpu_data_in,wr_en,addr,addr_decoded, ledg_reg, ledr_reg, pause_reg, config_6502_reg, rom_select_reg, ram_select_reg, gpio_enable_reg, spi_speed_reg, spi_addr_reg, zpu_hex_reg, sector_request_reg, sector_ready, sector_reg)
process(cpu_data_in,wr_en,addr,addr_decoded, spi_speed_reg, spi_addr_reg, out1_reg, out2_reg, out3_reg, out4_reg, pause_reg)
begin
config_6502_next <= config_6502_reg;
rom_select_next <= rom_select_reg;
ram_select_next <= ram_select_reg;
gpio_enable_next <= gpio_enable_reg;
pause_next <= pause_reg;
ledg_next <= ledg_reg;
ledr_next <= ledr_reg;
spi_speed_next <= spi_speed_reg;
spi_addr_next <= spi_addr_reg;
spi_tx_data <= (others=>'0');
spi_enable <= '0';
zpu_hex_next <= zpu_hex_reg;
sector_next <= sector_reg;
sector_request_next <= sector_request_reg and not(sector_ready);
paused_next <= '0';
if (not(pause_reg = X"00000000")) then
pause_next <= std_LOGIC_VECTOR(unsigned(pause_reg)-to_unsigned(1,32));
......
end if;
if (wr_en = '1' and addr(4) = '0') then
if(addr_decoded(0) = '1') then
config_6502_next <= cpu_data_in(7 downto 0);
ram_select_next <= cpu_DATA_IN(10 downto 8);
rom_select_next <= cpu_DATA_IN(13 downto 12);
gpio_enable_next <= cpu_DATA_IN(16);
end if;
if(addr_decoded(1) = '1') then
pause_next <= cpu_data_in;
paused_next <= '1';
end if;
if(addr_decoded(4) = '1') then
ledg_next <= cpu_data_in(7 downto 0);
out1_next <= cpu_data_in;
end if;
if(addr_decoded(5) = '1') then
ledr_next <= cpu_data_in(9 downto 0);
out2_next <= cpu_data_in;
end if;
if(addr_decoded(6) = '1') then
out3_next <= cpu_data_in;
end if;
if(addr_decoded(7) = '1') then
out4_next <= cpu_data_in;
end if;
if(addr_decoded(8) = '1') then
pause_next <= cpu_data_in;
paused_next <= '1';
end if;
if(addr_decoded(9) = '1') then
-- TODO, check overrun?
spi_tx_data <= cpu_data_in(7 downto 0);
spi_enable <= '1';
end if;
if(addr_decoded(7) = '1') then
if(addr_decoded(10) = '1') then
spi_addr_next <= cpu_data_in(0);
if (cpu_data_in(1) = '1') then
spi_speed_next <= X"80"; -- slow, for init
......
spi_speed_next <= X"04"; -- turbo!
end if;
end if;
if(addr_decoded(10) = '1') then
zpu_hex_next <= cpu_data_in(15 downto 0);
end if;
if(addr_decoded(11) = '1') then
sector_next <= cpu_data_in;
sector_request_next <= '1';
end if;
end if;
end process;
-- Read from registers
process(addr,addr_decoded, ledg_reg, ledr_reg, SWITCH, KEY, SIO_COMMAND_OUT, spi_rx_data, spi_busy, pokey_data_out, zpu_hex_reg, config_6502_reg, ram_select_reg, rom_select_reg, gpio_enable_reg, sector_request_reg)
process(addr,addr_decoded, in1, in2, in3, in4, out1_reg, out2_reg, out3_reg, out4_reg, SIO_COMMAND, spi_rx_data, spi_busy, pokey_data_out)
begin
data_out <= (others=>'0');
if (addr(4) = '0') then
if (addr_decoded(0) = '1') then
data_out(7 downto 0) <= config_6502_reg;
data_out(10 downto 8) <= ram_select_reg;
data_out(13 downto 12) <= rom_select_reg;
data_out(16) <= gpio_enable_reg;
data_out <= in1;
end if;
if (addr_decoded(1) = '1') then
data_out <= in2;
end if;
if (addr_decoded(2) = '1') then
data_out(9 downto 0) <= (others=>'0'); -- TODO - enable SD.
data_out <= in3;
end if;
if (addr_decoded(3) = '1') then
data_out(3 downto 0) <= key;
end if;
data_out <= in4;
end if;
if (addr_decoded(4) = '1') then
data_out(7 downto 0) <= ledg_reg;
data_out <= out1_reg;
end if;
if (addr_decoded(5) = '1') then
data_out(9 downto 0) <= ledr_reg;
data_out <= out2_reg;
end if;
if (addr_decoded(6) = '1') then
data_out <= out3_reg;
end if;
if (addr_decoded(7) = '1') then
data_out <= out4_reg;
end if;
if (addr_decoded(6) = '1') then
if (addr_decoded(9) = '1') then
data_out(7 downto 0) <= spi_rx_data;
end if;
if (addr_decoded(7) = '1') then
if (addr_decoded(10) = '1') then
data_out(0) <= spi_busy;
end if;
if(addr_decoded(8) = '1') then
data_out(0) <= sio_command_OUT;
if(addr_decoded(11) = '1') then
data_out(0) <= SIO_COMMAND;
end if;
if (addr_decoded(9) = '1') then
--data_out <= X"00000000"; -- DE1!
--data_out <= X"00000001"; -- DE2!
--data_out <= X"00000002"; -- SOCKIT!
--data_out <= X"00000003"; -- REPLAY!
data_out <= X"00000004"; -- MMC!
if (addr_decoded(12) = '1') then
data_out <= std_logic_vector(to_unsigned(platform,32));
end if;
if (addr_decoded(10) = '1') then
data_out(15 downto 0) <= zpu_hex_reg;
end if;
if (addr_decoded(11) = '1') then
data_out(0) <= sector_request_reg;
end if;
else
data_out(7 downto 0) <= pokey_data_out;
end if;
end process;
process(request_reset_zpu, config_6502_next, config_6502_reg)
begin
reset_n_next <= '1';
reset_zpu_next <= '0';
reset_6502_cpu_next <= config_6502_reg(7);
if (request_reset_zpu = '1') then
reset_n_next <= '0';
reset_zpu_next <= '1';
reset_6502_cpu_next <= '1';
end if;
end process;
-- outputs
PAUSE_ZPU <= paused_reg;
LEDG <= ledg_reg;
LEDR <= ledr_reg;
out1 <= out1_reg;
out2 <= out2_reg;
out3 <= out3_reg;
out4 <= out4_reg;
SDCARD_CLK <= spi_clk_out;
SDCARD_CMD <= spi_mosi;
spi_miso <= SDCARD_DAT; -- INPUT!! XXX
SDCARD_DAT3 <= spi_chip_select(0);
PAL <= '1'; -- TODO
USE_SDRAM <= '1'; -- should not be all or nothing. can mix for higher ram settings...
--USE_SDRAM <= '0'; -- should not be all or nothing. can mix for higher ram settings...
RAM_SELECT <= ram_select_reg;
VGA <= '1';
COMPOSITE_ON_HSYNC <= '0';
GPIO_ENABLE <= '0'; -- enable gpio - FIXME - esp carts!
ROM_SELECT <= "01";--rom_select_reg;
reset_n <= reset_n_reg; -- system reset or pll not locked
reset_zpu <= reset_zpu_reg; -- system_reset or pll not locked
reset_6502 <= reset_6502_cpu_reg; -- zpu software controlled
pause_6502 <= config_6502_reg(6); -- zpu software controlled
throttle_count_6502 <= config_6502_reg(5 downto 0); -- zpu software controlled
zpu_hex <= zpu_hex_reg;
sector <= sector_reg;
sector_request <= sector_request_reg;
end vhdl;

Also available in: Unified diff