diff --git a/Sharp - MZ-80K_MiST/Release/mz80k_mist.rbf b/Sharp - MZ-80K_MiST/Release/mz80k_mist.rbf new file mode 100644 index 00000000..68fe4d8b Binary files /dev/null and b/Sharp - MZ-80K_MiST/Release/mz80k_mist.rbf differ diff --git a/Sharp - MZ-80K_MiST/mz80k_mist.qsf b/Sharp - MZ-80K_MiST/mz80k_mist.qsf index b27e8cbf..da78897d 100644 --- a/Sharp - MZ-80K_MiST/mz80k_mist.qsf +++ b/Sharp - MZ-80K_MiST/mz80k_mist.qsf @@ -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 \ No newline at end of file +# end ENTITY(mz80k_mist) +# ---------------------- \ No newline at end of file diff --git a/Sharp - MZ-80K_MiST/rtl/build_id.v b/Sharp - MZ-80K_MiST/rtl/build_id.v index c95f4726..7da6cc7b 100644 --- a/Sharp - MZ-80K_MiST/rtl/build_id.v +++ b/Sharp - MZ-80K_MiST/rtl/build_id.v @@ -1,2 +1,2 @@ -`define BUILD_DATE "180624" -`define BUILD_TIME "132954" +`define BUILD_DATE "180929" +`define BUILD_TIME "130303" diff --git a/Sharp - MZ-80K_MiST/rtl/greybox_tmp/cbx_args.txt b/Sharp - MZ-80K_MiST/rtl/greybox_tmp/cbx_args.txt deleted file mode 100644 index 63b7b958..00000000 --- a/Sharp - MZ-80K_MiST/rtl/greybox_tmp/cbx_args.txt +++ /dev/null @@ -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 diff --git a/Sharp - MZ-80K_MiST/rtl/i8255.v b/Sharp - MZ-80K_MiST/rtl/i8255.v deleted file mode 100644 index a78a64de..00000000 --- a/Sharp - MZ-80K_MiST/rtl/i8255.v +++ /dev/null @@ -1,284 +0,0 @@ -`timescale 1ns / 1ps -// ============================================================================ -// i8255.v -// - PIO -// -// (C) 2012 Robert Finch, Stratford -// robfinch@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 . -// -// ============================================================================ -// -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 \ No newline at end of file diff --git a/Sharp - MZ-80K_MiST/rtl/i8255.vhd b/Sharp - MZ-80K_MiST/rtl/i8255.vhd index c2f3f1ce..7af5db5b 100644 --- a/Sharp - MZ-80K_MiST/rtl/i8255.vhd +++ b/Sharp - MZ-80K_MiST/rtl/i8255.vhd @@ -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; diff --git a/Sharp - MZ-80K_MiST/rtl/keyboard.sv b/Sharp - MZ-80K_MiST/rtl/keyboard.sv deleted file mode 100644 index ced157db..00000000 --- a/Sharp - MZ-80K_MiST/rtl/keyboard.sv +++ /dev/null @@ -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 diff --git a/Sharp - MZ-80K_MiST/rtl/keymatrix.vhd b/Sharp - MZ-80K_MiST/rtl/keymatrix.vhd new file mode 100644 index 00000000..98437bd8 --- /dev/null +++ b/Sharp - MZ-80K_MiST/rtl/keymatrix.vhd @@ -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 +-- +-- 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 . +--------------------------------------------------------------------------------------------------------- + +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; diff --git a/Sharp - MZ-80K_MiST/rtl/mist_io.v b/Sharp - MZ-80K_MiST/rtl/mist_io.v index ab9ef8ad..dc336b2f 100644 --- a/Sharp - MZ-80K_MiST/rtl/mist_io.v +++ b/Sharp - MZ-80K_MiST/rtl/mist_io.v @@ -5,6 +5,7 @@ // http://code.google.com/p/mist-board/ // // Copyright (c) 2014 Till Harbaum +// 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 \ No newline at end of file +endmodule \ No newline at end of file diff --git a/Sharp - MZ-80K_MiST/rtl/mz80k_mist.sv b/Sharp - MZ-80K_MiST/rtl/mz80k_mist.sv index 271c2fa0..3fdf77ec 100644 --- a/Sharp - MZ-80K_MiST/rtl/mz80k_mist.sv +++ b/Sharp - MZ-80K_MiST/rtl/mz80k_mist.sv @@ -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 \ No newline at end of file diff --git a/Sharp - MZ-80K_MiST/rtl/mz80k_top.v b/Sharp - MZ-80K_MiST/rtl/mz80k_top.v index 17e885c2..88686f8b 100644 --- a/Sharp - MZ-80K_MiST/rtl/mz80k_top.v +++ b/Sharp - MZ-80K_MiST/rtl/mz80k_top.v @@ -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���Ȃǂ�WAIT�ŏd�v (vram_select & rd) ? vram_data : (ram_select & rd) ? ram_data_out: 8'hzz; diff --git a/Sharp - MZ-80K_MiST/rtl/ps2.v b/Sharp - MZ-80K_MiST/rtl/ps2.v deleted file mode 100644 index 44d96d57..00000000 --- a/Sharp - MZ-80K_MiST/rtl/ps2.v +++ /dev/null @@ -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 diff --git a/Sharp - MZ-80K_MiST/rtl/ps2_recieve.v b/Sharp - MZ-80K_MiST/rtl/ps2_recieve.v deleted file mode 100644 index 3e3db386..00000000 --- a/Sharp - MZ-80K_MiST/rtl/ps2_recieve.v +++ /dev/null @@ -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 diff --git a/Sharp - MZ-80K_MiST/rtl/ps2n.sv b/Sharp - MZ-80K_MiST/rtl/ps2n.sv deleted file mode 100644 index 5dd29436..00000000 --- a/Sharp - MZ-80K_MiST/rtl/ps2n.sv +++ /dev/null @@ -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 \ No newline at end of file diff --git a/Sharp - MZ-80K_MiST/rtl/roms/combined_keymap.mif b/Sharp - MZ-80K_MiST/rtl/roms/combined_keymap.mif new file mode 100644 index 00000000..955a6b50 --- /dev/null +++ b/Sharp - MZ-80K_MiST/rtl/roms/combined_keymap.mif @@ -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; diff --git a/Sharp - MZ-80K_MiST/rtl/sprom.vhd b/Sharp - MZ-80K_MiST/rtl/sprom.vhd new file mode 100644 index 00000000..a81ac959 --- /dev/null +++ b/Sharp - MZ-80K_MiST/rtl/sprom.vhd @@ -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; diff --git a/Sharp - MZ-80K_MiST/snapshot/mz80a_mist.rbf b/Sharp - MZ-80K_MiST/snapshot/mz80a_mist.rbf deleted file mode 100644 index b7b4274c..00000000 Binary files a/Sharp - MZ-80K_MiST/snapshot/mz80a_mist.rbf and /dev/null differ diff --git a/Sharp - MZ-80K_MiST/snapshot/mz80k_mist.rbf b/Sharp - MZ-80K_MiST/snapshot/mz80k_mist.rbf deleted file mode 100644 index 741ef6ec..00000000 Binary files a/Sharp - MZ-80K_MiST/snapshot/mz80k_mist.rbf and /dev/null differ