1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-19 09:18:02 +00:00

Repair Keyboard -> Release

This commit is contained in:
Gehstock 2018-09-29 13:07:42 +02:00
parent 1847ad375f
commit 174c546ae6
18 changed files with 1365 additions and 1325 deletions

Binary file not shown.

View File

@ -17,15 +17,15 @@
# -------------------------------------------------------------------------- #
#
# Quartus II 64-Bit
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
# Date created = 18:40:37 November 24, 2017
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Full Version
# Date created = 13:05:26 September 29, 2018
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# ace_assignment_defaults.qdf
# mz80k_mist_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
@ -41,9 +41,28 @@
# ========================
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:59:05 MARCH 16, 2017"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY Output
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
set_global_assignment -name SYSTEMVERILOG_FILE rtl/mz80k_mist.sv
set_global_assignment -name VERILOG_FILE rtl/mz80k_top.v
set_global_assignment -name VERILOG_FILE rtl/vga.v
set_global_assignment -name VERILOG_FILE rtl/i8253.v
set_global_assignment -name VERILOG_FILE rtl/fz80.v
set_global_assignment -name VERILOG_FILE rtl/sound.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
set_global_assignment -name VERILOG_FILE rtl/sigma_delta_dac.v
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
set_global_assignment -name VERILOG_FILE rtl/osd.v
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
set_global_assignment -name VERILOG_FILE rtl/pll.v
set_global_assignment -name VERILOG_FILE rtl/cg_rom.v
set_global_assignment -name VERILOG_FILE rtl/ram2.v
set_global_assignment -name VERILOG_FILE rtl/monrom.v
set_global_assignment -name VHDL_FILE rtl/keymatrix.vhd
set_global_assignment -name VHDL_FILE rtl/sprom.vhd
set_global_assignment -name VHDL_FILE rtl/i8255.vhd
# Pin & Location Assignments
# ==========================
@ -129,15 +148,14 @@ set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
# ================================
set_global_assignment -name FAMILY "Cyclone III"
set_global_assignment -name TOP_LEVEL_ENTITY mz80k_mist
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
# Fitter Assignments
# ==================
set_global_assignment -name DEVICE EP3C25E144C8
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_NCE_PIN OFF
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
@ -173,46 +191,26 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# EDA Netlist Writer Assignments
# ==============================
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
# end EDA_TOOL_SETTINGS(eda_simulation)
# -------------------------------------
# ----------------------
# start ENTITY(ace_mist)
# ------------------------
# start ENTITY(mz80k_mist)
# start DESIGN_PARTITION(Top)
# ---------------------------
# Incremental Compilation Assignments
# ===================================
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# end DESIGN_PARTITION(Top)
# -------------------------
# end ENTITY(ace_mist)
# --------------------
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name SYSTEMVERILOG_FILE rtl/mz80k_mist.sv
set_global_assignment -name VERILOG_FILE rtl/mz80k_top.v
set_global_assignment -name VERILOG_FILE rtl/vga.v
set_global_assignment -name VERILOG_FILE rtl/i8253.v
set_global_assignment -name VERILOG_FILE rtl/ps2.v
set_global_assignment -name VERILOG_FILE rtl/fz80.v
set_global_assignment -name VERILOG_FILE rtl/sound.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
set_global_assignment -name VERILOG_FILE rtl/sigma_delta_dac.v
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
set_global_assignment -name VERILOG_FILE rtl/osd.v
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/keyboard.sv
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name VERILOG_FILE rtl/pll.v
set_global_assignment -name VERILOG_FILE rtl/cg_rom.v
set_global_assignment -name VERILOG_FILE rtl/ram2.v
set_global_assignment -name VERILOG_FILE rtl/monrom.v
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# end ENTITY(mz80k_mist)
# ----------------------

View File

@ -1,2 +1,2 @@
`define BUILD_DATE "180624"
`define BUILD_TIME "132954"
`define BUILD_DATE "180929"
`define BUILD_TIME "130303"

View File

@ -1,18 +0,0 @@
CLOCK_ENABLE_INPUT_A=NORMAL
CLOCK_ENABLE_OUTPUT_A=NORMAL
INIT_FILE=./roms/Mon.hex
INTENDED_DEVICE_FAMILY="Cyclone III"
NUMWORDS_A=32768
OPERATION_MODE=SINGLE_PORT
OUTDATA_ACLR_A=NONE
OUTDATA_REG_A=CLOCK0
POWER_UP_UNINITIALIZED=FALSE
READ_DURING_WRITE_MODE_PORT_A=NEW_DATA_NO_NBE_READ
WIDTHAD_A=15
WIDTH_A=8
WIDTH_BYTEENA_A=1
DEVICE_FAMILY="Cyclone III"
address_a
clock0
clocken0
q_a

View File

