Project

General

Profile

15 markw
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
1 markw
LIBRARY ieee;
USE ieee.std_logic_1164.all;
35 markw
use ieee.numeric_std.all;
1 markw
LIBRARY work;

15 markw
ENTITY atari800core_mcc IS
37 markw
GENERIC
(
VIDEO : integer; -- 1 = SVIDEO, 2 = VGA
54 markw
internal_rom : integer;
40 markw
internal_ram : integer;
ext_clock : integer
37 markw
);
1 markw
PORT
(
FPGA_CLK : IN STD_LOGIC;
35 markw
40 markw
-- For test bench
EXT_CLK_SDRAM : in std_logic_vector(ext_clock downto 1);
EXT_CLK : in std_logic_vector(ext_clock downto 1);
EXT_SDRAM_CLK : in std_logic_vector(ext_clock downto 1);
EXT_SVIDEO_DAC_CLK : in std_logic_vector(ext_clock downto 1);
EXT_SCANDOUBLE_CLK : in std_logic_vector(ext_clock downto 1);
EXT_PLL_LOCKED : in std_logic_vector(ext_clock downto 1);

1 markw
PS2K_CLK : IN STD_LOGIC;
PS2K_DAT : IN STD_LOGIC;
PS2M_CLK : IN STD_LOGIC;
PS2M_DAT : IN STD_LOGIC;

VGA_VS : OUT STD_LOGIC;
VGA_HS : OUT STD_LOGIC;
VGA_B : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
VGA_G : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
VGA_R : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

JOY1_n : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
JOY2_n : IN STD_LOGIC_VECTOR(5 DOWNTO 0);

AUDIO_L : OUT std_logic;
AUDIO_R : OUT std_logic;

SDRAM_BA : OUT STD_LOGIC_VECTOR(1 downto 0);
SDRAM_CS_N : OUT STD_LOGIC;
SDRAM_RAS_N : OUT STD_LOGIC;
SDRAM_CAS_N : OUT STD_LOGIC;
SDRAM_WE_N : OUT STD_LOGIC;
SDRAM_DQM_n : OUT STD_LOGIC_vector(1 downto 0);
SDRAM_CLK : OUT STD_LOGIC;
--SDRAM_CKE : OUT STD_LOGIC;
SDRAM_A : OUT STD_LOGIC_VECTOR(12 DOWNTO 0);
SDRAM_DQ : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);

SD_DAT0 : IN STD_LOGIC;
SD_CLK : OUT STD_LOGIC;
SD_CMD : OUT STD_LOGIC;
266 markw
SD_DAT3 : OUT STD_LOGIC;

USB2_P : INOUT STD_LOGIC;
USB2_N : INOUT STD_LOGIC
1 markw
);
15 markw
END atari800core_mcc;
1 markw
15 markw
ARCHITECTURE vhdl OF atari800core_mcc IS
1 markw
component hq_dac
port (
reset :in std_logic;
clk :in std_logic;
clk_ena : in std_logic;
pcm_in : in std_logic_vector(19 downto 0);
dac_out : out std_logic
);
end component;

35 markw
COMPONENT sdram_ctrl
port
(
--//--------------------
--// Clocks and reset --
--//--------------------
--// Global reset
rst : in std_logic;
--// Controller clock
clk : in std_logic;
--// Sequencer cycles
seq_cyc : in std_logic_vector(11 downto 0);
--// Sequencer phase
seq_ph : in std_logic;
--// Refresh cycle
refr_cyc : in std_logic;
--//------------------------
--// Access port #1 (CPU) --
--//------------------------
--// RAM select
ap1_ram_sel : in std_logic;
--// Address bus
ap1_address : in std_logic_vector(23 downto 1);
--// Read enable
ap1_rden : in std_logic;
--// Write enable
ap1_wren : in std_logic;
--// Byte enable
ap1_bena : in std_logic_vector(1 downto 0);
--// Data bus (read)
ap1_rddata : out std_logic_vector(15 downto 0);
--// Data bus (write)
ap1_wrdata : in std_logic_vector(15 downto 0);
--// Burst size
ap1_bst_siz : in std_logic_vector(2 downto 0);
--// Read burst active
ap1_rd_bst_act : out std_logic;
--// Write burst active
ap1_wr_bst_act : out std_logic;
--//------------------------
--// Access port #2 (GPU) --
--//------------------------
--// RAM select
ap2_ram_sel : in std_logic;
--// Address bus
ap2_address : in std_logic_vector(23 downto 1);
--// Read enable
ap2_rden : in std_logic;
--// Write enable
ap2_wren : in std_logic;
--// Byte enable
900 markw
Ap2_bena : in std_logic_vector(1 downto 0);
35 markw
--// Data bus (read)
ap2_rddata : out std_logic_vector(15 downto 0);
--// Data bus (write)
ap2_wrdata : in std_logic_vector(15 downto 0);
--// Burst size
ap2_bst_siz : in std_logic_vector(2 downto 0);
--// Read burst active
ap2_rd_bst_act : out std_logic;
--// Write burst active
ap2_wr_bst_act : out std_logic;
--//------------------------
--// Access port #3 (CTL) --
--//------------------------
--// RAM select
ap3_ram_sel : in std_logic;
--// Address bus
ap3_address : in std_logic_vector(23 downto 1);
--// Read enable
ap3_rden : in std_logic;
--// Write enable
ap3_wren : in std_logic;
--// Byte enable
ap3_bena : in std_logic_vector(1 downto 0);
--// Data bus (read)
ap3_rddata : out std_logic_vector(15 downto 0);
--// Data bus (write)
ap3_wrdata : in std_logic_vector(15 downto 0);
--// Burst size
ap3_bst_siz : in std_logic_vector(2 downto 0);
--// Read burst active
ap3_rd_bst_act : out std_logic;
--// Write burst active
ap3_wr_bst_act : out std_logic;
--//------------------------
--// SDRAM memory signals --
--//------------------------
--// SDRAM controller ready
sdram_rdy : out std_logic;
--// SDRAM chip select
sdram_cs_n : out std_logic;
--// SDRAM row address strobe
sdram_ras_n : out std_logic;
--// SDRAM column address strobe
sdram_cas_n : out std_logic;
--// SDRAM write enable
sdram_we_n : out std_logic;
--// SDRAM DQ masks
sdram_dqm_n : out std_logic_vector(1 downto 0);
--// SDRAM bank address
sdram_ba : out std_logic_vector(1 downto 0);
--// SDRAM address
sdram_addr : out std_logic_vector(11 downto 0);
--// SDRAM data
sdram_dq_oe : out std_logic;
sdram_dq_o : out std_logic_vector(15 downto 0);
sdram_dq_i : in std_logic_vector(15 downto 0)
);
END COMPONENT;

