diff --git a/Computer_MiST/Acorn - System1/Acorn_System1.qpf b/Computer_MiST/Acorn - System1/Acorn_System1.qpf new file mode 100644 index 00000000..e17aa063 --- /dev/null +++ b/Computer_MiST/Acorn - System1/Acorn_System1.qpf @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 2016 Intel Corporation. All rights reserved. +# Your use of Intel Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Intel Program License +# Subscription Agreement, the Intel Quartus Prime License Agreement, +# the Intel MegaCore Function License Agreement, or other +# applicable license agreement, including, without limitation, +# that your use is for the sole purpose of programming logic +# devices manufactured by Intel and sold by Intel or its +# authorized distributors. Please refer to the applicable +# agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus Prime +# Version 16.1.0 Build 196 10/24/2016 SJ Lite Edition +# Date created = 11:17:10 October 25, 2017 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "16.1" +DATE = "11:17:10 October 25, 2017" + +# Revisions + +PROJECT_REVISION = "Acorn_System1" diff --git a/Computer_MiST/Acorn - System1/Acorn_System1.qsf b/Computer_MiST/Acorn - System1/Acorn_System1.qsf new file mode 100644 index 00000000..f7990cbc --- /dev/null +++ b/Computer_MiST/Acorn - System1/Acorn_System1.qsf @@ -0,0 +1,166 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition +# Date created = 16:10:44 August 12, 2019 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# Acorn_System1_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 15.1.0 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:45:13 JUNE 17,2016" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" + +# Pin & Location Assignments +# ========================== +set_location_assignment PIN_7 -to LED +set_location_assignment PIN_54 -to CLOCK_27 +set_location_assignment PIN_144 -to VGA_R[5] +set_location_assignment PIN_143 -to VGA_R[4] +set_location_assignment PIN_142 -to VGA_R[3] +set_location_assignment PIN_141 -to VGA_R[2] +set_location_assignment PIN_137 -to VGA_R[1] +set_location_assignment PIN_135 -to VGA_R[0] +set_location_assignment PIN_133 -to VGA_B[5] +set_location_assignment PIN_132 -to VGA_B[4] +set_location_assignment PIN_125 -to VGA_B[3] +set_location_assignment PIN_121 -to VGA_B[2] +set_location_assignment PIN_120 -to VGA_B[1] +set_location_assignment PIN_115 -to VGA_B[0] +set_location_assignment PIN_114 -to VGA_G[5] +set_location_assignment PIN_113 -to VGA_G[4] +set_location_assignment PIN_112 -to VGA_G[3] +set_location_assignment PIN_111 -to VGA_G[2] +set_location_assignment PIN_110 -to VGA_G[1] +set_location_assignment PIN_106 -to VGA_G[0] +set_location_assignment PIN_136 -to VGA_VS +set_location_assignment PIN_119 -to VGA_HS +set_location_assignment PIN_65 -to AUDIO_L +set_location_assignment PIN_80 -to AUDIO_R +set_location_assignment PIN_105 -to SPI_DO +set_location_assignment PIN_88 -to SPI_DI +set_location_assignment PIN_126 -to SPI_SCK +set_location_assignment PIN_127 -to SPI_SS2 +set_location_assignment PIN_91 -to SPI_SS3 +set_location_assignment PIN_13 -to CONF_DATA0 + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name TOP_LEVEL_ENTITY System1_MiST +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 + +# Fitter Assignments +# ================== +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name ENABLE_NCE_PIN OFF + +# EDA Netlist Writer Assignments +# ============================== +set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)" + +# Assembler Assignments +# ===================== +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON + +# SignalTap II Assignments +# ======================== +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise + +# ---------------------- +# start ENTITY(SNES_top) + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(SNES_top) +# -------------------- +set_global_assignment -name SYSTEMVERILOG_FILE rtl/System1_MiST.sv +set_global_assignment -name VERILOG_FILE rtl/System1.v +set_global_assignment -name VERILOG_FILE rtl/cpu.v +set_global_assignment -name VERILOG_FILE rtl/ALU.v +set_global_assignment -name VERILOG_FILE rtl/m6522.v +set_global_assignment -name VHDL_FILE rtl/roms/acrnsys1.vhd +set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd +set_global_assignment -name VERILOG_FILE rtl/vga.v +set_global_assignment -name QIP_FILE ../../Mist_FPGA/common/mist/mist.qip +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 VERILOG_FILE rtl/pll.v +set_global_assignment -name VHDL_FILE rtl/ps2_mouse.vhd +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/Acorn_System1.srf b/Computer_MiST/Acorn - System1/Acorn_System1.srf new file mode 100644 index 00000000..d63be27f --- /dev/null +++ b/Computer_MiST/Acorn - System1/Acorn_System1.srf @@ -0,0 +1,6 @@ +{ "" "" "" "Verilog HDL or VHDL warning at cpu.v(148): object \"brk\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "Verilog HDL assignment warning at cpu.v(720): truncated value with size 32 to match size of target (1)" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "Verilog HDL assignment warning at cpu.v(717): truncated value with size 32 to match size of target (1)" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "Verilog HDL assignment warning at cpu.v(661): truncated value with size 32 to match size of target (8)" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "Verilog HDL assignment warning at ALU.v(50): truncated value with size 32 to match size of target (1)" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "Verilog HDL assignment warning at ALU.v(73): truncated value with size 9 to match size of target (8)" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""} diff --git a/Computer_MiST/Acorn - System1/README.txt b/Computer_MiST/Acorn - System1/README.txt new file mode 100644 index 00000000..8b80e55a --- /dev/null +++ b/Computer_MiST/Acorn - System1/README.txt @@ -0,0 +1,37 @@ +Acorn System 1 - Port to MiST + +ToDo: Mouse and Keyboard + + + + +This is a port of Acorn System 1 inspired by the work of David Banks. + + +This version has a huge 512 bytes of rom +and a massive 1024 bytes of memory. The display is the latest 9 digit (only 8 used )7 segment plus dp. +The keyboard is 25 soft touch positive click switches. + +My first computer was a system 1. I could spend hours entering one machine +code instruction at a time, then more hours debugging my mistakes. +Then switch off and it was all lost. +Ahh those were the days. + +I would think that this port will be of limited interest but I could not find any other +port of this machine. + +The mouse is the yellow dot on the screen. Left click to press switch. + +At present this is a basic system 1 there are no bells or whistles. +No input (tape) or output as yet. + +You will have to forgive the vga output, all hand drawn using several hundred 'if' statements. + +The quickest way to test is after load, press the rst key. Press 'm' key. +Enter '0015' and press 'm' again. +The address 0015 is the 3rd character from the right. The value shouls read 80. +type any hex character to change the value and the character will change. + + + +Dave Wood (oldgit) \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/Snapshot/Acorn_System1.rbf b/Computer_MiST/Acorn - System1/Snapshot/Acorn_System1.rbf new file mode 100644 index 00000000..9acf5abb Binary files /dev/null and b/Computer_MiST/Acorn - System1/Snapshot/Acorn_System1.rbf differ diff --git a/Computer_MiST/Acorn - System1/clean.bat b/Computer_MiST/Acorn - System1/clean.bat new file mode 100644 index 00000000..83fb0c47 --- /dev/null +++ b/Computer_MiST/Acorn - System1/clean.bat @@ -0,0 +1,15 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +del PLLJ_PLLSPE_INFO.txt +del *.qws +del *.ppf +del *.qip +del *.ddb +pause diff --git a/Computer_MiST/Acorn - System1/rtl/ALU.v b/Computer_MiST/Acorn - System1/rtl/ALU.v new file mode 100644 index 00000000..8d05fc03 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/ALU.v @@ -0,0 +1,108 @@ +/* + * ALU. + * + * AI and BI are 8 bit inputs. Result in OUT. + * CI is Carry In. + * CO is Carry Out. + * + * op[3:0] is defined as follows: + * + * 0011 AI + BI + * 0111 AI - BI + * 1011 AI + AI + * 1100 AI | BI + * 1101 AI & BI + * 1110 AI ^ BI + * 1111 AI + * + */ + +module ALU( clk, op, right, AI, BI, CI, CO, BCD, OUT, V, Z, N, HC, RDY ); + input clk; + input right; + input [3:0] op; // operation + input [7:0] AI; + input [7:0] BI; + input CI; + input BCD; // BCD style carry + output [7:0] OUT; + output CO; + output V; + output Z; + output N; + output HC; + input RDY; + +reg [7:0] OUT; +reg CO; +wire V; +wire Z; +reg N; +reg HC; + +reg AI7; +reg BI7; +reg [8:0] temp_logic; +reg [7:0] temp_BI; +reg [4:0] temp_l; +reg [4:0] temp_h; +wire [8:0] temp = { temp_h, temp_l[3:0] }; +wire adder_CI = (right | (op[3:2] == 2'b11)) ? 0 : CI; + +// calculate the logic operations. The 'case' can be done in 1 LUT per +// bit. The 'right' shift is a simple mux that can be implemented by +// F5MUX. +always @* begin + case( op[1:0] ) + 2'b00: temp_logic = AI | BI; + 2'b01: temp_logic = AI & BI; + 2'b10: temp_logic = AI ^ BI; + 2'b11: temp_logic = AI; + endcase + + if( right ) + temp_logic = { AI[0], CI, AI[7:1] }; +end + +// Add logic result to BI input. This only makes sense when logic = AI. +// This stage can be done in 1 LUT per bit, using carry chain logic. +always @* begin + case( op[3:2] ) + 2'b00: temp_BI = BI; // A+B + 2'b01: temp_BI = ~BI; // A-B + 2'b10: temp_BI = temp_logic; // A+A + 2'b11: temp_BI = 0; // A+0 + endcase +end + +// HC9 is the half carry bit when doing BCD add +wire HC9 = BCD & (temp_l[3:1] >= 3'd5); + +// CO9 is the carry-out bit when doing BCD add +wire CO9 = BCD & (temp_h[3:1] >= 3'd5); + +// combined half carry bit +wire temp_HC = temp_l[4] | HC9; + +// perform the addition as 2 separate nibble, so we get +// access to the half carry flag +always @* begin + temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI; + temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC; +end + +// calculate the flags +always @(posedge clk) + if( RDY ) begin + AI7 <= AI[7]; + BI7 <= temp_BI[7]; + OUT <= temp[7:0]; + CO <= temp[8] | CO9; + N <= temp[7]; + HC <= temp_HC; + end + +assign V = AI7 ^ BI7 ^ CO ^ N; +assign Z = ~|OUT; + +endmodule diff --git a/Computer_MiST/Acorn - System1/rtl/System1.v b/Computer_MiST/Acorn - System1/rtl/System1.v new file mode 100644 index 00000000..fe4b842e --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/System1.v @@ -0,0 +1,327 @@ +// ======================================================================= +// +// +// An Acorn System1 implementation for the Mister +// +// Copyright (C) 2019 Dave Wood +// +// This program 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 program 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 System1( + input clk25, + input reset, + output reg[8:0]ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7, + input sw0,sw1,sw2,sw3,sw4,sw5,sw6,sw7,sw8,sw9,swa,swb,swc,swd,swe,swf,swrst,swm,swl,swg,swr,swp,swU,sws,swD, +// Cassette / Sound + input cas_in, + output cas_out +); + +wire rom_cs; +wire [7:0] rom_dout; +acrnsys1 MONROM( + .clk(clk25 & rom_cs), + .addr(address[8:0]), + .data(rom_dout) +); + +wire ram_cs; +wire ram_wr = (!rnw & ram_cs); +wire [7:0] ram_dout; +gen_ram #( + .dWidth(8), + .aWidth(10)) +MRAM ( + .clk(clk25 & ram_cs), + .we(ram_wr), + .addr(address[9:0]), + .d(cpu_dout), + .q(ram_dout) +); + + // =============================================================== + // Wires/Reg definitions + // TODO: reorganize so all defined here + // =============================================================== + + + reg rnw; + + reg [15:0] address; + reg [7:0] cpu_dout; + + wire [7:0] via_dout; + + wire via_irq_n; + + wire [1:0] turbo = 2'b00; + reg lock; + reg [2:0] phase = 3'b000; + reg [2:0] scan = 3'b111; + wire [7:0] PA_out; + reg [7:0] PA_tmp = 8'b00000000; + + + + // =============================================================== + // Clock Enable Generation + // =============================================================== + + reg cpu_clken; + reg via1_clken; + reg via4_clken; + + reg [4:0] clkdiv = 5'b00000; // divider, from 25MHz down to 1, 2, 4 or 8MHz + + always @(posedge clk25) begin + if (clkdiv == 24) + clkdiv <= 0; + else + clkdiv <= clkdiv + 1; + case (turbo) + 2'b00: // 1MHz + begin + cpu_clken <= (clkdiv[3:0] == 0) & (clkdiv[4] == 0); + via1_clken <= (clkdiv[3:0] == 0) & (clkdiv[4] == 0); + via4_clken <= (clkdiv[1:0] == 0) & (clkdiv[4] == 0); + end + 2'b01: // 2MHz + begin + cpu_clken <= (clkdiv[2:0] == 0) & (clkdiv[4] == 0); + via1_clken <= (clkdiv[2:0] == 0) & (clkdiv[4] == 0); + via4_clken <= (clkdiv[0] == 0) & (clkdiv[4] == 0); + end + default: // 4MHz + begin + cpu_clken <= (clkdiv[1:0] == 0) & (clkdiv[4] == 0); + via1_clken <= (clkdiv[1:0] == 0) & (clkdiv[4] == 0); + via4_clken <= (clkdiv[4] == 0); + end + endcase + + end + + + // =============================================================== + // Cassette + // =============================================================== + + // The Atom drives cas_tone from 4MHz / 16 / 13 / 8 + // 208 = 16 * 13, and start with 1MHz and toggle + // so it's basically the same + + reg cas_tone = 1'b0; + reg [7:0] cas_div = 0; + + always @(posedge clk25) begin + + + if (cpu_clken) + begin + if (cas_div == 207) + begin + cas_div <= 0; + cas_tone <= !cas_tone; + end + else + cas_div <= cas_div + 1; + end + + end + + // this is a direct translation of the logic in the atom + // (two NAND gates and an inverter) +// assign cas_out = !(!(!cas_tone & pia_pc[1]) & pia_pc[0]); +// assign PB_in[7] = cas_in; + + + + // =============================================================== + // 6502 CPU + // =============================================================== + + wire [7:0] cpu_din; + wire [7:0] cpu_dout_c; + wire [15:0] address_c; + wire rnw_c; + + // Arlet's 6502 core is one of the smallest available + cpu CPU + ( + .clk(clk25), + .reset(swrst | reset), + .AB(address_c), + .DI(cpu_din), + .DO(cpu_dout_c), + .WE(rnw_c), + .IRQ(1'b0), //(!via_irq_n), + .NMI(1'b0), + .RDY(cpu_clken) + ); + + // The outputs of Arlets's 6502 core need registing + always @(posedge clk25) + begin + if (cpu_clken) + begin + address <= address_c; + cpu_dout <= cpu_dout_c; + rnw <= !rnw_c; + end + end + + // =============================================================== + // Address decoding logic and data in multiplexor + // =============================================================== + + // 0000-3FFF RAM + + // 0Exx-0Fxx 6522 VIA + + // FExx-FFxx Monitor Prom + + assign rom_cs = (address[15:9] == 7'b1111111); //FE00 - FFFF + wire via_cs = (address[15:9] == 7'b0000111); //0Exx + assign ram_cs = (address[15:10] == 6'b000000); //0000 - 003F + + assign cpu_din = via_cs ? via_dout : + ram_cs ? ram_dout : + rom_cs ? rom_dout : + 8'b11111111; + + // =============================================================== + // 6522 VIA at 0x0Exx + // =============================================================== + + wire [7:0] PB_out; + wire [7:0] PB_oe,PA_oe; + reg [7:0] PB_in; + wire pressed = (~sw0 & ~sw1 & ~sw2 & ~sw3 & ~sw4 & ~sw5 & ~sw6 & ~sw7 & ~sw8 & ~sw9 & ~swa & ~swb & ~swc & ~swd & ~swe & ~swf & ~swm & ~swl & ~swg & ~swr & ~swp & ~swU & ~sws & ~swD); + + always @(posedge via1_clken) begin + if (pressed) PB_in <= 8'b00111111; + if (phase == 3'b000 && PB_out[2:0] == 3'b111) begin + ch0 <= PA_out; + phase = 3'b001; + if (sw7) PB_in <= 8'b00011111; + if (swD) PB_in <= 8'b00101111; + if (swf) PB_in <= 8'b00110111; + end + if (phase == 3'b001 && PB_out[2:0] == 3'b110) begin + ch1 <= PA_out; + phase = 3'b010; + if (sw6) PB_in <= 8'b00011111; + if (swU) PB_in <= 8'b00101111; + if (swe) PB_in <= 8'b00110111; + end + if (phase == 3'b010 && PB_out[2:0] == 3'b101) begin + ch2 <= PA_out; + phase = 3'b011; + if (sw5) PB_in <= 8'b00011111; + if (swr) PB_in <= 8'b00101111; + if (swd) PB_in <= 8'b00110111; + end + if (phase == 3'b011 && PB_out[2:0] == 3'b100) begin + ch3 <= PA_out; + phase = 3'b100; + if (sw4) PB_in <= 8'b00011111; + if (swl) PB_in <= 8'b00101111; + if (swc) PB_in <= 8'b00110111; + end + if (phase == 3'b100 && PB_out[2:0] == 3'b011) begin + ch4 <= PA_out; + phase = 3'b101; + if (sw3) PB_in <= 8'b00011111; + if (sws) PB_in <= 8'b00101111; + if (swb) PB_in <= 8'b00110111; + end + if (phase == 3'b101 && PB_out[2:0] == 3'b010) begin + ch5 <= PA_out; + phase = 3'b110; + if (sw2) PB_in <= 8'b00011111; + if (swp) PB_in <= 8'b00101111; + if (swa) PB_in <= 8'b00110111; + end + if (phase == 3'b110 && PB_out[2:0] == 3'b001) begin + ch6 <= PA_out; + phase = 3'b111; + if (sw1) PB_in <= 8'b00011111; + if (swg) PB_in <= 8'b00101111; + if (sw9) PB_in <= 8'b00110111; + end + if (phase == 3'b111 && PB_out[2:0] == 3'b000) begin + ch7 <= PA_out; + phase = 3'b000; + if (sw0) PB_in <= 8'b00011111; + if (swm) PB_in <= 8'b00101111; + if (sw8) PB_in <= 8'b00110111; + end + end + + + m6522 VIA + ( + .I_RS(address[3:0]), + .I_DATA(cpu_dout), + .O_DATA(via_dout), + .O_DATA_OE_L(), + .I_RW_L(rnw), + .I_CS1(via_cs), + .I_CS2_L(1'b0), + .O_IRQ_L(via_irq_n), + .I_CA1(1'b0), + .I_CA2(1'b0), + .O_CA2(), + .O_CA2_OE_L(), + .I_PA(8'b0), + .O_PA(PA_out), + .O_PA_OE_L(PA_oe), + .I_CB1(1'b0), + .O_CB1(), + .O_CB1_OE_L(), + .I_CB2(1'b0), + .O_CB2(), + .O_CB2_OE_L(), + .I_PB(PB_in), + .O_PB(PB_out), + .O_PB_OE_L(PB_oe), + .I_P2_H(via1_clken), + .RESET_L(!reset), + .ENA_4(via4_clken), + .CLK(clk25) + ); + +/* + wire [7:0] digit_0 = 8'h3F; + wire [7:0] digit_1 = 8'h06; + wire [7:0] digit_2 = 8'h5B; + wire [7:0] digit_3 = 8'h4F; + wire [7:0] digit_4 = 8'h66; + wire [7:0] digit_5 = 8'h6D; + wire [7:0] digit_6 = 8'h7D; + wire [7:0] digit_7 = 8'h07; + wire [7:0] digit_8 = 8'h7F; + wire [7:0] digit_9 = 8'h6F; + wire [7:0] digit_A = 8'h77; + wire [7:0] digit_B = 8'h7C; + wire [7:0] digit_C = 8'h58; + wire [7:0] digit_D = 8'h5E; + wire [7:0] digit_E = 8'h79; + wire [7:0] digit_F = 8'h71; +*/ + + +endmodule diff --git a/Computer_MiST/Acorn - System1/rtl/System1_MiST.sv b/Computer_MiST/Acorn - System1/rtl/System1_MiST.sv new file mode 100644 index 00000000..20fb3392 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/System1_MiST.sv @@ -0,0 +1,296 @@ +module System1_MiST( + input CLOCK_27, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output LED, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0 +); + +`include "build_id.v" +localparam CONF_STR = { + "System1;;", + "T6,Reset;", + "V,v1.00.",`BUILD_DATE +}; +wire clk_sys; +wire key_pressed; +wire [7:0] key_code; +wire key_strobe; +wire key_extended; +wire [8:0] mouse_x,mouse_y; +wire [7:0] mouse_flags; +wire [7:0] r, g, b; +wire hs, vs, hb, vb; +wire blankn = ~(hb | vb); +wire [1:0] buttons, switches; +wire ypbpr; +wire scandoublerD; +wire [31:0] status; + +assign LED = 1'b1; + +pll pll ( + .inclk0 (CLOCK_27 ), + .c0 (clk_sys )//25 + ); + +user_io #( + .STRLEN (($size(CONF_STR)>>3))) +user_io( + .clk_sys (clk_sys ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_extended (key_extended ), + .key_code (key_code ), + .mouse_x (mouse_x ), + .mouse_y (mouse_y ), + .status (status ) + ); + +mist_video #(.COLOR_DEPTH(6)) mist_video( + .clk_sys (clk_sys ), + .SPI_SCK (SPI_SCK ), + .SPI_SS3 (SPI_SS3 ), + .SPI_DI (SPI_DI ), + .R (blankn ? r[7:2] : 0), + .G (blankn ? g[7:2] : 0), + .B (blankn ? b[7:2] : 0), + .HSync (hs ), + .VSync (vs ), + .VGA_R (VGA_R ), + .VGA_G (VGA_G ), + .VGA_B (VGA_B ), + .VGA_VS (VGA_VS ), + .VGA_HS (VGA_HS ), + .scandoubler_disable(1'b1 ), + .ypbpr (ypbpr ) + ); + +wire reset = (status[0] | status[6] | buttons[1]); +wire [8:0] ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7; +wire sw0,sw1,sw2,sw3,sw4,sw5,sw6,sw7,sw8,sw9,swa,swb,swc,swd,swe,swf,swrst,swm,swl,swg,swr,swp,swUP,sws,swDW; + +System1 System1( + .clk25(clk_sys), + .reset(reset), + .ch0(ch0), + .ch1(ch1), + .ch2(ch2), + .ch3(ch3), + .ch4(ch4), + .ch5(ch5), + .ch6(ch6), + .ch7(ch7), + .sw0(sw0 | tsw0), + .sw1(sw1 | tsw1), + .sw2(sw2 | tsw2), + .sw3(sw3 | tsw3), + .sw4(sw4 | tsw4), + .sw5(sw5 | tsw5), + .sw6(sw6 | tsw6), + .sw7(sw7 | tsw7), + .sw8(sw8 | tsw8), + .sw9(sw9 | tsw9), + .swa(swa | tswa), + .swb(swb | tswb), + .swc(swc | tswc), + .swd(swd | tswd), + .swe(swe | tswe), + .swf(swf | tswf), + .swrst(swrst | tswrst), + .swm(swm | tswm), + .swl(swl | tswl), + .swg(swg | tswg), + .swr(swr | tswr), + .swp(swp | tswp), + .swU(swUP | tswUP), + .sws(sws | tsws), + .swD(swDW | tswDW), + .cas_in(1'b0), + .cas_out() +); + +vga vga( + .clk(clk_sys), + .rst(reset), + .mbtnL(mouse_flags[0]), + .mbtnR(mouse_flags[1]), + .mbtnM(mouse_flags[2]), + .mx(mouse_x),//mx), + .my(mouse_y),//my), + .ch0(ch0), + .ch1(ch1), + .ch2(ch2), + .ch3(ch3), + .ch4(ch4), + .ch5(ch5), + .ch6(ch6), + .ch7(ch7), + .osw0(sw0), + .osw1(sw1), + .osw2(sw2), + .osw3(sw3), + .osw4(sw4), + .osw5(sw5), + .osw6(sw6), + .osw7(sw7), + .osw8(sw8), + .osw9(sw9), + .oswa(swa), + .oswb(swb), + .oswc(swc), + .oswd(swd), + .oswe(swe), + .oswf(swf), + .oswrst(swrst), + .oswm(swm), + .oswl(swl), + .oswg(swg), + .oswr(swr), + .oswp(swp), + .oswU(swUP), + .osws(sws), + .oswD(swDW), + + + .r(r), + .g(g), + .b(b), + .hs(hs), + .vs(vs), + .hblank(hb), + .vblank(vb) +); +/* +wire [10:0] mx,my; +wire x1,y1,mbtnL,mbtnR,mbtnM; + +ps2_mouse mouse +( + .clk(clk_sys), + .ce(1'b1), + .reset(reset), + .ps2_mouse(ps2_mouse), + .mx(mx), + .my(my), + .mbtnL(mbtnL), + .mbtnR(mbtnR), + .mbtnM(mbtnM) +);*/ +/* +ps2_mouse #( + .clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + .ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz) +MOUSE( + .clk : IN STD_LOGIC; --system clock input + .reset_n : IN STD_LOGIC; --active low asynchronous reset + .ps2_clk : INOUT STD_LOGIC; --clock signal from PS2 mouse + .ps2_data : INOUT STD_LOGIC; --data signal from PS2 mouse + .mouse_data : OUT STD_LOGIC_VECTOR(23 DOWNTO 0); --data received from mouse + .mouse_data_new : OUT STD_LOGIC + ); +*/ +reg tsw0 = 1'b0; +reg tsw1 = 1'b0; +reg tsw2 = 1'b0; +reg tsw3 = 1'b0; +reg tsw4 = 1'b0; +reg tsw5 = 1'b0; +reg tsw6 = 1'b0; +reg tsw7 = 1'b0; +reg tsw8 = 1'b0; +reg tsw9 = 1'b0; +reg tswa = 1'b0; +reg tswb = 1'b0; +reg tswc = 1'b0; +reg tswd = 1'b0; +reg tswe = 1'b0; +reg tswf = 1'b0; +reg tswm = 1'b0; +reg tswl = 1'b0; +reg tswg = 1'b0; +reg tswr = 1'b0; +reg tswp = 1'b0; +reg tswUP = 1'b0; +reg tsws = 1'b0; +reg tswDW = 1'b0; +reg tswrst = 1'b0; + + +always @(posedge clk_sys) begin + reg old_state; + old_state <= key_strobe; + + if(old_state != key_strobe) begin + casex(key_code) + 'h75: tswUP <= key_pressed; // up + 'h72: tswDW <= key_pressed; // down + + 'h45: tsw0 <= key_pressed; // 0 +// 'h70: tsw0 <= key_pressed; // 0 + + 'h16: tsw1 <= key_pressed; // 1 +// 'h69: tsw1 <= key_pressed; // 1 + + 'h1E: tsw2 <= key_pressed; // 2 +// 'h72: tsw2 <= key_pressed; // 2 + + 'h26: tsw3 <= key_pressed; // 3 +// 'h7A: tsw3 <= key_pressed; // 3 + + 'h25: tsw4 <= key_pressed; // 4 +// 'h6B: tsw4 <= key_pressed; // 4 + + 'h2E: tsw5 <= key_pressed; // 5 +// 'h73: tsw5 <= key_pressed; // 5 + + 'h36: tsw6 <= key_pressed; // 6 +// 'h74: tsw6 <= key_pressed; // 6 + + 'h3D: tsw7 <= key_pressed; // 7 +// 'h6C: tsw7 <= key_pressed; // 7 + + 'h3E: tsw8 <= key_pressed; // 8 +// 'h75: tsw8 <= key_pressed; // 8 + + 'h46: tsw9 <= key_pressed; // 9 +// 'h7D: tsw9 <= key_pressed; // 9 + + + 'h1C: tswa <= key_pressed; // a + 'h32: tswb <= key_pressed; // b + 'h21: tswc <= key_pressed; // c + 'h23: tswd <= key_pressed; // d + 'h24: tswe <= key_pressed; // e + 'h2B: tswf <= key_pressed; // f + 'h3A: tswm <= key_pressed; // m + 'h34: tswg <= key_pressed; // g + 'h4D: tswp <= key_pressed; // p + 'h1B: tsws <= key_pressed; // s + 'h4B: tswl <= key_pressed; // l + 'h2D: tswr <= key_pressed; // r +// 'h05: tswrst <= key_pressed; // F1 + endcase + end +end + + + +endmodule \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/rtl/build_id.tcl b/Computer_MiST/Acorn - System1/rtl/build_id.tcl new file mode 100644 index 00000000..938515d8 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "rtl/build_id.v" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_TIME \"$buildTime\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Generated build identification Verilog module: [pwd]/$outputFileName" + post_message "Date: $buildDate" + post_message "Time: $buildTime" +} + +# Comment out this line to prevent the process from automatically executing when the file is sourced: +generateBuildID_Verilog \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/rtl/cpu.v b/Computer_MiST/Acorn - System1/rtl/cpu.v new file mode 100644 index 00000000..ed8da623 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/cpu.v @@ -0,0 +1,1220 @@ +/* + * verilog model of 6502 CPU. + * + * (C) Arlet Ottens, + * + * Feel free to use this code in any project (commercial or not), as long as you + * keep this message, and the copyright notice. This code is provided "as is", + * without any warranties of any kind. + * + */ + +/* + * Note that not all 6502 interface signals are supported (yet). The goal + * is to create an Acorn Atom model, and the Atom didn't use all signals on + * the main board. + * + * The data bus is implemented as separate read/write buses. Combine them + * on the output pads if external memory is required. + */ + +module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); + +input clk; // CPU clock +input reset; // reset signal +output reg [15:0] AB; // address bus +input [7:0] DI; // data in, read bus +output [7:0] DO; // data out, write bus +output WE; // write enable +input IRQ; // interrupt request +input NMI; // non-maskable interrupt request +input RDY; // Ready signal. Pauses CPU when RDY=0 + +/* + * internal signals + */ + +reg [15:0] PC; // Program Counter +reg [7:0] ABL; // Address Bus Register LSB +reg [7:0] ABH; // Address Bus Register MSB +wire [7:0] ADD; // Adder Hold Register (registered in ALU) + +reg [7:0] DIHOLD; // Hold for Data In +reg DIHOLD_valid; // +wire [7:0] DIMUX; // + +reg [7:0] IRHOLD; // Hold for Instruction register +reg IRHOLD_valid; // Valid instruction in IRHOLD + +reg [7:0] AXYS[3:0]; // A, X, Y and S register file + +reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) +reg Z = 0; // zero flag +reg I = 0; // interrupt flag +reg D = 0; // decimal flag +reg V = 0; // overflow flag +reg N = 0; // negative flag +wire AZ; // ALU Zero flag +wire AV; // ALU overflow flag +wire AN; // ALU negative flag +wire HC; // ALU half carry + +reg [7:0] AI; // ALU Input A +reg [7:0] BI; // ALU Input B +wire [7:0] DI; // Data In +wire [7:0] IR; // Instruction register +reg [7:0] DO; // Data Out +reg WE; // Write Enable +reg CI; // Carry In +wire CO; // Carry Out +wire [7:0] PCH = PC[15:8]; +wire [7:0] PCL = PC[7:0]; + +reg NMI_edge = 0; // captured NMI edge + +reg [1:0] regsel; // Select A, X, Y or S register +wire [7:0] regfile = AXYS[regsel]; // Selected register output + +parameter + SEL_A = 2'd0, + SEL_S = 2'd1, + SEL_X = 2'd2, + SEL_Y = 2'd3; + +/* + * define some signals for watching in simulator output + */ + + +`ifdef SIM +wire [7:0] A = AXYS[SEL_A]; // Accumulator +wire [7:0] X = AXYS[SEL_X]; // X register +wire [7:0] Y = AXYS[SEL_Y]; // Y register +wire [7:0] S = AXYS[SEL_S]; // Stack pointer +`endif + +wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; + +/* + * instruction decoder/sequencer + */ + +reg [5:0] state; + +/* + * control signals + */ + +reg PC_inc; // Increment PC +reg [15:0] PC_temp; // intermediate value of PC + +reg [1:0] src_reg; // source register index +reg [1:0] dst_reg; // destination register index + +reg index_y; // if set, then Y is index reg rather than X +reg load_reg; // loading a register (A, X, Y, S) in this instruction +reg inc; // increment +reg write_back; // set if memory is read/modified/written +reg load_only; // LDA/LDX/LDY instruction +reg store; // doing store (STA/STX/STY) +reg adc_sbc; // doing ADC/SBC +reg compare; // doing CMP/CPY/CPX +reg shift; // doing shift/rotate instruction +reg rotate; // doing rotate (no shift) +reg backwards; // backwards branch +reg cond_true; // branch condition is true +reg [2:0] cond_code; // condition code bits from instruction +reg shift_right; // Instruction ALU shift/rotate right +reg alu_shift_right; // Current cycle shift right enable +reg [3:0] op; // Main ALU operation for instruction +reg [3:0] alu_op; // Current cycle ALU operation +reg adc_bcd; // ALU should do BCD style carry +reg adj_bcd; // results should be BCD adjusted + +/* + * some flip flops to remember we're doing special instructions. These + * get loaded at the DECODE state, and used later + */ +reg bit_ins; // doing BIT instruction +reg plp; // doing PLP instruction +reg php; // doing PHP instruction +reg clc; // clear carry +reg sec; // set carry +reg cld; // clear decimal +reg sed; // set decimal +reg cli; // clear interrupt +reg sei; // set interrupt +reg clv; // clear overflow +reg brk; // doing BRK + +reg res; // in reset + +/* + * ALU operations + */ + +parameter + OP_OR = 4'b1100, + OP_AND = 4'b1101, + OP_EOR = 4'b1110, + OP_ADD = 4'b0011, + OP_SUB = 4'b0111, + OP_ROL = 4'b1011, + OP_A = 4'b1111; + +/* + * Microcode state machine. Basically, every addressing mode has its own + * path through the state machine. Additional information, such as the + * operation, source and destination registers are decoded in parallel, and + * kept in separate flops. + */ + +parameter + ABS0 = 6'd0, // ABS - fetch LSB + ABS1 = 6'd1, // ABS - fetch MSB + ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) + ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) + ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) + BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) + BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU + BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) + BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) + BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) + BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) + BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe + DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg + FETCH = 6'd13, // fetch next opcode, and perform prev ALU op + INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) + INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 + INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 + INDX3 = 6'd17, // (ZP,X) - fetch data + INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) + INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) + INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) + INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) + JMP0 = 6'd22, // JMP - fetch PCL and hold + JMP1 = 6'd23, // JMP - fetch PCH + JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) + JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state + JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) + JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) + JSR2 = 6'd28, // JSR - write S + JSR3 = 6'd29, // JSR - fetch MSB + PULL0 = 6'd30, // PLP/PLA - save next op in IRHOLD, send S to ALU (+1) + PULL1 = 6'd31, // PLP/PLA - fetch data from stack, write S + PULL2 = 6'd32, // PLP/PLA - prefetch op, but don't increment PC + PUSH0 = 6'd33, // PHP/PHA - send A to ALU (+0) + PUSH1 = 6'd34, // PHP/PHA - write A/P, send S to ALU (-1) + READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) + REG = 6'd36, // Read register for reg-reg transfers + RTI0 = 6'd37, // RTI - send S to ALU (+1) + RTI1 = 6'd38, // RTI - read P from stack + RTI2 = 6'd39, // RTI - read PCL from stack + RTI3 = 6'd40, // RTI - read PCH from stack + RTI4 = 6'd41, // RTI - read PCH from stack + RTS0 = 6'd42, // RTS - send S to ALU (+1) + RTS1 = 6'd43, // RTS - read PCL from stack + RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH + RTS3 = 6'd45, // RTS - load PC and increment + WRITE = 6'd46, // Write memory for read/modify/write + ZP0 = 6'd47, // Z-page - fetch ZP address + ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) + ZPX1 = 6'd49; // ZP, X - load from memory + +`ifdef SIM + +/* + * easy to read names in simulator output + */ +reg [8*6-1:0] statename; + +always @* + case( state ) + DECODE: statename = "DECODE"; + REG: statename = "REG"; + ZP0: statename = "ZP0"; + ZPX0: statename = "ZPX0"; + ZPX1: statename = "ZPX1"; + ABS0: statename = "ABS0"; + ABS1: statename = "ABS1"; + ABSX0: statename = "ABSX0"; + ABSX1: statename = "ABSX1"; + ABSX2: statename = "ABSX2"; + INDX0: statename = "INDX0"; + INDX1: statename = "INDX1"; + INDX2: statename = "INDX2"; + INDX3: statename = "INDX3"; + INDY0: statename = "INDY0"; + INDY1: statename = "INDY1"; + INDY2: statename = "INDY2"; + INDY3: statename = "INDY3"; + READ: statename = "READ"; + WRITE: statename = "WRITE"; + FETCH: statename = "FETCH"; + PUSH0: statename = "PUSH0"; + PUSH1: statename = "PUSH1"; + PULL0: statename = "PULL0"; + PULL1: statename = "PULL1"; + PULL2: statename = "PULL2"; + JSR0: statename = "JSR0"; + JSR1: statename = "JSR1"; + JSR2: statename = "JSR2"; + JSR3: statename = "JSR3"; + RTI0: statename = "RTI0"; + RTI1: statename = "RTI1"; + RTI2: statename = "RTI2"; + RTI3: statename = "RTI3"; + RTI4: statename = "RTI4"; + RTS0: statename = "RTS0"; + RTS1: statename = "RTS1"; + RTS2: statename = "RTS2"; + RTS3: statename = "RTS3"; + BRK0: statename = "BRK0"; + BRK1: statename = "BRK1"; + BRK2: statename = "BRK2"; + BRK3: statename = "BRK3"; + BRA0: statename = "BRA0"; + BRA1: statename = "BRA1"; + BRA2: statename = "BRA2"; + JMP0: statename = "JMP0"; + JMP1: statename = "JMP1"; + JMPI0: statename = "JMPI0"; + JMPI1: statename = "JMPI1"; + endcase + +//always @( PC ) +// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); + +`endif + + + +/* + * Program Counter Increment/Load. First calculate the base value in + * PC_temp. + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_temp = { ABH, ABL }; + else + PC_temp = PC; + + + JMP1, + JMPI1, + JSR3, + RTS3, + RTI4: PC_temp = { DIMUX, ADD }; + + BRA1: PC_temp = { ABH, ADD }; + + BRA2: PC_temp = { ADD, PCL }; + + BRK2: PC_temp = res ? 16'hfffc : + NMI_edge ? 16'hfffa : 16'hfffe; + + default: PC_temp = PC; + endcase + +/* + * Determine wether we need PC_temp, or PC_temp + 1 + */ +always @* + case( state ) + DECODE: if( (~I & IRQ) | NMI_edge ) + PC_inc = 0; + else + PC_inc = 1; + + ABS0, + ABSX0, + FETCH, + BRA0, + BRA2, + BRK3, + JMPI1, + JMP1, + RTI4, + RTS3: PC_inc = 1; + + BRA1: PC_inc = CO ^~ backwards; + + default: PC_inc = 0; + endcase + +/* + * Set new PC + */ +always @(posedge clk) + if( RDY ) + PC <= PC_temp + PC_inc; + +/* + * Address Generator + */ + +parameter + ZEROPAGE = 8'h00, + STACKPAGE = 8'h01; + +always @* + case( state ) + ABSX1, + INDX3, + INDY2, + JMP1, + JMPI1, + RTI4, + ABS1: AB = { DIMUX, ADD }; + + BRA2, + INDY3, + ABSX2: AB = { ADD, ABL }; + + BRA1: AB = { ABH, ADD }; + + JSR0, + PUSH1, + RTS0, + RTI0, + BRK0: AB = { STACKPAGE, regfile }; + + BRK1, + JSR1, + PULL1, + RTS1, + RTS2, + RTI1, + RTI2, + RTI3, + BRK2: AB = { STACKPAGE, ADD }; + + INDY1, + INDX1, + ZPX1, + INDX2: AB = { ZEROPAGE, ADD }; + + ZP0, + INDY0: AB = { ZEROPAGE, DIMUX }; + + REG, + READ, + WRITE: AB = { ABH, ABL }; + + default: AB = PC; + endcase + +/* + * ABH/ABL pair is used for registering previous address bus state. + * This can be used to keep the current address, freeing up the original + * source of the address, such as the ALU or DI. + */ +always @(posedge clk) + if( state != PUSH0 && state != PUSH1 && RDY && + state != PULL0 && state != PULL1 && state != PULL2 ) + begin + ABL <= AB[7:0]; + ABH <= AB[15:8]; + end + +/* + * Data Out MUX + */ +always @* + case( state ) + WRITE: DO = ADD; + + JSR0, + BRK0: DO = PCH; + + JSR1, + BRK1: DO = PCL; + + PUSH1: DO = php ? P : ADD; + + BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; + + default: DO = regfile; + endcase + +/* + * Write Enable Generator + */ + +always @* + case( state ) + BRK0, // writing to stack or memory + BRK1, + BRK2, + JSR0, + JSR1, + PUSH1, + WRITE: WE = 1; + + INDX3, // only if doing a STA, STX or STY + INDY3, + ABSX2, + ABS1, + ZPX1, + ZP0: WE = store; + + default: WE = 0; + endcase + +/* + * register file, contains A, X, Y and S (stack pointer) registers. At each + * cycle only 1 of those registers needs to be accessed, so they combined + * in a small memory, saving resources. + */ + +reg write_register; // set when register file is written + +always @* + case( state ) + DECODE: write_register = load_reg & ~plp; + + PULL1, + RTS2, + RTI3, + BRK3, + JSR0, + JSR2 : write_register = 1; + + default: write_register = 0; + endcase + +/* + * BCD adjust logic + */ + +always @(posedge clk) + adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction + +reg [3:0] ADJL; +reg [3:0] ADJH; + +// adjustment term to be added to ADD[3:0] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// HC : half carry bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, HC} ) + 3'b0xx: ADJL = 4'd0; // no BCD instruction + 3'b100: ADJL = 4'd10; // SBC, and digital borrow + 3'b101: ADJL = 4'd0; // SBC, but no borrow + 3'b110: ADJL = 4'd0; // ADC, but no carry + 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry + endcase +end + +// adjustment term to be added to ADD[7:4] based on the following +// adj_bcd: '1' if doing ADC/SBC with D=1 +// adc_bcd: '1' if doing ADC with D=1 +// CO : carry out bit from ALU +always @* begin + casex( {adj_bcd, adc_bcd, CO} ) + 3'b0xx: ADJH = 4'd0; // no BCD instruction + 3'b100: ADJH = 4'd10; // SBC, and digital borrow + 3'b101: ADJH = 4'd0; // SBC, but no borrow + 3'b110: ADJH = 4'd0; // ADC, but no carry + 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry + endcase +end + +/* + * write to a register. Usually this is the (BCD corrected) output of the + * ALU, but in case of the JSR0 we use the S register to temporarily store + * the PCL. This is possible, because the S register itself is stored in + * the ALU during those cycles. + */ +always @(posedge clk) + if( write_register & RDY ) + AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; + +/* + * register select logic. This determines which of the A, X, Y or + * S registers will be accessed. + */ + +always @* + case( state ) + INDY1, + INDX0, + ZPX0, + ABSX0 : regsel = index_y ? SEL_Y : SEL_X; + + + DECODE : regsel = dst_reg; + + BRK0, + BRK3, + JSR0, + JSR2, + PULL0, + PULL1, + PUSH1, + RTI0, + RTI3, + RTS0, + RTS2 : regsel = SEL_S; + + default: regsel = src_reg; + endcase + +/* + * ALU + */ + +ALU ALU( .clk(clk), + .op(alu_op), + .right(alu_shift_right), + .AI(AI), + .BI(BI), + .CI(CI), + .BCD(adc_bcd & (state == FETCH)), + .CO(CO), + .OUT(ADD), + .V(AV), + .Z(AZ), + .N(AN), + .HC(HC), + .RDY(RDY) ); + +/* + * Select current ALU operation + */ + +always @* + case( state ) + READ: alu_op = op; + + BRA1: alu_op = backwards ? OP_SUB : OP_ADD; + + FETCH, + REG : alu_op = op; + + DECODE, + ABS1: alu_op = 1'bx; + + PUSH1, + BRK0, + BRK1, + BRK2, + JSR0, + JSR1: alu_op = OP_SUB; + + default: alu_op = OP_ADD; + endcase + +/* + * Determine shift right signal to ALU + */ + +always @* + if( state == FETCH || state == REG || state == READ ) + alu_shift_right = shift_right; + else + alu_shift_right = 0; + +/* + * Sign extend branch offset. + */ + +always @(posedge clk) + if( RDY ) + backwards <= DIMUX[7]; + +/* + * ALU A Input MUX + */ + +always @* + case( state ) + JSR1, + RTS1, + RTI1, + RTI2, + BRK1, + BRK2, + INDX1: AI = ADD; + + REG, + ZPX0, + INDX0, + ABSX0, + RTI0, + RTS0, + JSR0, + JSR2, + BRK0, + PULL0, + INDY1, + PUSH0, + PUSH1: AI = regfile; + + BRA0, + READ: AI = DIMUX; + + BRA1: AI = ABH; // don't use PCH in case we're + + FETCH: AI = load_only ? 0 : regfile; + + DECODE, + ABS1: AI = 8'hxx; // don't care + + default: AI = 0; + endcase + + +/* + * ALU B Input mux + */ + +always @* + case( state ) + BRA1, + RTS1, + RTI0, + RTI1, + RTI2, + INDX1, + READ, + REG, + JSR0, + JSR1, + JSR2, + BRK0, + BRK1, + BRK2, + PUSH0, + PUSH1, + PULL0, + RTS0: BI = 8'h00; + + BRA0: BI = PCL; + + DECODE, + ABS1: BI = 8'hxx; + + default: BI = DIMUX; + endcase + +/* + * ALU CI (carry in) mux + */ + +always @* + case( state ) + INDY2, + BRA1, + ABSX1: CI = CO; + + DECODE, + ABS1: CI = 1'bx; + + READ, + REG: CI = rotate ? C : + shift ? 0 : inc; + + FETCH: CI = rotate ? C : + compare ? 1 : + (shift | load_only) ? 0 : C; + + PULL0, + RTI0, + RTI1, + RTI2, + RTS0, + RTS1, + INDY0, + INDX1: CI = 1; + + default: CI = 0; + endcase + +/* + * Processor Status Register update + * + */ + +/* + * Update C flag when doing ADC/SBC, shift/rotate, compare + */ +always @(posedge clk ) + if( shift && state == WRITE ) + C <= CO; + else if( state == RTI2 ) + C <= DIMUX[0]; + else if( ~write_back && state == DECODE ) begin + if( adc_sbc | shift | compare ) + C <= CO; + else if( plp ) + C <= ADD[0]; + else begin + if( sec ) C <= 1; + if( clc ) C <= 0; + end + end + +/* + * Update Z, N flags when writing A, X, Y, Memory, or when doing compare + */ + +always @(posedge clk) + if( state == WRITE ) + Z <= AZ; + else if( state == RTI2 ) + Z <= DIMUX[1]; + else if( state == DECODE ) begin + if( plp ) + Z <= ADD[1]; + else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) + Z <= AZ; + end + +always @(posedge clk) + if( state == WRITE ) + N <= AN; + else if( state == RTI2 ) + N <= DIMUX[7]; + else if( state == DECODE ) begin + if( plp ) + N <= ADD[7]; + else if( (load_reg & (regsel != SEL_S)) | compare ) + N <= AN; + end else if( state == FETCH && bit_ins ) + N <= DIMUX[7]; + +/* + * Update I flag + */ + +always @(posedge clk) + if( state == BRK3 ) + I <= 1; + else if( state == RTI2 ) + I <= DIMUX[2]; + else if( state == REG ) begin + if( sei ) I <= 1; + if( cli ) I <= 0; + end else if( state == DECODE ) + if( plp ) I <= ADD[2]; + +/* + * Update D flag + */ +always @(posedge clk ) + if( state == RTI2 ) + D <= DIMUX[3]; + else if( state == DECODE ) begin + if( sed ) D <= 1; + if( cld ) D <= 0; + if( plp ) D <= ADD[3]; + end + +/* + * Update V flag + */ +always @(posedge clk ) + if( state == RTI2 ) + V <= DIMUX[6]; + else if( state == DECODE ) begin + if( adc_sbc ) V <= AV; + if( clv ) V <= 0; + if( plp ) V <= ADD[6]; + end else if( state == FETCH && bit_ins ) + V <= DIMUX[6]; + +/* + * Instruction decoder + */ + +/* + * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 + * states. In these states, the IR has been prefetched, and there is no + * time to read the IR again before the next decode. + */ + +always @(posedge clk ) + if( reset ) + IRHOLD_valid <= 0; + else if( RDY ) begin + if( state == PULL0 || state == PUSH0 ) begin + IRHOLD <= DIMUX; + IRHOLD_valid <= 1; + end else if( state == DECODE ) + IRHOLD_valid <= 0; + end + +assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : + IRHOLD_valid ? IRHOLD : DIMUX; + +always @(posedge clk ) + if( RDY ) + DIHOLD <= DI; + +assign DIMUX = ~RDY ? DIHOLD : DI; + +/* + * Microcode state machine + */ +always @(posedge clk or posedge reset) + if( reset ) + state <= BRK0; + else if( RDY ) case( state ) + DECODE : + casex ( IR ) + 8'b0000_0000: state <= BRK0; + 8'b0010_0000: state <= JSR0; + 8'b0010_1100: state <= ABS0; // BIT abs + 8'b0100_0000: state <= RTI0; // + 8'b0100_1100: state <= JMP0; + 8'b0110_0000: state <= RTS0; + 8'b0110_1100: state <= JMPI0; + 8'b0x00_1000: state <= PUSH0; + 8'b0x10_1000: state <= PULL0; + 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI + 8'b1xx0_00x0: state <= FETCH; // IMM + 8'b1xx0_1100: state <= ABS0; // X/Y abs + 8'b1xxx_1000: state <= REG; // DEY, TYA, ... + 8'bxxx0_0001: state <= INDX0; + 8'bxxx0_01xx: state <= ZP0; + 8'bxxx0_1001: state <= FETCH; // IMM + 8'bxxx0_1101: state <= ABS0; // even E column + 8'bxxx0_1110: state <= ABS0; // even E column + 8'bxxx1_0000: state <= BRA0; // odd 0 column + 8'bxxx1_0001: state <= INDY0; // odd 1 column + 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns + 8'bxxx1_1001: state <= ABSX0; // odd 9 column + 8'bxxx1_11xx: state <= ABSX0; // odd C, D, E, F columns + 8'bxxxx_1010: state <= REG; // A, TXA, ... NOP + endcase + + ZP0 : state <= write_back ? READ : FETCH; + + ZPX0 : state <= ZPX1; + ZPX1 : state <= write_back ? READ : FETCH; + + ABS0 : state <= ABS1; + ABS1 : state <= write_back ? READ : FETCH; + + ABSX0 : state <= ABSX1; + ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; + ABSX2 : state <= write_back ? READ : FETCH; + + INDX0 : state <= INDX1; + INDX1 : state <= INDX2; + INDX2 : state <= INDX3; + INDX3 : state <= FETCH; + + INDY0 : state <= INDY1; + INDY1 : state <= INDY2; + INDY2 : state <= (CO | store) ? INDY3 : FETCH; + INDY3 : state <= FETCH; + + READ : state <= WRITE; + WRITE : state <= FETCH; + FETCH : state <= DECODE; + + REG : state <= DECODE; + + PUSH0 : state <= PUSH1; + PUSH1 : state <= DECODE; + + PULL0 : state <= PULL1; + PULL1 : state <= PULL2; + PULL2 : state <= DECODE; + + JSR0 : state <= JSR1; + JSR1 : state <= JSR2; + JSR2 : state <= JSR3; + JSR3 : state <= FETCH; + + RTI0 : state <= RTI1; + RTI1 : state <= RTI2; + RTI2 : state <= RTI3; + RTI3 : state <= RTI4; + RTI4 : state <= DECODE; + + RTS0 : state <= RTS1; + RTS1 : state <= RTS2; + RTS2 : state <= RTS3; + RTS3 : state <= FETCH; + + BRA0 : state <= cond_true ? BRA1 : DECODE; + BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; + BRA2 : state <= DECODE; + + JMP0 : state <= JMP1; + JMP1 : state <= DECODE; + + JMPI0 : state <= JMPI1; + JMPI1 : state <= JMP0; + + BRK0 : state <= BRK1; + BRK1 : state <= BRK2; + BRK2 : state <= BRK3; + BRK3 : state <= JMP0; + + endcase + +/* + * Additional control signals + */ + +always @(posedge clk) + if( reset ) + res <= 1; + else if( state == DECODE ) + res <= 0; + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xx01010, // ASLA, ROLA, LSRA, RORA + 8'b0xxxxx01, // ORA, AND, EOR, ADC + 8'b100x10x0, // DEY, TYA, TXA, TXS + 8'b1010xxx0, // LDA/LDX/LDY + 8'b10111010, // TSX + 8'b1011x1x0, // LDX/LDY + 8'b11001010, // DEX + 8'b1x1xxx01, // LDA, SBC + 8'bxxx01000: // DEY, TAY, INY, INX + load_reg <= 1; + + default: load_reg <= 0; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1110_1000, // INX + 8'b1100_1010, // DEX + 8'b101x_xx10: // LDX, TAX, TSX + dst_reg <= SEL_X; + + 8'b0x00_1000, // PHP, PHA + 8'b1001_1010: // TXS + dst_reg <= SEL_S; + + 8'b1x00_1000, // DEY, DEX + 8'b101x_x100, // LDY + 8'b1010_x000: // LDY #imm, TAY + dst_reg <= SEL_Y; + + default: dst_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b1011_1010: // TSX + src_reg <= SEL_S; + + 8'b100x_x110, // STX + 8'b100x_1x10, // TXA, TXS + 8'b1110_xx00, // INX, CPX + 8'b1100_1010: // DEX + src_reg <= SEL_X; + + 8'b100x_x100, // STY + 8'b1001_1000, // TYA + 8'b1100_xx00, // CPY + 8'b1x00_1000: // DEY, INY + src_reg <= SEL_Y; + + default: src_reg <= SEL_A; + endcase + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'bxxx1_0001, // INDY + 8'b10x1_x110, // LDX/STX zpg/abs, Y + 8'bxxxx_1001: // abs, Y + index_y <= 1; + + default: index_y <= 0; + endcase + + +always @(posedge clk) + if( state == DECODE && RDY ) + casex( IR ) + 8'b100x_x1x0, // STX, STY + 8'b100x_xx01: // STA + store <= 1; + + default: store <= 0; + + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xxx_x110, // ASL, ROL, LSR, ROR + 8'b11xx_x110: // DEC/INC + write_back <= 1; + + default: write_back <= 0; + endcase + + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b101x_xxxx: // LDA, LDX, LDY + load_only <= 1; + default: load_only <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b111x_x110, // INC + 8'b11x0_1000: // INX, INY + inc <= 1; + + default: inc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'bx11x_xx01: // SBC, ADC + adc_sbc <= 1; + + default: adc_sbc <= 0; + endcase + +always @(posedge clk ) + if( (state == DECODE || state == BRK0) && RDY ) + casex( IR ) + 8'b011x_xx01: // ADC + adc_bcd <= D; + + default: adc_bcd <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) + 8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc) + shift <= 1; + + default: shift <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b11x0_0x00, // CPX, CPY (imm/zp) + 8'b11x0_1100, // CPX, CPY (abs) + 8'b110x_xx01: // CMP + compare <= 1; + + default: compare <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b01xx_xx10: // ROR, LSR + shift_right <= 1; + + default: shift_right <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0x1x_1010, // ROL A, ROR A + 8'b0x1x_x110: // ROR, ROL + rotate <= 1; + + default: rotate <= 0; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b00xx_xx10: // ROL, ASL + op <= OP_ROL; + + 8'b0010_x100: // BIT zp/abs + op <= OP_AND; + + 8'b01xx_xx10: // ROR, LSR + op <= OP_A; + + 8'b1000_1000, // DEY + 8'b1100_1010, // DEX + 8'b110x_x110, // DEC + 8'b11xx_xx01, // CMP, SBC + 8'b11x0_0x00, // CPX, CPY (imm, zpg) + 8'b11x0_1100: op <= OP_SUB; + + 8'b010x_xx01, // EOR + 8'b00xx_xx01: // ORA, AND + op <= { 2'b11, IR[6:5] }; + + default: op <= OP_ADD; + endcase + +always @(posedge clk ) + if( state == DECODE && RDY ) + casex( IR ) + 8'b0010_x100: // BIT zp/abs + bit_ins <= 1; + + default: bit_ins <= 0; + endcase + +/* + * special instructions + */ +always @(posedge clk ) + if( state == DECODE && RDY ) begin + php <= (IR == 8'h08); + clc <= (IR == 8'h18); + plp <= (IR == 8'h28); + sec <= (IR == 8'h38); + cli <= (IR == 8'h58); + sei <= (IR == 8'h78); + clv <= (IR == 8'hb8); + cld <= (IR == 8'hd8); + sed <= (IR == 8'hf8); + brk <= (IR == 8'h00); + end + +always @(posedge clk) + if( RDY ) + cond_code <= IR[7:5]; + +always @* + case( cond_code ) + 3'b000: cond_true = ~N; + 3'b001: cond_true = N; + 3'b010: cond_true = ~V; + 3'b011: cond_true = V; + 3'b100: cond_true = ~C; + 3'b101: cond_true = C; + 3'b110: cond_true = ~Z; + 3'b111: cond_true = Z; + endcase + + +reg NMI_1 = 0; // delayed NMI signal + +always @(posedge clk) + NMI_1 <= NMI; + +always @(posedge clk ) + if( NMI_edge && state == BRK3 ) + NMI_edge <= 0; + else if( NMI & ~NMI_1 ) + NMI_edge <= 1; + +endmodule diff --git a/Computer_MiST/Acorn - System1/rtl/debounce.vhd b/Computer_MiST/Acorn - System1/rtl/debounce.vhd new file mode 100644 index 00000000..271dc30b --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/debounce.vhd @@ -0,0 +1,58 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: debounce.vhd +-- Dependencies: none +-- Design Software: Quartus II 32-bit Version 11.1 Build 173 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 3/26/2012 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.std_logic_unsigned.all; + +ENTITY debounce IS + GENERIC( + counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal +END debounce; + +ARCHITECTURE logic OF debounce IS + SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops + SIGNAL counter_set : STD_LOGIC; --sync reset to zero + SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output +BEGIN + + counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter + + PROCESS(clk) + BEGIN + IF(clk'EVENT and clk = '1') THEN + flipflops(0) <= button; + flipflops(1) <= flipflops(0); + If(counter_set = '1') THEN --reset counter because input is changing + counter_out <= (OTHERS => '0'); + ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met + counter_out <= counter_out + 1; + ELSE --stable input time is met + result <= flipflops(1); + END IF; + END IF; + END PROCESS; +END logic; diff --git a/Computer_MiST/Acorn - System1/rtl/gen_ram.vhd b/Computer_MiST/Acorn - System1/rtl/gen_ram.vhd new file mode 100644 index 00000000..0794fdc0 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/gen_ram.vhd @@ -0,0 +1,82 @@ +-- ----------------------------------------------------------------------- +-- +-- Syntiac's generic VHDL support files. +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- +-- Modified April 2016 by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +-- Remove address register when writing +-- +-- ----------------------------------------------------------------------- +-- +-- gen_rwram.vhd +-- +-- ----------------------------------------------------------------------- +-- +-- generic ram. +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity gen_ram is + generic ( + dWidth : integer := 8; + aWidth : integer := 10 + ); + port ( + clk : in std_logic; + we : in std_logic; + addr : in std_logic_vector((aWidth-1) downto 0); + d : in std_logic_vector((dWidth-1) downto 0); + q : out std_logic_vector((dWidth-1) downto 0) + ); +end entity; + +-- ----------------------------------------------------------------------- + +architecture rtl of gen_ram is + subtype addressRange is integer range 0 to ((2**aWidth)-1); + type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0); + signal ram: ramDef; + + signal rAddrReg : std_logic_vector((aWidth-1) downto 0); + signal qReg : std_logic_vector((dWidth-1) downto 0); +begin +-- ----------------------------------------------------------------------- +-- Signals to entity interface +-- ----------------------------------------------------------------------- + q <= qReg; + +-- ----------------------------------------------------------------------- +-- Memory write +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if we = '1' then + ram(to_integer(unsigned(addr))) <= d; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Memory read +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then +-- qReg <= ram(to_integer(unsigned(rAddrReg))); +-- rAddrReg <= addr; + qReg <= ram(to_integer(unsigned(addr))); + end if; + end process; +end architecture; + diff --git a/Computer_MiST/Acorn - System1/rtl/m6522.v b/Computer_MiST/Acorn - System1/rtl/m6522.v new file mode 100644 index 00000000..1dc9f617 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/m6522.v @@ -0,0 +1,1074 @@ +// +// A simulation model of VIC20 hardware - VIA implementation +// Copyright (c) MikeJ - March 2003 +// +// 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 vic20@fpgaarcade.com +// +// +// Revision list +// +// version 005 Many fixes to all areas, VIA now passes all VICE tests +// version 004 fixes to PB7 T1 control and Mode 0 Shift Register operation +// version 003 fix reset of T1/T2 IFR flags if T1/T2 is reload via reg5/reg9 from wolfgang (WoS) +// Ported to numeric_std and simulation fix for signal initializations from arnim laeuger +// version 002 fix from Mark McDougall, untested +// version 001 initial release +// not very sure about the shift register, documentation is a bit light. + +module m6522 + ( + input [3:0] I_RS , + input [7:0] I_DATA , + output reg [7:0] O_DATA , + output O_DATA_OE_L , + + input I_RW_L , + input I_CS1 , + input I_CS2_L , + + output O_IRQ_L , // note, not open drain + + // port a + input I_CA1 , + input I_CA2 , + output reg O_CA2 , + output reg O_CA2_OE_L , + + input [7:0] I_PA , + output [7:0] O_PA , + output [7:0] O_PA_OE_L , + + // port b + input I_CB1 , + output O_CB1 , + output O_CB1_OE_L , + + input I_CB2 , + output reg O_CB2 , + output reg O_CB2_OE_L , + + input [7:0] I_PB , + output [7:0] O_PB , + output [7:0] O_PB_OE_L , + + input I_P2_H , // high for phase 2 clock ____////__ + input RESET_L , + input ENA_4 , // clk enable + input CLK + ); + + + + reg [1:0] phase = 2'b00; + reg p2_h_t1; + wire cs; + + // registers + reg [7:0] r_ddra; + reg [7:0] r_ora; + reg [7:0] r_ira; + + reg [7:0] r_ddrb; + reg [7:0] r_orb; + reg [7:0] r_irb; + + reg [7:0] r_t1l_l; + reg [7:0] r_t1l_h; + reg [7:0] r_t2l_l; + reg [7:0] r_t2l_h; // not in real chip + reg [7:0] r_sr; + reg [7:0] r_acr; + reg [7:0] r_pcr; + wire [7:0] r_ifr; + reg [6:0] r_ier; + + reg sr_write_ena; + reg sr_read_ena; + reg ifr_write_ena; + reg ier_write_ena; + wire [7:0] clear_irq; + reg [7:0] load_data; + + // timer 1 + reg [15:0] t1c = 16'hffff; // simulators may not catch up w/o init here... + reg t1c_active; + reg t1c_done; + reg t1_w_reset_int; + reg t1_r_reset_int; + reg t1_load_counter; + reg t1_reload_counter; + reg t1_int_enable = 1'b0; + reg t1_toggle; + reg t1_irq = 1'b0; + reg t1_pb7 = 1'b1; + reg t1_pb7_en_c; + reg t1_pb7_en_d; + + // timer 2 + reg [15:0] t2c = 16'hffff; // simulators may not catch up w/o init here... + reg t2c_active; + reg t2c_done; + reg t2_pb6; + reg t2_pb6_t1; + reg t2_cnt_clk = 1'b1; + reg t2_w_reset_int; + reg t2_r_reset_int; + reg t2_load_counter; + reg t2_reload_counter; + reg t2_int_enable = 1'b0; + reg t2_irq = 1'b0; + reg t2_sr_ena; + + // shift reg + reg [3:0] sr_cnt; + reg sr_cb1_oe_l; + reg sr_cb1_out; + reg sr_drive_cb2; + reg sr_strobe; + reg sr_do_shift = 1'b0; + reg sr_strobe_t1; + reg sr_strobe_falling; + reg sr_strobe_rising; + reg sr_irq; + reg sr_out; + reg sr_active; + + // io + reg w_orb_hs; + reg w_ora_hs; + reg r_irb_hs; + reg r_ira_hs; + + reg ca_hs_sr; + reg ca_hs_pulse; + reg cb_hs_sr; + reg cb_hs_pulse; + + wire cb1_in_mux; + reg ca1_ip_reg_c; + reg ca1_ip_reg_d; + reg cb1_ip_reg_c; + reg cb1_ip_reg_d; + wire ca1_int; + wire cb1_int; + reg ca1_irq; + reg cb1_irq; + + reg ca2_ip_reg_c; + reg ca2_ip_reg_d; + reg cb2_ip_reg_c; + reg cb2_ip_reg_d; + wire ca2_int; + wire cb2_int; + reg ca2_irq; + reg cb2_irq; + + reg final_irq; + + + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + p2_h_t1 <= I_P2_H; + if ((p2_h_t1 == 1'b0) & (I_P2_H == 1'b1)) begin + phase <= 2'b11; + end + else begin + phase <= phase + 1'b1; + end + end + end + + // internal clock phase + assign cs = (I_CS1 == 1'b1 & I_CS2_L == 1'b0 & I_P2_H == 1'b1) ? 1'b1 : 1'b0; + + // peripheral control reg (pcr) + // 0 ca1 interrupt control (0 +ve edge, 1 -ve edge) + // 3..1 ca2 operation + // 000 input -ve edge + // 001 independend interrupt input -ve edge + // 010 input +ve edge + // 011 independend interrupt input +ve edge + // 100 handshake output + // 101 pulse output + // 110 low output + // 111 high output + // 7..4 as 3..0 for cb1,cb2 + + // auxiliary control reg (acr) + // 0 input latch PA (0 disable, 1 enable) + // 1 input latch PB (0 disable, 1 enable) + // 4..2 shift reg control + // 000 disable + // 001 shift in using t2 + // 010 shift in using o2 + // 011 shift in using ext clk + // 100 shift out free running t2 rate + // 101 shift out using t2 + // 101 shift out using o2 + // 101 shift out using ext clk + // 5 t2 timer control (0 timed interrupt, 1 count down with pulses on pb6) + // 7..6 t1 timer control + // 00 timed interrupt each time t1 is loaded pb7 disable + // 01 continuous interrupts pb7 disable + // 00 timed interrupt each time t1 is loaded pb7 one shot output + // 01 continuous interrupts pb7 square wave output + // + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + r_ora <= 8'h00; + r_orb <= 8'h00; + r_ddra <= 8'h00; + r_ddrb <= 8'h00; + r_acr <= 8'h00; + r_pcr <= 8'h00; + w_orb_hs <= 1'b0; + w_ora_hs <= 1'b0; + end else begin + if (ENA_4 == 1'b1) begin + w_orb_hs <= 1'b0; + w_ora_hs <= 1'b0; + if ((cs == 1'b1) & (I_RW_L == 1'b0)) begin + case (I_RS) + 4'h 0 : begin + r_orb <= I_DATA; + w_orb_hs <= 1'b1; + end + + 4'h 1 : begin + r_ora <= I_DATA; + w_ora_hs <= 1'b1; + end + + 4'h 2 : begin + r_ddrb <= I_DATA; + end + + 4'h 3 : begin + r_ddra <= I_DATA; + end + + + 4'h B : begin + r_acr <= I_DATA; + end + + 4'h C : begin + r_pcr <= I_DATA; + end + + 4'h F : begin + r_ora <= I_DATA; + end + endcase + end + + // Set timer PB7 state, only on rising edge of setting ACR(7) + if ((t1_pb7_en_d == 1'b0) & (t1_pb7_en_c == 1'b1)) begin + t1_pb7 <= 1'b1; + end + + if (t1_load_counter) begin + t1_pb7 <= 1'b0; // Reset internal timer 1 PB7 state on every timer load + end else if (t1_toggle == 1'b1) begin + t1_pb7 <= !t1_pb7; + end + end + end + end + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + // The spec says, this is not reset. + // Fact is that the 1541 VIA1 timer won't work, + // as the firmware ONLY sets the r_t1l_h latch!!!! + r_t1l_l <= 8'hff; // All latches default to FFFF + r_t1l_h <= 8'hff; + r_t2l_l <= 8'hff; + r_t2l_h <= 8'hff; + end else begin + if (ENA_4 == 1'b1) begin + t1_w_reset_int <= 1'b0; + t1_load_counter <= 1'b0; + + t2_w_reset_int <= 1'b0; + t2_load_counter <= 1'b0; + + load_data <= 8'h00; + sr_write_ena <= 1'b0; + ifr_write_ena <= 1'b0; + ier_write_ena <= 1'b0; + + if ((cs == 1'b1) & (I_RW_L == 1'b0)) begin + load_data <= I_DATA; + case (I_RS) + 4'h4: begin + r_t1l_l <= I_DATA; + end + + 4'h5: begin + r_t1l_h <= I_DATA; + t1_w_reset_int <= 1'b1; + t1_load_counter <= 1'b1; + end + + 4'h6: begin + r_t1l_l <= I_DATA; + end + + 4'h7: begin + r_t1l_h <= I_DATA; + t1_w_reset_int <= 1'b1; + end + + + 4'h8: begin + r_t2l_l <= I_DATA; + end + + 4'h9: begin + r_t2l_h <= I_DATA; + t2_w_reset_int <= 1'b1; + t2_load_counter <= 1'b1; + end + + 4'hA: begin + sr_write_ena <= 1'b1; + end + + 4'hD: begin + ifr_write_ena <= 1'b1; + end + + 4'hE: begin + ier_write_ena <= 1'b1; + end + + endcase + end + end + end + end + + assign O_DATA_OE_L = (cs == 1'b1 & I_RW_L == 1'b 1) ? 1'b0 : 1'b1; + + reg [7:0] orb; + + always @(*) begin + t1_r_reset_int <= 1'b0; + t2_r_reset_int <= 1'b0; + sr_read_ena <= 1'b0; + r_irb_hs <= 1'b0; + r_ira_hs <= 1'b0; + O_DATA <= 8'h00; // default + + orb = (r_irb & !r_ddrb) | (r_orb & r_ddrb); + + // If PB7 under timer control, assign value from timer + if (t1_pb7_en_d == 1'b1) begin + orb[7] = t1_pb7; + end + + if ((cs == 1'b1) & (I_RW_L == 1'b1)) begin + case (I_RS) + 4'h0: begin + O_DATA <= orb; r_irb_hs <= 1'b1; + end + 4'h1: begin + O_DATA <= (r_ira & !r_ddra) | (r_ora & r_ddra); + r_ira_hs <= 1'b1; + end + 4'h2: begin + O_DATA <= r_ddrb; + end + 4'h3: begin + O_DATA <= r_ddra; + end + 4'h4: begin + O_DATA <= t1c[7:0]; + t1_r_reset_int <= 1'b1; + end + 4'h5: begin + O_DATA <= t1c[15:8]; + end + 4'h6: begin + O_DATA <= r_t1l_l; + end + 4'h7: begin + O_DATA <= r_t1l_h; + end + 4'h8: begin + O_DATA <= t2c[7:0]; + t2_r_reset_int <= 1'b1; + end + 4'h9: begin + O_DATA <= t2c[15:8]; + end + 4'hA: begin + O_DATA <= r_sr; + sr_read_ena <= 1'b1; + end + 4'hB: begin + O_DATA <= r_acr; + end + 4'hC: begin + O_DATA <= r_pcr; + end + 4'hD: begin + O_DATA <= r_ifr; + end + 4'hE: begin + O_DATA <= (1'b0 & r_ier); + end + 4'hF: begin + O_DATA <= r_ira; + end + endcase + end + + end + + // + // IO + // + + + // if the shift register is enabled, cb1 may be an output + // in this case we should NOT listen to the input as + // CB1 interrupts are not generated by the shift register + + assign cb1_in_mux = (sr_cb1_oe_l === 1'b 1) ? I_CB1 : 1'b1; + + // ca1 control + assign ca1_int = (r_pcr[0] == 1'b0) ? + // negative edge + (ca1_ip_reg_d == 1'b1) & (ca1_ip_reg_c == 1'b0) : + // positive edge + (ca1_ip_reg_d == 1'b0) & (ca1_ip_reg_c == 1'b1); + + // cb1 control + assign cb1_int = (r_pcr[4] == 1'b0) ? + // negative edge + (cb1_ip_reg_d == 1'b1) & (cb1_ip_reg_c == 1'b0) : + // positive edge + (cb1_ip_reg_d == 1'b0) & (cb1_ip_reg_c == 1'b1); + + + assign ca2_int = (r_pcr[3] == 1'b1) ? + // ca2 input + 1'b0 : + (r_pcr[2] == 1'b0) ? + // ca2 negative edge + (ca2_ip_reg_d == 1'b1) & (ca2_ip_reg_c == 1'b0) : + // ca2 positive edge + (ca2_ip_reg_d == 1'b0) & (ca2_ip_reg_c == 1'b1); + + + assign cb2_int = (r_pcr[7] == 1'b1) ? + // cb2 input + 1'b0 : + (r_pcr[6] == 1'b0) ? + // cb2 negative edge + (cb2_ip_reg_d == 1'b1) & (cb2_ip_reg_c == 1'b0) : + // cb2 positive edge + (cb2_ip_reg_d == 1'b0) & (cb2_ip_reg_c == 1'b1); + + + + + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + O_CA2 <= 1'b1; // Pullup is default + O_CA2_OE_L <= 1'b1; + O_CB2 <= 1'b1; // Pullup is default + O_CB2_OE_L <= 1'b1; + + ca_hs_sr <= 1'b0; + ca_hs_pulse <= 1'b0; + cb_hs_sr <= 1'b0; + cb_hs_pulse <= 1'b0; + end else begin + if (ENA_4 == 1'b1) begin + // ca + if ((phase == 2'b00) & ((w_ora_hs == 1'b1) | (r_ira_hs == 1'b1))) begin + ca_hs_sr <= 1'b1; + end else if (ca1_int) begin + ca_hs_sr <= 1'b0; + end + + if (phase == 2'b00) begin + ca_hs_pulse <= w_ora_hs | r_ira_hs; + end + + O_CA2_OE_L <= !r_pcr[3]; // ca2 output + case (r_pcr[3:1]) + 3'b000: begin + O_CA2 <= I_CA2; // input, output follows input + end + 3'b001: begin + O_CA2 <= I_CA2; // input, output follows input + end + 3'b010: begin + O_CA2 <= I_CA2; // input, output follows input + end + 3'b011: begin + O_CA2 <= I_CA2; // input, output follows input + end + 3'b100: begin + O_CA2 <= !(ca_hs_sr); // handshake + end + 3'b101: begin + O_CA2 <= !(ca_hs_pulse); // pulse + end + 3'b110: begin + O_CA2 <= 1'b0; // low + end + 3'b111: begin + O_CA2 <= 1'b1; // high + end + endcase + + if ((phase == 2'b00) & (w_orb_hs == 1'b1)) begin + cb_hs_sr <= 1'b1; + end else if (cb1_int) begin + cb_hs_sr <= 1'b0; + end + + if (phase == 2'b00) begin + cb_hs_pulse <= w_orb_hs; + end + + O_CB2_OE_L <= !(r_pcr[7] | sr_drive_cb2); // cb2 output or serial + if (sr_drive_cb2 == 1'b1) begin // serial output + O_CB2 <= sr_out; + end + else begin + case (r_pcr[7:5]) + 3'b000: begin + O_CB2 <= I_CB2; // input, output follows input + end + 3'b001: begin + O_CB2 <= I_CB2; // input, output follows input + end + 3'b010: begin + O_CB2 <= I_CB2; // input, output follows input + end + 3'b011: begin + O_CB2 <= I_CB2; // input, output follows input + end + 3'b100: begin + O_CB2 <= !(cb_hs_sr); // handshake + end + 3'b101: begin + O_CB2 <= !(cb_hs_pulse); // pulse + end + 3'b110: begin + O_CB2 <= 1'b0; // low + end + 3'b111: begin + O_CB2 <= 1'b1; // high + end + endcase + end + end + end + end + + assign O_CB1 = sr_cb1_out; + assign O_CB1_OE_L = sr_cb1_oe_l; + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + ca1_irq <= 1'b0; + ca2_irq <= 1'b0; + cb1_irq <= 1'b0; + cb2_irq <= 1'b0; + end else begin + if (ENA_4 == 1'b1) begin + // not pretty + if (ca1_int) begin + ca1_irq <= 1'b1; + end else if ((r_ira_hs == 1'b1) | (w_ora_hs == 1'b1) | (clear_irq[1] == 1'b1)) begin + ca1_irq <= 1'b0; + end + + if (ca2_int) begin + ca2_irq <= 1'b1; + end + else begin + if ((((r_ira_hs == 1'b1) | (w_ora_hs == 1'b1)) & (r_pcr[1] == 1'b0)) | (clear_irq[0] == 1'b1)) begin + ca2_irq <= 1'b0; + end + end + + if (cb1_int) begin + cb1_irq <= 1'b1; + end else if ((r_irb_hs == 1'b1) | (w_orb_hs == 1'b1) | (clear_irq[4] == 1'b1)) begin + cb1_irq <= 1'b0; + end + + if (cb2_int) begin + cb2_irq <= 1'b1; + end + else begin + if ((((r_irb_hs == 1'b1) | (w_orb_hs == 1'b1)) & (r_pcr[5] == 1'b0)) | (clear_irq[3] == 1'b1)) begin + cb2_irq <= 1'b0; + end + end + end + end + end + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + ca1_ip_reg_c <= 1'b0; + ca1_ip_reg_d <= 1'b0; + + cb1_ip_reg_c <= 1'b0; + cb1_ip_reg_d <= 1'b0; + + ca2_ip_reg_c <= 1'b0; + ca2_ip_reg_d <= 1'b0; + + cb2_ip_reg_c <= 1'b0; + cb2_ip_reg_d <= 1'b0; + + r_ira <= 8'h00; + r_irb <= 8'h00; + + end else begin + if (ENA_4 == 1'b1) begin + // we have a fast clock, so we can have input registers + ca1_ip_reg_c <= I_CA1; + ca1_ip_reg_d <= ca1_ip_reg_c; + + cb1_ip_reg_c <= cb1_in_mux; + cb1_ip_reg_d <= cb1_ip_reg_c; + + ca2_ip_reg_c <= I_CA2; + ca2_ip_reg_d <= ca2_ip_reg_c; + + cb2_ip_reg_c <= I_CB2; + cb2_ip_reg_d <= cb2_ip_reg_c; + + if (r_acr[0] == 1'b0) begin + r_ira <= I_PA; + end + else begin // enable latching + if (ca1_int) begin + r_ira <= I_PA; + end + end + + if (r_acr[1] == 1'b0) begin + r_irb <= I_PB; + end + else begin // enable latching + if (cb1_int) begin + r_irb <= I_PB; + end + end + end + end + end + + + // data direction reg (ddr) 0 = input, 1 = output + assign O_PA = r_ora; + assign O_PA_OE_L = ~r_ddra; + + // If PB7 is timer driven output set PB7 to the timer state, otherwise use value in ORB register + assign O_PB = (t1_pb7_en_d == 1'b1) ? { t1_pb7 , r_orb[6:0]} : r_orb; + + // NOTE: r_ddrb(7) must be set to enable T1 output on PB7 - [various datasheets specify this] + assign O_PB_OE_L = ~r_ddrb; + + // + // Timer 1 + // + + // Detect change in r_acr(7), timer 1 mode for PB7 + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + t1_pb7_en_c <= r_acr[7]; + t1_pb7_en_d <= t1_pb7_en_c; + end + end + + reg p_timer1_done; + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + p_timer1_done = (t1c == 16'h0000); + t1c_done <= p_timer1_done & (phase == 2'b11); + if ((phase == 2'b11) & !t1_load_counter) begin // Don't set reload if T1L-H written + t1_reload_counter <= p_timer1_done; + end else if (t1_load_counter) begin // Cancel a reload when T1L-H written + t1_reload_counter <= 1'b0; + end + if (t1_load_counter) begin // done reset on load! + t1c_done <= 1'b0; + end + end + end + + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + if (t1_load_counter | (t1_reload_counter & phase == 2'b11)) begin + t1c[ 7:0] <= r_t1l_l; + t1c[15:8] <= r_t1l_h; + // There is a need to write to Latch HI to enable interrupts for both continuous and one-shot modes + if (t1_load_counter) begin + t1_int_enable <= 1'b1; + end + end else if (phase == 2'b11) begin + t1c <= t1c - 1'b1; + end + + if (t1_load_counter | t1_reload_counter) begin + t1c_active <= 1'b1; + end else if (t1c_done) begin + t1c_active <= 1'b0; + end + + t1_toggle <= 1'b0; + if (t1c_active & t1c_done) begin + if (t1_int_enable) begin // Set interrupt only if T1L-H has been written + t1_toggle <= 1'b1; + t1_irq <= 1'b1; + if (r_acr[6] == 1'b0) begin // Disable further interrupts if in one shot mode + t1_int_enable <= 1'b0; + end + end + end else if (t1_w_reset_int | t1_r_reset_int | (clear_irq[6] == 1'b1)) begin + t1_irq <= 1'b0; + end + if (t1_load_counter) begin // irq reset on load! + t1_irq <= 1'b0; + end + end + end + + // + // Timer2 + // + + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + if (phase == 2'b01) begin // leading edge p2_h + t2_pb6 <= I_PB[6]; + t2_pb6_t1 <= t2_pb6; + end + end + end + + // Ensure we don't start counting until the P2 clock after r_acr is changed + always @(posedge I_P2_H) begin + if (r_acr[5] == 1'b0) begin + t2_cnt_clk <= 1'b1; + end + else begin + t2_cnt_clk <= 1'b0; + end + end + + reg p_timer2_done; + reg p_timer2_done_sr; + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + p_timer2_done = (t2c == 16'h0000); // Normal timer expires at 0000 + p_timer2_done_sr = (t2c[7:0] == 8'h00); // Shift register expires on low byte == 00 + t2c_done <= p_timer2_done & (phase == 2'b11); + if (phase == 2'b11) begin + t2_reload_counter <= p_timer2_done_sr; // Timer 2 is only reloaded when used for the shift register + end + if (t2_load_counter) begin // done reset on load! + t2c_done <= 1'b0; + end + end + end + + reg p_timer2_ena; + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + if (t2_cnt_clk == 1'b1) begin + p_timer2_ena = 1'b1; + t2c_active <= 1'b1; + t2_int_enable <= 1'b1; + end + else begin + p_timer2_ena = (t2_pb6_t1 == 1'b1) & (t2_pb6 == 1'b0); // falling edge + end + + // Shift register reload is only active when shift register mode using T2 is enabled + if (t2_reload_counter & (phase == 2'b11) & ((r_acr[4:2] == 3'b001) | (r_acr[4:2] == 3'b100) | (r_acr[4:2] == 3'b101))) begin + t2c[7:0] <= r_t2l_l; // For shift register only low latch is loaded! + end else if (t2_load_counter) begin + t2_int_enable <= 1'b1; + t2c[ 7:0] <= r_t2l_l; + t2c[15:8] <= r_t2l_h; + end + else begin + if ((phase == 2'b11) & p_timer2_ena) begin // or count mode + t2c <= t2c - 1'b1; + end + end + + // Shift register strobe on T2 occurs one P2H clock after timer expires + // so enable the strobe when we roll over to FF + t2_sr_ena <= (t2c[7:0] == 8'hFF) & (phase == 2'b11); + + if (t2_load_counter) begin + t2c_active <= 1'b1; + end else if (t2c_done) begin + t2c_active <= 1'b0; + end + + if (t2c_active & t2c_done & t2_int_enable) begin + t2_int_enable <= 1'b0; + t2_irq <= 1'b1; + end else if (t2_w_reset_int | t2_r_reset_int | (clear_irq[5] == 1'b1)) begin + t2_irq <= 1'b0; + end + if (t2_load_counter) begin // irq reset on load! + t2_irq <= 1'b0; + end + end + end + + // + // Shift Register + // + + reg sr_dir_out ; + reg sr_ena ; + reg sr_cb1_op ; + reg sr_cb1_ip ; + reg sr_use_t2 ; + reg sr_free_run ; + reg sr_count_ena ; + + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + r_sr <= 8'h00; + sr_drive_cb2 <= 1'b0; + sr_cb1_oe_l <= 1'b1; + sr_cb1_out <= 1'b0; + sr_do_shift <= 1'b0; + sr_strobe <= 1'b1; + sr_cnt <= 4'b0000; + sr_irq <= 1'b0; + sr_out <= 1'b0; + sr_active <= 1'b0; + end else begin + if (ENA_4 == 1'b1) begin + // decode mode + sr_dir_out = r_acr[4]; // output on cb2 + sr_cb1_op = 1'b0; + sr_cb1_ip = 1'b0; + sr_use_t2 = 1'b0; + sr_free_run = 1'b0; + + // DMB: SR still runs even in disabled mode (on rising edge of CB1). + // It just doesn't generate any interrupts. + // Ref BBC micro advanced user guide p409 + + case (r_acr[4:2]) + // DMB: in disabled mode, configure cb1 as an input + 3'b000: begin + sr_ena = 1'b0; sr_cb1_ip = 1'b1; // 0x00 Mode 0 SR disabled + end + 3'b001: begin + sr_ena = 1'b1; sr_cb1_op = 1'b1; sr_use_t2 = 1'b1; // 0x04 Mode 1 Shift in under T2 control + end + 3'b010: begin + sr_ena = 1'b1; sr_cb1_op = 1'b1; // 0x08 Mode 2 Shift in under P2 control + end + 3'b011: begin + sr_ena = 1'b1; sr_cb1_ip = 1'b1; // 0x0C Mode 3 Shift in under control of ext clock + end + 3'b100: begin + sr_ena = 1'b1; sr_cb1_op = 1'b1; sr_use_t2 = 1'b1; sr_free_run = 1'b1; // 0x10 Mode 4 Shift out free running under T2 control + end + 3'b101: begin + sr_ena = 1'b1; sr_cb1_op = 1'b1; sr_use_t2 = 1'b1; // 0x14 Mode 5 Shift out under T2 control + end + 3'b110: begin + sr_ena = 1'b1; sr_cb1_op = 1'b1; // 0x18 Mode 6 Shift out under P2 control + end + 3'b111: begin + sr_ena = 1'b1; sr_cb1_ip = 1'b1; // 0x1C Mode 7 Shift out under control of ext clock + end + endcase + + // clock select + // DMB: in disabled mode, strobe from cb1 + if (sr_cb1_ip == 1'b1) begin + sr_strobe <= I_CB1; + end + else begin + if ((sr_cnt[3] == 1'b0) & (sr_free_run == 1'b0)) begin + sr_strobe <= 1'b1; + end + else begin + if (((sr_use_t2 == 1'b1) & t2_sr_ena) | + ((sr_use_t2 == 1'b0) & (phase == 2'b00))) begin + sr_strobe <= !sr_strobe; + end + end + end + + // latch on rising edge, shift on falling edge of P2 + if (sr_write_ena) begin + r_sr <= load_data; + sr_out <= r_sr[7]; + + end + else begin + // DMB: allow shifting in all modes + if (sr_dir_out == 1'b0) begin + // input + if ((sr_cnt[3] == 1'b1) | (sr_cb1_ip == 1'b1)) begin + if (sr_strobe_rising) begin + sr_do_shift <= 1'b1; + r_sr[0] <= I_CB2; + end else if (sr_do_shift) begin + sr_do_shift <= 1'b0; + r_sr[7:1] <= r_sr[6:0]; + end + end + end + else begin + // output + if ((sr_cnt[3] == 1'b1) | (sr_cb1_ip == 1'b1) | (sr_free_run == 1'b1)) begin + if (sr_strobe_falling) begin + sr_out <= r_sr[7]; + sr_do_shift <= 1'b1; + end else if (sr_do_shift) begin + sr_do_shift <= 1'b0; + r_sr <= r_sr[6:0] & r_sr[7]; + end + end + end + end + + // Set shift enabled flag, note does not get set for free_run mode ! + if ((sr_ena == 1'b1) & (sr_cnt[3] == 1'b1)) begin + sr_active <= 1'b1; + end else if ((sr_ena == 1'b1) & (sr_cnt[3] == 1'b0) & (phase == 2'b11)) begin + sr_active <= 1'b0; + end + + sr_count_ena = sr_strobe_rising; + + // DMB: reseting sr_count when not enabled cause the sr to + // start running immediately it was enabled, which is incorrect + // and broke the latest SmartSPI ROM on the BBC Micro + if ((sr_ena == 1'b1) & (sr_write_ena | sr_read_ena) & (!sr_active)) begin + // some documentation says sr bit in IFR must be set as well ? + sr_cnt <= 4'b1000; + end else if (sr_count_ena & (sr_cnt[3] == 1'b1)) begin + sr_cnt <= sr_cnt + 1'b1; + end + + if (sr_count_ena & (sr_cnt == 4'b1111) & (sr_ena == 1'b1) & (sr_free_run == 1'b0)) begin + sr_irq <= 1'b1; + end else if (sr_write_ena | sr_read_ena | (clear_irq[2] == 1'b1)) begin + sr_irq <= 1'b0; + end + + // assign ops + sr_drive_cb2 <= sr_dir_out; + sr_cb1_oe_l <= !sr_cb1_op; + sr_cb1_out <= sr_strobe; + end + end + end + + always @(posedge CLK) begin + if (ENA_4 == 1'b1) begin + sr_strobe_t1 <= sr_strobe; + sr_strobe_rising <= (sr_strobe_t1 == 1'b0) & (sr_strobe == 1'b1); + sr_strobe_falling <= (sr_strobe_t1 == 1'b1) & (sr_strobe == 1'b0); + end + end + + // + // Interrupts + // + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + r_ier <= 7'b0000000; + end else begin + if (ENA_4 == 1'b1) begin + if (ier_write_ena) begin + if (load_data[7] == 1'b1) begin + // set + r_ier <= r_ier | load_data[6:0]; + end + else begin + // clear + r_ier <= r_ier & !load_data[6:0]; + end + end + end + end + end + + assign O_IRQ_L = ~final_irq; + + assign r_ifr = {final_irq, t1_irq, t2_irq, cb1_irq, cb2_irq, sr_irq, ca1_irq, ca2_irq}; + + + always @(posedge CLK, negedge RESET_L) begin + if (RESET_L == 1'b0) begin + final_irq <= 1'b0; + end else begin + if (ENA_4 == 1'b1) begin + if ((r_ifr[6:0] & r_ier[6:0]) == 7'b0000000) begin + final_irq <= 1'b0; // no interrupts + end + else begin + final_irq <= 1'b1; + end + end + end + end + + assign clear_irq = ifr_write_ena ? load_data : 8'h00; + +endmodule diff --git a/Computer_MiST/Acorn - System1/rtl/pll.ppf b/Computer_MiST/Acorn - System1/rtl/pll.ppf new file mode 100644 index 00000000..71e6f03a --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/pll.ppf @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Computer_MiST/Acorn - System1/rtl/pll.qip b/Computer_MiST/Acorn - System1/rtl/pll.qip new file mode 100644 index 00000000..afd958be --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/pll.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/Computer_MiST/Acorn - System1/rtl/pll.v b/Computer_MiST/Acorn - System1/rtl/pll.v new file mode 100644 index 00000000..fb0f488a --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/pll.v @@ -0,0 +1,329 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll ( + inclk0, + c0, + c1); + + input inclk0; + output c0; + output c1; + + wire [4:0] sub_wire0; + wire [0:0] sub_wire5 = 1'h0; + wire [1:1] sub_wire2 = sub_wire0[1:1]; + wire [0:0] sub_wire1 = sub_wire0[0:0]; + wire c0 = sub_wire1; + wire c1 = sub_wire2; + wire sub_wire3 = inclk0; + wire [1:0] sub_wire4 = {sub_wire5, sub_wire3}; + + altpll altpll_component ( + .inclk (sub_wire4), + .clk (sub_wire0), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .locked (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 255, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 236, + altpll_component.clk0_phase_shift = "0", + altpll_component.clk1_divide_by = 54, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 25, + altpll_component.clk1_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_UNUSED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "255" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "54" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "24.988235" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.500000" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "236" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "25" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.50000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLK1 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "255" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "236" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "54" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "25" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Computer_MiST/Acorn - System1/rtl/ps2_mouse.v b/Computer_MiST/Acorn - System1/rtl/ps2_mouse.v new file mode 100644 index 00000000..f60909f5 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/ps2_mouse.v @@ -0,0 +1,78 @@ +`timescale 1ns / 100ps + +// Dave Wood (oldgit) 2019 code taken from muliple sources +// thanks to the original designers. I just glue bits together. + +/* + * PS2 mouse protocol + * Bit 7 6 5 4 3 2 1 0 + * Byte 0: YOVR XOVR YSGN XSGN 1 MBUT RBUT LBUT + * Byte 1: XMOVE + * Byte 2: YMOVE + */ + +/* + * simple PS2 Mouse interface module + * starts with mouse pos(0,0) and keeps mouse location and updates. output is mouse pos(0--636/0--476) ! pos less 4 pixels for size + * mouse buttons 0 by default and 1 when pressed + */ +module ps2_mouse +( + input clk, + input ce, + + input reset, + + input [24:0] ps2_mouse, + + output reg [10:0] mx, my, + output reg mbtnL, + output reg mbtnR, + output reg mbtnM +); + +wire strobe = (old_stb != ps2_mouse[24]); +reg old_stb = 0; +always @(posedge clk) old_stb <= ps2_mouse[24]; + +/* Capture buttons state */ +always@(posedge clk or posedge reset) begin + if (reset) begin + mbtnL <= 1'b0; + mbtnR <= 1'b0; + mbtnM <= 1'b0; + end else if (strobe) begin + mbtnL <= ps2_mouse[0]; + mbtnR <= ps2_mouse[1]; + mbtnM <= ps2_mouse[2]; + end +end + // module parameters + parameter MAX_X = 635; + parameter MAX_Y = 475; + + // low level mouse driver + + wire [8:0] dx, dy; + + // Update "absolute" position of mouse + + wire sx = ps2_mouse[4]; // signs + wire sy = ps2_mouse[5]; + wire [8:0] ndx = sx ? {1'b0,~ps2_mouse[15:8]}+9'b000000001 : {1'b0,ps2_mouse[15:8]}; // magnitudes + wire [8:0] ndy = sy ? {1'b0,~ps2_mouse[23:16]}+9'b000000001 : {1'b0,ps2_mouse[23:16]}; + + always @(posedge clk) begin + mx <= reset ? 0 : + strobe ? (sx ? (mx>ndx ? mx - ndx : 0) + : (mx < MAX_X - ndx ? mx+ndx : MAX_X)) : mx; + // note Y is flipped for video cursor use of mouse + my <= reset ? 0 : + strobe ? (sy ? (my < MAX_Y - ndy ? my+ndy : MAX_Y) + : (my>ndy ? my - ndy : 0)) : my; +// strobe ? (sy ? (my>ndy ? my - ndy : 0) +// : (my < MAX_Y - ndy ? my+ndy : MAX_Y)) : my; + end + + +endmodule diff --git a/Computer_MiST/Acorn - System1/rtl/ps2_mouse.vhd b/Computer_MiST/Acorn - System1/rtl/ps2_mouse.vhd new file mode 100644 index 00000000..4c481b95 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/ps2_mouse.vhd @@ -0,0 +1,173 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: ps2_mouse.vhd +-- Dependencies: ps2_transceiver.vhd, debounce.vhd +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 2/16/2018 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY ps2_mouse IS + GENERIC( + clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock input + reset_n : IN STD_LOGIC; --active low asynchronous reset + ps2_clk : INOUT STD_LOGIC; --clock signal from PS2 mouse + ps2_data : INOUT STD_LOGIC; --data signal from PS2 mouse + mouse_data : OUT STD_LOGIC_VECTOR(23 DOWNTO 0); --data received from mouse + mouse_data_new : OUT STD_LOGIC); --new data packet available flag +END ps2_mouse; + +ARCHITECTURE logic OF ps2_mouse IS + TYPE machine IS(reset, rx_ack1, rx_bat, rx_id, ena_reporting, rx_ack2, stream); --needed states + SIGNAL state : machine := reset; --state machine + SIGNAL tx_ena : STD_LOGIC := '0'; --transmit enable for ps2_transceiver + SIGNAL tx_cmd : STD_LOGIC_VECTOR(8 DOWNTO 0); --command to transmit + SIGNAL tx_busy : STD_LOGIC; --ps2_transceiver busy signal + SIGNAL ps2_code : STD_LOGIC_VECTOR(7 DOWNTO 0); --PS/2 code received from ps2_transceiver + SIGNAL ps2_code_new : STD_LOGIC; --new PS/2 code available flag from ps2_transceiver + SIGNAL ps2_code_new_prev : STD_LOGIC; --previous value of ps2_code_new + SIGNAL packet_byte : INTEGER RANGE 0 TO 2 := 2; --counter to track which packet byte is being received + SIGNAL mouse_data_int : STD_LOGIC_VECTOR(23 DOWNTO 0); --internal mouse data register + + --component to control PS/2 bus interface to the mouse + COMPONENT ps2_transceiver IS + GENERIC( + clk_freq : INTEGER; --system clock frequency in Hz + debounce_counter_size : INTEGER); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock + reset_n : IN STD_LOGIC; --active low asynchronous reset + tx_ena : IN STD_LOGIC; --enable transmit + tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit + tx_busy : OUT STD_LOGIC; --indicates transmit in progress + ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error + ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 bus + ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus + rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error + ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal + ps2_data : INOUT STD_LOGIC); --PS/2 port data signal + END COMPONENT; + +BEGIN + + --PS/2 transceiver to control transactions with mouse + ps2_transceiver_0: ps2_transceiver + GENERIC MAP(clk_freq => clk_freq, debounce_counter_size => ps2_debounce_counter_size) + PORT MAP(clk => clk, reset_n => reset_n, tx_ena => tx_ena, tx_cmd => tx_cmd, tx_busy => tx_busy, ack_error => OPEN, + ps2_code => ps2_code, ps2_code_new => ps2_code_new, rx_error => OPEN, ps2_clk => ps2_clk, ps2_data => ps2_data); + + + PROCESS(clk, reset_n) + BEGIN + IF(reset_n = '0') THEN --asynchronous reset + mouse_data_new <= '0'; --clear new mouse data available flag + mouse_data <= (OTHERS => '0'); --clear last mouse data packet received + state <= reset; --set state machine to reset the mouse + ELSIF(clk'EVENT AND clk = '1') THEN + ps2_code_new_prev <= ps2_code_new; --store previous value of the new PS/2 code flag + + CASE state IS + + WHEN reset => + IF(tx_busy = '0') THEN --transmit to mouse not yet in process + tx_ena <= '1'; --enable transmit to PS/2 mouse + tx_cmd <= "111111111"; --send reset command (0xFF) + state <= reset; --remain in reset state + ELSIF(tx_busy = '1') THEN --transmit to mouse is in process + tx_ena <= '0'; --clear transmit enable + state <= rx_ack1; --wait to receive an acknowledge from mouse + END IF; + + WHEN rx_ack1 => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) + state <= rx_bat; --wait to receive new BAT completion code + ELSE --new PS/2 code was not an acknowledge + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_ack1; --wait to receive a code from mouse + END IF; + + WHEN rx_bat => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "10101010") THEN --new PS/2 code is BAT completion (0xAA) + state <= rx_id; --wait to receive device ID code + ELSE --new PS/2 code was not BAT completion + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_bat; --wait to receive a code from mouse + END IF; + + WHEN rx_id => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "00000000") THEN --new PS/2 code is a mouse device ID (0x00) + state <= ena_reporting; --send command to enable data reporting + ELSE --new PS/2 code is not a mouse device ID + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_id; --wait to receive a code from mouse + END IF; + + WHEN ena_reporting => + IF(tx_busy = '0') THEN --transmit to mouse not yet in process + tx_ena <= '1'; --enable transmit to PS/2 mouse + tx_cmd <= "011110100"; --send enable reporting command (0xF4) + state <= ena_reporting; --remain in ena_reporting state + ELSIF(tx_busy = '1') THEN --transmit to mouse is in process + tx_ena <= '0'; --clear transmit enable + state <= rx_ack2; --wait to receive an acknowledge from mouse + END IF; + + WHEN rx_ack2 => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) + state <= stream; --proceed to collect and output data from mouse + ELSE --new PS/2 code was not an acknowledge + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_ack2; --wait to receive a code from mouse + END IF; + + WHEN stream => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + mouse_data_new <= '0'; --clear new data packet available flag + mouse_data_int(7+packet_byte*8 DOWNTO packet_byte*8) <= ps2_code; --store new mouse data byte + IF(packet_byte = 0) THEN --all bytes in packet received and presented + packet_byte <= 2; --clear packet byte counter + ELSE --not all bytes in packet received yet + packet_byte <= packet_byte - 1; --increment packet byte counter + END IF; + END IF; + IF(ps2_code_new_prev = '1' AND ps2_code_new = '1' AND packet_byte = 2) THEN --mouse data receive is complete + mouse_data <= mouse_data_int; --present new mouse data at output + mouse_data_new <= '1'; --set new data packet available flag + END IF; + + END CASE; + END IF; + END PROCESS; + +END logic; \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/rtl/ps2_transceiver.vhd b/Computer_MiST/Acorn - System1/rtl/ps2_transceiver.vhd new file mode 100644 index 00000000..0e385877 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/ps2_transceiver.vhd @@ -0,0 +1,181 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: ps2_transceiver.vhd +-- Dependencies: debounce.vhd +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 1/19/2018 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY ps2_transceiver IS + GENERIC( + clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock + reset_n : IN STD_LOGIC; --active low asynchronous reset + tx_ena : IN STD_LOGIC; --enable transmit + tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit + tx_busy : OUT STD_LOGIC; --indicates transmit in progress + ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error + ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 + ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus + rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error + ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal + ps2_data : INOUT STD_LOGIC); --PS/2 port data signal +END ps2_transceiver; + +ARCHITECTURE logic OF ps2_transceiver IS + TYPE machine IS(receive, inhibit, transact, tx_complete); --needed states + SIGNAL state : machine := receive; --state machine + SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals + SIGNAL ps2_clk_int : STD_LOGIC; --debounced input clock signal from PS/2 port + SIGNAL ps2_clk_int_prev : STD_LOGIC; --previous state of the ps2_clk_int signal + SIGNAL ps2_data_int : STD_LOGIC; --debounced input data signal from PS/2 port + SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word (both tx and rx) + SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits for received data + SIGNAL timer : INTEGER RANGE 0 TO clk_freq/10_000 := 0; --counter to determine both inhibit period and when PS/2 is idle + SIGNAL bit_cnt : INTEGER RANGE 0 TO 11 := 0; --count the number of clock pulses during transmit + + --declare debounce component for debouncing PS2 input signals + COMPONENT debounce IS + GENERIC( + counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal + END COMPONENT; +BEGIN + + --synchronizer flip-flops + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal + sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal + END IF; + END PROCESS; + + --debounce PS2 input signals + debounce_ps2_clk: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int); + debounce_ps2_data: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int); + + --verify that parity, start, and stop bits are all correct for received data + error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR + ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR + ps2_word(2) XOR ps2_word(1))); + + --state machine to control transmit and receive processes + PROCESS(clk, reset_n) + BEGIN + IF(reset_n = '0') THEN --reset PS/2 transceiver + ps2_clk <= '0'; --inhibit communication on PS/2 bus + ps2_data <= 'Z'; --release PS/2 data line + tx_busy <= '1'; --indicate that no transmit is in progress + ack_error <= '0'; --clear acknowledge error flag + ps2_code <= (OTHERS => '0'); --clear received PS/2 code + ps2_code_new <= '0'; --clear new received PS/2 code flag + rx_error <= '0'; --clear receive error flag + state <= receive; --set state machine to receive state + ELSIF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + ps2_clk_int_prev <= ps2_clk_int; --store previous value of the PS/2 clock signal + CASE state IS --implement state machine + + WHEN receive => + IF(tx_ena = '1') THEN --transmit requested + tx_busy <= '1'; --indicate transmit in progress + timer <= 0; --reset timer for inhibit timing + ps2_word(9 DOWNTO 0) <= tx_cmd & '0'; --load parity, command, and start bit into PS/2 data buffer + bit_cnt <= 0; --clear bit counter + state <= inhibit; --inhibit communication to begin transaction + ELSE --transmit not requested + tx_busy <= '0'; --indicate no transmit in progress + ps2_clk <= 'Z'; --release PS/2 clock port + ps2_data <= 'Z'; --release PS/2 data port + --clock in receive data + IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock + ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer + END IF; + --determine if PS/2 port is idle + IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active + timer <= 0; --reset idle counter + ELSIF(timer < clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us) + timer <= timer + 1; --continue counting + END IF; + --output received data and port status + IF(timer = clk_freq/18_000) THEN --idle threshold reached + IF(error = '0') THEN --no error detected + ps2_code_new <= '1'; --set flag that new PS/2 code is available + ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code + ELSIF(error = '1') THEN --error detected + rx_error <= '1'; --set receive error flag + END IF; + ELSE --PS/2 port active + rx_error <= '0'; --clear receive error flag + ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress + END IF; + state <= receive; --continue streaming receive transactions + END IF; + + WHEN inhibit => + IF(timer < clk_freq/10_000) THEN --first 100us not complete + timer <= timer + 1; --increment timer + ps2_data <= 'Z'; --release data port + ps2_clk <= '0'; --inhibit communication + state <= inhibit; --continue inhibit + ELSE --100us complete + ps2_data <= ps2_word(0); --output start bit to PS/2 data port + state <= transact; --proceed to send bits + END IF; + + WHEN transact => + ps2_clk <= 'Z'; --release clock port + IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock + ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer + bit_cnt <= bit_cnt + 1; --count clock falling edges + END IF; + IF(bit_cnt < 10) THEN --all bits not sent + ps2_data <= ps2_word(0); --connect serial output of PS/2 data buffer to data port + ELSE --all bits sent + ps2_data <= 'Z'; --release data port + END IF; + IF(bit_cnt = 11) THEN --acknowledge bit received + ack_error <= ps2_data_int; --set error flag if acknowledge is not '0' + state <= tx_complete; --proceed to wait until the slave releases the bus + ELSE --acknowledge bit not received + state <= transact; --continue transaction + END IF; + + WHEN tx_complete => + IF(ps2_clk_int = '1' AND ps2_data_int = '1') THEN --device has released the bus + state <= receive; --proceed to receive data state + ELSE --bus not released by device + state <= tx_complete; --wait for device to release bus + END IF; + + END CASE; + END IF; + END PROCESS; + +END logic; \ No newline at end of file diff --git a/Computer_MiST/Acorn - System1/rtl/roms/ONE.mif b/Computer_MiST/Acorn - System1/rtl/roms/ONE.mif new file mode 100644 index 00000000..d51c8da2 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/roms/ONE.mif @@ -0,0 +1,53 @@ +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec -o --mif +-- +DEPTH = 1024; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +00A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +00D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +02A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +02B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +02D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +02E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +03A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +03C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +03D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +03F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +END; diff --git a/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.bin b/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.bin new file mode 100644 index 00000000..da655178 Binary files /dev/null and b/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.bin differ diff --git a/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.vhd b/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.vhd new file mode 100644 index 00000000..81976e40 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/roms/acrnsys1.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all,ieee.numeric_std.all; + +entity acrnsys1 is +port ( + clk : in std_logic; + addr : in std_logic_vector(8 downto 0); + data : out std_logic_vector(7 downto 0) +); +end entity; + +architecture prom of acrnsys1 is + type rom is array(0 to 511) of std_logic_vector(7 downto 0); + signal rom_data: rom := ( + X"A0",X"06",X"B5",X"00",X"20",X"6F",X"FE",X"CA",X"88",X"88",X"10",X"F6",X"86",X"1A",X"A2",X"07", + X"8E",X"22",X"0E",X"A0",X"00",X"B5",X"10",X"8D",X"21",X"0E",X"8E",X"20",X"0E",X"AD",X"20",X"0E", + X"29",X"3F",X"24",X"0F",X"10",X"18",X"C9",X"38",X"B0",X"06",X"86",X"19",X"A9",X"40",X"85",X"0F", + X"A1",X"00",X"88",X"D0",X"FB",X"CA",X"10",X"DB",X"A5",X"0E",X"30",X"D2",X"10",X"14",X"E4",X"19", + X"D0",X"EE",X"C9",X"38",X"90",X"04",X"A9",X"80",X"D0",X"E4",X"C5",X"0F",X"F0",X"E2",X"85",X"0F", + X"49",X"38",X"29",X"1F",X"C9",X"10",X"85",X"0D",X"A6",X"1A",X"8C",X"21",X"0E",X"60",X"A1",X"00", + X"A0",X"06",X"D0",X"0B",X"A0",X"03",X"B5",X"00",X"20",X"6F",X"FE",X"88",X"88",X"B5",X"01",X"C8", + X"48",X"20",X"7A",X"FE",X"88",X"68",X"4A",X"4A",X"4A",X"4A",X"84",X"1A",X"29",X"0F",X"A8",X"B9", + X"EA",X"FF",X"A4",X"1A",X"99",X"10",X"00",X"60",X"20",X"64",X"FE",X"20",X"0C",X"FE",X"B0",X"20", + X"A0",X"04",X"0A",X"0A",X"0A",X"0A",X"0A",X"36",X"00",X"36",X"01",X"88",X"D0",X"F8",X"F0",X"E8", + X"F6",X"06",X"D0",X"02",X"F6",X"07",X"B5",X"06",X"D5",X"08",X"D0",X"04",X"B5",X"07",X"D5",X"09", + X"60",X"A0",X"40",X"8C",X"22",X"0E",X"A0",X"07",X"8C",X"20",X"0E",X"6A",X"6A",X"20",X"CD",X"FE", + X"6A",X"8D",X"20",X"0E",X"88",X"10",X"F6",X"20",X"CD",X"FE",X"8C",X"20",X"0E",X"20",X"D0",X"FE", + X"84",X"1A",X"A0",X"48",X"88",X"D0",X"FD",X"88",X"D0",X"FD",X"A4",X"1A",X"60",X"A0",X"08",X"2C", + X"20",X"0E",X"30",X"FB",X"20",X"D0",X"FE",X"20",X"CD",X"FE",X"0E",X"20",X"0E",X"6A",X"88",X"D0", + X"F6",X"F0",X"DA",X"A2",X"FF",X"9A",X"8E",X"23",X"0E",X"86",X"0E",X"A0",X"80",X"A2",X"09",X"94", + X"0E",X"CA",X"D0",X"FB",X"20",X"0C",X"FE",X"90",X"F2",X"29",X"07",X"C9",X"04",X"90",X"25",X"F0", + X"6F",X"C9",X"06",X"F0",X"09",X"B0",X"0F",X"A5",X"0A",X"A6",X"0B",X"A4",X"0C",X"40",X"F6",X"00", + X"D0",X"0C",X"F6",X"01",X"B0",X"08",X"B5",X"00",X"D0",X"02",X"D6",X"01",X"D6",X"00",X"20",X"64", + X"FE",X"4C",X"45",X"FF",X"84",X"16",X"84",X"17",X"0A",X"AA",X"49",X"F7",X"85",X"10",X"20",X"88", + X"FE",X"E0",X"02",X"B0",X"15",X"20",X"5E",X"FE",X"20",X"0C",X"FE",X"B0",X"BC",X"A1",X"00",X"0A", + X"0A",X"0A",X"0A",X"05",X"0D",X"81",X"00",X"4C",X"45",X"FF",X"D0",X"03",X"6C",X"02",X"00",X"E0", + X"04",X"F0",X"36",X"A2",X"08",X"86",X"10",X"20",X"88",X"FE",X"A2",X"04",X"B5",X"05",X"20",X"B1", + X"FE",X"CA",X"D0",X"F8",X"A1",X"06",X"20",X"B1",X"FE",X"20",X"A0",X"FE",X"D0",X"F6",X"F0",X"2A", + X"A2",X"04",X"20",X"DD",X"FE",X"95",X"05",X"CA",X"D0",X"F8",X"20",X"DD",X"FE",X"81",X"06",X"8D", + X"21",X"0E",X"20",X"A0",X"FE",X"D0",X"F3",X"F0",X"11",X"A1",X"00",X"F0",X"06",X"85",X"18",X"A9", + X"00",X"F0",X"02",X"A5",X"18",X"81",X"00",X"20",X"5E",X"FE",X"4C",X"04",X"FF",X"6C",X"1C",X"00", + X"6C",X"1E",X"00",X"85",X"0A",X"86",X"0B",X"84",X"0C",X"68",X"48",X"85",X"0D",X"A2",X"0D",X"A9", + X"FF",X"85",X"0E",X"20",X"00",X"FE",X"BA",X"86",X"13",X"C8",X"84",X"12",X"D8",X"BD",X"02",X"01", + X"38",X"E5",X"1B",X"9D",X"02",X"01",X"85",X"11",X"BD",X"03",X"01",X"E9",X"00",X"9D",X"03",X"01", + X"85",X"10",X"A2",X"13",X"20",X"00",X"FE",X"4C",X"07",X"FF",X"3F",X"06",X"5B",X"4F",X"66",X"6D", + X"7D",X"07",X"7F",X"6F",X"77",X"7C",X"58",X"5E",X"79",X"71",X"AD",X"FF",X"F3",X"FE",X"B0",X"FF"); +begin +process(clk) +begin + if rising_edge(clk) then + data <= rom_data(to_integer(unsigned(addr))); + end if; +end process; +end architecture; diff --git a/Computer_MiST/Acorn - System1/rtl/roms/monitor.mif b/Computer_MiST/Acorn - System1/rtl/roms/monitor.mif new file mode 100644 index 00000000..f638fc1b --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/roms/monitor.mif @@ -0,0 +1,32 @@ +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec -o --mif +-- +DEPTH = 512; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: A0 06 B5 00 20 6F FE CA 88 88 10 F6 86 1A A2 07 8E 22 0E A0 00 B5 10 8D; +0018: 21 0E 8E 20 0E AD 20 0E 29 3F 24 0F 10 18 C9 38 B0 06 86 19 A9 40 85 0F; +0030: A1 00 88 D0 FB CA 10 DB A5 0E 30 D2 10 14 E4 19 D0 EE C9 38 90 04 A9 80; +0048: D0 E4 C5 0F F0 E2 85 0F 49 38 29 1F C9 10 85 0D A6 1A 8C 21 0E 60 A1 00; +0060: A0 06 D0 0B A0 03 B5 00 20 6F FE 88 88 B5 01 C8 48 20 7A FE 88 68 4A 4A; +0078: 4A 4A 84 1A 29 0F A8 B9 EA FF A4 1A 99 10 00 60 20 64 FE 20 0C FE B0 20; +0090: A0 04 0A 0A 0A 0A 0A 36 00 36 01 88 D0 F8 F0 E8 F6 06 D0 02 F6 07 B5 06; +00A8: D5 08 D0 04 B5 07 D5 09 60 A0 40 8C 22 0E A0 07 8C 20 0E 6A 6A 20 CD FE; +00C0: 6A 8D 20 0E 88 10 F6 20 CD FE 8C 20 0E 20 D0 FE 84 1A A0 48 88 D0 FD 88; +00D8: D0 FD A4 1A 60 A0 08 2C 20 0E 30 FB 20 D0 FE 20 CD FE 0E 20 0E 6A 88 D0; +00F0: F6 F0 DA A2 FF 9A 8E 23 0E 86 0E A0 80 A2 09 94 0E CA D0 FB 20 0C FE 90; +0108: F2 29 07 C9 04 90 25 F0 6F C9 06 F0 09 B0 0F A5 0A A6 0B A4 0C 40 F6 00; +0120: D0 0C F6 01 B0 08 B5 00 D0 02 D6 01 D6 00 20 64 FE 4C 45 FF 84 16 84 17; +0138: 0A AA 49 F7 85 10 20 88 FE E0 02 B0 15 20 5E FE 20 0C FE B0 BC A1 00 0A; +0150: 0A 0A 0A 05 0D 81 00 4C 45 FF D0 03 6C 02 00 E0 04 F0 36 A2 08 86 10 20; +0168: 88 FE A2 04 B5 05 20 B1 FE CA D0 F8 A1 06 20 B1 FE 20 A0 FE D0 F6 F0 2A; +0180: A2 04 20 DD FE 95 05 CA D0 F8 20 DD FE 81 06 8D 21 0E 20 A0 FE D0 F3 F0; +0198: 11 A1 00 F0 06 85 18 A9 00 F0 02 A5 18 81 00 20 5E FE 4C 04 FF 6C 1C 00; +01B0: 6C 1E 00 85 0A 86 0B 84 0C 68 48 85 0D A2 0D A9 FF 85 0E 20 00 FE BA 86; +01C8: 13 C8 84 12 D8 BD 02 01 38 E5 1B 9D 02 01 85 11 BD 03 01 E9 00 9D 03 01; +01E0: 85 10 A2 13 20 00 FE 4C 07 FF 3F 06 5B 4F 66 6D 7D 07 7F 6F 77 7C 58 5E; +01F8: 79 71 AD FF F3 FE B0 FF; +END; diff --git a/Computer_MiST/Acorn - System1/rtl/vga.v b/Computer_MiST/Acorn - System1/rtl/vga.v new file mode 100644 index 00000000..3bbd7cf4 --- /dev/null +++ b/Computer_MiST/Acorn - System1/rtl/vga.v @@ -0,0 +1,1638 @@ +// Display for Acorn system1 +// Dave Wood 2019 +// +// This is a complete mess and needs a re-write +// +// "Abandon all hope, ye who enter here." +// +// +// + +module vga ( + input clk, + input rst, + input wire x1,y1,mbtnL,mbtnR,mbtnM, + input wire [10:0] mx,my, + input wire [8:0] ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7, + output wire osw0,osw1,osw2,osw3,osw4,osw5,osw6,osw7,osw8,osw9,oswa,oswb,oswc,oswd,oswe,oswf,oswrst,oswm,oswl,oswg,oswr,oswp,oswU,osws,oswD, + output wire [7:0] r,g,b, + output reg hs, vs, hblank, vblank +); + +wire [9:0] dot_x = mx[9:0]; +wire [9:0] dot_y = my[9:0]; +reg [7:0] dispvar; +reg [23:0] pix_col; +//reg [9:0] mp; + + +assign r = pix_col[23:16]; +assign g = pix_col[15:8]; +assign b = pix_col[7:0]; + + +reg [9:0]hcount,vcount; +localparam hmax = 10'd799, vmax = 10'd524; + +reg sw0,sw1,sw2,sw3,sw4,sw5,sw6,sw7,sw8,sw9,swa,swb,swc,swd,swe,swf,swm,swl,swg,swr,swp,swU,sws,swD; +reg swrst=1'b0; +assign osw0 = sw0; +assign osw1 = sw1; +assign osw2 = sw2; +assign osw3 = sw3; +assign osw4 = sw4; +assign osw5 = sw5; +assign osw6 = sw6; +assign osw7 = sw7; +assign osw8 = sw8; +assign osw9 = sw9; +assign oswa = swa; +assign oswb = swb; +assign oswc = swc; +assign oswd = swd; +assign oswe = swe; +assign oswf = swf; +assign oswrst = swrst; +assign oswm = swm; +assign oswl = swl; +assign oswg = swg; +assign oswr = swr; +assign oswp = swp; +assign oswU = swU; +assign osws = sws; +assign oswD = swD; + +always @(posedge clk, posedge rst) begin + if (rst) begin + hcount <= 10'd0; + vcount <= 10'd0; + end else begin +// h & v pixel counters + if(hcount < hmax) + hcount <= hcount + 1'b1; + else begin + hcount <= 10'd0; + if(vcount < vmax) + vcount <= vcount + 1'b1; + else + vcount <= 10'd0; + end + +// v & h sync signals + if(hcount == 10'd656) + hs<=1'b1; + else if (hcount >= 10'd752) + hs<=1'b0; + if(vcount == 10'd490) + vs<=1'b1; + else if(vcount >= 10'd492) + vs<=1'b0; + +// h & v blanking signals + if(hcount >= 10'd640) + hblank <= 1'b1; + else + hblank <= 1'b0; + + if(vcount >= 10'd480) + vblank <= 1'b1; + else + vblank <= 1'b0; + + end +end + +always @(posedge clk, posedge rst) begin + if(rst) + pix_col <= black; + else begin +// borders + if(vcount == 10'd0 || vcount == 10'd479) + pix_col <= olive; + else if(hcount == 10'd0 || hcount == 10'd639) + pix_col <= teal; + else + pix_col <= black; + //eurocard + if(hcount >= 10'd100 && hcount <= 10'd484 && vcount >= 10'd110 && vcount <= 10'd370) + pix_col <= green; + + //ic1 & 8 + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd149) + pix_col <= silver; + + if(hcount >= 10'd154 && hcount <= 10'd155 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd149) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd149) + pix_col <= silver; + + if(hcount >= 10'd110 && hcount <= 10'd139 && vcount >= 10'd150 && vcount <= 10'd165) + pix_col <= black; + if(hcount >= 10'd152 && hcount <= 10'd185 && vcount >= 10'd150 && vcount <= 10'd165) + pix_col <= black; + + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd166) + pix_col <= silver; + + if(hcount >= 10'd154 && hcount <= 10'd155 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd166) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd166) + pix_col <= silver; + +// ic 2 & 4 + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd204) + pix_col <= silver; + + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd204) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd204) + pix_col <= silver; + + if(hcount >= 10'd110 && hcount <= 10'd139 && vcount >= 10'd205 && vcount <= 10'd220) + pix_col <= black; + if(hcount >= 10'd156 && hcount <= 10'd185 && vcount >= 10'd205 && vcount <= 10'd220) + pix_col <= black; + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd221) + pix_col <= silver; + + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd221) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd221) + pix_col <= silver; +// ic 3 &5 + + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd259) + pix_col <= silver; + + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd259) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd259) + pix_col <= silver; + + if(hcount >= 10'd110 && hcount <= 10'd139 && vcount >= 10'd260 && vcount <= 10'd275) + pix_col <= black; + if(hcount >= 10'd156 && hcount <= 10'd185 && vcount >= 10'd260 && vcount <= 10'd275) + pix_col <= black; + if(hcount >= 10'd112 && hcount <= 10'd113 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd116 && hcount <= 10'd117 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd120 && hcount <= 10'd121 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd276) + pix_col <= silver; + + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd276) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd276) + pix_col <= silver; + +// ic 7 & 6 + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd314) + pix_col <= silver; + if(hcount >= 10'd122 && hcount <= 10'd139 && vcount >= 10'd315 && vcount <= 10'd330) + pix_col <= black; + if(hcount >= 10'd156 && hcount <= 10'd185 && vcount >= 10'd315 && vcount <= 10'd330) + pix_col <= black; + + if(hcount >= 10'd124 && hcount <= 10'd125 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd128 && hcount <= 10'd129 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd132 && hcount <= 10'd133 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd136 && hcount <= 10'd137 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd158 && hcount <= 10'd159 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd162 && hcount <= 10'd163 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd166 && hcount <= 10'd167 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd170 && hcount <= 10'd171 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd174 && hcount <= 10'd175 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd178 && hcount <= 10'd179 && vcount == 10'd331) + pix_col <= silver; + if(hcount >= 10'd182 && hcount <= 10'd183 && vcount == 10'd331) + pix_col <= silver; + + //keybase + if(hcount >= 10'd200 && hcount <= 10'd466 && vcount >= 10'd120 && vcount <= 10'd360) + pix_col <= silver; + //slot + if(hcount >= 10'd244 && hcount <= 10'd336 && vcount >= 10'd200 && vcount <= 10'd204) + pix_col <= green; + //display + if(hcount >= 10'd230 && hcount <= 10'd346 && vcount >= 10'd140 && vcount <= 10'd176) + pix_col <= teal; + + +//chars +// left most - not connected + if(hcount >= 10'd235 && hcount <= 10'd244 && vcount >= 10'd150 && vcount <= 10'd164) begin + pix_col <= silver; + end +// character 7 left + if(hcount >= 10'd247 && hcount <= 10'd256 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd249 && hcount <= 10'd254 && vcount == 10'd152) + pix_col <= ch7[0] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd153) + pix_col <= ch7[5] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd153) + pix_col <= ch7[1] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd154) + pix_col <= ch7[5] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd154) + pix_col <= ch7[1] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd155) + pix_col <= ch7[5] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd155) + pix_col <= ch7[1] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd156) + pix_col <= ch7[5] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd156) + pix_col <= ch7[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd249 && hcount <= 10'd254 && vcount == 10'd157) + pix_col <= ch7[6] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd158) + pix_col <= ch7[4] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd158) + pix_col <= ch7[2] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd159) + pix_col <= ch7[4] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd159) + pix_col <= ch7[2] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd160) + pix_col <= ch7[4] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd160) + pix_col <= ch7[2] == 1'b1 ? red : silver; + else if(hcount == 10'd248 && vcount == 10'd161) + pix_col <= ch7[4] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd161) + pix_col <= ch7[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd249 && hcount <= 10'd254 && vcount == 10'd162) + pix_col <= ch7[3] == 1'b1 ? red : silver; + else if(hcount == 10'd255 && vcount == 10'd164) + pix_col <= ch7[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + + end +// character 6 + if(hcount >= 10'd259 && hcount <= 10'd268 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd261 && hcount <= 10'd266 && vcount == 10'd152) + pix_col <= ch6[0] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd153) + pix_col <= ch6[5] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd153) + pix_col <= ch6[1] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd154) + pix_col <= ch6[5] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd154) + pix_col <= ch6[1] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd155) + pix_col <= ch6[5] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd155) + pix_col <= ch6[1] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd156) + pix_col <= ch6[5] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd156) + pix_col <= ch6[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd261 && hcount <= 10'd266 && vcount == 10'd157) + pix_col <= ch6[6] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd158) + pix_col <= ch6[4] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd158) + pix_col <= ch6[2] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd159) + pix_col <= ch6[4] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd159) + pix_col <= ch6[2] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd160) + pix_col <= ch6[4] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd160) + pix_col <= ch6[2] == 1'b1 ? red : silver; + else if(hcount == 10'd260 && vcount == 10'd161) + pix_col <= ch6[4] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd161) + pix_col <= ch6[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd261 && hcount <= 10'd266 && vcount == 10'd162) + pix_col <= ch6[3] == 1'b1 ? red : silver; + else if(hcount == 10'd267 && vcount == 10'd164) + pix_col <= ch6[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 5 + if(hcount >= 10'd271 && hcount <= 10'd280 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd273 && hcount <= 10'd278 && vcount == 10'd152) + pix_col <= ch5[0] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd153) + pix_col <= ch5[5] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd153) + pix_col <= ch5[1] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd154) + pix_col <= ch5[5] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd154) + pix_col <= ch5[1] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd155) + pix_col <= ch5[5] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd155) + pix_col <= ch5[1] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd156) + pix_col <= ch5[5] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd156) + pix_col <= ch5[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd273 && hcount <= 10'd278 && vcount == 10'd157) + pix_col <= ch5[6] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd158) + pix_col <= ch5[4] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd158) + pix_col <= ch5[2] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd159) + pix_col <= ch5[4] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd159) + pix_col <= ch5[2] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd160) + pix_col <= ch5[4] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd160) + pix_col <= ch5[2] == 1'b1 ? red : silver; + else if(hcount == 10'd272 && vcount == 10'd161) + pix_col <= ch5[4] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd161) + pix_col <= ch5[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd273 && hcount <= 10'd278 && vcount == 10'd162) + pix_col <= ch5[3] == 1'b1 ? red : silver; + else if(hcount == 10'd279 && vcount == 10'd164) + pix_col <= ch5[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 4 + if(hcount >= 10'd283 && hcount <= 10'd292 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd285 && hcount <= 10'd290 && vcount == 10'd152) + pix_col <= ch4[0] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd153) + pix_col <= ch4[5] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd153) + pix_col <= ch4[1] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd154) + pix_col <= ch4[5] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd154) + pix_col <= ch4[1] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd155) + pix_col <= ch4[5] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd155) + pix_col <= ch4[1] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd156) + pix_col <= ch4[5] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd156) + pix_col <= ch4[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd285 && hcount <= 10'd290 && vcount == 10'd157) + pix_col <= ch4[6] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd158) + pix_col <= ch4[4] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd158) + pix_col <= ch4[2] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd159) + pix_col <= ch4[4] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd159) + pix_col <= ch4[2] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd160) + pix_col <= ch4[4] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd160) + pix_col <= ch4[2] == 1'b1 ? red : silver; + else if(hcount == 10'd284 && vcount == 10'd161) + pix_col <= ch4[4] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd161) + pix_col <= ch4[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd285 && hcount <= 10'd290 && vcount == 10'd162) + pix_col <= ch4[3] == 1'b1 ? red : silver; + else if(hcount == 10'd291 && vcount == 10'd164) + pix_col <= ch4[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 3 + if(hcount >= 10'd295 && hcount <= 10'd304 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd297 && hcount <= 10'd302 && vcount == 10'd152) + pix_col <= ch3[0] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd153) + pix_col <= ch3[5] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd153) + pix_col <= ch3[1] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd154) + pix_col <= ch3[5] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd154) + pix_col <= ch3[1] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd155) + pix_col <= ch3[5] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd155) + pix_col <= ch3[1] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd156) + pix_col <= ch3[5] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd156) + pix_col <= ch3[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd297 && hcount <= 10'd302 && vcount == 10'd157) + pix_col <= ch3[6] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd158) + pix_col <= ch3[4] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd158) + pix_col <= ch3[2] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd159) + pix_col <= ch3[4] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd159) + pix_col <= ch3[2] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd160) + pix_col <= ch3[4] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd160) + pix_col <= ch3[2] == 1'b1 ? red : silver; + else if(hcount == 10'd296 && vcount == 10'd161) + pix_col <= ch3[4] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd161) + pix_col <= ch3[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd297 && hcount <= 10'd302 && vcount == 10'd162) + pix_col <= ch3[3] == 1'b1 ? red : silver; + else if(hcount == 10'd303 && vcount == 10'd164) + pix_col <= ch3[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 2 + if(hcount >= 10'd307 && hcount <= 10'd316 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd309 && hcount <= 10'd314 && vcount == 10'd152) + pix_col <= ch2[0] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd153) + pix_col <= ch2[5] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd153) + pix_col <= ch2[1] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd154) + pix_col <= ch2[5] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd154) + pix_col <= ch2[1] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd155) + pix_col <= ch2[5] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd155) + pix_col <= ch2[1] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd156) + pix_col <= ch2[5] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd156) + pix_col <= ch2[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd309 && hcount <= 10'd314 && vcount == 10'd157) + pix_col <= ch2[6] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd158) + pix_col <= ch2[4] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd158) + pix_col <= ch2[2] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd159) + pix_col <= ch2[4] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd159) + pix_col <= ch2[2] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd160) + pix_col <= ch2[4] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd160) + pix_col <= ch2[2] == 1'b1 ? red : silver; + else if(hcount == 10'd308 && vcount == 10'd161) + pix_col <= ch2[4] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd161) + pix_col <= ch2[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd309 && hcount <= 10'd314 && vcount == 10'd162) + pix_col <= ch2[3] == 1'b1 ? red : silver; + else if(hcount == 10'd315 && vcount == 10'd164) + pix_col <= ch2[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 1 + if(hcount >= 10'd319 && hcount <= 10'd328 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd321 && hcount <= 10'd326 && vcount == 10'd152) + pix_col <= ch1[0] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd153) + pix_col <= ch1[5] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd153) + pix_col <= ch1[1] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd154) + pix_col <= ch1[5] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd154) + pix_col <= ch1[1] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd155) + pix_col <= ch1[5] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd155) + pix_col <= ch1[1] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd156) + pix_col <= ch1[5] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd156) + pix_col <= ch1[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd321 && hcount <= 10'd326 && vcount == 10'd157) + pix_col <= ch1[6] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd158) + pix_col <= ch1[4] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd158) + pix_col <= ch1[2] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd159) + pix_col <= ch1[4] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd159) + pix_col <= ch1[2] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd160) + pix_col <= ch1[4] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd160) + pix_col <= ch1[2] == 1'b1 ? red : silver; + else if(hcount == 10'd320 && vcount == 10'd161) + pix_col <= ch1[4] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd161) + pix_col <= ch1[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd321 && hcount <= 10'd326 && vcount == 10'd162) + pix_col <= ch1[3] == 1'b1 ? red : silver; + else if(hcount == 10'd327 && vcount == 10'd164) + pix_col <= ch1[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end +// character 0 right + if(hcount >= 10'd331 && hcount <= 10'd340 && vcount >= 10'd150 && vcount <= 10'd164) begin + if(hcount >= 10'd333 && hcount <= 10'd338 && vcount == 10'd152) + pix_col <= ch0[0] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd153) + pix_col <= ch0[5] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd153) + pix_col <= ch0[1] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd154) + pix_col <= ch0[5] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd154) + pix_col <= ch0[1] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd155) + pix_col <= ch0[5] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd155) + pix_col <= ch0[1] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd156) + pix_col <= ch0[5] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd156) + pix_col <= ch0[1] == 1'b1 ? red : silver; + else if(hcount >= 10'd333 && hcount <= 10'd338 && vcount == 10'd157) + pix_col <= ch0[6] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd158) + pix_col <= ch0[4] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd158) + pix_col <= ch0[2] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd159) + pix_col <= ch0[4] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd159) + pix_col <= ch0[2] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd160) + pix_col <= ch0[4] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd160) + pix_col <= ch0[2] == 1'b1 ? red : silver; + else if(hcount == 10'd332 && vcount == 10'd161) + pix_col <= ch0[4] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd161) + pix_col <= ch0[2] == 1'b1 ? red : silver; + else if(hcount >= 10'd333 && hcount <= 10'd338 && vcount == 10'd162) + pix_col <= ch0[3] == 1'b1 ? red : silver; + else if(hcount == 10'd339 && vcount == 10'd164) + pix_col <= ch0[7] == 1'b1 ? red : silver; + else + pix_col <= silver; + end + + + +//keys +//rst + if(hcount >= 10'd408 && hcount <= 10'd432 && vcount >= 10'd196 && vcount <= 10'd208) //rst + pix_col <= swrst == 1'b1 ? grey : white; + +//1st row + if(hcount >= 10'd232 && hcount <= 10'd256 && vcount >= 10'd224 && vcount <= 10'd236) //c + pix_col <= swc == 1'b1 ? grey : white; + if(hcount >= 10'd264 && hcount <= 10'd288 && vcount >= 10'd224 && vcount <= 10'd236) //d + pix_col <= swd == 1'b1 ? grey : white; + if(hcount >= 10'd296 && hcount <= 10'd320 && vcount >= 10'd224 && vcount <= 10'd236) //e + pix_col <= swe == 1'b1 ? grey : white; + if(hcount >= 10'd328 && hcount <= 10'd352 && vcount >= 10'd224 && vcount <= 10'd236) //f + pix_col <= swf == 1'b1 ? grey : white; + if(hcount >= 10'd376 && hcount <= 10'd400 && vcount >= 10'd224 && vcount <= 10'd236) //m + pix_col <= swm == 1'b1 ? grey : white; + if(hcount >= 10'd408 && hcount <= 10'd432 && vcount >= 10'd224 && vcount <= 10'd236) //l + pix_col <= swl == 1'b1 ? grey : white; + +//2nd row + if(hcount >= 10'd232 && hcount <= 10'd256 && vcount >= 10'd252 && vcount <= 10'd264) //8 + pix_col <= sw8 == 1'b1 ? grey : white; + if(hcount >= 10'd264 && hcount <= 10'd288 && vcount >= 10'd252 && vcount <= 10'd264) //9 + pix_col <= sw9 == 1'b1 ? grey: white; + if(hcount >= 10'd296 && hcount <= 10'd320 && vcount >= 10'd252 && vcount <= 10'd264) //a + pix_col <= swa == 1'b1 ? grey : white; + if(hcount >= 10'd328 && hcount <= 10'd352 && vcount >= 10'd252 && vcount <= 10'd264) //b + pix_col <= swb == 1'b1 ? grey : white; + if(hcount >= 10'd376 && hcount <= 10'd400 && vcount >= 10'd252 && vcount <= 10'd264) //g + pix_col <= swg == 1'b1 ? grey : white; + if(hcount >= 10'd408 && hcount <= 10'd432 && vcount >= 10'd252 && vcount <= 10'd264) //r + pix_col <= swr == 1'b1 ? grey : white; + +//3rd row + if(hcount >= 10'd232 && hcount <= 10'd256 && vcount >= 10'd280 && vcount <= 10'd292) //4 + pix_col <= sw4 == 1'b1 ? grey : white; + if(hcount >= 10'd264 && hcount <= 10'd288 && vcount >= 10'd280 && vcount <= 10'd292) //5 + pix_col <= sw5 == 1'b1 ? grey: white; + if(hcount >= 10'd296 && hcount <= 10'd320 && vcount >= 10'd280 && vcount <= 10'd292) //6 + pix_col <= sw6 == 1'b1 ? grey : white; + if(hcount >= 10'd328 && hcount <= 10'd352 && vcount >= 10'd280 && vcount <= 10'd292) //7 + pix_col <= sw7 == 1'b1 ? grey : white; + if(hcount >= 10'd376 && hcount <= 10'd400 && vcount >= 10'd280 && vcount <= 10'd292) //p + pix_col <= swp == 1'b1 ? grey : white; + if(hcount >= 10'd408 && hcount <= 10'd432 && vcount >= 10'd280 && vcount <= 10'd292) //U + pix_col <= swU == 1'b1 ? grey : white; + +//4th row + if(hcount >= 10'd232 && hcount <= 10'd256 && vcount >= 10'd308 && vcount <= 10'd320) //0 + pix_col <= sw0 == 1'b1 ? grey : white; + if(hcount >= 10'd264 && hcount <= 10'd288 && vcount >= 10'd308 && vcount <= 10'd320) //1 + pix_col <= sw1 == 1'b1 ? grey: white; + if(hcount >= 10'd296 && hcount <= 10'd320 && vcount >= 10'd308 && vcount <= 10'd320) //2 + pix_col <= sw2 == 1'b1 ? grey : white; + if(hcount >= 10'd328 && hcount <= 10'd352 && vcount >= 10'd308 && vcount <= 10'd320) //3 + pix_col <= sw3 == 1'b1 ? grey : white; + if(hcount >= 10'd376 && hcount <= 10'd400 && vcount >= 10'd308 && vcount <= 10'd320) //s + pix_col <= sws == 1'b1 ? grey : white; + if(hcount >= 10'd408 && hcount <= 10'd432 && vcount >= 10'd308 && vcount <= 10'd320) //D + pix_col <= swD == 1'b1 ? grey : white; + +//rst + if(hcount >= 10'd414 && hcount <= 10'd415 && vcount == 10'd186) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd187) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd188) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd189) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd190) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd191) + pix_col <= black; + if(hcount == 10'd413 && vcount == 10'd192) + pix_col <= black; + + + if(hcount >= 10'd419 && hcount <= 10'd421 && vcount == 10'd186) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd187) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd187) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd188) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd189) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd190) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd191) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd191) + pix_col <= black; + if(hcount >= 10'd419 && hcount <= 10'd421 && vcount == 10'd192) + pix_col <= black; + + if(hcount == 10'd427 && vcount == 10'd185) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd186) + pix_col <= black; + if(hcount >= 10'd426 && hcount <= 10'd429 && vcount == 10'd187) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd188) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd189) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd190) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd191) + pix_col <= black; + if(hcount == 10'd427 && vcount == 10'd192) + pix_col <= black; + +//c + if(hcount >= 10'd243 && hcount <= 10'd245 && vcount == 10'd214) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd246 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd246 && vcount == 10'd219) + pix_col <= black; + if(hcount >= 10'd243 && hcount <= 10'd245 && vcount == 10'd220) + pix_col <= black; +//d + if(hcount == 10'd278 && vcount == 10'd213) + pix_col <= black; + if(hcount == 10'd278 && vcount == 10'd214) + pix_col <= black; + if(hcount >= 10'd275 && hcount <= 10'd278 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd274 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd278 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd274 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd278 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd274 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd278 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd274 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd278 && vcount == 10'd219) + pix_col <= black; + if(hcount >= 10'd275 && hcount <= 10'd277 && vcount == 10'd220) + pix_col <= black; +//e 307 + if(hcount >= 10'd306 && hcount <= 10'd308 && vcount == 10'd214) + pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd309 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd309 && vcount == 10'd216) + pix_col <= black; + if(hcount >= 10'd305 && hcount <= 10'd309 && vcount == 10'd217) + pix_col <= black; +// if(hcount == 10'd305 && vcount == 10'd217) +// pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd309 && vcount == 10'd219) + pix_col <= black; + if(hcount >= 10'd306 && hcount <= 10'd308 && vcount == 10'd220) + pix_col <= black; +//f + if(hcount >= 10'd341 && hcount <= 10'd342 && vcount == 10'd213) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd214) + pix_col <= black; + if(hcount >= 10'd339 && hcount <= 10'd342 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd220) + pix_col <= black; + +//m + if(hcount >= 10'd387 && hcount <= 10'd388 && vcount == 10'd214) + pix_col <= black; + if(hcount >= 10'd390 && hcount <= 10'd391 && vcount == 10'd214) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd220) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd220) + pix_col <= black; + if(hcount == 10'd392 && vcount == 10'd220) + pix_col <= black; + +//l + if(hcount == 10'd420 && vcount == 10'd213) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd214) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd215) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd216) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd217) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd218) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd219) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd220) + pix_col <= black; + + + + +//8 + if(hcount >= 10'd242 && hcount <= 10'd246 && vcount == 10'd240) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd243) + pix_col <= black; + if(hcount >= 10'd242 && hcount <= 10'd246 && vcount == 10'd244) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd247) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd247) + pix_col <= black; + if(hcount >= 10'd242 && hcount <= 10'd246 && vcount == 10'd248) + pix_col <= black; + + +//9 + if(hcount >= 10'd274 && hcount <= 10'd278 && vcount == 10'd240) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd243) + pix_col <= black; + if(hcount >= 10'd274 && hcount <= 10'd278 && vcount == 10'd244) + pix_col <= black; + + if(hcount == 10'd279 && vcount == 10'd245) + pix_col <= black; + + if(hcount == 10'd279 && vcount == 10'd246) + pix_col <= black; + + if(hcount == 10'd279 && vcount == 10'd247) + pix_col <= black; + if(hcount >= 10'd274 && hcount <= 10'd278 && vcount == 10'd248) + pix_col <= black; +//a + if(hcount >= 10'd307 && hcount <= 10'd309 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd243) + pix_col <= black; + if(hcount >= 10'd307 && hcount <= 10'd310 && vcount == 10'd244) + pix_col <= black; +// if(hcount == 10'd306 && vcount == 10'd244) +// pix_col <= black; +// if(hcount == 10'd310 && vcount == 10'd244) +// pix_col <= black; + if(hcount == 10'd306 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd306 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd306 && vcount == 10'd247) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd247) + pix_col <= black; + if(hcount >= 10'd307 && hcount <= 10'd310 && vcount == 10'd248) + pix_col <= black; +//b + if(hcount == 10'd338 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd338 && vcount == 10'd242) + pix_col <= black; + if(hcount >= 10'd338 && hcount <= 10'd341 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd338 && vcount == 10'd244) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd244) + pix_col <= black; + if(hcount == 10'd338 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd338 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd338 && vcount == 10'd247) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd247) + pix_col <= black; + if(hcount >= 10'd339 && hcount <= 10'd341 && vcount == 10'd248) + pix_col <= black; +//g + if(hcount >= 10'd387 && hcount <= 10'd390 && vcount == 10'd241) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd244) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd244) + pix_col <= black; + if(hcount >= 10'd387 && hcount <= 10'd390 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd247) + pix_col <= black; + if(hcount >= 10'd387 && hcount <= 10'd389 && vcount == 10'd248) + pix_col <= black; + +//r + if(hcount >= 10'd420 && hcount <= 10'd421 && vcount == 10'd242) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd243) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd244) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd245) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd246) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd247) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd248) + pix_col <= black; + + + +//4 + if(hcount == 10'd245 && vcount == 10'd268) + pix_col <= black; + if(hcount == 10'd244 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd245 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd243 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd245 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd242 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd245 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd272) + pix_col <= black; + if(hcount == 10'd245 && vcount == 10'd272) + pix_col <= black; + if(hcount >= 10'd240 && hcount <= 10'd246 && vcount == 10'd273) + pix_col <= black; + + if(hcount == 10'd245 && vcount == 10'd274) + pix_col <= black; + + if(hcount == 10'd245 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd245 && vcount == 10'd276) + pix_col <= black; + +//5 + if(hcount >= 10'd273 && hcount <= 10'd279 && vcount == 10'd268) + pix_col <= black; + if(hcount == 10'd273 &&vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd271) + pix_col <= black; + if(hcount >= 10'd274 && hcount <= 10'd278 && vcount == 10'd272) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd273 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd279 && vcount == 10'd275) + pix_col <= black; + if(hcount >= 10'd274 && hcount <= 10'd278 && vcount == 10'd276) + pix_col <= black; +//6 + if(hcount >= 10'd305 && hcount <= 10'd309 && vcount == 10'd268) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd271) + pix_col <= black; + + if(hcount >= 10'd304 && hcount <= 10'd309 && vcount == 10'd272) + pix_col <= black; + + if(hcount == 10'd304 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd275) + pix_col <= black; + if(hcount >= 10'd305 && hcount <= 10'd309 && vcount == 10'd276) + pix_col <= black; +//7 + if(hcount >= 10'd336 && hcount <= 10'd342 && vcount == 10'd268) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd269) + pix_col <= black; + + if(hcount == 10'd341 && vcount == 10'd270) + pix_col <= black; + + + if(hcount == 10'd341 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd340 && vcount == 10'd272) + pix_col <= black; + + if(hcount == 10'd339 && vcount == 10'd273) + pix_col <= black; + + if(hcount == 10'd338 && vcount == 10'd274) + pix_col <= black; + + if(hcount == 10'd338 && vcount == 10'd275) + pix_col <= black; + + if(hcount == 10'd338 && vcount == 10'd276) + pix_col <= black; +//p + if(hcount >= 10'd386 && hcount <= 10'd389 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd272) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd272) + pix_col <= black; + if(hcount >= 10'd386 && hcount <= 10'd389 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd276) + pix_col <= black; + + +//up + if(hcount == 10'd420 && vcount == 10'd268) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd269) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd270) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd271) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd272) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd272) + pix_col <= black; + if(hcount == 10'd417 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd423 && vcount == 10'd273) + pix_col <= black; + if(hcount == 10'd417 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd423 && vcount == 10'd274) + pix_col <= black; + if(hcount == 10'd416 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd424 && vcount == 10'd275) + pix_col <= black; + if(hcount == 10'd416 && vcount == 10'd276) + pix_col <= black; + if(hcount == 10'd424 && vcount == 10'd276) + pix_col <= black; + + +//0 + if(hcount >= 10'd242 && hcount <= 10'd246 && vcount == 10'd296) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd241 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd247 && vcount == 10'd303) + pix_col <= black; + if(hcount >= 10'd242 && hcount <= 10'd246 && vcount == 10'd304) + pix_col <= black; + +//1 + if(hcount == 10'd276 && vcount == 10'd296) + pix_col <= black; + if(hcount >= 10'd275 && hcount <= 10'd276 &&vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd276 && vcount == 10'd304) + pix_col <= black; + +//2 + if(hcount >= 10'd306 && hcount <= 10'd308 && vcount == 10'd296) + pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd309 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd304 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd310 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd309 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd308 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd307 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd306 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd305 && vcount == 10'd303) + pix_col <= black; + if(hcount >= 10'd304 && hcount <= 10'd310 && vcount == 10'd304) + pix_col <= black; + +//3 + if(hcount >= 10'd338 && hcount <= 10'd340 && vcount == 10'd296) + pix_col <= black; + if(hcount == 10'd337 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd341 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd336 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd298) + pix_col <= black; + + if(hcount == 10'd342 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd341 && vcount == 10'd300) + pix_col <= black; + + if(hcount == 10'd342 && vcount == 10'd301) + pix_col <= black; + + if(hcount == 10'd336 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd342 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd337 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd341 && vcount == 10'd303) + pix_col <= black; + if(hcount >= 10'd338 && hcount <= 10'd340 && vcount == 10'd304) + pix_col <= black; + +//s + if(hcount >= 10'd387 && hcount <= 10'd389 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd387 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd388 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd389 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd386 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd390 && vcount == 10'd303) + pix_col <= black; + if(hcount >= 10'd387 && hcount <= 10'd389 && vcount == 10'd304) + pix_col <= black; + +//down + if(hcount == 10'd416 && vcount == 10'd296) + pix_col <= black; + if(hcount == 10'd424 && vcount == 10'd296) + pix_col <= black; + if(hcount == 10'd416 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd424 && vcount == 10'd297) + pix_col <= black; + if(hcount == 10'd417 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd423 && vcount == 10'd298) + pix_col <= black; + if(hcount == 10'd417 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd423 && vcount == 10'd299) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd300) + pix_col <= black; + if(hcount == 10'd418 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd422 && vcount == 10'd301) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd302) + pix_col <= black; + if(hcount == 10'd419 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd421 && vcount == 10'd303) + pix_col <= black; + if(hcount == 10'd420 && vcount == 10'd304) + pix_col <= black; + +// mouse buttons + if(hcount >= 10'd318 && hcount <= 10'd322 && vcount >= 10'd38 && vcount <= 10'd42) + pix_col <= mbtnR == 1'b0 ? red : lime; + if(hcount >= 10'd312 && hcount <= 10'd316 && vcount >= 10'd38 && vcount <= 10'd42) + pix_col <= mbtnM == 1'b0 ? red : blue; + if(hcount >= 10'd306 && hcount <= 10'd310 && vcount >= 10'd38 && vcount <= 10'd42) + pix_col <= mbtnL == 1'b0 ? red : yellow; +// mouse + if(hcount >= dot_x && hcount <= dot_x + 10'd4 && vcount >= dot_y && vcount <= dot_y + 10'd4) + pix_col <= mbtnL == 1'b0 ? yellow : aqua; + + end +end + +reg [7:0] tmp; +always @(posedge clk, posedge rst) begin + if(rst) + tmp <= 8'b10000000; + else begin +// if (mbtnM == 1'b1) +// mp <= my[9:0]; + if (mbtnL == 1'b1) begin + + + // key value + if(mx >= 10'd408 && mx <= 10'd432 && my >= 10'd196 && my <= 10'd208) + swrst <= 1'b1; + + if(mx >= 10'd232 && mx <= 10'd256 && my >= 10'd224 && my <= 10'd236) + swc <= 1'b1; + if(mx >= 10'd264 && mx <= 10'd288 && my >= 10'd224 && my <= 10'd236) + swd <= 1'b1; + if(mx >= 10'd296 && mx <= 10'd320 && my >= 10'd224 && my <= 10'd236) + swe <= 1'b1; + if(mx >= 10'd328 && mx <= 10'd352 && my >= 10'd224 && my <= 10'd236) + swf <= 1'b1; + if(mx >= 10'd376 && mx <= 10'd400 && my >= 10'd224 && my <= 10'd236) + swm <= 1'b1; + if(mx >= 10'd408 && mx <= 10'd432 && my >= 10'd224 && my <= 10'd236) + swl <= 1'b1; + + if(mx >= 10'd232 && mx <= 10'd256 && my >= 10'd252 && my <= 10'd264) + sw8 <= 1'b1; + if(mx >= 10'd264 && mx <= 10'd288 && my >= 10'd252 && my <= 10'd264) + sw9 <= 1'b1; + if(mx >= 10'd296 && mx <= 10'd320 && my >= 10'd252 && my <= 10'd264) + swa <= 1'b1; + if(mx >= 10'd328 && mx <= 10'd352 && my >= 10'd252 && my <= 10'd264) + swb <= 1'b1; + if(mx >= 10'd376 && mx <= 10'd400 && my >= 10'd252 && my <= 10'd264) + swg <= 1'b1; + if(mx >= 10'd408 && mx <= 10'd432 && my >= 10'd252 && my <= 10'd264) + swr <= 1'b1; + + if(mx >= 10'd232 && mx <= 10'd256 && my >= 10'd280 && my <= 10'd292) + sw4 <= 1'b1; + if(mx >= 10'd264 && mx <= 10'd288 && my >= 10'd280 && my <= 10'd292) + sw5 <= 1'b1; + if(mx >= 10'd296 && mx <= 10'd320 && my >= 10'd280 && my <= 10'd292) + sw6 <= 1'b1; + if(mx >= 10'd328 && mx <= 10'd352 && my >= 10'd280 && my <= 10'd292) + sw7 <= 1'b1; + if(mx >= 10'd376 && mx <= 10'd400 && my >= 10'd280 && my <= 10'd292) + swp <= 1'b1; + if(mx >= 10'd408 && mx <= 10'd432 && my >= 10'd280 && my <= 10'd292) + swU <= 1'b1; + + if(mx >= 10'd232 && mx <= 10'd256 && my >= 10'd308 && my <= 10'd320) + sw0 <= 1'b1; + if(mx >= 10'd264 && mx <= 10'd288 && my >= 10'd308 && my <= 10'd320) + sw1 <= 1'b1; + if(mx >= 10'd296 && mx <= 10'd320 && my >= 10'd308 && my <= 10'd320) + sw2 <= 1'b1; + if(mx >= 10'd328 && mx <= 10'd352 && my >= 10'd308 && my <= 10'd320) + sw3 <= 1'b1; + if(mx >= 10'd376 && mx <= 10'd400 && my >= 10'd308 && my <= 10'd320) + sws <= 1'b1; + if(mx >= 10'd408 && mx <= 10'd432 && my >= 10'd308 && my <= 10'd320) + swD <= 1'b1; + + + + end else begin + swrst <= 1'b0; + swc <= 1'b0; + swd <= 1'b0; + swe <= 1'b0; + swf <= 1'b0; + swm <= 1'b0; + swl <= 1'b0; + sw8 <= 1'b0; + sw9 <= 1'b0; + swa <= 1'b0; + swb <= 1'b0; + swg <= 1'b0; + swr <= 1'b0; + sw4 <= 1'b0; + sw5 <= 1'b0; + sw6 <= 1'b0; + sw7 <= 1'b0; + swp <= 1'b0; + swU <= 1'b0; + sw0 <= 1'b0; + sw1 <= 1'b0; + sw2 <= 1'b0; + sw3 <= 1'b0; + sws <= 1'b0; + swD <= 1'b0; + end + + + end +end + +// Take no notice - I change the values to suit +// without ghanging the name +// +// 24 bit colour + +wire [23:0] black = 24'h000000; +//wire [23:0] maroon = 24'hC00000; +wire [23:0] green = 24'h004000; +wire [23:0] olive = 24'h808000; +//wire [23:0] navy = 24'h000080; +//wire [23:0] purple = 24'h800080; +wire [23:0] teal = 24'h008080; +wire [23:0] silver = 24'hC0C0C0; +wire [23:0] grey = 24'h808080; +wire [23:0] red = 24'hFF0000; +wire [23:0] lime = 24'h00FF00; +wire [23:0] yellow = 24'hFFFF00; +wire [23:0] blue = 24'h0000FF; +//wire [23:0] fuchsia = 24'hFF00FF; +wire [23:0] aqua = 24'h00FFFF; +wire [23:0] white = 24'hFFFFFF; + +endmodule +