mirror of
https://github.com/brouhaha/Apple-II_MiSTer.git
synced 2024-10-06 14:54:59 +00:00
252 lines
6.9 KiB
VHDL
252 lines
6.9 KiB
VHDL
--
|
|
--
|
|
-- Apple II+ toplevel for the MiST board
|
|
-- https://github.com/wsoltys/mist_apple2
|
|
--
|
|
-- Copyright (c) 2014 W. Soltys <wsoltys@gmail.com>
|
|
--
|
|
-- This source file is free software: you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published
|
|
-- by the Free Software Foundation, either version 3 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This source file is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License
|
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
--
|
|
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity apple2_top is port
|
|
(
|
|
-- Clocks
|
|
CLK_28M : in std_logic;
|
|
CLK_14M : in std_logic;
|
|
CPU_WAIT : in std_logic;
|
|
|
|
reset_in : in std_logic;
|
|
|
|
-- VGA output
|
|
VGA_DE : out std_logic;
|
|
VGA_CLK : out std_logic;
|
|
VGA_HS : out std_logic;
|
|
VGA_VS : out std_logic;
|
|
VGA_R : out std_logic_vector(7 downto 0);
|
|
VGA_G : out std_logic_vector(7 downto 0);
|
|
VGA_B : out std_logic_vector(7 downto 0);
|
|
SCREEN_MODE : in std_logic_vector(1 downto 0); -- 00: Color, 01: B&W, 10:Green, 11: Amber
|
|
|
|
-- Audio
|
|
AUDIO_L : out std_logic_vector(7 downto 0);
|
|
AUDIO_R : out std_logic_vector(7 downto 0);
|
|
SPEAKER : out std_logic;
|
|
|
|
ps2Clk : in std_logic;
|
|
ps2Data : in std_logic;
|
|
|
|
joy : in std_logic_vector(5 downto 0);
|
|
joy_an : in std_logic_vector(15 downto 0);
|
|
|
|
-- mocking board
|
|
mb_enabled : in std_logic;
|
|
|
|
-- disk control
|
|
TRACK : out unsigned(5 downto 0);
|
|
TRACK_RAM_ADDR : in unsigned(12 downto 0);
|
|
TRACK_RAM_DI : in unsigned(7 downto 0);
|
|
TRACK_RAM_WE : in std_logic;
|
|
|
|
-- main RAM
|
|
ram_addr : out std_logic_vector(17 downto 0);
|
|
ram_dout : in std_logic_vector(7 downto 0);
|
|
ram_din : out std_logic_vector(7 downto 0);
|
|
ram_we : out std_logic;
|
|
|
|
-- LEDG
|
|
LED : out std_logic
|
|
);
|
|
|
|
end apple2_top;
|
|
|
|
architecture datapath of apple2_top is
|
|
|
|
signal CLK_2M, PRE_PHASE_ZERO: std_logic;
|
|
signal IO_SELECT, DEVICE_SELECT : std_logic_vector(7 downto 0);
|
|
signal ADDR : unsigned(15 downto 0);
|
|
signal D, PD: unsigned(7 downto 0);
|
|
|
|
signal we_ram : std_logic;
|
|
signal VIDEO, HBL, VBL, LD194 : std_logic;
|
|
signal COLOR_LINE : std_logic;
|
|
signal COLOR_LINE_CONTROL : std_logic;
|
|
signal GAMEPORT : std_logic_vector(7 downto 0);
|
|
signal cpu_pc : unsigned(15 downto 0);
|
|
|
|
signal K : unsigned(7 downto 0);
|
|
signal read_key : std_logic;
|
|
|
|
signal flash_clk : unsigned(22 downto 0) := (others => '0');
|
|
signal power_on_reset : std_logic := '1';
|
|
signal reset : std_logic;
|
|
|
|
signal a_ram: unsigned(17 downto 0);
|
|
|
|
signal joyx : std_logic;
|
|
signal joyy : std_logic;
|
|
signal pdl_strobe : std_logic;
|
|
|
|
begin
|
|
|
|
reset <= power_on_reset;
|
|
|
|
power_on : process(CLK_14M, reset_in)
|
|
begin
|
|
if reset_in = '1' then
|
|
power_on_reset <= '1';
|
|
elsif rising_edge(CLK_14M) then
|
|
if flash_clk(22) = '1' then
|
|
power_on_reset <= '0';
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- In the Apple ][, this was a 555 timer
|
|
flash_clkgen : process (CLK_14M, reset_in)
|
|
begin
|
|
if reset_in = '1' then
|
|
flash_clk <= (others=>'0');
|
|
elsif rising_edge(CLK_14M) then
|
|
flash_clk <= flash_clk + 1;
|
|
end if;
|
|
end process;
|
|
|
|
-- Paddle buttons
|
|
-- GAMEPORT input bits:
|
|
-- 7 6 5 4 3 2 1 0
|
|
-- pdl3 pdl2 pdl1 pdl0 pb3 pb2 pb1 casette
|
|
GAMEPORT <= "00" & joyy & joyx & "0" & joy(5) & joy(4) & "0";
|
|
|
|
process(CLK_2M, pdl_strobe)
|
|
variable cx, cy : integer range -100 to 5800 := 0;
|
|
begin
|
|
if rising_edge(CLK_2M) then
|
|
if cx > 0 then
|
|
cx := cx -1;
|
|
joyx <= '1';
|
|
else
|
|
joyx <= '0';
|
|
end if;
|
|
if cy > 0 then
|
|
cy := cy -1;
|
|
joyy <= '1';
|
|
else
|
|
joyy <= '0';
|
|
end if;
|
|
if pdl_strobe = '1' then
|
|
cx := 2800+(22*to_integer(signed(joy_an(7 downto 0))));
|
|
cy := 2800+(22*to_integer(signed(joy_an(15 downto 8)))); -- max 5650
|
|
if cx < 0 then
|
|
cx := 0;
|
|
elsif cx >= 5590 then
|
|
cx := 5650;
|
|
end if;
|
|
if cy < 0 then
|
|
cy := 0;
|
|
elsif cy >= 5590 then
|
|
cy := 5650;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
COLOR_LINE_CONTROL <= COLOR_LINE and not (SCREEN_MODE(0) or SCREEN_MODE(1)); -- Color or B&W mode
|
|
|
|
-- Simulate power up on cold reset to go to the disk boot routine
|
|
ram_we <= we_ram; -- when reset_in = '0' else '1';
|
|
ram_addr <= std_logic_vector(a_ram); -- when reset_in = '0' else std_logic_vector(to_unsigned(1012,ram_addr'length)); -- $3F4
|
|
ram_din <= std_logic_vector(D); -- when reset_in = '0' else "00000000";
|
|
|
|
core : entity work.apple2 port map (
|
|
CLK_14M => CLK_14M,
|
|
CLK_2M => CLK_2M,
|
|
CPU_WAIT => CPU_WAIT,
|
|
PRE_PHASE_ZERO => PRE_PHASE_ZERO,
|
|
FLASH_CLK => flash_clk(22),
|
|
reset => reset,
|
|
ADDR => ADDR,
|
|
ram_addr => a_ram,
|
|
D => D,
|
|
ram_do => unsigned(ram_dout),
|
|
PD => PD,
|
|
ram_we => we_ram,
|
|
VIDEO => VIDEO,
|
|
COLOR_LINE => COLOR_LINE,
|
|
HBL => HBL,
|
|
VBL => VBL,
|
|
LD194 => LD194,
|
|
K => K,
|
|
read_key => read_key,
|
|
AN => open,
|
|
GAMEPORT => GAMEPORT,
|
|
PDL_strobe => pdl_strobe,
|
|
IO_SELECT => IO_SELECT,
|
|
DEVICE_SELECT => DEVICE_SELECT,
|
|
pcDebugOut => cpu_pc,
|
|
speaker => SPEAKER,
|
|
laudio => AUDIO_L,
|
|
raudio => AUDIO_R,
|
|
mb_enabled => mb_enabled
|
|
);
|
|
|
|
vga : entity work.vga_controller port map (
|
|
CLK_28M => CLK_28M,
|
|
VIDEO => VIDEO,
|
|
COLOR_LINE => COLOR_LINE_CONTROL,
|
|
SCREEN_MODE => SCREEN_MODE,
|
|
HBL => HBL,
|
|
VBL => VBL,
|
|
LD194 => LD194,
|
|
VGA_CLK => VGA_CLK,
|
|
VGA_HS => VGA_HS,
|
|
VGA_VS => VGA_VS,
|
|
VGA_DE => VGA_DE,
|
|
std_logic_vector(VGA_R) => VGA_R,
|
|
std_logic_vector(VGA_G) => VGA_G,
|
|
std_logic_vector(VGA_B) => VGA_B
|
|
);
|
|
|
|
keyboard : entity work.keyboard port map (
|
|
PS2_Clk => ps2Clk,
|
|
PS2_Data => ps2Data,
|
|
CLK_14M => CLK_14M,
|
|
reset => reset,
|
|
reads => read_key,
|
|
K => K
|
|
);
|
|
|
|
disk : entity work.disk_ii port map (
|
|
CLK_14M => CLK_14M,
|
|
CLK_2M => CLK_2M,
|
|
PRE_PHASE_ZERO => PRE_PHASE_ZERO,
|
|
IO_SELECT => IO_SELECT(6),
|
|
DEVICE_SELECT => DEVICE_SELECT(6),
|
|
RESET => reset,
|
|
A => ADDR,
|
|
D_IN => D,
|
|
D_OUT => PD,
|
|
TRACK => TRACK,
|
|
TRACK_ADDR => open,
|
|
D1_ACTIVE => LED,
|
|
D2_ACTIVE => open,
|
|
ram_write_addr => TRACK_RAM_ADDR,
|
|
ram_di => TRACK_RAM_DI,
|
|
ram_we => TRACK_RAM_WE
|
|
);
|
|
|
|
end datapath; |