signal AUDIO_L_PCM : std_logic_vector(15 downto 0);
signal AUDIO_R_PCM : std_logic_vector(15 downto 0);

37 markw
signal VIDEO_VS : std_logic;
signal VIDEO_HS : std_logic;
346 markw
signal VIDEO_CS : std_logic;
920 markw
signal ATARI_COLOUR : std_logic_vector(7 downto 0);
37 markw
signal VIDEO_BLANK : std_logic;
signal VIDEO_BURST : std_logic;
signal VIDEO_START_OF_FIELD : std_logic;
signal VIDEO_ODD_LINE : std_logic;

35 markw
signal JOY1_IN_n : std_logic_vector(4 downto 0);
signal JOY2_IN_n : std_logic_vector(4 downto 0);
38 markw
285 markw
signal JOY1_USB : std_logic_vector(5 downto 0);
signal JOY2_USB : std_logic_vector(5 downto 0);
signal JOY1_USB_n : std_logic_vector(4 downto 0);
signal JOY2_USB_n : std_logic_vector(4 downto 0);

38 markw
signal PLL1_LOCKED : std_logic;
signal CLK_PLL1 : std_logic;
35 markw
signal RESET_n : std_logic;
signal PLL_LOCKED : std_logic;
signal CLK : std_logic;
signal CLK_SDRAM : std_logic;
1 markw
35 markw
-- SDRAM
278 markw
signal PREREG_SDRAM_REQUEST : std_logic;
signal PREREG_SDRAM_READ_ENABLE : STD_LOGIC;
signal PREREG_SDRAM_WRITE_ENABLE : std_logic;
signal PREREG_SDRAM_ADDR : STD_LOGIC_VECTOR(22 DOWNTO 0);
SIGNAL PREREG_SDRAM_DI : std_logic_vector(31 downto 0);
SIGNAL PREREG_SDRAM_WIDTH_32BIT_ACCESS : std_logic;
SIGNAL PREREG_SDRAM_WIDTH_16BIT_ACCESS : std_logic;
SIGNAL PREREG_SDRAM_WIDTH_8BIT_ACCESS : std_logic;
35 markw
signal SDRAM_REQUEST : std_logic;
signal SDRAM_READ_ENABLE : STD_LOGIC;
signal SDRAM_WRITE_ENABLE : std_logic;
signal SDRAM_ADDR : STD_LOGIC_VECTOR(22 DOWNTO 0);
SIGNAL SDRAM_DI : std_logic_vector(31 downto 0);
SIGNAL SDRAM_WIDTH_32BIT_ACCESS : std_logic;
SIGNAL SDRAM_WIDTH_16BIT_ACCESS : std_logic;
SIGNAL SDRAM_WIDTH_8BIT_ACCESS : std_logic;
278 markw
signal SDRAM_REQUEST_COMPLETE : std_logic;
35 markw
signal SDRAM_REFRESH : std_logic;
1 markw
35 markw
signal SYSTEM_RESET_REQUEST: std_logic;
1 markw
35 markw
signal seq_reg : std_logic_vector(11 downto 0);
signal seq_next : std_logic_vector(11 downto 0);

signal seq_ph_reg : std_logic;
signal seq_ph_next : std_logic;

signal ref_reg : std_logic;
signal ref_next : std_logic;
1 markw
35 markw
signal sdram_request_complete_next : std_logic;
signal sdram_request_complete_reg : std_logic;

signal sdram_request_next : std_logic;
signal sdram_request_reg : std_logic;

signal ram_di_next : std_logic_vector(15 downto 0);
signal ram_di_reg : std_logic_vector(15 downto 0);

signal ram_do_next : std_logic_vector(31 downto 0);
signal ram_do_reg : std_logic_vector(31 downto 0);

signal ram_do : std_logic_vector(15 downto 0);

signal ram_bena_next : std_logic_vector(1 downto 0);
signal ram_bena_reg : std_logic_vector(1 downto 0);

signal ram_rd_active : std_logic;
signal ram_wr_active : std_logic;

signal sdram_dq_oe : std_logic;
signal sdram_dq_o : std_logic_vector(15 downto 0);
signal sdram_dq_i : std_logic_vector(15 downto 0);

