repo2/common/a8core/atari800xl.vhd
507 | 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.
|
|||
---------------------------------------------------------------------------
|
|||
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;
|