From 121d786705e729d06327a6e7f6f138841d3b0149 Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Fri, 16 Dec 2016 17:53:56 +0100 Subject: [PATCH] Arreglo cores Electron, Apple2 --- cores/AcornElectron/working/ElectronFpga.xst | 2 +- cores/Apple2/build/APPLE2_TOP.prj | 6 +- cores/Apple2/source/PS2_Ctrl.vhd | 147 ------- cores/Apple2/source/i2c_controller.vhd | 211 ---------- cores/Apple2/source/i2c_testbench.vhd | 26 -- cores/Apple2/source/keyb.vhd | 224 +++++++++++ cores/Apple2/source/keyboard.vhd | 394 ------------------- cores/Apple2/source/multiboot_v4.v | 310 +++++++++++++++ cores/Apple2/source/ps2_intf.vhd | 119 ++++++ cores/Apple2/source/ramcard.v | 65 +++ cores/Apple2/source/timing_testbench.vhd | 25 -- cores/Apple2/source/wm8731_audio.vhd | 141 ------- cores/KypSpectrum/keyboard.vhd | 323 +++++++-------- cores/KypSpectrum/ula.vhd | 16 + cores/KypSpectrum/work/zxkyp.prj | 1 + cores/KypSpectrum/zxkyp.vhd | 5 + cores/KypSpectrum/zxkyp_zxuno_v4.ucf | 17 + cores/Spectrum/coreid.v | 10 +- cores/Spectrum/scancode_to_speccy.v | 2 +- cores/Spectrum/ula_radas.v | 83 +++- cores/Spectrum/zxuno.v | 1 + 21 files changed, 986 insertions(+), 1142 deletions(-) delete mode 100644 cores/Apple2/source/PS2_Ctrl.vhd delete mode 100644 cores/Apple2/source/i2c_controller.vhd delete mode 100644 cores/Apple2/source/i2c_testbench.vhd create mode 100644 cores/Apple2/source/keyb.vhd delete mode 100644 cores/Apple2/source/keyboard.vhd create mode 100644 cores/Apple2/source/multiboot_v4.v create mode 100644 cores/Apple2/source/ps2_intf.vhd create mode 100644 cores/Apple2/source/ramcard.v delete mode 100644 cores/Apple2/source/timing_testbench.vhd delete mode 100644 cores/Apple2/source/wm8731_audio.vhd diff --git a/cores/AcornElectron/working/ElectronFpga.xst b/cores/AcornElectron/working/ElectronFpga.xst index 364b805..0f65ef0 100644 --- a/cores/AcornElectron/working/ElectronFpga.xst +++ b/cores/AcornElectron/working/ElectronFpga.xst @@ -1,4 +1,4 @@ -set -tmpdir "xst/projnav.tmp" +set -tmpdir "projnav.tmp" set -xsthdpdir "xst" run -ifn ElectronFpga.prj diff --git a/cores/Apple2/build/APPLE2_TOP.prj b/cores/Apple2/build/APPLE2_TOP.prj index c24450c..320a374 100644 --- a/cores/Apple2/build/APPLE2_TOP.prj +++ b/cores/Apple2/build/APPLE2_TOP.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" diff --git a/cores/Apple2/source/PS2_Ctrl.vhd b/cores/Apple2/source/PS2_Ctrl.vhd deleted file mode 100644 index 6421c75..0000000 --- a/cores/Apple2/source/PS2_Ctrl.vhd +++ /dev/null @@ -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; - diff --git a/cores/Apple2/source/i2c_controller.vhd b/cores/Apple2/source/i2c_controller.vhd deleted file mode 100644 index 7df53dd..0000000 --- a/cores/Apple2/source/i2c_controller.vhd +++ /dev/null @@ -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; diff --git a/cores/Apple2/source/i2c_testbench.vhd b/cores/Apple2/source/i2c_testbench.vhd deleted file mode 100644 index ae6da6a..0000000 --- a/cores/Apple2/source/i2c_testbench.vhd +++ /dev/null @@ -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; diff --git a/cores/Apple2/source/keyb.vhd b/cores/Apple2/source/keyb.vhd new file mode 100644 index 0000000..b55f163 --- /dev/null +++ b/cores/Apple2/source/keyb.vhd @@ -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; diff --git a/cores/Apple2/source/keyboard.vhd b/cores/Apple2/source/keyboard.vhd deleted file mode 100644 index 737ed92..0000000 --- a/cores/Apple2/source/keyboard.vhd +++ /dev/null @@ -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; diff --git a/cores/Apple2/source/multiboot_v4.v b/cores/Apple2/source/multiboot_v4.v new file mode 100644 index 0000000..14c951a --- /dev/null +++ b/cores/Apple2/source/multiboot_v4.v @@ -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 diff --git a/cores/Apple2/source/ps2_intf.vhd b/cores/Apple2/source/ps2_intf.vhd new file mode 100644 index 0000000..7080c26 --- /dev/null +++ b/cores/Apple2/source/ps2_intf.vhd @@ -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; diff --git a/cores/Apple2/source/ramcard.v b/cores/Apple2/source/ramcard.v new file mode 100644 index 0000000..7d93dcf --- /dev/null +++ b/cores/Apple2/source/ramcard.v @@ -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 diff --git a/cores/Apple2/source/timing_testbench.vhd b/cores/Apple2/source/timing_testbench.vhd deleted file mode 100644 index ab249c1..0000000 --- a/cores/Apple2/source/timing_testbench.vhd +++ /dev/null @@ -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; diff --git a/cores/Apple2/source/wm8731_audio.vhd b/cores/Apple2/source/wm8731_audio.vhd deleted file mode 100644 index 9633393..0000000 --- a/cores/Apple2/source/wm8731_audio.vhd +++ /dev/null @@ -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; - - diff --git a/cores/KypSpectrum/keyboard.vhd b/cores/KypSpectrum/keyboard.vhd index 1d5e5e9..9351130 100644 --- a/cores/KypSpectrum/keyboard.vhd +++ b/cores/KypSpectrum/keyboard.vhd @@ -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; diff --git a/cores/KypSpectrum/ula.vhd b/cores/KypSpectrum/ula.vhd index 3893a8b..61a86e6 100644 --- a/cores/KypSpectrum/ula.vhd +++ b/cores/KypSpectrum/ula.vhd @@ -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; diff --git a/cores/KypSpectrum/work/zxkyp.prj b/cores/KypSpectrum/work/zxkyp.prj index d9e3b7e..f5de1ea 100644 --- a/cores/KypSpectrum/work/zxkyp.prj +++ b/cores/KypSpectrum/work/zxkyp.prj @@ -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" diff --git a/cores/KypSpectrum/zxkyp.vhd b/cores/KypSpectrum/zxkyp.vhd index 16d4d25..d74c578 100644 --- a/cores/KypSpectrum/zxkyp.vhd +++ b/cores/KypSpectrum/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, diff --git a/cores/KypSpectrum/zxkyp_zxuno_v4.ucf b/cores/KypSpectrum/zxkyp_zxuno_v4.ucf index f9727a4..9de5093 100644 --- a/cores/KypSpectrum/zxkyp_zxuno_v4.ucf +++ b/cores/KypSpectrum/zxkyp_zxuno_v4.ucf @@ -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; diff --git a/cores/Spectrum/coreid.v b/cores/Spectrum/coreid.v index 659c9cb..7c980a7 100644 --- a/cores/Spectrum/coreid.v +++ b/cores/Spectrum/coreid.v @@ -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"; diff --git a/cores/Spectrum/scancode_to_speccy.v b/cores/Spectrum/scancode_to_speccy.v index 19dcbee..22f0555 100644 --- a/cores/Spectrum/scancode_to_speccy.v +++ b/cores/Spectrum/scancode_to_speccy.v @@ -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; diff --git a/cores/Spectrum/ula_radas.v b/cores/Spectrum/ula_radas.v index 9fb9fdd..7a62610 100644 --- a/cores/Spectrum/ula_radas.v +++ b/cores/Spectrum/ula_radas.v @@ -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; diff --git a/cores/Spectrum/zxuno.v b/cores/Spectrum/zxuno.v index c95e534..f016078 100644 --- a/cores/Spectrum/zxuno.v +++ b/cores/Spectrum/zxuno.v @@ -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),