signal sdram_rdy : std_logic;
40 markw
signal sdram_reset_ctrl_n_next : std_logic;
signal sdram_reset_ctrl_n_reg : std_logic;
signal sdram_reset_n_next : std_logic;
signal sdram_reset_n_reg : std_logic;
35 markw
-- pokey keyboard
SIGNAL KEYBOARD_SCAN : std_logic_vector(5 downto 0);
SIGNAL KEYBOARD_RESPONSE : std_logic_vector(1 downto 0);
900 markw
signal atari_keyboard : std_logic_vector(63 downto 0);
35 markw
-- gtia consol keys
SIGNAL CONSOL_START : std_logic;
SIGNAL CONSOL_SELECT : std_logic;
SIGNAL CONSOL_OPTION : std_logic;
51 markw
SIGNAL FKEYS : std_logic_vector(11 downto 0);
35 markw
37 markw
-- scandoubler
signal scandouble_clk : std_logic;

signal half_scandouble_enable_reg : std_logic;
signal half_scandouble_enable_next : std_logic;

-- svideo
signal svideo_dac_clk : std_logic;

920 markw
signal chroma : std_logic_vector(7 downto 0);
signal luma : std_logic_vector(7 downto 0);
signal luma_sync_n : std_logic;
37 markw
45 markw
-- dma/virtual drive
signal DMA_ADDR_FETCH : std_logic_vector(23 downto 0);
signal DMA_WRITE_DATA : std_logic_vector(31 downto 0);
signal DMA_FETCH : std_logic;
signal DMA_32BIT_WRITE_ENABLE : std_logic;
signal DMA_16BIT_WRITE_ENABLE : std_logic;
signal DMA_8BIT_WRITE_ENABLE : std_logic;
signal DMA_READ_ENABLE : std_logic;
signal DMA_MEMORY_READY : std_logic;
signal DMA_MEMORY_DATA : std_logic_vector(31 downto 0);

signal ZPU_ADDR_ROM : std_logic_vector(15 downto 0);
signal ZPU_ROM_DATA : std_logic_vector(31 downto 0);

signal ZPU_OUT1 : std_logic_vector(31 downto 0);
signal ZPU_OUT2 : std_logic_vector(31 downto 0);
signal ZPU_OUT3 : std_logic_vector(31 downto 0);
signal ZPU_OUT4 : std_logic_vector(31 downto 0);
285 markw
signal ZPU_OUT5 : std_logic_vector(31 downto 0);
900 markw
signal ZPU_OUT6 : std_logic_vector(31 downto 0);
45 markw
signal zpu_pokey_enable : std_logic;
signal zpu_sio_txd : std_logic;
signal zpu_sio_rxd : std_logic;
signal zpu_sio_command : std_logic;
843 markw
SIGNAL ASIO_CLOCKOUT : std_logic;
45 markw
-- system control from zpu
signal ram_select : std_logic_vector(2 downto 0);
signal reset_atari : std_logic;
signal pause_atari : std_logic;
SIGNAL speed_6502 : std_logic_vector(5 downto 0);
933 markw
signal turbo_vblank_only : std_logic;
198 markw
signal emulated_cartridge_select: std_logic_vector(5 downto 0);
843 markw
signal key_type : std_logic;
signal atari800mode : std_logic;
45 markw
210 markw
-- turbo freezer!
signal freezer_enable : std_logic;
signal freezer_activate: std_logic;

266 markw
-- usb
signal CLK_USB : std_logic;
920 markw
signal USB_PLL_LOCKED : std_logic;
266 markw
signal USBWireVPin : std_logic;
signal USBWireVMin : std_logic;
signal USBWireVPout : std_logic;
signal USBWireVMout : std_logic;
signal USBWireOE_n : std_logic;

285 markw
signal PS2_KEYS : STD_LOGIC_VECTOR(511 downto 0);
signal PS2_KEYS_NEXT : STD_LOGIC_VECTOR(511 downto 0);

-- paddles
signal paddle_mode_next : std_logic;
signal paddle_mode_reg : std_logic;
signal JOY1X : std_logic_vector(7 downto 0);
signal JOY1Y : std_logic_vector(7 downto 0);
signal JOY2X : std_logic_vector(7 downto 0);
signal JOY2Y : std_logic_vector(7 downto 0);

900 markw
-- video settings
signal pal : std_logic;
signal scandouble : std_logic;
signal scanlines : std_logic;
signal csync : std_logic;
signal video_mode : std_logic_vector(2 downto 0);

1314 markw
-- pll switch
signal pll_reconfig_done : std_logic;

1 markw
BEGIN

278 markw
USB2_N <= USBWireVPout when USBWireOE_n='0' else 'Z';
USB2_P <= USBWireVMout when USBWireOE_n='0' else 'Z';
USBWireVPin <= USB2_N;
USBWireVMin <= USB2_P;
266 markw
1 markw
dac_left : hq_dac
port map
(
reset => not(reset_n),
clk => clk,
clk_ena => '1',
15 markw
pcm_in => AUDIO_L_PCM&"0000",
1 markw
dac_out => audio_l
);

dac_right : hq_dac
port map
(
reset => not(reset_n),
clk => clk,
clk_ena => '1',
15 markw
pcm_in => AUDIO_R_PCM&"0000",
1 markw
dac_out => audio_r
);

