├── src ├── README ├── crt0.S ├── .settings │ └── org.eclipse.cdt.core.prefs ├── .cdtproject ├── console.h ├── zxloader.c ├── Makefile ├── spectrum.h ├── common.h ├── .project ├── ansi.h ├── console.c └── .cproject ├── spectrum.cdf ├── pll_main.qip ├── pll_main.ppf ├── spectrum.qpf ├── README ├── i2c_loader_tb.vhd ├── seg7.vhd ├── clocks.vhd ├── ula_port.vhd ├── T80 ├── T80_Reg.vhd ├── T80_RegX.vhd ├── T80sed.vhd ├── T80se.vhd ├── T8080se.vhd ├── T80a.vhd ├── T80_Pack.vhd └── T80_ALU.vhd ├── i2s_intf_tb.vhd ├── ps2_intf_tb.vhd ├── video_tb.vhd ├── spi.vhd ├── ps2_intf.vhd ├── zxmmc.vhd ├── YM2149 └── YM2149_tb.vhd ├── i2s_intf.vhd ├── keyboard.vhd ├── i2c_loader.vhd ├── debugger.vhd ├── video.vhd └── CII_Starter_pin_assignments.csv /src/README: -------------------------------------------------------------------------------- 1 | Build requires sdcc, binutils-z80, z80dasm 2 | 3 | -------------------------------------------------------------------------------- /src/crt0.S: -------------------------------------------------------------------------------- 1 | /* 2 | * crt0.S 3 | * 4 | * Created on: 3 Apr 2010 5 | * Author: mike 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /src/.settings/org.eclipse.cdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Tue Jun 01 21:39:24 BST 2010 2 | eclipse.preferences.version=1 3 | indexerId=org.eclipse.cdt.core.fastIndexer 4 | -------------------------------------------------------------------------------- /spectrum.cdf: -------------------------------------------------------------------------------- 1 | /* Quartus II Version 9.1 Build 222 10/21/2009 SJ Web Edition */ 2 | JedecChain; 3 | FileRevision(JESD32A); 4 | DefaultMfr(6E); 5 | 6 | P ActionCode(Cfg) 7 | Device PartName(EP2C20F484) Path("U:/git_repos/fpga/spectrum/") File("spectrum.sof") MfrSpec(OpMask(1)); 8 | 9 | ChainEnd; 10 | 11 | AlteraBegin; 12 | ChainType(JTAG); 13 | AlteraEnd; 14 | -------------------------------------------------------------------------------- /pll_main.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "9.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_main.vhd"] 4 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_main.bsf"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_main.ppf"] 6 | -------------------------------------------------------------------------------- /src/.cdtproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /pll_main.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * console.h 3 | * 4 | * Created on: 3 Apr 2010 5 | * Author: mike 6 | */ 7 | 8 | #ifndef CONSOLE_H_ 9 | #define CONSOLE_H_ 10 | 11 | // Width of the console in characters 12 | #define CONSOLE_WIDTH 32 13 | // Height of the console in characters 14 | #define CONSOLE_HEIGHT 24 15 | 16 | // Determine first byte of the screen data for the 17 | // specified character coordinates 18 | #define CHAR_ADDR(x,y) (&pSCREEN[2048 * (y >> 3) + 32 * (y & 7) + x]) 19 | // Determine attribute address for specified character coordinates 20 | #define ATTR_ADDR(x,y) (&pATTR[32 * y + x]) 21 | 22 | void console_cls(void); 23 | 24 | #endif /* CONSOLE_H_ */ 25 | -------------------------------------------------------------------------------- /src/zxloader.c: -------------------------------------------------------------------------------- 1 | /* 2 | * main.c 3 | * 4 | * Created on: 3 Apr 2010 5 | * Author: mike 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | #include "common.h" 12 | #include "spectrum.h" 13 | #include "ansi.h" 14 | #include "console.h" 15 | 16 | int main(void) 17 | { 18 | int n = 0; 19 | volatile int m; 20 | 21 | console_cls(); 22 | 23 | BORDER(WHITE); 24 | printf(ATTR_RESET BG_BLUE FG_YELLOW 25 | " \n" 26 | " ZX Spectrum for Altera DE1 \n" 27 | " (C) 2010 Mike Stirling \n" 28 | " \n" ATTR_RESET "\n"); 29 | 30 | 31 | TRACE("Entering main loop\n"); 32 | 33 | while(1) { 34 | INFO("%d\n", n++); 35 | for (m = 0; m < 255; m++); 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=zxloader 2 | CPU=z80 3 | 4 | # Leave space for SDCC's standard C startup - we should probably 5 | # write our own 6 | ROM_BASE=0x0200 7 | # Memory below here and above 0x4000 is video RAM 8 | RAM_BASE=0x5b00 9 | 10 | # Size to pack binary image to 11 | ROM_SIZE=0x4000 12 | 13 | CC=sdcc 14 | CFLAGS=-m$(CPU) -DDEBUG=3 15 | LDFLAGS=-m$(CPU) --code-loc $(ROM_BASE) --data-loc $(RAM_BASE) 16 | 17 | # Must be listed first 18 | OBJS=$(TARGET).rel console.rel 19 | # Other objects in any order 20 | #OBJS+= 21 | 22 | all: $(TARGET).hex 23 | 24 | $(TARGET).hex: $(OBJS) 25 | $(CC) $(LDFLAGS) $^ 26 | packihx <$(TARGET).ihx >$(TARGET).hex 27 | z80-unknown-coff-objcopy -I ihex -O binary --pad-to=$(ROM_SIZE) $(TARGET).hex $(TARGET).bin 28 | z80dasm -g 0 -a -l -t $(TARGET).bin > $(TARGET).z80 29 | 30 | %.rel: %.c 31 | $(CC) -c $(CFLAGS) $< 32 | 33 | 34 | clean: 35 | rm -rf *.asm *.ihx *.hex *.lk *.noi *.lst *.map *.rel *.sym *.bin *.z80 36 | 37 | .PHONY: clean 38 | 39 | -------------------------------------------------------------------------------- /spectrum.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2009 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 20 | # Version 9.1 Build 222 10/21/2009 SJ Web Edition 21 | # Date created = 21:43:01 February 24, 2010 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "9.1" 26 | DATE = "21:43:01 February 24, 2010" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "spectrum" 31 | -------------------------------------------------------------------------------- /src/spectrum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spectrum.h 3 | * 4 | * Created on: 3 Apr 2010 5 | * Author: mike 6 | */ 7 | 8 | #ifndef SPECTRUM_H_ 9 | #define SPECTRUM_H_ 10 | 11 | /* 12 | * ULA output 13 | * 14 | * D7 - 15 | * D6 - 16 | * D5 - 17 | * D4 - EAR (high-level output) 18 | * D3 - MIC (low-level output) 19 | * D2 - BORDER GREEN 20 | * D1 - BORDER RED 21 | * D0 - BORDER BLUE 22 | * 23 | * ULA input 24 | * 25 | * D7 - 26 | * D6 - EAR input 27 | * D5 - 28 | * D4-D0 Keyboard 29 | */ 30 | __sfr __at(0xfffe) ULA_REG; 31 | 32 | /* 33 | * ULA keyboard registers 34 | */ 35 | 36 | // D4, D3, D2, D1, D0 37 | // B, N, M, SYM SHIFT, SPACE 38 | __sfr __at(0x7ffe) ULA_KEYB1; 39 | 40 | // D4, D3, D2, D1, D0 41 | // H, J, K, L, ENTER 42 | __sfr __at(0xbffe) ULA_KEYB2; 43 | 44 | // D4, D3, D2, D1, D0 45 | // Y, U, I, O, P 46 | __sfr __at(0xdffe) ULA_KEYB3; 47 | 48 | // D4, D3, D2, D1, D0 49 | // 6, 7, 8, 9, 0 50 | __sfr __at(0xeffe) ULA_KEYB4; 51 | 52 | // D4, D3, D2, D1, D0 53 | // 5, 4, 3, 2, 1 54 | __sfr __at(0xf7fe) ULA_KEYB5; 55 | 56 | // D4, D3, D2, D1, D0 57 | // T, R, E, W, Q 58 | __sfr __at(0xfbfe) ULA_KEYB6; 59 | 60 | // D4, D3, D2, D1, D0 61 | // G, F, D, S, A 62 | __sfr __at(0xfdfe) ULA_KEYB7; 63 | 64 | // D4, D3, D2, D1, D0 65 | // V, C, X, Z, CAPS SHIFT 66 | __sfr __at(0xfefe) ULA_KEYB8; 67 | 68 | /* Various macros */ 69 | 70 | #define BLACK 0 71 | #define BLUE 1 72 | #define RED 2 73 | #define MAGENTA 3 74 | #define GREEN 4 75 | #define CYAN 5 76 | #define YELLOW 6 77 | #define WHITE 7 78 | 79 | // The following macro generates code that changes the 80 | // border colour to the specified value immediately 81 | #define BORDER(a) (ULA_REG = (a & 7)) 82 | // The following macros generate byte values that may be 83 | // ORed together and applied to the attribute area to 84 | // change the attributes of an 8x8 square 85 | #define INK(a) (a & 7) 86 | #define PAPER(a) ((a & 7) << 3) 87 | #define BRIGHT (1 << 6) 88 | #define FLASH (1 << 7) 89 | 90 | // Screen area 91 | static volatile unsigned char *pSCREEN = (unsigned char*)0x4000; 92 | #define sizeofSCREEN (6144) 93 | // Attribute area 94 | static volatile unsigned char *pATTR = (unsigned char*)0x5800; 95 | #define sizeofATTR (768) 96 | 97 | #endif /* SPECTRUM_H_ */ 98 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Sinclair ZX Spectrum on an Altera DE1 Cyclone II FPGA board 2 | ----------------------------------------------------------- 3 | 4 | http://www.mike-stirling.com/retro-fpga/zx-spectrum-on-an-fpga/ 5 | (C) 2009-2016 Mike Stirling 6 | 7 | Uses components from: 8 | 9 | T80 Z80 core Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 10 | YM2149 Copyright (c) MikeJ - Jan 2005 11 | 12 | -- ZX Spectrum for Altera DE1 13 | -- 14 | -- Copyright (c) 2009-2011 Mike Stirling 15 | -- 16 | -- All rights reserved 17 | -- 18 | -- Redistribution and use in source and synthezised forms, with or without 19 | -- modification, are permitted provided that the following conditions are met: 20 | -- 21 | -- * Redistributions of source code must retain the above copyright notice, 22 | -- this list of conditions and the following disclaimer. 23 | -- 24 | -- * Redistributions in synthesized form must reproduce the above copyright 25 | -- notice, this list of conditions and the following disclaimer in the 26 | -- documentation and/or other materials provided with the distribution. 27 | -- 28 | -- * Neither the name of the author nor the names of other contributors may 29 | -- be used to endorse or promote products derived from this software without 30 | -- specific prior written agreement from the author. 31 | -- 32 | -- * License is granted for non-commercial use only. A fee may not be charged 33 | -- for redistributions as source code or in synthesized/hardware form without 34 | -- specific prior written agreement from the author. 35 | -- 36 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 37 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 38 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 40 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 41 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 42 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 44 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46 | -- POSSIBILITY OF SUCH DAMAGE. 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H_ 2 | #define COMMON_H_ 3 | 4 | /* 5 | * Define standard types 6 | */ 7 | 8 | //! Defines a boolean type 9 | typedef enum { 10 | False = 0, 11 | True 12 | } bool_t; 13 | 14 | #ifndef TRUE 15 | //! Alternative to "True" 16 | #define TRUE (True) 17 | #endif 18 | #ifndef FALSE 19 | //! Alternative to "False" 20 | #define FALSE (False) 21 | #endif 22 | 23 | #ifndef NULL 24 | //! A NULL pointer value 25 | #define NULL (void*)(0) 26 | #endif 27 | 28 | // Define debugging macros. These require extra include files 29 | // which the following will pull in. 30 | #ifdef DEBUG 31 | #include 32 | #include "ansi.h" 33 | #endif 34 | 35 | #if DEBUG > 0 36 | //! Outputs red debug messages when debug level is 1 or more 37 | #define ERROR(a,...) { printf(ATTR_RESET FG_RED __FILE__ "(%d): " ATTR_RESET a,__LINE__,##__VA_ARGS__); } 38 | #else 39 | #define ERROR(...) 40 | #endif 41 | 42 | #if DEBUG > 1 43 | //! Outputs yellow debug messages when debug level is 2 or more 44 | #define INFO(a,...) { printf(ATTR_RESET FG_YELLOW __FILE__ "(%d): " ATTR_RESET a,__LINE__,##__VA_ARGS__); } 45 | #else 46 | #define INFO(...) 47 | #endif 48 | 49 | #if DEBUG > 2 50 | //! Outputs green debug messages when debug level is 3 or more 51 | #define TRACE(a,...) { printf(ATTR_RESET FG_GREEN __FILE__ "(%d): " ATTR_RESET a,__LINE__,##__VA_ARGS__); } 52 | #else 53 | #define TRACE(...) 54 | #endif 55 | 56 | #if DEBUG > 3 57 | //! Intended for use in ISRs, outputs cyan debug messages when debug level is 4 or more 58 | #define ISR_TRACE(a,...) { printf(ATTR_RESET FG_CYAN __FILE__ "(%d): " ATTR_RESET a,__LINE__,##__VA_ARGS__); } 59 | #else 60 | #define ISR_TRACE(...) 61 | #endif 62 | 63 | /* 64 | * Byte manipulation macros 65 | */ 66 | 67 | //! Select the low byte of a 16-bit word 68 | #define UINT16_LOW(a) (a & 0xff) 69 | 70 | //! Select the high byte of a 16-bit word 71 | #define UINT16_HIGH(a) (a >> 8) 72 | 73 | /* 74 | * Bit manipulation macros 75 | */ 76 | 77 | //! Set bits in a register 78 | #define SET(reg, flags) ((reg) = (reg) | (flags)) 79 | //! Clear bits in a register 80 | #define CLEAR(reg, flags) ((reg) &= ~(flags)) 81 | 82 | //! Determine if bits in a register are set 83 | #define ISSET(reg, flags) (((reg) & (flags)) == (flags)) 84 | //! Determine if bits in a register are clear 85 | #define ISCLEAR(reg, flags) (((reg) & (flags)) == 0) 86 | 87 | //! This global is provided by version.c, which should be rebuilt every time 88 | extern const char *build_version; 89 | 90 | #endif /*COMMON_H_*/ 91 | -------------------------------------------------------------------------------- /src/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Spectrum Loader 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.cleanBuildTarget 34 | clean 35 | 36 | 37 | org.eclipse.cdt.make.core.contents 38 | org.eclipse.cdt.make.core.activeConfigSettings 39 | 40 | 41 | org.eclipse.cdt.make.core.enableAutoBuild 42 | false 43 | 44 | 45 | org.eclipse.cdt.make.core.enableCleanBuild 46 | true 47 | 48 | 49 | org.eclipse.cdt.make.core.enableFullBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.fullBuildTarget 54 | all 55 | 56 | 57 | org.eclipse.cdt.make.core.stopOnError 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.useDefaultBuildCmd 62 | true 63 | 64 | 65 | 66 | 67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 68 | 69 | 70 | 71 | 72 | 73 | org.eclipse.cdt.core.cnature 74 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 75 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 76 | 77 | 78 | -------------------------------------------------------------------------------- /i2c_loader_tb.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2010 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written permission. 20 | -- 21 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 25 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | -- POSSIBILITY OF SUCH DAMAGE. 32 | -- 33 | 34 | library IEEE; 35 | use IEEE.STD_LOGIC_1164.ALL; 36 | use IEEE.STD_LOGIC_ARITH.ALL; 37 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 38 | 39 | entity i2c_loader_tb is 40 | end i2c_loader_tb; 41 | 42 | architecture test of i2c_loader_tb is 43 | component i2c_loader is 44 | port ( 45 | CLK : in std_logic; 46 | CLKEN : in std_logic; 47 | nRESET : in std_logic; 48 | 49 | I2C_SCL : inout std_logic; 50 | I2C_SDA : inout std_logic; 51 | 52 | IS_DONE : out std_logic; 53 | IS_ERROR : out std_logic 54 | ); 55 | end component; 56 | signal clk : std_logic := '0'; 57 | signal clken : std_logic := '1'; 58 | signal nreset : std_logic := '0'; 59 | signal scl : std_logic := 'Z'; 60 | signal sda : std_logic := 'Z'; 61 | signal done : std_logic; 62 | signal error : std_logic; 63 | begin 64 | uut: i2c_loader port map( 65 | clk,clken,nreset,scl,sda,done,error); 66 | 67 | clk <= not clk after 100 ps; 68 | 69 | process 70 | begin 71 | wait for 500 ps; 72 | nreset <= '1'; 73 | end process; 74 | end test; 75 | 76 | -------------------------------------------------------------------------------- /seg7.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library ieee; 39 | use ieee.std_logic_1164.all; 40 | 41 | -- Convert BCD to 7-segment display characters 42 | entity seg7 is 43 | port ( 44 | D : in std_logic_vector(3 downto 0); 45 | Q : out std_logic_vector(6 downto 0) 46 | ); 47 | end seg7; 48 | 49 | architecture seg7_arch of seg7 is 50 | begin 51 | Q <= "1000000" when D = "0000" else 52 | "1111001" when D = "0001" else 53 | "0100100" when D = "0010" else 54 | "0110000" when D = "0011" else 55 | "0011001" when D = "0100" else 56 | "0010010" when D = "0101" else 57 | "0000010" when D = "0110" else 58 | "1111000" when D = "0111" else 59 | "0000000" when D = "1000" else 60 | "0010000" when D = "1001" else 61 | "0001000" when D = "1010" else 62 | "0000011" when D = "1011" else 63 | "1000110" when D = "1100" else 64 | "0100001" when D = "1101" else 65 | "0000110" when D = "1110" else 66 | "0001110"; 67 | end seg7_arch; 68 | 69 | -------------------------------------------------------------------------------- /clocks.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library IEEE; 39 | use IEEE.STD_LOGIC_1164.ALL; 40 | use IEEE.NUMERIC_STD.ALL; 41 | 42 | entity clocks is 43 | port ( 44 | -- 28 MHz master clock 45 | CLK : in std_logic; 46 | -- Master reset 47 | nRESET : in std_logic; 48 | 49 | -- 1.75 MHz clock enable for sound 50 | CLKEN_PSG : out std_logic; 51 | -- 3.5 MHz clock enable (1 in 8) 52 | CLKEN_CPU : out std_logic; 53 | -- 14 MHz clock enable (out of phase with CPU) 54 | CLKEN_VID : out std_logic 55 | ); 56 | end clocks; 57 | 58 | -- Clock enables for uncontended VRAM access 59 | -- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 60 | -- CPU VID VID VID VID VID VID VID VID 61 | -- PSG 62 | 63 | architecture clocks_arch of clocks is 64 | signal counter : unsigned(19 downto 0); 65 | begin 66 | -- X000 67 | CLKEN_CPU <= not (counter(0) or counter(1) or counter(2)); 68 | -- XXX1 69 | CLKEN_VID <= counter(0); 70 | -- 1111 71 | CLKEN_PSG <= counter(0) and counter(1) and counter(2) and counter(3); 72 | 73 | process(nRESET,CLK) 74 | begin 75 | if nRESET = '0' then 76 | counter <= (others => '0'); 77 | elsif falling_edge(CLK) then 78 | counter <= counter + 1; 79 | end if; 80 | end process; 81 | end clocks_arch; 82 | 83 | -------------------------------------------------------------------------------- /ula_port.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library IEEE; 39 | use IEEE.STD_LOGIC_1164.ALL; 40 | use IEEE.NUMERIC_STD.ALL; 41 | 42 | entity ula_port is 43 | port ( 44 | CLK : in std_logic; 45 | nRESET : in std_logic; 46 | 47 | -- CPU interface with separate read/write buses 48 | D_IN : in std_logic_vector(7 downto 0); 49 | D_OUT : out std_logic_vector(7 downto 0); 50 | ENABLE : in std_logic; 51 | nWR : in std_logic; 52 | 53 | BORDER_OUT : out std_logic_vector(2 downto 0); 54 | EAR_OUT : out std_logic; 55 | MIC_OUT : out std_logic; 56 | 57 | KEYB_IN : in std_logic_vector(4 downto 0); 58 | EAR_IN : in std_logic 59 | ); 60 | end ula_port; 61 | 62 | architecture ula_port_arch of ula_port is 63 | begin 64 | process(CLK,nRESET) 65 | begin 66 | if nRESET = '0' then 67 | -- Output register 68 | -- 7,6,5 = N/C 69 | -- 4 = EAR 70 | -- 3 = MIC 71 | -- 2,1,0 = BORDER (G, R, B) 72 | EAR_OUT <= '0'; 73 | MIC_OUT <= '0'; 74 | BORDER_OUT <= (others => '0'); 75 | 76 | -- Input register 77 | D_OUT <= (others => '0'); 78 | elsif rising_edge(CLK) then 79 | -- Register inputs 80 | -- 7 = N/C 81 | -- 6 = EAR 82 | -- 5 = N/C 83 | -- 4-0 = Keyboard 84 | D_OUT <= '0' & EAR_IN & '0' & KEYB_IN; 85 | 86 | if ENABLE = '1' and nWR = '0' then 87 | -- Latch input data to output register 88 | EAR_OUT <= D_IN(4); 89 | MIC_OUT <= D_IN(3); 90 | BORDER_OUT <= D_IN(2 downto 0); 91 | end if; 92 | end if; 93 | end process; 94 | end ula_port_arch; 95 | 96 | -------------------------------------------------------------------------------- /T80/T80_Reg.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- T80 Registers, technology independent 12 | -- 13 | -- Version : 0244 14 | -- 15 | -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) 16 | -- 17 | -- All rights reserved 18 | -- 19 | -- Redistribution and use in source and synthezised forms, with or without 20 | -- modification, are permitted provided that the following conditions are met: 21 | -- 22 | -- Redistributions of source code must retain the above copyright notice, 23 | -- this list of conditions and the following disclaimer. 24 | -- 25 | -- Redistributions in synthesized form must reproduce the above copyright 26 | -- notice, this list of conditions and the following disclaimer in the 27 | -- documentation and/or other materials provided with the distribution. 28 | -- 29 | -- Neither the name of the author nor the names of other contributors may 30 | -- be used to endorse or promote products derived from this software without 31 | -- specific prior written permission. 32 | -- 33 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 34 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 35 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 36 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 37 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 | -- POSSIBILITY OF SUCH DAMAGE. 44 | -- 45 | -- Please report bugs to the author, but before you do so, please 46 | -- make sure that this is not a derivative work and that 47 | -- you have the latest version of this file. 48 | -- 49 | -- The latest version of this file can be found at: 50 | -- http://www.opencores.org/cvsweb.shtml/t51/ 51 | -- 52 | -- Limitations : 53 | -- 54 | -- File history : 55 | -- 56 | -- 0242 : Initial release 57 | -- 58 | -- 0244 : Changed to single register file 59 | -- 60 | 61 | library IEEE; 62 | use IEEE.std_logic_1164.all; 63 | use IEEE.numeric_std.all; 64 | 65 | entity T80_Reg is 66 | port( 67 | Clk : in std_logic; 68 | CEN : in std_logic; 69 | WEH : in std_logic; 70 | WEL : in std_logic; 71 | AddrA : in std_logic_vector(2 downto 0); 72 | AddrB : in std_logic_vector(2 downto 0); 73 | AddrC : in std_logic_vector(2 downto 0); 74 | DIH : in std_logic_vector(7 downto 0); 75 | DIL : in std_logic_vector(7 downto 0); 76 | DOAH : out std_logic_vector(7 downto 0); 77 | DOAL : out std_logic_vector(7 downto 0); 78 | DOBH : out std_logic_vector(7 downto 0); 79 | DOBL : out std_logic_vector(7 downto 0); 80 | DOCH : out std_logic_vector(7 downto 0); 81 | DOCL : out std_logic_vector(7 downto 0) 82 | ); 83 | end T80_Reg; 84 | 85 | architecture rtl of T80_Reg is 86 | 87 | type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); 88 | signal RegsH : Register_Image(0 to 7); 89 | signal RegsL : Register_Image(0 to 7); 90 | 91 | begin 92 | 93 | process (Clk) 94 | begin 95 | if Clk'event and Clk = '1' then 96 | if CEN = '1' then 97 | if WEH = '1' then 98 | RegsH(to_integer(unsigned(AddrA))) <= DIH; 99 | end if; 100 | if WEL = '1' then 101 | RegsL(to_integer(unsigned(AddrA))) <= DIL; 102 | end if; 103 | end if; 104 | end if; 105 | end process; 106 | 107 | DOAH <= RegsH(to_integer(unsigned(AddrA))); 108 | DOAL <= RegsL(to_integer(unsigned(AddrA))); 109 | DOBH <= RegsH(to_integer(unsigned(AddrB))); 110 | DOBL <= RegsL(to_integer(unsigned(AddrB))); 111 | DOCH <= RegsH(to_integer(unsigned(AddrC))); 112 | DOCL <= RegsL(to_integer(unsigned(AddrC))); 113 | 114 | end; 115 | -------------------------------------------------------------------------------- /i2s_intf_tb.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2010 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written permission. 20 | -- 21 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 25 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | -- POSSIBILITY OF SUCH DAMAGE. 32 | -- 33 | 34 | library IEEE; 35 | use IEEE.STD_LOGIC_1164.ALL; 36 | use IEEE.STD_LOGIC_ARITH.ALL; 37 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 38 | 39 | entity i2s_intf_tb is 40 | end i2s_intf_tb; 41 | 42 | architecture test of i2s_intf_tb is 43 | component i2s_intf is 44 | generic( 45 | mclk_rate : positive := 12000000; 46 | sample_rate : positive := 8000; 47 | preamble : positive := 1; -- I2S 48 | word_length : positive := 16 49 | ); 50 | port ( 51 | -- 2x MCLK in (e.g. 24 MHz for WM8731 USB mode) 52 | CLK : in std_logic; 53 | nRESET : in std_logic; 54 | 55 | -- Parallel IO 56 | PCM_INL : out std_logic_vector(word_length - 1 downto 0); 57 | PCM_INR : out std_logic_vector(word_length - 1 downto 0); 58 | PCM_OUTL : in std_logic_vector(word_length - 1 downto 0); 59 | PCM_OUTR : in std_logic_vector(word_length - 1 downto 0); 60 | 61 | -- Codec interface (right justified mode) 62 | -- MCLK is generated at half of the CLK input 63 | I2S_MCLK : out std_logic; 64 | -- LRCLK is equal to the sample rate and is synchronous to 65 | -- MCLK. It must be related to MCLK by the oversampling ratio 66 | -- given in the codec datasheet. 67 | I2S_LRCLK : out std_logic; 68 | 69 | -- Data is shifted out on the falling edge of BCLK, sampled 70 | -- on the rising edge. The bit rate is determined such that 71 | -- it is fast enough to fit preamble + word_length bits into 72 | -- each LRCLK half cycle. The last cycle of each word may be 73 | -- stretched to fit to LRCLK. This is OK at least for the 74 | -- WM8731 codec. 75 | -- The first falling edge of each timeslot is always synchronised 76 | -- with the LRCLK edge. 77 | I2S_BCLK : out std_logic; 78 | -- Output bitstream 79 | I2S_DOUT : out std_logic; 80 | -- Input bitstream 81 | I2S_DIN : in std_logic 82 | ); 83 | end component; 84 | 85 | signal clk : std_logic := '0'; 86 | signal nreset : std_logic := '0'; 87 | signal pcminl : std_logic_vector(15 downto 0); 88 | signal pcminr : std_logic_vector(15 downto 0); 89 | signal pcmoutl : std_logic_vector(15 downto 0) := "0011001100110011"; 90 | signal pcmoutr : std_logic_vector(15 downto 0) := "1010101010101010"; 91 | 92 | signal i2smclk : std_logic; 93 | signal i2slrclk : std_logic; 94 | signal i2sbclk : std_logic; 95 | signal i2sdout : std_logic; 96 | signal i2sdin : std_logic := '0'; 97 | begin 98 | uut : i2s_intf port map (clk,nreset,pcminl,pcminr,pcmoutl,pcmoutr, 99 | i2smclk,i2slrclk,i2sbclk,i2sdout,i2sdin); 100 | 101 | -- Serial loopback 102 | i2sdin <= i2sdout; 103 | 104 | clk <= not clk after 100 ps; 105 | 106 | process 107 | begin 108 | wait for 500 ps; 109 | 110 | nreset <= '1'; 111 | end process; 112 | 113 | process 114 | begin 115 | wait for 800000 ps; 116 | 117 | pcmoutl <= "1110001110001100"; 118 | pcmoutr <= "0110110110110111"; 119 | end process; 120 | end test; 121 | -------------------------------------------------------------------------------- /ps2_intf_tb.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2010 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written permission. 20 | -- 21 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 25 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | -- POSSIBILITY OF SUCH DAMAGE. 32 | -- 33 | 34 | library IEEE; 35 | use IEEE.STD_LOGIC_1164.ALL; 36 | use IEEE.STD_LOGIC_ARITH.ALL; 37 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 38 | 39 | entity ps2_intf_tb is 40 | 41 | end ps2_intf_tb; 42 | 43 | architecture tb of ps2_intf_tb is 44 | component ps2_intf is 45 | port( 46 | CLK : in std_logic; 47 | nRESET : in std_logic; 48 | 49 | -- PS/2 interface (could be bi-dir) 50 | PS2_CLK : in std_logic; 51 | PS2_DATA : in std_logic; 52 | 53 | -- Byte-wide data interface - only valid for one clock 54 | -- so must be latched externally if required 55 | DATA : out std_logic_vector(7 downto 0); 56 | VALID : out std_logic; 57 | ERROR : out std_logic 58 | ); 59 | end component; 60 | signal CLK : std_logic := '0'; 61 | signal nRESET : std_logic := '0'; 62 | signal PS2_CLK : std_logic := '1'; 63 | signal PS2_DATA : std_logic := '1'; 64 | signal DATA : std_logic_vector(7 downto 0); 65 | signal VALID : std_logic; 66 | signal ERROR : std_logic; 67 | begin 68 | uut : ps2_intf port map( 69 | CLK,nRESET,PS2_CLK,PS2_DATA,DATA,VALID,ERROR); 70 | 71 | CLK <= not CLK after 100 ps; 72 | 73 | process 74 | begin 75 | wait for 2000 ps; 76 | nRESET <= '1'; 77 | end process; 78 | 79 | process 80 | begin 81 | wait for 2000 ps; 82 | 83 | PS2_DATA <= '0'; --start 84 | PS2_CLK <= '0'; 85 | wait for 2000 ps; 86 | PS2_CLK <= '1'; 87 | wait for 2000 ps; 88 | 89 | PS2_DATA <= '1'; 90 | PS2_CLK <= '0'; 91 | wait for 2000 ps; 92 | PS2_CLK <= '1'; 93 | wait for 2000 ps; 94 | 95 | PS2_DATA <= '0'; 96 | PS2_CLK <= '0'; 97 | wait for 2000 ps; 98 | PS2_CLK <= '1'; 99 | wait for 2000 ps; 100 | 101 | 102 | PS2_DATA <= '1'; 103 | PS2_CLK <= '0'; 104 | wait for 2000 ps; 105 | PS2_CLK <= '1'; 106 | wait for 2000 ps; 107 | 108 | PS2_DATA <= '1'; 109 | PS2_CLK <= '0'; 110 | wait for 2000 ps; 111 | PS2_CLK <= '1'; 112 | wait for 2000 ps; 113 | 114 | PS2_DATA <= '0'; 115 | PS2_CLK <= '0'; 116 | wait for 2000 ps; 117 | PS2_CLK <= '1'; 118 | wait for 2000 ps; 119 | 120 | PS2_DATA <= '0'; 121 | PS2_CLK <= '0'; 122 | wait for 2000 ps; 123 | PS2_CLK <= '1'; 124 | wait for 2000 ps; 125 | 126 | PS2_DATA <= '1'; 127 | PS2_CLK <= '0'; 128 | wait for 2000 ps; 129 | PS2_CLK <= '1'; 130 | wait for 2000 ps; 131 | 132 | PS2_DATA <= '1'; 133 | PS2_CLK <= '0'; 134 | wait for 2000 ps; 135 | PS2_CLK <= '1'; 136 | wait for 2000 ps; 137 | 138 | PS2_DATA <= '0'; -- odd parity 139 | PS2_CLK <= '0'; 140 | wait for 2000 ps; 141 | PS2_CLK <= '1'; 142 | wait for 2000 ps; 143 | 144 | PS2_DATA <= '1'; -- stop 145 | PS2_CLK <= '0'; 146 | wait for 2000 ps; 147 | PS2_CLK <= '1'; 148 | wait for 2000 ps; 149 | end process; 150 | 151 | end tb; 152 | -------------------------------------------------------------------------------- /src/ansi.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file ansi.h 3 | * \brief ANSI escape sequences 4 | * 5 | * Various escape sequences for use with serial terminals. 6 | * Allows enhanced formatting of text including the use of 7 | * positioning and colour. 8 | * 9 | * \author (C) 2007 Mike Stirling 10 | * ($Author: mike $) 11 | * \version $Revision: 24 $ 12 | * \date $Date$ 13 | */ 14 | 15 | #ifndef ANSI_H_ 16 | #define ANSI_H_ 17 | 18 | //! Move the cursor up one row 19 | #define CURSOR_UP "\033[A" 20 | //! Move the cursor up n rows 21 | #define CURSOR_UPn "\033[%dA" 22 | //! Move the cursor down one row 23 | #define CURSOR_DOWN "\033[B" 24 | //! Move the cursor down n rows 25 | #define CURSOR_DOWNn "\033[%dB" 26 | //! Move the cursor forward one column 27 | #define CURSOR_RIGHT "\033[C" 28 | //! Move the cursor forward n column 29 | #define CURSOR_RIGHTn "\033[%dC" 30 | //! Move the cursor back one column 31 | #define CURSOR_LEFT "\033[D" 32 | //! Move the cursor back n columns 33 | #define CURSOR_LEFTn "\033[%dD" 34 | 35 | //! Move the cursor to the start of the next row 36 | #define CURSOR_NL "\033[E" 37 | //! Move the cursor to the start of the previous row 38 | #define CURSOR_PL "\033[F" 39 | 40 | //! Move the cursor to the specified column (1 based) 41 | #define CURSOR_COL "\033[%dG" 42 | //! Move the cursor to the specified row,column (1 based) 43 | #define CURSOR_MOVE "\033[%d;%dH" 44 | 45 | //! Save the current cursor position 46 | #define CURSOR_SAVE "\033[s" 47 | //! Move the cursor to the last saved position 48 | #define CURSOR_RESTORE "\033[u" 49 | 50 | //! Clear from the cursor to the end of the screen 51 | #define CLEAR_AFTER "\033[0J" 52 | //! Clear from the cursor to the start of the screen 53 | #define CLEAR_BEFORE "\033[1J" 54 | //! Clear the entire screen 55 | #define CLEAR_SCREEN "\033[2J" 56 | 57 | //! Clear from the cursor to the end of the line 58 | #define CLEAR_EOL "\033[0K" 59 | //! Clear from the cursor to the start of the line 60 | #define CLEAR_SOL "\033[1K" 61 | //! Clear the current line 62 | #define CLEAR_LINE "\033[2K" 63 | 64 | //! Scroll the page up one line, adding a blank line at the bottom 65 | #define SCROLL_UP "\033[S" 66 | //! Scroll the page up n lines, adding blanks at the bottom 67 | #define SCROLL_UPn "\033[%dS" 68 | //! Scroll the page down one line, adding a blank line at the top 69 | #define SCROLL_DOWN "\033[T" 70 | //! Scroll the page down n lines, adding blanks at the bottom 71 | #define SCROLL_DOWNn "\033[%dT" 72 | 73 | //! Reset all attributes to defaults 74 | #define ATTR_RESET "\033[0m" 75 | //! Select normal character weight 76 | #define ATTR_NORMAL "\033[22m" 77 | //! Select bright text (sometimes rendered as bold) 78 | #define ATTR_BRIGHT "\033[1m" 79 | //! Select dim text (not necessarily supported) 80 | #define ATTR_DIM "\033[2m" 81 | //! Select italic text 82 | #define ATTR_ITALIC "\033[3m" 83 | //! Select underlining 84 | #define ATTR_UNDERLINE "\033[4m" 85 | //! Enable slow blink 86 | #define ATTR_BLINK "\033[5m" 87 | //! Enable fast blink 88 | #define ATTR_FASTBLINK "\033[6m" 89 | //! Cancel blinking 90 | #define ATTR_STEADY "\033[25m" 91 | //! Select inverse polarity text 92 | #define ATTR_INVERSE "\033[7m" 93 | //! Select normal polarity text 94 | #define ATTR_POSITIVE "\033[27m" 95 | 96 | //! Set foreground colour: black 97 | #define FG_BLACK "\033[30m" 98 | //! Set foreground colour: red 99 | #define FG_RED "\033[31m" 100 | //! Set foreground colour: green 101 | #define FG_GREEN "\033[32m" 102 | //! Set foreground colour: yellow 103 | #define FG_YELLOW "\033[33m" 104 | //! Set foreground colour: blue 105 | #define FG_BLUE "\033[34m" 106 | //! Set foreground colour: magenta 107 | #define FG_MAGENTA "\033[35m" 108 | //! Set foreground colour: cyan 109 | #define FG_CYAN "\033[36m" 110 | //! Set foreground colour: white 111 | #define FG_WHITE "\033[37m" 112 | //! Set foreground colour: reset to default 113 | #define FG_RESET "\033[39m" 114 | 115 | //! Set background colour: black 116 | #define BG_BLACK "\033[40m" 117 | //! Set background colour: red 118 | #define BG_RED "\033[41m" 119 | //! Set background colour: green 120 | #define BG_GREEN "\033[42m" 121 | //! Set background colour: yellow 122 | #define BG_YELLOW "\033[43m" 123 | //! Set background colour: blue 124 | #define BG_BLUE "\033[44m" 125 | //! Set background colour: magenta 126 | #define BG_MAGENTA "\033[45m" 127 | //! Set background colour: cyan 128 | #define BG_CYAN "\033[46m" 129 | //! Set background colour: white 130 | #define BG_WHITE "\033[47m" 131 | //! Set background colour: reset to default 132 | #define BG_RESET "\033[49m" 133 | 134 | #endif /*ANSI_H_*/ 135 | -------------------------------------------------------------------------------- /video_tb.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2010 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written permission. 20 | -- 21 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 25 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | -- POSSIBILITY OF SUCH DAMAGE. 32 | -- 33 | 34 | library IEEE; 35 | use IEEE.STD_LOGIC_1164.ALL; 36 | use IEEE.STD_LOGIC_ARITH.ALL; 37 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 38 | 39 | entity video_tb is 40 | 41 | end video_tb; 42 | 43 | architecture video_tb_arch of video_tb is 44 | component video 45 | port ( 46 | -- Master clock (28 MHz) 47 | CLK : in std_logic; 48 | -- Video domain clock enable (14 MHz) 49 | CLKEN : in std_logic; 50 | -- Master reset 51 | nRESET : in std_logic; 52 | 53 | -- Mode 54 | VGA : in std_logic; 55 | 56 | -- Memory interface 57 | VID_A : out std_logic_vector(12 downto 0); 58 | VID_D_IN : in std_logic_vector(7 downto 0); 59 | nVID_RD : out std_logic; 60 | nWAIT : out std_logic; 61 | 62 | -- IO interface 63 | BORDER_IN : in std_logic_vector(2 downto 0); 64 | 65 | -- Video outputs 66 | R : out std_logic_vector(3 downto 0); 67 | G : out std_logic_vector(3 downto 0); 68 | B : out std_logic_vector(3 downto 0); 69 | nVSYNC : out std_logic; 70 | nHSYNC : out std_logic; 71 | nCSYNC : out std_logic; 72 | nHCSYNC : out std_logic; 73 | IS_BORDER : out std_logic; 74 | IS_VALID : out std_logic; 75 | 76 | -- Clock outputs, might be useful 77 | PIXCLK : out std_logic; 78 | FLASHCLK : out std_logic; 79 | 80 | -- Interrupt to CPU (asserted for 32 T-states, 64 ticks) 81 | nIRQ : out std_logic 82 | ); 83 | end component; 84 | signal clk : std_logic := '0'; 85 | signal clken : std_logic; 86 | signal clken_cpu : std_logic; 87 | 88 | signal clken_counter : std_logic_vector(2 downto 0) := "000"; 89 | 90 | signal nreset : std_logic := '0'; 91 | 92 | signal vga : std_logic := '1'; 93 | signal vid_a : std_logic_vector(12 downto 0); 94 | signal vid_d_in : std_logic_vector(7 downto 0) := "10101010"; 95 | signal nvid_rd : std_logic; 96 | signal nwait : std_logic; 97 | 98 | signal border_in : std_logic_vector(2 downto 0) := "111"; 99 | signal r : std_logic_vector(3 downto 0); 100 | signal g : std_logic_vector(3 downto 0); 101 | signal b : std_logic_vector(3 downto 0); 102 | signal nvsync : std_logic; 103 | signal nhsync : std_logic; 104 | signal ncsync : std_logic; 105 | signal nhcsync : std_logic; 106 | 107 | signal is_border : std_logic; 108 | signal is_valid : std_logic; 109 | 110 | signal pixclk : std_logic; 111 | signal flashclk : std_logic; 112 | 113 | signal nirq : std_logic; 114 | 115 | begin 116 | uut: video port map ( 117 | clk,clken,nreset, 118 | vga,vid_a,vid_d_in,nvid_rd,nwait, 119 | border_in,r,g,b,nvsync,nhsync,ncsync,nhcsync, 120 | is_border,is_valid,pixclk,flashclk,nirq 121 | ); 122 | 123 | clken_cpu <= not (clken_counter(0) or clken_counter(1) or clken_counter(2)); 124 | clken <= clken_counter(0); 125 | 126 | -- clk 127 | process 128 | begin 129 | wait for 50 ps; 130 | 131 | clk <= not clk; 132 | end process; 133 | 134 | -- clken 135 | process 136 | begin 137 | wait for 100 ps; 138 | 139 | if nreset = '1' then 140 | clken_counter <= clken_counter + '1'; 141 | end if; 142 | end process; 143 | 144 | process 145 | begin 146 | wait for 500 ps; 147 | 148 | -- release reset 149 | nreset <= '1'; 150 | end process; 151 | end video_tb_arch; 152 | -------------------------------------------------------------------------------- /spi.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2010 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written permission. 20 | -- 21 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 25 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | -- POSSIBILITY OF SUCH DAMAGE. 32 | -- 33 | 34 | -- A master-only SPI interface implementation similar to 35 | -- that found on the Atmel AVR series 36 | 37 | library IEEE; 38 | use IEEE.STD_LOGIC_1164.ALL; 39 | use IEEE.STD_LOGIC_ARITH.ALL; 40 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 41 | use IEEE.NUMERIC_STD.ALL; 42 | 43 | -- SPCR (SPI control register) 44 | -- 45 | -- Bit 46 | -- 7 0 Reserved 47 | -- 6 R/W SPE - SPI enable (set to 1 for normal operation) 48 | -- 5 R/W DORD - Data order, 0 = MSB first (normal), 1 = LSB first 49 | -- 4 1 Reserved 50 | -- 3 R/W CPOL 51 | -- 2 R/W CPHA 52 | -- 1 R/W SPR1 53 | -- 0 R/W SPR0 54 | 55 | -- SPSR (SPI status register) 56 | -- 57 | -- Bit 58 | -- 7 R SPIF (Transfer complete, cleared by writing to SPDR) 59 | -- 6 R WCOL (Write collision) 60 | -- 5-1 0 Reserved 61 | -- 0 R/W SPI2X 62 | 63 | -- SCK rate is defined by 64 | -- SPI2X SPR1 SPR0 65 | -- 0 0 0 CLK/4 66 | -- 0 0 1 CLK/16 67 | -- 0 1 0 CLK/64 68 | -- 0 1 1 CLK/128 69 | -- 1 0 0 CLK/2 70 | -- 1 0 1 CLK/8 71 | -- 1 1 0 CLK/32 72 | -- 1 1 1 CLK/64 73 | 74 | -- SPDR (SPI data register) 75 | -- This is a read/write 8-bit register used for accessing 76 | -- the SPI shift register. Writing to this register starts 77 | -- a new byte transfer. 78 | 79 | -- Register addresses are: 80 | -- A1 A0 Register 81 | -- 0 0 SPDR 82 | -- 0 1 SPCR 83 | -- 1 0 SPSR 84 | -- 1 1 Reserved 85 | 86 | entity spi_master is 87 | port ( 88 | CLK : in std_logic; 89 | CLKEN : in std_logic; 90 | nRESET : in std_logic; 91 | 92 | MOSI : out std_logic; 93 | MISO : in std_logic; 94 | SCK : out std_logic; 95 | nSS : out std_logic; 96 | 97 | D_IN : in std_logic_vector(7 downto 0); 98 | D_OUT : out std_logic_vector(7 downto 0); 99 | 100 | A0 : in std_logic; 101 | 102 | nWR : in std_logic; 103 | ); 104 | end spi_master; 105 | 106 | architecture spi_master_arch of spi_master is 107 | signal shiftreg : std_logic_vector(7 downto 0); 108 | signal counter : std_logic_vector(3 downto 0); 109 | begin 110 | 111 | -- MSb first, connect end of shift register to output 112 | MOSI <= shiftreg(7); 113 | 114 | -- Clock generator 115 | process(nRESET,CLK) 116 | begin 117 | if nRESET = '0' then 118 | elsif rising_edge(CLK) and CLKEN = '1' then 119 | 120 | end if; 121 | end process; 122 | 123 | process(nRESET,CLK) 124 | begin 125 | if nRESET = '0' then 126 | shiftreg <= (others => '1'); -- MOSI idles high 127 | counter <= (others => '0'); 128 | SCK <= '0'; -- SCK idles low 129 | elsif rising_edge(CLK) and CLKEN = '1' then 130 | if counter = '0000' then 131 | -- Idle 132 | if nWR = '0' then 133 | -- Register input data when write strobe asserted 134 | -- and start new transfer 135 | shiftreg <= D_IN; 136 | counter <= '1111'; 137 | end if; 138 | else 139 | -- Busy 140 | if counter(0) = '1' then 141 | -- Shift master data to output on the falling clock edge 142 | SCK <= '0'; 143 | shiftreg(7 downto 1) <= shiftreg(6 downto 0); 144 | else 145 | -- Store slave data on the rising clock edge 146 | SCK <= '1'; 147 | shiftreg(0) <= MISO; 148 | end if; 149 | 150 | -- Decrement counter 151 | counter <= counter - '1'; 152 | end if; 153 | end if; 154 | end process; 155 | 156 | end spi_master_arch; 157 | -------------------------------------------------------------------------------- /src/console.c: -------------------------------------------------------------------------------- 1 | /* 2 | * console.c 3 | * 4 | * Created on: 3 Apr 2010 5 | * Author: mike 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | #include "spectrum.h" 12 | #include "console.h" 13 | 14 | // Current cursor position relative to top-left 15 | static int xpos; 16 | static int ypos; 17 | // Current text drawing attributes 18 | static unsigned char attr; 19 | // Whether or not the cursor is being shown 20 | static int cursor; 21 | // Whether or not an escape sequence is in progress 22 | static int escape; 23 | 24 | #include "font_pearl_8x8.c" 25 | 26 | static void console_handle_attribute(int code) 27 | { 28 | // Handle attribute changes 29 | switch (code) { 30 | case 0: 31 | // Reset 32 | attr = PAPER(WHITE) | INK(BLACK); 33 | break; 34 | case 1: 35 | // Bright 36 | attr |= BRIGHT; 37 | break; 38 | case 2: 39 | // Dim 40 | attr &= ~BRIGHT; 41 | break; 42 | case 5: 43 | // Flash 44 | attr |= FLASH; 45 | break; 46 | case 25: 47 | // Steady 48 | attr &= ~FLASH; 49 | break; 50 | 51 | case 30: 52 | case 39: 53 | // FG Black 54 | attr &= ~INK(WHITE); 55 | attr |= INK(BLACK); 56 | break; 57 | case 31: 58 | // FG Red 59 | attr &= ~INK(WHITE); 60 | attr |= INK(RED); 61 | break; 62 | case 32: 63 | // FG Green 64 | attr &= ~INK(WHITE); 65 | attr |= INK(GREEN); 66 | break; 67 | case 33: 68 | // FG Yellow 69 | attr &= ~INK(WHITE); 70 | attr |= INK(YELLOW); 71 | break; 72 | case 34: 73 | // FG Blue 74 | attr &= ~INK(WHITE); 75 | attr |= INK(BLUE); 76 | break; 77 | case 35: 78 | // FG Magenta 79 | attr &= ~INK(WHITE); 80 | attr |= INK(MAGENTA); 81 | break; 82 | case 36: 83 | // FG Cyan 84 | attr &= ~INK(WHITE); 85 | attr |= INK(CYAN); 86 | break; 87 | case 37: 88 | // FG White 89 | attr &= ~INK(WHITE); 90 | attr |= INK(WHITE); 91 | break; 92 | 93 | case 40: 94 | case 49: 95 | // BG Black 96 | attr &= ~PAPER(WHITE); 97 | attr |= PAPER(BLACK); 98 | break; 99 | case 41: 100 | // BG Red 101 | attr &= ~PAPER(WHITE); 102 | attr |= PAPER(RED); 103 | break; 104 | case 42: 105 | // BG Green 106 | attr &= ~PAPER(WHITE); 107 | attr |= PAPER(GREEN); 108 | break; 109 | case 43: 110 | // BG Yellow 111 | attr &= ~PAPER(WHITE); 112 | attr |= PAPER(YELLOW); 113 | break; 114 | case 44: 115 | // BG Blue 116 | attr &= ~PAPER(WHITE); 117 | attr |= PAPER(BLUE); 118 | break; 119 | case 45: 120 | // BG Magenta 121 | attr &= ~PAPER(WHITE); 122 | attr |= PAPER(MAGENTA); 123 | break; 124 | case 46: 125 | // BG Cyan 126 | attr &= ~PAPER(WHITE); 127 | attr |= PAPER(CYAN); 128 | break; 129 | case 47: 130 | // BG White 131 | attr &= ~PAPER(WHITE); 132 | attr |= PAPER(WHITE); 133 | break; 134 | } 135 | } 136 | 137 | static void console_handle_escape(char c) 138 | { 139 | static int code; 140 | 141 | switch (escape) { 142 | case 1: 143 | // Sequence must start ESC-[ 144 | if (c != '[') 145 | escape = 0; 146 | else { 147 | escape++; 148 | code = 0; 149 | } 150 | break; 151 | case 2: 152 | // Attribute sequences are an integer followed by 'm' 153 | if (c == 'm') { 154 | console_handle_attribute(code); 155 | escape = 0; 156 | } else if ((c >= '0') && (c <= '9')) { 157 | // Convert integer string to numerical value 158 | code *= 10; 159 | code += (int)c - '0'; 160 | } else 161 | // Invalid command sequence 162 | escape = 0; 163 | } 164 | } 165 | 166 | static void console_render_char(char c,int x,int y) 167 | { 168 | const unsigned char *fontptr = &fontdata_pearl8x8[c << 3]; 169 | unsigned char *scrptr = CHAR_ADDR(x,y); 170 | int n; 171 | 172 | for (n = 0; n < 8; n++) { 173 | *scrptr = *fontptr++; 174 | // Next row is 256 bytes away because of the way the screen is scanned 175 | scrptr += 256; 176 | } 177 | } 178 | 179 | // Call to clear the screen and set the cursor back 180 | // to the home position. Attributes are cleared to their default 181 | // values and the cursor is enabled. 182 | void console_cls(void) 183 | { 184 | // Clear screen to paper and set attributes to 185 | // white on black 186 | memset(pSCREEN,0,sizeofSCREEN); 187 | memset(pATTR,PAPER(WHITE) | INK(BLACK),sizeofATTR); 188 | 189 | // Defaults 190 | xpos = ypos = 0; 191 | attr = PAPER(WHITE) | INK(BLACK); 192 | cursor = 1; 193 | escape = 0; 194 | 195 | // Display cursor at location 0,0 196 | *ATTR_ADDR(0,0) = attr | FLASH; 197 | } 198 | 199 | // Define stdio putchar function. We can use printf now 200 | void putchar(char c) 201 | { 202 | if (escape) { 203 | // Route escape codes to the handler - do not display 204 | console_handle_escape(c); 205 | return; 206 | } 207 | 208 | // Clear the cursor at the current location in case we move 209 | *ATTR_ADDR(xpos,ypos) = attr; 210 | 211 | switch (c) { 212 | // Handle special characters 213 | case '\n': 214 | // Newline 215 | ypos++; 216 | // fall through 217 | case '\r': 218 | // Carriage return 219 | xpos = 0; 220 | break; 221 | case '\033': 222 | // Enter escape handler 223 | escape = 1; 224 | break; 225 | default: 226 | // Assume remaining characters are printable 227 | console_render_char(c,xpos++,ypos); 228 | } 229 | 230 | // Handle cursor movement 231 | if (xpos == CONSOLE_WIDTH) { 232 | xpos = 0; 233 | ypos++; 234 | } 235 | if (ypos == CONSOLE_HEIGHT) { 236 | // Scroll display 237 | memcpy(pSCREEN,pSCREEN + CONSOLE_WIDTH * 8,sizeofSCREEN - CONSOLE_WIDTH * 8); 238 | memcpy(pATTR,pATTR + CONSOLE_WIDTH,sizeofATTR - CONSOLE_WIDTH); 239 | ypos--; // Stay on bottom row 240 | } 241 | 242 | // Display cursor if enabled 243 | if (cursor) 244 | *ATTR_ADDR(xpos,ypos) = attr | FLASH; 245 | } 246 | -------------------------------------------------------------------------------- /T80/T80_RegX.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- T80 Registers for Xilinx Select RAM 12 | -- 13 | -- Version : 0244 14 | -- 15 | -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) 16 | -- 17 | -- All rights reserved 18 | -- 19 | -- Redistribution and use in source and synthezised forms, with or without 20 | -- modification, are permitted provided that the following conditions are met: 21 | -- 22 | -- Redistributions of source code must retain the above copyright notice, 23 | -- this list of conditions and the following disclaimer. 24 | -- 25 | -- Redistributions in synthesized form must reproduce the above copyright 26 | -- notice, this list of conditions and the following disclaimer in the 27 | -- documentation and/or other materials provided with the distribution. 28 | -- 29 | -- Neither the name of the author nor the names of other contributors may 30 | -- be used to endorse or promote products derived from this software without 31 | -- specific prior written permission. 32 | -- 33 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 34 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 35 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 36 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 37 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 | -- POSSIBILITY OF SUCH DAMAGE. 44 | -- 45 | -- Please report bugs to the author, but before you do so, please 46 | -- make sure that this is not a derivative work and that 47 | -- you have the latest version of this file. 48 | -- 49 | -- The latest version of this file can be found at: 50 | -- http://www.opencores.org/cvsweb.shtml/t51/ 51 | -- 52 | -- Limitations : 53 | -- 54 | -- File history : 55 | -- 56 | -- 0242 : Initial release 57 | -- 58 | -- 0244 : Removed UNISIM library and added componet declaration 59 | -- 60 | 61 | library IEEE; 62 | use IEEE.std_logic_1164.all; 63 | use IEEE.numeric_std.all; 64 | 65 | entity T80_Reg is 66 | port( 67 | Clk : in std_logic; 68 | CEN : in std_logic; 69 | WEH : in std_logic; 70 | WEL : in std_logic; 71 | AddrA : in std_logic_vector(2 downto 0); 72 | AddrB : in std_logic_vector(2 downto 0); 73 | AddrC : in std_logic_vector(2 downto 0); 74 | DIH : in std_logic_vector(7 downto 0); 75 | DIL : in std_logic_vector(7 downto 0); 76 | DOAH : out std_logic_vector(7 downto 0); 77 | DOAL : out std_logic_vector(7 downto 0); 78 | DOBH : out std_logic_vector(7 downto 0); 79 | DOBL : out std_logic_vector(7 downto 0); 80 | DOCH : out std_logic_vector(7 downto 0); 81 | DOCL : out std_logic_vector(7 downto 0) 82 | ); 83 | end T80_Reg; 84 | 85 | architecture rtl of T80_Reg is 86 | 87 | component RAM16X1D 88 | port( 89 | DPO : out std_ulogic; 90 | SPO : out std_ulogic; 91 | A0 : in std_ulogic; 92 | A1 : in std_ulogic; 93 | A2 : in std_ulogic; 94 | A3 : in std_ulogic; 95 | D : in std_ulogic; 96 | DPRA0 : in std_ulogic; 97 | DPRA1 : in std_ulogic; 98 | DPRA2 : in std_ulogic; 99 | DPRA3 : in std_ulogic; 100 | WCLK : in std_ulogic; 101 | WE : in std_ulogic); 102 | end component; 103 | 104 | signal ENH : std_logic; 105 | signal ENL : std_logic; 106 | 107 | begin 108 | 109 | ENH <= CEN and WEH; 110 | ENL <= CEN and WEL; 111 | 112 | bG1: for I in 0 to 7 generate 113 | begin 114 | Reg1H : RAM16X1D 115 | port map( 116 | DPO => DOBH(i), 117 | SPO => DOAH(i), 118 | A0 => AddrA(0), 119 | A1 => AddrA(1), 120 | A2 => AddrA(2), 121 | A3 => '0', 122 | D => DIH(i), 123 | DPRA0 => AddrB(0), 124 | DPRA1 => AddrB(1), 125 | DPRA2 => AddrB(2), 126 | DPRA3 => '0', 127 | WCLK => Clk, 128 | WE => ENH); 129 | Reg1L : RAM16X1D 130 | port map( 131 | DPO => DOBL(i), 132 | SPO => DOAL(i), 133 | A0 => AddrA(0), 134 | A1 => AddrA(1), 135 | A2 => AddrA(2), 136 | A3 => '0', 137 | D => DIL(i), 138 | DPRA0 => AddrB(0), 139 | DPRA1 => AddrB(1), 140 | DPRA2 => AddrB(2), 141 | DPRA3 => '0', 142 | WCLK => Clk, 143 | WE => ENL); 144 | Reg2H : RAM16X1D 145 | port map( 146 | DPO => DOCH(i), 147 | SPO => open, 148 | A0 => AddrA(0), 149 | A1 => AddrA(1), 150 | A2 => AddrA(2), 151 | A3 => '0', 152 | D => DIH(i), 153 | DPRA0 => AddrC(0), 154 | DPRA1 => AddrC(1), 155 | DPRA2 => AddrC(2), 156 | DPRA3 => '0', 157 | WCLK => Clk, 158 | WE => ENH); 159 | Reg2L : RAM16X1D 160 | port map( 161 | DPO => DOCL(i), 162 | SPO => open, 163 | A0 => AddrA(0), 164 | A1 => AddrA(1), 165 | A2 => AddrA(2), 166 | A3 => '0', 167 | D => DIL(i), 168 | DPRA0 => AddrC(0), 169 | DPRA1 => AddrC(1), 170 | DPRA2 => AddrC(2), 171 | DPRA3 => '0', 172 | WCLK => Clk, 173 | WE => ENL); 174 | end generate; 175 | 176 | end; 177 | -------------------------------------------------------------------------------- /ps2_intf.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | -- PS/2 interface (input only) 39 | -- Based loosely on ps2_ctrl.vhd (c) ALSE. http://www.alse-fr.com 40 | library IEEE; 41 | use IEEE.STD_LOGIC_1164.ALL; 42 | use IEEE.STD_LOGIC_ARITH.ALL; 43 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 44 | 45 | -- This is input-only for the time being 46 | entity ps2_intf is 47 | generic (filter_length : positive := 8); 48 | port( 49 | CLK : in std_logic; 50 | nRESET : in std_logic; 51 | 52 | -- PS/2 interface (could be bi-dir) 53 | PS2_CLK : in std_logic; 54 | PS2_DATA : in std_logic; 55 | 56 | -- Byte-wide data interface - only valid for one clock 57 | -- so must be latched externally if required 58 | DATA : out std_logic_vector(7 downto 0); 59 | VALID : out std_logic; 60 | ERROR : out std_logic 61 | ); 62 | end ps2_intf; 63 | 64 | architecture ps2_intf_arch of ps2_intf is 65 | subtype filter_t is std_logic_vector(filter_length-1 downto 0); 66 | signal clk_filter : filter_t; 67 | 68 | signal ps2_clk_in : std_logic; 69 | signal ps2_dat_in : std_logic; 70 | -- Goes high when a clock falling edge is detected 71 | signal clk_edge : std_logic; 72 | signal bit_count : unsigned (3 downto 0); 73 | signal shiftreg : std_logic_vector(8 downto 0); 74 | signal parity : std_logic; 75 | begin 76 | -- Register input signals 77 | process(nRESET,CLK) 78 | begin 79 | if nRESET = '0' then 80 | ps2_clk_in <= '1'; 81 | ps2_dat_in <= '1'; 82 | clk_filter <= (others => '1'); 83 | clk_edge <= '0'; 84 | elsif rising_edge(CLK) then 85 | -- Register inputs (and filter clock) 86 | ps2_dat_in <= PS2_DATA; 87 | clk_filter <= PS2_CLK & clk_filter(clk_filter'high downto 1); 88 | clk_edge <= '0'; 89 | 90 | if clk_filter = filter_t'(others => '1') then 91 | -- Filtered clock is high 92 | ps2_clk_in <= '1'; 93 | elsif clk_filter = filter_t'(others => '0') then 94 | -- Filter clock is low, check for edge 95 | if ps2_clk_in = '1' then 96 | clk_edge <= '1'; 97 | end if; 98 | ps2_clk_in <= '0'; 99 | end if; 100 | end if; 101 | end process; 102 | 103 | -- Shift in keyboard data 104 | process(nRESET,CLK) 105 | begin 106 | if nRESET = '0' then 107 | bit_count <= (others => '0'); 108 | shiftreg <= (others => '0'); 109 | parity <= '0'; 110 | DATA <= (others => '0'); 111 | VALID <= '0'; 112 | ERROR <= '0'; 113 | elsif rising_edge(CLK) then 114 | -- Clear flags 115 | VALID <= '0'; 116 | ERROR <= '0'; 117 | 118 | if clk_edge = '1' then 119 | -- We have a new bit from the keyboard for processing 120 | if bit_count = 0 then 121 | -- Idle state, check for start bit (0) only and don't 122 | -- start counting bits until we get it 123 | 124 | parity <= '0'; 125 | 126 | if ps2_dat_in = '0' then 127 | -- This is a start bit 128 | bit_count <= bit_count + 1; 129 | end if; 130 | else 131 | -- Running. 8-bit data comes in LSb first followed by 132 | -- a single stop bit (1) 133 | if bit_count < 10 then 134 | -- Shift in data and parity (9 bits) 135 | bit_count <= bit_count + 1; 136 | shiftreg <= ps2_dat_in & shiftreg(shiftreg'high downto 1); 137 | parity <= parity xor ps2_dat_in; -- Calculate parity 138 | elsif ps2_dat_in = '1' then 139 | -- Valid stop bit received 140 | bit_count <= (others => '0'); -- back to idle 141 | if parity = '1' then 142 | -- Parity correct, submit data to host 143 | DATA <= shiftreg(7 downto 0); 144 | VALID <= '1'; 145 | else 146 | -- Error 147 | ERROR <= '1'; 148 | end if; 149 | else 150 | -- Invalid stop bit 151 | bit_count <= (others => '0'); -- back to idle 152 | ERROR <= '1'; 153 | end if; 154 | end if; 155 | end if; 156 | end if; 157 | end process; 158 | end ps2_intf_arch; 159 | -------------------------------------------------------------------------------- /T80/T80sed.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- ** CUSTOM 2 CLOCK MEMORY ACCESS FOR PACMAN, MIKEJ ** 11 | -- 12 | -- Z80 compatible microprocessor core, synchronous top level with clock enable 13 | -- Different timing than the original z80 14 | -- Inputs needs to be synchronous and outputs may glitch 15 | -- 16 | -- Version : 0238 17 | -- 18 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 19 | -- 20 | -- All rights reserved 21 | -- 22 | -- Redistribution and use in source and synthezised forms, with or without 23 | -- modification, are permitted provided that the following conditions are met: 24 | -- 25 | -- Redistributions of source code must retain the above copyright notice, 26 | -- this list of conditions and the following disclaimer. 27 | -- 28 | -- Redistributions in synthesized form must reproduce the above copyright 29 | -- notice, this list of conditions and the following disclaimer in the 30 | -- documentation and/or other materials provided with the distribution. 31 | -- 32 | -- Neither the name of the author nor the names of other contributors may 33 | -- be used to endorse or promote products derived from this software without 34 | -- specific prior written permission. 35 | -- 36 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 37 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 38 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 40 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 41 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 42 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 44 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46 | -- POSSIBILITY OF SUCH DAMAGE. 47 | -- 48 | -- Please report bugs to the author, but before you do so, please 49 | -- make sure that this is not a derivative work and that 50 | -- you have the latest version of this file. 51 | -- 52 | -- The latest version of this file can be found at: 53 | -- http://www.opencores.org/cvsweb.shtml/t80/ 54 | -- 55 | -- Limitations : 56 | -- 57 | -- File history : 58 | -- 59 | -- 0235 : First release 60 | -- 61 | -- 0236 : Added T2Write generic 62 | -- 63 | -- 0237 : Fixed T2Write with wait state 64 | -- 65 | -- 0238 : Updated for T80 interface change 66 | -- 67 | -- 0242 : Updated for T80 interface change 68 | -- 69 | 70 | library IEEE; 71 | use IEEE.std_logic_1164.all; 72 | use IEEE.numeric_std.all; 73 | use work.T80_Pack.all; 74 | 75 | entity T80sed is 76 | port( 77 | RESET_n : in std_logic; 78 | CLK_n : in std_logic; 79 | CLKEN : in std_logic; 80 | WAIT_n : in std_logic; 81 | INT_n : in std_logic; 82 | NMI_n : in std_logic; 83 | BUSRQ_n : in std_logic; 84 | M1_n : out std_logic; 85 | MREQ_n : out std_logic; 86 | IORQ_n : out std_logic; 87 | RD_n : out std_logic; 88 | WR_n : out std_logic; 89 | RFSH_n : out std_logic; 90 | HALT_n : out std_logic; 91 | BUSAK_n : out std_logic; 92 | A : out std_logic_vector(15 downto 0); 93 | DI : in std_logic_vector(7 downto 0); 94 | DO : out std_logic_vector(7 downto 0) 95 | ); 96 | end T80sed; 97 | 98 | architecture rtl of T80sed is 99 | 100 | signal IntCycle_n : std_logic; 101 | signal NoRead : std_logic; 102 | signal Write : std_logic; 103 | signal IORQ : std_logic; 104 | signal DI_Reg : std_logic_vector(7 downto 0); 105 | signal MCycle : std_logic_vector(2 downto 0); 106 | signal TState : std_logic_vector(2 downto 0); 107 | 108 | begin 109 | 110 | u0 : T80 111 | generic map( 112 | Mode => 0, 113 | IOWait => 1) 114 | port map( 115 | CEN => CLKEN, 116 | M1_n => M1_n, 117 | IORQ => IORQ, 118 | NoRead => NoRead, 119 | Write => Write, 120 | RFSH_n => RFSH_n, 121 | HALT_n => HALT_n, 122 | WAIT_n => Wait_n, 123 | INT_n => INT_n, 124 | NMI_n => NMI_n, 125 | RESET_n => RESET_n, 126 | BUSRQ_n => BUSRQ_n, 127 | BUSAK_n => BUSAK_n, 128 | CLK_n => CLK_n, 129 | A => A, 130 | DInst => DI, 131 | DI => DI_Reg, 132 | DO => DO, 133 | MC => MCycle, 134 | TS => TState, 135 | IntCycle_n => IntCycle_n); 136 | 137 | process (RESET_n, CLK_n) 138 | begin 139 | if RESET_n = '0' then 140 | RD_n <= '1'; 141 | WR_n <= '1'; 142 | IORQ_n <= '1'; 143 | MREQ_n <= '1'; 144 | DI_Reg <= "00000000"; 145 | elsif CLK_n'event and CLK_n = '1' then 146 | if CLKEN = '1' then 147 | RD_n <= '1'; 148 | WR_n <= '1'; 149 | IORQ_n <= '1'; 150 | MREQ_n <= '1'; 151 | if MCycle = "001" then 152 | if TState = "001" or (TState = "010" and Wait_n = '0') then 153 | RD_n <= not IntCycle_n; 154 | MREQ_n <= not IntCycle_n; 155 | IORQ_n <= IntCycle_n; 156 | end if; 157 | if TState = "011" then 158 | MREQ_n <= '0'; 159 | end if; 160 | else 161 | if (TState = "001" or TState = "010") and NoRead = '0' and Write = '0' then 162 | RD_n <= '0'; 163 | IORQ_n <= not IORQ; 164 | MREQ_n <= IORQ; 165 | end if; 166 | if ((TState = "001") or (TState = "010")) and Write = '1' then 167 | WR_n <= '0'; 168 | IORQ_n <= not IORQ; 169 | MREQ_n <= IORQ; 170 | end if; 171 | end if; 172 | if TState = "010" and Wait_n = '1' then 173 | DI_Reg <= DI; 174 | end if; 175 | end if; 176 | end if; 177 | end process; 178 | 179 | end; 180 | -------------------------------------------------------------------------------- /zxmmc.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | -- Emulation of ZXMMC+ interface 38 | -- 39 | -- (C) 2011 Mike Stirling 40 | 41 | library IEEE; 42 | use IEEE.STD_LOGIC_1164.ALL; 43 | use IEEE.NUMERIC_STD.ALL; 44 | 45 | entity zxmmc is 46 | port ( 47 | CLOCK : in std_logic; 48 | nRESET : in std_logic; 49 | CLKEN : in std_logic; 50 | 51 | -- Bus interface 52 | ENABLE : in std_logic; 53 | -- 0 - W - Card chip selects (active low) 54 | -- 1 - RW - SPI tx/rx data register 55 | -- 2 - Not used 56 | -- 3 - RW - Paging control register 57 | RS : in std_logic_vector(1 downto 0); 58 | nWR : in std_logic; 59 | DI : in std_logic_vector(7 downto 0); 60 | DO : out std_logic_vector(7 downto 0); 61 | 62 | -- SD card interface 63 | SD_CS0 : out std_logic; 64 | SD_CS1 : out std_logic; 65 | SD_CLK : out std_logic; 66 | SD_MOSI : out std_logic; 67 | SD_MISO : in std_logic; 68 | 69 | -- Paging control for external RAM/ROM banks 70 | EXT_WR_EN : out std_logic; -- Enable writes to external RAM/ROM 71 | EXT_RD_EN : out std_logic; -- Enable reads from external RAM/ROM (overlay internal ROM) 72 | EXT_ROM_nRAM : out std_logic; -- Select external ROM or RAM banks 73 | EXT_BANK : out std_logic_vector(4 downto 0); -- Selected bank number 74 | 75 | -- DIP switches (reset values for corresponding bits above) 76 | INIT_RD_EN : in std_logic; 77 | INIT_ROM_nRAM : in std_logic 78 | ); 79 | end entity; 80 | 81 | architecture rtl of zxmmc is 82 | signal counter : unsigned(3 downto 0); 83 | -- Shift register has an extra bit because we write on the 84 | -- falling edge and read on the rising edge 85 | signal shift_reg : std_logic_vector(8 downto 0); 86 | signal in_reg : std_logic_vector(7 downto 0); 87 | signal paging_reg : std_logic_vector(7 downto 0); 88 | begin 89 | -- Input register read when RS=1 90 | DO <= 91 | in_reg when RS="01" else 92 | paging_reg when RS="11" else 93 | (others => '1'); 94 | 95 | -- Paging control outputs from register 96 | EXT_WR_EN <= paging_reg(7); 97 | EXT_RD_EN <= paging_reg(6); 98 | EXT_ROM_nRAM <= paging_reg(5); 99 | EXT_BANK <= paging_reg(4 downto 0); 100 | 101 | -- SD card outputs from clock divider and shift register 102 | SD_CLK <= counter(0); 103 | SD_MOSI <= shift_reg(8); 104 | 105 | -- Chip selects 106 | process(CLOCK,nRESET) 107 | begin 108 | if nRESET = '0' then 109 | SD_CS0 <= '1'; 110 | SD_CS1 <= '1'; 111 | elsif rising_edge(CLOCK) and CLKEN = '1' then 112 | if ENABLE = '1' and RS = "00" and nWR = '0' then 113 | -- The two chip select outputs are controlled directly 114 | -- by writes to the lowest two bits of the control register 115 | SD_CS0 <= DI(0); 116 | SD_CS1 <= DI(1); 117 | end if; 118 | end if; 119 | end process; 120 | 121 | -- Paging register writes 122 | process(CLOCK,nRESET) 123 | begin 124 | if nRESET = '0' then 125 | paging_reg <= "0" & INIT_RD_EN & INIT_ROM_nRAM & "00000"; 126 | elsif rising_edge(CLOCK) and CLKEN = '1' then 127 | if ENABLE = '1' and RS = "11" and nWR = '0' then 128 | paging_reg <= DI; 129 | end if; 130 | end if; 131 | end process; 132 | 133 | -- SPI write 134 | process(CLOCK,nRESET) 135 | begin 136 | if nRESET = '0' then 137 | shift_reg <= (others => '1'); 138 | in_reg <= (others => '1'); 139 | counter <= "1111"; -- Idle 140 | elsif rising_edge(CLOCK) and CLKEN = '1' then 141 | if counter = "1111" then 142 | -- Store previous shift register value in input register 143 | in_reg <= shift_reg(7 downto 0); 144 | 145 | -- Idle - check for a bus access 146 | if ENABLE = '1' and RS = "01" then 147 | -- Write loads shift register with data 148 | -- Read loads it with all 1s 149 | if nWR = '1' then 150 | shift_reg <= (others => '1'); 151 | else 152 | shift_reg <= DI & '1'; 153 | end if; 154 | counter <= "0000"; -- Initiates transfer 155 | end if; 156 | else 157 | -- Transfer in progress 158 | counter <= counter + 1; 159 | 160 | if counter(0) = '0' then 161 | -- Input next bit on rising edge 162 | shift_reg(0) <= SD_MISO; 163 | else 164 | -- Output next bit on falling edge 165 | shift_reg <= shift_reg(7 downto 0) & '1'; 166 | end if; 167 | end if; 168 | end if; 169 | end process; 170 | end architecture; 171 | -------------------------------------------------------------------------------- /YM2149/YM2149_tb.vhd: -------------------------------------------------------------------------------- 1 | 2 | use std.textio.ALL; 3 | library ieee; 4 | use ieee.std_logic_1164.all; 5 | use ieee.std_logic_arith.all; 6 | use ieee.std_logic_unsigned.all; 7 | 8 | entity YM2149_TB is 9 | end; 10 | 11 | architecture Sim of YM2149_TB is 12 | component YM2149 13 | port ( 14 | -- data bus 15 | I_DA : in std_logic_vector(7 downto 0); 16 | O_DA : out std_logic_vector(7 downto 0); 17 | O_DA_OE_L : out std_logic; 18 | -- control 19 | I_A9_L : in std_logic; 20 | I_A8 : in std_logic; 21 | I_BDIR : in std_logic; 22 | I_BC2 : in std_logic; 23 | I_BC1 : in std_logic; 24 | I_SEL_L : in std_logic; 25 | 26 | O_AUDIO : out std_logic_vector(7 downto 0); 27 | -- port a 28 | I_IOA : in std_logic_vector(7 downto 0); 29 | O_IOA : out std_logic_vector(7 downto 0); 30 | O_IOA_OE_L : out std_logic; 31 | -- port b 32 | I_IOB : in std_logic_vector(7 downto 0); 33 | O_IOB : out std_logic_vector(7 downto 0); 34 | O_IOB_OE_L : out std_logic; 35 | 36 | ENA : in std_logic; -- clock enable for higher speed operation 37 | RESET_L : in std_logic; 38 | CLK : in std_logic -- note 6 Mhz 39 | ); 40 | end component; 41 | 42 | -- signals 43 | constant CLKPERIOD : time := 25 ns; 44 | signal func : string(8 downto 1); 45 | 46 | signal clk : std_logic; 47 | signal reset_l : std_logic; 48 | signal reset_h : std_logic; 49 | 50 | signal da_in : std_logic_vector(7 downto 0); 51 | signal da_out : std_logic_vector(7 downto 0); 52 | signal da_oe_l : std_logic; 53 | signal bdir : std_logic; 54 | signal bc2 : std_logic; 55 | signal bc1 : std_logic; 56 | signal audio : std_logic_vector(7 downto 0); 57 | signal ioa_in : std_logic_vector(7 downto 0); 58 | signal ioa_out : std_logic_vector(7 downto 0); 59 | signal ioa_oe_l : std_logic; 60 | signal iob_in : std_logic_vector(7 downto 0); 61 | signal iob_out : std_logic_vector(7 downto 0); 62 | signal iob_oe_l : std_logic; 63 | begin 64 | u0 : YM2149 65 | port map ( 66 | -- data bus 67 | I_DA => da_in, 68 | O_DA => da_out, 69 | O_DA_OE_L => da_oe_l, 70 | -- control 71 | I_A9_L => '0', 72 | I_A8 => '1', 73 | I_BDIR => bdir, 74 | I_BC2 => bc2, 75 | I_BC1 => bc1, 76 | I_SEL_L => '1', 77 | 78 | O_AUDIO => audio, 79 | -- port a 80 | I_IOA => ioa_in, 81 | O_IOA => ioa_out, 82 | O_IOA_OE_L => ioa_oe_l, 83 | -- port b 84 | I_IOB => iob_in, 85 | O_IOB => iob_out, 86 | O_IOB_OE_L => iob_oe_l, 87 | 88 | ENA => '1', 89 | RESET_L => reset_l, 90 | CLK => clk 91 | ); 92 | 93 | p_clk : process 94 | begin 95 | CLK <= '0'; 96 | wait for CLKPERIOD / 2; 97 | CLK <= '1'; 98 | wait for CLKPERIOD - (CLKPERIOD / 2); 99 | end process; 100 | 101 | p_debug_comb : process(bdir, bc2, bc1) 102 | variable sel : std_logic_vector(2 downto 0); 103 | begin 104 | func <= "-XXXXXX-"; 105 | sel := bdir & bc2 & bc1; 106 | case sel is 107 | when "000" | 108 | "010" | 109 | "101" => func <= "inactive"; 110 | when "001" | 111 | "100" | 112 | "111" => func <= "address "; 113 | when "011" => func <= "read "; 114 | when "110" => func <= "write "; 115 | when others => null; 116 | end case; 117 | end process; 118 | 119 | p_test : process 120 | 121 | procedure write( 122 | addr : in bit_vector(3 downto 0); 123 | data : in bit_vector(7 downto 0) 124 | ) is 125 | begin 126 | wait until rising_edge(clk); 127 | -- addr 128 | bdir <= '1'; 129 | bc2 <= '1'; 130 | bc1 <= '1'; 131 | da_in <= x"0" & to_stdlogicvector(addr); 132 | wait for 300 ns; 133 | bdir <= '0'; 134 | bc2 <= '0'; 135 | bc1 <= '0'; 136 | wait for 80 ns; 137 | da_in <= (others => 'Z'); 138 | wait for 100 ns; 139 | -- write 140 | bdir <= '1'; 141 | bc2 <= '1'; 142 | bc1 <= '0'; 143 | da_in <= to_stdlogicvector(data); 144 | wait for 300 ns; 145 | bdir <= '0'; 146 | bc2 <= '0'; 147 | bc1 <= '0'; 148 | wait for 80 ns; 149 | da_in <= (others => 'Z'); 150 | wait for 100 ns; 151 | wait until rising_edge(clk); 152 | 153 | end write; 154 | 155 | procedure read( 156 | addr : in bit_vector(3 downto 0) 157 | ) is 158 | begin 159 | wait until rising_edge(clk); 160 | -- addr 161 | bdir <= '1'; 162 | bc2 <= '1'; 163 | bc1 <= '1'; 164 | da_in <= x"0" & to_stdlogicvector(addr); 165 | wait for 300 ns; 166 | bdir <= '0'; 167 | bc2 <= '0'; 168 | bc1 <= '0'; 169 | wait for 80 ns; 170 | da_in <= (others => 'Z'); 171 | wait for 100 ns; 172 | -- read 173 | bdir <= '0'; 174 | bc2 <= '1'; 175 | bc1 <= '1'; 176 | da_in <= (others => 'Z'); 177 | wait for 300 ns; 178 | bdir <= '0'; 179 | bc2 <= '0'; 180 | bc1 <= '0'; 181 | wait for 180 ns; 182 | wait until rising_edge(clk); 183 | 184 | end read; 185 | 186 | begin 187 | reset_l <= '0'; 188 | reset_h <= '1'; 189 | da_in <= (others => 'Z'); 190 | bdir <= '0'; 191 | bc2 <= '0'; 192 | bc1 <= '0'; 193 | wait for 100 ns; 194 | reset_l <= '1'; 195 | reset_h <= '0'; 196 | wait until rising_edge(clk); 197 | wait until rising_edge(clk); 198 | wait until rising_edge(clk); 199 | write(x"0",x"08"); 200 | write(x"1",x"00"); 201 | read(x"0"); 202 | wait for 500 ns; 203 | write(x"7",x"fb"); 204 | write(x"8",x"00"); 205 | write(x"a",x"0f"); 206 | write(x"B",x"00"); 207 | write(x"C",x"00"); 208 | write(x"D",x"0E"); 209 | wait; 210 | end process; 211 | 212 | end Sim; 213 | 214 | -------------------------------------------------------------------------------- /T80/T80se.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- Z80 compatible microprocessor core, synchronous top level with clock enable 12 | -- Different timing than the original z80 13 | -- Inputs needs to be synchronous and outputs may glitch 14 | -- 15 | -- Version : 0240 16 | -- 17 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 18 | -- 19 | -- All rights reserved 20 | -- 21 | -- Redistribution and use in source and synthezised forms, with or without 22 | -- modification, are permitted provided that the following conditions are met: 23 | -- 24 | -- Redistributions of source code must retain the above copyright notice, 25 | -- this list of conditions and the following disclaimer. 26 | -- 27 | -- Redistributions in synthesized form must reproduce the above copyright 28 | -- notice, this list of conditions and the following disclaimer in the 29 | -- documentation and/or other materials provided with the distribution. 30 | -- 31 | -- Neither the name of the author nor the names of other contributors may 32 | -- be used to endorse or promote products derived from this software without 33 | -- specific prior written permission. 34 | -- 35 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 37 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 39 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 | -- POSSIBILITY OF SUCH DAMAGE. 46 | -- 47 | -- Please report bugs to the author, but before you do so, please 48 | -- make sure that this is not a derivative work and that 49 | -- you have the latest version of this file. 50 | -- 51 | -- The latest version of this file can be found at: 52 | -- http://www.opencores.org/cvsweb.shtml/t80/ 53 | -- 54 | -- Limitations : 55 | -- 56 | -- File history : 57 | -- 58 | -- 0235 : First release 59 | -- 60 | -- 0236 : Added T2Write generic 61 | -- 62 | -- 0237 : Fixed T2Write with wait state 63 | -- 64 | -- 0238 : Updated for T80 interface change 65 | -- 66 | -- 0240 : Updated for T80 interface change 67 | -- 68 | -- 0242 : Updated for T80 interface change 69 | -- 70 | library IEEE; 71 | use IEEE.std_logic_1164.all; 72 | use IEEE.numeric_std.all; 73 | use work.T80_Pack.all; 74 | 75 | entity T80se is 76 | generic( 77 | Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 78 | T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 79 | IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle 80 | ); 81 | port( 82 | RESET_n : in std_logic; 83 | CLK_n : in std_logic; 84 | CLKEN : in std_logic; 85 | WAIT_n : in std_logic; 86 | INT_n : in std_logic; 87 | NMI_n : in std_logic; 88 | BUSRQ_n : in std_logic; 89 | M1_n : out std_logic; 90 | MREQ_n : out std_logic; 91 | IORQ_n : out std_logic; 92 | RD_n : out std_logic; 93 | WR_n : out std_logic; 94 | RFSH_n : out std_logic; 95 | HALT_n : out std_logic; 96 | BUSAK_n : out std_logic; 97 | A : out std_logic_vector(15 downto 0); 98 | DI : in std_logic_vector(7 downto 0); 99 | DO : out std_logic_vector(7 downto 0) 100 | ); 101 | end T80se; 102 | 103 | architecture rtl of T80se is 104 | 105 | signal IntCycle_n : std_logic; 106 | signal NoRead : std_logic; 107 | signal Write : std_logic; 108 | signal IORQ : std_logic; 109 | signal DI_Reg : std_logic_vector(7 downto 0); 110 | signal MCycle : std_logic_vector(2 downto 0); 111 | signal TState : std_logic_vector(2 downto 0); 112 | 113 | begin 114 | 115 | u0 : T80 116 | generic map( 117 | Mode => Mode, 118 | IOWait => IOWait) 119 | port map( 120 | CEN => CLKEN, 121 | M1_n => M1_n, 122 | IORQ => IORQ, 123 | NoRead => NoRead, 124 | Write => Write, 125 | RFSH_n => RFSH_n, 126 | HALT_n => HALT_n, 127 | WAIT_n => Wait_n, 128 | INT_n => INT_n, 129 | NMI_n => NMI_n, 130 | RESET_n => RESET_n, 131 | BUSRQ_n => BUSRQ_n, 132 | BUSAK_n => BUSAK_n, 133 | CLK_n => CLK_n, 134 | A => A, 135 | DInst => DI, 136 | DI => DI_Reg, 137 | DO => DO, 138 | MC => MCycle, 139 | TS => TState, 140 | IntCycle_n => IntCycle_n); 141 | 142 | process (RESET_n, CLK_n) 143 | begin 144 | if RESET_n = '0' then 145 | RD_n <= '1'; 146 | WR_n <= '1'; 147 | IORQ_n <= '1'; 148 | MREQ_n <= '1'; 149 | DI_Reg <= "00000000"; 150 | elsif CLK_n'event and CLK_n = '1' then 151 | if CLKEN = '1' then 152 | RD_n <= '1'; 153 | WR_n <= '1'; 154 | IORQ_n <= '1'; 155 | MREQ_n <= '1'; 156 | if MCycle = "001" then 157 | if TState = "001" or (TState = "010" and Wait_n = '0') then 158 | RD_n <= not IntCycle_n; 159 | MREQ_n <= not IntCycle_n; 160 | IORQ_n <= IntCycle_n; 161 | end if; 162 | if TState = "011" then 163 | MREQ_n <= '0'; 164 | end if; 165 | else 166 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then 167 | RD_n <= '0'; 168 | IORQ_n <= not IORQ; 169 | MREQ_n <= IORQ; 170 | end if; 171 | if T2Write = 0 then 172 | if TState = "010" and Write = '1' then 173 | WR_n <= '0'; 174 | IORQ_n <= not IORQ; 175 | MREQ_n <= IORQ; 176 | end if; 177 | else 178 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then 179 | WR_n <= '0'; 180 | IORQ_n <= not IORQ; 181 | MREQ_n <= IORQ; 182 | end if; 183 | end if; 184 | end if; 185 | if TState = "010" and Wait_n = '1' then 186 | DI_Reg <= DI; 187 | end if; 188 | end if; 189 | end if; 190 | end process; 191 | 192 | end; 193 | -------------------------------------------------------------------------------- /T80/T8080se.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- 8080 compatible microprocessor core, synchronous top level with clock enable 12 | -- Different timing than the original 8080 13 | -- Inputs needs to be synchronous and outputs may glitch 14 | -- 15 | -- Version : 0242 16 | -- 17 | -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) 18 | -- 19 | -- All rights reserved 20 | -- 21 | -- Redistribution and use in source and synthezised forms, with or without 22 | -- modification, are permitted provided that the following conditions are met: 23 | -- 24 | -- Redistributions of source code must retain the above copyright notice, 25 | -- this list of conditions and the following disclaimer. 26 | -- 27 | -- Redistributions in synthesized form must reproduce the above copyright 28 | -- notice, this list of conditions and the following disclaimer in the 29 | -- documentation and/or other materials provided with the distribution. 30 | -- 31 | -- Neither the name of the author nor the names of other contributors may 32 | -- be used to endorse or promote products derived from this software without 33 | -- specific prior written permission. 34 | -- 35 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 37 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 39 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 | -- POSSIBILITY OF SUCH DAMAGE. 46 | -- 47 | -- Please report bugs to the author, but before you do so, please 48 | -- make sure that this is not a derivative work and that 49 | -- you have the latest version of this file. 50 | -- 51 | -- The latest version of this file can be found at: 52 | -- http://www.opencores.org/cvsweb.shtml/t80/ 53 | -- 54 | -- Limitations : 55 | -- STACK status output not supported 56 | -- 57 | -- File history : 58 | -- 59 | -- 0237 : First version 60 | -- 61 | -- 0238 : Updated for T80 interface change 62 | -- 63 | -- 0240 : Updated for T80 interface change 64 | -- 65 | -- 0242 : Updated for T80 interface change 66 | -- 67 | 68 | library IEEE; 69 | use IEEE.std_logic_1164.all; 70 | use IEEE.numeric_std.all; 71 | use work.T80_Pack.all; 72 | 73 | entity T8080se is 74 | generic( 75 | Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 76 | T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 77 | ); 78 | port( 79 | RESET_n : in std_logic; 80 | CLK : in std_logic; 81 | CLKEN : in std_logic; 82 | READY : in std_logic; 83 | HOLD : in std_logic; 84 | INT : in std_logic; 85 | INTE : out std_logic; 86 | DBIN : out std_logic; 87 | SYNC : out std_logic; 88 | VAIT : out std_logic; 89 | HLDA : out std_logic; 90 | WR_n : out std_logic; 91 | A : out std_logic_vector(15 downto 0); 92 | DI : in std_logic_vector(7 downto 0); 93 | DO : out std_logic_vector(7 downto 0) 94 | ); 95 | end T8080se; 96 | 97 | architecture rtl of T8080se is 98 | 99 | signal IntCycle_n : std_logic; 100 | signal NoRead : std_logic; 101 | signal Write : std_logic; 102 | signal IORQ : std_logic; 103 | signal INT_n : std_logic; 104 | signal HALT_n : std_logic; 105 | signal BUSRQ_n : std_logic; 106 | signal BUSAK_n : std_logic; 107 | signal DO_i : std_logic_vector(7 downto 0); 108 | signal DI_Reg : std_logic_vector(7 downto 0); 109 | signal MCycle : std_logic_vector(2 downto 0); 110 | signal TState : std_logic_vector(2 downto 0); 111 | signal One : std_logic; 112 | 113 | begin 114 | 115 | INT_n <= not INT; 116 | BUSRQ_n <= HOLD; 117 | HLDA <= not BUSAK_n; 118 | SYNC <= '1' when TState = "001" else '0'; 119 | VAIT <= '1' when TState = "010" else '0'; 120 | One <= '1'; 121 | 122 | DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA 123 | DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n 124 | DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! 125 | DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA 126 | DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT 127 | DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 128 | DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP 129 | DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR 130 | 131 | u0 : T80 132 | generic map( 133 | Mode => Mode, 134 | IOWait => 0) 135 | port map( 136 | CEN => CLKEN, 137 | M1_n => open, 138 | IORQ => IORQ, 139 | NoRead => NoRead, 140 | Write => Write, 141 | RFSH_n => open, 142 | HALT_n => HALT_n, 143 | WAIT_n => READY, 144 | INT_n => INT_n, 145 | NMI_n => One, 146 | RESET_n => RESET_n, 147 | BUSRQ_n => One, 148 | BUSAK_n => BUSAK_n, 149 | CLK_n => CLK, 150 | A => A, 151 | DInst => DI, 152 | DI => DI_Reg, 153 | DO => DO_i, 154 | MC => MCycle, 155 | TS => TState, 156 | IntCycle_n => IntCycle_n, 157 | IntE => INTE); 158 | 159 | process (RESET_n, CLK) 160 | begin 161 | if RESET_n = '0' then 162 | DBIN <= '0'; 163 | WR_n <= '1'; 164 | DI_Reg <= "00000000"; 165 | elsif CLK'event and CLK = '1' then 166 | if CLKEN = '1' then 167 | DBIN <= '0'; 168 | WR_n <= '1'; 169 | if MCycle = "001" then 170 | if TState = "001" or (TState = "010" and READY = '0') then 171 | DBIN <= IntCycle_n; 172 | end if; 173 | else 174 | if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then 175 | DBIN <= '1'; 176 | end if; 177 | if T2Write = 0 then 178 | if TState = "010" and Write = '1' then 179 | WR_n <= '0'; 180 | end if; 181 | else 182 | if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then 183 | WR_n <= '0'; 184 | end if; 185 | end if; 186 | end if; 187 | if TState = "010" and READY = '1' then 188 | DI_Reg <= DI; 189 | end if; 190 | end if; 191 | end if; 192 | end process; 193 | 194 | end; 195 | -------------------------------------------------------------------------------- /i2s_intf.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library IEEE; 39 | use IEEE.STD_LOGIC_1164.ALL; 40 | use IEEE.STD_LOGIC_ARITH.ALL; 41 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 42 | 43 | entity i2s_intf is 44 | generic( 45 | mclk_rate : positive := 12000000; 46 | sample_rate : positive := 8000; 47 | preamble : positive := 1; -- I2S 48 | word_length : positive := 16 49 | ); 50 | 51 | port ( 52 | -- 2x MCLK in (e.g. 24 MHz for WM8731 USB mode) 53 | CLK : in std_logic; 54 | nRESET : in std_logic; 55 | 56 | -- Parallel IO 57 | PCM_INL : out std_logic_vector(word_length - 1 downto 0); 58 | PCM_INR : out std_logic_vector(word_length - 1 downto 0); 59 | PCM_OUTL : in std_logic_vector(word_length - 1 downto 0); 60 | PCM_OUTR : in std_logic_vector(word_length - 1 downto 0); 61 | 62 | -- Codec interface (right justified mode) 63 | -- MCLK is generated at half of the CLK input 64 | I2S_MCLK : out std_logic; 65 | -- LRCLK is equal to the sample rate and is synchronous to 66 | -- MCLK. It must be related to MCLK by the oversampling ratio 67 | -- given in the codec datasheet. 68 | I2S_LRCLK : out std_logic; 69 | 70 | -- Data is shifted out on the falling edge of BCLK, sampled 71 | -- on the rising edge. The bit rate is determined such that 72 | -- it is fast enough to fit preamble + word_length bits into 73 | -- each LRCLK half cycle. The last cycle of each word may be 74 | -- stretched to fit to LRCLK. This is OK at least for the 75 | -- WM8731 codec. 76 | -- The first falling edge of each timeslot is always synchronised 77 | -- with the LRCLK edge. 78 | I2S_BCLK : out std_logic; 79 | -- Output bitstream 80 | I2S_DOUT : out std_logic; 81 | -- Input bitstream 82 | I2S_DIN : in std_logic 83 | ); 84 | end i2s_intf; 85 | 86 | architecture i2s_intf_arch of i2s_intf is 87 | constant ratio_mclk_fs : positive := (mclk_rate / sample_rate); 88 | constant lrdivider_top : positive := (ratio_mclk_fs / 2) - 1; 89 | constant bdivider_top : positive := (ratio_mclk_fs / 8 / (preamble + word_length) * 2) - 1; 90 | constant nbits : positive := preamble + word_length; 91 | 92 | subtype lrdivider_t is integer range 0 to lrdivider_top; 93 | subtype bdivider_t is integer range 0 to bdivider_top; 94 | subtype bitcount_t is integer range 0 to nbits; 95 | 96 | signal lrdivider : lrdivider_t; 97 | signal bdivider : bdivider_t; 98 | signal bitcount : bitcount_t; 99 | 100 | signal mclk_r : std_logic; 101 | signal lrclk_r : std_logic; 102 | signal bclk_r : std_logic; 103 | 104 | -- Shift register is long enough for the number of data bits 105 | -- plus the preamble, plus an extra bit on the right to register 106 | -- the incoming data 107 | signal shiftreg : std_logic_vector(nbits downto 0); 108 | begin 109 | I2S_MCLK <= mclk_r; 110 | I2S_LRCLK <= lrclk_r; 111 | I2S_BCLK <= bclk_r; 112 | I2S_DOUT <= shiftreg(nbits); -- data goes out MSb first 113 | 114 | process(nRESET,CLK) 115 | begin 116 | if nRESET = '0' then 117 | PCM_INL <= (others => '0'); 118 | PCM_INR <= (others => '0'); 119 | 120 | -- Preload down-counters for clock generation 121 | lrdivider <= lrdivider_top; 122 | bdivider <= bdivider_top; 123 | bitcount <= nbits; 124 | 125 | mclk_r <= '0'; 126 | lrclk_r <= '0'; 127 | bclk_r <= '0'; 128 | shiftreg <= (others => '0'); 129 | elsif rising_edge(CLK) then 130 | -- Generate MCLK at half input clock rate 131 | mclk_r <= not mclk_r; 132 | 133 | -- Generate LRCLK at rate specified by codec configuration 134 | if lrdivider = 0 then 135 | -- LRCLK divider has reached 0 - start again from the top 136 | lrdivider <= lrdivider_top; 137 | 138 | -- Generate LRCLK edge and sync the BCLK counter 139 | lrclk_r <= not lrclk_r; 140 | bclk_r <= '0'; 141 | bitcount <= nbits; -- 1 extra required for setup 142 | bdivider <= bdivider_top; 143 | 144 | -- Load shift register with output data padding preamble 145 | -- with 0s. Load output buses with input word from the 146 | -- previous timeslot. 147 | shiftreg(nbits downto nbits - preamble + 1) <= (others => '0'); 148 | if lrclk_r = '0' then 149 | -- Previous channel input is LEFT. This is available in the 150 | -- shift register at the end of a cycle, right justified 151 | PCM_INL <= shiftreg(word_length - 1 downto 0); 152 | -- Next channel to output is RIGHT. Load this into the 153 | -- shift register at the start of a cycle, left justified 154 | shiftreg(word_length downto 1) <= PCM_OUTR; 155 | else 156 | -- Previous channel input is RIGHT 157 | PCM_INR <= shiftreg(word_length - 1 downto 0); 158 | -- Next channel is LEFT 159 | shiftreg(word_length downto 1) <= PCM_OUTL; 160 | end if; 161 | else 162 | -- Decrement the LRCLK counter 163 | lrdivider <= lrdivider - 1; 164 | 165 | -- Generate BCLK at a suitable rate to fit the required number 166 | -- of bits into each timeslot. Data is changed on the falling edge, 167 | -- sampled on the rising edge 168 | if bdivider = 0 then 169 | -- If all bits have been output for this phase then 170 | -- stop and wait to sync back up with LRCLK 171 | if bitcount > 0 then 172 | -- Reset 173 | bdivider <= bdivider_top; 174 | 175 | -- Toggle BCLK 176 | bclk_r <= not bclk_r; 177 | if bclk_r = '0' then 178 | -- Rising edge - shift in current bit and decrement bit counter 179 | bitcount <= bitcount - 1; 180 | shiftreg(0) <= I2S_DIN; 181 | else 182 | -- Falling edge - shift out next bit 183 | shiftreg(nbits downto 1) <= shiftreg(nbits - 1 downto 0); 184 | end if; 185 | end if; 186 | else 187 | -- Decrement the BCLK counter 188 | bdivider <= bdivider - 1; 189 | end if; 190 | end if; 191 | 192 | end if; 193 | end process; 194 | end i2s_intf_arch; 195 | 196 | -------------------------------------------------------------------------------- /keyboard.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | -- PS/2 scancode to Spectrum matrix conversion 39 | library IEEE; 40 | use IEEE.STD_LOGIC_1164.ALL; 41 | use IEEE.NUMERIC_STD.ALL; 42 | 43 | entity keyboard is 44 | port ( 45 | CLK : in std_logic; 46 | nRESET : in std_logic; 47 | 48 | -- PS/2 interface 49 | PS2_CLK : in std_logic; 50 | PS2_DATA : in std_logic; 51 | 52 | -- CPU address bus (row) 53 | A : in std_logic_vector(15 downto 0); 54 | -- Column outputs to ULA 55 | KEYB : out std_logic_vector(4 downto 0) 56 | ); 57 | end keyboard; 58 | 59 | architecture rtl of keyboard is 60 | 61 | -- PS/2 interface 62 | component ps2_intf is 63 | generic (filter_length : positive := 8); 64 | port( 65 | CLK : in std_logic; 66 | nRESET : in std_logic; 67 | 68 | -- PS/2 interface (could be bi-dir) 69 | PS2_CLK : in std_logic; 70 | PS2_DATA : in std_logic; 71 | 72 | -- Byte-wide data interface - only valid for one clock 73 | -- so must be latched externally if required 74 | DATA : out std_logic_vector(7 downto 0); 75 | VALID : out std_logic; 76 | ERROR : out std_logic 77 | ); 78 | end component; 79 | 80 | -- Interface to PS/2 block 81 | signal keyb_data : std_logic_vector(7 downto 0); 82 | signal keyb_valid : std_logic; 83 | signal keyb_error : std_logic; 84 | 85 | -- Internal signals 86 | type key_matrix is array (7 downto 0) of std_logic_vector(4 downto 0); 87 | signal keys : key_matrix; 88 | signal release : std_logic; 89 | signal extended : std_logic; 90 | begin 91 | 92 | ps2 : ps2_intf port map ( 93 | CLK, nRESET, 94 | PS2_CLK, PS2_DATA, 95 | keyb_data, keyb_valid, keyb_error 96 | ); 97 | 98 | -- Output addressed row to ULA 99 | KEYB <= keys(0) when A(8) = '0' else 100 | keys(1) when A(9) = '0' else 101 | keys(2) when A(10) = '0' else 102 | keys(3) when A(11) = '0' else 103 | keys(4) when A(12) = '0' else 104 | keys(5) when A(13) = '0' else 105 | keys(6) when A(14) = '0' else 106 | keys(7) when A(15) = '0' else 107 | (others => '1'); 108 | 109 | process(nRESET,CLK) 110 | begin 111 | if nRESET = '0' then 112 | release <= '0'; 113 | extended <= '0'; 114 | 115 | keys(0) <= (others => '1'); 116 | keys(1) <= (others => '1'); 117 | keys(2) <= (others => '1'); 118 | keys(3) <= (others => '1'); 119 | keys(4) <= (others => '1'); 120 | keys(5) <= (others => '1'); 121 | keys(6) <= (others => '1'); 122 | keys(7) <= (others => '1'); 123 | elsif rising_edge(CLK) then 124 | if keyb_valid = '1' then 125 | if keyb_data = X"e0" then 126 | -- Extended key code follows 127 | extended <= '1'; 128 | elsif keyb_data = X"f0" then 129 | -- Release code follows 130 | release <= '1'; 131 | else 132 | -- Cancel extended/release flags for next time 133 | release <= '0'; 134 | extended <= '0'; 135 | 136 | case keyb_data is 137 | when X"12" => keys(0)(0) <= release; -- Left shift (CAPS SHIFT) 138 | when X"59" => keys(0)(0) <= release; -- Right shift (CAPS SHIFT) 139 | when X"1a" => keys(0)(1) <= release; -- Z 140 | when X"22" => keys(0)(2) <= release; -- X 141 | when X"21" => keys(0)(3) <= release; -- C 142 | when X"2a" => keys(0)(4) <= release; -- V 143 | 144 | when X"1c" => keys(1)(0) <= release; -- A 145 | when X"1b" => keys(1)(1) <= release; -- S 146 | when X"23" => keys(1)(2) <= release; -- D 147 | when X"2b" => keys(1)(3) <= release; -- F 148 | when X"34" => keys(1)(4) <= release; -- G 149 | 150 | when X"15" => keys(2)(0) <= release; -- Q 151 | when X"1d" => keys(2)(1) <= release; -- W 152 | when X"24" => keys(2)(2) <= release; -- E 153 | when X"2d" => keys(2)(3) <= release; -- R 154 | when X"2c" => keys(2)(4) <= release; -- T 155 | 156 | when X"16" => keys(3)(0) <= release; -- 1 157 | when X"1e" => keys(3)(1) <= release; -- 2 158 | when X"26" => keys(3)(2) <= release; -- 3 159 | when X"25" => keys(3)(3) <= release; -- 4 160 | when X"2e" => keys(3)(4) <= release; -- 5 161 | 162 | when X"45" => keys(4)(0) <= release; -- 0 163 | when X"46" => keys(4)(1) <= release; -- 9 164 | when X"3e" => keys(4)(2) <= release; -- 8 165 | when X"3d" => keys(4)(3) <= release; -- 7 166 | when X"36" => keys(4)(4) <= release; -- 6 167 | 168 | when X"4d" => keys(5)(0) <= release; -- P 169 | when X"44" => keys(5)(1) <= release; -- O 170 | when X"43" => keys(5)(2) <= release; -- I 171 | when X"3c" => keys(5)(3) <= release; -- U 172 | when X"35" => keys(5)(4) <= release; -- Y 173 | 174 | when X"5a" => keys(6)(0) <= release; -- ENTER 175 | when X"4b" => keys(6)(1) <= release; -- L 176 | when X"42" => keys(6)(2) <= release; -- K 177 | when X"3b" => keys(6)(3) <= release; -- J 178 | when X"33" => keys(6)(4) <= release; -- H 179 | 180 | when X"29" => keys(7)(0) <= release; -- SPACE 181 | when X"14" => keys(7)(1) <= release; -- CTRL (Symbol Shift) 182 | when X"3a" => keys(7)(2) <= release; -- M 183 | when X"31" => keys(7)(3) <= release; -- N 184 | when X"32" => keys(7)(4) <= release; -- B 185 | 186 | -- Cursor keys - these are actually extended (E0 xx), but 187 | -- the scancodes for the numeric keypad cursor keys are 188 | -- are the same but without the extension, so we'll accept 189 | -- the codes whether they are extended or not 190 | when X"6B" => keys(0)(0) <= release; -- Left (CAPS 5) 191 | keys(3)(4) <= release; 192 | when X"72" => keys(0)(0) <= release; -- Down (CAPS 6) 193 | keys(4)(4) <= release; 194 | when X"75" => keys(0)(0) <= release; -- Up (CAPS 7) 195 | keys(4)(3) <= release; 196 | when X"74" => keys(0)(0) <= release; -- Right (CAPS 8) 197 | keys(4)(2) <= release; 198 | 199 | -- Other special keys sent to the ULA as key combinations 200 | when X"66" => keys(0)(0) <= release; -- Backspace (CAPS 0) 201 | keys(4)(0) <= release; 202 | when X"58" => keys(0)(0) <= release; -- Caps lock (CAPS 2) 203 | keys(3)(1) <= release; 204 | when X"76" => keys(0)(0) <= release; -- Escape (CAPS SPACE) 205 | keys(7)(0) <= release; 206 | 207 | when others => 208 | null; 209 | end case; 210 | end if; 211 | end if; 212 | end if; 213 | end process; 214 | 215 | end architecture; 216 | -------------------------------------------------------------------------------- /T80/T80a.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- Z80 compatible microprocessor core, asynchronous top level 12 | -- 13 | -- Version : 0247 14 | -- 15 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 16 | -- 17 | -- All rights reserved 18 | -- 19 | -- Redistribution and use in source and synthezised forms, with or without 20 | -- modification, are permitted provided that the following conditions are met: 21 | -- 22 | -- Redistributions of source code must retain the above copyright notice, 23 | -- this list of conditions and the following disclaimer. 24 | -- 25 | -- Redistributions in synthesized form must reproduce the above copyright 26 | -- notice, this list of conditions and the following disclaimer in the 27 | -- documentation and/or other materials provided with the distribution. 28 | -- 29 | -- Neither the name of the author nor the names of other contributors may 30 | -- be used to endorse or promote products derived from this software without 31 | -- specific prior written permission. 32 | -- 33 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 34 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 35 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 36 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 37 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 | -- POSSIBILITY OF SUCH DAMAGE. 44 | -- 45 | -- Please report bugs to the author, but before you do so, please 46 | -- make sure that this is not a derivative work and that 47 | -- you have the latest version of this file. 48 | -- 49 | -- The latest version of this file can be found at: 50 | -- http://www.opencores.org/cvsweb.shtml/t80/ 51 | -- 52 | -- Limitations : 53 | -- 54 | -- File history : 55 | -- 56 | -- 0208 : First complete release 57 | -- 58 | -- 0211 : Fixed interrupt cycle 59 | -- 60 | -- 0235 : Updated for T80 interface change 61 | -- 62 | -- 0238 : Updated for T80 interface change 63 | -- 64 | -- 0240 : Updated for T80 interface change 65 | -- 66 | -- 0242 : Updated for T80 interface change 67 | -- 68 | -- 0247 : Fixed bus req/ack cycle 69 | -- 70 | 71 | library IEEE; 72 | use IEEE.std_logic_1164.all; 73 | use IEEE.numeric_std.all; 74 | use work.T80_Pack.all; 75 | 76 | entity T80a is 77 | generic( 78 | Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 79 | ); 80 | port( 81 | RESET_n : in std_logic; 82 | CLK_n : in std_logic; 83 | WAIT_n : in std_logic; 84 | INT_n : in std_logic; 85 | NMI_n : in std_logic; 86 | BUSRQ_n : in std_logic; 87 | M1_n : out std_logic; 88 | MREQ_n : out std_logic; 89 | IORQ_n : out std_logic; 90 | RD_n : out std_logic; 91 | WR_n : out std_logic; 92 | RFSH_n : out std_logic; 93 | HALT_n : out std_logic; 94 | BUSAK_n : out std_logic; 95 | A : out std_logic_vector(15 downto 0); 96 | D : inout std_logic_vector(7 downto 0) 97 | ); 98 | end T80a; 99 | 100 | architecture rtl of T80a is 101 | 102 | signal CEN : std_logic; 103 | signal Reset_s : std_logic; 104 | signal IntCycle_n : std_logic; 105 | signal IORQ : std_logic; 106 | signal NoRead : std_logic; 107 | signal Write : std_logic; 108 | signal MREQ : std_logic; 109 | signal MReq_Inhibit : std_logic; 110 | signal Req_Inhibit : std_logic; 111 | signal RD : std_logic; 112 | signal MREQ_n_i : std_logic; 113 | signal IORQ_n_i : std_logic; 114 | signal RD_n_i : std_logic; 115 | signal WR_n_i : std_logic; 116 | signal RFSH_n_i : std_logic; 117 | signal BUSAK_n_i : std_logic; 118 | signal A_i : std_logic_vector(15 downto 0); 119 | signal DO : std_logic_vector(7 downto 0); 120 | signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser 121 | signal Wait_s : std_logic; 122 | signal MCycle : std_logic_vector(2 downto 0); 123 | signal TState : std_logic_vector(2 downto 0); 124 | 125 | begin 126 | 127 | CEN <= '1'; 128 | 129 | BUSAK_n <= BUSAK_n_i; 130 | MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); 131 | RD_n_i <= not RD or Req_Inhibit; 132 | 133 | MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; 134 | IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; 135 | RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; 136 | WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; 137 | RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; 138 | A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); 139 | D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); 140 | 141 | process (RESET_n, CLK_n) 142 | begin 143 | if RESET_n = '0' then 144 | Reset_s <= '0'; 145 | elsif CLK_n'event and CLK_n = '1' then 146 | Reset_s <= '1'; 147 | end if; 148 | end process; 149 | 150 | u0 : T80 151 | generic map( 152 | Mode => Mode, 153 | IOWait => 1) 154 | port map( 155 | CEN => CEN, 156 | M1_n => M1_n, 157 | IORQ => IORQ, 158 | NoRead => NoRead, 159 | Write => Write, 160 | RFSH_n => RFSH_n_i, 161 | HALT_n => HALT_n, 162 | WAIT_n => Wait_s, 163 | INT_n => INT_n, 164 | NMI_n => NMI_n, 165 | RESET_n => Reset_s, 166 | BUSRQ_n => BUSRQ_n, 167 | BUSAK_n => BUSAK_n_i, 168 | CLK_n => CLK_n, 169 | A => A_i, 170 | DInst => D, 171 | DI => DI_Reg, 172 | DO => DO, 173 | MC => MCycle, 174 | TS => TState, 175 | IntCycle_n => IntCycle_n); 176 | 177 | process (CLK_n) 178 | begin 179 | if CLK_n'event and CLK_n = '0' then 180 | Wait_s <= WAIT_n; 181 | if TState = "011" and BUSAK_n_i = '1' then 182 | DI_Reg <= to_x01(D); 183 | end if; 184 | end if; 185 | end process; 186 | 187 | process (Reset_s,CLK_n) 188 | begin 189 | if Reset_s = '0' then 190 | WR_n_i <= '1'; 191 | elsif CLK_n'event and CLK_n = '1' then 192 | WR_n_i <= '1'; 193 | if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! 194 | WR_n_i <= not Write; 195 | end if; 196 | end if; 197 | end process; 198 | 199 | process (Reset_s,CLK_n) 200 | begin 201 | if Reset_s = '0' then 202 | Req_Inhibit <= '0'; 203 | elsif CLK_n'event and CLK_n = '1' then 204 | if MCycle = "001" and TState = "010" then 205 | Req_Inhibit <= '1'; 206 | else 207 | Req_Inhibit <= '0'; 208 | end if; 209 | end if; 210 | end process; 211 | 212 | process (Reset_s,CLK_n) 213 | begin 214 | if Reset_s = '0' then 215 | MReq_Inhibit <= '0'; 216 | elsif CLK_n'event and CLK_n = '0' then 217 | if MCycle = "001" and TState = "010" then 218 | MReq_Inhibit <= '1'; 219 | else 220 | MReq_Inhibit <= '0'; 221 | end if; 222 | end if; 223 | end process; 224 | 225 | process(Reset_s,CLK_n) 226 | begin 227 | if Reset_s = '0' then 228 | RD <= '0'; 229 | IORQ_n_i <= '1'; 230 | MREQ <= '0'; 231 | elsif CLK_n'event and CLK_n = '0' then 232 | 233 | if MCycle = "001" then 234 | if TState = "001" then 235 | RD <= IntCycle_n; 236 | MREQ <= IntCycle_n; 237 | IORQ_n_i <= IntCycle_n; 238 | end if; 239 | if TState = "011" then 240 | RD <= '0'; 241 | IORQ_n_i <= '1'; 242 | MREQ <= '1'; 243 | end if; 244 | if TState = "100" then 245 | MREQ <= '0'; 246 | end if; 247 | else 248 | if TState = "001" and NoRead = '0' then 249 | RD <= not Write; 250 | IORQ_n_i <= not IORQ; 251 | MREQ <= not IORQ; 252 | end if; 253 | if TState = "011" then 254 | RD <= '0'; 255 | IORQ_n_i <= '1'; 256 | MREQ <= '0'; 257 | end if; 258 | end if; 259 | end if; 260 | end process; 261 | 262 | end; 263 | -------------------------------------------------------------------------------- /T80/T80_Pack.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 6 | -- Ver 300 started tidyup 7 | -- MikeJ March 2005 8 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 9 | -- 10 | -- **** 11 | -- 12 | -- Z80 compatible microprocessor core 13 | -- 14 | -- Version : 0242 15 | -- 16 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 17 | -- 18 | -- All rights reserved 19 | -- 20 | -- Redistribution and use in source and synthezised forms, with or without 21 | -- modification, are permitted provided that the following conditions are met: 22 | -- 23 | -- Redistributions of source code must retain the above copyright notice, 24 | -- this list of conditions and the following disclaimer. 25 | -- 26 | -- Redistributions in synthesized form must reproduce the above copyright 27 | -- notice, this list of conditions and the following disclaimer in the 28 | -- documentation and/or other materials provided with the distribution. 29 | -- 30 | -- Neither the name of the author nor the names of other contributors may 31 | -- be used to endorse or promote products derived from this software without 32 | -- specific prior written permission. 33 | -- 34 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 36 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 37 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 38 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 39 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44 | -- POSSIBILITY OF SUCH DAMAGE. 45 | -- 46 | -- Please report bugs to the author, but before you do so, please 47 | -- make sure that this is not a derivative work and that 48 | -- you have the latest version of this file. 49 | -- 50 | -- The latest version of this file can be found at: 51 | -- http://www.opencores.org/cvsweb.shtml/t80/ 52 | -- 53 | -- Limitations : 54 | -- 55 | -- File history : 56 | -- 57 | 58 | library IEEE; 59 | use IEEE.std_logic_1164.all; 60 | 61 | package T80_Pack is 62 | 63 | component T80 64 | generic( 65 | Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 66 | IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle 67 | Flag_C : integer := 0; 68 | Flag_N : integer := 1; 69 | Flag_P : integer := 2; 70 | Flag_X : integer := 3; 71 | Flag_H : integer := 4; 72 | Flag_Y : integer := 5; 73 | Flag_Z : integer := 6; 74 | Flag_S : integer := 7 75 | ); 76 | port( 77 | RESET_n : in std_logic; 78 | CLK_n : in std_logic; 79 | CEN : in std_logic; 80 | WAIT_n : in std_logic; 81 | INT_n : in std_logic; 82 | NMI_n : in std_logic; 83 | BUSRQ_n : in std_logic; 84 | M1_n : out std_logic; 85 | IORQ : out std_logic; 86 | NoRead : out std_logic; 87 | Write : out std_logic; 88 | RFSH_n : out std_logic; 89 | HALT_n : out std_logic; 90 | BUSAK_n : out std_logic; 91 | A : out std_logic_vector(15 downto 0); 92 | DInst : in std_logic_vector(7 downto 0); 93 | DI : in std_logic_vector(7 downto 0); 94 | DO : out std_logic_vector(7 downto 0); 95 | MC : out std_logic_vector(2 downto 0); 96 | TS : out std_logic_vector(2 downto 0); 97 | IntCycle_n : out std_logic; 98 | IntE : out std_logic; 99 | Stop : out std_logic 100 | ); 101 | end component; 102 | 103 | component T80_Reg 104 | port( 105 | Clk : in std_logic; 106 | CEN : in std_logic; 107 | WEH : in std_logic; 108 | WEL : in std_logic; 109 | AddrA : in std_logic_vector(2 downto 0); 110 | AddrB : in std_logic_vector(2 downto 0); 111 | AddrC : in std_logic_vector(2 downto 0); 112 | DIH : in std_logic_vector(7 downto 0); 113 | DIL : in std_logic_vector(7 downto 0); 114 | DOAH : out std_logic_vector(7 downto 0); 115 | DOAL : out std_logic_vector(7 downto 0); 116 | DOBH : out std_logic_vector(7 downto 0); 117 | DOBL : out std_logic_vector(7 downto 0); 118 | DOCH : out std_logic_vector(7 downto 0); 119 | DOCL : out std_logic_vector(7 downto 0) 120 | ); 121 | end component; 122 | 123 | component T80_MCode 124 | generic( 125 | Mode : integer := 0; 126 | Flag_C : integer := 0; 127 | Flag_N : integer := 1; 128 | Flag_P : integer := 2; 129 | Flag_X : integer := 3; 130 | Flag_H : integer := 4; 131 | Flag_Y : integer := 5; 132 | Flag_Z : integer := 6; 133 | Flag_S : integer := 7 134 | ); 135 | port( 136 | IR : in std_logic_vector(7 downto 0); 137 | ISet : in std_logic_vector(1 downto 0); 138 | MCycle : in std_logic_vector(2 downto 0); 139 | F : in std_logic_vector(7 downto 0); 140 | NMICycle : in std_logic; 141 | IntCycle : in std_logic; 142 | XY_State : in std_logic_vector(1 downto 0); 143 | MCycles : out std_logic_vector(2 downto 0); 144 | TStates : out std_logic_vector(2 downto 0); 145 | Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD 146 | Inc_PC : out std_logic; 147 | Inc_WZ : out std_logic; 148 | IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc 149 | Read_To_Reg : out std_logic; 150 | Read_To_Acc : out std_logic; 151 | Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F 152 | Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 153 | ALU_Op : out std_logic_vector(3 downto 0); 154 | -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None 155 | Save_ALU : out std_logic; 156 | PreserveC : out std_logic; 157 | Arith16 : out std_logic; 158 | Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI 159 | IORQ : out std_logic; 160 | Jump : out std_logic; 161 | JumpE : out std_logic; 162 | JumpXY : out std_logic; 163 | Call : out std_logic; 164 | RstP : out std_logic; 165 | LDZ : out std_logic; 166 | LDW : out std_logic; 167 | LDSPHL : out std_logic; 168 | Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None 169 | ExchangeDH : out std_logic; 170 | ExchangeRp : out std_logic; 171 | ExchangeAF : out std_logic; 172 | ExchangeRS : out std_logic; 173 | I_DJNZ : out std_logic; 174 | I_CPL : out std_logic; 175 | I_CCF : out std_logic; 176 | I_SCF : out std_logic; 177 | I_RETN : out std_logic; 178 | I_BT : out std_logic; 179 | I_BC : out std_logic; 180 | I_BTR : out std_logic; 181 | I_RLD : out std_logic; 182 | I_RRD : out std_logic; 183 | I_INRC : out std_logic; 184 | SetDI : out std_logic; 185 | SetEI : out std_logic; 186 | IMode : out std_logic_vector(1 downto 0); 187 | Halt : out std_logic; 188 | NoRead : out std_logic; 189 | Write : out std_logic; 190 | XYbit_undoc : out std_logic 191 | ); 192 | end component; 193 | 194 | component T80_ALU 195 | generic( 196 | Mode : integer := 0; 197 | Flag_C : integer := 0; 198 | Flag_N : integer := 1; 199 | Flag_P : integer := 2; 200 | Flag_X : integer := 3; 201 | Flag_H : integer := 4; 202 | Flag_Y : integer := 5; 203 | Flag_Z : integer := 6; 204 | Flag_S : integer := 7 205 | ); 206 | port( 207 | Arith16 : in std_logic; 208 | Z16 : in std_logic; 209 | ALU_Op : in std_logic_vector(3 downto 0); 210 | IR : in std_logic_vector(5 downto 0); 211 | ISet : in std_logic_vector(1 downto 0); 212 | BusA : in std_logic_vector(7 downto 0); 213 | BusB : in std_logic_vector(7 downto 0); 214 | F_In : in std_logic_vector(7 downto 0); 215 | Q : out std_logic_vector(7 downto 0); 216 | F_Out : out std_logic_vector(7 downto 0) 217 | ); 218 | end component; 219 | 220 | end; 221 | -------------------------------------------------------------------------------- /i2c_loader.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library IEEE; 39 | use IEEE.STD_LOGIC_1164.ALL; 40 | use IEEE.STD_LOGIC_ARITH.ALL; 41 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 42 | use IEEE.STD_LOGIC_MISC.ALL; -- for AND_REDUCE 43 | use IEEE.NUMERIC_STD.ALL; 44 | 45 | entity i2c_loader is 46 | generic ( 47 | -- Address of slave to be loaded 48 | device_address : integer := 16#1a#; 49 | -- Number of retries to allow before stopping 50 | num_retries : integer := 0; 51 | -- Length of clock divider in bits. Resulting bus frequency is 52 | -- CLK/2^(log2_divider + 2) 53 | log2_divider : integer := 6 54 | ); 55 | 56 | port ( 57 | CLK : in std_logic; 58 | nRESET : in std_logic; 59 | 60 | I2C_SCL : inout std_logic; 61 | I2C_SDA : inout std_logic; 62 | 63 | IS_DONE : out std_logic; 64 | IS_ERROR : out std_logic 65 | ); 66 | end i2c_loader; 67 | 68 | architecture i2c_loader_arch of i2c_loader is 69 | type regs is array(0 to 19) of std_logic_vector(7 downto 0); 70 | constant init_regs : regs := ( 71 | -- Left line in, 0dB, unmute 72 | X"00", X"17", 73 | -- Right line in, 0dB, unmute 74 | X"02", X"17", 75 | -- Left headphone out, 0dB 76 | X"04", X"79", 77 | -- Right headphone out, 0dB 78 | X"06", X"79", 79 | -- Audio path, DAC enabled, Line in, Bypass off, mic unmuted 80 | X"08", X"10", 81 | -- Digital path, Unmute, HP filter enabled 82 | X"0A", X"00", 83 | -- Power down mic, clkout and xtal osc 84 | X"0C", X"62", 85 | -- Format 16-bit I2S, no bit inversion or phase changes 86 | X"0E", X"02", 87 | -- Sampling control, 8 kHz USB mode (MCLK = 250fs * 6) 88 | --X"10", X"0D", 89 | -- 48 kHz 90 | X"10", X"01", 91 | -- Activate 92 | X"12", X"01" 93 | ); 94 | -- Number of bursts (i.e. total number of registers) 95 | constant burst_length : positive := 2; 96 | -- Number of bytes to transfer per burst 97 | constant num_bursts : positive := (init_regs'length / burst_length); 98 | 99 | type state_t is (Idle, Start, Data, Ack, Stop, Pause, Done); 100 | signal state : state_t; 101 | signal phase : std_logic_vector(1 downto 0); 102 | subtype nbit_t is integer range 0 to 7; 103 | signal nbit : nbit_t; 104 | subtype nbyte_t is integer range 0 to burst_length; -- +1 for address byte 105 | signal nbyte : nbyte_t; 106 | subtype thisbyte_t is integer range 0 to init_regs'length; -- +1 for "done" 107 | signal thisbyte : thisbyte_t; 108 | subtype retries_t is integer range 0 to num_retries; 109 | signal retries : retries_t; 110 | 111 | signal clken : std_logic; 112 | signal divider : std_logic_vector(log2_divider-1 downto 0); 113 | signal shiftreg : std_logic_vector(7 downto 0); 114 | signal scl_out : std_logic; 115 | signal sda_out : std_logic; 116 | signal nak : std_logic; 117 | begin 118 | -- Create open-drain outputs for I2C bus 119 | I2C_SCL <= '0' when scl_out = '0' else 'Z'; 120 | I2C_SDA <= '0' when sda_out = '0' else 'Z'; 121 | -- Status outputs are driven both ways 122 | IS_DONE <= '1' when state = Done else '0'; 123 | IS_ERROR <= nak; 124 | 125 | -- Generate clock enable for desired bus speed 126 | clken <= AND_REDUCE(divider); 127 | process(nRESET,CLK) 128 | begin 129 | if nRESET = '0' then 130 | divider <= (others => '0'); 131 | elsif falling_edge(CLK) then 132 | divider <= divider + '1'; 133 | end if; 134 | end process; 135 | 136 | -- The I2C loader process 137 | process(nRESET,CLK) 138 | begin 139 | if nRESET = '0' then 140 | scl_out <= '1'; 141 | sda_out <= '1'; 142 | state <= Idle; 143 | phase <= "00"; 144 | nbit <= 0; 145 | nbyte <= 0; 146 | thisbyte <= 0; 147 | shiftreg <= (others => '0'); 148 | nak <= '0'; -- No error 149 | retries <= num_retries; 150 | elsif rising_edge(CLK) and clken = '1' then 151 | -- Next phase by default 152 | phase <= phase + 1; 153 | 154 | -- STATE: IDLE 155 | if state = Idle then 156 | -- Start loading the device registers straight away 157 | -- A 'GO' bit could be polled here if required 158 | state <= Start; 159 | phase <= "00"; 160 | scl_out <= '1'; 161 | sda_out <= '1'; 162 | 163 | -- STATE: START 164 | elsif state = Start then 165 | -- Generate START condition 166 | case phase is 167 | when "00" => 168 | -- Drop SDA first 169 | sda_out <= '0'; 170 | when "10" => 171 | -- Then drop SCL 172 | scl_out <= '0'; 173 | when "11" => 174 | -- Advance to next state 175 | -- Shift register loaded with device slave address 176 | state <= Data; 177 | nbit <= 7; 178 | shiftreg <= std_logic_vector(to_unsigned(device_address,7)) & '0'; -- writing 179 | nbyte <= burst_length; 180 | when others => 181 | null; 182 | end case; 183 | 184 | -- STATE: DATA 185 | elsif state = Data then 186 | -- Generate data 187 | case phase is 188 | when "00" => 189 | -- Drop SCL 190 | scl_out <= '0'; 191 | when "01" => 192 | -- Output data and shift (MSb first) 193 | sda_out <= shiftreg(7); 194 | shiftreg <= shiftreg(6 downto 0) & '0'; 195 | when "10" => 196 | -- Raise SCL 197 | scl_out <= '1'; 198 | when "11" => 199 | -- Next bit or advance to next state when done 200 | if nbit = 0 then 201 | state <= Ack; 202 | else 203 | nbit <= nbit - 1; 204 | end if; 205 | when others => 206 | null; 207 | end case; 208 | 209 | -- STATE: ACK 210 | elsif state = Ack then 211 | -- Generate ACK clock and check for error condition 212 | case phase is 213 | when "00" => 214 | -- Drop SCL 215 | scl_out <= '0'; 216 | when "01" => 217 | -- Float data 218 | sda_out <= '1'; 219 | when "10" => 220 | -- Sample ack bit 221 | nak <= I2C_SDA; 222 | if I2C_SDA = '1' then 223 | -- Error 224 | nbyte <= 0; -- Close this burst and skip remaining registers 225 | thisbyte <= init_regs'length; 226 | else 227 | -- Hold ACK to avoid spurious stops - this seems to fix a 228 | -- problem with the Wolfson codec which releases the ACK 229 | -- right on the falling edge of the clock pulse. It looks like 230 | -- the device interprets this is a STOP condition and then fails 231 | -- to acknowledge the next byte. We can avoid this by holding the 232 | -- ACK condition for a little longer. 233 | sda_out <= '0'; 234 | end if; 235 | -- Raise SCL 236 | scl_out <= '1'; 237 | when "11" => 238 | -- Advance to next state 239 | if nbyte = 0 then 240 | -- No more bytes in this burst - generate a STOP 241 | state <= Stop; 242 | else 243 | -- Generate next byte 244 | state <= Data; 245 | nbit <= 7; 246 | shiftreg <= init_regs(thisbyte); 247 | nbyte <= nbyte - 1; 248 | thisbyte <= thisbyte + 1; 249 | end if; 250 | when others => 251 | null; 252 | end case; 253 | 254 | -- STATE: STOP 255 | elsif state = Stop then 256 | -- Generate STOP condition 257 | case phase is 258 | when "00" => 259 | -- Drop SCL first 260 | scl_out <= '0'; 261 | when "01" => 262 | -- Drop SDA 263 | sda_out <= '0'; 264 | when "10" => 265 | -- Raise SCL 266 | scl_out <= '1'; 267 | when "11" => 268 | if thisbyte = init_regs'length then 269 | -- All registers done, advance to finished state. This will 270 | -- bring SDA high while SCL is still high, completing the STOP 271 | -- condition 272 | state <= Done; 273 | else 274 | -- Load the next register after a short delay 275 | state <= Pause; 276 | end if; 277 | when others => 278 | null; 279 | end case; 280 | 281 | -- STATE: PAUSE 282 | elsif state = Pause then 283 | -- Delay for one cycle of 'phase' then start the next burst 284 | scl_out <= '1'; 285 | sda_out <= '1'; 286 | if phase = "11" then 287 | state <= Start; 288 | end if; 289 | 290 | -- STATE: DONE 291 | else 292 | -- Finished 293 | scl_out <= '1'; 294 | sda_out <= '1'; 295 | 296 | if nak = '1' and retries > 0 then 297 | -- We can retry in the event of a NAK in case the 298 | -- slave got out of sync for some reason 299 | retries <= retries - 1; 300 | state <= Idle; 301 | end if; 302 | end if; 303 | end if; 304 | end process; 305 | end i2c_loader_arch; 306 | 307 | -------------------------------------------------------------------------------- /src/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /debugger.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | -- 38 | -- General purpose hardware debugger 39 | -- 40 | -- (C) 2011 Mike Stirling 41 | -- 42 | 43 | library IEEE; 44 | use IEEE.STD_LOGIC_1164.ALL; 45 | use IEEE.NUMERIC_STD.ALL; 46 | 47 | entity debugger is 48 | generic ( 49 | -- Set this for a reasonable half flash duration relative to the 50 | -- clock frequency 51 | flash_divider : natural := 24 52 | ); 53 | port ( 54 | CLOCK : in std_logic; 55 | nRESET : in std_logic; 56 | -- CPU clock enable in 57 | CLKEN_IN : in std_logic; 58 | -- Gated clock enable back out to CPU 59 | CLKEN_OUT : out std_logic; 60 | -- CPU IRQ in 61 | nIRQ_IN : in std_logic; 62 | -- Gated IRQ back out to CPU (no interrupts when single stepping) 63 | nIRQ_OUT : out std_logic; 64 | 65 | -- CPU 66 | A_CPU : in std_logic_vector(15 downto 0); 67 | R_nW : in std_logic; 68 | SYNC : in std_logic; 69 | 70 | -- Aux bus input for display in hex 71 | AUX_BUS : in std_logic_vector(15 downto 0); 72 | 73 | -- Controls 74 | -- RUN or HALT CPU 75 | RUN : in std_logic; 76 | -- Push button to single-step in HALT mode 77 | nSTEP : in std_logic; 78 | -- Push button to cycle display mode 79 | nMODE : in std_logic; 80 | -- Push button to cycle display digit in edit mode 81 | nDIGIT : in std_logic; 82 | -- Push button to cycle digit value in edit mode 83 | nSET : in std_logic; 84 | 85 | -- Output to display 86 | DIGIT3 : out std_logic_vector(6 downto 0); 87 | DIGIT2 : out std_logic_vector(6 downto 0); 88 | DIGIT1 : out std_logic_vector(6 downto 0); 89 | DIGIT0 : out std_logic_vector(6 downto 0); 90 | 91 | LED_BREAKPOINT : out std_logic; 92 | LED_WATCHPOINT : out std_logic 93 | ); 94 | end entity; 95 | 96 | architecture rtl of debugger is 97 | 98 | component seg7 is 99 | port ( 100 | D : in std_logic_vector(3 downto 0); 101 | Q : out std_logic_vector(6 downto 0) 102 | ); 103 | end component; 104 | 105 | -- Current display mode 106 | type mode_t is (modeAddress,modeBreak,modeWatch,modeAux); 107 | signal mode : mode_t; 108 | -- Current edit digit 109 | signal digit : unsigned(1 downto 0); 110 | -- For flashing selected digit 111 | signal counter : unsigned(flash_divider-1 downto 0); 112 | signal flash : std_logic; 113 | -- Selected breakpoint address (stop on instruction fetch) 114 | signal breakpoint : std_logic_vector(15 downto 0); 115 | -- Selected watchpoint address (stop on write) 116 | signal watchpoint : std_logic_vector(15 downto 0); 117 | -- Address of last instruction fetch 118 | signal instr_addr : std_logic_vector(15 downto 0); 119 | -- Break flags 120 | signal halt : std_logic; 121 | -- Set when a request to resume has been received but before 122 | -- the CPU has run 123 | signal resuming : std_logic; 124 | 125 | -- Display interface 126 | signal a_display : std_logic_vector(15 downto 0); 127 | signal d3_display : std_logic_vector(6 downto 0); 128 | signal d2_display : std_logic_vector(6 downto 0); 129 | signal d1_display : std_logic_vector(6 downto 0); 130 | signal d0_display : std_logic_vector(6 downto 0); 131 | 132 | -- Registered button inputs 133 | signal r_step_n : std_logic; 134 | signal r_mode_n : std_logic; 135 | signal r_digit_n : std_logic; 136 | signal r_set_n : std_logic; 137 | 138 | begin 139 | -- Mask CPU clock enable 140 | CLKEN_OUT <= CLKEN_IN and not halt; 141 | -- Mask interrupt 142 | nIRQ_OUT <= nIRQ_IN or not RUN; 143 | 144 | -- Route selected address to display 145 | a_display <= instr_addr when mode = modeAddress else 146 | breakpoint when mode = modeBreak else 147 | watchpoint when mode = modeWatch else 148 | AUX_BUS when mode = modeAux else 149 | (others => '0'); 150 | 151 | -- Generate display digits from binary 152 | d3 : seg7 port map (a_display(15 downto 12),d3_display); 153 | d2 : seg7 port map (a_display(11 downto 8),d2_display); 154 | d1 : seg7 port map (a_display(7 downto 4),d1_display); 155 | d0 : seg7 port map (a_display(3 downto 0),d0_display); 156 | 157 | -- Flash selected digit in edit modes 158 | DIGIT3 <= d3_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "11") else "1111111"; 159 | DIGIT2 <= d2_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "10") else "1111111"; 160 | DIGIT1 <= d1_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "01") else "1111111"; 161 | DIGIT0 <= d0_display when (mode = modeAddress or mode = modeAux or flash = '1' or digit /= "00") else "1111111"; 162 | 163 | -- Show mode on LEDs 164 | LED_BREAKPOINT <= '1' when mode = modeBreak or mode = modeAux else '0'; 165 | LED_WATCHPOINT <= '1' when mode = modeWatch or mode = modeAux else '0'; 166 | 167 | -- Flash counter 168 | process(CLOCK,nRESET) 169 | begin 170 | if nRESET = '0' then 171 | counter <= (others => '0'); 172 | flash <= '0'; 173 | elsif rising_edge(CLOCK) then 174 | counter <= counter + 1; 175 | if counter = 0 then 176 | flash <= not flash; 177 | end if; 178 | end if; 179 | end process; 180 | 181 | -- Register buttons, select input mode and digit 182 | process(CLOCK,nRESET) 183 | begin 184 | if nRESET = '0' then 185 | r_mode_n <= '1'; 186 | r_digit_n <= '1'; 187 | r_set_n <= '1'; 188 | mode <= modeAddress; 189 | digit <= (others => '0'); 190 | elsif rising_edge(CLOCK) then 191 | -- Register buttons 192 | r_mode_n <= nMODE; 193 | r_digit_n <= nDIGIT; 194 | r_set_n <= nSET; 195 | 196 | if r_mode_n = '1' and nMODE = '0' then 197 | -- Increment mode 198 | if mode = modeAddress then 199 | mode <= modeBreak; 200 | elsif mode = modeBreak then 201 | mode <= modeWatch; 202 | elsif mode = modeWatch then 203 | mode <= modeAux; 204 | else 205 | mode <= modeAddress; 206 | end if; 207 | end if; 208 | if r_digit_n = '1' and nDIGIT = '0' then 209 | -- Increment digit 210 | digit <= digit + 1; 211 | end if; 212 | end if; 213 | end process; 214 | 215 | -- Set watchpoint address 216 | process(CLOCK,nRESET) 217 | begin 218 | if nRESET = '0' then 219 | watchpoint <= (others => '0'); 220 | elsif rising_edge(CLOCK) and mode = modeWatch then 221 | if r_set_n = '1' and nSET = '0' then 222 | -- Increment selected digit on each button press 223 | case digit is 224 | when "00" => watchpoint(3 downto 0) <= std_logic_vector(unsigned(watchpoint(3 downto 0)) + 1); 225 | when "01" => watchpoint(7 downto 4) <= std_logic_vector(unsigned(watchpoint(7 downto 4)) + 1); 226 | when "10" => watchpoint(11 downto 8) <= std_logic_vector(unsigned(watchpoint(11 downto 8)) + 1); 227 | when "11" => watchpoint(15 downto 12) <= std_logic_vector(unsigned(watchpoint(15 downto 12)) + 1); 228 | when others => null; 229 | end case; 230 | end if; 231 | end if; 232 | end process; 233 | 234 | -- Set breakpoint address 235 | process(CLOCK,nRESET) 236 | begin 237 | if nRESET = '0' then 238 | breakpoint <= (others => '0'); 239 | elsif rising_edge(CLOCK) and mode = modeBreak then 240 | if r_set_n = '1' and nSET = '0' then 241 | -- Increment selected digit on each button press 242 | case digit is 243 | when "00" => breakpoint(3 downto 0) <= std_logic_vector(unsigned(breakpoint(3 downto 0)) + 1); 244 | when "01" => breakpoint(7 downto 4) <= std_logic_vector(unsigned(breakpoint(7 downto 4)) + 1); 245 | when "10" => breakpoint(11 downto 8) <= std_logic_vector(unsigned(breakpoint(11 downto 8)) + 1); 246 | when "11" => breakpoint(15 downto 12) <= std_logic_vector(unsigned(breakpoint(15 downto 12)) + 1); 247 | 248 | when others => null; 249 | end case; 250 | end if; 251 | end if; 252 | end process; 253 | 254 | -- CPU control logic 255 | process(CLOCK,nRESET) 256 | begin 257 | if nRESET = '0' then 258 | r_step_n <= '1'; 259 | halt <= '0'; 260 | resuming <= '0'; 261 | instr_addr <= (others => '0'); 262 | elsif rising_edge(CLOCK) then 263 | -- Register single-step button 264 | r_step_n <= nSTEP; 265 | 266 | -- Once the CPU has run we can trigger a new halt 267 | if CLKEN_IN = '1' then 268 | resuming <= '0'; 269 | end if; 270 | 271 | if SYNC = '1' then 272 | -- Latch address of instruction fetch 273 | instr_addr <= A_CPU; 274 | end if; 275 | 276 | -- Check for halt conditions if we are not resuming from a previous halt 277 | if resuming = '0' then 278 | if RUN = '0' and SYNC = '1' then 279 | -- If not in RUN mode then halt on any instruction fetch 280 | -- (single-step) 281 | halt <= '1'; 282 | end if; 283 | if A_CPU = breakpoint and SYNC = '1' then 284 | -- Halt CPU when instruction fetched from breakpoint address 285 | halt <= '1'; 286 | end if; 287 | if A_CPU = watchpoint and SYNC = '0' and R_nW = '0' then 288 | -- Halt CPU when data write to watchpoint address 289 | halt <= '1'; 290 | end if; 291 | end if; 292 | 293 | -- Resume or single step when user presses "STEP" button 294 | if r_step_n = '1' and nSTEP = '0' then 295 | resuming <= '1'; 296 | halt <= '0'; 297 | end if; 298 | end if; 299 | end process; 300 | end architecture; 301 | -------------------------------------------------------------------------------- /T80/T80_ALU.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle 6 | -- Ver 300 started tidyup 7 | -- MikeJ March 2005 8 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 9 | -- 10 | -- **** 11 | -- 12 | -- Z80 compatible microprocessor core 13 | -- 14 | -- Version : 0247 15 | -- 16 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 17 | -- 18 | -- All rights reserved 19 | -- 20 | -- Redistribution and use in source and synthezised forms, with or without 21 | -- modification, are permitted provided that the following conditions are met: 22 | -- 23 | -- Redistributions of source code must retain the above copyright notice, 24 | -- this list of conditions and the following disclaimer. 25 | -- 26 | -- Redistributions in synthesized form must reproduce the above copyright 27 | -- notice, this list of conditions and the following disclaimer in the 28 | -- documentation and/or other materials provided with the distribution. 29 | -- 30 | -- Neither the name of the author nor the names of other contributors may 31 | -- be used to endorse or promote products derived from this software without 32 | -- specific prior written permission. 33 | -- 34 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 36 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 37 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 38 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 39 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44 | -- POSSIBILITY OF SUCH DAMAGE. 45 | -- 46 | -- Please report bugs to the author, but before you do so, please 47 | -- make sure that this is not a derivative work and that 48 | -- you have the latest version of this file. 49 | -- 50 | -- The latest version of this file can be found at: 51 | -- http://www.opencores.org/cvsweb.shtml/t80/ 52 | -- 53 | -- Limitations : 54 | -- 55 | -- File history : 56 | -- 57 | -- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test 58 | -- 59 | -- 0238 : Fixed zero flag for 16 bit SBC and ADC 60 | -- 61 | -- 0240 : Added GB operations 62 | -- 63 | -- 0242 : Cleanup 64 | -- 65 | -- 0247 : Cleanup 66 | -- 67 | 68 | library IEEE; 69 | use IEEE.std_logic_1164.all; 70 | use IEEE.numeric_std.all; 71 | 72 | entity T80_ALU is 73 | generic( 74 | Mode : integer := 0; 75 | Flag_C : integer := 0; 76 | Flag_N : integer := 1; 77 | Flag_P : integer := 2; 78 | Flag_X : integer := 3; 79 | Flag_H : integer := 4; 80 | Flag_Y : integer := 5; 81 | Flag_Z : integer := 6; 82 | Flag_S : integer := 7 83 | ); 84 | port( 85 | Arith16 : in std_logic; 86 | Z16 : in std_logic; 87 | ALU_Op : in std_logic_vector(3 downto 0); 88 | IR : in std_logic_vector(5 downto 0); 89 | ISet : in std_logic_vector(1 downto 0); 90 | BusA : in std_logic_vector(7 downto 0); 91 | BusB : in std_logic_vector(7 downto 0); 92 | F_In : in std_logic_vector(7 downto 0); 93 | Q : out std_logic_vector(7 downto 0); 94 | F_Out : out std_logic_vector(7 downto 0) 95 | ); 96 | end T80_ALU; 97 | 98 | architecture rtl of T80_ALU is 99 | 100 | procedure AddSub(A : std_logic_vector; 101 | B : std_logic_vector; 102 | Sub : std_logic; 103 | Carry_In : std_logic; 104 | signal Res : out std_logic_vector; 105 | signal Carry : out std_logic) is 106 | 107 | variable B_i : unsigned(A'length - 1 downto 0); 108 | variable Res_i : unsigned(A'length + 1 downto 0); 109 | begin 110 | if Sub = '1' then 111 | B_i := not unsigned(B); 112 | else 113 | B_i := unsigned(B); 114 | end if; 115 | 116 | Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); 117 | Carry <= Res_i(A'length + 1); 118 | Res <= std_logic_vector(Res_i(A'length downto 1)); 119 | end; 120 | 121 | -- AddSub variables (temporary signals) 122 | signal UseCarry : std_logic; 123 | signal Carry7_v : std_logic; 124 | signal Overflow_v : std_logic; 125 | signal HalfCarry_v : std_logic; 126 | signal Carry_v : std_logic; 127 | signal Q_v : std_logic_vector(7 downto 0); 128 | 129 | signal BitMask : std_logic_vector(7 downto 0); 130 | 131 | begin 132 | 133 | with IR(5 downto 3) select BitMask <= "00000001" when "000", 134 | "00000010" when "001", 135 | "00000100" when "010", 136 | "00001000" when "011", 137 | "00010000" when "100", 138 | "00100000" when "101", 139 | "01000000" when "110", 140 | "10000000" when others; 141 | 142 | UseCarry <= not ALU_Op(2) and ALU_Op(0); 143 | AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); 144 | AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); 145 | AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); 146 | 147 | -- bug fix - parity flag is just parity for 8080, also overflow for Z80 148 | process (Carry_v, Carry7_v, Q_v) 149 | begin 150 | if(Mode=2) then 151 | OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor 152 | Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else 153 | OverFlow_v <= Carry_v xor Carry7_v; 154 | end if; 155 | end process; 156 | 157 | process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) 158 | variable Q_t : std_logic_vector(7 downto 0); 159 | variable DAA_Q : unsigned(8 downto 0); 160 | begin 161 | Q_t := "--------"; 162 | F_Out <= F_In; 163 | DAA_Q := "---------"; 164 | case ALU_Op is 165 | when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => 166 | F_Out(Flag_N) <= '0'; 167 | F_Out(Flag_C) <= '0'; 168 | case ALU_OP(2 downto 0) is 169 | when "000" | "001" => -- ADD, ADC 170 | Q_t := Q_v; 171 | F_Out(Flag_C) <= Carry_v; 172 | F_Out(Flag_H) <= HalfCarry_v; 173 | F_Out(Flag_P) <= OverFlow_v; 174 | when "010" | "011" | "111" => -- SUB, SBC, CP 175 | Q_t := Q_v; 176 | F_Out(Flag_N) <= '1'; 177 | F_Out(Flag_C) <= not Carry_v; 178 | F_Out(Flag_H) <= not HalfCarry_v; 179 | F_Out(Flag_P) <= OverFlow_v; 180 | when "100" => -- AND 181 | Q_t(7 downto 0) := BusA and BusB; 182 | F_Out(Flag_H) <= '1'; 183 | when "101" => -- XOR 184 | Q_t(7 downto 0) := BusA xor BusB; 185 | F_Out(Flag_H) <= '0'; 186 | when others => -- OR "110" 187 | Q_t(7 downto 0) := BusA or BusB; 188 | F_Out(Flag_H) <= '0'; 189 | end case; 190 | if ALU_Op(2 downto 0) = "111" then -- CP 191 | F_Out(Flag_X) <= BusB(3); 192 | F_Out(Flag_Y) <= BusB(5); 193 | else 194 | F_Out(Flag_X) <= Q_t(3); 195 | F_Out(Flag_Y) <= Q_t(5); 196 | end if; 197 | if Q_t(7 downto 0) = "00000000" then 198 | F_Out(Flag_Z) <= '1'; 199 | if Z16 = '1' then 200 | F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC 201 | end if; 202 | else 203 | F_Out(Flag_Z) <= '0'; 204 | end if; 205 | F_Out(Flag_S) <= Q_t(7); 206 | case ALU_Op(2 downto 0) is 207 | when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP 208 | when others => 209 | F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor 210 | Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); 211 | end case; 212 | if Arith16 = '1' then 213 | F_Out(Flag_S) <= F_In(Flag_S); 214 | F_Out(Flag_Z) <= F_In(Flag_Z); 215 | F_Out(Flag_P) <= F_In(Flag_P); 216 | end if; 217 | when "1100" => 218 | -- DAA 219 | F_Out(Flag_H) <= F_In(Flag_H); 220 | F_Out(Flag_C) <= F_In(Flag_C); 221 | DAA_Q(7 downto 0) := unsigned(BusA); 222 | DAA_Q(8) := '0'; 223 | if F_In(Flag_N) = '0' then 224 | -- After addition 225 | -- Alow > 9 or H = 1 226 | if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then 227 | if (DAA_Q(3 downto 0) > 9) then 228 | F_Out(Flag_H) <= '1'; 229 | else 230 | F_Out(Flag_H) <= '0'; 231 | end if; 232 | DAA_Q := DAA_Q + 6; 233 | end if; 234 | -- new Ahigh > 9 or C = 1 235 | if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then 236 | DAA_Q := DAA_Q + 96; -- 0x60 237 | end if; 238 | else 239 | -- After subtraction 240 | if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then 241 | if DAA_Q(3 downto 0) > 5 then 242 | F_Out(Flag_H) <= '0'; 243 | end if; 244 | DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; 245 | end if; 246 | if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then 247 | DAA_Q := DAA_Q - 352; -- 0x160 248 | end if; 249 | end if; 250 | F_Out(Flag_X) <= DAA_Q(3); 251 | F_Out(Flag_Y) <= DAA_Q(5); 252 | F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); 253 | Q_t := std_logic_vector(DAA_Q(7 downto 0)); 254 | if DAA_Q(7 downto 0) = "00000000" then 255 | F_Out(Flag_Z) <= '1'; 256 | else 257 | F_Out(Flag_Z) <= '0'; 258 | end if; 259 | F_Out(Flag_S) <= DAA_Q(7); 260 | F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor 261 | DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); 262 | when "1101" | "1110" => 263 | -- RLD, RRD 264 | Q_t(7 downto 4) := BusA(7 downto 4); 265 | if ALU_Op(0) = '1' then 266 | Q_t(3 downto 0) := BusB(7 downto 4); 267 | else 268 | Q_t(3 downto 0) := BusB(3 downto 0); 269 | end if; 270 | F_Out(Flag_H) <= '0'; 271 | F_Out(Flag_N) <= '0'; 272 | F_Out(Flag_X) <= Q_t(3); 273 | F_Out(Flag_Y) <= Q_t(5); 274 | if Q_t(7 downto 0) = "00000000" then 275 | F_Out(Flag_Z) <= '1'; 276 | else 277 | F_Out(Flag_Z) <= '0'; 278 | end if; 279 | F_Out(Flag_S) <= Q_t(7); 280 | F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor 281 | Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); 282 | when "1001" => 283 | -- BIT 284 | Q_t(7 downto 0) := BusB and BitMask; 285 | F_Out(Flag_S) <= Q_t(7); 286 | if Q_t(7 downto 0) = "00000000" then 287 | F_Out(Flag_Z) <= '1'; 288 | F_Out(Flag_P) <= '1'; 289 | else 290 | F_Out(Flag_Z) <= '0'; 291 | F_Out(Flag_P) <= '0'; 292 | end if; 293 | F_Out(Flag_H) <= '1'; 294 | F_Out(Flag_N) <= '0'; 295 | F_Out(Flag_X) <= '0'; 296 | F_Out(Flag_Y) <= '0'; 297 | if IR(2 downto 0) /= "110" then 298 | F_Out(Flag_X) <= BusB(3); 299 | F_Out(Flag_Y) <= BusB(5); 300 | end if; 301 | when "1010" => 302 | -- SET 303 | Q_t(7 downto 0) := BusB or BitMask; 304 | when "1011" => 305 | -- RES 306 | Q_t(7 downto 0) := BusB and not BitMask; 307 | when "1000" => 308 | -- ROT 309 | case IR(5 downto 3) is 310 | when "000" => -- RLC 311 | Q_t(7 downto 1) := BusA(6 downto 0); 312 | Q_t(0) := BusA(7); 313 | F_Out(Flag_C) <= BusA(7); 314 | when "010" => -- RL 315 | Q_t(7 downto 1) := BusA(6 downto 0); 316 | Q_t(0) := F_In(Flag_C); 317 | F_Out(Flag_C) <= BusA(7); 318 | when "001" => -- RRC 319 | Q_t(6 downto 0) := BusA(7 downto 1); 320 | Q_t(7) := BusA(0); 321 | F_Out(Flag_C) <= BusA(0); 322 | when "011" => -- RR 323 | Q_t(6 downto 0) := BusA(7 downto 1); 324 | Q_t(7) := F_In(Flag_C); 325 | F_Out(Flag_C) <= BusA(0); 326 | when "100" => -- SLA 327 | Q_t(7 downto 1) := BusA(6 downto 0); 328 | Q_t(0) := '0'; 329 | F_Out(Flag_C) <= BusA(7); 330 | when "110" => -- SLL (Undocumented) / SWAP 331 | if Mode = 3 then 332 | Q_t(7 downto 4) := BusA(3 downto 0); 333 | Q_t(3 downto 0) := BusA(7 downto 4); 334 | F_Out(Flag_C) <= '0'; 335 | else 336 | Q_t(7 downto 1) := BusA(6 downto 0); 337 | Q_t(0) := '1'; 338 | F_Out(Flag_C) <= BusA(7); 339 | end if; 340 | when "101" => -- SRA 341 | Q_t(6 downto 0) := BusA(7 downto 1); 342 | Q_t(7) := BusA(7); 343 | F_Out(Flag_C) <= BusA(0); 344 | when others => -- SRL 345 | Q_t(6 downto 0) := BusA(7 downto 1); 346 | Q_t(7) := '0'; 347 | F_Out(Flag_C) <= BusA(0); 348 | end case; 349 | F_Out(Flag_H) <= '0'; 350 | F_Out(Flag_N) <= '0'; 351 | F_Out(Flag_X) <= Q_t(3); 352 | F_Out(Flag_Y) <= Q_t(5); 353 | F_Out(Flag_S) <= Q_t(7); 354 | if Q_t(7 downto 0) = "00000000" then 355 | F_Out(Flag_Z) <= '1'; 356 | else 357 | F_Out(Flag_Z) <= '0'; 358 | end if; 359 | F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor 360 | Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); 361 | if ISet = "00" then 362 | F_Out(Flag_P) <= F_In(Flag_P); 363 | F_Out(Flag_S) <= F_In(Flag_S); 364 | F_Out(Flag_Z) <= F_In(Flag_Z); 365 | end if; 366 | when others => 367 | null; 368 | end case; 369 | Q <= Q_t; 370 | end process; 371 | end; 372 | -------------------------------------------------------------------------------- /video.vhd: -------------------------------------------------------------------------------- 1 | -- ZX Spectrum for Altera DE1 2 | -- 3 | -- Copyright (c) 2009-2011 Mike Stirling 4 | -- 5 | -- All rights reserved 6 | -- 7 | -- Redistribution and use in source and synthezised forms, with or without 8 | -- modification, are permitted provided that the following conditions are met: 9 | -- 10 | -- * Redistributions of source code must retain the above copyright notice, 11 | -- this list of conditions and the following disclaimer. 12 | -- 13 | -- * Redistributions in synthesized form must reproduce the above copyright 14 | -- notice, this list of conditions and the following disclaimer in the 15 | -- documentation and/or other materials provided with the distribution. 16 | -- 17 | -- * Neither the name of the author nor the names of other contributors may 18 | -- be used to endorse or promote products derived from this software without 19 | -- specific prior written agreement from the author. 20 | -- 21 | -- * License is granted for non-commercial use only. A fee may not be charged 22 | -- for redistributions as source code or in synthesized/hardware form without 23 | -- specific prior written agreement from the author. 24 | -- 25 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 29 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | -- POSSIBILITY OF SUCH DAMAGE. 36 | -- 37 | 38 | library IEEE; 39 | use IEEE.STD_LOGIC_1164.ALL; 40 | use IEEE.STD_LOGIC_ARITH.ALL; 41 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 42 | 43 | entity video is 44 | port( 45 | -- Master clock (28 MHz) 46 | CLK : in std_logic; 47 | -- Video domain clock enable (14 MHz) 48 | CLKEN : in std_logic; 49 | -- Master reset 50 | nRESET : in std_logic; 51 | 52 | -- Mode 53 | VGA : in std_logic; 54 | 55 | -- Memory interface 56 | VID_A : out std_logic_vector(12 downto 0); 57 | VID_D_IN : in std_logic_vector(7 downto 0); 58 | nVID_RD : out std_logic; 59 | nWAIT : out std_logic; 60 | 61 | -- IO interface 62 | BORDER_IN : in std_logic_vector(2 downto 0); 63 | 64 | -- Video outputs 65 | R : out std_logic_vector(3 downto 0); 66 | G : out std_logic_vector(3 downto 0); 67 | B : out std_logic_vector(3 downto 0); 68 | nVSYNC : out std_logic; 69 | nHSYNC : out std_logic; 70 | nCSYNC : out std_logic; 71 | nHCSYNC : out std_logic; 72 | IS_BORDER : out std_logic; 73 | IS_VALID : out std_logic; 74 | 75 | -- Clock outputs, might be useful 76 | PIXCLK : out std_logic; 77 | FLASHCLK : out std_logic; 78 | 79 | -- Interrupt to CPU (asserted for 32 T-states, 64 ticks) 80 | nIRQ : out std_logic 81 | ); 82 | end video; 83 | 84 | architecture video_arch of video is 85 | signal pixels : std_logic_vector(9 downto 0); 86 | signal attr : std_logic_vector(7 downto 0); 87 | 88 | -- Video logic runs at 14 MHz so hcounter has an additonal LSb which is 89 | -- skipped if running in VGA scan-doubled mode. The value of this 90 | -- extra bit is 1/2 for the purposes of timing calculations bit 1 is 91 | -- assumed to have a value of 1. 92 | signal hcounter : std_logic_vector(9 downto 0); 93 | -- vcounter has an extra LSb as well except this is skipped if running 94 | -- in PAL mode. By not skipping it in VGA mode we get the required 95 | -- double-scanning of each line. This extra bit has a value 1/2 as well. 96 | signal vcounter : std_logic_vector(9 downto 0); 97 | signal flashcounter : std_logic_vector(4 downto 0); 98 | signal vblanking : std_logic; 99 | signal hblanking : std_logic; 100 | signal hpicture : std_logic; 101 | signal vpicture : std_logic; 102 | signal picture : std_logic; 103 | signal blanking : std_logic; 104 | 105 | signal hsync : std_logic; 106 | signal vsync : std_logic; 107 | 108 | signal red : std_logic; 109 | signal green : std_logic; 110 | signal blue : std_logic; 111 | signal bright : std_logic; 112 | signal dot : std_logic; 113 | begin 114 | -- The first 256 pixels of each line are valid picture 115 | picture <= hpicture and vpicture; 116 | blanking <= hblanking or vblanking; 117 | 118 | -- Generate clocks and enables from internal signals 119 | FLASHCLK <= flashcounter(4); 120 | IS_VALID <= not blanking; 121 | IS_BORDER <= not picture; 122 | -- FIXME: This needs to be halved for PAL mode 123 | PIXCLK <= CLK and CLKEN and nRESET; 124 | 125 | -- Output syncs 126 | nVSYNC <= not vsync; 127 | nHSYNC <= not hsync; 128 | nCSYNC <= not (vsync xor hsync); 129 | -- Combined HSYNC/CSYNC. Feeds HSYNC to VGA HSYNC in VGA mode, 130 | -- or CSYNC to the same pin in PAL mode 131 | nHCSYNC <= not (vsync xor hsync) when VGA = '0' else 132 | not hsync; 133 | 134 | -- Determine the pixel colour 135 | dot <= pixels(9) xor (flashcounter(4) and attr(7)); -- Combine delayed pixel with FLASH attr and clock state 136 | red <= attr(1) when picture = '1' and dot = '1' else 137 | attr(4) when picture = '1' and dot = '0' else 138 | BORDER_IN(1) when blanking = '0' else 139 | '0'; 140 | green <= attr(2) when picture = '1' and dot = '1' else 141 | attr(5) when picture = '1' and dot = '0' else 142 | BORDER_IN(2) when blanking = '0' else 143 | '0'; 144 | blue <= attr(0) when picture = '1' and dot = '1' else 145 | attr(3) when picture = '1' and dot = '0' else 146 | BORDER_IN(0) when blanking = '0' else 147 | '0'; 148 | bright <= attr(6) when picture = '1' else 149 | '0'; 150 | 151 | -- Re-register video output to DACs to clean up edges 152 | process(nRESET,CLK) 153 | begin 154 | if nRESET = '0' then 155 | -- Asynchronous clear 156 | R <= (others => '0'); 157 | G <= (others => '0'); 158 | B <= (others => '0'); 159 | elsif rising_edge(CLK) then 160 | -- Output video to DACs 161 | R <= (3 => red, others => bright and red); 162 | G <= (3 => green, others => bright and green); 163 | B <= (3 => blue, others => bright and blue); 164 | end if; 165 | end process; 166 | 167 | 168 | -- This is what the contention model is supposed to look like. 169 | -- We may need to emulate this to ensure proper compatibility. 170 | -- 171 | -- At vcounter = 0 and hcounter = 0 we are at 172 | -- 14336*T since the falling edge of the vsync. 173 | -- This is where we start contending RAM access. 174 | -- The contention pattern repeats every 8 T states, with 175 | -- CPU clock held during the first 6 of every 8 T states 176 | -- (where one T state is two ticks of the horizontal counter). 177 | -- Two screen bytes are fetched consecutively, display first 178 | -- followed by attribute. The cycle looks like this: 179 | -- hcounter[3..1] = 000 Fetch data 1 nWAIT = 0 180 | -- 001 Fetch attr 1 0 181 | -- 010 Fetch data 2 0 182 | -- 011 Fetch attr 2 0 183 | -- 100 1 184 | -- 101 1 185 | -- 110 0 186 | -- 111 0 187 | 188 | -- What we actually do is the following, interleaved with CPU RAM access 189 | -- so that we don't need any contention: 190 | -- hcounter[2..0] = 000 Fetch data (LOAD) 191 | -- 001 Fetch data (STORE) 192 | -- 010 Fetch attr (LOAD) 193 | -- 011 Fetch attr (STORE) 194 | -- 100 Idle 195 | -- 101 Idle 196 | -- 110 Idle 197 | -- 111 Idle 198 | -- The load/store pairs take place over two clock enables. In VGA mode 199 | -- there is one picture/attribute pair fetch per CPU clock enable. In PAL 200 | -- mode every other tick is ignored, so the picture/attribute fetches occur 201 | -- on alternate CPU clocks. At no time must a CPU cycle be allowed to split 202 | -- a LOAD/STORE pair, as the bus routing logic will disconnect the memory from 203 | -- the CPU during this time. 204 | 205 | -- RAM address is generated continuously from the counter values 206 | -- Pixel fetch takes place when hcounter(2) = 0, attribute when = 1 207 | VID_A(12 downto 0) <= 208 | -- Picture 209 | vcounter(8 downto 7) & vcounter(3 downto 1) & vcounter(6 downto 4) & hcounter(8 downto 4) 210 | when hcounter(2) = '0' else 211 | -- Attribute 212 | "110" & vcounter(8 downto 7) & vcounter(6 downto 4) & hcounter(8 downto 4); 213 | 214 | -- This timing model is completely uncontended. CPU runs all the time. 215 | nWAIT <= '1'; 216 | 217 | -- First 192 lines are picture 218 | vpicture <= not (vcounter(9) or (vcounter(8) and vcounter(7))); 219 | 220 | process(nRESET,CLK,CLKEN,hcounter,vcounter) 221 | begin 222 | if nRESET = '0' then 223 | -- Asynchronous master reset 224 | hcounter <= (others => '0'); 225 | vcounter <= (others => '0'); 226 | flashcounter <= (others => '0'); 227 | 228 | vblanking <= '0'; 229 | hblanking <= '0'; 230 | hpicture <= '1'; 231 | hsync <= '0'; 232 | vsync <= '0'; 233 | nIRQ <= '1'; 234 | nVID_RD <= '1'; 235 | 236 | pixels <= (others => '0'); 237 | attr <= (others => '0'); 238 | elsif rising_edge(CLK) and CLKEN = '1' then 239 | -- Most functions are only performed when hcounter(0) is clear. 240 | -- This is the 'half' bit inserted to allow for scan-doubled VGA output. 241 | -- In VGA mode the counter will be stepped through the even values only, 242 | -- so the rest of the logic remains the same. 243 | if vpicture = '1' and hcounter(0) = '0' then 244 | -- Pump pixel shift register - this is two pixels longer 245 | -- than a byte to delay the pixels back into alignment with 246 | -- the attribute byte, stored two ticks later 247 | pixels(9 downto 1) <= pixels(8 downto 0); 248 | 249 | if hcounter(9) = '0' and hcounter(3) = '0' then 250 | -- Handle the fetch cycle 251 | -- 3210 252 | -- 0000 PICTURE LOAD 253 | -- 0010 PICTURE STORE 254 | -- 0100 ATTR LOAD 255 | -- 0110 ATTR STORE 256 | if hcounter(1) = '0' then 257 | -- LOAD 258 | -- Assert the read strobe during the active picture in the 259 | -- first and third pixel of every 8. This splits a picture/attribute 260 | -- fetch pair across two CPU cycles in PAL mode, or both in one cycle 261 | -- in VGA mode 262 | nVID_RD <= '0'; 263 | else 264 | -- STORE 265 | if hcounter(2) = '0' then 266 | -- PICTURE 267 | pixels(7 downto 0) <= VID_D_IN; 268 | else 269 | -- ATTR 270 | attr <= VID_D_IN; 271 | end if; 272 | 273 | nVID_RD <= '1'; 274 | end if; 275 | end if; 276 | 277 | -- Delay horizontal picture enable until the end of the first fetch cycle 278 | -- This also allows for the re-registration of the outputs 279 | if hcounter(9) = '0' and hcounter(2 downto 1) = "11" then 280 | hpicture <= '1'; 281 | end if; 282 | if hcounter(9) = '1' and hcounter(2 downto 1) = "11" then 283 | hpicture <= '0'; 284 | end if; 285 | end if; 286 | 287 | -- Step the horizontal counter and check for wrap 288 | if VGA = '1' then 289 | -- Counter wraps after 894 in VGA mode 290 | if hcounter = "1101111110" then 291 | hcounter <= (others => '0'); 292 | -- Increment vertical counter by ones for VGA so that 293 | -- lines are double-scanned 294 | vcounter <= vcounter + '1'; 295 | else 296 | -- Increment horizontal counter 297 | -- Even values only for VGA mode 298 | hcounter <= hcounter + "10"; 299 | hcounter(0) <= '0'; 300 | end if; 301 | else 302 | -- Counter wraps after 895 in PAL mode 303 | if hcounter = "1101111111" then 304 | hcounter <= (others => '0'); 305 | -- Increment vertical counter by even values for PAL 306 | vcounter <= vcounter + "10"; 307 | vcounter(0) <= '0'; 308 | else 309 | -- Increment horizontal counter 310 | -- All values for PAL mode 311 | hcounter <= hcounter + '1'; 312 | end if; 313 | end if; 314 | 315 | 316 | -------------------- 317 | -- HORIZONTAL 318 | -------------------- 319 | 320 | -- Each line comprises the following: 321 | -- 256 pixels of active image 322 | -- 48 pixels right border 323 | -- 24 pixels front porch 324 | -- 32 pixels sync 325 | -- 40 pixels back porch 326 | -- 48 pixels left border 327 | 328 | -- Generate timing signals during inactive region 329 | -- (when hcounter(9) = 1) 330 | case hcounter(9 downto 4) is 331 | -- Blanking starts at 304 332 | when "100110" => hblanking <= '1'; 333 | -- Sync starts at 328 334 | when "101001" => hsync <= '1'; 335 | -- Sync ends at 360 336 | when "101101" => hsync <= '0'; 337 | -- Blanking ends at 400 338 | when "110010" => hblanking <= '0'; 339 | when others => 340 | null; 341 | end case; 342 | 343 | -- Clear interrupt after 32T 344 | if hcounter(7) = '1' then 345 | nIRQ <= '1'; 346 | end if; 347 | 348 | ---------------- 349 | -- VERTICAL 350 | ---------------- 351 | 352 | case vcounter(9 downto 3) is 353 | when "0111110" => 354 | -- Start of blanking and vsync(line 248) 355 | vblanking <= '1'; 356 | vsync <= '1'; 357 | -- Assert vsync interrupt 358 | nIRQ <= '0'; 359 | when "0111111" => 360 | -- End of vsync after 4 lines (line 252) 361 | vsync <= '0'; 362 | when "1000000" => 363 | -- End of blanking and start of top border (line 256) 364 | -- Should be line 264 but this is simpler and doesn't really make 365 | -- any difference 366 | vblanking <= '0'; 367 | when others => 368 | null; 369 | end case; 370 | 371 | -- Wrap vertical counter at line 312-1, 372 | -- Top counter value is 623 for VGA, 622 for PAL 373 | if vcounter(9 downto 1) = "100110111" then 374 | if (VGA = '1' and vcounter(0) = '1') or VGA = '0' then 375 | -- Start of picture area 376 | vcounter <= (others => '0'); 377 | -- Increment the flash counter once per frame 378 | flashcounter <= flashcounter + '1'; 379 | end if; 380 | end if; 381 | end if; 382 | end process; 383 | end video_arch; 384 | 385 | -------------------------------------------------------------------------------- /CII_Starter_pin_assignments.csv: -------------------------------------------------------------------------------- 1 | 2 | # Note: The column header names should not be changed if you wish to import this .csv file into the Quartus II software. 3 | 4 | From,To,Assignment Name,Value,Enabled 5 | ,GPIO_0[0],Location,PIN_A13,Yes 6 | ,GPIO_0[1],Location,PIN_B13,Yes 7 | ,GPIO_0[2],Location,PIN_A14,Yes 8 | ,GPIO_0[3],Location,PIN_B14,Yes 9 | ,GPIO_0[4],Location,PIN_A15,Yes 10 | ,GPIO_0[5],Location,PIN_B15,Yes 11 | ,GPIO_0[6],Location,PIN_A16,Yes 12 | ,GPIO_0[7],Location,PIN_B16,Yes 13 | ,GPIO_0[8],Location,PIN_A17,Yes 14 | ,GPIO_0[9],Location,PIN_B17,Yes 15 | ,GPIO_0[10],Location,PIN_A18,Yes 16 | ,GPIO_0[11],Location,PIN_B18,Yes 17 | ,GPIO_0[12],Location,PIN_A19,Yes 18 | ,GPIO_0[13],Location,PIN_B19,Yes 19 | ,GPIO_0[14],Location,PIN_A20,Yes 20 | ,GPIO_0[15],Location,PIN_B20,Yes 21 | ,GPIO_0[16],Location,PIN_C21,Yes 22 | ,GPIO_0[17],Location,PIN_C22,Yes 23 | ,GPIO_0[18],Location,PIN_D21,Yes 24 | ,GPIO_0[19],Location,PIN_D22,Yes 25 | ,GPIO_0[20],Location,PIN_E21,Yes 26 | ,GPIO_0[21],Location,PIN_E22,Yes 27 | ,GPIO_0[22],Location,PIN_F21,Yes 28 | ,GPIO_0[23],Location,PIN_F22,Yes 29 | ,GPIO_0[24],Location,PIN_G21,Yes 30 | ,GPIO_0[25],Location,PIN_G22,Yes 31 | ,GPIO_0[26],Location,PIN_J21,Yes 32 | ,GPIO_0[27],Location,PIN_J22,Yes 33 | ,GPIO_0[28],Location,PIN_K21,Yes 34 | ,GPIO_0[29],Location,PIN_K22,Yes 35 | ,GPIO_0[30],Location,PIN_J19,Yes 36 | ,GPIO_0[31],Location,PIN_J20,Yes 37 | ,GPIO_0[32],Location,PIN_J18,Yes 38 | ,GPIO_0[33],Location,PIN_K20,Yes 39 | ,GPIO_0[34],Location,PIN_L19,Yes 40 | ,GPIO_0[35],Location,PIN_L18,Yes 41 | ,GPIO_1[0],Location,PIN_H12,Yes 42 | ,GPIO_1[1],Location,PIN_H13,Yes 43 | ,GPIO_1[2],Location,PIN_H14,Yes 44 | ,GPIO_1[3],Location,PIN_G15,Yes 45 | ,GPIO_1[4],Location,PIN_E14,Yes 46 | ,GPIO_1[5],Location,PIN_E15,Yes 47 | ,GPIO_1[6],Location,PIN_F15,Yes 48 | ,GPIO_1[7],Location,PIN_G16,Yes 49 | ,GPIO_1[8],Location,PIN_F12,Yes 50 | ,GPIO_1[9],Location,PIN_F13,Yes 51 | ,GPIO_1[10],Location,PIN_C14,Yes 52 | ,GPIO_1[11],Location,PIN_D14,Yes 53 | ,GPIO_1[12],Location,PIN_D15,Yes 54 | ,GPIO_1[13],Location,PIN_D16,Yes 55 | ,GPIO_1[14],Location,PIN_C17,Yes 56 | ,GPIO_1[15],Location,PIN_C18,Yes 57 | ,GPIO_1[16],Location,PIN_C19,Yes 58 | ,GPIO_1[17],Location,PIN_C20,Yes 59 | ,GPIO_1[18],Location,PIN_D19,Yes 60 | ,GPIO_1[19],Location,PIN_D20,Yes 61 | ,GPIO_1[20],Location,PIN_E20,Yes 62 | ,GPIO_1[21],Location,PIN_F20,Yes 63 | ,GPIO_1[22],Location,PIN_E19,Yes 64 | ,GPIO_1[23],Location,PIN_E18,Yes 65 | ,GPIO_1[24],Location,PIN_G20,Yes 66 | ,GPIO_1[25],Location,PIN_G18,Yes 67 | ,GPIO_1[26],Location,PIN_G17,Yes 68 | ,GPIO_1[27],Location,PIN_H17,Yes 69 | ,GPIO_1[28],Location,PIN_J15,Yes 70 | ,GPIO_1[29],Location,PIN_H18,Yes 71 | ,GPIO_1[30],Location,PIN_N22,Yes 72 | ,GPIO_1[31],Location,PIN_N21,Yes 73 | ,GPIO_1[32],Location,PIN_P15,Yes 74 | ,GPIO_1[33],Location,PIN_N15,Yes 75 | ,GPIO_1[34],Location,PIN_P17,Yes 76 | ,GPIO_1[35],Location,PIN_P18,Yes 77 | ,GPIO_0[0],I/O Standard,LVTTL,Yes 78 | ,GPIO_0[1],I/O Standard,LVTTL,Yes 79 | ,GPIO_0[2],I/O Standard,LVTTL,Yes 80 | ,GPIO_0[3],I/O Standard,LVTTL,Yes 81 | ,GPIO_0[4],I/O Standard,LVTTL,Yes 82 | ,GPIO_0[5],I/O Standard,LVTTL,Yes 83 | ,GPIO_0[6],I/O Standard,LVTTL,Yes 84 | ,GPIO_0[7],I/O Standard,LVTTL,Yes 85 | ,GPIO_0[8],I/O Standard,LVTTL,Yes 86 | ,GPIO_0[9],I/O Standard,LVTTL,Yes 87 | ,GPIO_0[10],I/O Standard,LVTTL,Yes 88 | ,GPIO_0[11],I/O Standard,LVTTL,Yes 89 | ,GPIO_0[12],I/O Standard,LVTTL,Yes 90 | ,GPIO_0[13],I/O Standard,LVTTL,Yes 91 | ,GPIO_0[14],I/O Standard,LVTTL,Yes 92 | ,GPIO_0[15],I/O Standard,LVTTL,Yes 93 | ,GPIO_0[16],I/O Standard,LVTTL,Yes 94 | ,GPIO_0[17],I/O Standard,LVTTL,Yes 95 | ,GPIO_0[18],I/O Standard,LVTTL,Yes 96 | ,GPIO_0[19],I/O Standard,LVTTL,Yes 97 | ,GPIO_0[20],I/O Standard,LVTTL,Yes 98 | ,GPIO_0[21],I/O Standard,LVTTL,Yes 99 | ,GPIO_0[22],I/O Standard,LVTTL,Yes 100 | ,GPIO_0[23],I/O Standard,LVTTL,Yes 101 | ,GPIO_0[24],I/O Standard,LVTTL,Yes 102 | ,GPIO_0[25],I/O Standard,LVTTL,Yes 103 | ,GPIO_0[26],I/O Standard,LVTTL,Yes 104 | ,GPIO_0[27],I/O Standard,LVTTL,Yes 105 | ,GPIO_0[28],I/O Standard,LVTTL,Yes 106 | ,GPIO_0[29],I/O Standard,LVTTL,Yes 107 | ,GPIO_0[30],I/O Standard,LVTTL,Yes 108 | ,GPIO_0[31],I/O Standard,LVTTL,Yes 109 | ,GPIO_0[32],I/O Standard,LVTTL,Yes 110 | ,GPIO_0[33],I/O Standard,LVTTL,Yes 111 | ,GPIO_0[34],I/O Standard,LVTTL,Yes 112 | ,GPIO_0[35],I/O Standard,LVTTL,Yes 113 | ,GPIO_1[0],I/O Standard,LVTTL,Yes 114 | ,GPIO_1[1],I/O Standard,LVTTL,Yes 115 | ,GPIO_1[2],I/O Standard,LVTTL,Yes 116 | ,GPIO_1[3],I/O Standard,LVTTL,Yes 117 | ,GPIO_1[4],I/O Standard,LVTTL,Yes 118 | ,GPIO_1[5],I/O Standard,LVTTL,Yes 119 | ,GPIO_1[6],I/O Standard,LVTTL,Yes 120 | ,GPIO_1[7],I/O Standard,LVTTL,Yes 121 | ,GPIO_1[8],I/O Standard,LVTTL,Yes 122 | ,GPIO_1[9],I/O Standard,LVTTL,Yes 123 | ,GPIO_1[10],I/O Standard,LVTTL,Yes 124 | ,GPIO_1[11],I/O Standard,LVTTL,Yes 125 | ,GPIO_1[12],I/O Standard,LVTTL,Yes 126 | ,GPIO_1[13],I/O Standard,LVTTL,Yes 127 | ,GPIO_1[14],I/O Standard,LVTTL,Yes 128 | ,GPIO_1[15],I/O Standard,LVTTL,Yes 129 | ,GPIO_1[16],I/O Standard,LVTTL,Yes 130 | ,GPIO_1[17],I/O Standard,LVTTL,Yes 131 | ,GPIO_1[18],I/O Standard,LVTTL,Yes 132 | ,GPIO_1[19],I/O Standard,LVTTL,Yes 133 | ,GPIO_1[20],I/O Standard,LVTTL,Yes 134 | ,GPIO_1[21],I/O Standard,LVTTL,Yes 135 | ,GPIO_1[22],I/O Standard,LVTTL,Yes 136 | ,GPIO_1[23],I/O Standard,LVTTL,Yes 137 | ,GPIO_1[24],I/O Standard,LVTTL,Yes 138 | ,GPIO_1[25],I/O Standard,LVTTL,Yes 139 | ,GPIO_1[26],I/O Standard,LVTTL,Yes 140 | ,GPIO_1[27],I/O Standard,LVTTL,Yes 141 | ,GPIO_1[28],I/O Standard,LVTTL,Yes 142 | ,GPIO_1[29],I/O Standard,LVTTL,Yes 143 | ,GPIO_1[30],I/O Standard,LVTTL,Yes 144 | ,GPIO_1[31],I/O Standard,LVTTL,Yes 145 | ,GPIO_1[32],I/O Standard,LVTTL,Yes 146 | ,GPIO_1[33],I/O Standard,LVTTL,Yes 147 | ,GPIO_1[34],I/O Standard,LVTTL,Yes 148 | ,GPIO_1[35],I/O Standard,LVTTL,Yes 149 | ,SW[0],Location,PIN_L22,Yes 150 | ,SW[1],Location,PIN_L21,Yes 151 | ,SW[2],Location,PIN_M22,Yes 152 | ,SW[3],Location,PIN_V12,Yes 153 | ,SW[4],Location,PIN_W12,Yes 154 | ,SW[5],Location,PIN_U12,Yes 155 | ,SW[6],Location,PIN_U11,Yes 156 | ,SW[7],Location,PIN_M2,Yes 157 | ,SW[8],Location,PIN_M1,Yes 158 | ,SW[9],Location,PIN_L2,Yes 159 | ,SW[0],I/O Standard,LVTTL,Yes 160 | ,SW[1],I/O Standard,LVTTL,Yes 161 | ,SW[2],I/O Standard,LVTTL,Yes 162 | ,SW[3],I/O Standard,LVTTL,Yes 163 | ,SW[4],I/O Standard,LVTTL,Yes 164 | ,SW[5],I/O Standard,LVTTL,Yes 165 | ,SW[6],I/O Standard,LVTTL,Yes 166 | ,SW[7],I/O Standard,LVTTL,Yes 167 | ,SW[8],I/O Standard,LVTTL,Yes 168 | ,SW[9],I/O Standard,LVTTL,Yes 169 | ,HEX0[0],Location,PIN_J2,Yes 170 | ,HEX0[1],Location,PIN_J1,Yes 171 | ,HEX0[2],Location,PIN_H2,Yes 172 | ,HEX0[3],Location,PIN_H1,Yes 173 | ,HEX0[4],Location,PIN_F2,Yes 174 | ,HEX0[5],Location,PIN_F1,Yes 175 | ,HEX0[6],Location,PIN_E2,Yes 176 | ,HEX1[0],Location,PIN_E1,Yes 177 | ,HEX1[1],Location,PIN_H6,Yes 178 | ,HEX1[2],Location,PIN_H5,Yes 179 | ,HEX1[3],Location,PIN_H4,Yes 180 | ,HEX1[4],Location,PIN_G3,Yes 181 | ,HEX1[5],Location,PIN_D2,Yes 182 | ,HEX1[6],Location,PIN_D1,Yes 183 | ,HEX2[0],Location,PIN_G5,Yes 184 | ,HEX2[1],Location,PIN_G6,Yes 185 | ,HEX2[2],Location,PIN_C2,Yes 186 | ,HEX2[3],Location,PIN_C1,Yes 187 | ,HEX2[4],Location,PIN_E3,Yes 188 | ,HEX2[5],Location,PIN_E4,Yes 189 | ,HEX2[6],Location,PIN_D3,Yes 190 | ,HEX3[0],Location,PIN_F4,Yes 191 | ,HEX3[1],Location,PIN_D5,Yes 192 | ,HEX3[2],Location,PIN_D6,Yes 193 | ,HEX3[3],Location,PIN_J4,Yes 194 | ,HEX3[4],Location,PIN_L8,Yes 195 | ,HEX3[5],Location,PIN_F3,Yes 196 | ,HEX3[6],Location,PIN_D4,Yes 197 | ,HEX0[0],I/O Standard,LVTTL,Yes 198 | ,HEX0[1],I/O Standard,LVTTL,Yes 199 | ,HEX0[2],I/O Standard,LVTTL,Yes 200 | ,HEX0[3],I/O Standard,LVTTL,Yes 201 | ,HEX0[4],I/O Standard,LVTTL,Yes 202 | ,HEX0[5],I/O Standard,LVTTL,Yes 203 | ,HEX0[6],I/O Standard,LVTTL,Yes 204 | ,HEX1[0],I/O Standard,LVTTL,Yes 205 | ,HEX1[1],I/O Standard,LVTTL,Yes 206 | ,HEX1[2],I/O Standard,LVTTL,Yes 207 | ,HEX1[3],I/O Standard,LVTTL,Yes 208 | ,HEX1[4],I/O Standard,LVTTL,Yes 209 | ,HEX1[5],I/O Standard,LVTTL,Yes 210 | ,HEX1[6],I/O Standard,LVTTL,Yes 211 | ,HEX2[0],I/O Standard,LVTTL,Yes 212 | ,HEX2[1],I/O Standard,LVTTL,Yes 213 | ,HEX2[2],I/O Standard,LVTTL,Yes 214 | ,HEX2[3],I/O Standard,LVTTL,Yes 215 | ,HEX2[4],I/O Standard,LVTTL,Yes 216 | ,HEX2[5],I/O Standard,LVTTL,Yes 217 | ,HEX2[6],I/O Standard,LVTTL,Yes 218 | ,HEX3[0],I/O Standard,LVTTL,Yes 219 | ,HEX3[1],I/O Standard,LVTTL,Yes 220 | ,HEX3[2],I/O Standard,LVTTL,Yes 221 | ,HEX3[3],I/O Standard,LVTTL,Yes 222 | ,HEX3[4],I/O Standard,LVTTL,Yes 223 | ,HEX3[5],I/O Standard,LVTTL,Yes 224 | ,HEX3[6],I/O Standard,LVTTL,Yes 225 | ,KEY[0],Location,PIN_R22,Yes 226 | ,KEY[1],Location,PIN_R21,Yes 227 | ,KEY[2],Location,PIN_T22,Yes 228 | ,KEY[3],Location,PIN_T21,Yes 229 | ,LEDR[0],Location,PIN_R20,Yes 230 | ,LEDR[1],Location,PIN_R19,Yes 231 | ,LEDR[2],Location,PIN_U19,Yes 232 | ,LEDR[3],Location,PIN_Y19,Yes 233 | ,LEDR[4],Location,PIN_T18,Yes 234 | ,LEDR[5],Location,PIN_V19,Yes 235 | ,LEDR[6],Location,PIN_Y18,Yes 236 | ,LEDR[7],Location,PIN_U18,Yes 237 | ,LEDR[8],Location,PIN_R18,Yes 238 | ,LEDR[9],Location,PIN_R17,Yes 239 | ,LEDG[0],Location,PIN_U22,Yes 240 | ,LEDG[1],Location,PIN_U21,Yes 241 | ,LEDG[2],Location,PIN_V22,Yes 242 | ,LEDG[3],Location,PIN_V21,Yes 243 | ,LEDG[4],Location,PIN_W22,Yes 244 | ,LEDG[5],Location,PIN_W21,Yes 245 | ,LEDG[6],Location,PIN_Y22,Yes 246 | ,LEDG[7],Location,PIN_Y21,Yes 247 | ,KEY[0],I/O Standard,LVTTL,Yes 248 | ,KEY[1],I/O Standard,LVTTL,Yes 249 | ,KEY[2],I/O Standard,LVTTL,Yes 250 | ,KEY[3],I/O Standard,LVTTL,Yes 251 | ,LEDR[0],I/O Standard,LVTTL,Yes 252 | ,LEDR[1],I/O Standard,LVTTL,Yes 253 | ,LEDR[2],I/O Standard,LVTTL,Yes 254 | ,LEDR[3],I/O Standard,LVTTL,Yes 255 | ,LEDR[4],I/O Standard,LVTTL,Yes 256 | ,LEDR[5],I/O Standard,LVTTL,Yes 257 | ,LEDR[6],I/O Standard,LVTTL,Yes 258 | ,LEDR[7],I/O Standard,LVTTL,Yes 259 | ,LEDR[8],I/O Standard,LVTTL,Yes 260 | ,LEDR[9],I/O Standard,LVTTL,Yes 261 | ,LEDG[0],I/O Standard,LVTTL,Yes 262 | ,LEDG[1],I/O Standard,LVTTL,Yes 263 | ,LEDG[2],I/O Standard,LVTTL,Yes 264 | ,LEDG[3],I/O Standard,LVTTL,Yes 265 | ,LEDG[4],I/O Standard,LVTTL,Yes 266 | ,LEDG[5],I/O Standard,LVTTL,Yes 267 | ,LEDG[6],I/O Standard,LVTTL,Yes 268 | ,LEDG[7],I/O Standard,LVTTL,Yes 269 | ,CLOCK_27[0],Location,PIN_D12,Yes 270 | ,CLOCK_27[1],Location,PIN_E12,Yes 271 | ,CLOCK_24[0],Location,PIN_B12,Yes 272 | ,CLOCK_24[1],Location,PIN_A12,Yes 273 | ,CLOCK_50,Location,PIN_L1,Yes 274 | ,EXT_CLOCK,Location,PIN_M21,Yes 275 | ,CLOCK_27[1],I/O Standard,LVTTL,Yes 276 | ,CLOCK_24[0],I/O Standard,LVTTL,Yes 277 | ,CLOCK_24[1],I/O Standard,LVTTL,Yes 278 | ,CLOCK_50,I/O Standard,LVTTL,Yes 279 | ,EXT_CLOCK,I/O Standard,LVTTL,Yes 280 | ,PS2_CLK,Location,PIN_H15,Yes 281 | ,PS2_DAT,Location,PIN_J14,Yes 282 | ,UART_RXD,Location,PIN_F14,Yes 283 | ,UART_TXD,Location,PIN_G12,Yes 284 | ,PS2_CLK,I/O Standard,LVTTL,Yes 285 | ,PS2_DAT,I/O Standard,LVTTL,Yes 286 | ,UART_RXD,I/O Standard,LVTTL,Yes 287 | ,UART_TXD,I/O Standard,LVTTL,Yes 288 | ,TDI,Location,PIN_E8,Yes 289 | ,TCS,Location,PIN_D8,Yes 290 | ,TCK,Location,PIN_C7,Yes 291 | ,TDO,Location,PIN_D7,Yes 292 | ,TDI,I/O Standard,LVTTL,Yes 293 | ,TCS,I/O Standard,LVTTL,Yes 294 | ,TCK,I/O Standard,LVTTL,Yes 295 | ,TDO,I/O Standard,LVTTL,Yes 296 | ,VGA_R[0],Location,PIN_D9,Yes 297 | ,VGA_R[1],Location,PIN_C9,Yes 298 | ,VGA_R[2],Location,PIN_A7,Yes 299 | ,VGA_R[3],Location,PIN_B7,Yes 300 | ,VGA_G[0],Location,PIN_B8,Yes 301 | ,VGA_G[1],Location,PIN_C10,Yes 302 | ,VGA_G[2],Location,PIN_B9,Yes 303 | ,VGA_G[3],Location,PIN_A8,Yes 304 | ,VGA_B[0],Location,PIN_A9,Yes 305 | ,VGA_B[1],Location,PIN_D11,Yes 306 | ,VGA_B[2],Location,PIN_A10,Yes 307 | ,VGA_B[3],Location,PIN_B10,Yes 308 | ,VGA_HS,Location,PIN_A11,Yes 309 | ,VGA_VS,Location,PIN_B11,Yes 310 | ,VGA_R[0],I/O Standard,LVTTL,Yes 311 | ,VGA_R[1],I/O Standard,LVTTL,Yes 312 | ,VGA_R[2],I/O Standard,LVTTL,Yes 313 | ,VGA_R[3],I/O Standard,LVTTL,Yes 314 | ,VGA_G[0],I/O Standard,LVTTL,Yes 315 | ,VGA_G[1],I/O Standard,LVTTL,Yes 316 | ,VGA_G[2],I/O Standard,LVTTL,Yes 317 | ,VGA_G[3],I/O Standard,LVTTL,Yes 318 | ,VGA_B[0],I/O Standard,LVTTL,Yes 319 | ,VGA_B[1],I/O Standard,LVTTL,Yes 320 | ,VGA_B[2],I/O Standard,LVTTL,Yes 321 | ,VGA_B[3],I/O Standard,LVTTL,Yes 322 | ,VGA_HS,I/O Standard,LVTTL,Yes 323 | ,VGA_VS,I/O Standard,LVTTL,Yes 324 | ,I2C_SCLK,Location,PIN_A3,Yes 325 | ,I2C_SDAT,Location,PIN_B3,Yes 326 | ,AUD_ADCLRCK,Location,PIN_A6,Yes 327 | ,AUD_ADCDAT,Location,PIN_B6,Yes 328 | ,AUD_DACLRCK,Location,PIN_A5,Yes 329 | ,AUD_DACDAT,Location,PIN_B5,Yes 330 | ,AUD_XCK,Location,PIN_B4,Yes 331 | ,AUD_BCLK,Location,PIN_A4,Yes 332 | ,I2C_SCLK,I/O Standard,LVTTL,Yes 333 | ,I2C_SDAT,I/O Standard,LVTTL,Yes 334 | ,AUD_ADCLRCK,I/O Standard,LVTTL,Yes 335 | ,AUD_ADCDAT,I/O Standard,LVTTL,Yes 336 | ,AUD_DACLRCK,I/O Standard,LVTTL,Yes 337 | ,AUD_DACDAT,I/O Standard,LVTTL,Yes 338 | ,AUD_XCK,I/O Standard,LVTTL,Yes 339 | ,AUD_BCLK,I/O Standard,LVTTL,Yes 340 | ,DRAM_ADDR[0],Location,PIN_W4,Yes 341 | ,DRAM_ADDR[1],Location,PIN_W5,Yes 342 | ,DRAM_ADDR[2],Location,PIN_Y3,Yes 343 | ,DRAM_ADDR[3],Location,PIN_Y4,Yes 344 | ,DRAM_ADDR[4],Location,PIN_R6,Yes 345 | ,DRAM_ADDR[5],Location,PIN_R5,Yes 346 | ,DRAM_ADDR[6],Location,PIN_P6,Yes 347 | ,DRAM_ADDR[7],Location,PIN_P5,Yes 348 | ,DRAM_ADDR[8],Location,PIN_P3,Yes 349 | ,DRAM_ADDR[9],Location,PIN_N4,Yes 350 | ,DRAM_ADDR[10],Location,PIN_W3,Yes 351 | ,DRAM_ADDR[11],Location,PIN_N6,Yes 352 | ,DRAM_BA_0,Location,PIN_U3,Yes 353 | ,DRAM_BA_1,Location,PIN_V4,Yes 354 | ,DRAM_CAS_N,Location,PIN_T3,Yes 355 | ,DRAM_CKE,Location,PIN_N3,Yes 356 | ,DRAM_CLK,Location,PIN_U4,Yes 357 | ,DRAM_CS_N,Location,PIN_T6,Yes 358 | ,DRAM_DQ[0],Location,PIN_U1,Yes 359 | ,DRAM_DQ[1],Location,PIN_U2,Yes 360 | ,DRAM_DQ[2],Location,PIN_V1,Yes 361 | ,DRAM_DQ[3],Location,PIN_V2,Yes 362 | ,DRAM_DQ[4],Location,PIN_W1,Yes 363 | ,DRAM_DQ[5],Location,PIN_W2,Yes 364 | ,DRAM_DQ[6],Location,PIN_Y1,Yes 365 | ,DRAM_DQ[7],Location,PIN_Y2,Yes 366 | ,DRAM_DQ[8],Location,PIN_N1,Yes 367 | ,DRAM_DQ[9],Location,PIN_N2,Yes 368 | ,DRAM_DQ[10],Location,PIN_P1,Yes 369 | ,DRAM_DQ[11],Location,PIN_P2,Yes 370 | ,DRAM_DQ[12],Location,PIN_R1,Yes 371 | ,DRAM_DQ[13],Location,PIN_R2,Yes 372 | ,DRAM_DQ[14],Location,PIN_T1,Yes 373 | ,DRAM_DQ[15],Location,PIN_T2,Yes 374 | ,DRAM_LDQM,Location,PIN_R7,Yes 375 | ,DRAM_RAS_N,Location,PIN_T5,Yes 376 | ,DRAM_UDQM,Location,PIN_M5,Yes 377 | ,DRAM_WE_N,Location,PIN_R8,Yes 378 | ,FL_ADDR[0],Location,PIN_AB20,Yes 379 | ,FL_ADDR[1],Location,PIN_AA14,Yes 380 | ,FL_ADDR[2],Location,PIN_Y16,Yes 381 | ,FL_ADDR[3],Location,PIN_R15,Yes 382 | ,FL_ADDR[4],Location,PIN_T15,Yes 383 | ,FL_ADDR[5],Location,PIN_U15,Yes 384 | ,FL_ADDR[6],Location,PIN_V15,Yes 385 | ,FL_ADDR[7],Location,PIN_W15,Yes 386 | ,FL_ADDR[8],Location,PIN_R14,Yes 387 | ,FL_ADDR[9],Location,PIN_Y13,Yes 388 | ,FL_ADDR[10],Location,PIN_R12,Yes 389 | ,FL_ADDR[11],Location,PIN_T12,Yes 390 | ,FL_ADDR[12],Location,PIN_AB14,Yes 391 | ,FL_ADDR[13],Location,PIN_AA13,Yes 392 | ,FL_ADDR[14],Location,PIN_AB13,Yes 393 | ,FL_ADDR[15],Location,PIN_AA12,Yes 394 | ,FL_ADDR[16],Location,PIN_AB12,Yes 395 | ,FL_ADDR[17],Location,PIN_AA20,Yes 396 | ,FL_ADDR[18],Location,PIN_U14,Yes 397 | ,FL_ADDR[19],Location,PIN_V14,Yes 398 | ,FL_ADDR[20],Location,PIN_U13,Yes 399 | ,FL_ADDR[21],Location,PIN_R13,Yes 400 | ,FL_DQ[0],Location,PIN_AB16,Yes 401 | ,FL_DQ[1],Location,PIN_AA16,Yes 402 | ,FL_DQ[2],Location,PIN_AB17,Yes 403 | ,FL_DQ[3],Location,PIN_AA17,Yes 404 | ,FL_DQ[4],Location,PIN_AB18,Yes 405 | ,FL_DQ[5],Location,PIN_AA18,Yes 406 | ,FL_DQ[6],Location,PIN_AB19,Yes 407 | ,FL_DQ[7],Location,PIN_AA19,Yes 408 | ,FL_OE_N,Location,PIN_AA15,Yes 409 | ,FL_RST_N,Location,PIN_W14,Yes 410 | ,FL_WE_N,Location,PIN_Y14,Yes 411 | ,FL_CE_N,Location,PIN_AB15,Yes 412 | ,SRAM_ADDR[0],Location,PIN_AA3,Yes 413 | ,SRAM_ADDR[1],Location,PIN_AB3,Yes 414 | ,SRAM_ADDR[2],Location,PIN_AA4,Yes 415 | ,SRAM_ADDR[3],Location,PIN_AB4,Yes 416 | ,SRAM_ADDR[4],Location,PIN_AA5,Yes 417 | ,SRAM_ADDR[5],Location,PIN_AB10,Yes 418 | ,SRAM_ADDR[6],Location,PIN_AA11,Yes 419 | ,SRAM_ADDR[7],Location,PIN_AB11,Yes 420 | ,SRAM_ADDR[8],Location,PIN_V11,Yes 421 | ,SRAM_ADDR[9],Location,PIN_W11,Yes 422 | ,SRAM_ADDR[10],Location,PIN_R11,Yes 423 | ,SRAM_ADDR[11],Location,PIN_T11,Yes 424 | ,SRAM_ADDR[12],Location,PIN_Y10,Yes 425 | ,SRAM_ADDR[13],Location,PIN_U10,Yes 426 | ,SRAM_ADDR[14],Location,PIN_R10,Yes 427 | ,SRAM_ADDR[15],Location,PIN_T7,Yes 428 | ,SRAM_ADDR[16],Location,PIN_Y6,Yes 429 | ,SRAM_ADDR[17],Location,PIN_Y5,Yes 430 | ,SRAM_CE_N,Location,PIN_AB5,Yes 431 | ,SRAM_DQ[0],Location,PIN_AA6,Yes 432 | ,SRAM_DQ[1],Location,PIN_AB6,Yes 433 | ,SRAM_DQ[2],Location,PIN_AA7,Yes 434 | ,SRAM_DQ[3],Location,PIN_AB7,Yes 435 | ,SRAM_DQ[4],Location,PIN_AA8,Yes 436 | ,SRAM_DQ[5],Location,PIN_AB8,Yes 437 | ,SRAM_DQ[6],Location,PIN_AA9,Yes 438 | ,SRAM_DQ[7],Location,PIN_AB9,Yes 439 | ,SRAM_DQ[8],Location,PIN_Y9,Yes 440 | ,SRAM_DQ[9],Location,PIN_W9,Yes 441 | ,SRAM_DQ[10],Location,PIN_V9,Yes 442 | ,SRAM_DQ[11],Location,PIN_U9,Yes 443 | ,SRAM_DQ[12],Location,PIN_R9,Yes 444 | ,SRAM_DQ[13],Location,PIN_W8,Yes 445 | ,SRAM_DQ[14],Location,PIN_V8,Yes 446 | ,SRAM_DQ[15],Location,PIN_U8,Yes 447 | ,SRAM_LB_N,Location,PIN_Y7,Yes 448 | ,SRAM_OE_N,Location,PIN_T8,Yes 449 | ,SRAM_UB_N,Location,PIN_W7,Yes 450 | ,SRAM_WE_N,Location,PIN_AA10,Yes 451 | ,SD_nCS,Location,PIN_U20,Yes 452 | ,SD_MOSI,Location,PIN_Y20,Yes 453 | ,SD_SCLK,Location,PIN_V20,Yes 454 | ,SD_MISO,Location,PIN_W20,Yes 455 | 456 | --------------------------------------------------------------------------------