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:
parent
1847ad375f
commit
174c546ae6
BIN
Sharp - MZ-80K_MiST/Release/mz80k_mist.rbf
Normal file
BIN
Sharp - MZ-80K_MiST/Release/mz80k_mist.rbf
Normal file
Binary file not shown.
@ -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)
|
||||
# ----------------------
|
||||
@ -1,2 +1,2 @@
|
||||
`define BUILD_DATE "180624"
|
||||
`define BUILD_TIME "132954"
|
||||
`define BUILD_DATE "180929"
|
||||
`define BUILD_TIME "130303"
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
226
Sharp - MZ-80K_MiST/rtl/keymatrix.vhd
Normal file
226
Sharp - MZ-80K_MiST/rtl/keymatrix.vhd
Normal 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;
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
102
Sharp - MZ-80K_MiST/rtl/roms/combined_keymap.mif
Normal file
102
Sharp - MZ-80K_MiST/rtl/roms/combined_keymap.mif
Normal 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;
|
||||
82
Sharp - MZ-80K_MiST/rtl/sprom.vhd
Normal file
82
Sharp - MZ-80K_MiST/rtl/sprom.vhd
Normal 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;
|
||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user