40 markw
gen_fake_pll : if ext_clock=1 generate
CLK_SDRAM <= EXT_CLK_SDRAM(1);
CLK <= EXT_CLK(1);
SDRAM_CLK <= EXT_CLK_SDRAM(1);
SVIDEO_DAC_CLK <= EXT_SVIDEO_DAC_CLK(1);
SCANDOUBLE_CLK <= EXT_SCANDOUBLE_CLK(1);
PLL_LOCKED <= EXT_PLL_LOCKED(1);
37 markw
end generate;
1 markw
266 markw
usb_pll : entity work.usbpll
PORT MAP(inclk0 => FPGA_CLK,
c0 => CLK_USB,
920 markw
locked => USB_PLL_LOCKED);
266 markw
40 markw
gen_real_pll : if ext_clock=0 generate

920 markw
pll_switcher : work.switch_pal_ntsc
GENERIC MAP
(
CLOCKS => 5,
SYNC_ON => 1
)
PORT MAP
(
RECONFIG_CLK => CLK_USB,
RESET_N => USB_PLL_LOCKED,

PAL => PAL,

INPUT_CLK => FPGA_CLK,
PLL_CLKS(0) => CLK_SDRAM,
PLL_CLKS(1) => CLK,
PLL_CLKS(2) => SDRAM_CLK,
PLL_CLKS(3) => open,
PLL_CLKS(4) => SCANDOUBLE_CLK,

1314 markw
RESET_N_OUT => RESET_N,
PLL_RECONFIG_DONE => PLL_RECONFIG_DONE
920 markw
);
SVIDEO_DAC_CLK <= SCANDOUBLE_CLK;
37 markw
end generate;

15 markw
JOY1_IN_N <= JOY1_n(4)&JOY1_n(0)&JOY1_n(1)&JOY1_n(2)&JOY1_n(3);
JOY2_IN_N <= JOY2_n(4)&JOY2_n(0)&JOY2_n(1)&JOY2_n(2)&JOY2_n(3);
1 markw
35 markw
--atari800xl : entity work.atari800core_helloworld
-- GENERIC MAP
-- (
-- cycle_length => 32,
-- video_bits => 4,
-- internal_ram => 16384
-- )
-- PORT MAP
-- (
-- CLK => clk,
-- RESET_N => reset_n,
--
-- VGA_VS => vga_vs_raw,
-- VGA_HS => vga_hs_raw,
-- VGA_B => vga_b,
-- VGA_G => vga_g,
-- VGA_R => vga_r,
--
-- AUDIO_L => AUDIO_L_PCM,
-- AUDIO_R => AUDIO_R_PCM,
--
-- JOY1_n => JOY1_IN_n,
-- JOY2_n => JOY2_IN_n,
--
-- PS2_CLK => ps2k_clk,
-- PS2_DAT => ps2k_dat,
--
-- PAL => '1'
-- );

-- PS2 to pokey
keyboard_map1 : entity work.ps2_to_atari800
285 markw
GENERIC MAP
(
ps2_enable => 1,
direct_enable => 1
)
35 markw
PORT MAP
(
CLK => clk,
1314 markw
RESET_N => reset_n and not(PLL_RECONFIG_DONE),
35 markw
PS2_CLK => ps2k_clk,
PS2_DAT => ps2k_dat,
285 markw
INPUT => zpu_out4,
843 markw
900 markw
ATARI_KEYBOARD_OUT => atari_keyboard,

843 markw
KEY_TYPE => key_type,
35 markw
KEYBOARD_SCAN => KEYBOARD_SCAN,
KEYBOARD_RESPONSE => KEYBOARD_RESPONSE,

CONSOL_START => CONSOL_START,
CONSOL_SELECT => CONSOL_SELECT,
51 markw
CONSOL_OPTION => CONSOL_OPTION,
35 markw
210 markw
FKEYS => FKEYS,
285 markw
FREEZER_ACTIVATE => freezer_activate,

PS2_KEYS_NEXT_OUT => ps2_keys_next,
PS2_KEYS => ps2_keys
35 markw
);

