---------------------------------------------------------------------------------- -- ATARI FPGA Entwicklungsboard (C) 2015-2016 mega-hz -- -- Last Update: 27.07.2016 ------------------------------------------------------------------------------------ --Änderungen: -- --es gibt jetzt ein write-enable byte in D3FD, muss auf 55 stehen. --es gibt nun ein READ-Access Enable bei $D3FB, wenn dort ein R drin steht, werden Lesezugriffe angezeigt. --es gibt nun ein WRITE-Access Enable bei $D3FC, wenn dort ein W drin steht, werden Schreibzugriffe angezeigt. --es gibt nun ein Trigger-Enable bei $D3FA, wenn dort ein T drin steht, wird ein verlängertes Signal als Triggerimpuls --zum (z.B.) Freezer oder Bibomon geschickt um diesen zu aktivieren. --es gibt nun eine Triggeradresse, wird auf diese zugegriffen, wird der Trigger ausgelöst. -- -- D380-D387: hier werden 8 Bytes des linken Sockels (EEPROM oder EPROM) zum testen eingeblendet -- D388-D38F: hier werden 8 Bytes des rechten Sockels (FLASH oder SRAM) zum testen eingeblendet -- D3B7: Schalter 7 bis 0 (nur lesen) -- D3B7: Taster 1 und 0 (nur lesen) -- D3C6: LO Byte der GPIO's (Bits 7-0: GPIO7,GPIO6,GPIO5,GPIO4,GPIO3,GPIO2,GPIO1,GPIO0) -- D3C7: HI Byte der GPIO's (Bits 7-0: GPIN0,GPIN1,GPIO13,GPIO12,GPIO11,GPIO10,GPIO9,GPIO8) -- D3F0: Triggeradresse Write Enable bei #$55 -- D3F1: Trigger Enable 54 "T" -- D3F2: Trigger-Piep Enable "P" -- D3F4: Triggeradresse Read Access bei 52 "R" -- D3F5: Triggeradresse Write Access bei 57 "W" -- D3F6: Triggeradresse (LO) -- D3F7: Triggeradresse (HI) -- D3F8: Debugadresse Write Enable bei #$55 -- D3FC: Debugadresse Read Access bei 52 "R" -- D3FD: Debugadresse Write Access bei 57 "W" -- D3FE: Debugadresse (LO) -- D3FF: Debugadresse (HI) -- -- RAM1CE als Pad für Huckepack SRAM -- 8 Schalter, 2 Taster -- die Leitungen DISP_1 - 14 werden doppelt genutzt, Anzeigen,Schaltern und Tastern, je per Diode entkoppelt -- freie IOs als GPIOs, nur per Handverdrahtung an 16pol. Buchsenleiste oder ab neuen Layout V3 an der rechten Seite -- freien GPIOs sind nun bei $D3C6/C7 erreichbar: Bits 15-0: GPIN0,GPIN1,GPIO13,GPIO12,GPIO11,GPIO10,GPIO9,GPIO8,GPIO7,GPIO6,GPIO5,GPIO4,GPIO3,GPIO2,GPIO1,GPIO0 -- Dezimalpunkte eingebaut -- akustischen Trigger per PBI-Audio und 1khz Ton zuschaltbar -- switches umgenannt von sw7-0 anstatt 8-1 -- taster umgenannt von ta1-0 anstatt 2-1 -- zum direkten auslesen Schalter nach D3B7 und Taster nach D3B6 gemappt. -- in der set_refresh routine $D380 - $D3FF eingefügt; Problem das auf $D300-$D303 gespiegelt geschrieben wird, behoben. -- -- to do: -- trigger data abfrage: wenn z.b. 77 in die triggeradresse geschrieben wird, nur dann einen triggerimpuls auslösen -- korrekte PIA Emulation um OS-Roms einzublenden -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.NUMERIC_STD.ALL; library work; use work.all; entity ATARI_PBI_FPGA is Port( adr: in std_logic_vector(15 downto 0); -- ATARI Adressbus data: inout std_logic_vector(7 downto 0); -- ATARI Datenbus ram_rom_adr: inout std_logic_vector(18 downto 0);-- Externer SRAM/(E)EPROM Adressbus data_en: out std_logic := '1'; -- Enable Data-Bustreiber data_dir: out std_logic := '0'; -- Direction Data-Bustreiber LO=ATARI zum FPGA. HI=FPGA zum ATARI adress_en: out std_logic := '1'; -- Enable Adress-Bustreiber adress_dir: out std_logic := '0'; -- Direction Adress-Bustreiber LO=ATARI zum FPGA. HI=FPGA zum ATARI ram0_ce: out std_logic := '1'; -- CE vom SRAM0 ram1_ce: out std_logic := '1'; -- CE vom SRAM1 (zusätzliches Pad zum Huckepack RAM) ram_oe: out std_logic := '1'; -- OE vom SRAM ramrom_we: out std_logic := '1'; -- WE vom SRAM und EEPROM rom_ce: out std_logic := '1'; -- CE vom (E)EPROM rom_oe: out std_logic := '1'; -- OE vom (E)EPROM rdy: in std_logic; -- RDY Signal vom ATARI, nicht benutzt rw: in std_logic; -- ATARI R/W audio: out std_logic; -- zum PBI Audio Eingang via 100nF segment7: out std_logic_vector(7 downto 0); -- Segmente a-g der 7Segment Anzeigen und 8Bits für LEDs display7: out std_logic_vector(14 downto 1); -- 7Segment Anzeigen, LEDs und Schalter/Taster switch_in: in std_logic := '0'; -- HI aktiver Schalter Eingang phi2 : in std_logic; -- ATARI Clock phi2short: in std_logic; -- verkürzte ATARI Clock durch 74123 reset_n_in: in std_logic; -- Reseteingang trigger: out std_logic := '0'; -- Triggerausgang mit verlängerten Signal(74HCT123) für z.B. Freezer / Bibomon IRQ: out std_logic := '0'; -- IRQ Ausgang, um den ATARI zu bremsen (über BC847 Transistor) clk50: in std_logic; -- 50Mhz Oszillator gpio: inout std_logic_vector(13 downto 0); -- freie IOs, rechte Seite ab Layout V3 gpin: in std_logic_vector(1 downto 0); -- freie INs, rechte Seite ab Layout V3 refresh: out std_logic := '0' -- Refreshausgang, um eigene Zugriffe auf den Bus zu ermöglichen (über BC847 Transistor) ); end ATARI_PBI_FPGA; architecture Behavioral of ATARI_PBI_FPGA is signal data_out: std_logic_vector(7 downto 0); signal data_out_enable: boolean; signal data_in: std_logic_vector(7 downto 0); signal trigger_adr: std_logic_vector(15 downto 0) := x"D501"; -- Triggeradresse erstmal festlegen $xxxx in $D3F6-D3F7 signal trigger_adr_data: std_logic_vector(7 downto 0); signal trigger_enable: std_logic_vector(7 downto 0) := x"D4"; -- Trigger Enable bei "T x54)" in $D3F1 signal trigger_en: boolean:= false; signal trigger_wr: std_logic_vector(7 downto 0) := x"57"; -- Write Zugriffe anzeigen bei "W" in $D3F5 signal trigger_rd: std_logic_vector(7 downto 0) := x"52"; -- Read Zugriffe anzeigen bei "R" in $D3F4 signal trigger_we: std_logic_vector(7 downto 0) := x"77"; -- Triggerdresse Write Enable bei #$55 in $D3F0 signal piep: std_logic_vector(7 downto 0) := x"D0"; -- akustischer Trigger, Enable bei #$50 in $D3F2 signal piep_enable: boolean:= false; signal piep_out: boolean:= false; signal piep_divisor: integer range 0 to 3540 := 0; -- Frequenzteiler für 1KHz Ton signal status1: std_logic_vector(7 downto 0) := x"A0"; -- inverses Leerzeichen signal status2: std_logic_vector(7 downto 0) := x"A0"; signal status3: std_logic_vector(7 downto 0) := x"A0"; signal status4: std_logic_vector(7 downto 0) := x"A0"; signal status5: std_logic_vector(7 downto 0) := x"A0"; signal status6: std_logic_vector(7 downto 0) := x"A0"; signal status7: std_logic_vector(7 downto 0) := x"A0"; signal status8: std_logic_vector(7 downto 0) := x"A0"; signal status9: std_logic_vector(7 downto 0) := x"A0"; signal status10: std_logic_vector(7 downto 0) := x"A0"; signal status11: std_logic_vector(7 downto 0) := x"A0"; signal status12: std_logic_vector(7 downto 0) := x"A0"; signal debug_adr: std_logic_vector(15 downto 0) := x"D500"; -- Debugadresse erstmal festlegen $xxxx in $D3FE-D3FF signal debug_we: std_logic_vector(7 downto 0) := x"77"; -- Debugadresse Write Enable bei #$55 in $D3F8 signal debug_wr: std_logic_vector(7 downto 0) := x"57"; -- Write Zugriffe anzeigen bei "W" in $D3FD signal debug_rd: std_logic_vector(7 downto 0) := x"52"; -- Read Zugriffe anzeigen bei "R" in $D3FC signal mux_divisor: integer range 0 to 64 := 0; signal delay2: integer range 0 to 20000000 := 0; signal reset_delay: integer range 0 to 20000000 := 0; signal reset_n_sync1: std_logic := '0'; signal reset_n_sync: std_logic := '0'; signal mux_position: integer range 1 to 15 := 1; signal mux_nibble: std_logic_vector(3 downto 0); signal bcd7: std_logic_vector(6 downto 0); signal ram_rom_adr_next: std_logic_vector(18 downto 0) := "1111111111111111111"; signal ram_rom_access: boolean := false; signal rom_ce_next: std_logic := '1'; signal rom_oe_next: std_logic := '1'; signal ram0_ce_next: std_logic := '1'; signal ram1_ce_next: std_logic := '1'; signal ram_oe_next: std_logic := '1'; signal ramrom_we_next: std_logic := '1'; signal enable_trgset: boolean := false; signal trigger_read_access_enable: boolean :=true; signal trigger_write_access_enable: boolean :=true; signal enable_adrset: boolean := false; signal read_access_enable: boolean :=true; signal write_access_enable: boolean :=true; signal coldst: boolean := false; signal run_ok: boolean := false; signal space: std_logic_vector(7 downto 0) := x"20"; signal dp: std_logic_vector(12 downto 1) := "000000000000"; signal led1: std_logic := '0'; signal led2: std_logic := '0'; signal led3: std_logic := '0'; signal led4: std_logic := '0'; signal led5: std_logic := '0'; signal led6: std_logic := '0'; signal led7: std_logic := '0'; signal led8: std_logic := '0'; signal led9: std_logic := '0'; signal led10: std_logic := '0'; signal led11: std_logic := '0'; signal led12: std_logic := '0'; signal led13: std_logic := '0'; signal led14: std_logic := '0'; signal led15: std_logic := '0'; signal led16: std_logic := '0'; signal sw0: std_logic := '0'; signal sw1: std_logic := '0'; signal sw2: std_logic := '0'; signal sw3: std_logic := '0'; signal sw4: std_logic := '0'; signal sw5: std_logic := '0'; signal sw6: std_logic := '0'; signal sw7: std_logic := '0'; signal ta0: std_logic := '0'; signal ta1: std_logic := '0'; signal sw: std_logic_vector(7 downto 0) := x"00"; signal ta: std_logic_vector(7 downto 0) := x"00"; signal pia_portb: std_logic_vector(7 downto 0); signal portb: std_logic_vector(7 downto 0); -------------------------------------------------------------------------- -- Signale, die als "Schalter" dienen und Funktionen ein/ausschalten, nach Bedarf -------------------------------------------------------------------------- signal option_flash_ram: boolean := false; -- true = Flash, false = SRAM bestückt signal option_test_quarz: boolean := true; -- lässt einen Zähler vom 50Mhz Quarz laufen und LED blinken signal option_test_schalter: boolean := true; -- Schaltertest: SW0-7 werden auf LED1-8 angezeigt signal option_display: boolean := true; -- enabled die Debuganzeige, false: nur LEDs 9-16 aktiv -------------------------------------------------------------------------- begin use_PIA: entity PIA port map ( clk_register => phi2short, adr => adr, data_in => data, rw => rw, reset_n_in => reset_n_in, portb => portb ); --------------------------------------------------------------------------- -- temporäre Signale "_next" in die "echten" Register übertragen -------------------------------------------------------------------------- set_registers: process(phi2short, phi2, ram_rom_adr_next, ram0_ce_next, ram1_ce_next, ram_oe_next, rom_ce_next, rom_oe_next, option_flash_ram, ramrom_we_next, enable_adrset, coldst, run_ok, trigger_en, data, debug_we, status8, status9, status10, read_access_enable, write_access_enable, trigger_we, trigger_enable, piep_enable, status4, trigger_read_access_enable, trigger_write_access_enable, gpio, portb) begin -- if falling_edge(phi2) then rom_ce <= rom_ce_next; rom_oe <= rom_oe_next; ram0_ce <= ram0_ce_next; ram1_ce <= ram1_ce_next; ram_oe <= ram_oe_next; data <= data; -- hier werden statussymbole (*) direkt in den Speicher eingeblendet, um beim disassemblen gleich sehen zu können, was gesetzt ist. if (debug_we = x"55") then status7 <= x"AA"; -- inv. * else status7 <= x"A0"; end if; status8 <= status8; status9 <= status9; status10 <= status10; if (read_access_enable = true) then status11 <= x"AA"; -- inv. * else status11 <= x"A0"; end if; if (write_access_enable = true) then status12 <= x"AA"; -- inv. * else status12 <= x"A0"; end if; if (trigger_we = x"55") then status1 <= x"AA"; -- inv. * else status1 <= x"A0"; end if; if (trigger_enable = x"54") then status2 <= x"AA"; -- inv. * else status2 <= x"A0"; end if; if (piep_enable = true) then status3 <= x"AA"; -- inv. * else status3 <= x"A0"; end if; status4 <= status4; if (trigger_read_access_enable = true) then status5 <= x"AA"; -- inv. * else status5 <= x"A0"; end if; if (trigger_write_access_enable = true) then status6 <= x"AA"; -- inv. * else status6 <= x"A0"; end if; if (coldst) then led13 <= '1'; else led13 <= '0'; end if; if run_ok then led14 <= '1'; else led14 <= '0'; end if; -- end if; end process set_registers; ----------------------------------------------------------------------------- divide_mux_frequency: process(phi2short, mux_divisor) begin if falling_edge(phi2short) then if (mux_divisor >= 64) then -- ca. 27kHz bei 1.77Mhz Clock mux_divisor <= 0; else mux_divisor <= mux_divisor + 1; end if; end if; end process divide_mux_frequency; --------------------------------------------------------------------------- set_mux_position: process(phi2, mux_position, mux_divisor, option_display) -- 1-6 = 1.Anzeige, 7-12 = 2.Anzeige, 13-14 = LED Streifen begin if falling_edge(phi2) then if (option_display = true) then if (mux_divisor = 0) then if (mux_position >= 15) then mux_position <= 1; else mux_position <= mux_position + 1; end if; end if; else mux_position <= 14; -- wenn "option_display" false ist, wird nur die LED-Reihe LED9-16 eingeschaltet end if; end if; end process set_mux_position; --------------------------------------------------------------------------- set_mux_nibble: process(mux_position, debug_adr, trigger_adr, trigger_adr_data, data_in, phi2short, led1, led2, led3, led4, led5, led6, led7, led8, led9, led10, led11, led12, led13, led14, led15, led16 ) begin if falling_edge(phi2short) then case mux_position is -- 1. Anzeige when 1 => mux_nibble <= debug_adr(15 downto 12); -- HIHI Debugadresse segment7 <= dp(1) & bcd7; when 2 => mux_nibble <= debug_adr(11 downto 8); -- HILO Debugadresse segment7 <= dp(2) & bcd7; when 3 => mux_nibble <= debug_adr(7 downto 4); -- LOHI Debugadresse segment7 <= dp(3) & bcd7; when 4 => mux_nibble <= debug_adr(3 downto 0); -- LOLO Debugadresse segment7 <= dp(4) & bcd7; when 5 => mux_nibble <= data_in(7 downto 4); -- HI Daten segment7 <= dp(5) & bcd7; when 6 => mux_nibble <= data_in(3 downto 0); -- LO Daten segment7 <= dp(6) & bcd7; -- 2. Anzeige when 7 => mux_nibble <= trigger_adr(15 downto 12); -- HIHI Triggeradresse segment7 <= dp(7) & bcd7; when 8 => mux_nibble <= trigger_adr(11 downto 8); -- HILO Triggeradresse segment7 <= dp(8) & bcd7; when 9 => mux_nibble <= trigger_adr(7 downto 4); -- LOHI Triggeradresse segment7 <= dp(9) & bcd7; when 10 => mux_nibble <= trigger_adr(3 downto 0); -- LOLO Triggeradresse segment7 <= dp(10) & bcd7; when 11 => mux_nibble <= trigger_adr_data(7 downto 4);-- HI Daten Triggeradresse segment7 <= dp(11) & bcd7; when 12 => mux_nibble <= trigger_adr_data(3 downto 0);-- LO Daten Triggeradresse segment7 <= dp(12) & bcd7; -- 1. 8fach LED Leiste when 13 => segment7 <= led8 & led7 & led6 & led5 & led4 & led3 & led2 & led1; -- 2. 8fach LED Leiste when 14 => segment7 <= led16 & led15 & led14 & led13 & led12 & led11 & led10 & led9; when others => mux_nibble <= (others => '0'); segment7 <= "00000000"; end case; end if; end process set_mux_nibble; --------------------------------------------------------------------------- enable_mux_display: process(mux_position, phi2short, switch_in) begin if falling_edge(phi2short) then case mux_position is when 1 => display7 <="00000000000001"; sw0 <= switch_in; sw(0) <= switch_in; when 2 => display7 <="00000000000010"; sw1 <= switch_in; sw(1) <= switch_in; when 3 => display7 <="00000000000100"; sw2 <= switch_in; sw(2) <= switch_in; when 4 => display7 <="00000000001000"; sw3 <= switch_in; sw(3) <= switch_in; when 5 => display7 <="00000000010000"; ta1 <= switch_in; ta(1) <= switch_in; when 6 => display7 <="00000000100000"; ta0 <= switch_in; ta(0) <= switch_in; when 7 => display7 <="00000001000000"; when 8 => display7 <="00000010000000"; when 9 => display7 <="00000100000000"; when 10 => display7 <="00001000000000"; when 11 => display7 <="00010000000000"; sw4 <= switch_in; sw(4) <= switch_in; when 12 => display7 <="00100000000000"; sw5 <= switch_in; sw(5) <= switch_in; when 13 => display7 <="01000000000000"; sw6 <= switch_in; sw(6) <= switch_in; when 14 => display7 <="10000000000000"; sw7 <= switch_in; sw(7) <= switch_in; when others => display7 <="00000000000000"; end case; end if; end process enable_mux_display; --------------------------------------------------------------------------- decode_7segment: process(mux_nibble, phi2short) begin if rising_edge(phi2short) then case mux_nibble is when x"0" => bcd7 <="0111111"; -- '0' when x"1" => bcd7 <="0000110"; -- '1' when x"2" => bcd7 <="1011011"; -- '2' when x"3" => bcd7 <="1001111"; -- '3' when x"4" => bcd7 <="1100110"; -- '4' when x"5" => bcd7 <="1101101"; -- '5' when x"6" => bcd7 <="1111101"; -- '6' when x"7" => bcd7 <="0000111"; -- '7' when x"8" => bcd7 <="1111111"; -- '8' when x"9" => bcd7 <="1101111"; -- '9' when x"A" => bcd7 <="1110111"; -- 'A' when x"B" => bcd7 <="1111100"; -- 'b' when x"C" => bcd7 <="0111001"; -- 'C' when x"D" => bcd7 <="1011110"; -- 'd' when x"E" => bcd7 <="1111001"; -- 'E' when x"F" => bcd7 <="1110001"; -- 'F' when others => bcd7 <="0000000"; end case; end if; end process decode_7segment; ---------------------------------------------------------------------------------------- -- Hier wird ein Text sowie die Trigger- und Debug-Adressen im D3xx Bereich eingeblendet ---------------------------------------------------------------------------------------- signature: process (phi2, adr, data, rw, debug_adr, trigger_adr, debug_we, debug_rd, debug_wr, trigger_rd, trigger_wr, trigger_we, trigger_enable, run_ok, status1, status2, status3, status4, status5, status6, status7, status8, status9, status10, status11, status12, piep, space, gpio, gpin, sw, ta) begin data_out_enable <= false; data_out <= (others => '0'); if run_ok then if (adr >= x"D304" and adr <= x"D3FF") then if (rw = '1') then data_out_enable <= true; case adr(15 downto 0) is when x"D390" => data_out <= x"A0"; -- when x"D391" => data_out <= x"A0"; -- when x"D392" => data_out <= x"C6"; -- F when x"D393" => data_out <= x"D0"; -- P when x"D394" => data_out <= x"C7"; -- G when x"D395" => data_out <= x"C1"; -- A when x"D396" => data_out <= x"A0"; -- when x"D397" => data_out <= x"A0"; -- when x"D398" => data_out <= x"A0"; -- when x"D399" => data_out <= x"C4"; -- D when x"D39A" => data_out <= x"C5"; -- E when x"D39B" => data_out <= x"C2"; -- B when x"D39C" => data_out <= x"D5"; -- U when x"D39D" => data_out <= x"C7"; -- G when x"D39E" => data_out <= x"A0"; -- when x"D39F" => data_out <= x"A0"; -- when x"D3A0" => data_out <= x"C4"; -- D when x"D3A1" => data_out <= x"C9"; -- I when x"D3A2" => data_out <= x"D3"; -- S when x"D3A3" => data_out <= x"D0"; -- P when x"D3A4" => data_out <= x"CC"; -- L when x"D3A5" => data_out <= x"C1"; -- A when x"D3A6" => data_out <= x"D9"; -- Y when x"D3A7" => data_out <= x"A0"; -- when x"D3B0" => data_out <= x"D3"; -- S when x"D3B1" => data_out <= x"D7"; -- W when x"D3B2" => data_out <= x"C9"; -- I when x"D3B3" => data_out <= x"D4"; -- T when x"D3B4" => data_out <= x"C3"; -- C when x"D3B5" => data_out <= x"C8"; -- H when x"D3B6" => data_out <= ta; --$D3B6 Taster zurücklesen when x"D3B7" => data_out <= sw; --$D3B7 Schalter zurücklesen when x"D3C0" => data_out <= x"C7"; -- G when x"D3C1" => data_out <= x"D0"; -- P when x"D3C2" => data_out <= x"C9"; -- I when x"D3C3" => data_out <= x"CF"; -- O when x"D3C4" => data_out <= x"A0"; -- when x"D3C5" => data_out <= x"A0"; -- when x"D3C6" => data_out <= gpio(7 downto 0); --$D3C6 GPIO LO-Byte zurücklesen when x"D3C7" => data_out(5 downto 0) <= gpio(13 downto 8); --$D3C7 GPIO HI-Byte zurücklesen data_out(7 downto 6) <= gpin(1 downto 0); --$D3C7 GPIN zurücklesen when x"D3D0" => data_out <= x"D4"; -- T when x"D3D1" => data_out <= x"D2"; -- R when x"D3D2" => data_out <= x"C9"; -- I when x"D3D3" => data_out <= x"C7"; -- G when x"D3D4" => data_out <= x"C7"; -- G when x"D3D5" => data_out <= x"C5"; -- E when x"D3D6" => data_out <= x"D2"; -- R when x"D3D7" => data_out <= x"BA"; -- : when x"D3D8" => data_out <= status1; when x"D3D9" => data_out <= status2; when x"D3DA" => data_out <= status3; when x"D3DB" => data_out <= status4; when x"D3DC" => data_out <= status5; when x"D3DD" => data_out <= status6; when x"D3E0" => data_out <= x"A0"; -- when x"D3E1" => data_out <= x"C4"; -- D when x"D3E2" => data_out <= x"C5"; -- E when x"D3E3" => data_out <= x"C2"; -- B when x"D3E4" => data_out <= x"D5"; -- U when x"D3E5" => data_out <= x"C7"; -- G when x"D3E6" => data_out <= x"A0"; -- when x"D3E7" => data_out <= x"BA"; -- : when x"D3E8" => data_out <= status7; when x"D3E9" => data_out <= status8; when x"D3EA" => data_out <= status9; when x"D3EB" => data_out <= status10; when x"D3EC" => data_out <= status11; when x"D3ED" => data_out <= status12; when x"D3F0" => data_out <= trigger_we(7 downto 0); --$D3F0 Trigger Write-Enable Byte zurücklesen when x"D3F1" => data_out <= trigger_enable(7 downto 0);--$D3F1 Trigger Enable Byte zurücklesen when x"D3F2" => data_out <= piep(7 downto 0); --$D3F2 akustischer Trigger Byte zurücklesen when x"D3F3" => data_out <= space; --$D3F3 when x"D3F4" => data_out <= trigger_rd(7 downto 0); --$D3F4 Trigger-Read Zugriff byte zurücklesen when x"D3F5" => data_out <= trigger_wr(7 downto 0); --$D3F5 Trigger-Write Zugriff byte zurücklesen when x"D3F6" => data_out <= trigger_adr(7 downto 0); --$D3F6 LO byte von trigger_adr zurücklesen when x"D3F7" => data_out <= trigger_adr(15 downto 8); --$D3F7 Hi byte von trigger_adr zurücklesen when x"D3F8" => data_out <= debug_we(7 downto 0); --$D3F8 Write Enable byte zurücklesen when x"D3F9" => data_out <= space; --$D3F9 when x"D3FA" => data_out <= space; --$D3FA when x"D3FB" => data_out <= space; --$D3FB when x"D3FC" => data_out <= debug_rd(7 downto 0); --$D3FC Read Zugriff byte zurücklesen when x"D3FD" => data_out <= debug_wr(7 downto 0); --$D3FD Write Zugriff byte zurücklesen when x"D3FE" => data_out <= debug_adr(7 downto 0); --$D3FE LO byte von debug_adr zurücklesen when x"D3FF" => data_out <= debug_adr(15 downto 8); --$D3FF Hi byte von debug_adr zurücklesen when others => data_out <= x"A0"; -- inverted space end case; end if; end if; -- if (adr = x"D304" or adr = x"D305") then -- if (rw = '1') then -- data_out_enable <= true; -- -- case adr(15 downto 0) is -- -- when x"D304" => data_out <= x"55"; -- -- when x"D305" => data_out <= x"55"; -- -- when others => data_out <= x"A0"; -- inverted space -- -- end case; -- end if; -- end if; end if; end process signature; ---------------------------------------------------------------------------------------- -- Hier wird ein Teil des (E)EPROMs / Flash / SRAMs eingeblendet ---------------------------------------------------------------------------------------- ram_rom_einblenden: process (phi2short, adr, data, rw, ram_rom_adr, run_ok, portb, gpin, option_flash_ram, ram_rom_adr_next, ramrom_we_next) begin ram_rom_adr_next(18 downto 0) <= "1111111111111111111"; ram_rom_access <= false; rom_ce_next <= '1'; rom_oe_next <= '1'; ram0_ce_next <= '1'; ram1_ce_next <= '1'; ram_oe_next <= '1'; ramrom_we_next <= '1'; -- Pinswapping für FLASH / SRAM erlaubt die Verwendung eines SRAMs oder eines 29C0x0 FLASH If (option_flash_ram = true) then ram_rom_adr(18 downto 16) <= ram_rom_adr_next(18 downto 16); -- A18-A16 übernehmen ram_rom_adr(15) <= ramrom_we_next; -- Sockel Pin31 (SRAM A15) wird zu (FLASH WE) ram_rom_adr(14) <= ram_rom_adr_next(15); -- Sockel Pin29 (SRAM WE) wird zu (FLASH A14) ramrom_we <= ram_rom_adr_next(14); -- Sockel Pin3 (SRAM A14) wird zu (FLASH A15) ram_rom_adr(13 downto 0) <= ram_rom_adr_next(13 downto 0); -- A13-A0 übernehmen else ram_rom_adr <= ram_rom_adr_next; ramrom_we <= ramrom_we_next; end if; ---------------------------------------------------------------------------------------------------------------------- -- SRAM Zugriffe Test, rechter Sockel if (adr >= x"D380" and adr <= x"D387") and run_ok then ram_rom_access <= true; option_flash_ram <= false; -- Pinswapping für SRAM einschalten ram_rom_adr_next(18 downto 3) <= "0000000000000000"; -- Im SRAM Adr. 0000 ram_rom_adr_next(2 downto 0) <= adr(2 downto 0); -- nur die unteren 8 Bytes einblenden if (rw = '1') then ram0_ce_next <= '0'; ram1_ce_next <= '1'; ram_oe_next <= '0'; ramrom_we_next <= '1'; else ram0_ce_next <= '0'; ram1_ce_next <= '1'; ram_oe_next <= '1'; ramrom_we_next <= '0'; end if; end if; ---------------------------------------------------------------------------------------------------------------------- ---- Flash/SRAM Zugriffe Test, rechter Sockel -- if (adr >= x"D380" and adr <= x"D387") and run_ok then -- ram_rom_access <= true; -- option_flash_ram <= true; -- Pinswapping für Flash einschalten ---- ram_rom_adr_next(18 downto 3) <= "0000000000000000"; -- Im Flash Adr. 0000 Test Text ---- ram_rom_adr_next(18 downto 3) <= "0000100000000000"; -- Im Flash Adr. 4000 HIAS HIGHSPEED OS ---- ram_rom_adr_next(18 downto 3) <= "0001000000000000"; -- Im Flash Adr. 8000 1200XL OS -- ram_rom_adr_next(18 downto 3) <= "0001100000000000"; -- Im Flash Adr. C000 QMEG 4.04 ---- ram_rom_adr_next(18 downto 3) <= "0010000000000000"; -- Im Flash Adr. 10000 4K-Bibomon -- ram_rom_adr_next(2 downto 0) <= adr(2 downto 0); -- nur die unteren 8 Bytes einblenden -- -- if (rw = '1') then -- ram0_ce_next <= '0'; -- ram1_ce_next <= '1'; -- ram_oe_next <= '0'; -- ramrom_we_next <= '1'; -- else -- ram0_ce_next <= '0'; -- ram1_ce_next <= '1'; -- ram_oe_next <= '1'; -- ramrom_we_next <= '0'; -- end if; -- end if; ---------------------------------------------------------------------------------------------------- -- (E)EPROM Zugriffe, linker Sockel if (adr >= x"D388" and adr <= x"D38F") and run_ok then ram_rom_access <= true; option_flash_ram <= false; -- Pinswapping für SRAM einschalten damit ramrom_we wieder richtig ist falls ein FLASH im rechten Sockel bestückt ist ram_rom_adr_next(18 downto 3) <= "0000000000000000"; ram_rom_adr_next(2 downto 0) <= adr(2 downto 0); -- nur die unteren 8 Bytes einblenden if (rw = '1') then rom_ce_next <= '0'; rom_oe_next <= '0'; ramrom_we_next <= '1'; else rom_ce_next <= '0'; rom_oe_next <= '1'; ramrom_we_next <= '0'; --############## 1= Writeprotect end if; end if; ---------------------------------------------------------------------------------------------------------------------- -- Flash Zugriffe: OS-Ersatz -- ##################### funktioniert nicht, PIA Emulation nötig? ############################## -- if (adr >= x"E000" and adr <= x"FFFF") then -- if (rw = '1') then ---- if (gpin(0) = '0') then -- nur wenn GPIN0-Taster gedrückt wird. ---- ram_rom_adr_next(18 downto 14) <= "00000"; -- Im Flash Adr. 0000 BIOS-OLD-OS ---- ram_rom_adr_next(18 downto 14) <= "00001"; -- Im Flash Adr. 4000 HIAS HIGHSPEED OS ---- ram_rom_adr_next(18 downto 14) <= "00010"; -- Im Flash Adr. 8000 1200XL OS ---- ram_rom_adr_next(18 downto 14) <= "00011"; -- Im Flash Adr. C000 QMEG 4.04 ---- ram_rom_adr_next(18 downto 14) <= "00100"; -- Im Flash Adr. 10000 4K-Bibomon ---- ram_rom_adr_next(18 downto 14) <= "00101"; -- Im Flash Adr. 14000 OLD-OS -- ram_rom_adr_next(18 downto 14) <= "00110"; -- Im Flash Adr. 18000 TFHH-OLD-OS ---- ram_rom_adr_next(18 downto 14) <= "11111"; -- Im Flash Adr. 7C000 Moon-Patrol 16K -- ram_rom_adr_next(13 downto 0) <= adr(13 downto 0); -- ram_rom_access <= true; -- Refresh setzen -- ram0_ce_next <= '0'; -- ram0_ce ist auch flash_ce -- ram_oe_next <= '0'; -- flash output enable ---- end if; -- end if; -- end if; -- if (adr >= x"8000" and adr <= x"BFFF") then -- Moon-Patrol einblenden -- if (rw = '1') then -- if (phi2 = '1') then -- option_flash_ram <= true; -- ram_rom_adr_next(18 downto 14) <= "11111"; -- Im Flash Adr. 7C000 Moon-Patrol 16K -- ram_rom_adr_next(13 downto 0) <= adr(13 downto 0); -- 3FFF Bytes einblenden -- ram_rom_access <= true; -- rom_ce_next <= '1'; -- rom_oe_next <= '1'; -- ram0_ce_next <= '0'; -- ram1_ce_next <= '1'; -- ram_oe_next <= '0'; -- end if; -- end if; -- end if; end process ram_rom_einblenden; ---------------------------------------------------------------------------------- set_bustreiber: process(data_out, data_out_enable, ram_rom_access, phi2, rw) begin data_dir <= '0'; -- Datenbus FPGA < ATARI (Atari Schreibzugriffe) data_en <= '0'; -- Bustreiber einschalten data <= (others => 'Z'); adress_en <= '0'; -- Adressbus fest auf lesen adress_dir <= '0'; -- vom Atari einstellen. if (phi2 = '1') then if (rw = '1') then if (ram_rom_access = true) then data_en <= '1'; -- Bustreiber abschalten, wenn RAM/ROM Zugriffe stattfinden, else -- da RAM und ROM direkt am ATARI Datenbus hängen! if (data_out_enable) then data_dir <= '1'; -- Datenbus FPGA > ATARI (Atari Lesezugiffe) data_en <= '0'; -- Bustreiber einschalten data <= data_out; end if; end if; end if; end if; end process set_bustreiber; ------------------------------------------------------------------------------- set_refresh: process(data_out_enable, ram_rom_access) begin refresh <= '0'; if (data_out_enable or ram_rom_access or(adr >= x"D304" and adr <= x"D3FF" and run_ok)) then refresh <= '1'; end if; end process set_refresh; ----------------------------------------------------------------------------- -- Adress-Decodierungen ----------------------------------------------------------------------------- -- $0244 Kaltstart Flag abfragen ----------------------------------------------------------------------------- decode_0244: process(adr, phi2short, rw, data, enable_adrset) begin if falling_edge(phi2short) then if (adr = x"0244") then coldst <= true; if (data <= x"00") then coldst <= false; end if; end if; end if; end process decode_0244; ----------------------------------------------------------------------------- -- Vergleich, ob aktuelle Adresse der eingestellten Debug-Adresse gleich ist ----------------------------------------------------------------------------- decode_debug: process(phi2short, rw, adr, data, read_access_enable, write_access_enable) begin if falling_edge(phi2short) then if (adr = debug_adr) then if (read_access_enable) or (write_access_enable) then data_in <= data; end if; end if; end if; end process decode_debug; ----------------------------------------------------------------------------- -- Vergleich, ob aktuelle Adresse der eingestellten Trigger-Adresse gleich ist ----------------------------------------------------------------------------- decode_trigger: process(phi2short, adr, data, trigger_en, trigger_write_access_enable, trigger_read_access_enable) begin if falling_edge(phi2short) then trigger <= '0'; if (adr = trigger_adr) then if (trigger_read_access_enable) then -- read trigger_adr_data <= data; if (trigger_en) then trigger <= '1'; else trigger <= '0'; end if; if (piep_enable) then piep_out <= true; else piep_out <= false; end if; end if; if (trigger_write_access_enable) then -- write trigger_adr_data <= data; if (trigger_en) then trigger <= '1'; else trigger <= '0'; end if; if (piep_enable) then piep_out <= true; else piep_out <= false; end if; end if; end if; end if; end process decode_trigger; --------------------------------------------------------------------------- -- $D3C6 LO-Byte der GPIO übernehmen --------------------------------------------------------------------------- decode_d3c6: process(phi2short, rw, adr, data, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3C6") and (rw = '0') then gpio(7 downto 0) <= data; end if; end if; end process decode_d3c6; --------------------------------------------------------------------------- -- $D3C7 HI-Byte der GPIO übernehmen --------------------------------------------------------------------------- decode_d3c7: process(phi2short, rw, adr, data, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3C7") and (rw = '0') then gpio(13 downto 8) <= data(5 downto 0); end if; end if; end process decode_d3c7; ----------------------------------------------------------------------------- -- $D3F0 REGISTER-WRITE-ENABLE Byte übernehmen -- (nur bei #$55 werden Schreibzugriffe auf die Trigger-Adress-Register erlaubt) ----------------------------------------------------------------------------- decode_d3f0: process(phi2short, rw, adr, data, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F0") and (rw = '0') and (run_ok) then trigger_we <= data; if (data = x"55") then dp(12) <= '1'; -- Dezimalpunkt der 12.Anzeige einschalten für WriteEnable enable_trgset <= true; else dp(12) <= '0'; -- Dezimalpunkt der 12.Anzeige ausschalten für WriteProtect enable_trgset <= false; end if; end if; end if; end process decode_d3f0; --------------------------------------------------------------------------- -- $D3F1 ENABLE Byte der Triggeradresse übernehmen, muss "T" / #$54 sein --------------------------------------------------------------------------- decode_d3f1: process(phi2short, rw, adr, data, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F1") and (rw = '0') and (run_ok) then -- ohhh, scheinbar wird D301 auch beschrieben!################################ if (enable_trgset) then trigger_enable <= data; if (data = x"54") then ----------------- T trigger_en <= true; dp(10) <= '1'; else trigger_en <= false; dp(10) <= '0'; end if; end if; end if; end if; end process decode_d3f1; ----------------------------------------------------------------------------- -- $D3F2 Piep-Trigger ----------------------------------------------------------------------------- decode_d3f2: process(adr, phi2short, rw, data, enable_adrset, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F2") and (rw = '0') and (run_ok) then if (enable_trgset = true) then piep <= data; if (data = x"50") then -- P dp(11) <= '1'; -- Dezimalpunkt der 11.Anzeige einschalten für PiepEnable piep_enable <= true; else piep_enable <= false; dp(11) <= '0'; -- Dezimalpunkt der 11.Anzeige ausschalten für PiepDisable end if; end if; end if; end if; end process decode_d3f2; divide_piep_frequency: process(phi2short, piep_divisor) begin if falling_edge(phi2short) then if (piep_enable) then if (piep_divisor >= 3540) then -- 1kHz bei 1.77Mhz Clock piep_divisor <= 0; else piep_divisor <= piep_divisor + 1; if (piep_out) then if (piep_divisor <1770) then audio <= '1'; -- PBI Audio Ausgang ansteuern else audio <= '0'; -- PBI Audio Ausgang ansteuern end if; end if; end if; end if; end if; end process divide_piep_frequency; --------------------------------------------------------------------------- -- $D3F4 READ-Enable Byte der Trigger-Adresse übernehmen -- (damit werden Lesezugriffe auf der Triggeranzeige erlaubt) ----------------------------------------------------------------------------- decode_d3f4: process(phi2short, rw, adr, data, enable_trgset, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F4") and (rw = '0') and (run_ok) then if (enable_trgset) then trigger_rd <= data; if (data = x"52") then ----------------- R trigger_read_access_enable <= true; else trigger_read_access_enable <= false; end if; end if; end if; end if; end process decode_d3f4; ----------------------------------------------------------------------------- -- $D3F5 WRITE-Enable Byte der Trigger-Adresse übernehmen -- (damit werden Schreibzugriffe auf der Triggeranzeige erlaubt) ----------------------------------------------------------------------------- decode_d3f5: process(phi2short, rw, adr, data, enable_trgset, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F5") and (rw = '0') and (run_ok) then if (enable_trgset) then trigger_wr <= data; if (data = x"57") then ----------------- W trigger_write_access_enable <= true; else trigger_write_access_enable <= false; end if; end if; end if; end if; end process decode_d3f5; --------------------------------------------------------------------------- -- $D3F6 LO-Byte der Triggeradresse übernehmen --------------------------------------------------------------------------- decode_d3f6: process(phi2short, rw, adr, data, enable_trgset,run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F6") and (rw = '0') and (run_ok) then if enable_trgset then trigger_adr(7 downto 0) <= data; end if; end if; end if; end process decode_d3f6; --------------------------------------------------------------------------- -- $D3F7 HI-Byte der Triggeradresse übernehmen --------------------------------------------------------------------------- decode_d3f7: process(phi2short, rw, adr, data, enable_trgset,run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F7") and (rw = '0') and (run_ok) then if enable_trgset then trigger_adr(15 downto 8) <= data; end if; end if; end if; end process decode_d3f7; ----------------------------------------------------------------------------- -- $D3F8 REGISTER-WRITE-ENABLE Byte übernehmen -- (nur bei #$55 werden Schreibzugriffe auf die DebugAdr-Register erlaubt) ----------------------------------------------------------------------------- decode_d3f8: process(phi2short, rw, adr, data, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3F8") and (rw = '0') and (run_ok) then debug_we <= data; if (data = x"55") then dp(6) <= '1'; -- Dezimalpunkt der 6.Anzeige einschalten für WriteEnable enable_adrset <= true; else dp(6) <= '0'; -- Dezimalpunkt der 6.Anzeige ausschalten für WriteProtect enable_adrset <= false; end if; end if; end if; end process decode_d3f8; ----------------------------------------------------------------------------- -- $D3FC READ-Enable Byte der Debug-Adresse übernehmen -- (damit werden Lesezugriffe auf der Debuganzeige erlaubt) ----------------------------------------------------------------------------- decode_d3fc: process(phi2short, rw, adr, data, enable_adrset, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3FC") and (rw = '0') and (run_ok) then if enable_adrset then debug_rd <= data; if (data = x"52") then ----------------- R read_access_enable <= true; else read_access_enable <= false; end if; end if; end if; end if; end process decode_d3fc; ----------------------------------------------------------------------------- -- $D3FD WRITE-Enable Byte der Debug-Adresse übernehmen -- (damit werden Schreibzugriffe auf der Debuganzeige erlaubt) ----------------------------------------------------------------------------- decode_d3fd: process(phi2short, rw, adr, data, enable_adrset, run_ok) begin if falling_edge(phi2short) then if (adr = x"D3FD") and (rw = '0') and (run_ok) then if enable_adrset then debug_wr <= data; if (data = x"57") then ----------------- W write_access_enable <= true; else write_access_enable <= false; end if; end if; end if; end if; end process decode_d3fd; ----------------------------------------------------------------------------- -- $D3FE LO-Byte der Debug-Adresse übernehmen ----------------------------------------------------------------------------- decode_d3fe: process(phi2short, rw, adr, data, enable_adrset) begin if falling_edge(phi2short) then if (adr = x"D3FE") and (rw = '0') then if enable_adrset then debug_adr(7 downto 0) <= data; end if; end if; end if; end process decode_d3fe; ----------------------------------------------------------------------------- -- $D3FF HI-Byte der Debug-Adresse übernehmen ----------------------------------------------------------------------------- decode_d3ff: process(phi2short, rw, adr, data, enable_adrset) begin if falling_edge(phi2short) then if (adr = x"D3FF") and (rw = '0') then if enable_adrset then debug_adr(15 downto 8) <= data; end if; end if; end if; end process decode_d3ff; ----------------------------------------------------------------------------- -- Hier wird ein Zähler bis 2000000 hochgezählt, um die Zeit, -- die das OS braucht zum löschen aller Adressen (auch D3FE/FF) zu überbrücken -- Beim Reset muss dieser Zähler erneut starten, sonst löscht das OS ebenfalls -- den $D3FE/FF Bereich und die Debugadresse ist futsch. ----------------------------------------------------------------------------- delay_reset: process(phi2short, reset_n_in, run_ok, reset_n_sync1, reset_n_sync) begin if falling_edge(phi2short) then if (reset_n_sync = '0') then reset_delay <= 0; else if (reset_delay = 2000000) then run_ok <= true; else run_ok <= false; reset_delay <= reset_delay + 1; end if; end if; end if; end process delay_reset; ----------------------------------------------------------------------------- -- two-stage synchronizer for reset input ----------------------------------------------------------------------------- sync_reset: process(phi2short) begin if falling_edge(phi2short) then reset_n_sync <= reset_n_sync1; reset_n_sync1 <= reset_n_in; end if; end process sync_reset; ----------------------------------------------------------------------------- -- Hier sind einige Testroutinen die zu Kontrolle des Boards gebraucht werden. -- Diese Routinen können später, wenn alles ok ist, gelöscht werden oder -- mit den "option_xxxx"-Signalen abgeschaltet werden. -- Solange das "Grundgerüst" nicht 100%ig fertig ist, sollten diese bleiben. ----------------------------------------------------------------------------- test: process(clk50, phi2, phi2short, option_test_quarz, option_test_schalter) begin --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if falling_edge(clk50) then -- ok, der quarzoszillator funktioniert! if (option_test_quarz = true) then if (delay2 > 5000000) then led10 <= '0'; -- LED 10 blinken .... else led10 <= '1'; -- ... lassen, als Lebenszeichen end if; if (delay2 >= 10000000) then delay2 <= 0; else delay2 <= delay2 + 1; end if; end if; end if; --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if falling_edge(phi2) then if (option_test_schalter = true) then led1 <= sw0; led2 <= sw1; led3 <= sw2; led4 <= sw3; led5 <= sw4; led6 <= sw5; led7 <= sw6; led8 <= sw7; led9 <= reset_n_in; led9 <= ta0 or ta1; led15 <= not gpin(0); led16 <= not gpin(1); end if; end if; --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end process test; end Behavioral;