mirror of https://github.com/zxdos/zxuno.git
Arreglo cores Electron, Apple2
This commit is contained in:
parent
a24ec4713f
commit
121d786705
|
|
@ -1,4 +1,4 @@
|
|||
set -tmpdir "xst/projnav.tmp"
|
||||
set -tmpdir "projnav.tmp"
|
||||
set -xsthdpdir "xst"
|
||||
run
|
||||
-ifn ElectronFpga.prj
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
vhdl work "../source/character_rom.vhd"
|
||||
vhdl work "../source/video_generator.vhd"
|
||||
vhdl work "../source/timing_generator.vhd"
|
||||
vhdl work "../source/PS2_Ctrl.vhd"
|
||||
verilog work "../source/ramcard.v"
|
||||
vhdl work "../source/ps2_intf.vhd"
|
||||
vhdl work "../source/main_roms.vhd"
|
||||
vhdl work "../source/disk_ii_rom.vhd"
|
||||
vhdl work "../source/cpu6502.vhd"
|
||||
vhdl work "../source/vga_controller.vhd"
|
||||
vhdl work "../source/spi_controller.vhd"
|
||||
vhdl work "../source/keyboard.vhd"
|
||||
verilog work "../source/multiboot_v4.v"
|
||||
vhdl work "../source/keyb.vhd"
|
||||
vhdl work "../source/disk_ii.vhd"
|
||||
vhdl work "../source/dac.vhd"
|
||||
vhdl work "../source/clocks.vhd"
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
-- PS2_Ctrl.vhd
|
||||
-- ------------------------------------------------
|
||||
-- Simplified PS/2 Controller (kbd, mouse...)
|
||||
-- ------------------------------------------------
|
||||
-- Only the Receive function is implemented !
|
||||
-- (c) ALSE. http://www.alse-fr.com
|
||||
|
||||
library IEEE;
|
||||
use IEEE.Std_Logic_1164.all;
|
||||
use IEEE.Numeric_Std.all;
|
||||
|
||||
-- --------------------------------------
|
||||
Entity PS2_Ctrl is
|
||||
-- --------------------------------------
|
||||
generic (FilterSize : positive := 8);
|
||||
port( Clk : in std_logic; -- System Clock
|
||||
Reset : in std_logic; -- System Reset
|
||||
PS2_Clk : in std_logic; -- Keyboard Clock Line
|
||||
PS2_Data : in std_logic; -- Keyboard Data Line
|
||||
DoRead : in std_logic; -- From outside when reading the scan code
|
||||
Scan_Err : out std_logic; -- To outside : Parity or Overflow error
|
||||
Scan_DAV : out std_logic; -- To outside when a scan code has arrived
|
||||
Scan_Code : out unsigned(7 downto 0) -- Eight bits Data Out
|
||||
);
|
||||
end PS2_Ctrl;
|
||||
|
||||
-- --------------------------------------
|
||||
Architecture ALSE_RTL of PS2_Ctrl is
|
||||
-- --------------------------------------
|
||||
-- (c) ALSE. http://www.alse-fr.com
|
||||
-- Author : Bert Cuzeau.
|
||||
-- Fully synchronous solution, same Filter on PS2_Clk.
|
||||
-- Still as compact as "Plain_wrong"...
|
||||
-- Possible improvement : add TIMEOUT on PS2_Clk while shifting
|
||||
-- Note: PS2_Data is resynchronized though this should not be
|
||||
-- necessary (qualified by Fall_Clk and does not change at that time).
|
||||
-- Note the tricks to correctly interpret 'H' as '1' in RTL simulation.
|
||||
|
||||
signal PS2_Datr : std_logic;
|
||||
|
||||
subtype Filter_t is std_logic_vector(FilterSize-1 downto 0);
|
||||
signal Filter : Filter_t;
|
||||
signal Fall_Clk : std_logic;
|
||||
signal Bit_Cnt : unsigned(3 downto 0);
|
||||
signal Parity : std_logic;
|
||||
signal Scan_DAVi : std_logic;
|
||||
|
||||
signal S_Reg : unsigned(8 downto 0);
|
||||
|
||||
signal PS2_Clk_f : std_logic;
|
||||
|
||||
Type State_t is (Idle, Shifting);
|
||||
signal State : State_t;
|
||||
|
||||
begin
|
||||
|
||||
Scan_DAV <= Scan_DAVi;
|
||||
|
||||
-- This filters digitally the raw clock signal coming from the keyboard :
|
||||
-- * Eight consecutive PS2_Clk=1 makes the filtered_clock go high
|
||||
-- * Eight consecutive PS2_Clk=0 makes the filtered_clock go low
|
||||
-- Implies a (FilterSize+1) x Tsys_clock delay on Fall_Clk wrt Data
|
||||
-- Also in charge of the re-synchronization of PS2_Data
|
||||
|
||||
process (Clk,Reset)
|
||||
begin
|
||||
if Reset='1' then
|
||||
PS2_Datr <= '0';
|
||||
PS2_Clk_f <= '0';
|
||||
Filter <= (others=>'0');
|
||||
Fall_Clk <= '0';
|
||||
elsif rising_edge (Clk) then
|
||||
PS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1'
|
||||
Fall_Clk <= '0';
|
||||
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);
|
||||
if Filter = Filter_t'(others=>'1') then
|
||||
PS2_Clk_f <= '1';
|
||||
elsif Filter = Filter_t'(others=>'0') then
|
||||
PS2_Clk_f <= '0';
|
||||
if PS2_Clk_f = '1' then
|
||||
Fall_Clk <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- This simple State Machine reads in the Serial Data
|
||||
-- coming from the PS/2 peripheral.
|
||||
|
||||
process(Clk,Reset)
|
||||
begin
|
||||
|
||||
if Reset='1' then
|
||||
State <= Idle;
|
||||
Bit_Cnt <= (others => '0');
|
||||
S_Reg <= (others => '0');
|
||||
Scan_Code <= (others => '0');
|
||||
Parity <= '0';
|
||||
Scan_Davi <= '0';
|
||||
Scan_Err <= '0';
|
||||
|
||||
elsif rising_edge (Clk) then
|
||||
|
||||
if DoRead='1' then
|
||||
Scan_Davi <= '0'; -- note: this assgnmnt can be overriden
|
||||
end if;
|
||||
|
||||
case State is
|
||||
|
||||
when Idle =>
|
||||
Parity <= '0';
|
||||
Bit_Cnt <= (others => '0');
|
||||
-- note that we dont need to clear the Shift Register
|
||||
if Fall_Clk='1' and PS2_Datr='0' then -- Start bit
|
||||
Scan_Err <= '0';
|
||||
State <= Shifting;
|
||||
end if;
|
||||
|
||||
when Shifting =>
|
||||
if Bit_Cnt >= 9 then
|
||||
if Fall_Clk='1' then -- Stop Bit
|
||||
-- Error is (wrong Parity) or (Stop='0') or Overflow
|
||||
Scan_Err <= (not Parity) or (not PS2_Datr) or Scan_DAVi;
|
||||
Scan_Davi <= '1';
|
||||
Scan_Code <= S_Reg(7 downto 0);
|
||||
State <= Idle;
|
||||
end if;
|
||||
elsif Fall_Clk='1' then
|
||||
Bit_Cnt <= Bit_Cnt + 1;
|
||||
S_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right
|
||||
Parity <= Parity xor PS2_Datr;
|
||||
end if;
|
||||
|
||||
when others => -- never reached
|
||||
State <= Idle;
|
||||
|
||||
end case;
|
||||
|
||||
--Scan_Err <= '0'; -- to create an on-purpose error on Scan_Err !
|
||||
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
end ALSE_RTL;
|
||||
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Simple I2C bus interface for initializing the Wolfson WM8731 audio codec
|
||||
-- on the DE2
|
||||
--
|
||||
-- Stephen A. Edwards (sedwards@cs.columbia.edu)
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity i2c_controller is
|
||||
|
||||
port (
|
||||
CLK : in std_logic; -- 50 MHz main clock
|
||||
SCLK : out std_logic; -- I2C clock
|
||||
SDAT : inout std_logic; -- I2C data
|
||||
reset : in std_logic);
|
||||
end i2c_controller;
|
||||
|
||||
architecture rtl of i2c_controller is
|
||||
|
||||
type phases is (IDLE, START, ZERO, ONE, ACK, STOP);
|
||||
|
||||
type packet_states is (P_IDLE,
|
||||
P_START,
|
||||
P_ADDR,
|
||||
P_WRITE,
|
||||
P_ADDR_ACK,
|
||||
P_DATA1,
|
||||
P_DATA1_ACK,
|
||||
P_DATA2,
|
||||
P_DATA2_ACK,
|
||||
P_STOP);
|
||||
|
||||
type data_states is (D_SEND, D_DONE, D_IDLE);
|
||||
|
||||
signal address : unsigned(6 downto 0);
|
||||
signal data1, data2 : unsigned(7 downto 0);
|
||||
signal send, done : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
address <= "0011010"; -- fixed address of WM8731
|
||||
|
||||
send_data : process (CLK)
|
||||
variable state : data_states;
|
||||
variable reg : unsigned(3 downto 0);
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if reset = '1' then
|
||||
state := D_DONE;
|
||||
reg := X"0";
|
||||
send <= '0';
|
||||
data2 <= X"00";
|
||||
else
|
||||
case state is
|
||||
when D_DONE =>
|
||||
if done = '0' then
|
||||
state := D_SEND;
|
||||
send <= '1';
|
||||
data1 <= "000" & reg & "0";
|
||||
case reg is
|
||||
when X"0" => data2 <= X"1A"; -- LIN_L
|
||||
when X"1" => data2 <= X"1A"; -- LIN_R
|
||||
when X"2" => data2 <= X"7B"; -- HEAD_L
|
||||
when X"3" => data2 <= X"7B"; -- HEAD_R
|
||||
when X"4" => data2 <= X"F8"; -- A_PATH_CTRL
|
||||
when X"5" => data2 <= X"06"; -- D_PATH_CTRL
|
||||
when X"6" => data2 <= X"00"; -- POWER_ON
|
||||
when X"7" => data2 <= X"01"; -- SET_FORMAT
|
||||
when X"8" => data2 <= X"02"; -- SAMPLE_CTRL
|
||||
when X"9" => data2 <= X"01"; -- SET_ACTIVE
|
||||
when others =>
|
||||
state := D_IDLE;
|
||||
send <= '0';
|
||||
end case;
|
||||
reg := reg + 1;
|
||||
end if;
|
||||
|
||||
when D_SEND =>
|
||||
if done = '1' then
|
||||
send <= '0';
|
||||
state := D_DONE;
|
||||
end if;
|
||||
|
||||
when D_IDLE => -- hold
|
||||
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
send_packet : process (CLK)
|
||||
variable clock_prescaler : unsigned(7 downto 0);
|
||||
variable sreg : unsigned(22 downto 0);
|
||||
variable state : packet_states;
|
||||
variable bit_counter : unsigned(2 downto 0);
|
||||
variable phase : phases;
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if reset = '1' then
|
||||
state := P_IDLE;
|
||||
phase := IDLE;
|
||||
SCLK <= '1';
|
||||
SDAT <= 'Z';
|
||||
clock_prescaler := X"00";
|
||||
sreg := (others => '0');
|
||||
else
|
||||
if clock_prescaler = X"00" then
|
||||
done <= '0';
|
||||
case state is
|
||||
when P_IDLE =>
|
||||
phase := IDLE;
|
||||
sreg := address & data1 & data2;
|
||||
if send = '1' then
|
||||
state := P_START;
|
||||
end if;
|
||||
|
||||
when P_START =>
|
||||
phase := START;
|
||||
bit_counter := "110";
|
||||
state := P_ADDR;
|
||||
|
||||
when P_ADDR =>
|
||||
if sreg(22) = '1' then phase := ONE;
|
||||
else phase := ZERO; end if;
|
||||
sreg := sreg(21 downto 0) & '0';
|
||||
if bit_counter = "000" then state := P_WRITE; end if;
|
||||
bit_counter := bit_counter - 1;
|
||||
|
||||
when P_WRITE =>
|
||||
phase := ZERO;
|
||||
state := P_ADDR_ACK;
|
||||
|
||||
when P_ADDR_ACK =>
|
||||
phase := ACK;
|
||||
bit_counter := "111";
|
||||
state := P_DATA1;
|
||||
|
||||
when P_DATA1 =>
|
||||
if sreg(22) = '1' then phase := ONE;
|
||||
else phase := ZERO; end if;
|
||||
sreg := sreg(21 downto 0) & '0';
|
||||
if bit_counter = "000" then state := P_DATA1_ACK; end if;
|
||||
bit_counter := bit_counter - 1;
|
||||
|
||||
when P_DATA1_ACK =>
|
||||
phase := ACK;
|
||||
bit_counter := "111";
|
||||
state := P_DATA2;
|
||||
|
||||
when P_DATA2 =>
|
||||
if sreg(22) = '1' then phase := ONE;
|
||||
else phase := ZERO; end if;
|
||||
sreg := sreg(21 downto 0) & '0';
|
||||
if bit_counter = "000" then state := P_DATA2_ACK; end if;
|
||||
bit_counter := bit_counter - 1;
|
||||
|
||||
when P_DATA2_ACK =>
|
||||
phase := ACK;
|
||||
state := P_STOP;
|
||||
|
||||
when P_STOP =>
|
||||
phase := STOP;
|
||||
done <= '1';
|
||||
state := P_IDLE;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
|
||||
case phase is
|
||||
when IDLE =>
|
||||
SCLK <= '1';
|
||||
SDAT <= 'Z';
|
||||
|
||||
when START =>
|
||||
if clock_prescaler(7 downto 6) = "00" then SDAT <= '1';
|
||||
else SDAT <= '0';
|
||||
end if;
|
||||
if clock_prescaler(7 downto 6) = "11" then SCLK <= '0';
|
||||
else SCLK <= '1';
|
||||
end if;
|
||||
|
||||
when ZERO | ONE =>
|
||||
if phase = ONE then SDAT <= '1'; else SDAT <= '0'; end if;
|
||||
if clock_prescaler(7) = clock_prescaler(6) then SCLK <= '0';
|
||||
else SCLK <= '1';
|
||||
end if;
|
||||
|
||||
when ACK =>
|
||||
if clock_prescaler(7) = clock_prescaler(6) then SCLK <= '0';
|
||||
else SCLK <= '1'; end if;
|
||||
SDAT <= 'Z';
|
||||
|
||||
when STOP =>
|
||||
SCLK <= '1';
|
||||
if clock_prescaler(7) = '1' then SDAT <= '1';
|
||||
else SDAT <= '0'; end if;
|
||||
|
||||
end case;
|
||||
|
||||
clock_prescaler := clock_prescaler + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
|
||||
end rtl;
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity i2c_testbench is
|
||||
|
||||
end i2c_testbench;
|
||||
|
||||
architecture behavioral of i2c_testbench is
|
||||
|
||||
signal CLK : std_logic := '0';
|
||||
signal reset : std_logic := '1';
|
||||
|
||||
begin
|
||||
|
||||
uut : entity work.i2c_controller
|
||||
port map (
|
||||
CLK => CLK,
|
||||
reset => reset
|
||||
);
|
||||
|
||||
CLK <= not CLK after 10 ns;
|
||||
|
||||
reset <= '0' after 40 ns;
|
||||
|
||||
end behavioral;
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity keyboard is
|
||||
port (
|
||||
ps2_clk : in std_logic;
|
||||
ps2_data : in std_logic;
|
||||
clk : in std_logic;
|
||||
rst_n : in std_logic;
|
||||
readd : in std_logic;
|
||||
K : out unsigned(7 downto 0);
|
||||
scanSW : out std_logic_vector(3 downto 0);
|
||||
imageCount : out unsigned(7 downto 0);
|
||||
AReset : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture rtl of keyboard is
|
||||
|
||||
type key_matrix is array(0 to 13) of std_logic_vector(3 downto 0);
|
||||
signal keys : key_matrix;
|
||||
signal release : std_logic;
|
||||
signal extended : std_logic;
|
||||
|
||||
signal keyb_data : std_logic_vector(7 downto 0);
|
||||
signal keyb_valid : std_logic;
|
||||
signal keyb_error : std_logic;
|
||||
|
||||
signal CTRL : std_logic;
|
||||
signal ALT : std_logic;
|
||||
signal SHIFT : std_logic;
|
||||
signal VIDEO : std_logic;
|
||||
signal SCANL : std_logic;
|
||||
signal VMODE : std_logic;
|
||||
|
||||
signal ascii : unsigned(7 downto 0); -- decoded
|
||||
|
||||
signal inList : std_logic := '0';
|
||||
|
||||
begin
|
||||
|
||||
ps2 : entity work.ps2_intf port map (
|
||||
CLK => clk,
|
||||
nRESET => rst_n,
|
||||
PS2_CLK => ps2_clk,
|
||||
PS2_DATA => ps2_data,
|
||||
DATA => keyb_data,
|
||||
VALID => keyb_valid,
|
||||
error => keyb_error
|
||||
);
|
||||
|
||||
K <= inList & "00" & ascii(4 downto 0) when CTRL = '1' else
|
||||
inList & ascii(6 downto 0);
|
||||
|
||||
process(clk, rst_n)
|
||||
begin
|
||||
if rst_n = '0' then
|
||||
|
||||
release <= '0';
|
||||
extended <= '0';
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
|
||||
if readd = '1' then
|
||||
inList <= '0';
|
||||
end if; --q
|
||||
|
||||
if keyb_valid = '1' then
|
||||
if keyb_data = X"e0" then
|
||||
extended <= '1';
|
||||
elsif keyb_data = X"f0" then
|
||||
release <= '1';
|
||||
inList <= '0';
|
||||
else
|
||||
release <= '0';
|
||||
extended <= '0';
|
||||
|
||||
case keyb_data is
|
||||
--disk slot insertion (up to 20 images)
|
||||
when X"05" => if SHIFT = '0' then imageCount <= X"00"; -- F1
|
||||
else imageCount <= X"0A"; end if; inList <= '0'; -- SHIFT F1
|
||||
when X"06" => if SHIFT = '0' then imageCount <= X"01"; -- F2
|
||||
else imageCount <= X"0B"; end if; inList <= '0'; -- SHIFT F2
|
||||
when X"04" => if SHIFT = '0' then imageCount <= X"02"; -- F3
|
||||
else imageCount <= X"0C"; end if; inList <= '0'; -- SHIFT F3
|
||||
when X"0C" => if SHIFT = '0' then imageCount <= X"03"; -- F4
|
||||
else imageCount <= X"0D"; end if; inList <= '0'; -- SHIFT F4
|
||||
when X"03" => if SHIFT = '0' then imageCount <= X"04"; -- F5
|
||||
else imageCount <= X"0E"; end if; inList <= '0'; -- SHIFT F5
|
||||
when X"0B" => if SHIFT = '0' then imageCount <= X"05"; -- F6
|
||||
else imageCount <= X"0F"; end if; inList <= '0'; -- SHIFT F6
|
||||
when X"83" => if SHIFT = '0' then imageCount <= X"06"; -- F7
|
||||
else imageCount <= X"10"; end if; inList <= '0'; -- SHIFT F7
|
||||
when X"0A" => if SHIFT = '0' then imageCount <= X"07"; -- F8
|
||||
else imageCount <= X"11"; end if; inList <= '0'; -- SHIFT F8
|
||||
when X"01" => if SHIFT = '0' then imageCount <= X"08"; -- F9
|
||||
else imageCount <= X"12"; end if; inList <= '0'; -- SHIFT F9
|
||||
when X"09" => if SHIFT = '0' then imageCount <= X"09"; -- F10
|
||||
else imageCount <= X"13"; end if; inList <= '0'; -- SHIFT F10
|
||||
|
||||
when X"07" => AReset <= not release; inList <= '0'; -- F12 reset
|
||||
|
||||
when X"11" => ALT <= not release; inList <= '0'; -- ALT
|
||||
when X"14" => CTRL <= not release; inList <= '0'; -- CTRL
|
||||
when X"59" => SHIFT <= not release; inList <= '0'; -- RSHIFT
|
||||
when X"12" => SHIFT <= not release; inList <= '0'; -- LSHIFT
|
||||
|
||||
when X"74" => ascii <= X"15"; inList <= not release; -- RIGHT
|
||||
when X"6B" => ascii <= X"08"; inList <= not release; -- LEFT
|
||||
when X"72" => ascii <= X"0a"; inList <= not release; -- DOWN
|
||||
when X"75" => ascii <= X"0b"; inList <= not release; -- UP
|
||||
when X"5A" => ascii <= X"0d"; inList <= not release; -- RETURN
|
||||
when X"66" => if (CTRL = '1' and ALT = '1') then -- MASTER RESET
|
||||
scanSW(0) <= not release; inList <= '0';
|
||||
else
|
||||
ascii <= X"08"; inList <= not release; -- BACKSPACE (DELETE)
|
||||
end if;
|
||||
when X"0D" => ascii <= X"09"; inList <= not release; -- HORIZ TAB
|
||||
when X"29" => ascii <= X"20"; inList <= not release; -- SPACE
|
||||
when X"4E" => if SHIFT = '0' then ascii <= X"2d"; -- -
|
||||
else ascii <= X"5f"; end if; inList <= not release; --- _
|
||||
when X"0E" => if SHIFT = '0' then ascii <= X"60"; -- `
|
||||
else ascii <= X"7e"; end if; inList <= not release; --- ~
|
||||
when X"54" => if SHIFT = '0' then ascii <= X"5b"; -- [
|
||||
else ascii <= X"7b"; end if; inList <= not release; --- {
|
||||
when X"5B" => if SHIFT = '0' then ascii <= X"5d"; -- ]
|
||||
else ascii <= X"7d"; end if; inList <= not release; --- }
|
||||
when X"52" => if SHIFT = '0' then ascii <= X"27"; -- '
|
||||
else ascii <= X"22"; end if; inList <= not release; --- "
|
||||
when X"4D" => if SHIFT = '0' then ascii <= X"50"; -- P
|
||||
else ascii <= X"40"; end if; inList <= not release; --- @
|
||||
when X"4C" => if SHIFT = '0' then ascii <= X"3b"; -- ;
|
||||
else ascii <= X"3a"; end if; inList <= not release; --- :
|
||||
when X"4A" => if SHIFT = '0' then ascii <= X"2f"; -- /
|
||||
else ascii <= X"3f"; end if; inList <= not release; --- ?
|
||||
when X"55" => if SHIFT = '0' then ascii <= X"3d"; -- =
|
||||
else ascii <= X"2b"; end if; inList <= not release; --- +
|
||||
when X"44" => ascii <= X"4f"; inList <= not release; -- O
|
||||
when X"4B" => ascii <= X"4c"; inList <= not release; -- L
|
||||
when X"49" => if SHIFT = '0' then ascii <= X"2e"; -- .
|
||||
else ascii <= X"3e"; end if; inList <= not release; --- >
|
||||
when X"43" => ascii <= X"49"; inList <= not release; -- I
|
||||
when X"42" => ascii <= X"4b"; inList <= not release; -- K
|
||||
when X"41" => if SHIFT = '0' then ascii <= X"2c"; -- ,
|
||||
else ascii <= X"3c"; end if; inList <= not release; --- <
|
||||
when X"3C" => ascii <= X"55"; inList <= not release; -- U
|
||||
when X"3B" => ascii <= X"4a"; inList <= not release; -- J
|
||||
when X"3A" => ascii <= X"4d"; inList <= not release; -- M
|
||||
when X"35" => ascii <= X"59"; inList <= not release; -- Y
|
||||
when X"33" => ascii <= X"48"; inList <= not release; -- H
|
||||
when X"31" => ascii <= X"4e"; inList <= not release; -- N
|
||||
when X"2C" => ascii <= X"54"; inList <= not release; -- T
|
||||
when X"34" => ascii <= X"47"; inList <= not release; -- G
|
||||
when X"32" => ascii <= X"42"; inList <= not release; -- B
|
||||
when X"2D" => ascii <= X"52"; inList <= not release; -- R
|
||||
when X"2B" => ascii <= X"46"; inList <= not release; -- F
|
||||
when X"2A" => ascii <= X"56"; inList <= not release; -- V
|
||||
when X"24" => ascii <= X"45"; inList <= not release; -- E
|
||||
when X"23" => ascii <= X"44"; inList <= not release; -- D
|
||||
when X"21" => ascii <= X"43"; inList <= not release; -- C
|
||||
when X"1D" => ascii <= X"57"; inList <= not release; -- W
|
||||
when X"1B" => ascii <= X"53"; inList <= not release; -- S
|
||||
when X"22" => ascii <= X"58"; inList <= not release; -- X
|
||||
when X"45" => if SHIFT = '0' then ascii <= X"30"; -- 0
|
||||
else ascii <= X"29"; end if; inList <= not release; --- )
|
||||
when X"16" => if SHIFT = '0' then ascii <= X"31"; -- 1
|
||||
else ascii <= X"21"; end if; inList <= not release; --- !
|
||||
when X"1E" => if SHIFT = '0' then ascii <= X"32"; -- 2
|
||||
else ascii <= X"40"; end if; inList <= not release; --- @
|
||||
when X"26" => if SHIFT = '0' then ascii <= X"33"; -- 3
|
||||
else ascii <= X"23"; end if; inList <= not release; --- #
|
||||
when X"25" => if SHIFT = '0' then ascii <= X"34"; -- 4
|
||||
else ascii <= X"24"; end if; inList <= not release; --- $
|
||||
when X"2E" => if SHIFT = '0' then ascii <= X"35"; -- 5
|
||||
else ascii <= X"25"; end if; inList <= not release; --- %
|
||||
when X"36" => if SHIFT = '0' then ascii <= X"36"; -- 6
|
||||
else ascii <= X"5e"; end if; inList <= not release; --- &
|
||||
when X"3D" => if SHIFT = '0' then ascii <= X"37"; -- 7
|
||||
else ascii <= X"26"; end if; inList <= not release; --- '
|
||||
when X"3E" => if SHIFT = '0' then ascii <= X"38"; -- 8
|
||||
else ascii <= X"2a"; end if; inList <= not release; --- *
|
||||
when X"46" => if SHIFT = '0' then ascii <= X"39"; -- 9
|
||||
else ascii <= X"28"; end if; inList <= not release; --- (
|
||||
when X"15" => ascii <= X"51"; inList <= not release; -- Q
|
||||
when X"1C" => ascii <= X"41"; inList <= not release; -- A
|
||||
when X"1A" => ascii <= X"5a"; inList <= not release; -- Z
|
||||
when X"76" => ascii <= X"1b"; inList <= not release; -- ESCAPE
|
||||
when X"71" => ascii <= X"7f"; inList <= not release; -- DEL
|
||||
|
||||
when X"7E" => -- scrolLock RGB/VGA
|
||||
if (VIDEO = '0' and release = '0') then -- NOT impplemented YET
|
||||
scanSW(1) <= '1'; VIDEO <= '1';
|
||||
elsif (VIDEO = '1' and release = '0') then
|
||||
scanSW(1) <= '0'; VIDEO <= '0';
|
||||
end if;
|
||||
inList <= '0';
|
||||
|
||||
when X"7B" => -- "-" Scanlines
|
||||
if (SCANL = '0' and release = '0') then
|
||||
scanSW(2) <= '1'; SCANL <= '1';
|
||||
elsif (SCANL = '1' and release = '0') then
|
||||
scanSW(2) <= '0'; SCANL <= '0';
|
||||
end if;
|
||||
inList <= '0';
|
||||
|
||||
when X"7C" => -- "*" Mode COLOR / B&W
|
||||
if (VMODE = '0' and release = '0') then
|
||||
scanSW(3) <= '1'; VMODE <= '1';
|
||||
elsif (VMODE = '1' and release = '0') then
|
||||
scanSW(3) <= '0'; VMODE <= '0';
|
||||
end if;
|
||||
inList <= '0';
|
||||
|
||||
when others => inList <= '0';
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
|
|
@ -1,394 +0,0 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- PS/2 Keyboard interface for the Apple ][
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
-- After an original by Alex Freed
|
||||
-- i18n & French keyboard by Michel Stempin
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity keyboard is
|
||||
|
||||
generic (
|
||||
KEYMAP : string := "EN-us" -- English US keymap
|
||||
-- KEYMAP : string := "FR-fr" -- French keymap
|
||||
);
|
||||
|
||||
port (
|
||||
PS2_Clk : in std_logic; -- From PS/2 port
|
||||
PS2_Data : in std_logic; -- From PS/2 port
|
||||
CLK_14M : in std_logic;
|
||||
read : in std_logic; -- Read strobe
|
||||
reset : in std_logic;
|
||||
key_code : out unsigned(11 downto 0);
|
||||
K : out unsigned(7 downto 0) -- Latched, decoded keyboard data
|
||||
);
|
||||
end keyboard;
|
||||
|
||||
architecture rtl of keyboard is
|
||||
|
||||
signal code, latched_code : unsigned(7 downto 0);
|
||||
signal code_available : std_logic;
|
||||
signal ascii : unsigned(7 downto 0); -- decoded
|
||||
signal shifted_code : unsigned(11 downto 0);
|
||||
|
||||
signal key_pressed : std_logic; -- Key pressed & not read
|
||||
signal ctrl, shift, alt : std_logic;
|
||||
|
||||
-- Special PS/2 keyboard codes
|
||||
constant KEY_UP_CODE : unsigned(7 downto 0) := X"F0";
|
||||
constant EXTENDED_CODE : unsigned(7 downto 0) := X"E0";
|
||||
constant LEFT_SHIFT : unsigned(7 downto 0) := X"12";
|
||||
constant RIGHT_SHIFT : unsigned(7 downto 0) := X"59";
|
||||
constant LEFT_CTRL : unsigned(7 downto 0) := X"14";
|
||||
constant ALT_GR : unsigned(7 downto 0) := X"11";
|
||||
|
||||
type states is (IDLE,
|
||||
HAVE_CODE,
|
||||
DECODE,
|
||||
GOT_KEY_UP_CODE,
|
||||
GOT_KEY_UP2,
|
||||
GOT_KEY_UP3,
|
||||
KEY_UP,
|
||||
NORMAL_KEY
|
||||
);
|
||||
|
||||
signal state, next_state : states;
|
||||
|
||||
begin
|
||||
|
||||
ps2_controller : entity work.PS2_Ctrl port map (
|
||||
Clk => CLK_14M,
|
||||
Reset => reset,
|
||||
PS2_Clk => PS2_Clk,
|
||||
PS2_Data => PS2_Data,
|
||||
DoRead => code_available,
|
||||
Scan_DAV => code_available,
|
||||
Scan_Code => code);
|
||||
|
||||
K <= key_pressed & "00" & ascii(4 downto 0) when ctrl = '1' and ascii /= "00" else
|
||||
key_pressed & ascii(6 downto 0) when ascii /= "00" else X"00"; --Q ascii
|
||||
|
||||
shift_ctrl : process (CLK_14M, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
shift <= '0';
|
||||
ctrl <= '0';
|
||||
elsif rising_edge(CLK_14M) then
|
||||
if state = HAVE_CODE then
|
||||
if code = LEFT_SHIFT or code = RIGHT_SHIFT then
|
||||
shift <= '1';
|
||||
elsif code = LEFT_CTRL then
|
||||
ctrl <= '1';
|
||||
elsif code = ALT_GR then
|
||||
alt <= '1';
|
||||
end if;
|
||||
elsif state = KEY_UP then
|
||||
if code = LEFT_SHIFT or code = RIGHT_SHIFT then
|
||||
shift <= '0';
|
||||
elsif code = LEFT_CTRL then
|
||||
ctrl <= '0';
|
||||
elsif code = ALT_GR then
|
||||
alt <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process shift_ctrl;
|
||||
|
||||
fsm : process (CLK_14M, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
state <= IDLE;
|
||||
latched_code <= (others => '0');
|
||||
key_pressed <= '0';
|
||||
elsif rising_edge(CLK_14M) then
|
||||
state <= next_state;
|
||||
if read = '1' then key_pressed <= '0'; end if;
|
||||
if state = NORMAL_KEY then
|
||||
latched_code <= code ;
|
||||
key_pressed <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process fsm;
|
||||
|
||||
fsm_next_state : process (code, code_available, state)
|
||||
begin
|
||||
next_state <= state;
|
||||
case state is
|
||||
when IDLE =>
|
||||
if code_available = '1' then next_state <= HAVE_CODE; end if;
|
||||
|
||||
when HAVE_CODE =>
|
||||
next_state <= DECODE;
|
||||
|
||||
when DECODE =>
|
||||
if code = KEY_UP_CODE then
|
||||
next_state <= GOT_KEY_UP_CODE;
|
||||
elsif code = EXTENDED_CODE then -- Treat extended codes as normal
|
||||
next_state <= IDLE;
|
||||
elsif code = LEFT_SHIFT or code = RIGHT_SHIFT or code = LEFT_CTRL then
|
||||
next_state <= IDLE;
|
||||
else
|
||||
|
||||
next_state <= NORMAL_KEY;
|
||||
end if;
|
||||
|
||||
when GOT_KEY_UP_CODE =>
|
||||
next_state <= GOT_KEY_UP2;
|
||||
|
||||
when GOT_KEY_UP2 =>
|
||||
next_state <= GOT_KEY_UP3;
|
||||
|
||||
when GOT_KEY_UP3 =>
|
||||
if code_available = '1' then
|
||||
next_state <= KEY_UP;
|
||||
end if;
|
||||
|
||||
when KEY_UP | NORMAL_KEY =>
|
||||
next_state <= IDLE;
|
||||
end case;
|
||||
end process fsm_next_state;
|
||||
|
||||
-- PS/2 scancode to ASCII translation
|
||||
|
||||
shifted_code <= "00" & alt & shift & latched_code;
|
||||
|
||||
key_code <= shifted_code when state = KEY_UP else X"000"; --Q
|
||||
|
||||
EN_us: if KEYMAP = "EN-us" generate
|
||||
with shifted_code select
|
||||
ascii <=
|
||||
X"08" when X"066", -- Backspace ("backspace" key)
|
||||
X"08" when X"166", -- Backspace ("backspace" key)
|
||||
X"09" when X"00d", -- Horizontal Tab
|
||||
X"09" when X"10d", -- Horizontal Tab
|
||||
X"0d" when X"05a", -- Carriage return ("enter" key)
|
||||
X"0d" when X"15a", -- Carriage return ("enter" key)
|
||||
X"1b" when X"076", -- Escape ("esc" key)
|
||||
X"1b" when X"176", -- Escape ("esc" key)
|
||||
X"20" when X"029", -- Space
|
||||
X"20" when X"129", -- Space
|
||||
X"21" when X"116", -- !
|
||||
X"22" when X"152", -- "
|
||||
X"23" when X"126", -- #
|
||||
X"24" when X"125", -- $
|
||||
X"25" when X"12e", --
|
||||
X"26" when X"13d", --
|
||||
X"27" when X"052", --
|
||||
X"28" when X"146", --
|
||||
X"29" when X"145", --
|
||||
X"2a" when X"13e", -- *
|
||||
X"2b" when X"155", -- +
|
||||
X"2c" when X"041", -- ,
|
||||
X"2d" when X"04e", -- -
|
||||
X"2e" when X"049", -- .
|
||||
X"2f" when X"04a", -- /
|
||||
X"30" when X"045", -- 0
|
||||
X"31" when X"016", -- 1
|
||||
X"32" when X"01e", -- 2
|
||||
X"33" when X"026", -- 3
|
||||
X"34" when X"025", -- 4
|
||||
X"35" when X"02e", -- 5
|
||||
X"36" when X"036", -- 6
|
||||
X"37" when X"03d", -- 7
|
||||
X"38" when X"03e", -- 8
|
||||
X"39" when X"046", -- 9
|
||||
X"3a" when X"14c", -- :
|
||||
X"3b" when X"04c", -- ;
|
||||
X"3c" when X"141", -- <
|
||||
X"3d" when X"055", -- =
|
||||
X"3e" when X"149", -- >
|
||||
X"3f" when X"14a", -- ?
|
||||
X"40" when X"11e", -- @
|
||||
X"41" when X"11c", -- A
|
||||
X"42" when X"132", -- B
|
||||
X"43" when X"121", -- C
|
||||
X"44" when X"123", -- D
|
||||
X"45" when X"124", -- E
|
||||
X"46" when X"12b", -- F
|
||||
X"47" when X"134", -- G
|
||||
X"48" when X"133", -- H
|
||||
X"49" when X"143", -- I
|
||||
X"4a" when X"13b", -- J
|
||||
X"4b" when X"142", -- K
|
||||
X"4c" when X"14b", -- L
|
||||
X"4d" when X"13a", -- M
|
||||
X"4e" when X"131", -- N
|
||||
X"4f" when X"144", -- O
|
||||
X"50" when X"14d", -- P
|
||||
X"51" when X"115", -- Q
|
||||
X"52" when X"12d", -- R
|
||||
X"53" when X"11b", -- S
|
||||
X"54" when X"12c", -- T
|
||||
X"55" when X"13c", -- U
|
||||
X"56" when X"12a", -- V
|
||||
X"57" when X"11d", -- W
|
||||
X"58" when X"122", -- X
|
||||
X"59" when X"135", -- Y
|
||||
X"5a" when X"11a", -- Z
|
||||
X"5b" when X"054", -- [
|
||||
X"5c" when X"05d", -- \
|
||||
X"5d" when X"05b", -- ]
|
||||
X"5e" when X"136", -- ^
|
||||
X"5f" when X"14e", -- _
|
||||
X"60" when X"00e", -- `
|
||||
X"41" when X"01c", -- A
|
||||
X"42" when X"032", -- B
|
||||
X"43" when X"021", -- C
|
||||
X"44" when X"023", -- D
|
||||
X"45" when X"024", -- E
|
||||
X"46" when X"02b", -- F
|
||||
X"47" when X"034", -- G
|
||||
X"48" when X"033", -- H
|
||||
X"49" when X"043", -- I
|
||||
X"4a" when X"03b", -- J
|
||||
X"4b" when X"042", -- K
|
||||
X"4c" when X"04b", -- L
|
||||
X"4d" when X"03a", -- M
|
||||
X"4e" when X"031", -- N
|
||||
X"4f" when X"044", -- O
|
||||
X"50" when X"04d", -- P
|
||||
X"51" when X"015", -- Q
|
||||
X"52" when X"02d", -- R
|
||||
X"53" when X"01b", -- S
|
||||
X"54" when X"02c", -- T
|
||||
X"55" when X"03c", -- U
|
||||
X"56" when X"02a", -- V
|
||||
X"57" when X"01d", -- W
|
||||
X"58" when X"022", -- X
|
||||
X"59" when X"035", -- Y
|
||||
X"5a" when X"01a", -- Z
|
||||
X"7b" when X"154", -- {
|
||||
X"7c" when X"15d", -- |
|
||||
X"7d" when X"15b", -- }
|
||||
X"7e" when X"10e", -- ~
|
||||
X"7f" when X"071", -- (Delete OR DEL on numeric keypad)
|
||||
X"15" when X"074", -- right arrow (cntrl U)
|
||||
X"08" when X"06b", -- left arrow (BS)
|
||||
X"0B" when X"075", -- (up arrow)
|
||||
X"0A" when X"072", -- (down arrow, ^J, LF)
|
||||
X"7f" when X"171", -- (Delete OR DEL on numeric keypad)
|
||||
X"00" when others;
|
||||
end generate EN_us;
|
||||
|
||||
FR_fr: if KEYMAP = "FR-fr" generate
|
||||
with shifted_code select
|
||||
ascii <=
|
||||
X"08" when X"066", -- Backspace ("backspace" key)
|
||||
X"08" when X"166", -- Backspace ("backspace" key)
|
||||
X"09" when X"00d", -- Horizontal Tab
|
||||
X"09" when X"10d", -- Horizontal Tab
|
||||
X"0d" when X"05a", -- Carriage return ("enter" key)
|
||||
X"0d" when X"15a", -- Carriage return ("enter" key)
|
||||
X"1b" when X"076", -- Escape ("esc" key)
|
||||
X"1b" when X"176", -- Escape ("esc" key)
|
||||
X"20" when X"029", -- Space
|
||||
X"20" when X"129", -- Space
|
||||
X"21" when X"04a", -- !
|
||||
X"22" when X"026", -- "
|
||||
X"23" when X"226", -- #
|
||||
X"24" when X"05b", -- $
|
||||
X"25" when X"152", -- %
|
||||
X"26" when X"016", -- &
|
||||
X"27" when X"025", -- '
|
||||
X"28" when X"02e", -- (
|
||||
X"29" when X"04e", -- )
|
||||
X"2a" when X"05d", -- *
|
||||
X"2b" when X"155", -- +
|
||||
X"2c" when X"03a", -- ,
|
||||
X"2d" when X"036", -- -
|
||||
X"2e" when X"141", -- .
|
||||
X"2f" when X"149", -- /
|
||||
X"30" when X"145", -- 0
|
||||
X"31" when X"116", -- 1
|
||||
X"32" when X"11e", -- 2
|
||||
X"33" when X"126", -- 3
|
||||
X"34" when X"125", -- 4
|
||||
X"35" when X"12e", -- 5
|
||||
X"36" when X"136", -- 6
|
||||
X"37" when X"13d", -- 7
|
||||
X"38" when X"13e", -- 8
|
||||
X"39" when X"146", -- 9
|
||||
X"3a" when X"049", -- :
|
||||
X"3b" when X"041", -- ;
|
||||
X"3c" when X"061", -- <
|
||||
X"3d" when X"055", -- =
|
||||
X"3e" when X"161", -- >
|
||||
X"3f" when X"13a", -- ?
|
||||
X"40" when X"245", -- @
|
||||
X"41" when X"115", -- A
|
||||
X"42" when X"132", -- B
|
||||
X"43" when X"121", -- C
|
||||
X"44" when X"123", -- D
|
||||
X"45" when X"124", -- E
|
||||
X"46" when X"12b", -- F
|
||||
X"47" when X"134", -- G
|
||||
X"48" when X"133", -- H
|
||||
X"49" when X"143", -- I
|
||||
X"4a" when X"13b", -- J
|
||||
X"4b" when X"142", -- K
|
||||
X"4c" when X"14b", -- L
|
||||
X"4d" when X"14c", -- M
|
||||
X"4e" when X"131", -- N
|
||||
X"4f" when X"144", -- O
|
||||
X"50" when X"14d", -- P
|
||||
X"51" when X"11c", -- Q
|
||||
X"52" when X"12d", -- R
|
||||
X"53" when X"11b", -- S
|
||||
X"54" when X"12c", -- T
|
||||
X"55" when X"13c", -- U
|
||||
X"56" when X"12a", -- V
|
||||
X"57" when X"11a", -- W
|
||||
X"58" when X"122", -- X
|
||||
X"59" when X"135", -- Y
|
||||
X"5a" when X"11d", -- Z
|
||||
X"5b" when X"22e", -- [
|
||||
X"5c" when X"23e", -- \
|
||||
X"5d" when X"24e", -- ]
|
||||
X"5e" when X"054", -- ^
|
||||
X"5f" when X"03e", -- _
|
||||
X"60" when X"23d", -- `
|
||||
X"41" when X"015", -- A
|
||||
X"42" when X"032", -- B
|
||||
X"43" when X"021", -- C
|
||||
X"44" when X"023", -- D
|
||||
X"45" when X"024", -- E
|
||||
X"46" when X"02b", -- F
|
||||
X"47" when X"034", -- G
|
||||
X"48" when X"033", -- H
|
||||
X"49" when X"043", -- I
|
||||
X"4a" when X"03b", -- J
|
||||
X"4b" when X"042", -- K
|
||||
X"4c" when X"04b", -- L
|
||||
X"4d" when X"04c", -- M
|
||||
X"4e" when X"031", -- N
|
||||
X"4f" when X"044", -- O
|
||||
X"50" when X"04d", -- P
|
||||
X"51" when X"01c", -- Q
|
||||
X"52" when X"02d", -- R
|
||||
X"53" when X"01b", -- S
|
||||
X"54" when X"02c", -- T
|
||||
X"55" when X"03c", -- U
|
||||
X"56" when X"02a", -- V
|
||||
X"57" when X"01a", -- W
|
||||
X"58" when X"022", -- X
|
||||
X"59" when X"035", -- Y
|
||||
X"5a" when X"01d", -- Z
|
||||
X"7b" when X"225", -- {
|
||||
X"7c" when X"236", -- |
|
||||
X"7d" when X"255", -- }
|
||||
X"7e" when X"21e", -- ~
|
||||
X"7f" when X"071", -- (Delete OR DEL on numeric keypad)
|
||||
X"15" when X"074", -- right arrow (cntrl U)
|
||||
X"08" when X"06b", -- left arrow (BS)
|
||||
X"0B" when X"075", -- (up arrow)
|
||||
X"0A" when X"072", -- (down arrow, ^J, LF)
|
||||
X"7f" when X"171", -- (Delete OR DEL on numeric keypad)
|
||||
X"00" when others;
|
||||
end generate FR_fr;
|
||||
|
||||
end rtl;
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
module multiboot (
|
||||
input wire clk_icap,
|
||||
input wire REBOOT
|
||||
);
|
||||
|
||||
reg [23:0] spi_addr = 24'h058000; // default: SPI address of second core as defined by the SPI memory map
|
||||
|
||||
reg [4:0] q = 5'b00000;
|
||||
reg reboot_ff = 1'b0;
|
||||
|
||||
always @(posedge clk_icap) begin
|
||||
q[0] <= REBOOT;
|
||||
q[1] <= q[0];
|
||||
q[2] <= q[1];
|
||||
q[3] <= q[2];
|
||||
q[4] <= q[3];
|
||||
reboot_ff <= (q[4] && (!q[3]) && (!q[2]) && (!q[1]) );
|
||||
end
|
||||
|
||||
multiboot_spartan6 hacer_multiboot (
|
||||
.CLK(clk_icap),
|
||||
.MBT_RESET(1'b0),
|
||||
.MBT_REBOOT(reboot_ff),
|
||||
.spi_addr(spi_addr)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module multiboot_spartan6 (
|
||||
input wire CLK,
|
||||
input wire MBT_RESET,
|
||||
input wire MBT_REBOOT,
|
||||
input wire [23:0] spi_addr
|
||||
);
|
||||
|
||||
reg [15:0] icap_din;
|
||||
reg icap_ce;
|
||||
reg icap_wr;
|
||||
|
||||
reg [15:0] ff_icap_din_reversed;
|
||||
reg ff_icap_ce;
|
||||
reg ff_icap_wr;
|
||||
|
||||
|
||||
ICAP_SPARTAN6 ICAP_SPARTAN6_inst (
|
||||
|
||||
.CE (ff_icap_ce), // Clock enable input
|
||||
.CLK (CLK), // Clock input
|
||||
.I (ff_icap_din_reversed), // 16-bit data input
|
||||
.WRITE (ff_icap_wr) // Write input
|
||||
);
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
// -- State Machine for ICAP_SPARTAN6 MultiBoot --
|
||||
// -------------------------------------------------
|
||||
|
||||
|
||||
parameter IDLE = 0,
|
||||
SYNC_H = 1,
|
||||
SYNC_L = 2,
|
||||
|
||||
CWD_H = 3,
|
||||
CWD_L = 4,
|
||||
|
||||
GEN1_H = 5,
|
||||
GEN1_L = 6,
|
||||
|
||||
GEN2_H = 7,
|
||||
GEN2_L = 8,
|
||||
|
||||
GEN3_H = 9,
|
||||
GEN3_L = 10,
|
||||
|
||||
GEN4_H = 11,
|
||||
GEN4_L = 12,
|
||||
|
||||
GEN5_H = 13,
|
||||
GEN5_L = 14,
|
||||
|
||||
NUL_H = 15,
|
||||
NUL_L = 16,
|
||||
|
||||
MOD_H = 17,
|
||||
MOD_L = 18,
|
||||
|
||||
HCO_H = 19,
|
||||
HCO_L = 20,
|
||||
|
||||
RBT_H = 21,
|
||||
RBT_L = 22,
|
||||
|
||||
NOOP_0 = 23,
|
||||
NOOP_1 = 24,
|
||||
NOOP_2 = 25,
|
||||
NOOP_3 = 26;
|
||||
|
||||
|
||||
reg [4:0] state;
|
||||
reg [4:0] next_state;
|
||||
|
||||
|
||||
always @*
|
||||
begin: COMB
|
||||
|
||||
case (state)
|
||||
|
||||
IDLE:
|
||||
begin
|
||||
if (MBT_REBOOT)
|
||||
begin
|
||||
next_state = SYNC_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'hAA99; // Sync word 1
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = IDLE;
|
||||
icap_ce = 1;
|
||||
icap_wr = 1;
|
||||
icap_din = 16'hFFFF; // Null
|
||||
end
|
||||
end
|
||||
|
||||
SYNC_H:
|
||||
begin
|
||||
next_state = SYNC_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h5566; // Sync word 2
|
||||
end
|
||||
|
||||
SYNC_L:
|
||||
begin
|
||||
next_state = NUL_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h30A1; // Write to Command Register....
|
||||
end
|
||||
|
||||
NUL_H:
|
||||
begin
|
||||
// next_state = NUL_L;
|
||||
next_state = GEN1_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h0000; // Null Command issued.... value = 0x0000
|
||||
end
|
||||
|
||||
//Q
|
||||
|
||||
GEN1_H:
|
||||
begin
|
||||
next_state = GEN1_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h3261; // Escritura a reg GENERAL_1 (bit boot en caliente)
|
||||
end
|
||||
|
||||
GEN1_L:
|
||||
begin
|
||||
next_state = GEN2_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = spi_addr[15:0]; //16'hC000; // dreccion SPI BAJA
|
||||
end
|
||||
|
||||
GEN2_H:
|
||||
begin
|
||||
next_state = GEN2_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h3281; // Escritura a reg GENERAL_2
|
||||
end
|
||||
|
||||
GEN2_L:
|
||||
begin
|
||||
next_state = MOD_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = {8'h6B, spi_addr[23:16]}; // 16'h030A; // 03 lectura SPI opcode + direccion SPI ALTA (03 = 1x, 6B = 4x)
|
||||
end
|
||||
|
||||
/////// Registro MODE (para carga a 4x tras reboot)
|
||||
|
||||
MOD_H:
|
||||
begin
|
||||
next_state = MOD_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h3301; // Escritura a reg MODE
|
||||
end
|
||||
|
||||
MOD_L:
|
||||
begin
|
||||
next_state = NUL_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h3100; // Activamos bit de lectura a modo 4x en el proceso de Config
|
||||
end
|
||||
/////
|
||||
|
||||
NUL_L:
|
||||
begin
|
||||
next_state = RBT_H;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h30A1; // Write to Command Register....
|
||||
end
|
||||
|
||||
RBT_H:
|
||||
begin
|
||||
next_state = RBT_L;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h000E; // REBOOT Command 0x000E
|
||||
end
|
||||
|
||||
//--------------------
|
||||
|
||||
RBT_L:
|
||||
begin
|
||||
next_state = NOOP_0;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h2000; // NOOP
|
||||
end
|
||||
|
||||
NOOP_0:
|
||||
begin
|
||||
next_state = NOOP_1;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h2000; // NOOP
|
||||
end
|
||||
|
||||
NOOP_1:
|
||||
begin
|
||||
next_state = NOOP_2;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h2000; // NOOP
|
||||
end
|
||||
|
||||
NOOP_2:
|
||||
begin
|
||||
next_state = NOOP_3;
|
||||
icap_ce = 0;
|
||||
icap_wr = 0;
|
||||
icap_din = 16'h2000; // NOOP
|
||||
end
|
||||
|
||||
//--------------------
|
||||
|
||||
NOOP_3:
|
||||
begin
|
||||
next_state = IDLE;
|
||||
icap_ce = 1;
|
||||
icap_wr = 1;
|
||||
icap_din = 16'h1111; // NULL value
|
||||
end
|
||||
|
||||
default:
|
||||
begin
|
||||
next_state = IDLE;
|
||||
icap_ce = 1;
|
||||
icap_wr = 1;
|
||||
icap_din = 16'h1111; // 16'h1111"
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge CLK)
|
||||
|
||||
begin: SEQ
|
||||
if (MBT_RESET)
|
||||
state <= IDLE;
|
||||
else
|
||||
state <= next_state;
|
||||
end
|
||||
|
||||
|
||||
always @(posedge CLK)
|
||||
|
||||
begin: ICAP_FF
|
||||
|
||||
ff_icap_din_reversed[0] <= icap_din[7]; //need to reverse bits to ICAP module since D0 bit is read first
|
||||
ff_icap_din_reversed[1] <= icap_din[6];
|
||||
ff_icap_din_reversed[2] <= icap_din[5];
|
||||
ff_icap_din_reversed[3] <= icap_din[4];
|
||||
ff_icap_din_reversed[4] <= icap_din[3];
|
||||
ff_icap_din_reversed[5] <= icap_din[2];
|
||||
ff_icap_din_reversed[6] <= icap_din[1];
|
||||
ff_icap_din_reversed[7] <= icap_din[0];
|
||||
ff_icap_din_reversed[8] <= icap_din[15];
|
||||
ff_icap_din_reversed[9] <= icap_din[14];
|
||||
ff_icap_din_reversed[10] <= icap_din[13];
|
||||
ff_icap_din_reversed[11] <= icap_din[12];
|
||||
ff_icap_din_reversed[12] <= icap_din[11];
|
||||
ff_icap_din_reversed[13] <= icap_din[10];
|
||||
ff_icap_din_reversed[14] <= icap_din[9];
|
||||
ff_icap_din_reversed[15] <= icap_din[8];
|
||||
|
||||
ff_icap_ce <= icap_ce;
|
||||
ff_icap_wr <= icap_wr;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.all;
|
||||
use IEEE.NUMERIC_STD.all;
|
||||
|
||||
-- This is input-only for the time being
|
||||
entity ps2_intf is
|
||||
generic (filter_length : positive := 8);
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
nRESET : in std_logic;
|
||||
|
||||
-- PS/2 interface (could be bi-dir)
|
||||
PS2_CLK : in std_logic;
|
||||
PS2_DATA : in std_logic;
|
||||
|
||||
-- Byte-wide data interface - only valid for one clock
|
||||
-- so must be latched externally if required
|
||||
DATA : out std_logic_vector(7 downto 0);
|
||||
VALID : out std_logic;
|
||||
error : out std_logic
|
||||
);
|
||||
end ps2_intf;
|
||||
|
||||
architecture ps2_intf_arch of ps2_intf is
|
||||
--subtype filter_t is std_logic_vector(filter_length-1 downto 0);
|
||||
--signal clk_filter : filter_t;
|
||||
signal clk_filter : std_logic_vector(7 downto 0);
|
||||
|
||||
signal ps2_clk_in : std_logic;
|
||||
signal ps2_dat_in : std_logic;
|
||||
-- Goes high when a clock falling edge is detected
|
||||
signal clk_edge : std_logic;
|
||||
signal bit_count : unsigned (3 downto 0);
|
||||
signal shiftreg : std_logic_vector(8 downto 0);
|
||||
signal parity : std_logic;
|
||||
begin
|
||||
-- Register input signals
|
||||
process(nRESET, CLK)
|
||||
begin
|
||||
if nRESET = '0' then
|
||||
ps2_clk_in <= '1';
|
||||
ps2_dat_in <= '1';
|
||||
clk_filter <= (others => '1');
|
||||
clk_edge <= '0';
|
||||
elsif rising_edge(CLK) then
|
||||
-- Register inputs (and filter clock)
|
||||
ps2_dat_in <= PS2_DATA;
|
||||
clk_filter <= PS2_CLK & clk_filter(7 downto 1);
|
||||
clk_edge <= '0';
|
||||
|
||||
if clk_filter = x"ff" then
|
||||
-- Filtered clock is high
|
||||
ps2_clk_in <= '1';
|
||||
elsif clk_filter = x"00" then
|
||||
-- Filter clock is low, check for edge
|
||||
if ps2_clk_in = '1' then
|
||||
clk_edge <= '1';
|
||||
end if;
|
||||
ps2_clk_in <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Shift in keyboard data
|
||||
process(nRESET, CLK)
|
||||
begin
|
||||
if nRESET = '0' then
|
||||
bit_count <= (others => '0');
|
||||
shiftreg <= (others => '0');
|
||||
parity <= '0';
|
||||
DATA <= (others => '0');
|
||||
VALID <= '0';
|
||||
error <= '0';
|
||||
elsif rising_edge(CLK) then
|
||||
-- Clear flags
|
||||
VALID <= '0';
|
||||
error <= '0';
|
||||
|
||||
if clk_edge = '1' then
|
||||
-- We have a new bit from the keyboard for processing
|
||||
if bit_count = 0 then
|
||||
-- Idle state, check for start bit (0) only and don't
|
||||
-- start counting bits until we get it
|
||||
|
||||
parity <= '0';
|
||||
|
||||
if ps2_dat_in = '0' then
|
||||
-- This is a start bit
|
||||
bit_count <= bit_count + 1;
|
||||
end if;
|
||||
else
|
||||
-- Running. 8-bit data comes in LSb first followed by
|
||||
-- a single stop bit (1)
|
||||
if bit_count < 10 then
|
||||
-- Shift in data and parity (9 bits)
|
||||
bit_count <= bit_count + 1;
|
||||
shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1);
|
||||
parity <= parity xor ps2_dat_in; -- Calculate parity
|
||||
elsif ps2_dat_in = '1' then
|
||||
-- Valid stop bit received
|
||||
bit_count <= (others => '0'); -- back to idle
|
||||
if parity = '1' then
|
||||
-- Parity correct, submit data to host
|
||||
DATA <= shiftreg(7 downto 0);
|
||||
VALID <= '1';
|
||||
else
|
||||
-- Error
|
||||
error <= '1';
|
||||
end if;
|
||||
else
|
||||
-- Invalid stop bit
|
||||
bit_count <= (others => '0'); -- back to idle
|
||||
error <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end ps2_intf_arch;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// taken from the Apple II project by Alex Freed
|
||||
// and modified for own use
|
||||
|
||||
module ramcard(mclk28,reset_in,addr,ram_addr, we, card_ram_we,card_ram_rd, bank1);
|
||||
input mclk28;
|
||||
input reset_in;
|
||||
input [15:0] addr;
|
||||
output [17:0] ram_addr;
|
||||
input we;
|
||||
output card_ram_we;
|
||||
output card_ram_rd;
|
||||
output bank1;
|
||||
|
||||
reg bank1, read_en, write_en, pre_wr_en, bankB, sat_read_en, sat_write_en, sat_pre_wr_en, sat_en;
|
||||
reg [2:0] bank16k;
|
||||
reg [15:0] addr2;
|
||||
wire Dxxx,DEF;
|
||||
|
||||
always @(posedge mclk28) begin
|
||||
addr2 <= addr;
|
||||
if(reset_in) begin
|
||||
bank1 <= 0;
|
||||
read_en <= 0;
|
||||
write_en <= 1;
|
||||
pre_wr_en <= 0;
|
||||
|
||||
bankB <= 0;
|
||||
sat_read_en <= 0;
|
||||
sat_write_en <= 0;
|
||||
sat_pre_wr_en <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if((addr[15:4] == 'hC08) & (addr2 != addr)) begin
|
||||
// Looks like a Language Card in slot 0
|
||||
bank1 <= addr[3];
|
||||
pre_wr_en <= addr[0] & ~we;
|
||||
write_en <= addr[0] & pre_wr_en & ~we;
|
||||
read_en <= ~(addr[0] ^ addr[1]);
|
||||
end
|
||||
if((addr[15:4] == 'hC0D) & (addr2 != addr)) begin
|
||||
// Looks like Saturn128 Card in slot 5
|
||||
if(addr[2] == 0) begin
|
||||
// State selection
|
||||
bankB <= addr[3];
|
||||
sat_pre_wr_en <= addr[0];
|
||||
sat_write_en <= addr[0] & sat_pre_wr_en;
|
||||
sat_read_en <= ~(addr[0] ^ addr[1]);
|
||||
end
|
||||
else
|
||||
begin
|
||||
// 16K bank selection
|
||||
bank16k <= {addr[3], addr[1], addr[0]};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign Dxxx = (addr[15:12] == 4'b1101);
|
||||
assign DEF = ((addr[15:14] == 2'b11) & (addr[13:12] != 2'b00));
|
||||
assign ram_addr = ((sat_write_en || sat_read_en) && DEF)?{1'b1, bank16k, addr[13], addr[12] & ~(bankB & Dxxx), addr[11:0]}:{2'b0,addr[15:13], addr[12] & ~(bank1 & Dxxx), addr[11:0]};
|
||||
assign card_ram_we = (write_en | sat_write_en);
|
||||
assign card_ram_rd = (read_en | sat_read_en);
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity timing_testbench is
|
||||
|
||||
end timing_testbench;
|
||||
|
||||
architecture behavioral of timing_testbench is
|
||||
|
||||
signal CLK_14M : std_logic := '0';
|
||||
|
||||
begin
|
||||
|
||||
uut : entity work.timing_generator
|
||||
port map (
|
||||
CLK_14M => CLK_14M,
|
||||
TEXT_MODE => '1',
|
||||
PAGE2 => '0',
|
||||
HIRES => '1'
|
||||
);
|
||||
|
||||
CLK_14M <= not CLK_14M after 34.920639355 ns;
|
||||
|
||||
end behavioral;
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity wm8731_audio is
|
||||
port (
|
||||
clk : in std_logic; -- Audio CODEC Chip Clock AUD_XCK (18.43 MHz)
|
||||
reset : in std_logic;
|
||||
audio_request : out std_logic; -- Audio controller request new data
|
||||
data : in unsigned(15 downto 0);
|
||||
|
||||
-- Audio interface signals
|
||||
AUD_ADCLRCK : out std_logic; -- Audio CODEC ADC LR Clock
|
||||
AUD_ADCDAT : in std_logic; -- Audio CODEC ADC Data
|
||||
AUD_DACLRCK : out std_logic; -- Audio CODEC DAC LR Clock
|
||||
AUD_DACDAT : out std_logic; -- Audio CODEC DAC Data
|
||||
AUD_BCLK : inout std_logic -- Audio CODEC Bit-Stream Clock
|
||||
);
|
||||
end wm8731_audio;
|
||||
|
||||
architecture rtl of wm8731_audio is
|
||||
|
||||
signal lrck : std_logic;
|
||||
signal bclk : std_logic;
|
||||
signal xck : std_logic;
|
||||
|
||||
signal lrck_divider : unsigned(7 downto 0);
|
||||
signal bclk_divider : unsigned(3 downto 0);
|
||||
|
||||
signal set_bclk : std_logic;
|
||||
signal set_lrck : std_logic;
|
||||
signal clr_bclk : std_logic;
|
||||
signal lrck_lat : std_logic;
|
||||
|
||||
signal shift_out : unsigned(15 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- LRCK divider
|
||||
-- Audio chip main clock is 18.432MHz / Sample rate 48KHz
|
||||
-- Divider is 18.432 MHz / 48KHz = 192 (X"C0")
|
||||
-- Left justify mode set by I2C controller
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
lrck_divider <= (others => '0');
|
||||
elsif lrck_divider = X"BF" then -- "C0" minus 1
|
||||
lrck_divider <= X"00";
|
||||
else
|
||||
lrck_divider <= lrck_divider + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
bclk_divider <= (others => '0');
|
||||
elsif bclk_divider = X"B" or set_lrck = '1' then
|
||||
bclk_divider <= X"0";
|
||||
else
|
||||
bclk_divider <= bclk_divider + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
set_lrck <= '1' when lrck_divider = X"BF" else '0';
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
lrck <= '0';
|
||||
elsif set_lrck = '1' then
|
||||
lrck <= not lrck;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- BCLK divider
|
||||
set_bclk <= '1' when bclk_divider(3 downto 0) = "0101" else '0';
|
||||
clr_bclk <= '1' when bclk_divider(3 downto 0) = "1011" else '0';
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
bclk <= '0';
|
||||
elsif set_lrck = '1' or clr_bclk = '1' then
|
||||
bclk <= '0';
|
||||
elsif set_bclk = '1' then
|
||||
bclk <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Audio data shift output
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
shift_out <= (others => '0');
|
||||
elsif set_lrck = '1' then
|
||||
shift_out <= data;
|
||||
elsif clr_bclk = '1' then
|
||||
shift_out <= shift_out (14 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Audio outputs
|
||||
|
||||
AUD_ADCLRCK <= lrck;
|
||||
AUD_DACLRCK <= lrck;
|
||||
AUD_DACDAT <= shift_out(15);
|
||||
AUD_BCLK <= bclk;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
lrck_lat <= lrck;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if lrck_lat = '1' and lrck = '0' then
|
||||
audio_request <= '1';
|
||||
else
|
||||
audio_request <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
|
|
@ -1,189 +1,158 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity keyboard is
|
||||
port
|
||||
(
|
||||
boot : out std_logic;
|
||||
reset : out std_logic;
|
||||
nmi : out std_logic;
|
||||
received : in std_logic;
|
||||
scancode : in std_logic_vector(7 downto 0);
|
||||
rows : in std_logic_vector(7 downto 0);
|
||||
cols : out std_logic_vector(4 downto 0)
|
||||
);
|
||||
port
|
||||
(
|
||||
sw : in std_logic_vector(7 downto 0);
|
||||
col : in std_logic_vector(4 downto 0);
|
||||
boot : out std_logic;
|
||||
reset : out std_logic;
|
||||
nmi : out std_logic;
|
||||
received : in std_logic;
|
||||
scancode : in std_logic_vector(7 downto 0);
|
||||
rows : in std_logic_vector(7 downto 0);
|
||||
cols : out std_logic_vector(4 downto 0)
|
||||
);
|
||||
end;
|
||||
|
||||
architecture behavioral of keyboard is
|
||||
|
||||
type matrix is array (57 downto 0) of std_logic;
|
||||
signal keys : matrix := (others => '1');
|
||||
|
||||
signal pressed : std_logic := '0';
|
||||
signal extended : std_logic := '0';
|
||||
type matrix is array (7 downto 0) of std_logic_vector(4 downto 0);
|
||||
signal keys, mikeys : matrix;
|
||||
signal isalt : std_logic;
|
||||
signal pressed : std_logic;
|
||||
|
||||
begin
|
||||
process(received, scancode)
|
||||
begin
|
||||
if falling_edge(received) then
|
||||
nmi <= '0';
|
||||
boot <= '0';
|
||||
reset <= '0';
|
||||
pressed <= '1';
|
||||
case scancode is
|
||||
when X"f0" => pressed <= '0';
|
||||
when X"12" |
|
||||
X"59" => keys(0)(0) <= pressed; -- Left or Right shift (CAPS SHIFT)
|
||||
when X"1a" => keys(0)(1) <= pressed; -- Z
|
||||
when X"22" => keys(0)(2) <= pressed; -- X
|
||||
when X"21" => keys(0)(3) <= pressed; -- C
|
||||
when X"2a" => keys(0)(4) <= pressed; -- V
|
||||
when X"1c" => keys(1)(0) <= pressed; -- A
|
||||
when X"1b" => keys(1)(1) <= pressed; -- S
|
||||
when X"23" => keys(1)(2) <= pressed; -- D
|
||||
when X"2b" => keys(1)(3) <= pressed; -- F
|
||||
when X"34" => keys(1)(4) <= pressed; -- G
|
||||
when X"15" => keys(2)(0) <= pressed; -- Q
|
||||
when X"1d" => keys(2)(1) <= pressed; -- W
|
||||
when X"24" => keys(2)(2) <= pressed; -- E
|
||||
when X"2d" => keys(2)(3) <= pressed; -- R
|
||||
when X"2c" => keys(2)(4) <= pressed; -- T
|
||||
when X"16" => keys(3)(0) <= pressed; -- 1
|
||||
when X"1e" => keys(3)(1) <= pressed; -- 2
|
||||
when X"26" => keys(3)(2) <= pressed; -- 3
|
||||
when X"25" => keys(3)(3) <= pressed; -- 4
|
||||
when X"2e" => keys(3)(4) <= pressed; -- 5
|
||||
when X"45" => keys(4)(0) <= pressed; -- 0
|
||||
when X"46" => keys(4)(1) <= pressed; -- 9
|
||||
when X"3e" => keys(4)(2) <= pressed; -- 8
|
||||
when X"3d" => keys(4)(3) <= pressed; -- 7
|
||||
when X"36" => keys(4)(4) <= pressed; -- 6
|
||||
when X"4d" => keys(5)(0) <= pressed; -- P
|
||||
when X"44" => keys(5)(1) <= pressed; -- O
|
||||
when X"43" => keys(5)(2) <= pressed; -- I
|
||||
when X"3c" => keys(5)(3) <= pressed; -- U
|
||||
when X"35" => keys(5)(4) <= pressed; -- Y
|
||||
when X"5a" => keys(6)(0) <= pressed; -- ENTER
|
||||
when X"4b" => keys(6)(1) <= pressed; -- L
|
||||
when X"42" => keys(6)(2) <= pressed; -- K
|
||||
when X"3b" => keys(6)(3) <= pressed; -- J
|
||||
when X"33" => keys(6)(4) <= pressed; -- H
|
||||
when X"29" => keys(7)(0) <= pressed; -- SPACE
|
||||
when X"14" => keys(7)(1) <= pressed; -- CTRL (Symbol Shift)
|
||||
when X"3a" => keys(7)(2) <= pressed; -- M
|
||||
when X"31" => keys(7)(3) <= pressed; -- N
|
||||
when X"32" => keys(7)(4) <= pressed; -- B
|
||||
when X"76" => keys(0)(0) <= pressed; -- Break (Caps Space)
|
||||
keys(7)(0) <= pressed;
|
||||
when X"0e" |
|
||||
X"06" => keys(0)(0) <= pressed; -- Edit (Caps 1)
|
||||
keys(3)(0) <= pressed;
|
||||
when X"4e" |
|
||||
X"09" => keys(0)(0) <= pressed; -- Graph (Caps 9)
|
||||
keys(4)(1) <= pressed;
|
||||
when X"66" => keys(0)(0) <= pressed; -- Backspace (Caps 0)
|
||||
keys(4)(0) <= pressed;
|
||||
if keys(7)(1)='1' and isalt='1' then
|
||||
boot <= '1'; -- Master Reset
|
||||
end if;
|
||||
when X"0d" => keys(0)(0) <= pressed; -- Extend
|
||||
keys(7)(1) <= pressed;
|
||||
when X"54" => keys(0)(0) <= pressed; -- True Video (Caps 3)
|
||||
keys(3)(2) <= pressed;
|
||||
when X"5b" => keys(0)(0) <= pressed; -- Inv. Video (Caps 4)
|
||||
keys(3)(3) <= pressed;
|
||||
when X"58" => keys(0)(0) <= pressed; -- Caps lock (Caps 2)
|
||||
keys(3)(1) <= pressed;
|
||||
when X"6b" => keys(0)(0) <= pressed; -- Left (Caps 5)
|
||||
keys(3)(4) <= pressed;
|
||||
when X"72" => keys(0)(0) <= pressed; -- Down (Caps 6)
|
||||
keys(4)(4) <= pressed;
|
||||
when X"75" => keys(0)(0) <= pressed; -- Up (Caps 7)
|
||||
keys(4)(3) <= pressed;
|
||||
when X"74" => keys(0)(0) <= pressed; -- Right (Caps 8)
|
||||
keys(4)(2) <= pressed;
|
||||
when X"55" => keys(7)(1) <= pressed; -- = (Symb L)
|
||||
keys(6)(1) <= pressed;
|
||||
when X"4a" => keys(7)(1) <= pressed; -- / (Symb V)
|
||||
keys(0)(4) <= pressed;
|
||||
when X"7c" => keys(7)(1) <= pressed; -- * (Symb B)
|
||||
keys(7)(4) <= pressed;
|
||||
when X"7b" => keys(7)(1) <= pressed; -- - (Symb J)
|
||||
keys(6)(3) <= pressed;
|
||||
when X"79" => keys(7)(1) <= pressed; -- + (Symb K)
|
||||
keys(6)(2) <= pressed;
|
||||
when X"4c" => keys(7)(1) <= pressed; -- ; (Symb O)
|
||||
keys(5)(1) <= pressed;
|
||||
when X"52" => keys(7)(1) <= pressed; -- " (Symb P)
|
||||
keys(5)(0) <= pressed;
|
||||
when X"41" => keys(7)(1) <= pressed; -- , (Symb N)
|
||||
keys(7)(3) <= pressed;
|
||||
when X"49" => keys(7)(1) <= pressed; -- , (Symb M)
|
||||
keys(7)(2) <= pressed;
|
||||
when X"71" => if keys(7)(1)='1' and isalt='1' then
|
||||
reset <= '1'; -- Reset
|
||||
end if;
|
||||
when X"11" => isalt <= pressed;
|
||||
when X"03" => if keys(7)(1)='1' and isalt='1' then
|
||||
nmi <= '1'; -- NMI
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(received, scancode)
|
||||
begin
|
||||
if falling_edge(received) then
|
||||
|
||||
case scancode is
|
||||
when x"E0" => extended <= '1'; -- extended
|
||||
when x"F0" => pressed <= '1'; -- released
|
||||
when others =>
|
||||
extended <= '0';
|
||||
pressed <= '0';
|
||||
end case;
|
||||
|
||||
if extended = '0' then
|
||||
case scancode is
|
||||
when x"12" => keys( 0) <= pressed; -- CS (LSHIFT)
|
||||
when x"1A" => keys( 1) <= pressed; -- Z
|
||||
when x"22" => keys( 2) <= pressed; -- X
|
||||
when x"21" => keys( 3) <= pressed; -- C
|
||||
when x"2A" => keys( 4) <= pressed; -- V
|
||||
|
||||
when x"1C" => keys( 5) <= pressed; -- A
|
||||
when x"1B" => keys( 6) <= pressed; -- S
|
||||
when x"23" => keys( 7) <= pressed; -- D
|
||||
when x"2B" => keys( 8) <= pressed; -- F
|
||||
when x"34" => keys( 9) <= pressed; -- G
|
||||
|
||||
when x"15" => keys(10) <= pressed; -- Q
|
||||
when x"1D" => keys(11) <= pressed; -- W
|
||||
when x"24" => keys(12) <= pressed; -- E
|
||||
when x"2D" => keys(13) <= pressed; -- R
|
||||
when x"2C" => keys(14) <= pressed; -- T
|
||||
|
||||
when x"16" => keys(15) <= pressed; -- 1
|
||||
when x"1E" => keys(16) <= pressed; -- 2
|
||||
when x"26" => keys(17) <= pressed; -- 3
|
||||
when x"25" => keys(18) <= pressed; -- 4
|
||||
when x"2E" => keys(19) <= pressed; -- 5
|
||||
|
||||
when x"45" => keys(20) <= pressed; -- 0
|
||||
when x"46" => keys(21) <= pressed; -- 9
|
||||
when x"3E" => keys(22) <= pressed; -- 8
|
||||
when x"3D" => keys(23) <= pressed; -- 7
|
||||
when x"36" => keys(24) <= pressed; -- 6
|
||||
|
||||
when x"4D" => keys(25) <= pressed; -- P
|
||||
when x"44" => keys(26) <= pressed; -- O
|
||||
when x"43" => keys(27) <= pressed; -- I
|
||||
when x"3C" => keys(28) <= pressed; -- U
|
||||
when x"35" => keys(29) <= pressed; -- Y
|
||||
|
||||
when x"5A" => keys(30) <= pressed; -- ENTER
|
||||
when x"4B" => keys(31) <= pressed; -- L
|
||||
when x"42" => keys(32) <= pressed; -- K
|
||||
when x"3B" => keys(33) <= pressed; -- J
|
||||
when x"33" => keys(34) <= pressed; -- H
|
||||
|
||||
when x"29" => keys(35) <= pressed; -- SPACE
|
||||
when x"59" => keys(36) <= pressed; -- SS (RSHIFT)
|
||||
when x"3A" => keys(37) <= pressed; -- M
|
||||
when x"31" => keys(38) <= pressed; -- N
|
||||
when x"32" => keys(39) <= pressed; -- B
|
||||
|
||||
when x"14" => keys(40) <= pressed; -- LCTRL
|
||||
when x"11" => keys(41) <= pressed; -- LALT
|
||||
when x"71" => keys(42) <= pressed; -- KP.
|
||||
|
||||
when x"66" => keys(43) <= pressed; -- BKSP
|
||||
when x"4A" => keys(44) <= pressed; -- -
|
||||
when x"49" => keys(45) <= pressed; -- .
|
||||
when x"41" => keys(46) <= pressed; -- ,
|
||||
|
||||
when x"03" => keys(54) <= pressed; -- F5
|
||||
when x"78" => keys(57) <= pressed; -- F11
|
||||
when x"07" => keys(55) <= pressed; -- F12
|
||||
when x"76" => keys(56) <= pressed; -- ESCAPE
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
case scancode is
|
||||
when x"14" => keys(47) <= pressed; -- RCTRL
|
||||
when x"11" => keys(48) <= pressed; -- RALT
|
||||
when x"71" => keys(49) <= pressed; -- DEL
|
||||
|
||||
when x"75" => keys(50) <= pressed; -- UP
|
||||
when x"72" => keys(51) <= pressed; -- DOWN
|
||||
when x"6B" => keys(52) <= pressed; -- LEFT
|
||||
when x"74" => keys(53) <= pressed; -- RIGHT
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cols(0) <= ( keys( 0) or rows(0) ) and -- CS
|
||||
( keys( 5) or rows(1) ) and -- A
|
||||
( keys(10) or rows(2) ) and -- Q
|
||||
( keys(15) or rows(3) ) and -- 1
|
||||
( keys(20) or rows(4) ) and -- 0
|
||||
( keys(25) or rows(5) ) and -- P
|
||||
( keys(30) or rows(6) ) and -- ENTER
|
||||
( keys(35) or rows(7) ) and -- SPACE
|
||||
( keys(43) or rows(0) ) and -- DELETE(CS)
|
||||
( keys(43) or rows(4) ) and -- DELETE(0)
|
||||
( keys(50) or rows(0) ) and -- UP(CS)
|
||||
( keys(51) or rows(0) ) and -- DOWN(CS)
|
||||
( keys(52) or rows(0) ) and -- LEFT(CS)
|
||||
( keys(53) or rows(0) ) and -- RIGHT(CS)
|
||||
( keys(56) or rows(0) ) and -- ESC
|
||||
( keys(56) or rows(7) ); -- ESC
|
||||
|
||||
cols(1) <= ( keys( 1) or rows(0) ) and -- Z
|
||||
( keys( 6) or rows(1) ) and -- S
|
||||
( keys(11) or rows(2) ) and -- W
|
||||
( keys(16) or rows(3) ) and -- 2
|
||||
( keys(21) or rows(4) ) and -- 9
|
||||
( keys(26) or rows(5) ) and -- O
|
||||
( keys(31) or rows(6) ) and -- L
|
||||
( keys(36) or rows(7) ) and -- SS
|
||||
( keys(44) or rows(7) ) and -- -(SS)
|
||||
( keys(45) or rows(7) ) and -- .(SS)
|
||||
( keys(46) or rows(7) ); -- ,(SS)
|
||||
|
||||
cols(2) <= ( keys( 2) or rows(0) ) and -- X
|
||||
( keys( 7) or rows(1) ) and -- D
|
||||
( keys(12) or rows(2) ) and -- E
|
||||
( keys(17) or rows(3) ) and -- 3
|
||||
( keys(22) or rows(4) ) and -- 8
|
||||
( keys(27) or rows(5) ) and -- I
|
||||
( keys(32) or rows(6) ) and -- K
|
||||
( keys(37) or rows(7) ) and -- M
|
||||
( keys(45) or rows(7) ) and -- .(M)
|
||||
( keys(53) or rows(4) ); -- RIGHT(8)
|
||||
|
||||
cols(3) <= ( keys( 3) or rows(0) ) and -- C
|
||||
( keys( 8) or rows(1) ) and -- F
|
||||
( keys(13) or rows(2) ) and -- R
|
||||
( keys(18) or rows(3) ) and -- 4
|
||||
( keys(23) or rows(4) ) and -- 7
|
||||
( keys(28) or rows(5) ) and -- U
|
||||
( keys(33) or rows(6) ) and -- J
|
||||
( keys(38) or rows(7) ) and -- N
|
||||
( keys(44) or rows(6) ) and -- -(J)
|
||||
( keys(46) or rows(7) ) and -- ,(N)
|
||||
( keys(50) or rows(4) ); -- UP(7)
|
||||
|
||||
cols(4) <= ( keys( 4) or rows(0) ) and -- V
|
||||
( keys( 9) or rows(1) ) and -- G
|
||||
( keys(14) or rows(2) ) and -- T
|
||||
( keys(19) or rows(3) ) and -- 5
|
||||
( keys(24) or rows(4) ) and -- 6
|
||||
( keys(29) or rows(5) ) and -- Y
|
||||
( keys(34) or rows(6) ) and -- H
|
||||
( keys(39) or rows(7) ) and -- B
|
||||
( keys(52) or rows(3) ) and -- LEFT(5)
|
||||
( keys(51) or rows(4) ); -- DOWN(7)
|
||||
|
||||
nmi <= keys(54);
|
||||
boot <= keys(57) and ((keys(40) and keys(47)) or (keys(41) and keys(48)) or (keys(43)));
|
||||
reset <= keys(55) and ((keys(40) and keys(47)) or (keys(41) and keys(48)) or (keys(42) and keys(49)));
|
||||
process (col)
|
||||
begin
|
||||
for i in 0 to 4 loop
|
||||
if col(i)='0' then
|
||||
for j in 0 to 7 loop
|
||||
mikeys(j)(i)<= sw(j);
|
||||
end loop;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
process (keys, rows)
|
||||
variable tmp: std_logic;
|
||||
begin
|
||||
for i in 0 to 4 loop
|
||||
tmp:= '1';
|
||||
for j in 0 to 7 loop
|
||||
tmp:= tmp and (not keys(j)(i) or not mikeys(j)(i) or rows(j));
|
||||
end loop;
|
||||
cols(i) <= tmp;
|
||||
end loop;
|
||||
end process;
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ entity ula is
|
|||
mic : out std_logic;
|
||||
speaker : out std_logic;
|
||||
--
|
||||
sw : in std_logic_vector(7 downto 0);
|
||||
col : inout std_logic_vector(4 downto 0);
|
||||
rows : in std_logic_vector(15 downto 8);
|
||||
boot : out std_logic;
|
||||
reset : out std_logic;
|
||||
|
|
@ -92,6 +94,8 @@ begin
|
|||
(
|
||||
received => received,
|
||||
scancode => scancode,
|
||||
sw => sw,
|
||||
col => col,
|
||||
boot => boot,
|
||||
reset => reset,
|
||||
nmi => nmi,
|
||||
|
|
@ -129,6 +133,18 @@ begin
|
|||
if vCount < 311
|
||||
then
|
||||
vCount <= vCount+1;
|
||||
case vCount(8 downto 6) is
|
||||
when "000" =>
|
||||
col <= "11110";
|
||||
when "001" =>
|
||||
col <= "11101";
|
||||
when "010" =>
|
||||
col <= "11011";
|
||||
when "011" =>
|
||||
col <= "10111";
|
||||
when others =>
|
||||
col <= "01111";
|
||||
end case;
|
||||
else
|
||||
vCount <= (others => '0');
|
||||
fCount <= fCount+1;
|
||||
|
|
|
|||
|
|
@ -17,4 +17,5 @@ verilog work "../multiboot.v"
|
|||
vhdl work "../mixer.vhd"
|
||||
vhdl work "../div.vhd"
|
||||
vhdl work "../clock.vhd"
|
||||
vhdl work "../ay8910.vhd"
|
||||
vhdl work "../zxkyp.vhd"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ entity zxkyp is
|
|||
clock50 : in std_logic;
|
||||
led : out std_logic;
|
||||
--
|
||||
sw : in std_logic_vector(7 downto 0);
|
||||
col : inout std_logic_vector(4 downto 0);
|
||||
--
|
||||
sramWr : out std_logic;
|
||||
sramData : inout std_logic_vector( 7 downto 0);
|
||||
sramAddr : out std_logic_vector(18 downto 0);
|
||||
|
|
@ -163,6 +166,8 @@ begin
|
|||
mic => mic,
|
||||
speaker => speaker,
|
||||
--
|
||||
sw => sw,
|
||||
col => col,
|
||||
rows => addr(15 downto 8),
|
||||
boot => boot,
|
||||
reset => reset,
|
||||
|
|
|
|||
|
|
@ -91,3 +91,20 @@ NET "sdDo" LOC="P78" | IOSTANDARD = LVCMOS33 | SLEW=FAST; # do
|
|||
|
||||
#NET "flash_ext1" LOC="P62" | IOSTANDARD = LVCMOS33;
|
||||
#NET "flash_ext2" LOC="P61" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
# 8 slide switches
|
||||
NET "sw<0>" LOC="P51" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<1>" LOC="P46" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<2>" LOC="P45" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<3>" LOC="P50" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<4>" LOC="P48" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<5>" LOC="P57" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<6>" LOC="P56" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
NET "sw<7>" LOC="P58" | IOSTANDARD=LVCMOS33 | PULLUP;
|
||||
|
||||
# 5 columns
|
||||
NET "col<0>" LOC="P33" | IOSTANDARD=LVCMOS33;
|
||||
NET "col<1>" LOC="P40" | IOSTANDARD=LVCMOS33;
|
||||
NET "col<2>" LOC="P17" | IOSTANDARD=LVCMOS33;
|
||||
NET "col<3>" LOC="P44" | IOSTANDARD=LVCMOS33;
|
||||
NET "col<4>" LOC="P14" | IOSTANDARD=LVCMOS33;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ module coreid (
|
|||
text[i] = 8'h00;
|
||||
text[ 0] = "T";
|
||||
text[ 1] = "2";
|
||||
text[ 2] = "3";
|
||||
text[ 2] = "4";
|
||||
text[ 3] = "-";
|
||||
text[ 4] = "1";
|
||||
text[ 5] = "6";
|
||||
text[ 6] = "0";
|
||||
text[ 7] = "9";
|
||||
text[ 4] = "0";
|
||||
text[ 5] = "7";
|
||||
text[ 6] = "1";
|
||||
text[ 7] = "1";
|
||||
text[ 8] = "2";
|
||||
text[ 9] = "0";
|
||||
text[10] = "1";
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ module scancode_to_speccy (
|
|||
reg [13:0] addr = 14'h0000;
|
||||
reg [13:0] cpuaddr = 14'h0000; // Dirección E/S desde la CPU. Se autoincrementa en cada acceso
|
||||
initial begin
|
||||
$readmemh ("../keymaps/keyb_es_hex.txt", keymap);
|
||||
$readmemh ("keyb_es_hex.txt", keymap);
|
||||
end
|
||||
|
||||
reg [2:0] keyrow1 = 3'h0;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ module ula_radas (
|
|||
input wire [7:0] zxuno_addr,
|
||||
input wire zxuno_regrd,
|
||||
input wire zxuno_regwr,
|
||||
input wire regaddr_changed,
|
||||
|
||||
// I/O ports
|
||||
input wire ear,
|
||||
|
|
@ -103,13 +104,23 @@ module ula_radas (
|
|||
wire [8:0] hc;
|
||||
wire [8:0] vc;
|
||||
|
||||
// Initial values for Radastanian mode pixel and border palette bank
|
||||
reg radasborderpalettehalf = 1'b0;
|
||||
reg [1:0] radaspixelpalettequarter = 2'b00;
|
||||
|
||||
// Initial values for synch, syncv for all supported timings
|
||||
reg [8:0] hinit48k = 9'd112;
|
||||
reg [8:0] vinit48k = 9'd2;
|
||||
reg [8:0] vinit48k = 9'd0;
|
||||
reg [8:0] hinit128k = 9'd116;
|
||||
reg [8:0] vinit128k = 9'd2;
|
||||
reg [8:0] vinit128k = 9'd0;
|
||||
reg [8:0] hinitpen = 9'd110;
|
||||
reg [8:0] vinitpen = 9'd0;
|
||||
|
||||
// Initial values for offset and padding in Radastanian mode, used for HW scroller
|
||||
reg [13:0] radasoffset = 14'h0000;
|
||||
reg [7:0] radaspadding = 8'h00;
|
||||
reg ffbitmapofs = 1'b0;
|
||||
reg [7:0] lastdatatoradasoffset = 8'h00;
|
||||
|
||||
// Signal when the vertical counter is in the line that we use to make the INT signal
|
||||
wire in_int_line;
|
||||
|
|
@ -230,7 +241,7 @@ module ula_radas (
|
|||
always @* begin
|
||||
InputToAttrOutput = AttrData;
|
||||
case ({VideoEnable,HR})
|
||||
2'b00 : InputToAttrOutput = (RadasEnabled)? {1'b0,Border,1'b0,Border} : {2'b00,Border,3'b000};
|
||||
2'b00 : InputToAttrOutput = (RadasEnabled)? {radasborderpalettehalf,Border,radasborderpalettehalf,Border} : {2'b00,Border,3'b000};
|
||||
2'b01,
|
||||
2'b11 : InputToAttrOutput = {2'b01,~HRInk,HRInk};
|
||||
2'b10 : InputToAttrOutput = AttrData;
|
||||
|
|
@ -339,9 +350,9 @@ module ula_radas (
|
|||
wire [7:0] ULAplusPaperColour;
|
||||
wire [7:0] ULAplusInkColour;
|
||||
|
||||
wire [5:0] AddressA1 = (RadasEnabled)? {2'b00,InputToAttrOutput[7:4]} :
|
||||
wire [5:0] AddressA1 = (RadasEnabled)? {radaspixelpalettequarter,InputToAttrOutput[7:4]} :
|
||||
{InputToAttrOutput[7:6],1'b1,InputToAttrOutput[5:3]};
|
||||
wire [5:0] AddressA2 = (RadasEnabled)? {2'b00,InputToAttrOutput[3:0]} :
|
||||
wire [5:0] AddressA2 = (RadasEnabled)? {radaspixelpalettequarter,InputToAttrOutput[3:0]} :
|
||||
{InputToAttrOutput[7:6],1'b0,InputToAttrOutput[2:0]};
|
||||
lut palette (
|
||||
.clk(clk28),
|
||||
|
|
@ -418,8 +429,9 @@ module ula_radas (
|
|||
else
|
||||
va = 14'hZZZZ;
|
||||
end
|
||||
else begin
|
||||
va = {PG,vc[7:1],hcd[7:2]};
|
||||
else begin
|
||||
//va = {PG,vc[7:1],hcd[7:2]};
|
||||
va = {PG,vc[7:1],hcd[7:2]} + radasoffset + vc[7:1]*radaspadding;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -500,8 +512,7 @@ module ula_radas (
|
|||
TIMEXPORT = 8'hFF,
|
||||
TIMEXMMU = 8'hF4,
|
||||
ULAPLUSADDR = 16'hBF3B,
|
||||
ULAPLUSDATA = 16'hFF3B,
|
||||
RADASCTRL = 8'h40;
|
||||
ULAPLUSDATA = 16'hFF3B;
|
||||
|
||||
parameter
|
||||
HOFFS48K = 8'h80,
|
||||
|
|
@ -510,6 +521,12 @@ module ula_radas (
|
|||
VOFFS128K = 8'h83,
|
||||
HOFFSPEN = 8'h84,
|
||||
VOFFSPEN = 8'h85;
|
||||
|
||||
parameter
|
||||
RADASCTRL = 8'h40,
|
||||
RADASOFFSET = 8'h41,
|
||||
RADASPADDING = 8'h42,
|
||||
RADASPALBANK = 8'h43;
|
||||
|
||||
// Z80 writes values into registers
|
||||
// Port 0xFE
|
||||
|
|
@ -542,7 +559,7 @@ module ula_radas (
|
|||
end
|
||||
end
|
||||
|
||||
// Sync adjustment
|
||||
// Sync and radastanian palette adjustment
|
||||
always @(posedge clkregs) begin
|
||||
if (zxuno_regwr == 1'b1) begin
|
||||
case (zxuno_addr)
|
||||
|
|
@ -552,9 +569,45 @@ module ula_radas (
|
|||
VOFFS128K: vinit128k <= {din,1'b0};
|
||||
HOFFSPEN: hinitpen <= {din,1'b0};
|
||||
VOFFSPEN: vinitpen <= {din,1'b0};
|
||||
RADASPALBANK: {radasborderpalettehalf,radaspixelpalettequarter} <= din[2:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// Control de offsets del modo radastaniano
|
||||
reg offset_reg_accessed = 1'b0;
|
||||
always @(posedge clkregs) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
ffbitmapofs <= 1'b0;
|
||||
radasoffset <= 14'h0000;
|
||||
radaspadding <= 8'h00;
|
||||
end
|
||||
else begin
|
||||
if (regaddr_changed && zxuno_addr == RADASOFFSET)
|
||||
ffbitmapofs <= 1'b0;
|
||||
else if (offset_reg_accessed == 1'b0 && zxuno_addr == RADASOFFSET && (zxuno_regrd == 1'b1 || zxuno_regwr == 1'b1)) begin
|
||||
if (zxuno_regwr == 1'b1 && ffbitmapofs == 1'b0) begin
|
||||
radasoffset[7:0] <= din;
|
||||
end
|
||||
else if (zxuno_regwr == 1'b1 && ffbitmapofs == 1'b1) begin
|
||||
radasoffset[13:8] <= din[5:0];
|
||||
end
|
||||
else if (zxuno_regrd == 1'b1 && ffbitmapofs == 1'b0) begin
|
||||
lastdatatoradasoffset <= radasoffset[7:0];
|
||||
end
|
||||
else if (zxuno_regrd == 1'b1 && ffbitmapofs == 1'b1) begin
|
||||
lastdatatoradasoffset <= {2'b00,radasoffset[13:8]};
|
||||
end
|
||||
ffbitmapofs <= ~ffbitmapofs;
|
||||
offset_reg_accessed <= 1'b1;
|
||||
end
|
||||
else if (zxuno_regwr == 1'b1 && zxuno_addr == RADASPADDING) begin
|
||||
radaspadding <= din;
|
||||
end
|
||||
if (offset_reg_accessed == 1'b1 && zxuno_regwr == 1'b0 && zxuno_regwr == 1'b0)
|
||||
offset_reg_accessed <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
reg post_processed_ear; // EAR signal after being altered by the keyboard current issue
|
||||
always @* begin
|
||||
|
|
@ -570,8 +623,6 @@ module ula_radas (
|
|||
if (iorq_n==1'b0 && rd_n==1'b0) begin
|
||||
if (a[0]==1'b0 && a[7:0]!=8'hF4)
|
||||
dout = {1'b1,post_processed_ear,1'b1,kbd};
|
||||
else if (zxuno_addr == RADASCTRL && zxuno_regrd == 1'b1 && !disable_radas)
|
||||
dout = {6'b000000,RadasCtrl};
|
||||
else if (a==ULAPLUSADDR && !disable_ulaplus)
|
||||
dout = {1'b0,PaletteReg};
|
||||
else if (a==ULAPLUSDATA && PaletteReg[6]==1'b0 && !disable_ulaplus)
|
||||
|
|
@ -592,6 +643,14 @@ module ula_radas (
|
|||
dout = hinitpen[8:1];
|
||||
else if (zxuno_addr == VOFFSPEN && zxuno_regrd == 1'b1)
|
||||
dout = vinitpen[8:1];
|
||||
else if (zxuno_addr == RADASCTRL && zxuno_regrd == 1'b1 && !disable_radas)
|
||||
dout = {6'b000000,RadasCtrl};
|
||||
else if (zxuno_addr == RADASOFFSET && zxuno_regrd == 1'b1 && !disable_radas)
|
||||
dout = lastdatatoradasoffset;
|
||||
else if (zxuno_addr == RADASPADDING && zxuno_regrd == 1'b1 && !disable_radas)
|
||||
dout = radaspadding;
|
||||
else if (zxuno_addr == RADASPALBANK && zxuno_regrd == 1'b1 && !disable_radas)
|
||||
dout = {5'b00000, radasborderpalettehalf,radaspixelpalettequarter};
|
||||
else begin
|
||||
if (BitmapAddr || AttrAddr)
|
||||
dout = vramdata;
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ module zxuno (
|
|||
.zxuno_addr(zxuno_addr),
|
||||
.zxuno_regrd(zxuno_regrd),
|
||||
.zxuno_regwr(zxuno_regwr),
|
||||
.regaddr_changed(regaddr_changed),
|
||||
|
||||
// I/O ports
|
||||
.ear(ear),
|
||||
|
|
|
|||
Loading…
Reference in New Issue