285 markw
-- hack for paddles
process(clk,RESET_N)
begin
if (RESET_N = '0') then
paddle_mode_reg <= '0';
elsif (clk'event and clk='1') then
paddle_mode_reg <= paddle_mode_next;
end if;
end process;

JOY1_USB <= zpu_out2(5 downto 4)&zpu_out2(0)&zpu_out2(1)&zpu_out2(2)&zpu_out2(3);
JOY2_USB <= zpu_out3(5 downto 4)&zpu_out3(0)&zpu_out3(1)&zpu_out3(2)&zpu_out3(3);

JOY1X <= zpu_out5(7 downto 0);
JOY1Y <= zpu_out5(15 downto 8);
JOY2X <= zpu_out5(23 downto 16);
JOY2Y <= zpu_out5(31 downto 24);

process(paddle_mode_reg, joy1_usb, joy2_usb)
begin
joy1_usb_n <= (others=>'1');
joy2_usb_n <= (others=>'1');

if (paddle_mode_reg = '1') then
joy1_usb_n <= "111"&not(joy1_usb(4)&joy1_usb(5)); --FLRDU
joy2_usb_n <= "111"&not(joy2_usb(4)&joy2_usb(5));
else
joy1_usb_n <= not(joy1_usb(4 downto 0));
joy2_usb_n <= not(joy2_usb(4 downto 0));
end if;
end process;

paddle_mode_next <= paddle_mode_reg xor (not(ps2_keys(16#11F#)) and ps2_keys_next(16#11F#)); -- left windows key

390 markw
return_to_boot_menu : entity work.delayed_reconfig
PORT MAP
(
CLK_5MHZ => FPGA_CLK,
RESET_N => RESET_N,
RECONFIG_BUTTON => FKEYS(6)
);

35 markw
atarixl_simple_sdram1 : entity work.atari800core_simple_sdram
15 markw
GENERIC MAP
(
35 markw
cycle_length => 16,
54 markw
internal_rom => internal_rom,
37 markw
internal_ram => internal_ram,
video_bits => 8,
900 markw
palette => 0
15 markw
)
PORT MAP
(
35 markw
CLK => CLK,
--RESET_N => RESET_N and SDRAM_RESET_N and not(SYSTEM_RESET_REQUEST),
40 markw
RESET_N => RESET_N and SDRAM_RESET_N_REG,
1 markw
37 markw
VIDEO_VS => VIDEO_VS,
VIDEO_HS => VIDEO_HS,
346 markw
VIDEO_CS => VIDEO_CS,
920 markw
VIDEO_B => ATARI_COLOUR,
VIDEO_G => open,
VIDEO_R => open,
37 markw
VIDEO_BLANK =>VIDEO_BLANK,
VIDEO_BURST =>VIDEO_BURST,
VIDEO_START_OF_FIELD =>VIDEO_START_OF_FIELD,
VIDEO_ODD_LINE =>VIDEO_ODD_LINE,
1 markw
15 markw
AUDIO_L => AUDIO_L_PCM,
AUDIO_R => AUDIO_R_PCM,
1 markw
285 markw
JOY1_n => JOY1_IN_n and JOY1_USB_n,
JOY2_n => JOY2_IN_n and JOY2_USB_n,
1 markw
285 markw
PADDLE0 => signed(joy1x),
PADDLE1 => signed(joy1y),
PADDLE2 => signed(joy2x),
PADDLE3 => signed(joy2y),


35 markw
KEYBOARD_RESPONSE => KEYBOARD_RESPONSE,
KEYBOARD_SCAN => KEYBOARD_SCAN,
1 markw
45 markw
SIO_COMMAND => zpu_sio_command,
SIO_RXD => zpu_sio_txd,
SIO_TXD => zpu_sio_rxd,
843 markw
SIO_CLOCKOUT => ASIO_CLOCKOUT,
35 markw
CONSOL_OPTION => CONSOL_OPTION,
CONSOL_SELECT => CONSOL_SELECT,
CONSOL_START => CONSOL_START,

278 markw
SDRAM_REQUEST => PREREG_SDRAM_REQUEST,
35 markw
SDRAM_REQUEST_COMPLETE => SDRAM_REQUEST_COMPLETE,
278 markw
SDRAM_READ_ENABLE => PREREG_SDRAM_READ_ENABLE,
SDRAM_WRITE_ENABLE => PREREG_SDRAM_WRITE_ENABLE,
SDRAM_ADDR => PREREG_SDRAM_ADDR,
35 markw
SDRAM_DO => ram_do_reg,
278 markw
SDRAM_DI => PREREG_SDRAM_DI,
SDRAM_32BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_32bit_ACCESS,
SDRAM_16BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_16bit_ACCESS,
SDRAM_8BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_8bit_ACCESS,
37 markw
SDRAM_REFRESH => SDRAM_REFRESH,
35 markw
45 markw
DMA_FETCH => dma_fetch,
DMA_READ_ENABLE => dma_read_enable,
DMA_32BIT_WRITE_ENABLE => dma_32bit_write_enable,
DMA_16BIT_WRITE_ENABLE => dma_16bit_write_enable,
DMA_8BIT_WRITE_ENABLE => dma_8bit_write_enable,
DMA_ADDR => dma_addr_fetch,
DMA_WRITE_DATA => dma_write_data,
MEMORY_READY_DMA => dma_memory_ready,
DMA_MEMORY_DATA => dma_memory_data,
35 markw
45 markw
RAM_SELECT => ram_select,
37 markw
PAL => PAL,
45 markw
HALT => pause_atari,
920 markw
ATARI800MODE => atari800mode,
198 markw
THROTTLE_COUNT_6502 => speed_6502,
933 markw
TURBO_VBLANK_ONLY => turbo_vblank_only,
210 markw
emulated_cartridge_select => emulated_cartridge_select,
freezer_enable => freezer_enable,
freezer_activate => freezer_activate
1 markw
);

40 markw
process(clk_sdram,sdram_reset_ctrl_n_reg)
35 markw
begin
40 markw
if (sdram_reset_ctrl_n_reg='0') then
278 markw
seq_reg <= "010000000000";
40 markw
seq_ph_reg <= '1';
35 markw
ref_reg <= '0';

ram_do_reg <= (others=>'0');
ram_di_reg <= (others=>'0');
ram_bena_reg <= (others=>'0');
sdram_request_complete_reg <= '0';
sdram_request_reg <= '0';
elsif (clk_sdram'event and clk_sdram = '1') then
seq_reg <= seq_next;
seq_ph_reg <= seq_ph_next;
ref_reg <= ref_next;

ram_do_reg <= ram_do_next;
ram_di_reg <= ram_di_next;
ram_bena_reg <= ram_bena_next;
sdram_request_complete_reg <= sdram_request_complete_next;
sdram_request_reg <= sdram_request_next;
end if;
end process;

40 markw
process(clk,reset_n)
begin
if (reset_n='0') then
sdram_reset_n_reg <= '0';
sdram_reset_ctrl_n_reg <= '0';
elsif (clk'event and clk = '1') then
sdram_reset_n_reg <= sdram_reset_n_next;
sdram_reset_ctrl_n_reg <= reset_n;
end if;
end process;

35 markw
-- Generate sdram sequence
process(seq_reg, seq_ph_reg, ref_reg)
begin
seq_next <= seq_reg(10 downto 0)&seq_reg(11);
seq_ph_next <= seq_ph_reg;
ref_next <= ref_reg;
40 markw
if (seq_reg(11) = '1') then
35 markw
seq_ph_next <= not(seq_ph_reg);
ref_next <= not(ref_reg);
end if;
end process;

45 markw
process(seq_reg, seq_next, sdram_rdy, sdram_reset_n_reg, reset_atari)
40 markw
begin
sdram_reset_n_next <= sdram_reset_n_reg;
278 markw
if (sdram_rdy = '1' and seq_next(7)='1' and seq_reg(7)='0') then
40 markw
sdram_reset_n_next <= '1';
end if;
45 markw
if (reset_atari = '1') then
sdram_reset_n_next <= '0';
end if;
40 markw
end process;

278 markw
-- register sdram request on the falling edge, 1/3 timing not enough, but 1/2 timing should be... This pushes back request 1 clock cycle. Result can also be clocking on the falling edge!
process(clk,reset_n)
begin
if (reset_n='0') then
SDRAM_REQUEST <= '0';
SDRAM_READ_ENABLE <= '0';
SDRAM_WRITE_ENABLE <= '0';
SDRAM_ADDR <= (others=>'0');
SDRAM_DI <= (others=>'0');
SDRAM_WIDTH_32BIT_ACCESS <= '0';
SDRAM_WIDTH_16BIT_ACCESS <= '0';
SDRAM_WIDTH_8BIT_ACCESS <= '0';
elsif(clk'event and clk='0') then -- FALLING EDGE
SDRAM_REQUEST <= PREREG_SDRAM_REQUEST;
SDRAM_READ_ENABLE <= PREREG_SDRAM_READ_ENABLE;
SDRAM_WRITE_ENABLE <= PREREG_SDRAM_WRITE_ENABLE;
SDRAM_ADDR <= PREREG_SDRAM_ADDR;
SDRAM_DI <= PREREG_SDRAM_DI;
SDRAM_WIDTH_32BIT_ACCESS <= PREREG_SDRAM_WIDTH_32BIT_ACCESS;
SDRAM_WIDTH_16BIT_ACCESS <= PREREG_SDRAM_WIDTH_16BIT_ACCESS;
SDRAM_WIDTH_8BIT_ACCESS <= PREREG_SDRAM_WIDTH_8BIT_ACCESS;
end if;
end process;

35 markw
-- Adapt SDRAM
process(sdram_request_reg, sdram_request, sdram_request_complete_reg, ram_do_reg, seq_reg, ram_do, ram_rd_active, ram_wr_active, SDRAM_WIDTH_8BIT_ACCESS, SDRAM_WRITE_ENABLE, SDRAM_READ_ENABLE, SDRAM_DI, SDRAM_ADDR)
begin
278 markw
sdram_request_next <= (sdram_request_reg or sdram_request) and not(sdram_request_complete_reg);
35 markw
sdram_request_complete_next <= sdram_request_complete_reg;
ram_bena_next <= "00";
ram_di_next <= (others=>'0');
ram_do_next <= ram_do_reg;

case seq_reg is
when "000000000001" =>
-- nop
when "000000000010" => -- write data from next...
if (SDRAM_WRITE_ENABLE = '1') then
if (SDRAM_WIDTH_8BIT_ACCESS = '1') then
ram_di_next <= SDRAM_DI(7 downto 0)&SDRAM_DI(7 downto 0);
ram_bena_next <= SDRAM_ADDR(0)&not(SDRAM_ADDR(0));
else
ram_di_next <= SDRAM_DI(15 downto 0);
ram_bena_next <= "11";
end if;
end if;
when "000000000100" =>
if (SDRAM_WRITE_ENABLE = '1') then
if (SDRAM_WIDTH_8BIT_ACCESS = '1') then
ram_di_next <= (others=>'0');
else
45 markw
ram_di_next <= SDRAM_DI(31 downto 16);
35 markw
ram_bena_next <= "11";
end if;
end if;
if ((ram_wr_active)='1') then
sdram_request_complete_next <= '1';
sdram_request_next <= '0';
end if;
when "000000001000" =>
-- nop
when "000000010000" =>
-- nop
when "000000100000" =>
278 markw
sdram_request_complete_next <= '0';
35 markw
-- nop
when "000001000000" =>
if (SDRAM_READ_ENABLE = '1') then
if (SDRAM_WIDTH_8BIT_ACCESS = '1') then
if (SDRAM_ADDR(0) = '0') then
ram_do_next(15 downto 0) <= ram_do(7 downto 0)&ram_do(7 downto 0);
else
ram_do_next(15 downto 0) <= ram_do(15 downto 8)&ram_do(15 downto 8);
end if;
else
ram_do_next(15 downto 0) <= ram_do;
end if;
end if;
when "000010000000" =>
if (SDRAM_READ_ENABLE = '1') then
if (SDRAM_WIDTH_8BIT_ACCESS = '1') then
ram_do_next(31 downto 16) <= (others=>'0');
else
ram_do_next(31 downto 16) <= ram_do;
end if;
end if;
if ((ram_rd_active)='1') then
sdram_request_complete_next <= '1';
sdram_request_next <= '0';
end if;
when "000100000000" =>
-- nop
when "001000000000" =>
-- nop
when "010000000000" =>
-- nop
when "100000000000" =>
278 markw
sdram_request_complete_next <= '0';
35 markw
-- nop
when others =>
-- never
end case;
end process;

SDRAM_REQUEST_COMPLETE <= SDRAM_REQUEST_COMPLETE_REG;
sdram_controller : sdram_ctrl
PORT MAP
(
CLK => CLK_SDRAM,
40 markw
rst => not(sdram_reset_ctrl_n_reg),
35 markw
seq_cyc => seq_reg(11 downto 0),
seq_ph => seq_ph_reg,
37 markw
--refr_cyc => ref_reg,
refr_cyc => SDRAM_REFRESH,
35 markw
40 markw
ap1_ram_sel => SDRAM_REQUEST_NEXT,
35 markw
ap1_address => '0'&SDRAM_ADDR(22 downto 1),
ap1_rden => SDRAM_READ_ENABLE,
ap1_wren => SDRAM_WRITE_ENABLE,
ap1_bena => ram_bena_reg,
ap1_rddata => ram_do,
ap1_wrdata => ram_di_reg,
ap1_bst_siz => "001",
ap1_rd_bst_act => ram_rd_active,
ap1_wr_bst_act => ram_wr_active,

ap2_ram_sel => '0',
ap2_address => "00000000000000000000000",
ap2_rden => '0',
ap2_wren => '0',
ap2_bena => "11",
ap2_rddata => open,
ap2_wrdata => X"0000",
ap2_bst_siz => "111",
ap2_rd_bst_act => open,
ap2_wr_bst_act => open,

ap3_ram_sel => '0',
ap3_address => "00000000000000000000000",
ap3_rden => '0',
ap3_wren => '0',
ap3_bena => "11",
ap3_rddata => open,
ap3_wrdata => X"0000",
ap3_bst_siz => "111",
ap3_rd_bst_act => open,
ap3_wr_bst_act => open,

sdram_rdy => sdram_rdy,
sdram_cs_n => sdram_cs_n,
sdram_ras_n => sdram_ras_n,
sdram_cas_n => sdram_cas_n,
sdram_we_n => sdram_we_n,
sdram_dqm_n => sdram_dqm_n,
sdram_ba => sdram_ba,
sdram_addr => sdram_a(11 downto 0),
sdram_dq_oe => sdram_dq_oe,
sdram_dq_o => sdram_dq_o,
sdram_dq_i => sdram_dq_i
);

sdram_dq <= sdram_dq_o when sdram_dq_oe='1' else (others=>'Z');
sdram_dq_i <= sdram_dq;
sdram_a(12) <= '1';
37 markw
-- Video options
gen_video_vga : if video=2 generate
900 markw
process(scandouble_clk,sdram_reset_n_reg)
begin
if (sdram_reset_n_reg='0') then
half_scandouble_enable_reg <= '0';
elsif (scandouble_clk'event and scandouble_clk='1') then
half_scandouble_enable_reg <= half_scandouble_enable_next;
end if;
end process;
37 markw
900 markw
half_scandouble_enable_next <= not(half_scandouble_enable_reg);
37 markw
900 markw
scandoubler1: entity work.scandoubler
PORT MAP
(
CLK => SCANDOUBLE_CLK,
RESET_N => sdram_reset_n_reg,

VGA => scandouble,
COMPOSITE_ON_HSYNC => csync,
37 markw
900 markw
colour_enable => half_scandouble_enable_reg,
doubled_enable => '1',
scanlines_on => scanlines,

-- GTIA interface
pal => PAL,
920 markw
colour_in => ATARI_COLOUR,
900 markw
vsync_in => VIDEO_VS,
hsync_in => VIDEO_HS,
csync_in => VIDEO_CS,

-- TO TV...
R => VGA_R,
G => VGA_G,
B => VGA_B,

VSYNC => VGA_VS,
HSYNC => VGA_HS
);
37 markw
end generate;

gen_video_svideo: if video=1 generate

920 markw
svideo : entity work.svideo_gtia
37 markw
PORT MAP
920 markw
(
CLK => SVIDEO_DAC_CLK, -- 56.75MHz PAL, 57.272727... NTSC
RESET_N => RESET_N,

brightness => ATARI_COLOUR(3 downto 0),
hue => ATARI_COLOUR(7 downto 4),
burst => VIDEO_BURST,
37 markw
blank => VIDEO_BLANK,
920 markw
sof => VIDEO_VS,
346 markw
csync_n => not(VIDEO_CS),
920 markw
vpos_lsb => VIDEO_ODD_LINE,
pal => PAL,

composite => '1',
1 markw
920 markw
chroma => chroma,
luma => luma,
luma_sync_n => luma_sync_n -- TODO, need to adjust svideo_gtia to work without this!
37 markw
);
920 markw
process(luma, luma_sync_n)
begin
if (luma_sync_n='0') then
VGA_B <= (others=>'0');
VGA_G <= (others=>'0');
else
VGA_B <= luma(7 downto 4);
VGA_G <= luma(3 downto 0);
end if;
end process;
37 markw
920 markw
VGA_R <= chroma(7 downto 4);
VGA_HS <= chroma(3);
VGA_VS <= chroma(2);

37 markw
end generate;

45 markw
zpu: entity work.zpucore
GENERIC MAP
(
59 markw
platform => 1,
278 markw
spi_clock_div => 1, -- 28MHz/2. Max for SD cards is 25MHz...
memory => 8192,
858 markw
usb => 1,
nMHz_clock_div => 48
45 markw
)
PORT MAP
(
-- standard...
CLK => CLK,
RESET_N => RESET_N and sdram_rdy,

-- dma bus master (with many waitstates...)
ZPU_ADDR_FETCH => dma_addr_fetch,
ZPU_DATA_OUT => dma_write_data,
ZPU_FETCH => dma_fetch,
ZPU_32BIT_WRITE_ENABLE => dma_32bit_write_enable,
ZPU_16BIT_WRITE_ENABLE => dma_16bit_write_enable,
ZPU_8BIT_WRITE_ENABLE => dma_8bit_write_enable,
ZPU_READ_ENABLE => dma_read_enable,
ZPU_MEMORY_READY => dma_memory_ready,
ZPU_MEMORY_DATA => dma_memory_data,

-- rom bus master
-- data on next cycle after addr
ZPU_ADDR_ROM => zpu_addr_rom,
ZPU_ROM_DATA => zpu_rom_data,

-- spi master
-- Too painful to bit bang spi from zpu, so we have a hardware master in here
843 markw
ZPU_SPI_DI => sd_dat0,
ZPU_SPI_CLK => sd_clk,
ZPU_SPI_DO => sd_cmd,
ZPU_SPI_SELECT0 => sd_dat3,
ZPU_SPI_SELECT1 => open,
45 markw
-- SIO
-- Ditto for speaking to Atari, we have a built in Pokey
ZPU_POKEY_ENABLE => zpu_pokey_enable,
ZPU_SIO_TXD => zpu_sio_txd,
ZPU_SIO_RXD => zpu_sio_rxd,
ZPU_SIO_COMMAND => zpu_sio_command,
843 markw
ZPU_SIO_CLK => ASIO_CLOCKOUT,
45 markw
-- external control
-- switches etc. sector DMA blah blah.
285 markw
ZPU_IN1 => X"000"&
900 markw
"00"&
(atari_keyboard(28))&ps2_keys(16#5A#)&ps2_keys(16#174#)&ps2_keys(16#16B#)&ps2_keys(16#172#)&ps2_keys(16#175#)& -- (esc)FLRDU
285 markw
FKEYS,
45 markw
ZPU_IN2 => X"00000000",
900 markw
ZPU_IN3 => atari_keyboard(31 downto 0),
ZPU_IN4 => atari_keyboard(63 downto 32),
45 markw
-- ouputs - e.g. Atari system control, halt, throttle, rom select
ZPU_OUT1 => zpu_out1,
285 markw
ZPU_OUT2 => zpu_out2, --joy0
ZPU_OUT3 => zpu_out3, --joy1
ZPU_OUT4 => zpu_out4, --keyboard
ZPU_OUT5 => zpu_out5, --analog stick
900 markw
ZPU_OUT6 => zpu_out6, --video mode
278 markw
-- USB host
858 markw
CLK_nMHz => CLK_USB,
278 markw
CLK_USB => CLK_USB,

USBWireVPin(0) => USBWireVPin,
USBWireVMin(0) => USBWireVMin,
USBWireVPout(0) => USBWireVPout,
USBWireVMout(0) => USBWireVMout,
USBWireOE_n(0) => USBWireOE_n
45 markw
);

pause_atari <= zpu_out1(0);
reset_atari <= zpu_out1(1);
speed_6502 <= zpu_out1(7 downto 2);
ram_select <= zpu_out1(10 downto 8);
843 markw
atari800mode <= zpu_out1(11);
198 markw
emulated_cartridge_select <= zpu_out1(22 downto 17);
210 markw
freezer_enable <= zpu_out1(25);
843 markw
key_type <= zpu_out1(26);
45 markw
933 markw
turbo_vblank_only <= zpu_out1(31);

900 markw
video_mode <= zpu_out6(2 downto 0);
PAL <= zpu_out6(4);
scanlines <= zpu_out6(5);
csync <= zpu_out6(6);

process(video_mode)
begin
SCANDOUBLE <= '0';

-- original RGB
-- scandoubled RGB (works on some vga devices...)
-- svideo
-- hdmi with audio (and vga exact mode...)
-- dvi (i.e. no preamble or audio) (and vga exact mode...)
-- vga exact mode (hdmi off)
-- composite (todo firmware...)

case video_mode is
when "000" =>
when "001" =>
SCANDOUBLE <= '1';
when "010" => -- svideo
-- not supported -- TODO: need to provide a bitmask to firmware on what modes we support I think? Then can handle this in a better way!
when "011" =>
-- not supported
when "100" =>
-- not supported
when "101" =>
-- not supported
when "110" => -- composite
-- not supported

when others =>
end case;
end process;

864 markw
zpu_rom1: entity work.zpu_rom
45 markw
port map(
clock => clk,
900 markw
address => zpu_addr_rom(15 downto 2),
45 markw
q => zpu_rom_data
);

enable_179_clock_div_zpu_pokey : entity work.enable_divider
generic map (COUNT=>16) -- cycle_length
port map(clk=>clk,reset_n=>reset_n,enable_in=>'1',enable_out=>zpu_pokey_enable);

15 markw
END vhdl;