1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-25 20:11:30 +00:00
Files
Gehstock.Mist_FPGA/Computer_MiST/Oric Atmos_MiST/rtl/oricatmos.vhd
Gehstock b4920d3288 1
2018-10-27 14:54:23 +02:00

399 lines
11 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
entity oricatmos is
port (
CLOCK_27 : in std_logic;
LED : out std_logic;
VGA_R : out std_logic_vector(5 downto 0);
VGA_G : out std_logic_vector(5 downto 0);
VGA_B : out std_logic_vector(5 downto 0);
VGA_HS : out std_logic;
VGA_VS : out std_logic;
SPI_SCK : in std_logic;
SPI_DI : in std_logic;
SPI_DO : out std_logic;
SPI_SS3 : in std_logic;
CONF_DATA0 : in std_logic;
AUDIO_L : out std_logic;
AUDIO_R : out std_logic
);
end;
architecture RTL of oricatmos is
signal VGA_R_O : std_logic_vector(3 downto 0);
signal VGA_G_O : std_logic_vector(3 downto 0);
signal VGA_B_O : std_logic_vector(3 downto 0);
signal hsync : std_logic;
signal vsync : std_logic;
signal hq2x : std_logic;
signal buttons : std_logic_vector(1 downto 0);
signal switches : std_logic_vector(1 downto 0);
signal status : std_logic_vector(31 downto 0);
signal scandoubler_disable : std_logic;
signal scanlines : std_logic_vector(1 downto 0);
signal ypbpr : std_logic;
signal ps2Clk : std_logic;
signal ps2Data : std_logic;
signal loc_reset_n : std_logic; --active low
signal reset : std_logic := '1';
signal clk24 : std_logic := '0';
signal clk12 : std_logic := '0';
signal clk6 : std_logic := '0';
signal pll_locked : std_logic := '0';
signal CPU_ADDR : std_logic_vector(23 downto 0);
signal CPU_DI : std_logic_vector( 7 downto 0);
signal CPU_DO : std_logic_vector( 7 downto 0);
signal cpu_rw : std_logic;
signal cpu_irq : std_logic;
signal ad : std_logic_vector(15 downto 0);
signal via_pa_out_oe : std_logic_vector( 7 downto 0);
signal via_pa_in : std_logic_vector( 7 downto 0);
signal via_pa_out : std_logic_vector( 7 downto 0);
signal via_cb1_out : std_logic;
signal via_cb1_oe_l : std_logic;
signal via_cb2_out : std_logic;
signal via_cb2_oe_l : std_logic;
signal via_in : std_logic_vector( 7 downto 0);
signal via_out : std_logic_vector( 7 downto 0);
signal via_oe_l : std_logic_vector( 7 downto 0);
signal VIA_DO : std_logic_vector( 7 downto 0);
signal KEY_ROW : std_logic_vector( 7 downto 0);
signal psg_bdir : std_logic;
signal PSG_OUT : std_logic_vector( 7 downto 0);
signal ula_phi2 : std_logic;
signal ula_CSIOn : std_logic;
signal ula_CSIO : std_logic;
signal ula_CSROMn : std_logic;
signal SRAM_DO : std_logic_vector( 7 downto 0);
signal ula_AD_SRAM : std_logic_vector(15 downto 0);
signal ula_CE_SRAM : std_logic;
signal ula_OE_SRAM : std_logic;
signal ula_WE_SRAM : std_logic;
signal ula_LE_SRAM : std_logic;
signal ula_CLK_4 : std_logic;
signal ula_IOCONTROL : std_logic;
signal ula_VIDEO_R : std_logic;
signal ula_VIDEO_G : std_logic;
signal ula_VIDEO_B : std_logic;
signal ula_SYNC : std_logic;
signal ROM_DO : std_logic_vector( 7 downto 0);
signal hs_int : std_logic;
signal vs_int : std_logic;
signal dummy : std_logic_vector( 3 downto 0) := (others => '0');
signal s_cmpblk_n_out : std_logic;
constant CONF_STR : string :=
"ORIC;;O89,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;T6,Reset;";
function to_slv(s: string) return std_logic_vector is
constant ss: string(1 to s'length) := s;
variable rval: std_logic_vector(1 to 8 * s'length);
variable p: integer;
variable c: integer;
begin
for i in ss'range loop
p := 8 * i;
c := character'pos(ss(i));
rval(p - 7 to p) := std_logic_vector(to_unsigned(c,8));
end loop;
return rval;
end function;
component mist_io
generic ( STRLEN : integer := 0 );
port (
clk_sys :in std_logic;
SPI_SCK, CONF_DATA0, SPI_DI :in std_logic;
SPI_DO : out std_logic;
conf_str : in std_logic_vector(8*STRLEN-1 downto 0);
buttons : out std_logic_vector(1 downto 0);
switches : out std_logic_vector(1 downto 0);
joystick_0 : out std_logic_vector(7 downto 0);
joystick_1 : out std_logic_vector(7 downto 0);
status : out std_logic_vector(31 downto 0);
scandoubler_disable, ypbpr : out std_logic;
ps2_kbd_clk : out std_logic;
ps2_kbd_data : out std_logic
);
end component mist_io;
component video_mixer
generic ( LINE_LENGTH : integer := 384; HALF_DEPTH : integer := 1 );
port (
clk_sys, ce_pix, ce_pix_actual : in std_logic;
SPI_SCK, SPI_SS3, SPI_DI : in std_logic;
scandoubler_disable, hq2x, ypbpr, ypbpr_full : in std_logic;
scanlines : in std_logic_vector(1 downto 0);
R, G, B : in std_logic_vector(2 downto 0);
HSync, VSync, line_start, mono : in std_logic;
VGA_R,VGA_G, VGA_B : out std_logic_vector(5 downto 0);
VGA_VS, VGA_HS : out std_logic
);
end component video_mixer;
begin
inst_pll : entity work.pll
port map (
areset => open,
inclk0 => CLOCK_27,
c0 => clk24,
c1 => clk12,
c2 => clk6,
locked => pll_locked
);
loc_reset_n <= pll_locked;
--reset <= not status(0) or status(6) or buttons(1);
inst_cpu : entity work.T65
port map (
Mode => "00",
Res_n => loc_reset_n,
Enable => '1',
Clk => ula_phi2,
Rdy => '1',
Abort_n => '1',
IRQ_n => cpu_irq,
NMI_n => '1',
SO_n => '1',
R_W_n => cpu_rw,
Sync => open,
EF => open,
MF => open,
XF => open,
ML_n => open,
VP_n => open,
VDA => open,
VPA => open,
A => CPU_ADDR,
DI => CPU_DI,
DO => CPU_DO
);
-- place Rom in LE and we can use 48kb Memory
-- inst_rom : entity work.rom
-- port map (
-- clk => clk24,
-- ADDR => CPU_ADDR(13 downto 0),
-- DATA => ROM_DO
-- );
-- place in BRAM and reduce Memory to 16kb see file ram48k
inst_rom : entity work.rrom
port map (
clock => clk24,
address => CPU_ADDR(13 downto 0),
q => ROM_DO
);
ad(15 downto 0) <= ula_AD_SRAM when ula_phi2 = '0' else CPU_ADDR(15 downto 0);
inst_ram : entity work.ram48k
port map(
clk => clk24,
cs => ula_CE_SRAM,
oe => ula_OE_SRAM,
we => ula_WE_SRAM,
addr => ad,
di => CPU_DO,
do => SRAM_DO
);
inst_ula : entity work.ULA
port map (
RESETn => loc_reset_n,
CLK => clk24,
CLK_4 => ula_CLK_4,
RW => cpu_rw,
ADDR => CPU_ADDR(15 downto 0),
MAPn => '1',
DB => SRAM_DO,
CSROMn => ula_CSROMn,
CSIOn => ula_CSIOn,
SRAM_AD => ula_AD_SRAM,
SRAM_OE => ula_OE_SRAM,
SRAM_CE => ula_CE_SRAM,
SRAM_WE => ula_WE_SRAM,
LATCH_SRAM => ula_LE_SRAM,
PHI2 => ula_PHI2,
R => ULA_VIDEO_R,
G => ULA_VIDEO_G,
B => ULA_VIDEO_B,
SYNC => ULA_SYNC,
HSYNC => hs_int,
VSYNC => vs_int
);
vmixer : video_mixer
generic map(
HALF_DEPTH => 1,
LINE_LENGTH => 480
)
port map (
clk_sys => clk24,
ce_pix => clk6,
ce_pix_actual => clk6,
SPI_SCK => SPI_SCK,
SPI_SS3 => SPI_SS3,
SPI_DI => SPI_DI,
hq2x => hq2x,
ypbpr => ypbpr,
ypbpr_full => '1',
scanlines => scanlines,
scandoubler_disable => scandoubler_disable,
R => ULA_VIDEO_R & ULA_VIDEO_R & ULA_VIDEO_R,
G => ULA_VIDEO_G & ULA_VIDEO_G & ULA_VIDEO_G,
B => ULA_VIDEO_B & ULA_VIDEO_B & ULA_VIDEO_B,
HSync => hs_int,
VSync => vs_int,
line_start => '0',
mono => '0',
VGA_R => VGA_R,
VGA_G => VGA_G,
VGA_B => VGA_B,
VGA_VS => VGA_VS,
VGA_HS => VGA_HS
);
scanlines(1) <= '1' when status(9 downto 8) = "11" and scandoubler_disable = '0' else '0';
scanlines(0) <= '1' when status(9 downto 8) = "10" and scandoubler_disable = '0' else '0';
hq2x <= '1' when status(9 downto 8) = "01" else '0';
mist_io_inst : mist_io
generic map (STRLEN => CONF_STR'length)
port map (
clk_sys => clk24,
SPI_SCK => SPI_SCK,
CONF_DATA0 => CONF_DATA0,
SPI_DI => SPI_DI,
SPI_DO => SPI_DO,
conf_str => to_slv(CONF_STR),
buttons => buttons,
switches => switches,
scandoubler_disable => scandoubler_disable,
ypbpr => ypbpr,
status => status,
ps2_kbd_clk => ps2Clk,
ps2_kbd_data => ps2Data
);
ula_CSIO <= not ula_CSIOn;
inst_via : entity work.M6522
port map (
I_RS => CPU_ADDR(3 downto 0),
I_DATA => CPU_DO(7 downto 0),
O_DATA => VIA_DO,
O_DATA_OE_L => open,
I_RW_L => cpu_rw,
I_CS1 => ula_CSIO,
I_CS2_L => ula_IOCONTROL,
O_IRQ_L => cpu_irq, -- note, not open drain
I_CA1 => '1', -- PRT_ACK
I_CA2 => '1', -- psg_bdir
O_CA2 => psg_bdir, -- via_ca2_out
O_CA2_OE_L => open,
I_PA => via_pa_in,
O_PA => via_pa_out,
O_PA_OE_L => via_pa_out_oe,
-- I_CB1 => K7_TAPEIN,
I_CB1 => '0',
O_CB1 => via_cb1_out,
O_CB1_OE_L => via_cb1_oe_l,
I_CB2 => '1',
O_CB2 => via_cb2_out,
O_CB2_OE_L => via_cb2_oe_l,
I_PB => via_in,
O_PB => via_out,
O_PB_OE_L => via_oe_l,
RESET_L => loc_reset_n,
I_P2_H => ula_phi2,
ENA_4 => '1',
CLK => ula_CLK_4
);
inst_key : entity work.keyboard
port map(
CLK => clk24,
RESET => '0', -- active high reset
PS2CLK => ps2Clk,
PS2DATA => ps2Data,
COL => via_out(2 downto 0),
ROWbit => KEY_ROW
);
via_in <= x"F7" when (KEY_ROW or VIA_PA_OUT) = x"FF" else x"FF";
inst_psg : entity work.YM2149
port map (
I_DA => via_pa_out,
O_DA => via_pa_in,
O_DA_OE_L => open,
I_A9_L => '0',
I_A8 => '1',
I_BDIR => via_cb2_out,
I_BC2 => '1',
I_BC1 => psg_bdir,
I_SEL_L => '1',
O_AUDIO => PSG_OUT,
RESET_L => loc_reset_n,
ENA => '1',
CLK => ula_PHI2
);
inst_dacl : entity work.DAC
port map (
CLK_DAC => clk24,
RST => loc_reset_n,
IN_DAC => PSG_OUT,
OUT_DAC => AUDIO_L
);
inst_dacr : entity work.DAC
port map (
CLK_DAC => clk24,
RST => loc_reset_n,
IN_DAC => PSG_OUT,
OUT_DAC => AUDIO_R
);
ula_IOCONTROL <= '0';
process
begin
wait until rising_edge(clk24);
-- expansion port
if cpu_rw = '1' and ula_IOCONTROL = '1' and ula_CSIOn = '0' then
CPU_DI <= SRAM_DO;
-- Via
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_CSIOn = '0' and ula_LE_SRAM = '0' then
CPU_DI <= VIA_DO;
-- ROM
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_CSROMn = '0' then
CPU_DI <= ROM_DO;
-- Read data
elsif cpu_rw = '1' and ula_IOCONTROL = '0' and ula_phi2 = '1' and ula_LE_SRAM = '0' then
cpu_di <= SRAM_DO;
end if;
end process;
------------------------------------------------------------
-- K7 PORT
------------------------------------------------------------
-- K7_TAPEOUT <= via_out(7);
-- K7_REMOTE <= via_out(6);
-- K7_AUDIOOUT <= AUDIO_OUT;
------------------------------------------------------------
-- PRINTER PORT
------------------------------------------------------------
-- PRT_DATA <= via_pa_out;
-- PRT_STR <= via_out(4);
LED <= '1';
end RTL;