@ -1,284 +0,0 @@
`timescale 1ns / 1ps
// ============================================================================
// i8255.v
// - PIO
//
// (C) 2012 Robert Finch, Stratford
// robfinch<remove>@opencores.org
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
module i8255(ack_o, rst_i, clk_i, rd_i, we_i, cs_i, adr_i, dat_i, dat_o, a, b, c);
output ack_o;
input rst_i;
input clk_i;
input rd_i;
input we_i;
input cs_i;
input [1:0] adr_i;
input [7:0] dat_i;
output [7:0] dat_o;
reg [7:0] dat_o;
inout [7:0] a;
tri [7:0] a;
inout [7:0] b;
tri [7:0] b;
inout [7:0] c;
tri [7:0] c;
reg [7:0] ao,bo,co; // output registers
reg [7:0] aL,bL; // input latches
reg [1:0] modeA;
reg modeB;
reg [7:0] cio;
reg aio;
reg bio;
wire INTEai = co[4];
wire INTEao = co[6];
wire INTEb = co[2];
wire ackA_n = c[6];
wire stbA_n = c[4];
wire ackB_n = c[2];
wire stbB_n = c[2];
reg ostbA_n,ostbB_n; // old strobe
reg oackA_n,oackB_n; // old acknowledge
reg ack1;
//wire cs = cyc_i && stb_i && (adr_i[15:2]==pIOAddress[15:2]);
always @(posedge clk_i)
ack1 <= cs_i;
assign ack_o = cs_i ? (we_i ? 1'b1 : ack1) : 1'b0;
wire wr = cs_i & we_i;
reg owr; // old write
reg [1:0] oad; // old address
// Input port latches
always @(stbA_n)
if (stbA_n==1'b0)
aL <= a;
always @(stbB_n)
if (stbB_n==1'b0)
bL <= b;
always @(posedge clk_i)
if (rst_i) begin
modeA <= 2'd0;
modeB <= 1'b0;
cio <= 8'hFF;
aio <= 1'b1;
bio <= 1'b1;
ao <= 8'h00;
bo <= 8'h00;
co <= 8'h00;
end
else begin
owr <= wr;
oad <= adr_i[1:0];
ostbA_n <= stbA_n;
ostbB_n <= stbB_n;
oackA_n <= ackA_n;
oackB_n <= ackB_n;
// Ports in Input mode: Negative edge on strobe actives IBF signal
if (stbA_n==1'b0 && ostbA_n==1'b1 && ((modeA==2'd1 && aio) || modeA==2'd2))
co[5] <= 1'b1;
if (stbB_n==1'b0 && ostbB_n==1'b1 && modeB==1'b1 && bio)
co[1] <= 1'b1;
// Ports in input mode: rising edge on strobe sets interrupt output if INTE is set.
if (stbA_n==1'b1 && ostbA_n==1'b0 && ((modeA==2'd1 && aio) || modeA==2'd2))
if (INTEai)
co[3] <= 1'b1;
if (stbB_n==1'b1 && ostbB_n==1'b0 && modeB==1'b1 && bio)
if (INTEb)
co[0] <= 1'b1;
// Ports in output mode: Rising edge on ACK sets interrupt output if INTE is set.
if (!oackA_n & ackA_n && ((modeA==2'd1 && !aio) || modeA==2'd2))
if (INTEao)
co[3] <= 1'b1;
if (!oackB_n & ackB_n && (modeB==1'd1 && !bio))
if (INTEb)
co[0] <= 1'b1;
// Deactivation of write causes OBF_n to be activated
// Output: write causes INTR to be reset
if (!wr & owr) begin
case(oad)
2'd0: begin
if ((modeA==2'd1 && !aio) || modeA==2'd2)
co[7] <= 1'b0;
if ((modeA==2'd1 && !aio) || modeA==2'd2)
if (INTEao)
co[3] <= 1'b0;
end
2'd1: begin
if (modeB==1'b1 && !bio)
co[1] <= 1'b0;
if (modeB==1'b1 && !bio)
if (INTEb)
co[0] <= 1'b0;
end
endcase
end
// falling edge of ACK causes OBF_n to be deactivated
if (oackA_n & !ackA_n && ((modeA==2'b01 && !aio) || modeA==2'd2))
co[7] <= 1'b1;
if (oackB_n & !ackB_n && (modeB==1'b1 && !bio))
co[1] <= 1'b1;
if (cs_i & we_i) begin
case(adr_i[1:0])
2'd0: ao <= dat_i;
2'd1: bo <= dat_i;
2'd2: co <= dat_i;
2'd3:
begin
if (dat_i[7]) begin
modeB <= dat_i[2];
if (dat_i[2]) begin
// Port C pin directions are the same for
// both input and output under mode 1
cio[2] <= 1'b1;
cio[1] <= 1'b0;
cio[0] <= 1'b0;
end
else begin
cio[3] <= dat_i[0]; // This pin control will be overridden by Port A settings.
cio[2] <= dat_i[0];
cio[1] <= dat_i[0];
cio[0] <= dat_i[0];
end
modeA <= dat_i[6:5];
case(dat_i[6:5])
2'b00: begin
cio[7] <= dat_i[3];
cio[6] <= dat_i[3];
cio[5] <= dat_i[3];
cio[4] <= dat_i[3];
end
2'b01: begin
// Mode 1 - Input
if (dat_i[4]) begin
cio[4] <= 1'b1;
cio[5] <= 1'b0;
cio[3] <= 1'b0;
end
// Mode 1 - Output
else begin
cio[7] <= 1'b0;
cio[6] <= 1'b1;
cio[3] <= 1'b0;
end
end
2'b1x: begin
cio[7] <= 1'b0;
cio[6] <= 1'b1;
cio[4] <= 1'b1;
cio[5] <= 1'b0;
cio[3] <= 1'b0;
end
endcase
aio <= dat_i[4];
bio <= dat_i[1];
// Mode change causes port A and C outputs to be
// reset to zero.
if (dat_i[6:5]!=modeA) begin
ao <= 8'h00;
co <= 8'h00;
end
end
else begin
case(dat_i[3:1])
3'd0: co[0] <= dat_i[0];
3'd1: co[1] <= dat_i[0];
3'd2: co[2] <= dat_i[0];
3'd3: co[3] <= dat_i[0];
3'd4: co[4] <= dat_i[0];
3'd5: co[5] <= dat_i[0];
3'd6: co[6] <= dat_i[0];
3'd7: co[7] <= dat_i[0];
endcase
end
end
endcase
end
// Reads
if (cs_i) begin
case(adr_i[1:0])
2'd0: begin
if (modeA==2'b00) // Simple I/O
dat_o <= aio ? a : ao;
else begin // Handshake I/O
// Reading port clears IBF
if (aio==1'b1) begin
dat_o <= aL;
co[5] <= 1'b0;
if (INTEai) // Reading the port resets the interrupt
co[3] <= 1'b0;
end
else
dat_o <= ao;
end
end
2'd1: begin
if (modeB==1'b0)
dat_o <= bio ? b : bo;
else begin
// Reading port clears IBF
if (bio==1'b1) begin
dat_o <= bL;
co[1] <= 1'b0;
if (INTEb) // Reading the port resets the interrupt
co[0] <= 1'b0;
end
else
dat_o <= bo;
end
end
2'd2: dat_o <= {
cio[0] ? c[0] : co[0],
cio[1] ? c[1] : co[1],
cio[2] ? c[2] : co[2],
cio[3] ? c[3] : co[3],
cio[4] ? c[4] : co[4],
cio[5] ? c[5] : co[5],
cio[6] ? c[6] : co[6],
cio[7] ? c[7] : co[7],
};
2'd3: dat_o <= 8'h00; // no read of control word
endcase
end
else
dat_o <= 8'h00;
end
// In mode 2 the I/O is defined as output when ACK is active, otherwise input; the aio setting is a don't care.
assign a =
(modeA==2'd2) ? (ackA_n==1'b0 ? ao : 8'bz) :
aio ? 8'bz : ao;
assign b = bio ? 8'bz : bo;
assign c[0] = cio[0] ? 1'bz : co[0];
assign c[1] = cio[1] ? 1'bz : co[1];
assign c[2] = cio[2] ? 1'bz : co[2];
assign c[3] = cio[3] ? 1'bz : co[3];
assign c[4] = cio[4] ? 1'bz : co[4];
assign c[5] = cio[5] ? 1'bz : co[5];
assign c[6] = cio[6] ? 1'bz : co[6];
assign c[7] = cio[7] ? 1'bz : co[7];
endmodule

View File

@ -1,203 +1,700 @@
---------------------------------------------------------------------------------------------------------
--
-- i8255.vhd
-- Name: i8255.vhd
-- Created: Feb 2007
-- Author(s): MikeJ, Refactored and ported for this emulation by Philip Smart
-- Description: Sharp MZ series i8255 PPI
-- This module emulates the Intel i8255 Programmable Peripheral Interface chip.
--
-- Intel 8255 (PPI:Programmable Peripheral Interface) partiality compatible module
-- for MZ-700 on FPGA
-- Credits:
-- Copyright: (c) MikeJ - Feb 2007
--
-- Port A : Output, mode 0 only
-- Port B : Input, mode 0 only
-- Port C : Input(7-4)&Output(3-0), mode 0 only, bit set/reset support
-- History: July 2018 - Initial module refactored and updated for this emulation.
--
-- Nibbles Lab. 2005
---------------------------------------------------------------------------------------------------------
--
-- Original copyright notice below:-
--
-- A simulation model of i8255 PIA
-- Copyright (c) MikeJ - Feb 2007
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- You are responsible for any legal issues arising from your use of this code.
--
-- The latest version of this file can be found at: www.fpgaarcade.com
--
-- Email support@fpgaarcade.com
--
-- Revision list
--
-- version 001 initial release
--
---------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity i8255 is
Port ( RST : in std_logic;
A : in std_logic_vector(1 downto 0);
CS : in std_logic;
WR : in std_logic;
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
LDDAT : out std_logic_vector(7 downto 0);
-- LDDAT2 : out std_logic;
-- LDSNS : out std_logic;
CLKIN : in std_logic;
KCLK : in std_logic;
-- FCLK : in std_logic;
VBLNK : in std_logic;
INTMSK : out std_logic;
RBIT : in std_logic;
SENSE : in std_logic;
MOTOR : out std_logic;
PS2CK : in std_logic;
PS2DT : in std_logic);
end i8255;
port (
RESET : in std_logic;
CLK : in std_logic;
ENA : in std_logic; -- (CPU) clk enable
ADDR : in std_logic_vector(1 downto 0); -- A1-A0
DI : in std_logic_vector(7 downto 0); -- D7-D0
DO : out std_logic_vector(7 downto 0);
-- DO_OE_n : out std_logic;
CS_n : in std_logic;
RD_n : in std_logic;
WR_n : in std_logic;
PA_I : in std_logic_vector(7 downto 0);
PA_O : out std_logic_vector(7 downto 0);
PA_O_OE_n : out std_logic_vector(7 downto 0);
PB_I : in std_logic_vector(7 downto 0);
PB_O : out std_logic_vector(7 downto 0);
PB_O_OE_n : out std_logic_vector(7 downto 0);
PC_I : in std_logic_vector(7 downto 0);
PC_O : out std_logic_vector(7 downto 0);
PC_O_OE_n : out std_logic_vector(7 downto 0)
);
end;
architecture Behavioral of i8255 is
--
-- Port Register
--
signal PA : std_logic_vector(7 downto 0);
signal PB : std_logic_vector(7 downto 0);
signal PC : std_logic_vector(7 downto 0);
--
-- Port Selecter
--
signal SELPA : std_logic;
signal SELPB : std_logic;
signal SELPC : std_logic;
signal SELCT : std_logic;
--
-- CURSOR blink
--
signal TBLNK : std_logic;
signal CCOUNT : std_logic_vector(3 downto 0);
--
-- Remote
--
signal SNS : std_logic;
signal MTR : std_logic;
signal M_ON : std_logic;
signal SENSE0 : std_logic;
signal SWIN : std_logic_vector(3 downto 0);
--
-- Components
--
component keymatrix
Port ( RST : in std_logic;
PA : in std_logic_vector(3 downto 0);
PB : out std_logic_vector(7 downto 0);
KCLK : in std_logic;
LDDAT : out std_logic_vector(7 downto 0);
PS2CK : in std_logic;
PS2DT : in std_logic);
end component;
architecture RTL of i8255 is
-- registers
signal bit_mask : std_logic_vector(7 downto 0);
signal r_porta : std_logic_vector(7 downto 0);
signal r_portb : std_logic_vector(7 downto 0);
signal r_portc : std_logic_vector(7 downto 0);
signal r_control : std_logic_vector(7 downto 0);
--
signal porta_we : std_logic;
signal portb_we : std_logic;
signal porta_re : std_logic;
signal portb_re : std_logic;
--
signal porta_we_t1 : std_logic;
signal portb_we_t1 : std_logic;
signal porta_re_t1 : std_logic;
signal portb_re_t1 : std_logic;
--
signal porta_we_rising : boolean;
signal portb_we_rising : boolean;
signal porta_re_rising : boolean;
signal portb_re_rising : boolean;
--
signal groupa_mode : std_logic_vector(1 downto 0); -- port a/c upper
signal groupb_mode : std_logic; -- port b/c lower
--
signal porta_read : std_logic_vector(7 downto 0);
signal portb_read : std_logic_vector(7 downto 0);
signal portc_read : std_logic_vector(7 downto 0);
signal control_read : std_logic_vector(7 downto 0);
signal mode_clear : std_logic;
--
signal a_inte1 : std_logic;
signal a_inte2 : std_logic;
signal b_inte : std_logic;
--
signal a_intr : std_logic;
signal a_obf_l : std_logic;
signal a_ibf : std_logic;
signal a_ack_l : std_logic;
signal a_stb_l : std_logic;
signal a_ack_l_t1 : std_logic;
signal a_stb_l_t1 : std_logic;
--
signal b_intr : std_logic;
signal b_obf_l : std_logic;
signal b_ibf : std_logic;
signal b_ack_l : std_logic;
signal b_stb_l : std_logic;
signal b_ack_l_t1 : std_logic;
signal b_stb_l_t1 : std_logic;
--
signal a_ack_l_rising : boolean;
signal a_stb_l_rising : boolean;
signal b_ack_l_rising : boolean;
signal b_stb_l_rising : boolean;
--
signal porta_ipreg : std_logic_vector(7 downto 0);
signal portb_ipreg : std_logic_vector(7 downto 0);
begin
--
-- mode 0 - basic input/output
-- mode 1 - strobed input/output
-- mode 2/3 - bi-directional bus
--
-- control word (write)
--
-- D7 mode set flag 1 = active
-- D6..5 GROUPA mode selection (mode 0,1,2)
-- D4 GROUPA porta 1 = input, 0 = output
-- D3 GROUPA portc upper 1 = input, 0 = output
-- D2 GROUPB mode selection (mode 0 ,1)
-- D1 GROUPB portb 1 = input, 0 = output
-- D0 GROUPB portc lower 1 = input, 0 = output
--
-- D7 bit set/reset 0 = active
-- D6..4 x
-- D3..1 bit select
-- d0 1 = set, 0 - reset
--
-- all output registers including status are reset when mode is changed
--1. Port A:
--All Modes: Output data is cleared, input data is not cleared.
--
-- Instantiation
--
keys : keymatrix port map (
RST => RST,
PA => PA(3 downto 0),
PB => PB,
KCLK => KCLK,
LDDAT => LDDAT,
PS2CK => PS2CK,
PS2DT => PS2DT);
--2. Port B:
--Mode 0: Output data is cleared, input data is not cleared.
--Mode 1 and 2: Both output and input data are cleared.
--
-- Port select for Output
--
SELPA<='1' when A="00" else '0';
SELPB<='1' when A="01" else '0';
SELPC<='1' when A="10" else '0';
SELCT<='1' when A="11" else '0';
--3. Port C:
--Mode 0:Output data is cleared, input data is not cleared.
--Mode 1 and 2: IBF and INTR are cleared and OBF# is set.
--Outputs in Port C which are not used for handshaking or interrupt signals are cleared.
--Inputs such as STB#, ACK#, or "spare" inputs are not affected. The interrupts for Ports A and B are disabled.
--
-- Output
--
process( RST, WR, CS ) begin
if( RST='0' ) then
PA<=(others=>'0');
-- PB<=(others=>'0');
PC<=(others=>'0');
elsif( WR'event and WR='1' and CS='0' ) then
if( SELPA='1' ) then
PA<=DI;
end if;
-- if( SELPB='1' ) then
-- PB<=DI;
-- end if;
if( SELPC='1' ) then
PC(3 downto 0)<=DI(3 downto 0);
end if;
if( SELCT='1' and DI(7)='0' ) then
case DI(3 downto 0) is
when "0000" => PC(0)<='0';
when "0001" => PC(0)<='1';
when "0010" => PC(1)<='0';
when "0011" => PC(1)<='1';
when "0100" => PC(2)<='0';
when "0101" => PC(2)<='1';
when "0110" => PC(3)<='0';
when "0111" => PC(3)<='1';
-- when "1000" => PC(4)<='0';
-- when "1001" => PC(4)<='1';
-- when "1010" => PC(5)<='0';
-- when "1011" => PC(5)<='1';
-- when "1100" => PC(6)<='0';
-- when "1101" => PC(6)<='1';
-- when "1110" => PC(7)<='0';
-- when "1111" => PC(7)<='1';
when others => PC<="XXXXXXXX";
end case;
end if;
end if;
end process;
p_bit_mask : process(DI)
begin
bit_mask <= x"01";
case DI(3 downto 1) is
when "000" => bit_mask <= x"01";
when "001" => bit_mask <= x"02";
when "010" => bit_mask <= x"04";
when "011" => bit_mask <= x"08";
when "100" => bit_mask <= x"10";
when "101" => bit_mask <= x"20";
when "110" => bit_mask <= x"40";
when "111" => bit_mask <= x"80";
when others => null;
end case;
end process;
--
-- CURSOR blink Clock
--
process( CLKIN, PA(7) ) begin
if( PA(7)='0' ) then
CCOUNT<=(others=>'0');
elsif( CLKIN'event and CLKIN='1' ) then
CCOUNT<=CCOUNT+'1';
if( CCOUNT=13 ) then
CCOUNT<=(others=>'0');
TBLNK<=not TBLNK;
end if;
end if;
end process;
p_write_reg_reset : process(RESET, CLK)
variable r_portc_masked : std_logic_vector(7 downto 0);
variable r_portc_setclr : std_logic_vector(7 downto 0);
begin
if (RESET = '1') then
r_porta <= x"00";
r_portb <= x"00";
r_portc <= x"00";
r_control <= x"9B"; -- 10011011
mode_clear <= '1';
elsif rising_edge(CLK) then
--
-- Input select
--
DO<=PB when SELPB='1' else
VBLNK&TBLNK&RBIT&MTR&PC(3 downto 0) when SELPC='1' else (others=>'1');
r_portc_masked := (not bit_mask) and r_portc;
for i in 0 to 7 loop
r_portc_setclr(i) := bit_mask(i) and DI(0);
end loop;
--
-- Remote
--
MOTOR<=MTR;
process( KCLK ) begin
if( KCLK'event and KCLK='1' ) then
M_ON<=PC(3);
SNS<=SENSE0;
if( SENSE0='1' ) then
MTR<='0';
elsif( SNS='1' and SENSE0='0' ) then
MTR<='1';
elsif( M_ON='0' and PC(3)='1' ) then
MTR<=not MTR;
end if;
if (ENA = '1') then
mode_clear <= '0';
if (CS_n = '0') and (WR_n = '0') then
case ADDR is
when "00" => r_porta <= DI;
when "01" => r_portb <= DI;
when "10" => r_portc <= DI;
SWIN<=SWIN(2 downto 0)&(not SENSE);
if( SWIN="1111" and SENSE='0' ) then
SENSE0<='0';
elsif( SWIN="0000" and SENSE='1' ) then
SENSE0<='1';
end if;
end if;
end process;
when "11" => if (DI(7) = '0') then -- set/clr
r_portc <= r_portc_masked or r_portc_setclr;
else
--mode_clear <= '1';
--r_porta <= x"00";
--r_portb <= x"00"; -- clear port b input reg
--r_portc <= x"00"; -- clear control sigs
r_control <= DI; -- load new mode
end if;
when others => null;
end case;
end if;
end if;
end if;
end process;
--
-- Others
--
INTMSK<=PC(2);
p_decode_control : process(r_control)
begin
groupa_mode <= r_control(6 downto 5);
groupb_mode <= r_control(2);
end process;
end Behavioral;
--p_oe : process(CS_n, RD_n)
--begin
-- DO_OE_n <= '1';
-- if (CS_n = '0') and (RD_n = '0') then
-- DO_OE_n <= '0';
-- end if;
--end process;
p_read : process(ADDR , porta_read, portb_read, portc_read, control_read)
begin
DO <= x"00"; -- default
--if (CS_n = '0') and (RD_n = '0') then -- not required
case ADDR is
when "00" => DO <= porta_read;
when "01" => DO <= portb_read;
when "10" => DO <= portc_read;
when "11" => DO <= control_read;
when others => null;
end case;
--end if;
end process;
control_read(7) <= '1'; -- always 1
control_read(6 downto 0) <= r_control(6 downto 0);
p_rw_control : process(CS_n, RD_n, WR_n, ADDR )
begin
porta_we <= '0';
portb_we <= '0';
porta_re <= '0';
portb_re <= '0';
if (CS_n = '0') and (ADDR = "00") then
porta_we <= not WR_n;
porta_re <= not RD_n;
end if;
if (CS_n = '0') and (ADDR = "01") then
portb_we <= not WR_n;
portb_re <= not RD_n;
end if;
end process;
p_rw_control_reg : process
begin
wait until rising_edge(CLK);
if (ENA = '1') then
porta_we_t1 <= porta_we;
portb_we_t1 <= portb_we;
porta_re_t1 <= porta_re;
portb_re_t1 <= portb_re;
a_stb_l_t1 <= a_stb_l;
a_ack_l_t1 <= a_ack_l;
b_stb_l_t1 <= b_stb_l;
b_ack_l_t1 <= b_ack_l;
end if;
end process;
porta_we_rising <= (porta_we = '0') and (porta_we_t1 = '1'); -- falling as inverted
portb_we_rising <= (portb_we = '0') and (portb_we_t1 = '1'); -- "
porta_re_rising <= (porta_re = '0') and (porta_re_t1 = '1'); -- falling as inverted
portb_re_rising <= (portb_re = '0') and (portb_re_t1 = '1'); -- "
--
a_stb_l_rising <= (a_stb_l = '1') and (a_stb_l_t1 = '0');
a_ack_l_rising <= (a_ack_l = '1') and (a_ack_l_t1 = '0');
b_stb_l_rising <= (b_stb_l = '1') and (b_stb_l_t1 = '0');
b_ack_l_rising <= (b_ack_l = '1') and (b_ack_l_t1 = '0');
--
-- GROUP A
-- in mode 1
--
-- d4=1 (porta = input)
-- pc7,6 io (d3=1 input, d3=0 output)
-- pc5 output a_ibf
-- pc4 input a_stb_l
-- pc3 output a_intr
--
-- d4=0 (porta = output)
-- pc7 output a_obf_l
-- pc6 input a_ack_l
-- pc5,4 io (d3=1 input, d3=0 output)
-- pc3 output a_intr
--
-- GROUP B
-- in mode 1
-- d1=1 (portb = input)
-- pc2 input b_stb_l
-- pc1 output b_ibf
-- pc0 output b_intr
--
-- d1=0 (portb = output)
-- pc2 input b_ack_l
-- pc1 output b_obf_l
-- pc0 output b_intr
-- WHEN AN INPUT
--
-- stb_l a low on this input latches input data
-- ibf a high on this output indicates data latched. set by stb_l and reset by rising edge of RD_L
-- intr a high on this output indicates interrupt. set by stb_l high, ibf high and inte high. reset by falling edge of RD_L
-- inte A controlled by bit/set PC4
-- inte B controlled by bit/set PC2
-- WHEN AN OUTPUT
--
-- obf_l output will go low when cpu has written data
-- ack_l input - a low on this clears obf_l
-- intr output set when ack_l is high, obf_l is high and inte is one. reset by falling edge of WR_L
-- inte A controlled by bit/set PC6
-- inte B controlled by bit/set PC2
-- GROUP A
-- in mode 2
--
-- porta = IO
--
-- control bits 2..0 still control groupb/c lower 2..0
--
--
-- PC7 output a_obf
-- PC6 input a_ack_l
-- PC5 output a_ibf
-- PC4 input a_stb_l
-- PC3 is still interrupt out
p_control_flags : process(RESET, CLK)
variable we : boolean;
variable set1 : boolean;
variable set2 : boolean;
begin
if (RESET = '1') then
a_obf_l <= '1';
a_inte1 <= '0';
a_ibf <= '0';
a_inte2 <= '0';
a_intr <= '0';
--
b_inte <= '0';
b_obf_l <= '1';
b_ibf <= '0';
b_intr <= '0';
elsif rising_edge(CLK) then
we := (CS_n = '0') and (WR_n = '0') and (ADDR = "11") and (DI(7) = '0');
if (ENA = '1') then
if (mode_clear = '1') then
a_obf_l <= '1';
a_inte1 <= '0';
a_ibf <= '0';
a_inte2 <= '0';
a_intr <= '0';
--
b_inte <= '0';
b_obf_l <= '1';
b_ibf <= '0';
b_intr <= '0';
else
if (bit_mask(7) = '1') and we then
a_obf_l <= DI(0);
else
if porta_we_rising then
a_obf_l <= '0';
elsif (a_ack_l = '0') then
a_obf_l <= '1';
end if;
end if;
--
if (bit_mask(6) = '1') and we then a_inte1 <= DI(0); end if; -- bus set when mode1 & input?
--
if (bit_mask(5) = '1') and we then
a_ibf <= DI(0);
else
if porta_re_rising then
a_ibf <= '0';
elsif (a_stb_l = '0') then
a_ibf <= '1';
end if;
end if;
--
if (bit_mask(4) = '1') and we then a_inte2 <= DI(0); end if; -- bus set when mode1 & output?
--
set1 := a_ack_l_rising and (a_obf_l = '1') and (a_inte1 = '1');
set2 := a_stb_l_rising and (a_ibf = '1') and (a_inte2 = '1');
--
if (bit_mask(3) = '1') and we then
a_intr <= DI(0);
else
if (groupa_mode(1) = '1') then
if (porta_we = '1') or (porta_re = '1') then
a_intr <= '0';
elsif set1 or set2 then
a_intr <= '1';
end if;
else
if (r_control(4) = '0') then -- output
if (porta_we = '1') then -- falling ?
a_intr <= '0';
elsif set1 then
a_intr <= '1';
end if;
elsif (r_control(4) = '1') then -- input
if (porta_re = '1') then -- falling ?
a_intr <= '0';
elsif set2 then
a_intr <= '1';
end if;
end if;
end if;
end if;
--
if (bit_mask(2) = '1') and we then b_inte <= DI(0); end if; -- bus set?
if (bit_mask(1) = '1') and we then
b_obf_l <= DI(0);
else
if (r_control(1) = '0') then -- output
if portb_we_rising then
b_obf_l <= '0';
elsif (b_ack_l = '0') then
b_obf_l <= '1';
end if;
else
if portb_re_rising then
b_ibf <= '0';
elsif (b_stb_l = '0') then
b_ibf <= '1';
end if;
end if;
end if;
if (bit_mask(0) = '1') and we then
b_intr <= DI(0);
else
if (r_control(1) = '0') then -- output
if (portb_we = '1') then -- falling ?
b_intr <= '0';
elsif b_ack_l_rising and (b_obf_l = '1') and (b_inte = '1') then
b_intr <= '1';
end if;
else
if (portb_re = '1') then -- falling ?
b_intr <= '0';
elsif b_stb_l_rising and (b_ibf = '1') and (b_inte = '1') then
b_intr <= '1';
end if;
end if;
end if;
end if;
end if;
end if;
end process;
p_porta : process(r_porta, r_control, groupa_mode, PA_I, porta_ipreg, a_ack_l)
begin
-- D4 GROUPA porta 1 = input, 0 = output
PA_O <= x"FF"; -- if not driven, float high
PA_O_OE_n <= x"FF";
porta_read <= x"00";
if (groupa_mode = "00") then -- simple io
if (r_control(4) = '0') then -- output
PA_O <= r_porta;
PA_O_OE_n <= x"00";
end if;
porta_read <= PA_I;
elsif (groupa_mode = "01") then -- strobed
if (r_control(4) = '0') then -- output
PA_O <= r_porta;
PA_O_OE_n <= x"00";
end if;
porta_read <= porta_ipreg;
else -- if (groupa_mode(1) = '1') then -- bi dir
if (a_ack_l = '0') then -- output enable
PA_O <= r_porta;
PA_O_OE_n <= x"00";
end if;
porta_read <= porta_ipreg; -- latched data
end if;
end process;
p_portb : process(r_portb, r_control, groupb_mode, PB_I, portb_ipreg)
begin
PB_O <= x"FF"; -- if not driven, float high
PB_O_OE_n <= x"FF";
portb_read <= x"00";
if (groupb_mode = '0') then -- simple io
if (r_control(1) = '0') then -- output
PB_O <= r_portb;
PB_O_OE_n <= x"00";
end if;
portb_read <= PB_I;
else -- strobed mode
if (r_control(1) = '0') then -- output
PB_O <= r_portb;
PB_O_OE_n <= x"00";
end if;
portb_read <= portb_ipreg;
end if;
end process;
p_portc_out : process(r_portc, r_control, groupa_mode, groupb_mode,
a_obf_l, a_ibf, a_intr,b_obf_l, b_ibf, b_intr)
begin
PC_O <= x"FF"; -- if not driven, float high
PC_O_OE_n <= x"FF";
-- bits 7..4
if (groupa_mode = "00") then -- simple io
if (r_control(3) = '0') then -- output
PC_O (7 downto 4) <= r_portc(7 downto 4);
PC_O_OE_n(7 downto 4) <= x"0";
end if;
elsif (groupa_mode = "01") then -- mode1
if (r_control(4) = '0') then -- port a output
PC_O (7) <= a_obf_l;
PC_O_OE_n(7) <= '0';
-- 6 is ack_l input
if (r_control(3) = '0') then -- port c output
PC_O (5 downto 4) <= r_portc(5 downto 4);
PC_O_OE_n(5 downto 4) <= "00";
end if;
else -- port a input
if (r_control(3) = '0') then -- port c output
PC_O (7 downto 6) <= r_portc(7 downto 6);
PC_O_OE_n(7 downto 6) <= "00";
end if;
PC_O (5) <= a_ibf;
PC_O_OE_n(5) <= '0';
-- 4 is stb_l input
end if;
else -- if (groupa_mode(1) = '1') then -- mode2
PC_O (7) <= a_obf_l;
PC_O_OE_n(7) <= '0';
-- 6 is ack_l input
PC_O (5) <= a_ibf;
PC_O_OE_n(5) <= '0';
-- 4 is stb_l input
end if;
-- bit 3 (controlled by group a)
if (groupa_mode = "00") then -- group a steals this bit
--if (groupb_mode = '0') then -- we will let bit 3 be driven, data sheet is a bit confused about this
if (r_control(0) = '0') then -- ouput (note, groupb control bit)
PC_O (3) <= r_portc(3);
PC_O_OE_n(3) <= '0';
end if;
--
else -- stolen
PC_O (3) <= a_intr;
PC_O_OE_n(3) <= '0';
end if;
-- bits 2..0
if (groupb_mode = '0') then -- simple io
if (r_control(0) = '0') then -- output
PC_O (2 downto 0) <= r_portc(2 downto 0);
PC_O_OE_n(2 downto 0) <= "000";
end if;
else
-- mode 1
-- 2 is input
if (r_control(1) = '0') then -- output
PC_O (1) <= b_obf_l;
PC_O_OE_n(1) <= '0';
else -- input
PC_O (1) <= b_ibf;
PC_O_OE_n(1) <= '0';
end if;
PC_O (0) <= b_intr;
PC_O_OE_n(0) <= '0';
end if;
end process;
p_portc_in : process(r_portc, PC_I, r_control, groupa_mode, groupb_mode, a_ibf, b_obf_l,
a_obf_l, a_inte1, a_inte2, a_intr, b_inte, b_ibf, b_intr)
begin
portc_read <= x"00";
a_stb_l <= '1';
a_ack_l <= '1';
b_stb_l <= '1';
b_ack_l <= '1';
if (groupa_mode = "01") then -- mode1 or 2
if (r_control(4) = '0') then -- port a output
a_ack_l <= PC_I(6);
else -- port a input
a_stb_l <= PC_I(4);
end if;
elsif (groupa_mode(1) = '1') then -- mode 2
a_ack_l <= PC_I(6);
a_stb_l <= PC_I(4);
end if;
if (groupb_mode = '1') then
if (r_control(1) = '0') then -- output
b_ack_l <= PC_I(2);
else -- input
b_stb_l <= PC_I(2);
end if;
end if;
if (groupa_mode = "00") then -- simple io
portc_read(7 downto 3) <= PC_I(7 downto 3);
elsif (groupa_mode = "01") then
if (r_control(4) = '0') then -- port a output
portc_read(7 downto 3) <= a_obf_l & a_inte1 & PC_I(5 downto 4) & a_intr;
else -- input
portc_read(7 downto 3) <= PC_I(7 downto 6) & a_ibf & a_inte2 & a_intr;
end if;
else -- mode 2
portc_read(7 downto 3) <= a_obf_l & a_inte1 & a_ibf & a_inte2 & a_intr;
end if;
if (groupb_mode = '0') then -- simple io
portc_read(2 downto 0) <= PC_I(2 downto 0);
else
if (r_control(1) = '0') then -- output
portc_read(2 downto 0) <= b_inte & b_obf_l & b_intr;
else -- input
portc_read(2 downto 0) <= b_inte & b_ibf & b_intr;
end if;
end if;
end process;
p_ipreg : process
begin
wait until rising_edge(CLK);
-- pc4 input a_stb_l
-- pc2 input b_stb_l
if (ENA = '1') then
if (a_stb_l = '0') then
porta_ipreg <= PA_I;
end if;
if (mode_clear = '1') then
portb_ipreg <= (others => '0');
elsif (b_stb_l = '0') then
portb_ipreg <= PB_I;
end if;
end if;
end process;
end architecture RTL;

View File

@ -1,78 +0,0 @@
module keyboard
(
input clk,
input reset,
input ps2_kbd_clk,
input ps2_kbd_data,
output reg[7:0] joystick
);
reg [11:0] shift_reg = 12'hFFF;
wire[11:0] kdata = {ps2_kbd_data,shift_reg[11:1]};
wire [7:0] kcode = kdata[9:2];
reg release_btn = 0;
reg [7:0] code;
reg input_strobe = 0;
always @(negedge clk) begin
reg old_reset = 0;
old_reset <= reset;
if(~old_reset & reset)begin
joystick <= 0;
end
if(input_strobe) begin
case(code)
'h75: joystick[7] <= ~release_btn; // arrow up
'h74: joystick[6] <= ~release_btn; // arrow right
'h72: joystick[5] <= ~release_btn; // arrow down
'h6B: joystick[4] <= ~release_btn; // arrow left
'h16: joystick[3] <= ~release_btn; // 1
'h1E: joystick[2] <= ~release_btn; // 2
'h26: joystick[1] <= ~release_btn; // 3
'h25: joystick[0] <= ~release_btn; // 4
endcase
end
end
always @(posedge clk) begin
reg [3:0] prev_clk = 0;
reg old_reset = 0;
reg action = 0;
old_reset <= reset;
input_strobe <= 0;
if(~old_reset & reset)begin
prev_clk <= 0;
shift_reg <= 12'hFFF;
end else begin
prev_clk <= {ps2_kbd_clk,prev_clk[3:1]};
if(prev_clk == 1) begin
if (kdata[11] & ^kdata[10:2] & ~kdata[1] & kdata[0]) begin
shift_reg <= 12'hFFF;
if (kcode == 8'he0) ;
// Extended key code follows
else if (kcode == 8'hf0)
// Release code follows
action <= 1;
else begin
// Cancel extended/release flags for next time
action <= 0;
release_btn <= action;
code <= kcode;
input_strobe <= 1;
end
end else begin
shift_reg <= kdata;
end
end
end
end
endmodule

View File

@ -0,0 +1,226 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: keymatrix.vhd
-- Created: July 2018
-- Author(s): Philip Smart
-- Description: Keyboard module to convert PS2 key codes into Sharp scan matrix key connections.
-- For each scan output (10 lines) sent by the Sharp, an 8bit response is read in
-- and the bits set indicate keys pressed. This allows for multiple keys to be pressed
-- at the same time. The PS2 scan code is mapped via a rom and the output is used to drive
-- the data in lines of the 8255.
--
-- Credits: Nibbles Lab (c) 2005-2012
-- Copyright: (c) 2018 Philip Smart <philip.smart@net2net.org>
--
-- History: July 2018 - Initial module written, originally based on the Nibbles Lab code but
-- rewritten to match the overall design of this emulation.
--
---------------------------------------------------------------------------------------------------------
-- This source file is free software: you can redistribute it and-or modify
-- it under the terms of the GNU General Public License as published
-- by the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This source file is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
---------------------------------------------------------------------------------------------------------
library IEEE;
library pkgs;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity keymatrix is
Port (
RST_n : in std_logic;
-- i8255
PA : in std_logic_vector(3 downto 0);
PB : out std_logic_vector(7 downto 0);
STALL : in std_logic;
-- PS/2 Keyboard Data
PS2_KEY : in std_logic_vector(10 downto 0); -- PS2 Key data.
KEY_BANK : in std_logic_vector(2 downto 0);
-- Clock signals used by this module.
CKCPU : in std_logic
);
end keymatrix;
architecture Behavioral of keymatrix is
--
-- prefix flag
--
signal FLGF0 : std_logic;
signal FLGE0 : std_logic;
--
-- MZ-series matrix registers
--
signal SCAN00 : std_logic_vector(7 downto 0);
signal SCAN01 : std_logic_vector(7 downto 0);
signal SCAN02 : std_logic_vector(7 downto 0);
signal SCAN03 : std_logic_vector(7 downto 0);
signal SCAN04 : std_logic_vector(7 downto 0);
signal SCAN05 : std_logic_vector(7 downto 0);
signal SCAN06 : std_logic_vector(7 downto 0);
signal SCAN07 : std_logic_vector(7 downto 0);
signal SCAN08 : std_logic_vector(7 downto 0);
signal SCAN09 : std_logic_vector(7 downto 0);
signal SCAN10 : std_logic_vector(7 downto 0);
signal SCAN11 : std_logic_vector(7 downto 0);
signal SCAN12 : std_logic_vector(7 downto 0);
signal SCAN13 : std_logic_vector(7 downto 0);
signal SCAN14 : std_logic_vector(7 downto 0);
signal SCANLL : std_logic_vector(7 downto 0);
--
-- Key code exchange table
--
signal MTEN : std_logic_vector(3 downto 0);
signal F_KBDT : std_logic_vector(7 downto 0);
signal MAP_DATA : std_logic_vector(7 downto 0);
signal KEY_EXTENDED : std_logic;
signal KEY_FLAG : std_logic;
signal KEY_PRESS : std_logic;
signal KEY_VALID : std_logic;
begin
--
-- Instantiation
--
-- 0 = MZ80K KEYMAP = 256Bytes -> 0000:00ff 0000 bytes padding
-- 1 = MZ80C KEYMAP = 256Bytes -> 0100:01ff 0000 bytes padding
-- 2 = MZ1200 KEYMAP = 256Bytes -> 0200:02ff 0000 bytes padding
-- 3 = MZ80A KEYMAP = 256Bytes -> 0300:03ff 0000 bytes padding
-- 4 = MZ700 KEYMAP = 256Bytes -> 0400:04ff 0000 bytes padding
-- 5 = MZ80B KEYMAP = 256Bytes -> 0500:05ff 0000 bytes padding
-- KEY_BANK <= "000" when CONFIG(MZ80K) = '1' else -- Key map for MZ80K
-- "001" when CONFIG(MZ80C) = '1' else -- Key map for MZ80C
-- "010" when CONFIG(MZ1200) = '1' else -- Key map for MZ1200
-- "011" when CONFIG(MZ80A) = '1' else -- Key map for MZ80A
-- "100" when CONFIG(MZ700) = '1' else -- Key map for MZ700
-- "101" when CONFIG(MZ800) = '1' else -- Key map for MZ800
-- "110" when CONFIG(MZ80B) = '1' else -- Key map for MZ80B
-- "111" when CONFIG(MZ2000) = '1'; -- Key map for MZ2000
--KEY_BANK <= "000";
MAP0 : entity work.sprom
GENERIC MAP (
--init_file => "./mif/key_80k_80b.mif",
init_file => "./roms/combined_keymap.mif",
widthad_a => 11,
width_a => 8
)
PORT MAP (
clock => CKCPU,
address => KEY_BANK & F_KBDT,
q => MAP_DATA
);
-- Store changes to the key valid flag in a flip flop.
process( CKCPU ) begin
if rising_edge(CKCPU) then
KEY_FLAG <= PS2_KEY(10);
end if;
end process;
KEY_PRESS <= PS2_KEY(9);
KEY_EXTENDED <= PS2_KEY(8);
KEY_VALID <= '1' when KEY_FLAG /= PS2_KEY(10) else '0';
--
-- Convert
--
process( RST_n, CKCPU) begin
if RST_n = '0' then
SCAN00 <= (others=>'0');
SCAN01 <= (others=>'0');
SCAN02 <= (others=>'0');
SCAN03 <= (others=>'0');
SCAN04 <= (others=>'0');
SCAN05 <= (others=>'0');
SCAN06 <= (others=>'0');
SCAN07 <= (others=>'0');
SCAN08 <= (others=>'0');
SCAN09 <= (others=>'0');
SCAN10 <= (others=>'0');
SCAN11 <= (others=>'0');
SCAN12 <= (others=>'0');
SCAN13 <= (others=>'0');
SCAN14 <= (others=>'0');
FLGF0 <= '0';
FLGE0 <= '0';
MTEN <= (others=>'0');
elsif CKCPU'event and CKCPU='1' then
MTEN <= MTEN(2 downto 0) & KEY_VALID;
if KEY_VALID='1' then
if(KEY_EXTENDED='1') then
FLGE0 <= '1';
end if;
if(KEY_PRESS='0') then
FLGF0 <= '1';
end if;
if(PS2_KEY(7 downto 0) = X"AA" ) then
F_KBDT <= X"EF";
else
F_KBDT <= FLGE0 & PS2_KEY(6 downto 0); FLGE0<='0';
end if;
end if;
if MTEN(3)='1' then
case MAP_DATA(7 downto 4) is
when "0000" => SCAN00(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0001" => SCAN01(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0010" => SCAN02(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0011" => SCAN03(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0100" => SCAN04(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0101" => SCAN05(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0110" => SCAN06(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "0111" => SCAN07(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1000" => SCAN08(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1001" => SCAN09(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1010" => SCAN10(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1011" => SCAN11(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1100" => SCAN12(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1101" => SCAN13(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
when "1110" => SCAN14(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0;
when others => SCAN14(conv_integer(MAP_DATA(2 downto 0))) <= not FLGF0; FLGF0 <= '0';
end case;
end if;
end if;
end process;
PA_L : for I in 0 to 7 generate
SCANLL(I) <= SCAN00(I) or SCAN01(I) or SCAN02(I) or SCAN03(I) or SCAN04(I) or
SCAN05(I) or SCAN06(I) or SCAN07(I) or SCAN08(I) or SCAN09(I) or
SCAN10(I) or SCAN11(I) or SCAN12(I) or SCAN13(I) or SCAN14(I);
end generate PA_L;
--
-- response from key access
--
PB <= (not SCANLL) when STALL='0' and KEY_BANK="110" else
(not SCAN00) when PA="0000" else
(not SCAN01) when PA="0001" else
(not SCAN02) when PA="0010" else
(not SCAN03) when PA="0011" else
(not SCAN04) when PA="0100" else
(not SCAN05) when PA="0101" else
(not SCAN06) when PA="0110" else
(not SCAN07) when PA="0111" else
(not SCAN08) when PA="1000" else
(not SCAN09) when PA="1001" else
(not SCAN10) when PA="1010" else
(not SCAN11) when PA="1011" else
(not SCAN12) when PA="1100" else
(not SCAN13) when PA="1101" else (others=>'1');
end Behavioral;

View File

@ -5,6 +5,7 @@
// http://code.google.com/p/mist-board/
//
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
// Copyright (c) 2015-2017 Sorgelig
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
@ -61,13 +62,13 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
// SD config
input sd_conf,
input sd_sdhc,
output img_mounted, // signaling that new image has been mounted
output [1:0] img_mounted, // signaling that new image has been mounted
output reg [31:0] img_size, // size of image in bytes
// SD block level access
input [31:0] sd_lba,
input sd_rd,
input sd_wr,
input [1:0] sd_rd,
input [1:0] sd_wr,
output reg sd_ack,
output reg sd_ack_conf,
@ -83,25 +84,27 @@ module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
output ps2_mouse_clk,
output reg ps2_mouse_data,
// ps2 alternative interface.
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
output reg [10:0] ps2_key = 0,
// [24] - toggles with every event
output reg [24:0] ps2_mouse = 0,
// ARM -> FPGA download
input ioctl_force_erase,
input ioctl_ce,
output reg ioctl_download = 0, // signal indicating an active download
output reg ioctl_erasing = 0, // signal indicating an active erase
output reg [7:0] ioctl_index, // menu index used to upload the file
output reg ioctl_wr = 0,
output reg [24:0] ioctl_addr,
output reg [7:0] ioctl_dout
);
reg [7:0] b_data;
reg [6:0] sbuf;
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [7:0] byte_cnt; // counts bytes
reg [7:0] but_sw;
reg [2:0] stick_idx;
reg mount_strobe = 0;
reg [1:0] mount_strobe = 0;
assign img_mounted = mount_strobe;
assign buttons = but_sw[1:0];
@ -109,160 +112,189 @@ assign switches = but_sw[3:2];
assign scandoubler_disable = but_sw[4];
assign ypbpr = but_sw[5];
wire [7:0] spi_dout = { sbuf, SPI_DI};
// this variant of user_io is for 8 bit cores (type == a4) only
wire [7:0] core_type = 8'ha4;
// command byte read by the io controller
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
wire drive_sel = sd_rd[1] | sd_wr[1];
wire [7:0] sd_cmd = { 4'h6, sd_conf, sd_sdhc, sd_wr[drive_sel], sd_rd[drive_sel] };
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [9:0] byte_cnt; // counts bytes
reg spi_do;
assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do;
// drive MISO only when transmitting core id
always@(negedge SPI_SCK) begin
if(!CONF_DATA0) begin
// first byte returned is always core type, further bytes are
// command dependent
if(byte_cnt == 0) begin
spi_do <= core_type[~bit_cnt];
reg [7:0] spi_data_out;
end else begin
case(cmd)
// reading config string
8'h14: begin
// returning a byte from string
if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
else spi_do <= 0;
end
// SPI transmitter
always@(negedge SPI_SCK) spi_do <= spi_data_out[~bit_cnt];
// reading sd card status
8'h16: begin
if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt];
else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}];
else spi_do <= 0;
end
// reading sd card write data
8'h18:
spi_do <= b_data[~bit_cnt];
default:
spi_do <= 0;
endcase
end
end
end
reg b_wr2,b_wr3;
always @(negedge clk_sys) begin
b_wr3 <= b_wr2;
sd_buff_wr <= b_wr3;
end
reg [7:0] spi_data_in;
reg spi_data_ready = 0;
// SPI receiver
always@(posedge SPI_SCK or posedge CONF_DATA0) begin
reg [6:0] sbuf;
reg [31:0] sd_lba_r;
reg drive_sel_r;
if(CONF_DATA0) begin
b_wr2 <= 0;
bit_cnt <= 0;
byte_cnt <= 0;
sd_ack <= 0;
sd_ack_conf <= 0;
end else begin
b_wr2 <= 0;
sbuf <= spi_dout[6:0];
spi_data_out <= core_type;
end
else
begin
bit_cnt <= bit_cnt + 1'd1;
if(bit_cnt == 5) begin
if (byte_cnt == 0) sd_buff_addr <= 0;
if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1;
if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0;
end
sbuf <= {sbuf[5:0], SPI_DI};
// finished reading command byte
if(bit_cnt == 7) begin
if(!byte_cnt) cmd <= {sbuf, SPI_DI};
spi_data_in <= {sbuf, SPI_DI};
spi_data_ready <= ~spi_data_ready;
if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1;
if(byte_cnt == 0) begin
cmd <= spi_dout;
if(spi_dout == 8'h19) begin
sd_ack_conf <= 1;
sd_buff_addr <= 0;
end
if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin
sd_ack <= 1;
sd_buff_addr <= 0;
end
if(spi_dout == 8'h18) b_data <= sd_buff_din;
mount_strobe <= 0;
end else begin
case(cmd)
// buttons and switches
8'h01: but_sw <= spi_dout;
8'h02: joystick_0 <= spi_dout;
8'h03: joystick_1 <= spi_dout;
spi_data_out <= 0;
case({(!byte_cnt) ? {sbuf, SPI_DI} : cmd})
// reading config string
8'h14: if(byte_cnt < STRLEN) spi_data_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8];
// store incoming ps2 mouse bytes
8'h04: begin
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout;
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
end
// reading sd card status
8'h16: if(byte_cnt == 0) begin
spi_data_out <= sd_cmd;
sd_lba_r <= sd_lba;
drive_sel_r <= drive_sel;
end else if (byte_cnt == 1) begin
spi_data_out <= drive_sel_r;
end else if(byte_cnt < 6) spi_data_out <= sd_lba_r[(5-byte_cnt)<<3 +:8];
// store incoming ps2 keyboard bytes
8'h05: begin
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout;
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
end
8'h15: status[7:0] <= spi_dout;
// send SD config IO -> FPGA
// flag that download begins
// sd card knows data is config if sd_dout_strobe is asserted
// with sd_ack still being inactive (low)
8'h19,
// send sector IO -> FPGA
// flag that download begins
8'h17: begin
sd_buff_dout <= spi_dout;
b_wr2 <= 1;
end
// reading sd card write data
8'h18: spi_data_out <= sd_buff_din;
endcase
end
end
end
8'h18: b_data <= sd_buff_din;
reg [31:0] ps2_key_raw = 0;
wire pressed = (ps2_key_raw[15:8] != 8'hf0);
wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0));
// joystick analog
8'h1a: begin
// first byte is joystick index
if(byte_cnt == 1) stick_idx <= spi_dout[2:0];
else if(byte_cnt == 2) begin
// second byte is x axis
if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout;
else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout;
end else if(byte_cnt == 3) begin
// third byte is y axis
if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout;
else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout;
end
end
// transfer to clk_sys domain
always@(posedge clk_sys) begin
reg old_ss1, old_ss2;
reg old_ready1, old_ready2;
reg [2:0] b_wr;
reg got_ps2 = 0;
// notify image selection
8'h1c: mount_strobe <= 1;
old_ss1 <= CONF_DATA0;
old_ss2 <= old_ss1;
old_ready1 <= spi_data_ready;
old_ready2 <= old_ready1;
sd_buff_wr <= b_wr[0];
if(b_wr[2] && (~&sd_buff_addr)) sd_buff_addr <= sd_buff_addr + 1'b1;
b_wr <= (b_wr<<1);
// send image info
8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout;
// status, 32bit version
8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout;
default: ;
endcase
if(old_ss2) begin
got_ps2 <= 0;
sd_ack <= 0;
sd_ack_conf <= 0;
sd_buff_addr <= 0;
if(got_ps2) begin
if(cmd == 4) ps2_mouse[24] <= ~ps2_mouse[24];
if(cmd == 5) begin
ps2_key <= {~ps2_key[10], pressed, extended, ps2_key_raw[7:0]};
if(ps2_key_raw == 'hE012E07C) ps2_key[9:0] <= 'h37C; // prnscr pressed
if(ps2_key_raw == 'h7CE0F012) ps2_key[9:0] <= 'h17C; // prnscr released
if(ps2_key_raw == 'hF014F077) ps2_key[9:0] <= 'h377; // pause pressed
end
end
end
else
if(old_ready2 ^ old_ready1) begin
if(cmd == 8'h18 && ~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
if(byte_cnt < 2) begin
if (cmd == 8'h19) sd_ack_conf <= 1;
if((cmd == 8'h17) || (cmd == 8'h18)) sd_ack <= 1;
mount_strobe <= 0;
if(cmd == 5) ps2_key_raw <= 0;
end else begin
case(cmd)
// buttons and switches
8'h01: but_sw <= spi_data_in;
8'h02: joystick_0 <= spi_data_in;
8'h03: joystick_1 <= spi_data_in;
// store incoming ps2 mouse bytes
8'h04: begin
got_ps2 <= 1;
case(byte_cnt)
2: ps2_mouse[7:0] <= spi_data_in;
3: ps2_mouse[15:8] <= spi_data_in;
4: ps2_mouse[23:16] <= spi_data_in;
endcase
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_data_in;
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
end
// store incoming ps2 keyboard bytes
8'h05: begin
got_ps2 <= 1;
ps2_key_raw[31:0] <= {ps2_key_raw[23:0], spi_data_in};
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_data_in;
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
end
8'h15: status[7:0] <= spi_data_in;
// send SD config IO -> FPGA
// flag that download begins
// sd card knows data is config if sd_dout_strobe is asserted
// with sd_ack still being inactive (low)
8'h19,
// send sector IO -> FPGA
// flag that download begins
8'h17: begin
sd_buff_dout <= spi_data_in;
b_wr <= 1;
end
// joystick analog
8'h1a: begin
// first byte is joystick index
if(byte_cnt == 2) stick_idx <= spi_data_in[2:0];
else if(byte_cnt == 3) begin
// second byte is x axis
if(stick_idx == 0) joystick_analog_0[15:8] <= spi_data_in;
else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_data_in;
end else if(byte_cnt == 4) begin
// third byte is y axis
if(stick_idx == 0) joystick_analog_0[7:0] <= spi_data_in;
else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_data_in;
end
end
// notify image selection
8'h1c: mount_strobe[spi_data_in[0]] <= 1;
// send image info
8'h1d: if(byte_cnt<6) img_size[(byte_cnt-2)<<3 +:8] <= spi_data_in;
// status, 32bit version
8'h1e: if(byte_cnt<6) status[(byte_cnt-2)<<3 +:8] <= spi_data_in;
default: ;
endcase
end
end
end
@ -417,6 +449,8 @@ localparam UIO_FILE_TX = 8'h53;
localparam UIO_FILE_TX_DAT = 8'h54;
localparam UIO_FILE_INDEX = 8'h55;
reg rdownload = 0;
// data_io has its own SPI interface to the io controller
always@(posedge SPI_SCK, posedge SPI_SS2) begin
reg [6:0] sbuf;
@ -426,15 +460,10 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin
if(SPI_SS2) cnt <= 0;
else begin
rclk <= 0;
// don't shift in last bit. It is evaluated directly
// when writing to ram
if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI};
// increase target address after write
if(rclk) addr <= addr + 1'd1;
// count 0-7 8-15 8-15 ...
if(cnt < 15) cnt <= cnt + 1'd1;
else cnt <= 8;
@ -446,18 +475,11 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin
if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
// prepare
if(SPI_DI) begin
case(ioctl_index)
0: addr <= 'h080000; // BOOT ROM
'h01: addr <= 'h000100; // ROM file
'h41: addr <= 'h000100; // COM file
'h81: addr <= 'h000000; // C00 file
'hC1: addr <= 'h010000; // EDD file
default: addr <= 'h100000; // FDD file
endcase
ioctl_download <= 1;
addr <= 25'h080000;
rdownload <= 1;
end else begin
addr_w <= addr;
ioctl_download <= 0;
rdownload <= 0;
end
end
@ -465,7 +487,8 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin
if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin
addr_w <= addr;
data_w <= {sbuf, SPI_DI};
rclk <= 1;
addr <= addr + 1'd1;
rclk <= ~rclk;
end
// expose file (menu) index
@ -473,60 +496,24 @@ always@(posedge SPI_SCK, posedge SPI_SS2) begin
end
end
reg [24:0] erase_mask;
wire [24:0] next_erase = (ioctl_addr + 1'd1) & erase_mask;
// transfer to ioctl_clk domain.
// ioctl_index is set before ioctl_download, so it's stable already
always@(posedge clk_sys) begin
reg rclkD, rclkD2;
reg old_force = 0;
reg [5:0] erase_clk_div;
reg [24:0] end_addr;
reg erase_trigger = 0;
rclkD <= rclk;
rclkD2 <= rclkD;
ioctl_wr <= 0;
if(ioctl_ce) begin
ioctl_download <= rdownload;
if(rclkD & ~rclkD2) begin
ioctl_dout <= data_w;
ioctl_addr <= addr_w;
ioctl_wr <= 1;
end
rclkD <= rclk;
rclkD2 <= rclkD;
ioctl_wr <= 0;
if(ioctl_download) begin
old_force <= 0;
ioctl_erasing <= 0;
erase_trigger <= (ioctl_index == 1);
end else begin
old_force <= ioctl_force_erase;
// start erasing
if(erase_trigger) begin
erase_trigger <= 0;
erase_mask <= 'hFFFF;
end_addr <= 'h0100;
erase_clk_div <= 1;
ioctl_erasing <= 1;
end else if((ioctl_force_erase & ~old_force)) begin
erase_trigger <= 0;
ioctl_addr <= 'h1FFFFFF;
erase_mask <= 'h1FFFFFF;
end_addr <= 'h0050000;
erase_clk_div <= 1;
ioctl_erasing <= 1;
end else if(ioctl_erasing) begin
erase_clk_div <= erase_clk_div + 1'd1;
if(!erase_clk_div) begin
if(next_erase == end_addr) ioctl_erasing <= 0;
else begin
ioctl_addr <= next_erase;
ioctl_dout <= 0;
ioctl_wr <= 1;
end
end
if(rclkD != rclkD2) begin
ioctl_dout <= data_w;
ioctl_addr <= addr_w;
ioctl_wr <= 1;
end
end
end
endmodule
endmodule

View File

@ -44,7 +44,7 @@ wire clk_12p5;
wire locked;
wire scandoubler_disable;
wire ypbpr;
wire ps2_kbd_clk, ps2_kbd_data;
wire [10:0] PS2_KEY;
wire [31:0] status;
wire [1:0] buttons;
wire [1:0] switches;
@ -84,8 +84,7 @@ mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io
.scandoubler_disable(scandoubler_disable),
.ypbpr(ypbpr),
.status(status),
.ps2_kbd_clk(ps2_kbd_clk),
.ps2_kbd_data(ps2_kbd_data)
.ps2_key(PS2_KEY)
);
video_mixer #(.LINE_LENGTH(480), .HALF_DEPTH(1)) video_mixer
@ -128,8 +127,7 @@ assign AUDIO_R = AUDIO_L;
mz80k_top mz80k_top(
.CLK_50MHZ(clk_sys),
.RESET(reset),
.PS2_CLK(ps2_kbd_clk),
.PS2_DATA(ps2_kbd_data),
.PS2_KEY(PS2_KEY),
.VGA_RED(r),
.VGA_GREEN(g),
.VGA_BLUE(b),
@ -138,13 +136,5 @@ mz80k_top mz80k_top(
.TURBO(status[2]),
.TP1(audio)
);
keyboard keyboard(
.clk(clk_sys),
.reset(0),
.ps2_kbd_clk(ps2_kbd_clk),
.ps2_kbd_data(ps2_kbd_data),
.joystick(kb_ext)
);
endmodule

View File

@ -2,8 +2,7 @@
module mz80k_top(
input CLK_50MHZ,
input RESET,
input PS2_CLK,
input PS2_DATA,
input [10:0] PS2_KEY,
output VGA_RED,
output VGA_GREEN,
output VGA_BLUE,
@ -42,22 +41,27 @@ module mz80k_top(
wire start, waitreq;
// I/O
wire io_e000 = (cpu_addr[15:0] == 16'he000) & mreq;
wire io_e001 = (cpu_addr[15:0] == 16'he001) & mreq;
/* CS_E0_n <= '0' when CS_E_n='0' and T80_A16(11 downto 2)="0000000000" -- 8255
else '1';
CS_E1_n <= '0' when CS_E_n='0' and T80_A16(11 downto 2)="0000000001" -- 8253
else '1';
CS_E2_n <= '0' when CS_E_n='0' and T80_A16(11 downto 2)="0000000010" -- LS367
else '1';
CS_ESWP_n <= '0' when CONFIG(MZ_A)='1' and CS_E_n='0' and T80_RD_n='0' and T80_A16(11 downto 5)="0000000" -- ROM/RAM Swap
else '1';*/
//wire io_e000 = (cpu_addr[15:0] == 16'he000) & mreq;
//wire io_e001 = (cpu_addr[15:0] == 16'he001) & mreq;
wire io_e002 = (cpu_addr[15:0] == 16'he002) & mreq;
wire io_8253 = (cpu_addr[15:2] == 14'b11100000000001) & mreq;
wire io_8255 = (cpu_addr[15:2] == 14'b11100000000000) & mreq;
wire io_e008 = (cpu_addr[15:0] == 16'he008) & mreq;
reg [3:0] key_no;
reg speaker_enable;
always @(posedge CLK_CPU or posedge RESET) begin
if (RESET) begin
key_no <= 0;
speaker_enable <= 0;
end else begin
if (io_e000 & wr ) begin
key_no <= cpu_data_out[3:0];
end else if (io_e008 & wr ) begin
if (io_e008 & wr ) begin
speaker_enable <= cpu_data_out[0];
end
end
@ -103,18 +107,44 @@ module mz80k_top(
.out2(out2)
);
// KEYBOARD
wire [7:0] ps2_dat;
ps2 ps2_1(
.clk(CLK_50MHZ),
.reset(RESET),
.ps2_clk(PS2_CLK),
.ps2_data(PS2_DATA),
.cs(io_e001 & rd),
.rd(rd),
.addr(key_no),
.data(ps2_dat)
);
wire [7:0] i8255_data_out;
wire [7:0] i8255_PA_I;
wire [7:0] i8255_PA_O;
wire [7:0] i8255_PB_I;
wire [7:0] i8255_PB_O;
wire [7:0] i8255_PC_I;
wire [7:0] i8255_PC_O;
i8255 i8255_1(
.RESET(RESET),
.CLK(CLK_CPU),
.ENA(1'b1),
.ADDR(cpu_addr[1:0]),
.DI(cpu_data_out),
.DO(i8255_data_out),
.CS_n(~io_8255),
.RD_n(~rd),
.WR_n(~wr),
.PA_I(i8255_PA_I),
.PA_O(i8255_PA_O),
.PA_O_OE_n(),
.PB_I(i8255_PB_I),
.PB_O(i8255_PB_O),
.PB_O_OE_n(),
.PC_I(i8255_PC_I),
.PC_O(i8255_PC_O),
.PC_O_OE_n()
);
keymatrix keymatrix(
.RST_n(~RESET),
.PA(i8255_PA_O[3:0]),
.PB(i8255_PB_I),
.STALL(i8255_PA_O[4]),
.PS2_KEY(PS2_KEY),
.KEY_BANK(3'b000),
.CKCPU(CLK_CPU)
);
// VGA
wire [11:0] vga_addr;
@ -172,9 +202,9 @@ module mz80k_top(
assign vram_wr = busack ? 1'b0 : wr;
// Memory
assign cpu_data_in =
( io_e001 & rd ) ? ps2_dat :
( io_e002 & rd ) ? {VGA_VSYNC, clk_count[24], 6'b0000000} :
( io_8253 & rd ) ? i8253_data_out :
( io_8255 & rd ) ? i8255_data_out :
( io_e008 & rd ) ? {7'b0000000, clk_count[19]} : // MUSIC<EFBFBD><EFBFBD><EFBFBD>Ȃǂ<EFBFBD>WAIT<EFBFBD>ŏd<EFBFBD>v
(vram_select & rd) ? vram_data :
(ram_select & rd) ? ram_data_out: 8'hzz;

View File

@ -1,283 +0,0 @@
module ps2(clk, reset,
ps2_clk, ps2_data,
cs, rd, addr, data);
input clk,reset;
input ps2_clk, ps2_data;
input cs, rd;
input [7:0] addr;
output [7:0] data;
wire clk, reset;
wire ps2_clk, ps2_data;
wire cs, rd;
wire [7:0] addr;
reg [7:0] data;
reg [7:0]key_tbl0 = 8'b11111111,
key_tbl1 = 8'b11111111,
key_tbl2 = 8'b11111111,
key_tbl3 = 8'b11111111,
key_tbl4 = 8'b11111111,
key_tbl5 = 8'b11111111,
key_tbl6 = 8'b11111111,
key_tbl7 = 8'b11111111,
key_tbl8 = 8'b11111111,
key_tbl9 = 8'b11111111,
key_tbla = 8'b11111111,
key_tblb = 8'b11111111,
key_tblc = 8'b11111111,
key_tbld = 8'b11111111,
key_tble = 8'b11111111;
reg key_f0 = 1'b0;
reg key_e0 = 1'b0;
//
// I/O(0-9) read
//
always @(posedge clk ) begin
if ( cs & rd ) begin
begin
case (addr[3:0])
4'h0: data <= key_tbl0;
4'h1: data <= key_tbl1;
4'h2: data <= key_tbl2;
4'h3: data <= key_tbl3;
4'h4: data <= key_tbl4;
4'h5: data <= key_tbl5;
4'h6: data <= key_tbl6;
4'h7: data <= key_tbl7;
4'h8: data <= key_tbl8;
4'h9: data <= key_tbl9;
4'ha: data <= key_tbla;
4'hb: data <= key_tblb;
4'hc: data <= key_tblc;
4'hd: data <= key_tbld;
4'he: data <= key_tble;
default: data <= 8'hzz;
endcase
end
end
end
//
// PS/2ü͏ˆŽÀ
//
wire dten;
wire [7:0] kdata;
ps2_recieve ps2_recieve1(.clk(clk), .reset(reset),
.ps2_clk(ps2_clk), .ps2_data(ps2_data),
.dten(dten), .kdata(kdata));
//
//
//
always @(posedge clk or posedge reset) begin
if( reset ) begin
key_e0 <= 1'b0;
key_f0 <= 1'b0;
key_tbl0 <= 8'b11111111;
key_tbl1 <= 8'b11111111;
key_tbl2 <= 8'b11111111;
key_tbl3 <= 8'b11111111;
key_tbl4 <= 8'b11111111;
key_tbl5 <= 8'b11111111;
key_tbl6 <= 8'b11111111;
key_tbl7 <= 8'b11111111;
key_tbl8 <= 8'b11111111;
key_tbl9 <= 8'b11111111;
end else if ( dten ) begin
case ( kdata )
8'h70: begin
if ( key_e0 ) begin
key_tbl8[1] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // INS (E0)
end else begin
key_tbl1[4] <= key_f0; key_f0 <= 1'b0; // 0
end
end
8'h69: begin
if ( key_e0 ) begin
key_f0 <= 1'b0; key_e0 <= 1'b0; // END (E0)
end else begin
key_tbl0[0] <= key_f0; key_f0 <= 1'b0; // 1
end
end
8'h72: begin
if ( key_e0 ) begin
key_tbl9[2] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // DOWN (E0)
end else begin
key_tbl1[0] <= key_f0; key_f0 <= 1'b0; // 2
end
end
8'h7A: begin
if ( key_e0 ) begin
key_tble[0] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // PGDN (E0)
end else begin
key_tbl0[1] <= key_f0; key_f0 <= 1'b0; // 3
end
end
8'h6B: begin
if ( key_e0 ) begin
key_tbl8[3] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // LEFT (E0)
end else begin
key_tbl1[1] <= key_f0; key_f0 <= 1'b0; // 4
end
end
8'h73: begin key_tbl0[2] <= key_f0; key_f0 <= 1'b0; end // 5
8'h74: begin
if ( key_e0 ) begin
key_tbl8[3] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // RIGHT (E0)
end else begin
key_tbl1[2] <= key_f0; key_f0 <= 1'b0; // 6
end
end
8'h6C: begin
if ( key_e0 ) begin
key_tbl8[0] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // HOME (E0)
end else begin
key_tbl0[3] <= key_f0; key_f0 <= 1'b0; // 7
end
end
8'h75: begin
if ( key_e0 ) begin
key_tbl9[2] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // UP (E0)
end else begin
key_tbl1[3] <= key_f0; key_f0 <= 1'b0; // 8
end
end
8'h7D: begin
if ( key_e0 ) begin
key_tble[0] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // PGUP (E0)
end else begin
key_tbl0[4] <= key_f0; key_f0 <= 1'b0; // 9
end
end
8'h7C: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // *
8'h79: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // +
8'h7B: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // =
8'h7C: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // ,
8'h71: begin
if ( key_e0 ) begin
key_tbl8[1] <= key_f0; key_tblc[7] <= key_f0; key_f0 <= 1'b0; key_e0 <= 1'b0; // DEL (E0)
end else begin
key_tble[0] <= key_f0; key_f0 <= 1'b0; // .
end
end
8'h71: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // .
8'h5A: begin key_tbl8[4] <= key_f0; key_f0 <= 1'b0; end // RET E0
8'h54: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // @
8'h1C: begin key_tbl4[0] <= key_f0; key_f0 <= 1'b0; end // A
8'h32: begin key_tbl6[2] <= key_f0; key_f0 <= 1'b0; end // B
8'h21: begin key_tbl6[1] <= key_f0; key_f0 <= 1'b0; end // C
8'h23: begin key_tbl4[1] <= key_f0; key_f0 <= 1'b0; end // D
8'h24: begin key_tbl2[1] <= key_f0; key_f0 <= 1'b0; end // E
8'h2B: begin key_tbl5[1] <= key_f0; key_f0 <= 1'b0; end // F
8'h34: begin key_tbl4[2] <= key_f0; key_f0 <= 1'b0; end // G
8'h33: begin key_tbl5[2] <= key_f0; key_f0 <= 1'b0; end // H
8'h43: begin key_tbl3[3] <= key_f0; key_f0 <= 1'b0; end // I
8'h3B: begin key_tbl4[3] <= key_f0; key_f0 <= 1'b0; end // J
8'h42: begin key_tbl5[3] <= key_f0; key_f0 <= 1'b0; end // K
8'h4B: begin key_tbl4[4] <= key_f0; key_f0 <= 1'b0; end // L
8'h3A: begin key_tbl6[3] <= key_f0; key_f0 <= 1'b0; end // M
8'h31: begin key_tbl7[2] <= key_f0; key_f0 <= 1'b0; end // N
8'h44: begin key_tbl2[4] <= key_f0; key_f0 <= 1'b0; end // O
8'h4D: begin key_tbl3[4] <= key_f0; key_f0 <= 1'b0; end // P
8'h15: begin key_tbl2[0] <= key_f0; key_f0 <= 1'b0; end // Q
8'h2D: begin key_tbl3[1] <= key_f0; key_f0 <= 1'b0; end // R
8'h1B: begin key_tbl5[0] <= key_f0; key_f0 <= 1'b0; end // S
8'h2C: begin key_tbl2[2] <= key_f0; key_f0 <= 1'b0; end // T
8'h3C: begin key_tbl2[3] <= key_f0; key_f0 <= 1'b0; end // U
8'h2A: begin key_tbl7[1] <= key_f0; key_f0 <= 1'b0; end // V
8'h1D: begin key_tbl3[0] <= key_f0; key_f0 <= 1'b0; end // W
8'h22: begin key_tbl7[0] <= key_f0; key_f0 <= 1'b0; end // X
8'h35: begin key_tbl3[2] <= key_f0; key_f0 <= 1'b0; end // Y
8'h1A: begin key_tbl6[0] <= key_f0; key_f0 <= 1'b0; end // Z
8'h5B: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // [
8'h6A: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // \
8'h5D: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // ]
8'h55: begin key_tbl5[5] <= key_f0; key_f0 <= 1'b0; end // ^
8'h4E: begin key_tbl2[5] <= key_f0; key_f0 <= 1'b0; end // =
8'h45: begin key_tbl1[4] <= key_f0; key_f0 <= 1'b0; end // 0
8'h16: begin key_tbl0[0] <= key_f0; key_f0 <= 1'b0; end // 1
8'h1E: begin key_tbl1[0] <= key_f0; key_f0 <= 1'b0; end // 2
8'h26: begin key_tbl0[1] <= key_f0; key_f0 <= 1'b0; end // 3
8'h25: begin key_tbl1[1] <= key_f0; key_f0 <= 1'b0; end // 4
8'h2E: begin key_tbl0[2] <= key_f0; key_f0 <= 1'b0; end // 5
8'h36: begin key_tbl1[2] <= key_f0; key_f0 <= 1'b0; end // 6
8'h3D: begin key_tbl0[3] <= key_f0; key_f0 <= 1'b0; end // 7
8'h3E: begin key_tbl1[3] <= key_f0; key_f0 <= 1'b0; end // 8
8'h46: begin key_tbl0[4] <= key_f0; key_f0 <= 1'b0; end // 9
8'h52: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // :
8'h4C: begin key_tbl5[4] <= key_f0; key_f0 <= 1'b0; end // ;
8'h41: begin key_tbl7[3] <= key_f0; key_f0 <= 1'b0; end // < ,
8'h49: begin key_tbl6[4] <= key_f0; key_f0 <= 1'b0; end // > .
8'h4A: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // ?
8'h51: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // _
8'h11: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // GRPH
8'h13: begin key_tbl6[5] <= key_f0; key_f0 <= 1'b0; end // ƒJƒi
8'h12: begin key_tbl8[0] <= ( key_f0 | key_e0 ) & (key_tbl8[0] | ~key_e0 ); key_f0 <= 1'b0; key_e0 <= 1'b0; end // SHIFT
8'h59: begin key_tbl8[5] <= ( key_f0 | key_e0 ) & (key_tbl8[5] | ~key_e0 ); key_f0 <= 1'b0; key_e0 <= 1'b0; end // SHIFT
8'h14: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // CTRL
8'h77: begin key_tbl9[3] <= key_f0; key_f0 <= 1'b0; end // STOP (E1)
8'h7E: begin key_tbl9[3] <= key_f0; key_f0 <= 1'b0; end // STOP (SCROLL KEY)
8'h05: begin key_tble[0] <= key_f0; key_tblc[0] <= key_f0; key_f0 <= 1'b0; end // F1
8'h06: begin key_tble[0] <= key_f0; key_tblc[1] <= key_f0; key_f0 <= 1'b0; end // F2
8'h04: begin key_tble[0] <= key_f0; key_tblc[2] <= key_f0; key_f0 <= 1'b0; end // F3
8'h0C: begin key_tble[0] <= key_f0; key_tblc[3] <= key_f0; key_f0 <= 1'b0; end // F4
8'h03: begin key_tble[0] <= key_f0; key_tblc[4] <= key_f0; key_f0 <= 1'b0; end // F5
8'h29: begin key_tbl9[1] <= key_f0; key_tbld[7] <= key_f0; key_f0 <= 1'b0; end // SPACE
8'h76: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // ESC
8'h0d: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // TAB
8'h58: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // CAPS
8'h66: begin key_tbl8[1] <= key_f0; key_f0 <= 1'b0; end // BS
8'h0b: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // F6
8'h83: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // F7
8'h0a: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // F8
8'h01: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // F9
8'h09: begin key_tble[0] <= key_f0; key_f0 <= 1'b0; end // F10
8'he0: key_e0 <= 1'b1;
8'hf0: key_f0 <= 1'b1;
default: begin key_e0 <= 1'b0; key_f0 <= 1'b0; end
endcase
end
end
endmodule
module ps2_recieve(clk, reset,
ps2_clk, ps2_data,
dten, kdata);
input clk,reset;
input ps2_clk, ps2_data;
output dten;
output [7:0] kdata;
wire clk, reset;
wire ps2_clk, ps2_data;
reg dten;
reg [7:0] kdata;
reg [10:0] key_data;
reg [3:0] clk_data;
always @(posedge clk or posedge reset) begin
if( reset ) begin
key_data <= 11'b11111111111;
dten <= 1'b0;
end else begin
clk_data <= {clk_data[2:0], ps2_clk};
if ( clk_data == 4'b0011 )
key_data <= {ps2_data, key_data[10:1]};
if ( !key_data[0] & key_data[10] ) begin
dten <= 1'b1;
kdata <= key_data[8:1];
key_data <= 11'b11111111111;
end else
dten <= 1'b0;
end
end
endmodule

View File

@ -1,116 +0,0 @@
module ps2_recieve(
input clk,
input reset,
input ps2_clk,
input ps2_data,
output dten,
output [7:0] kdata);
reg [10:0] key_data;
reg [3:0] clk_data;
always @(posedge clk or posedge reset) begin
if( reset ) begin
key_data <= 11'b11111111111;
dten <= 1'b0;
end else begin
clk_data <= {clk_data[2:0], ps2_clk};
if ( clk_data == 4'b0011 )
key_data <= {ps2_data, key_data[10:1]};
if ( !key_data[0] & key_data[10] ) begin
dten <= 1'b1;
kdata <= key_data[8:1];
key_data <= 11'b11111111111;
end else
dten <= 1'b0;
end
end
endmodule
module keyboard (
input clock,
input ps2_data,
input ps2_clk,
output reg [7:0] led_g
);
parameter idle = 2'b01;
parameter receive = 2'b10;
parameter ready = 2'b11;
reg [1:0] state=idle;
reg [15:0] rxtimeout=16'b0000000000000000;
reg [10:0] rxregister=11'b11111111111;
reg [1:0] datasr=2'b11;
reg [1:0] clksr=2'b11;
reg [7:0] rxdata;
reg datafetched;
reg rxactive;
reg dataready;
always @(posedge clock )
begin
if(datafetched==1)
led_g <=rxdata;
end
always @(posedge clock )
begin
rxtimeout<=rxtimeout+1;
datasr <= {datasr[0],ps2_data};
clksr <= {clksr[0],ps2_clk};
if(clksr==2'b10)
rxregister<= {datasr[1],rxregister[10:1]};
case (state)
idle:
begin
rxregister <=11'b11111111111;
rxactive <=0;
dataready <=0;
rxtimeout <=16'b0000000000000000;
if(datasr[1]==0 && clksr[1]==1)
begin
state<=receive;
rxactive<=1;
end
end
receive:
begin
if(rxtimeout==50000)
state<=idle;
else if(rxregister[0]==0)
begin
dataready<=1;
rxdata<=rxregister[8:1];
state<=ready;
datafetched<=1;
end
end
ready:
begin
if(datafetched==1)
begin
state <=idle;
dataready <=0;
rxactive <=0;
end
end
endcase
end
endmodule

View File

@ -1,93 +0,0 @@
module ps2n(
input clk,
input reset,
input ps2_clk,
input ps2_data,
input cs,
input rd,
input [7:0] addr,
output [7:0] data);
reg [7:0]key_tbl0 = 8'b11111111,
key_tbl1 = 8'b11111111,
key_tbl2 = 8'b11111111,
key_tbl3 = 8'b11111111,
key_tbl4 = 8'b11111111,
key_tbl5 = 8'b11111111,
key_tbl6 = 8'b11111111,
key_tbl7 = 8'b11111111,
key_tbl8 = 8'b11111111,
key_tbl9 = 8'b11111111,
key_tbla = 8'b11111111,
key_tblb = 8'b11111111,
key_tblc = 8'b11111111,
key_tbld = 8'b11111111,
key_tble = 8'b11111111;
always @(posedge clk ) begin
if ( cs & rd ) begin
begin
case (addr[3:0])
4'h0: data <= key_tbl0;
4'h1: data <= key_tbl1;
4'h2: data <= key_tbl2;
4'h3: data <= key_tbl3;
4'h4: data <= key_tbl4;
4'h5: data <= key_tbl5;
4'h6: data <= key_tbl6;
4'h7: data <= key_tbl7;
4'h8: data <= key_tbl8;
4'h9: data <= key_tbl9;
4'ha: data <= key_tbla;
4'hb: data <= key_tblb;
4'hc: data <= key_tblc;
4'hd: data <= key_tbld;
4'he: data <= key_tble;
default: data <= 8'hzz;
endcase
end
end
end
always @(posedge clk ) begin
key_tbl0 <= 8'b11111111;
key_tbl1 <= 8'b11111111;
key_tbl2 <= 8'b11111111;
key_tbl3 <= 8'b11111111;
key_tbl4 <= 8'b11111111;
key_tbl5 <= 8'b11111111;
key_tbl6 <= 8'b11111111;
key_tbl7 <= 8'b11111111;
key_tbl8 <= 8'b11111111;
key_tbl9 <= 8'b11111111;
case ( kdata )
8'h1C: begin key_tbl4[0] = 1'b0; end//A
8'h32: begin key_tbl6[2] = 1'b0; end//B
default: begin end
endcase
end
wire dten;
wire [7:0] kdata;
ps2_recieve ps2_recieve1(
.clk(clk),
.reset(reset),
.ps2_clk(ps2_clk),
.ps2_data(ps2_data),
.dten(dten),
.kdata(kdata)
);
endmodule

View File

@ -0,0 +1,102 @@
DEPTH = 1536;
WIDTH = 8;
ADDRESS_RADIX = HEX;
DATA_RADIX = HEX;
CONTENT BEGIN
0000: ff ff ff ff ff ff ff 86 ff 37 ff ff ff 90 93 ff;
0010: ff ff 80 ff ff 20 00 ff ff ff 60 50 40 30 10 ff;
0020: ff 61 70 41 21 11 01 ff ff 91 71 51 22 31 02 ff;
0030: ff 72 62 52 42 32 12 ff ff ff 63 43 23 03 13 ff;
0040: ff 73 53 33 24 14 04 ff ff 64 74 44 54 34 05 ff;
0050: ff 95 45 ff 25 15 ff ff 81 85 84 55 ff 75 ff ff;
0060: ff ff ff ff ff ff 65 ff ff 66 35 46 26 ff ff ff;
0070: 96 87 76 56 47 36 ff 06 77 57 67 17 07 27 ff ff;
0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
00c0: ff ff ff ff ff ff ff ff ff ff 16 ff ff ff ff ff;
00d0: ff ff ff ff ff ff ff ff ff ff 97 ff ff ff ff ff;
00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ef;
00f0: ff 81 92 ff 83 ff ff ff ff ff ff ff ff ff ff ff;
0100: ff ff ff ff ff ff ff 86 ff 37 ff ff ff 90 93 ff;
0110: ff ff 80 ff ff 20 00 ff ff ff 60 50 40 30 10 ff;
0120: ff 61 70 41 21 11 01 ff ff 91 71 51 22 31 02 ff;
0130: ff 72 62 52 42 32 12 ff ff ff 63 43 23 03 13 ff;
0140: ff 73 53 33 24 14 04 ff ff 64 74 44 54 34 05 ff;
0150: ff 95 45 ff 25 15 ff ff 81 85 84 55 ff 75 ff ff;
0160: ff ff ff ff ff ff 65 ff ff 66 35 46 26 ff ff ff;
0170: 96 87 76 56 47 36 ff 06 77 57 67 17 07 27 ff ff;
0180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0190: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
01a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
01b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
01c0: ff ff ff ff ff ff ff ff ff ff 16 ff ff ff ff ff;
01d0: ff ff ff ff ff ff ff ff ff ff 97 ff ff ff ff ff;
01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ef;
01f0: ff 81 92 ff 83 ff ff ff ff ff ff ff ff ff ff ff;
0200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0210: ff ff 00 ff 27 14 16 ff ff ff 10 22 13 15 17 ff;
0220: ff 20 21 23 24 27 26 ff ff 40 31 32 34 25 36 ff;
0230: ff 41 30 42 33 35 37 ff ff ff 50 43 44 46 47 ff;
0240: ff 51 52 45 54 57 56 ff ff 60 70 53 63 55 67 ff;
0250: ff ff 62 ff 65 66 ff ff 11 07 73 72 64 76 ff ff;
0260: ff ff ff ff ff ff 61 ff ff 8a ff 84 77 ff ff ff;
0270: 12 ff 74 85 75 a7 ff ff ff 97 92 95 90 96 ff ff;
0280: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0290: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
02f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0300: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0310: ff ff 00 ff 27 14 16 ff ff ff 10 22 13 15 17 ff;
0320: ff 20 21 23 24 27 26 ff ff 40 31 32 34 25 36 ff;
0330: ff 41 30 42 33 35 37 ff ff ff 50 43 44 46 47 ff;
0340: ff 51 52 45 54 57 56 ff ff 60 70 53 63 55 67 ff;
0350: ff ff 62 ff 65 66 ff ff 11 07 73 72 64 76 ff ff;
0360: ff ff ff ff ff ff 61 ff ff 8a ff 84 77 ff ff ff;
0370: 12 ff 74 85 75 a7 ff ff ff 97 92 95 90 96 ff ff;
0380: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0390: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
03f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0400: ff ff ff 93 95 97 96 ff ff ff ff ff 94 ff ff ff;
0410: ff 06 80 ff a6 27 57 ff ff ff 16 25 47 21 56 ff;
0420: ff 45 20 44 43 45 55 ff ff 64 22 42 24 26 53 ff;
0430: ff 32 46 40 41 17 52 ff ff ff 33 36 23 51 50 ff;
0440: ff 61 35 37 31 63 62 ff ff 60 70 34 0a 30 75 ff;
0450: ff ff ff ff 14 65 ff ff 04 ff 00 13 ff 67 ff ff;
0460: ff ff ff ff ff ff ff ff ff ff ff 72 ff ff ff ff;
0470: 77 76 74 ff 73 75 87 ff ff ff ff ff ff ff ff ff;
0480: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0490: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
04f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
0500: ff 10 ff 04 02 00 01 ff ff 11 07 05 03 b0 b3 ff;
0510: ff 30 b2 ff ff 61 81 ff ff ff 72 63 41 67 82 ff;
0520: ff 43 70 44 45 84 83 ff ff 31 66 46 64 62 85 ff;
0530: ff 56 42 50 47 71 86 ff ff ff 55 52 65 87 90 ff;
0540: ff 77 53 51 57 80 91 ff ff 76 40 54 93 60 94 ff;
0550: ff 75 92 ff 95 73 ff ff b1 b2 32 96 ff a0 ff ff;
0560: ff ff ff ff ff ff 37 ff ff 21 74 24 27 ff ff ff;
0570: 20 15 22 25 26 12 ff ff ff 17 23 16 ff 13 ff ff;
0580: ff ff ff 06 ff ff ff ff ff ff ff ff ff ff ff ff;
0590: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
05a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
05b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff;
05c0: ff ff ff ff ff ff ff ff ff ff 14 ff ff ff ff ff;
05d0: ff ff ff ff ff ff ff ff ff ff 32 ff ff ff ff ff;
05e0: ff ff ff ff ff ff ff ff ff ff ff 35 ff ff ff ef;
05f0: a2 a3 34 ff 36 33 ff ff ff ff ff ff ff ff ff ff;
END;

View File

@ -0,0 +1,82 @@
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY sprom IS
GENERIC
(
init_file : string := "";
widthad_a : natural;
width_a : natural := 8;
outdata_reg_a : string := "UNREGISTERED"
);
PORT
(
address : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
);
END sprom;
ARCHITECTURE SYN OF sprom IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
clock_enable_input_a : STRING;
clock_enable_output_a : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
clock0 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
);
END COMPONENT;
BEGIN
q <= sub_wire0(width_a-1 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => init_file,
intended_device_family => "Cyclone III",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 2**widthad_a,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => outdata_reg_a,
widthad_a => widthad_a,
width_a => width_a,
width_byteena_a => 1
)
PORT MAP (
clock0 => clock,
address_a => address,
q_a => sub_wire0
);
END SYN;