├── 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 |
--------------------------------------------------------------------------------