|
---------------------------------------------------------------------------
|
|
-- (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.
|
|
---------------------------------------------------------------------------
|
|
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.all;
|
|
use IEEE.STD_LOGIC_MISC.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
LIBRARY work;
|
|
|
|
-- There is a higher level that just wires up internal ROM/RAM/joysticks to demonstrate how to use this
|
|
-- Also see board specific top levels
|
|
ENTITY atari800xl IS
|
|
PORT
|
|
(
|
|
CLK : IN STD_LOGIC; -- cycle_length*1.79MHz
|
|
RESET_N : IN STD_LOGIC;
|
|
|
|
-- VIDEO OUT - PAL/NTSC, original Atari timings approx (may be higher res)
|
|
VIDEO_VS : OUT STD_LOGIC;
|
|
VIDEO_HS : OUT STD_LOGIC;
|
|
VIDEO_CS : OUT STD_LOGIC;
|
|
COLOUR : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
VIDEO_BLANK : out std_logic;
|
|
VIDEO_BURST : out std_logic;
|
|
VIDEO_START_OF_FIELD : out std_logic;
|
|
VIDEO_ODD_LINE : out std_logic;
|
|
|
|
-- AUDIO OUT - Pokey/GTIA 1-bit and Covox all mixed
|
|
AUDIO_L : OUT std_logic_vector(15 downto 0);
|
|
AUDIO_R : OUT std_logic_vector(15 downto 0);
|
|
SIO_AUDIO : IN std_logic_vector(7 downto 0);
|
|
|
|
-- PIA
|
|
CA1_IN : IN STD_LOGIC; -- SIO Proceed
|
|
CB1_IN : IN STD_LOGIC; -- SIO IRQ
|
|
CA2_IN : IN STD_LOGIC; -- SIO Motor control
|
|
CA2_OUT : OUT STD_LOGIC;
|
|
CA2_DIR_OUT: OUT STD_LOGIC; -- 1=output mode
|
|
CB2_IN: IN STD_LOGIC;
|
|
CB2_OUT : OUT STD_LOGIC; -- SIO Command
|
|
CB2_DIR_OUT: OUT STD_LOGIC; -- 1=output mode
|
|
PORTA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- For joystick
|
|
PORTA_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
PORTA_DIR_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
PORTB_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- For bank switching on XL/XE, for joystick on 800
|
|
PORTB_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
PORTB_DIR_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
|
|
-- Pokey keyboard matrix
|
|
-- Standard component available to connect this to PS2
|
|
KEYBOARD_RESPONSE : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
|
|
KEYBOARD_SCAN : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
|
|
|
|
-- Pokey pots
|
|
POT_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
POT_RESET : OUT STD_LOGIC;
|
|
|
|
-- CARTRIDGE ACCESS
|
|
-- (R/W/DO on PBI)
|
|
CART_RD4 : in STD_LOGIC;
|
|
CART_RD5 : in STD_LOGIC;
|
|
CART_S4_n : out STD_LOGIC;
|
|
CART_S5_N : out STD_LOGIC;
|
|
CART_CCTL_N : out std_logic;
|
|
|
|
-- PBI
|
|
PBI_MPD_N : in STD_LOGIC;
|
|
PBI_REF_N_IN : in STD_LOGIC;
|
|
PBI_EXTSEL_N : in STD_LOGIC;
|
|
PBI_CAS : out STD_LOGIC;
|
|
PBI_RAS : out STD_LOGIC;
|
|
PBI_CAS_INHIBIT : out STD_LOGIC;
|
|
PBI_REF_N_OUT : out STD_LOGIC;
|
|
PBI_IRQ_N : IN STD_LOGIC := '1';
|
|
|
|
-- SIO
|
|
SIO_RXD : in std_logic;
|
|
SIO_TXD : out std_logic;
|
|
SIO_CLOCKIN : in std_logic :='1';
|
|
SIO_CLOCKOUT : out std_logic;
|
|
-- SIO_COMMAND_TX - see PIA PB2
|
|
-- TODO CLOCK IN/CLOCK OUT (unused almost everywhere...)
|
|
|
|
-- GTIA consol
|
|
CONSOL_OPTION : IN STD_LOGIC;
|
|
CONSOL_SELECT : IN STD_LOGIC;
|
|
CONSOL_START : IN STD_LOGIC;
|
|
GTIA_TRIG : IN STD_LOGIC_VECTOR(3 downto 0);
|
|
|
|
-- ANTIC lightpen
|
|
ANTIC_LIGHTPEN : IN std_logic;
|
|
ANTIC_REFRESH : out STD_LOGIC -- 1 'original' cycle high when antic doing refresh cycle...
|
|
);
|
|
END atari800xl;
|
|
|
|
ARCHITECTURE bdf_type OF atari800xl IS
|
|
|
|
-- BUS
|
|
SIGNAL BUS_ADDR : STD_LOGIC_VECTOR(15 downto 0);
|
|
SIGNAL BUS_DATA : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
signal IO_DO : std_logic_vector(7 downto 0);
|
|
signal PBI_DO : std_logic_vector(7 downto 0);
|
|
signal BASIC_DO : std_logic_vector(7 downto 0);
|
|
signal OS_DO : std_logic_vector(7 downto 0);
|
|
signal RAM_DO : std_logic_vector(7 downto 0);
|
|
|
|
-- ANTIC
|
|
SIGNAL ANTIC_ADDR : STD_LOGIC_VECTOR(15 DOWNTO 0);
|
|
SIGNAL ANTIC_AN : STD_LOGIC_VECTOR(2 DOWNTO 0);
|
|
SIGNAL ANTIC_COLOUR_CLOCK_OUT : STD_LOGIC;
|
|
SIGNAL ANTIC_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
SIGNAL ANTIC_FETCH : STD_LOGIC;
|
|
SIGNAL ANTIC_HIGHRES_COLOUR_CLOCK_OUT : STD_LOGIC;
|
|
SIGNAL ANTIC_ORIGINAL_COLOUR_CLOCK_OUT : STD_LOGIC;
|
|
SIGNAL ANTIC_RDY : STD_LOGIC;
|
|
SIGNAL BREAK_PRESSED : STD_LOGIC;
|
|
signal hcount_temp : std_logic_vector(7 downto 0);
|
|
signal vcount_temp : std_logic_vector(8 downto 0);
|
|
signal ANTIC_REFRESH_CYCLE : STD_LOGIC;
|
|
|
|
-- GTIA
|
|
SIGNAL GTIA_SOUND : STD_LOGIC;
|
|
SIGNAL CONSOL_OUT : STD_LOGIC_VECTOR(3 downto 0);
|
|
SIGNAL CONSOL_IN : STD_LOGIC_VECTOR(3 downto 0);
|
|
SIGNAL GTIA_TRIG_MERGED : STD_LOGIC_VECTOR(3 downto 0);
|
|
|
|
SIGNAL GTIA_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
|
|
-- CPU
|
|
SIGNAL CPU_6502_RESET : STD_LOGIC;
|
|
SIGNAL CPU_ADDR : STD_LOGIC_VECTOR(15 DOWNTO 0);
|
|
SIGNAL CPU_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
SIGNAL CPU_FETCH : STD_LOGIC;
|
|
SIGNAL IRQ_n : STD_LOGIC;
|
|
SIGNAL NMI_n : STD_LOGIC;
|
|
SIGNAL R_W_N : STD_LOGIC;
|
|
|
|
-- POKEY
|
|
SIGNAL POKEY_IRQ : STD_LOGIC;
|
|
|
|
SIGNAL POKEY_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
signal POKEY1_CHANNEL0 : std_logic_vector(3 downto 0);
|
|
signal POKEY1_CHANNEL1 : std_logic_vector(3 downto 0);
|
|
signal POKEY1_CHANNEL2 : std_logic_vector(3 downto 0);
|
|
signal POKEY1_CHANNEL3 : std_logic_vector(3 downto 0);
|
|
|
|
-- PIA
|
|
SIGNAL PIA_DO : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
SIGNAL PIA_IRQA : STD_LOGIC;
|
|
SIGNAL PIA_IRQB : STD_LOGIC;
|
|
SIGNAL PORTB_OUT_INT : STD_LOGIC_VECTOR(7 downto 0);
|
|
SIGNAL PORTB_OPTIONS : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
-- cart
|
|
signal cart_trig3_out: std_logic;
|
|
|
|
-- timing
|
|
signal shift_cpu_run_next : std_logic_vector(31 downto 0);
|
|
signal shift_cpu_run_reg : std_logic_vector(31 downto 0);
|
|
signal run_system : std_logic;
|
|
signal run_cpu : std_logic;
|
|
|
|
-- mmu
|
|
signal io_select : std_logic_vector(7 downto 0);
|
|
signal CS_GTIA : std_logic;
|
|
signal CS_D1 : std_logic;
|
|
signal CS_POKEY : std_logic;
|
|
signal CS_PIA : std_logic;
|
|
signal CS_ANTIC : std_logic;
|
|
signal CS_D5 : std_logic;
|
|
signal CS_D6 : std_logic;
|
|
signal CS_D7 : std_logic;
|
|
|
|
signal ANTIC_WRITE_ENABLE : std_logic;
|
|
signal POKEY_WRITE_ENABLE : std_logic;
|
|
signal PIA_WRITE_ENABLE : std_logic;
|
|
signal PIA_READ_ENABLE : std_logic;
|
|
signal GTIA_WRITE_ENABLE : std_logic;
|
|
signal RAM_WRITE_ENABLE : std_logic;
|
|
|
|
|
|
signal CS_BASIC : std_logic;
|
|
signal CS_IO : std_logic;
|
|
signal CS_OS : std_logic;
|
|
signal CAS_INHIBIT : std_logic;
|
|
signal REF_N : std_logic;
|
|
|
|
signal PAL : std_logic;
|
|
|
|
BEGIN
|
|
|
|
PAL <= '1';
|
|
|
|
CPU_6502_RESET <= NOT(RESET_N);
|
|
cpu6502 : entity work.cpu
|
|
PORT MAP(CLK => CLK,
|
|
RESET => CPU_6502_RESET,
|
|
ENABLE => RESET_N,
|
|
IRQ_n => IRQ_n,
|
|
NMI_n => NMI_n,
|
|
MEMORY_READY => '1',
|
|
THROTTLE => run_cpu,
|
|
RDY => ANTIC_RDY,
|
|
DI => BUS_DATA(7 DOWNTO 0),
|
|
R_W_n => R_W_N,
|
|
CPU_FETCH => CPU_FETCH,
|
|
A => CPU_ADDR,
|
|
DO => CPU_DO);
|
|
|
|
antic1 : entity work.antic
|
|
GENERIC MAP(cycle_length => 32)
|
|
PORT MAP(CLK => CLK,
|
|
WR_EN => ANTIC_WRITE_ENABLE,
|
|
RESET_N => RESET_N,
|
|
MEMORY_READY_ANTIC => RUN_CPU,
|
|
MEMORY_READY_CPU => RUN_CPU,
|
|
ANTIC_ENABLE_179 => RUN_CPU,
|
|
PAL => PAL,
|
|
lightpen => ANTIC_LIGHTPEN,
|
|
ADDR => BUS_ADDR(3 DOWNTO 0),
|
|
CPU_DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
MEMORY_DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
NMI_N_OUT => NMI_n,
|
|
ANTIC_READY => ANTIC_RDY,
|
|
COLOUR_CLOCK_ORIGINAL_OUT => ANTIC_ORIGINAL_COLOUR_CLOCK_OUT,
|
|
COLOUR_CLOCK_OUT => ANTIC_COLOUR_CLOCK_OUT,
|
|
HIGHRES_COLOUR_CLOCK_OUT => ANTIC_HIGHRES_COLOUR_CLOCK_OUT,
|
|
dma_fetch_out => ANTIC_FETCH,
|
|
hcount_out => hcount_temp,
|
|
vcount_out => vcount_temp,
|
|
refresh_out => ANTIC_REFRESH_CYCLE,
|
|
AN => ANTIC_AN,
|
|
DATA_OUT => ANTIC_DO,
|
|
dma_address_out => ANTIC_ADDR);
|
|
|
|
pokey_mixer_both : entity work.pokey_mixer_mux
|
|
PORT MAP(CLK => CLK,
|
|
GTIA_SOUND => GTIA_SOUND,
|
|
SIO_AUDIO => SIO_AUDIO,
|
|
CHANNEL_L_0 => POKEY1_CHANNEL0,
|
|
CHANNEL_L_1 => POKEY1_CHANNEL1,
|
|
CHANNEL_L_2 => POKEY1_CHANNEL2,
|
|
CHANNEL_L_3 => POKEY1_CHANNEL3,
|
|
COVOX_CHANNEL_L_0 => (others=>'0'),
|
|
COVOX_CHANNEL_L_1 => (others=>'0'),
|
|
CHANNEL_R_0 => POKEY1_CHANNEL0,
|
|
CHANNEL_R_1 => POKEY1_CHANNEL1,
|
|
CHANNEL_R_2 => POKEY1_CHANNEL2,
|
|
CHANNEL_R_3 => POKEY1_CHANNEL3,
|
|
COVOX_CHANNEL_R_0 => (others=>'0'),
|
|
COVOX_CHANNEL_R_1 => (others=>'0'),
|
|
VOLUME_OUT_L => AUDIO_L,
|
|
VOLUME_OUT_R => AUDIO_R);
|
|
|
|
pia1 : entity work.pia
|
|
PORT MAP(CLK => CLK,
|
|
EN => PIA_READ_ENABLE,
|
|
WR_EN => PIA_WRITE_ENABLE,
|
|
RESET_N => RESET_N,
|
|
CA1 => CA1_IN,
|
|
CB1 => CB1_IN,
|
|
CA2_DIR_OUT => CA2_DIR_OUT,
|
|
CA2_IN => CA2_IN,
|
|
CA2_OUT => CA2_OUT,
|
|
CB2_DIR_OUT => CB2_DIR_OUT,
|
|
CB2_IN => CB2_IN,
|
|
CB2_OUT => CB2_OUT,
|
|
ADDR => BUS_ADDR(1 DOWNTO 0),
|
|
CPU_DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
IRQA_N => PIA_IRQA,
|
|
IRQB_N => PIA_IRQB,
|
|
DATA_OUT => PIA_DO,
|
|
PORTA_IN => PORTA_IN,
|
|
PORTA_DIR_OUT => PORTA_DIR_OUT,
|
|
PORTA_OUT => PORTA_OUT,
|
|
PORTB_IN => PORTB_IN,
|
|
PORTB_DIR_OUT => PORTB_DIR_OUT,
|
|
PORTB_OUT => PORTB_OUT_INT);
|
|
|
|
PORTB_OPTIONS <= PORTB_OUT_INT;
|
|
PORTB_OUT <= PORTB_OUT_INT;
|
|
GTIA_TRIG_MERGED <= cart_trig3_out & GTIA_TRIG(2 downto 0); -- NOTE, inputs ignored, careful when adding 4 joystick support
|
|
|
|
pokey1 : entity work.pokey
|
|
PORT MAP(CLK => CLK,
|
|
ENABLE_179 => run_system,
|
|
WR_EN => POKEY_WRITE_ENABLE,
|
|
RESET_N => RESET_N,
|
|
SIO_IN1 => SIO_RXD,
|
|
SIO_IN2 => '1',
|
|
SIO_IN3 => '1',
|
|
SIO_CLOCKIN => SIO_CLOCKIN,
|
|
ADDR => BUS_ADDR(3 DOWNTO 0),
|
|
DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
keyboard_response => KEYBOARD_RESPONSE,
|
|
POT_IN => POT_IN,
|
|
IRQ_N_OUT => POKEY_IRQ,
|
|
SIO_OUT1 => SIO_TXD,
|
|
SIO_OUT2 => open,
|
|
SIO_OUT3 => open,
|
|
SIO_CLOCKOUT => SIO_CLOCKOUT,
|
|
POT_RESET => POT_RESET,
|
|
CHANNEL_0_OUT => POKEY1_CHANNEL0,
|
|
CHANNEL_1_OUT => POKEY1_CHANNEL1,
|
|
CHANNEL_2_OUT => POKEY1_CHANNEL2,
|
|
CHANNEL_3_OUT => POKEY1_CHANNEL3,
|
|
DATA_OUT => POKEY_DO,
|
|
keyboard_scan => KEYBOARD_SCAN);
|
|
|
|
CONSOL_IN <= '1'&CONSOL_OPTION&CONSOL_SELECT&CONSOL_START;
|
|
|
|
gtia1 : entity work.gtia
|
|
PORT MAP(CLK => CLK,
|
|
WR_EN => GTIA_WRITE_ENABLE,
|
|
ANTIC_FETCH => ANTIC_FETCH, -- for first pmg fetch
|
|
CPU_ENABLE_ORIGINAL => run_system, -- for subsequent pmg fetches
|
|
RESET_N => RESET_N,
|
|
PAL => PAL,
|
|
COLOUR_CLOCK_ORIGINAL => ANTIC_ORIGINAL_COLOUR_CLOCK_OUT,
|
|
COLOUR_CLOCK => ANTIC_COLOUR_CLOCK_OUT,
|
|
COLOUR_CLOCK_HIGHRES => ANTIC_HIGHRES_COLOUR_CLOCK_OUT,
|
|
CONSOL_OUT => CONSOL_OUT,
|
|
CONSOL_IN => CONSOL_IN,
|
|
TRIG => GTIA_TRIG_MERGED,
|
|
ADDR => BUS_ADDR(4 DOWNTO 0),
|
|
AN => ANTIC_AN,
|
|
CPU_DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
MEMORY_DATA_IN => BUS_DATA(7 DOWNTO 0),
|
|
VSYNC => VIDEO_VS,
|
|
HSYNC => VIDEO_HS,
|
|
CSYNC => VIDEO_CS,
|
|
BLANK => VIDEO_BLANK,
|
|
BURST => VIDEO_BURST,
|
|
START_OF_FIELD => VIDEO_START_OF_FIELD,
|
|
ODD_LINE => VIDEO_ODD_LINE,
|
|
COLOUR_out => COLOUR,
|
|
DATA_OUT => GTIA_DO);
|
|
|
|
GTIA_SOUND <= CONSOL_OUT(3);
|
|
|
|
irq_glue1 : entity work.irq_glue
|
|
PORT MAP(pokey_irq => POKEY_IRQ,
|
|
pia_irqa => PIA_IRQA,
|
|
pia_irqb => PIA_IRQB,
|
|
pbi_irq => PBI_IRQ_N,
|
|
combined_irq => IRQ_n);
|
|
|
|
process(ANTIC_FETCH, ANTIC_ADDR, CPU_ADDR)
|
|
begin
|
|
BUS_ADDR <= CPU_ADDR;
|
|
if (ANTIC_FETCH = '1') then
|
|
BUS_ADDR <= ANTIC_ADDR;
|
|
end if;
|
|
end process;
|
|
|
|
PBI_REF_N_OUT <= not(ANTIC_REFRESH_CYCLE);
|
|
REF_N <= PBI_REF_N_IN and not(ANTIC_REFRESH_CYCLE);
|
|
PBI_CAS_INHIBIT <= CAS_INHIBIT;
|
|
|
|
|
|
-- TODO
|
|
-- implement in timing_6502, along with driving bus every cycle (for snoopers)
|
|
--PBI_CAS : out STD_LOGIC; -- high with RAS, low (unless extsel/inhibited) depends on read write. phi2 low-> cas low (read)=300-370, write=425-?
|
|
--PBI_RAS : out STD_LOGIC; -- high slightly after PHI2 high, low slight before phi low. phi2 low -> raw low 210-305
|
|
|
|
mmu1: entity work.mmu
|
|
PORT MAP
|
|
(
|
|
ADDR => BUS_ADDR(15 downto 11),
|
|
REF_N => REF_N,
|
|
RD4 => CART_RD4,
|
|
RD5 => CART_RD5,
|
|
MPD_N => PBI_MPD_N,
|
|
REN => PORTB_OUT_INT(0),
|
|
BE_N => PORTB_OUT_INT(1),
|
|
MAP_N => PORTB_OUT_INT(7),
|
|
S4_N => CART_S4_N,
|
|
S5_N => CART_S5_N,
|
|
BASIC => CS_BASIC,
|
|
IO => CS_IO,
|
|
OS => CS_OS,
|
|
CI => CAS_INHIBIT --Disable RAM
|
|
);
|
|
|
|
--74ls138
|
|
decode_addr1 : entity work.complete_address_decoder
|
|
generic map(width=>3)
|
|
port map (addr_in=>BUS_ADDR(10 downto 8), addr_decoded=>io_select);
|
|
|
|
CS_GTIA <= CS_IO and io_select(0);
|
|
CS_D1 <= CS_IO and io_select(1); -- PBI regs
|
|
CS_POKEY <= CS_IO and io_select(2);
|
|
CS_PIA <= CS_IO and io_select(3);
|
|
CS_ANTIC <= CS_IO and io_select(4); -- Antic decodes bus itself
|
|
CS_D5 <= CS_IO and io_select(5); -- CART CTRL
|
|
CS_D6 <= CS_IO and io_select(6); -- PBI RAM?
|
|
CS_D7 <= CS_IO and io_select(7); -- PBI RAM?
|
|
|
|
ANTIC_WRITE_ENABLE <= CS_ANTIC AND NOT(R_W_N) and run_cpu;
|
|
POKEY_WRITE_ENABLE <= CS_POKEY AND NOT(R_W_N) and run_cpu;
|
|
PIA_WRITE_ENABLE <= CS_PIA AND NOT(R_W_N) and run_cpu;
|
|
PIA_READ_ENABLE <= CS_PIA AND R_W_N and run_system;
|
|
GTIA_WRITE_ENABLE <= CS_GTIA AND NOT(R_W_N) and run_cpu;
|
|
|
|
RAM_WRITE_ENABLE <= NOT(R_W_N) and NOT(CAS_INHIBIT) and run_cpu;
|
|
|
|
process(BUS_ADDR, GTIA_DO, POKEY_DO, PIA_DO, ANTIC_DO, PBI_DO)
|
|
begin
|
|
case (BUS_ADDR(10 downto 8)) is
|
|
when "000" =>
|
|
IO_DO <= GTIA_DO;
|
|
when "010" =>
|
|
IO_DO <= POKEY_DO;
|
|
when "011" =>
|
|
IO_DO <= PIA_DO;
|
|
when "100" =>
|
|
IO_DO <= ANTIC_DO;
|
|
when others =>
|
|
IO_DO <= PBI_DO; -- D1,D5,D6,D7
|
|
end case;
|
|
|
|
end process;
|
|
|
|
-- CAS_INHIBIT -> RAM disabled. e.g. IO, ROM etc.
|
|
-- So PBI can reply if its IO and there is no chip selected - D1,D6,D7
|
|
process(R_W_N, CS_BASIC, CS_IO, CS_OS, CAS_INHIBIT, PBI_EXTSEL_N, IO_DO, RAM_DO, OS_DO, BASIC_DO, PBI_DO, CPU_DO)
|
|
variable casesig : std_logic_vector(5 downto 0);
|
|
begin
|
|
BUS_DATA <= (others=>'1');
|
|
casesig := R_W_N&CS_BASIC&CS_IO&CS_OS&CAS_INHIBIT&PBI_EXTSEL_N;
|
|
case casesig is
|
|
when
|
|
"000000"|"000001"|"000010"|"000011"|"000100"|"000101"|"000110"|"000111"|
|
|
"001000"|"001001"|"001010"|"001011"|"001100"|"001101"|"001110"|"001111"|
|
|
"010000"|"010001"|"010010"|"010011"|"010100"|"010101"|"010110"|"010111"|
|
|
"011000"|"011001"|"011010"|"011011"|"011100"|"011101"|"011110"|"011111"
|
|
=>
|
|
BUS_DATA <= CPU_DO;
|
|
when "110010"|"110011" =>
|
|
BUS_DATA <= BASIC_DO;
|
|
when "101010"|"101011" =>
|
|
BUS_DATA <= IO_DO;
|
|
when "100110"|"100111" =>
|
|
BUS_DATA <= OS_DO;
|
|
when "100010"|"100011" =>
|
|
BUS_DATA <= PBI_DO; -- i.e. CAS inhibited, nothing selected (e.g. REF_N is low)
|
|
when "100001" =>
|
|
BUS_DATA <= RAM_DO; -- i.e. RAM access, no EXTSEL
|
|
when "100000" =>
|
|
BUS_DATA <= PBI_DO; -- i.e. RAM access, but EXTSEL asserted
|
|
when others =>
|
|
BUS_DATA <= (others=>'1');
|
|
end case;
|
|
end process;
|
|
|
|
-- 00000000001111111111122222222233
|
|
-- 01234567890123456789012345678901
|
|
-- 00000000000000000000000000000001 run antic and CPU and kick off pbi/cart cycle
|
|
-- simple shift reg will do it
|
|
process(clk, reset_n)
|
|
begin
|
|
if (reset_n='0') then
|
|
shift_cpu_run_reg <= "00000000000000000000000000000001";
|
|
elsif (clk'event and clk='1') then
|
|
shift_cpu_run_reg <= shift_cpu_run_next;
|
|
end if;
|
|
end process;
|
|
shift_cpu_run_next <= shift_cpu_run_reg(30 downto 0)&shift_cpu_run_reg(31);
|
|
run_system <= shift_cpu_run_reg(31);
|
|
run_cpu <= run_system and not(ANTIC_FETCH or ANTIC_REFRESH_CYCLE);
|
|
|
|
-- Internal rom/ram
|
|
internalromram1 : entity work.internalromram_simple
|
|
PORT MAP (
|
|
clock => CLK,
|
|
reset_n => RESET_N,
|
|
|
|
ROM_ADDR => "000000"&BUS_ADDR,
|
|
ROM_REQUEST_COMPLETE => open,
|
|
ROM_REQUEST => '1',
|
|
BASIC_DATA => BASIC_DO,
|
|
OS_DATA => OS_DO,
|
|
|
|
RAM_ADDR => "000"&BUS_ADDR,
|
|
RAM_WR_ENABLE => RAM_WRITE_ENABLE,
|
|
RAM_DATA_IN => BUS_DATA(7 downto 0),
|
|
RAM_REQUEST_COMPLETE => open,
|
|
RAM_REQUEST => '1',
|
|
RAM_DATA => RAM_DO(7 downto 0)
|
|
);
|
|
|
|
END bdf_type;
|