-- --------------------------------------------------------------------- -- ES5700 GLU -- based on EPS schematics, ES5570, 74161, and 7474 datasheet -- incorporates PLAs (U29/31/33), 74LS161 (U38), 3x 74LS74 (U30/34/39), -- and 74LS138 (U32) -- --------------------------------------------------------------------- -- slightly expanded to fully decode -- Expansion Memory (range 3c.0000-3f.ffff, external device #3) -- Sample RAM (range 80.0000-bf.ffff, upper 4MB/2MW) -- --------------------------------------------------------------------- -- -- V1.0 2019-11-27 by Rainer Buchty, rainer@buchty.net -- syntax test only (ghdl -a) -- -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Definite memory map for DOC-II/OTIS/OTTO machines -- --------------------------------------------------------------------- -- 00.0000-01.ffff OSRAM (bottom) (typically 64k used, depending on machine) -- 20.0000-23.ffff DOC-II/OTIS/OTTO range (only 1e bytes used); TS10/12 places DUART here, byte access -- 24.0000-25.ffff DMAC (only ff bytes used; only on samplers; synths place ESP here) -- 26.0000-27.ffff ESP (only 3f bytes used) -- 28.0000-2b.ffff DUART (only 1d bytes used) TS10/12 places FDC here (uPD72069 / uA765) -- 2c.0000-2f.ffff FDC / Cartridge (Cartridge only on diskless machines) WD1772 -- 30.0000-33.ffff External device #1 TS10/12 places OTTO here -- 34.0000-37.ffff External device #2 -- 38.0000-3b.ffff External device #3 TS10/12 places ESP here -- 3c.0000-3f.ffff External device #4 (maybe used on ASR/TS, not on earlier ones) -- 40.0000-bf.ffff Sample Memory (size used depending on machine, 8MB only with OTTO machines ASR/TS) -- c0.0000-df.ffff OS ROM (64k to 512k used, depending on machine) -- e0.0000-ff.ffff OSRAM (top) (typically 64k used, depending on machine) -- -- DMAC/ESP ranges split using GLU's cs_dmac# and A17 via 74139, cf. e.g. EPS16 schematics library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity es5570 is port( -- general control clk10, -- 10MHz input clock (GLU also drives xtal to TTL) -- clk8, -- 8MHz input clock (GLU only drives xtal to TTL) cs_oe: in std_logic; -- '1' enables cs_fdc and cs_doc as outputs, typically clamped to Vcc -- CPU inputs cpu_as, -- address strobe cpu_uds, -- upper data strobe cpu_lds, -- lower data strobe cpu_rw: in std_logic; -- read/write cpu_al: in std_logic_vector(2 downto 1); -- A(2:1) cpu_ah: in std_logic_vector(23 downto 18); -- A(23:18) cpu_fc: in std_logic_vector(2 downto 0); -- function code -- peripheral inputs dmac_own, -- '0': bus owned by DMAC dmac_dben, -- '0': DMAC data buffer enable (data portion of bus cycle) dmac_irq, -- '0': DMAC IRQ duart_irq, -- '0': DUART IRQ doc_irq, -- '0': DOC IRQ doc_ras, -- RAS# doc_cas, -- CAS# doc_da18, -- DA18 doc_dbus: in std_logic; -- '0': DOC bus access -- dram input dram_1mb: in std_logic; -- '0': 1MB of sound RAM installed -- counter input fclk_mute: in std_logic; -- '1': preset counter fclk_preset: in std_logic_vector(3 downto 0); -- 4-bit counter preset input -- output clocks clk_5m, -- clk10 div 2 clk_500k, -- clk10 div 20 fclk: out std_logic; -- FCLK counter for analog section -- CPU feedback cpu_dtack, -- '0': data transfer ack cpu_vpa: out std_logic; -- '0': autovector cpu_ipl: out std_logic_vector(1 downto 0); -- interrupt priority level -- periphery chip selects cs_osram, -- 00.0000-00.7fff (bottom), ff.0000-ff.7fff (top) cs_sram, -- 40.0000-bf.ffff (GLU only supports up to 7f.ffff) cs_osrom, -- c0.0000-cf.ffff (depending on machine) cs_dmac, -- 24.0000-27.ffff (used: 24.0000-24.00ff, on ESP machines split into DMAC and ESP) cs_duart: out std_logic; -- 28.0000-2b.ffff (used: 28.0001-28.001f) cs_excs: out std_logic_vector(3 downto 0); -- 30.0000-3f.ffff (GLU only supports excs[2:0] up to 3b.ffff) -- external pulldown forces internal FF/counter reset cs_doc, -- 20.0000-23.ffff (20.0000-20.001e) cs_fdc: inout std_logic; -- 2c.0000-2f.ffff (FDC: 2c.0001-2c.0007; Cartridge: 2c.0000-2c.ffff) -- periphery IACK dmac_iack, duart_iack: out std_logic; -- RAM read/write control sram_ugwe, -- SRAM: CPU/DOC sram_lgwe, cpu_uwe, -- RAM/OS: CPU-only cpu_lwe, cpu_urd, cpu_lrd: out std_logic; -- DRAM banks dram_cas: out std_logic_vector(1 downto 0); -- CAS0#, CAS1# -- TTL control en_138, -- only needed in case of external 138 (DIP64, not PLCC68) that generates cs_# en_244, en_245u, en_245l: out std_logic ); end entity; architecture rtl of es5570 is -- ICU signals signal icu_ipl: std_logic_vector(1 downto 0); signal icu_duiack, icu_dmiack, icu_vpa, icu_iack, icu_super, icu_dtack: std_logic; -- MMU signals signal mmu_cs_doc, mmu_cs_dmac, mmu_cs_duart, mmu_cs_fdc, mmu_cs_sram, mmu_cs_osram, mmu_cs_osrom, mmu_cs_io, mmu_da18l, mmu_dtack: std_logic; signal mmu_cs_excs: std_logic_vector(3 downto 0); -- standard GLU only supports (2:0) signal mmu_dram_cas: std_logic_vector(1 downto 0); -- standard GLU only supports (0) -- BCU signals signal bcu_ds, bcu_urd, bcu_uwe, bcu_lrd, bcu_lwe, bcu_ugwe, bcu_lgwe, bcu_u245en, bcu_l245en, bcu_en244: std_logic; -- additional signals signal rst, ls74_5m, ls74_fdcdly, ls74_fclk, ls161_ld, ls161_rco: std_logic; signal ls161_cnt: std_logic_vector(3 downto 0); signal cnt_johnson: std_logic_vector(4 downto 0); -- helpers signal a: std_logic_vector(23 downto 1) := cpu_ah & "000000000000000" & cpu_al; begin -- --------------------------------------------------------------------- -- Interrupt Control Unit (82S153/U33), cf. page 12/13 -- --------------------------------------------------------------------- -- interrupt priority level (cf. page 2) icu_ipl(0) <= '0' when duart_irq='0' else '0' when doc_irq='0' and dmac_irq='1' else '1'; icu_ipl(1) <= '0' when duart_irq='0' else '0' when dmac_irq='0' else '1'; -- CPU states fed into MMU, cf. EPS schematics icu_iack <= '0' when cpu_fc="111" else '1'; icu_super <= '0' when cpu_fc="110" else '1'; -- interrupt acknowledge icu_duiack <= '0' when cpu_as='0' and icu_iack='0' and a(2 downto 1) = "11" else '1'; icu_dmiack <= '0' when cpu_as='0' and icu_iack='0' and a(2 downto 1) = "10" else '1'; icu_vpa <= '0' when cpu_as='0' and icu_iack='0' and a(2 downto 1) = "01" else '1'; -- pin wiring cpu_ipl <= icu_ipl; duart_iack <= icu_duiack; dmac_iack <= icu_dmiack; cpu_vpa <= icu_vpa; cpu_dtack <= icu_iack when mmu_dtack ='1' else 'Z'; -- according to EPS schematics -- --------------------------------------------------------------------- -- Memory Management Unit (74LS138/U32), cf. page 2 -- --------------------------------------------------------------------- mmu_cs_doc <= '0' when a(23 downto 18)="001000" else '1'; -- Y0: 20-23 mmu_cs_dmac <= '0' when a(23 downto 18)="001001" else '1'; -- Y1: 24-27 VFX: ESP; otherwise: further divided by 74139 into DMAC (24/25) and ESP (26/27) mmu_cs_duart <= '0' when a(23 downto 18)="001010" else '1'; -- Y2: 28-2b mmu_cs_fdc <= '0' when a(23 downto 18)="001011" else '1'; -- Y3: 2c-2f VFX: cartridge, otherwise FDC mmu_cs_excs(0) <= '0' when a(23 downto 18)="001100" else '1'; -- Y4: 30-33 mmu_cs_excs(1) <= '0' when a(23 downto 18)="001101" else '1'; -- Y5: 34-37 mmu_cs_excs(2) <= '0' when a(23 downto 18)="001110" else '1'; -- Y6: 38-3b mmu_cs_excs(3) <= '0' when a(23 downto 18)="001111" else '1'; -- Y7: 3c-3f spare -- pin wiring cs_dmac <= mmu_cs_dmac; cs_duart <= mmu_cs_duart; cs_excs <= mmu_cs_excs; -- pin wiring (these also work as inputs, cf. page 5) cs_doc <= mmu_cs_doc when cs_oe='1' else 'Z'; cs_fdc <= mmu_cs_fdc when cs_oe='1' else 'Z'; -- --------------------------------------------------------------------- -- Memory Management Unit (74LS74/U30b, 74LS04/U19b) -- --------------------------------------------------------------------- process(doc_ras) begin if falling_edge(doc_ras) then mmu_da18l <= doc_da18; end if; end process; -- --------------------------------------------------------------------- -- Memory Management Unit (82S153/U31), cf. page 14/15 -- --------------------------------------------------------------------- -- CS signals mmu_cs_sram <= '0' when a(23 downto 22)="01" -- 40-7f else '0' when a(23 downto 22)="10" -- 80-bf 4MB spare in sample memory space else '1'; -- -> used in ASR10/88 and TS10/12 for 8MB sample RAM window mmu_cs_osram <= '0' when cpu_as='0' and a(23 downto 21)="000" and icu_super='1' -- 00/1f user mode else '0' when cpu_as='0' and a(23 downto 21)="111" and icu_iack='1' -- e0/ff else '1'; mmu_cs_osrom <= '0' when cpu_as='0' and a(23 downto 21)="000" and icu_super='0' -- 00/1f supervisor mode else '0' when cpu_as='0' and a(23 downto 21)="110" -- c0/df else '1'; mmu_cs_io <= '0' when cpu_as='0' and a(23 downto 21)="001" else '1'; -- 20/3f (required only if external 74LS138 is used / DIP64 GLU) -- MMU DT feeds ICU DT according to EPS schem. mmu_dtack <= '0' when mmu_cs_osram='0' else '0' when mmu_cs_osrom='0' else '0' when ls74_fdcdly='0' else '1'; mmu_dram_cas(0) <= '0' when doc_cas='0' and doc_dbus='1' and cpu_as='0' and a(23 downto 21)="010" else '0' when doc_cas='0' and doc_dbus='0' and mmu_da18l='1' and dram_1mb='1' else '1'; mmu_dram_cas(1) <= '0' when doc_cas='0' and doc_dbus='1' and cpu_as='0' and a(23 downto 21)="011" else '0' when doc_cas='0' and doc_dbus='0' and mmu_da18l='0' and dram_1mb='1' else '0' when doc_cas='0' and doc_dbus='0' and dram_1mb='0' else '1'; -- pin wiring cs_sram <= mmu_cs_sram; cs_osram <= mmu_cs_osram; cs_osrom <= mmu_cs_osrom; dram_cas <= mmu_dram_cas; en_138 <= mmu_cs_io; -- --------------------------------------------------------------------- -- Bus Control Unit (82S153/U29), cf. page 16/17 -- --------------------------------------------------------------------- -- data strobe bcu_ds <= '0' when dmac_own='1' and (cpu_uds='0' or cpu_lds='0') -- CPU owns bus else '0' when dmac_own='0' and (cpu_uds='0' or cpu_lds='0') and dmac_dben='0' -- DMAC owns bus else '1'; -- upper/lower transfers bcu_urd <= '0' when cpu_rw='1' and cpu_uds='0' and bcu_ds='0' else '1'; -- upper byte read bcu_uwe <= '0' when cpu_rw='0' and cpu_uds='0' and bcu_ds='0' else '1'; -- upper byte write bcu_lrd <= '0' when cpu_rw='1' and cpu_lds='0' and bcu_ds='0' else '1'; -- lower byte read bcu_lwe <= '0' when cpu_rw='0' and cpu_lds='0' and bcu_ds='0' else '1'; -- lower byte write bcu_ugwe <= '0' when cpu_rw='0' and doc_dbus='1' and mmu_cs_sram='0' and cpu_uds='0' else '1'; -- shared RAM upper byte write bcu_lgwe <= '0' when cpu_rw='0' and doc_dbus='1' and mmu_cs_sram='0' and cpu_lds='0' else '1'; -- shared RAM lower byte write -- bus buffer upper byte enable bcu_u245en <= '0' when mmu_cs_sram='0' and doc_dbus='1' and cpu_uds='0' and bcu_ds='0' -- SRAM access else '0' when mmu_cs_doc='0' and doc_dbus='1' -- DOC/OTIS/OTTO access else '1'; bcu_l245en <= '0' when mmu_cs_sram='0' and doc_dbus='1' and cpu_lds='0' and bcu_ds='0' -- SRAM access else '0' when mmu_cs_doc='0' and doc_dbus='1' -- DOC/OTIS/OTTO access else '1'; -- low-nibble pulldown bcu_en244 <= '0' when mmu_cs_sram='0' and doc_dbus='0' and cpu_rw='1' else '1'; -- pin wiring cpu_urd <= bcu_urd; cpu_uwe <= bcu_uwe; cpu_lrd <= bcu_lrd; cpu_lwe <= bcu_lwe; sram_ugwe <= bcu_ugwe; sram_lgwe <= bcu_lgwe; en_245u <= bcu_u245en; en_245l <= bcu_l245en; en_244 <= bcu_en244; -- --------------------------------------------------------------------- -- misc stuff that went into GLU according to the datasheet -- --------------------------------------------------------------------- -- external pulldown generates counter/FF reset (cf. page 5) rst <= '0' when cs_fdc='0' and cs_doc='0' else '1'; -- --------------------------------------------------------------------- -- FDC CS# delay (EPS: 74LS74/U30a) -- 5M clock divider (EPS: 74LS74/U34b) -- --------------------------------------------------------------------- process(clk10, rst) begin -- reset, cf. page 5 if rst='0' then ls74_fdcdly <='1'; ls74_5m <= '0'; -- cf. EPS schematics elsif rising_edge(clk10) then ls74_fdcdly <= mmu_cs_fdc; -- U30a ls74_5m <= not(ls74_5m); -- U34b end if; end process; -- pin wiring clk_5m <= ls74_5m; -- --------------------------------------------------------------------- -- 500kHz clock generation, 10MHz:20 (cf. page 4) -- --------------------------------------------------------------------- -- In the EPS, this is derived from 68k E clock and 74LS74/U34a -- GLU however does not get E clock -- -> 5-stage Johnson counter clocked by 5MHz (5MHz:10) -- --------------------------------------------------------------------- process(ls74_5m, rst) begin -- reset, cf. page 5 if rst='0' then cnt_johnson <= "00000"; elsif rising_edge(ls74_5m) then cnt_johnson(3 downto 0) <= cnt_johnson(4 downto 1); cnt_johnson(4) <= not(cnt_johnson(0)); end if; end process; -- pin wiring clk_500k <= cnt_johnson(0); -- --------------------------------------------------------------------- -- FCLK generation: 4-bit presettable counter -- (EPS: 74LS161/U37, 74LS74/U39) -- --------------------------------------------------------------------- process(clk10, fclk_mute, rst) begin -- reset, cf. page 5 if rst='0' then ls161_cnt <= "0000"; -- mute, cf. EPS schematics elsif fclk_mute='0' then ls161_ld <= '0'; -- counter/loading, cf. EPS schematics elsif rising_edge(clk10) then -- counter if ls161_ld='1' then ls161_cnt <= fclk_preset; else ls161_cnt <= std_logic_vector(unsigned(ls161_cnt) + 1); end if; -- load FF if ls161_rco='1' then ls161_ld <= '1'; else ls161_ld <= '0'; end if; end if; end process; ls161_rco <= '1' when ls161_cnt="1111" else '0'; -- final fclk generation, cf. EPS schematics process(ls161_rco) begin if rising_edge(ls161_rco) then ls74_fclk <= not(ls74_fclk); end if; end process; -- pin wiring fclk <= ls74_fclk; end architecture;