summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2003-09-06 03:42:22 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2003-09-06 03:42:22 (GMT)
commitb7d9d27bbca28a133278b1061e2c79eb038e4a0f (patch)
tree5af9b1f9c990249ac6e7b32a336f556b940fa7a0
parente6922d76fbcec783fc0080b6b93f0669c906a42d (diff)
downloadkeyboard-b7d9d27bbca28a133278b1061e2c79eb038e4a0f.zip
keyboard-b7d9d27bbca28a133278b1061e2c79eb038e4a0f.tar.gz
keyboard-b7d9d27bbca28a133278b1061e2c79eb038e4a0f.tar.bz2
keyboard-b7d9d27bbca28a133278b1061e2c79eb038e4a0f.tar.xz
*** empty log message ***
-rw-r--r--data/Makefile17
-rwxr-xr-xdata/bin2mif.pl62
-rw-r--r--data/keyboard.asm109
-rw-r--r--mega/kbdram.bsf75
-rw-r--r--mega/kbdram.cmp31
-rw-r--r--mega/kbdram.inc32
-rw-r--r--mega/kbdram.v127
-rw-r--r--mega/kbdram_bb.v35
-rw-r--r--mega/kbdram_inst.v7
-rw-r--r--t80/DebugSystem.vhd181
-rw-r--r--t80/DebugSystemXR.vhd185
-rw-r--r--t80/SSRAM.vhd94
-rw-r--r--t80/SSRAM2.vhd92
-rw-r--r--t80/SSRAMX.vhd132
-rw-r--r--t80/T16450.vhd459
-rw-r--r--t80/T80.vhd1073
-rw-r--r--t80/T8080se.vhd185
-rw-r--r--t80/T80_ALU.vhd351
-rw-r--r--t80/T80_MCode.vhd1934
-rw-r--r--t80/T80_Pack.vhd208
-rw-r--r--t80/T80_Reg.vhd105
-rw-r--r--t80/T80_RegX.vhd170
-rw-r--r--t80/T80a.vhd253
-rw-r--r--t80/T80s.vhd227
-rw-r--r--t80/T80se.vhd184
25 files changed, 6328 insertions, 0 deletions
diff --git a/data/Makefile b/data/Makefile
new file mode 100644
index 0000000..9db3228
--- /dev/null
+++ b/data/Makefile
@@ -0,0 +1,17 @@
+BIN2MIF = ./bin2mif.pl
+
+.SUFFIXES: .asm .obj .bin .mif
+
+.asm.obj:
+ asmz80 -o $@ $< || ( rm -f $@ ; exit 1 )
+
+.obj.bin:
+ linkz80 -r $@ $< || ( rm -f $@ ; exit 1 )
+
+all : keyboard.mif
+
+keyboard.mif : keyboard.bin
+ $(BIN2MIF) 2048 8 < $< > $@ || ( rm -f $@ ; exit 1 )
+
+clean:
+ rm -f *.obj *.bin *.mif
diff --git a/data/bin2mif.pl b/data/bin2mif.pl
new file mode 100755
index 0000000..5b3b900
--- /dev/null
+++ b/data/bin2mif.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+#
+# Usage bin2mif.pl <depth> <width> < input.bin > output.mif
+#
+
+eval { use bytes; binmode(STDIN); };
+
+$depth = $ARGV[0] + 0;
+$width = $ARGV[1] + 0;
+$fill = $ARGV[2];
+$fill = oct($fill) if ( $fill =~ /^0/ );
+
+if ( $width > 64 ) {
+ print STDERR "$0: width > 64 not supported\n";
+ exit(1);
+} elsif ( $width > 32 ) {
+ $bytesper = 8;
+} elsif ( $width > 16 ) {
+ $bytesper = 4;
+} elsif ( $width > 8 ) {
+ $bytesper = 2;
+} else {
+ $bytesper = 1;
+}
+
+print "DEPTH = $depth;\n";
+print "WIDTH = $width;\n";
+print "ADDRESS_RADIX = HEX;\n";
+print "DATA_RADIX = HEX;\n";
+print "CONTENT\n";
+print "BEGIN\n";
+
+$a = 0; $d = 0; $s = 0; $n = 0;
+while ( ($len = read(STDIN, $bytes, 512)) > 0 ) {
+ $i = 0;
+ while ( $i < $len ) {
+ while ( $n < $bytesper ) {
+ # This assumes littleendian data...
+ $d += ord(substr($bytes,$i++,1)) << $s;
+ $s += 8;
+ $n++;
+ }
+ if ( $n >= $bytesper ) {
+ printf "%X : %X;\n", $a++, $d;
+ $d = 0; $s = 0; $n = 0;
+ }
+ }
+}
+
+if ( $a < $depth ) {
+ if ( $a == $depth-1 ) {
+ printf "%X : %X;\n", $a, $fill;
+ } else {
+ printf "[%X..%X] : %X;\n", $a, $depth-1, $fill;
+ }
+}
+
+print "END;\n";
+
+if ( $a > $depth ) {
+ print STDERR "$0: Data overflow!\n";
+}
diff --git a/data/keyboard.asm b/data/keyboard.asm
new file mode 100644
index 0000000..29f49d1
--- /dev/null
+++ b/data/keyboard.asm
@@ -0,0 +1,109 @@
+; Keyboard controller program written in Z80 assembly
+;
+; This is a test...
+;
+
+_start
+ ; Enter here after reset
+ ld sp,#2048 ; Initialize stack pointer
+
+ ; Test the serial port
+ ; Send one character followed by a long pause
+ ld a,#0x58
+ call (sendchar)
+
+ ld hl,#0
+zzz
+ dec hl
+ ld a,h
+ or l
+ jr nz,zzz
+
+ ; Send a string
+ ld hl,hello_msg
+send_msg
+ ld a,(hl)
+ inc hl
+ and a
+ jr z,sm_done
+ call (sendchar)
+ jr send_msg
+sm_done
+
+ ; Now, other stuff...
+
+ xor a ; A <- 0
+ ld b,a
+ ld h,a
+ ld l,a
+
+scan
+ out (#3),a
+ push af
+ ld a,b
+ out (#2),a
+delay
+ push de
+ pop de
+ dec hl
+ ld a,h
+ or l
+ jr nz,delay
+
+ ; Rotate A left inserting the inverse byte
+ pop af
+ cp #0x80 ; Set C iff A < 0x7F
+ rla
+
+ jr nz,scan
+
+ ; Loop counter (increment when A <- 0)
+ inc b
+
+ ; Output the loop counter on the serial port
+ push af
+ push hl
+ push de
+ ld de,hextbl
+ ld h,#0
+ ld l,b
+ srl l
+ srl l
+ srl l
+ srl l
+ add hl,de
+ ld a,(hl)
+ call (sendchar)
+ ld h,#0
+ ld a,b
+ and #0x0F
+ ld l,a
+ add hl,de
+ ld a,(hl)
+ call (sendchar)
+ ld a,#32
+ call (sendchar)
+ pop de
+ pop hl
+ pop af
+
+ jr scan
+
+;
+; Send a byte to the debug serial port
+;
+sendchar
+ push af
+sc_notready
+ in a,(#1)
+ cp #0x80 ; Bit 7 = serial port ready
+ jr c,sc_notready
+ pop af
+ out (#1),a
+ ret
+
+hello_msg
+ byte "Hello, World!", 13, 10, 0
+
+hextbl
+ byte "0123456789ABCDEF"
diff --git a/mega/kbdram.bsf b/mega/kbdram.bsf
new file mode 100644
index 0000000..4573028
--- /dev/null
+++ b/mega/kbdram.bsf
@@ -0,0 +1,75 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any megafunction design, and related netlist (encrypted or decrypted),
+support information, device programming or simulation file, and any other
+associated documentation or information provided by Altera or a partner
+under Altera's Megafunction Partnership Program may be used only
+to program PLD devices (but not masked PLD devices) from Altera. Any
+other use of such megafunction design, netlist, support information,
+device programming or simulation file, or any other related documentation
+or information is prohibited for any other purpose, including, but not
+limited to modification, reverse engineering, de-compiling, or use with
+any other silicon devices, unless such use is explicitly licensed under
+a separate agreement with Altera or a megafunction partner. Title to the
+intellectual property, including patents, copyrights, trademarks, trade
+secrets, or maskworks, embodied in any such megafunction design, netlist,
+support information, device programming or simulation file, or any other
+related documentation or information provided by Altera or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+ (rect 0 0 160 112)
+ (text "kbdram" (rect 59 1 106 17)(font "Arial" (font_size 10)))
+ (text "inst" (rect 8 96 24 108)(font "Arial" ))
+ (port
+ (pt 0 32)
+ (input)
+ (text "data[7..0]" (rect 0 0 49 14)(font "Arial" (font_size 8)))
+ (text "data[7..0]" (rect 20 26 65 39)(font "Arial" (font_size 8)))
+ (line (pt 0 32)(pt 16 32)(line_width 3))
+ )
+ (port
+ (pt 0 48)
+ (input)
+ (text "wren" (rect 0 0 28 14)(font "Arial" (font_size 8)))
+ (text "wren" (rect 20 42 42 55)(font "Arial" (font_size 8)))
+ (line (pt 0 48)(pt 16 48)(line_width 1))
+ )
+ (port
+ (pt 0 64)
+ (input)
+ (text "address[10..0]" (rect 0 0 77 14)(font "Arial" (font_size 8)))
+ (text "address[10..0]" (rect 20 58 85 71)(font "Arial" (font_size 8)))
+ (line (pt 0 64)(pt 16 64)(line_width 3))
+ )
+ (port
+ (pt 0 80)
+ (input)
+ (text "clock" (rect 0 0 27 14)(font "Arial" (font_size 8)))
+ (text "clock" (rect 26 74 49 87)(font "Arial" (font_size 8)))
+ (line (pt 0 80)(pt 16 80)(line_width 1))
+ )
+ (port
+ (pt 160 32)
+ (output)
+ (text "q[7..0]" (rect 0 0 33 14)(font "Arial" (font_size 8)))
+ (text "q[7..0]" (rect 111 26 141 39)(font "Arial" (font_size 8)))
+ (line (pt 160 32)(pt 144 32)(line_width 3))
+ )
+ (drawing
+ (line (pt 16 16)(pt 144 16)(line_width 1))
+ (line (pt 144 16)(pt 144 96)(line_width 1))
+ (line (pt 144 96)(pt 16 96)(line_width 1))
+ (line (pt 16 96)(pt 16 16)(line_width 1))
+ (line (pt 16 74)(pt 22 80)(line_width 1))
+ (line (pt 22 80)(pt 16 86)(line_width 1))
+ )
+)
diff --git a/mega/kbdram.cmp b/mega/kbdram.cmp
new file mode 100644
index 0000000..314a183
--- /dev/null
+++ b/mega/kbdram.cmp
@@ -0,0 +1,31 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any megafunction design, and related netlist (encrypted or decrypted),
+--support information, device programming or simulation file, and any other
+--associated documentation or information provided by Altera or a partner
+--under Altera's Megafunction Partnership Program may be used only
+--to program PLD devices (but not masked PLD devices) from Altera. Any
+--other use of such megafunction design, netlist, support information,
+--device programming or simulation file, or any other related documentation
+--or information is prohibited for any other purpose, including, but not
+--limited to modification, reverse engineering, de-compiling, or use with
+--any other silicon devices, unless such use is explicitly licensed under
+--a separate agreement with Altera or a megafunction partner. Title to the
+--intellectual property, including patents, copyrights, trademarks, trade
+--secrets, or maskworks, embodied in any such megafunction design, netlist,
+--support information, device programming or simulation file, or any other
+--related documentation or information provided by Altera or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component kbdram
+ PORT
+ (
+ address : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
+ clock : IN STD_LOGIC ;
+ data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
+ wren : IN STD_LOGIC ;
+ q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+ );
+end component;
diff --git a/mega/kbdram.inc b/mega/kbdram.inc
new file mode 100644
index 0000000..7a8e4b2
--- /dev/null
+++ b/mega/kbdram.inc
@@ -0,0 +1,32 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any megafunction design, and related netlist (encrypted or decrypted),
+--support information, device programming or simulation file, and any other
+--associated documentation or information provided by Altera or a partner
+--under Altera's Megafunction Partnership Program may be used only
+--to program PLD devices (but not masked PLD devices) from Altera. Any
+--other use of such megafunction design, netlist, support information,
+--device programming or simulation file, or any other related documentation
+--or information is prohibited for any other purpose, including, but not
+--limited to modification, reverse engineering, de-compiling, or use with
+--any other silicon devices, unless such use is explicitly licensed under
+--a separate agreement with Altera or a megafunction partner. Title to the
+--intellectual property, including patents, copyrights, trademarks, trade
+--secrets, or maskworks, embodied in any such megafunction design, netlist,
+--support information, device programming or simulation file, or any other
+--related documentation or information provided by Altera or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION kbdram
+(
+ address[10..0],
+ clock,
+ data[7..0],
+ wren
+)
+
+RETURNS (
+ q[7..0]
+);
diff --git a/mega/kbdram.v b/mega/kbdram.v
new file mode 100644
index 0000000..0494e50
--- /dev/null
+++ b/mega/kbdram.v
@@ -0,0 +1,127 @@
+// megafunction wizard: %RAM: 1-PORT%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altsyncram
+
+// ============================================================
+// File Name: kbdram.v
+// Megafunction Name(s):
+// altsyncram
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any megafunction design, and related netlist (encrypted or decrypted),
+//support information, device programming or simulation file, and any other
+//associated documentation or information provided by Altera or a partner
+//under Altera's Megafunction Partnership Program may be used only
+//to program PLD devices (but not masked PLD devices) from Altera. Any
+//other use of such megafunction design, netlist, support information,
+//device programming or simulation file, or any other related documentation
+//or information is prohibited for any other purpose, including, but not
+//limited to modification, reverse engineering, de-compiling, or use with
+//any other silicon devices, unless such use is explicitly licensed under
+//a separate agreement with Altera or a megafunction partner. Title to the
+//intellectual property, including patents, copyrights, trademarks, trade
+//secrets, or maskworks, embodied in any such megafunction design, netlist,
+//support information, device programming or simulation file, or any other
+//related documentation or information provided by Altera or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+module kbdram (
+ address,
+ clock,
+ data,
+ wren,
+ q);
+
+ input [10:0] address;
+ input clock;
+ input [7:0] data;
+ input wren;
+ output [7:0] q;
+
+ wire [7:0] sub_wire0;
+ wire [7:0] q = sub_wire0[7:0];
+
+ altsyncram altsyncram_component (
+ .wren_a (wren),
+ .clock0 (clock),
+ .address_a (address),
+ .data_a (data),
+ .q_a (sub_wire0));
+ defparam
+ altsyncram_component.intended_device_family = "Cyclone",
+ altsyncram_component.width_a = 8,
+ altsyncram_component.widthad_a = 11,
+ altsyncram_component.numwords_a = 2048,
+ altsyncram_component.operation_mode = "SINGLE_PORT",
+ altsyncram_component.outdata_reg_a = "UNREGISTERED",
+ altsyncram_component.indata_aclr_a = "NONE",
+ altsyncram_component.wrcontrol_aclr_a = "NONE",
+ altsyncram_component.address_aclr_a = "NONE",
+ altsyncram_component.outdata_aclr_a = "NONE",
+ altsyncram_component.width_byteena_a = 1,
+ altsyncram_component.ram_block_type = "AUTO",
+ altsyncram_component.init_file = "U:/altera/keyboard/data/keyboard.mif",
+ altsyncram_component.lpm_type = "altsyncram";
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: WidthData NUMERIC "8"
+// Retrieval info: PRIVATE: WidthAddr NUMERIC "11"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
+// Retrieval info: PRIVATE: RegData NUMERIC "1"
+// Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+// Retrieval info: PRIVATE: RegOutput NUMERIC "0"
+// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
+// Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+// Retrieval info: PRIVATE: AclrData NUMERIC "0"
+// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
+// Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+// Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+// Retrieval info: PRIVATE: Clken NUMERIC "0"
+// Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
+// Retrieval info: PRIVATE: MIFfilename STRING "U:/altera/keyboard/data/keyboard.mif"
+// Retrieval info: PRIVATE: UseLCs NUMERIC "0"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "256"
+// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
+// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
+// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
+// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
+// Retrieval info: CONSTANT: INDATA_ACLR_A STRING "NONE"
+// Retrieval info: CONSTANT: WRCONTROL_ACLR_A STRING "NONE"
+// Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
+// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+// Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: INIT_FILE STRING "U:/altera/keyboard/data/keyboard.mif"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+// Retrieval info: USED_PORT: address 0 0 11 0 INPUT NODEFVAL address[10..0]
+// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
+// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
+// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL wren
+// Retrieval info: CONNECT: @address_a 0 0 11 0 address 0 0 11 0
+// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
+// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
+// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
diff --git a/mega/kbdram_bb.v b/mega/kbdram_bb.v
new file mode 100644
index 0000000..eb53f17
--- /dev/null
+++ b/mega/kbdram_bb.v
@@ -0,0 +1,35 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any megafunction design, and related netlist (encrypted or decrypted),
+//support information, device programming or simulation file, and any other
+//associated documentation or information provided by Altera or a partner
+//under Altera's Megafunction Partnership Program may be used only
+//to program PLD devices (but not masked PLD devices) from Altera. Any
+//other use of such megafunction design, netlist, support information,
+//device programming or simulation file, or any other related documentation
+//or information is prohibited for any other purpose, including, but not
+//limited to modification, reverse engineering, de-compiling, or use with
+//any other silicon devices, unless such use is explicitly licensed under
+//a separate agreement with Altera or a megafunction partner. Title to the
+//intellectual property, including patents, copyrights, trademarks, trade
+//secrets, or maskworks, embodied in any such megafunction design, netlist,
+//support information, device programming or simulation file, or any other
+//related documentation or information provided by Altera or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module kbdram (
+ address,
+ clock,
+ data,
+ wren,
+ q);
+
+ input [10:0] address;
+ input clock;
+ input [7:0] data;
+ input wren;
+ output [7:0] q;
+
+endmodule
+
diff --git a/mega/kbdram_inst.v b/mega/kbdram_inst.v
new file mode 100644
index 0000000..decf97a
--- /dev/null
+++ b/mega/kbdram_inst.v
@@ -0,0 +1,7 @@
+kbdram kbdram_inst (
+ .address ( address_sig ),
+ .clock ( clock_sig ),
+ .data ( data_sig ),
+ .wren ( wren_sig ),
+ .q ( q_sig )
+ );
diff --git a/t80/DebugSystem.vhd b/t80/DebugSystem.vhd
new file mode 100644
index 0000000..c11663b
--- /dev/null
+++ b/t80/DebugSystem.vhd
@@ -0,0 +1,181 @@
+-- Z80, Monitor ROM, 4k RAM and two 16450 UARTs
+-- that can be synthesized and used with
+-- the NoICE debugger that can be found at
+-- http://www.noicedebugger.com/
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+entity DebugSystem is
+ port(
+ Reset_n : in std_logic;
+ Clk : in std_logic;
+ NMI_n : in std_logic;
+ RXD0 : in std_logic;
+ CTS0 : in std_logic;
+ DSR0 : in std_logic;
+ RI0 : in std_logic;
+ DCD0 : in std_logic;
+ RXD1 : in std_logic;
+ CTS1 : in std_logic;
+ DSR1 : in std_logic;
+ RI1 : in std_logic;
+ DCD1 : in std_logic;
+ TXD0 : out std_logic;
+ RTS0 : out std_logic;
+ DTR0 : out std_logic;
+ TXD1 : out std_logic;
+ RTS1 : out std_logic;
+ DTR1 : out std_logic
+ );
+end DebugSystem;
+
+architecture struct of DebugSystem is
+
+ signal M1_n : std_logic;
+ signal MREQ_n : std_logic;
+ signal IORQ_n : std_logic;
+ signal RD_n : std_logic;
+ signal WR_n : std_logic;
+ signal RFSH_n : std_logic;
+ signal HALT_n : std_logic;
+ signal WAIT_n : std_logic;
+ signal INT_n : std_logic;
+ signal RESET_s : std_logic;
+ signal BUSRQ_n : std_logic;
+ signal BUSAK_n : std_logic;
+ signal A : std_logic_vector(15 downto 0);
+ signal D : std_logic_vector(7 downto 0);
+ signal ROM_D : std_logic_vector(7 downto 0);
+ signal SRAM_D : std_logic_vector(7 downto 0);
+ signal UART0_D : std_logic_vector(7 downto 0);
+ signal UART1_D : std_logic_vector(7 downto 0);
+ signal CPU_D : std_logic_vector(7 downto 0);
+
+ signal Mirror : std_logic;
+
+ signal IOWR_n : std_logic;
+ signal RAMCS_n : std_logic;
+ signal UART0CS_n : std_logic;
+ signal UART1CS_n : std_logic;
+
+ signal BaudOut0 : std_logic;
+ signal BaudOut1 : std_logic;
+
+begin
+
+ Wait_n <= '1';
+ BusRq_n <= '1';
+ INT_n <= '1';
+
+ process (Reset_n, Clk)
+ begin
+ if Reset_n = '0' then
+ Reset_s <= '0';
+ Mirror <= '0';
+ elsif Clk'event and Clk = '1' then
+ Reset_s <= '1';
+ if IORQ_n = '0' and A(7 downto 4) = "1111" then
+ Mirror <= D(0);
+ end if;
+ end if;
+ end process;
+
+ IOWR_n <= WR_n or IORQ_n;
+ RAMCS_n <= (not Mirror and not A(15)) or MREQ_n;
+ UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1';
+ UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1';
+
+ CPU_D <=
+ SRAM_D when RAMCS_n = '0' else
+ UART0_D when UART0CS_n = '0' else
+ UART1_D when UART1CS_n = '0' else
+ ROM_D;
+
+ u0 : entity work.T80s
+ generic map(Mode => 1, T2Write => 1, IOWait => 0)
+ port map(
+ RESET_n => RESET_s,
+ CLK_n => Clk,
+ WAIT_n => WAIT_n,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ BUSRQ_n => BUSRQ_n,
+ M1_n => M1_n,
+ MREQ_n => MREQ_n,
+ IORQ_n => IORQ_n,
+ RD_n => RD_n,
+ WR_n => WR_n,
+ RFSH_n => RFSH_n,
+ HALT_n => HALT_n,
+ BUSAK_n => BUSAK_n,
+ A => A,
+ DI => CPU_D,
+ DO => D);
+
+ u1 : entity work.MonZ80
+ port map(
+ Clk => Clk,
+ A => A(10 downto 0),
+ D => ROM_D);
+
+ u2 : entity work.SSRAM
+ generic map(
+ AddrWidth => 12)
+ port map(
+ Clk => Clk,
+ CE_n => RAMCS_n,
+ WE_n => WR_n,
+ A => A(11 downto 0),
+ DIn => D,
+ DOut => SRAM_D);
+
+ u3 : entity work.T16450
+ port map(
+ MR_n => Reset_s,
+ XIn => Clk,
+ RClk => BaudOut0,
+ CS_n => UART0CS_n,
+ Rd_n => RD_n,
+ Wr_n => IOWR_n,
+ A => A(2 downto 0),
+ D_In => D,
+ D_Out => UART0_D,
+ SIn => RXD0,
+ CTS_n => CTS0,
+ DSR_n => DSR0,
+ RI_n => RI0,
+ DCD_n => DCD0,
+ SOut => TXD0,
+ RTS_n => RTS0,
+ DTR_n => DTR0,
+ OUT1_n => open,
+ OUT2_n => open,
+ BaudOut => BaudOut0,
+ Intr => open);
+
+ u4 : entity work.T16450
+ port map(
+ MR_n => Reset_s,
+ XIn => Clk,
+ RClk => BaudOut1,
+ CS_n => UART1CS_n,
+ Rd_n => RD_n,
+ Wr_n => IOWR_n,
+ A => A(2 downto 0),
+ D_In => D,
+ D_Out => UART1_D,
+ SIn => RXD1,
+ CTS_n => CTS1,
+ DSR_n => DSR1,
+ RI_n => RI1,
+ DCD_n => DCD1,
+ SOut => TXD1,
+ RTS_n => RTS1,
+ DTR_n => DTR1,
+ OUT1_n => open,
+ OUT2_n => open,
+ BaudOut => BaudOut1,
+ Intr => open);
+
+end;
diff --git a/t80/DebugSystemXR.vhd b/t80/DebugSystemXR.vhd
new file mode 100644
index 0000000..ca8fa87
--- /dev/null
+++ b/t80/DebugSystemXR.vhd
@@ -0,0 +1,185 @@
+-- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs
+-- that can be synthesized and used with
+-- the NoICE debugger that can be found at
+-- http://www.noicedebugger.com/
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+entity DebugSystemXR is
+ port(
+ Reset_n : in std_logic;
+ Clk : in std_logic;
+ NMI_n : in std_logic;
+ OE_n : out std_logic;
+ WE_n : out std_logic;
+ RAMCS_n : out std_logic;
+ ROMCS_n : out std_logic;
+ PGM_n : out std_logic;
+ A : out std_logic_vector(16 downto 0);
+ D : inout std_logic_vector(7 downto 0);
+ RXD0 : in std_logic;
+ CTS0 : in std_logic;
+ DSR0 : in std_logic;
+ RI0 : in std_logic;
+ DCD0 : in std_logic;
+ RXD1 : in std_logic;
+ CTS1 : in std_logic;
+ DSR1 : in std_logic;
+ RI1 : in std_logic;
+ DCD1 : in std_logic;
+ TXD0 : out std_logic;
+ RTS0 : out std_logic;
+ DTR0 : out std_logic;
+ TXD1 : out std_logic;
+ RTS1 : out std_logic;
+ DTR1 : out std_logic
+ );
+end entity DebugSystemXR;
+
+architecture struct of DebugSystemXR is
+
+ signal M1_n : std_logic;
+ signal MREQ_n : std_logic;
+ signal IORQ_n : std_logic;
+ signal RD_n : std_logic;
+ signal WR_n : std_logic;
+ signal RFSH_n : std_logic;
+ signal HALT_n : std_logic;
+ signal WAIT_n : std_logic;
+ signal INT_n : std_logic;
+ signal RESET_s : std_logic;
+ signal BUSRQ_n : std_logic;
+ signal BUSAK_n : std_logic;
+ signal A_i : std_logic_vector(15 downto 0);
+ signal D_i : std_logic_vector(7 downto 0);
+ signal ROM_D : std_logic_vector(7 downto 0);
+ signal UART0_D : std_logic_vector(7 downto 0);
+ signal UART1_D : std_logic_vector(7 downto 0);
+ signal CPU_D : std_logic_vector(7 downto 0);
+
+ signal Mirror : std_logic;
+
+ signal IOWR_n : std_logic;
+ signal RAMCS_n_i : std_logic;
+ signal UART0CS_n : std_logic;
+ signal UART1CS_n : std_logic;
+
+ signal BaudOut0 : std_logic;
+ signal BaudOut1 : std_logic;
+
+begin
+
+ Wait_n <= '1';
+ BusRq_n <= '1';
+ INT_n <= '1';
+
+ OE_n <= RD_n;
+ WE_n <= WR_n;
+ RAMCS_n <= RAMCS_n_i;
+ ROMCS_n <= '1';
+ PGM_n <= '1';
+ A(14 downto 0) <= A_i(14 downto 0);
+ A(16 downto 15) <= "00";
+ D <= D_i when WR_n = '0' else "ZZZZZZZZ";
+
+ process (Reset_n, Clk)
+ begin
+ if Reset_n = '0' then
+ Reset_s <= '0';
+ Mirror <= '0';
+ elsif Clk'event and Clk = '1' then
+ Reset_s <= '1';
+ if IORQ_n = '0' and A_i(7 downto 4) = "1111" then
+ Mirror <= D_i(0);
+ end if;
+ end if;
+ end process;
+
+ IOWR_n <= WR_n or IORQ_n;
+ RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n;
+ UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1';
+ UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1';
+
+ CPU_D <=
+ D when RAMCS_n_i = '0' else
+ UART0_D when UART0CS_n = '0' else
+ UART1_D when UART1CS_n = '0' else
+ ROM_D;
+
+ u0 : entity work.T80s
+ generic map(Mode => 1, T2Write => 1, IOWait => 0)
+ port map(
+ RESET_n => RESET_s,
+ CLK_n => Clk,
+ WAIT_n => WAIT_n,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ BUSRQ_n => BUSRQ_n,
+ M1_n => M1_n,
+ MREQ_n => MREQ_n,
+ IORQ_n => IORQ_n,
+ RD_n => RD_n,
+ WR_n => WR_n,
+ RFSH_n => RFSH_n,
+ HALT_n => HALT_n,
+ BUSAK_n => BUSAK_n,
+ A => A_i,
+ DI => CPU_D,
+ DO => D_i);
+
+ u1 : entity work.MonZ80
+ port map(
+ Clk => Clk,
+ A => A_i(10 downto 0),
+ D => ROM_D);
+
+ u3 : entity work.T16450
+ port map(
+ MR_n => Reset_s,
+ XIn => Clk,
+ RClk => BaudOut0,
+ CS_n => UART0CS_n,
+ Rd_n => RD_n,
+ Wr_n => IOWR_n,
+ A => A_i(2 downto 0),
+ D_In => D_i,
+ D_Out => UART0_D,
+ SIn => RXD0,
+ CTS_n => CTS0,
+ DSR_n => DSR0,
+ RI_n => RI0,
+ DCD_n => DCD0,
+ SOut => TXD0,
+ RTS_n => RTS0,
+ DTR_n => DTR0,
+ OUT1_n => open,
+ OUT2_n => open,
+ BaudOut => BaudOut0,
+ Intr => open);
+
+ u4 : entity work.T16450
+ port map(
+ MR_n => Reset_s,
+ XIn => Clk,
+ RClk => BaudOut1,
+ CS_n => UART1CS_n,
+ Rd_n => RD_n,
+ Wr_n => IOWR_n,
+ A => A_i(2 downto 0),
+ D_In => D_i,
+ D_Out => UART1_D,
+ SIn => RXD1,
+ CTS_n => CTS1,
+ DSR_n => DSR1,
+ RI_n => RI1,
+ DCD_n => DCD1,
+ SOut => TXD1,
+ RTS_n => RTS1,
+ DTR_n => DTR1,
+ OUT1_n => open,
+ OUT2_n => open,
+ BaudOut => BaudOut1,
+ Intr => open);
+
+end;
diff --git a/t80/SSRAM.vhd b/t80/SSRAM.vhd
new file mode 100644
index 0000000..5d59eb8
--- /dev/null
+++ b/t80/SSRAM.vhd
@@ -0,0 +1,94 @@
+--
+-- Inferrable Synchronous SRAM for XST synthesis
+--
+-- Version : 0220
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t51/
+--
+-- Limitations :
+--
+-- File history :
+-- 0208 : Initial release
+-- 0218 : Fixed data out at write
+-- 0220 : Added support for XST
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity SSRAM is
+ generic(
+ AddrWidth : integer := 11;
+ DataWidth : integer := 8
+ );
+ port(
+ Clk : in std_logic;
+ CE_n : in std_logic;
+ WE_n : in std_logic;
+ A : in std_logic_vector(AddrWidth - 1 downto 0);
+ DIn : in std_logic_vector(DataWidth - 1 downto 0);
+ DOut : out std_logic_vector(DataWidth - 1 downto 0)
+ );
+end SSRAM;
+
+architecture behaviour of SSRAM is
+
+ type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
+ signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
+ signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
+ signal B : std_logic_vector(AddrWidth - 1 downto 0);
+
+begin
+
+ process (Clk)
+ begin
+ if Clk'event and Clk = '1' then
+ if (CE_n nor WE_n) = '1' then
+ RAM(to_integer(unsigned(B))) <= DIn;
+ end if;
+ A_r <= A;
+ B <= A;
+ end if;
+ end process;
+
+ DOut <= RAM(to_integer(unsigned(A_r)))
+-- pragma translate_off
+ when not is_x(A_r) else (others => '-')
+-- pragma translate_on
+ ;
+end;
diff --git a/t80/SSRAM2.vhd b/t80/SSRAM2.vhd
new file mode 100644
index 0000000..98c0c2c
--- /dev/null
+++ b/t80/SSRAM2.vhd
@@ -0,0 +1,92 @@
+--
+-- Inferrable Synchronous SRAM for Leonardo synthesis, no write through!
+--
+-- Version : 0236
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t51/
+--
+-- Limitations :
+--
+-- File history :
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity SSRAM is
+ generic(
+ AddrWidth : integer := 16;
+ DataWidth : integer := 8
+ );
+ port(
+ Clk : in std_logic;
+ CE_n : in std_logic;
+ WE_n : in std_logic;
+ A : in std_logic_vector(AddrWidth - 1 downto 0);
+ DIn : in std_logic_vector(DataWidth - 1 downto 0);
+ DOut : out std_logic_vector(DataWidth - 1 downto 0)
+ );
+end SSRAM;
+
+architecture behaviour of SSRAM is
+
+ type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
+ signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
+ signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
+
+begin
+
+ process (Clk)
+ begin
+ if Clk'event and Clk = '1' then
+-- pragma translate_off
+ if not is_x(A) then
+-- pragma translate_on
+ DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0))));
+-- pragma translate_off
+ end if;
+-- pragma translate_on
+ if CE_n = '0' and WE_n = '0' then
+ RAM(to_integer(unsigned(A_r))) <= DIn;
+ end if;
+ A_r <= A;
+ end if;
+ end process;
+
+end;
diff --git a/t80/SSRAMX.vhd b/t80/SSRAMX.vhd
new file mode 100644
index 0000000..474a6ff
--- /dev/null
+++ b/t80/SSRAMX.vhd
@@ -0,0 +1,132 @@
+--
+-- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes)
+--
+-- Version : 0247
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t51/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0240 : Initial release
+--
+-- 0242 : Changed RAMB4_S8 to map by name
+--
+-- 0247 : Added RAMB4_S8 component declaration
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity SSRAM is
+ generic(
+ AddrWidth : integer := 11;
+ DataWidth : integer := 8
+ );
+ port(
+ Clk : in std_logic;
+ CE_n : in std_logic;
+ WE_n : in std_logic;
+ A : in std_logic_vector(AddrWidth - 1 downto 0);
+ DIn : in std_logic_vector(DataWidth - 1 downto 0);
+ DOut : out std_logic_vector(DataWidth - 1 downto 0)
+ );
+end SSRAM;
+
+architecture rtl of SSRAM is
+
+ component RAMB4_S8
+ port(
+ DO : out std_logic_vector(7 downto 0);
+ ADDR : in std_logic_vector(8 downto 0);
+ CLK : in std_ulogic;
+ DI : in std_logic_vector(7 downto 0);
+ EN : in std_ulogic;
+ RST : in std_ulogic;
+ WE : in std_ulogic);
+ end component;
+
+ constant RAMs : integer := (2 ** AddrWidth) / 512;
+
+ type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0);
+
+ signal bRAMOut : bRAMOut_a;
+ signal biA_r : integer;
+ signal A_r : unsigned(A'left downto 0);
+ signal A_i : std_logic_vector(8 downto 0);
+ signal WEA : std_logic_vector(RAMs - 1 downto 0);
+
+begin
+
+ process (Clk)
+ begin
+ if Clk'event and Clk = '1' then
+ A_r <= unsigned(A);
+ end if;
+ end process;
+
+ biA_r <= to_integer(A_r(A'left downto 9));
+ A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0);
+
+ bG1: for I in 0 to RAMs - 1 generate
+ begin
+ WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0';
+ BSSRAM : RAMB4_S8
+ port map(
+ DI => DIn,
+ EN => '1',
+ WE => WEA(I),
+ RST => '0',
+ CLK => Clk,
+ ADDR => A_i,
+ DO => bRAMOut(I));
+ end generate;
+
+ process (biA_r, bRAMOut)
+ begin
+ DOut <= bRAMOut(0);
+ for I in 1 to RAMs - 1 loop
+ if biA_r = I then
+ DOut <= bRAMOut(I);
+ end if;
+ end loop;
+ end process;
+
+end;
diff --git a/t80/T16450.vhd b/t80/T16450.vhd
new file mode 100644
index 0000000..ad266c2
--- /dev/null
+++ b/t80/T16450.vhd
@@ -0,0 +1,459 @@
+--
+-- 16450 compatible UART with synchronous bus interface
+-- RClk/BaudOut is XIn enable instead of actual clock
+--
+-- Version : 0249b
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0208 : First release
+--
+-- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer
+-- Added modem status and break detection
+-- Added support for 1.5 and 2 stop bits
+--
+-- 0249b : Fixed loopback break generation bugs found by Andy Dyer
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity T16450 is
+ port(
+ MR_n : in std_logic;
+ XIn : in std_logic;
+ RClk : in std_logic;
+ CS_n : in std_logic;
+ Rd_n : in std_logic;
+ Wr_n : in std_logic;
+ A : in std_logic_vector(2 downto 0);
+ D_In : in std_logic_vector(7 downto 0);
+ D_Out : out std_logic_vector(7 downto 0);
+ SIn : in std_logic;
+ CTS_n : in std_logic;
+ DSR_n : in std_logic;
+ RI_n : in std_logic;
+ DCD_n : in std_logic;
+ SOut : out std_logic;
+ RTS_n : out std_logic;
+ DTR_n : out std_logic;
+ OUT1_n : out std_logic;
+ OUT2_n : out std_logic;
+ BaudOut : out std_logic;
+ Intr : out std_logic
+ );
+end T16450;
+
+architecture rtl of T16450 is
+
+ signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register
+ signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register
+ signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register
+ signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register
+ signal LCR : std_logic_vector(7 downto 0); -- Line Control Register
+ signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register
+ signal LSR : std_logic_vector(7 downto 0); -- Line Status Register
+ signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register
+ signal SCR : std_logic_vector(7 downto 0); -- Scratch Register
+ signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS)
+ signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS)
+
+ signal DM0 : std_logic_vector(7 downto 0);
+ signal DM1 : std_logic_vector(7 downto 0);
+
+ signal MSR_In : std_logic_vector(3 downto 0);
+
+ signal Bit_Phase : unsigned(3 downto 0);
+ signal Brk_Cnt : unsigned(3 downto 0);
+ signal RX_Filtered : std_logic;
+ signal RX_ShiftReg : std_logic_vector(7 downto 0);
+ signal RX_Bit_Cnt : integer range 0 to 11;
+ signal RX_Parity : std_logic;
+ signal RXD : std_logic;
+
+ signal TX_Tick : std_logic;
+ signal TX_ShiftReg : std_logic_vector(7 downto 0);
+ signal TX_Bit_Cnt : integer range 0 to 11;
+ signal TX_Parity : std_logic;
+ signal TX_Next_Is_Stop : std_logic;
+ signal TX_Stop_Bit : std_logic;
+ signal TXD : std_logic;
+
+begin
+
+ DTR_n <= MCR(4) or not MCR(0);
+ RTS_n <= MCR(4) or not MCR(1);
+ OUT1_n <= MCR(4) or not MCR(2);
+ OUT2_n <= MCR(4) or not MCR(3);
+ SOut <= MCR(4) or (TXD and not LCR(6));
+ RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6));
+
+ Intr <= not IIR(0);
+
+ -- Registers
+ DM0 <= DLL when LCR(7) = '1' else RBR;
+ DM1 <= DLM when LCR(7) = '1' else IER;
+ with A select
+ D_Out <=
+ DM0 when "000",
+ DM1 when "001",
+ IIR when "010",
+ LCR when "011",
+ MCR when "100",
+ LSR when "101",
+ MSR when "110",
+ SCR when others;
+ process (MR_n, XIn)
+ begin
+ if MR_n = '0' then
+ THR <= "00000000";
+ IER <= "00000000";
+ LCR <= "00000000";
+ MCR <= "00000000";
+ MSR(3 downto 0) <= "0000";
+ SCR <= "00000000"; -- ??
+ DLL <= "00000000"; -- ??
+ DLM <= "00000000"; -- ??
+ elsif XIn'event and XIn = '1' then
+ if Wr_n = '0' and CS_n = '0' then
+ case A is
+ when "000" =>
+ if LCR(7) = '1' then
+ DLL <= D_In;
+ else
+ THR <= D_In;
+ end if;
+ when "001" =>
+ if LCR(7) = '1' then
+ DLM <= D_In;
+ else
+ IER(3 downto 0) <= D_In(3 downto 0);
+ end if;
+ when "011" =>
+ LCR <= D_In;
+ when "100" =>
+ MCR <= D_In;
+ when "111" =>
+ SCR <= D_In;
+ when others =>
+ end case;
+ end if;
+ if Rd_n = '0' and CS_n = '0' and A = "110" then
+ MSR(3 downto 0) <= "0000";
+ end if;
+ if MSR(4) /= MSR_In(0) then
+ MSR(0) <= '1';
+ end if;
+ if MSR(5) /= MSR_In(1) then
+ MSR(1) <= '1';
+ end if;
+ if MSR(6) = '0' and MSR_In(2) = '1' then
+ MSR(2) <= '1';
+ end if;
+ if MSR(7) /= MSR_In(3) then
+ MSR(3) <= '1';
+ end if;
+ end if;
+ end process;
+ process (XIn)
+ begin
+ if XIn'event and XIn = '1' then
+ if MCR(4) = '0' then
+ MSR(4) <= MSR_In(0);
+ MSR(5) <= MSR_In(1);
+ MSR(6) <= MSR_In(2);
+ MSR(7) <= MSR_In(3);
+ else
+ MSR(4) <= MCR(1);
+ MSR(5) <= MCR(0);
+ MSR(6) <= MCR(2);
+ MSR(7) <= MCR(3);
+ end if;
+ MSR_In(0) <= CTS_n;
+ MSR_In(1) <= DSR_n;
+ MSR_In(2) <= RI_n;
+ MSR_In(3) <= DCD_n;
+ end if;
+ end process;
+
+ IIR(7 downto 3) <= "00000";
+ IIR(2 downto 0) <=
+ "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else
+ "100" when (IER(0) and LSR(0)) = '1' else
+ "010" when (IER(1) and LSR(5)) = '1' else
+ "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or
+ (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else
+ "001";
+
+ -- Baud x 16 clock generator
+ process (MR_n, XIn)
+ variable Baud_Cnt : unsigned(15 downto 0);
+ begin
+ if MR_n = '0' then
+ Baud_Cnt := "0000000000000000";
+ BaudOut <= '0';
+ elsif XIn'event and XIn = '1' then
+ if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then
+ Baud_Cnt(15 downto 8) := unsigned(DLM);
+ Baud_Cnt(7 downto 0) := unsigned(DLL);
+ BaudOut <= '1';
+ else
+ Baud_Cnt := Baud_Cnt - 1;
+ BaudOut <= '0';
+ end if;
+ end if;
+ end process;
+
+ -- Input filter
+ process (MR_n, XIn)
+ variable Samples : std_logic_vector(1 downto 0);
+ begin
+ if MR_n = '0' then
+ Samples := "11";
+ RX_Filtered <= '1';
+ elsif XIn'event and XIn = '1' then
+ if RClk = '1' then
+ Samples(1) := Samples(0);
+ Samples(0) := RXD;
+ end if;
+ if Samples = "00" then
+ RX_Filtered <= '0';
+ end if;
+ if Samples = "11" then
+ RX_Filtered <= '1';
+ end if;
+ end if;
+ end process;
+
+ -- Receive state machine
+ process (MR_n, XIn)
+ begin
+ if MR_n = '0' then
+ RBR <= "00000000";
+ LSR(4 downto 0) <= "00000";
+ Bit_Phase <= "0000";
+ Brk_Cnt <= "0000";
+ RX_ShiftReg(7 downto 0) <= "00000000";
+ RX_Bit_Cnt <= 0;
+ RX_Parity <= '0';
+ elsif XIn'event and XIn = '1' then
+ if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then
+ LSR(0) <= '0'; -- DR
+ end if;
+ if A = "101" and Rd_n = '0' and CS_n = '0' then
+ LSR(4) <= '0'; -- BI
+ LSR(3) <= '0'; -- FE
+ LSR(2) <= '0'; -- PE
+ LSR(1) <= '0'; -- OE
+ end if;
+ if RClk = '1' then
+ if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then
+ Bit_Phase <= "0000";
+ else
+ Bit_Phase <= Bit_Phase + 1;
+ end if;
+ if Bit_Phase = "1111" then
+ if RX_Filtered = '1' then
+ Brk_Cnt <= "0000";
+ else
+ Brk_Cnt <= Brk_Cnt + 1;
+ end if;
+ if Brk_Cnt = "1100" then
+ LSR(4) <= '1'; -- BI
+ end if;
+ end if;
+ if RX_Bit_Cnt = 0 then
+ if Bit_Phase = "0111" then
+ RX_Bit_Cnt <= RX_Bit_Cnt + 1;
+ RX_Parity <= not LCR(4); -- EPS
+ end if;
+ elsif Bit_Phase = "1111" then
+ RX_Bit_Cnt <= RX_Bit_Cnt + 1;
+ if RX_Bit_Cnt = 10 then -- Parity stop bit
+ RX_Bit_Cnt <= 0;
+ LSR(0) <= '1'; -- UART Receive complete
+ LSR(3) <= not RX_Filtered; -- Framing error
+ elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
+ (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
+ (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
+ (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity
+ RX_Bit_Cnt <= 0;
+ if LCR(3) = '1' then -- PEN
+ RX_Bit_Cnt <= 10;
+ if LCR(5) = '1' then -- Stick parity
+ if RX_Filtered = LCR(4) then
+ LSR(2) <= '1';
+ end if;
+ else
+ if RX_Filtered /= RX_Parity then
+ LSR(2) <= '1';
+ end if;
+ end if;
+ else
+ LSR(0) <= '1'; -- UART Receive complete
+ LSR(3) <= not RX_Filtered; -- Framing error
+ end if;
+ RBR <= RX_ShiftReg(7 downto 0);
+ LSR(1) <= LSR(0);
+ if A = "101" and Rd_n = '0' and CS_n = '0' then
+ LSR(1) <= '0';
+ end if;
+ else
+ RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1);
+ RX_ShiftReg(7) <= RX_Filtered;
+ if LCR(1 downto 0) = "10" then
+ RX_ShiftReg(7) <= '0';
+ RX_ShiftReg(6) <= RX_Filtered;
+ end if;
+ if LCR(1 downto 0) = "01" then
+ RX_ShiftReg(7) <= '0';
+ RX_ShiftReg(6) <= '0';
+ RX_ShiftReg(5) <= RX_Filtered;
+ end if;
+ if LCR(1 downto 0) = "00" then
+ RX_ShiftReg(7) <= '0';
+ RX_ShiftReg(6) <= '0';
+ RX_ShiftReg(5) <= '0';
+ RX_ShiftReg(4) <= RX_Filtered;
+ end if;
+ RX_Parity <= RX_Filtered xor RX_Parity;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -- Transmit bit tick
+ process (MR_n, XIn)
+ variable TX_Cnt : unsigned(4 downto 0);
+ begin
+ if MR_n = '0' then
+ TX_Cnt := "00000";
+ TX_Tick <= '0';
+ elsif XIn'event and XIn = '1' then
+ TX_Tick <= '0';
+ if RClk = '1' then
+ TX_Cnt := TX_Cnt + 1;
+ if LCR(2) = '1' and TX_Stop_Bit = '1' then
+ if LCR(1 downto 0) = "00" then
+ if TX_Cnt = "10111" then
+ TX_Tick <= '1';
+ TX_Cnt(3 downto 0) := "0000";
+ end if;
+ else
+ if TX_Cnt = "11111" then
+ TX_Tick <= '1';
+ TX_Cnt(3 downto 0) := "0000";
+ end if;
+ end if;
+ else
+ TX_Cnt(4) := '1';
+ if TX_Cnt(3 downto 0) = "1111" then
+ TX_Tick <= '1';
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -- Transmit state machine
+ process (MR_n, XIn)
+ begin
+ if MR_n = '0' then
+ LSR(7 downto 5) <= "011";
+ TX_Bit_Cnt <= 0;
+ TX_ShiftReg <= (others => '0');
+ TXD <= '1';
+ TX_Parity <= '0';
+ TX_Next_Is_Stop <= '0';
+ TX_Stop_Bit <= '0';
+ elsif XIn'event and XIn = '1' then
+ if TX_Tick = '1' then
+ TX_Next_Is_Stop <= '0';
+ TX_Stop_Bit <= TX_Next_Is_Stop;
+ case TX_Bit_Cnt is
+ when 0 =>
+ if LSR(5) <= '0' then -- THRE
+ TX_Bit_Cnt <= 1;
+ end if;
+ TXD <= '1';
+ when 1 => -- Start bit
+ TX_ShiftReg(7 downto 0) <= THR;
+ LSR(5) <= '1'; -- THRE
+ TXD <= '0';
+ TX_Parity <= not LCR(4); -- EPS
+ TX_Bit_Cnt <= TX_Bit_Cnt + 1;
+ when 10 => -- Parity bit
+ TXD <= TX_Parity;
+ if LCR(5) = '1' then -- Stick parity
+ TXD <= not LCR(4);
+ end if;
+ TX_Bit_Cnt <= 0;
+ TX_Next_Is_Stop <= '1';
+ when others =>
+ TX_Bit_Cnt <= TX_Bit_Cnt + 1;
+ if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
+ (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
+ (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
+ (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then
+ TX_Bit_Cnt <= 0;
+ if LCR(3) = '1' then -- PEN
+ TX_Bit_Cnt <= 10;
+ else
+ TX_Next_Is_Stop <= '1';
+ end if;
+ LSR(6) <= '1'; -- TEMT
+ end if;
+ TXD <= TX_ShiftReg(0);
+ TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1);
+ TX_Parity <= TX_ShiftReg(0) xor TX_Parity;
+ end case;
+ end if;
+ if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then
+ LSR(5) <= '0'; -- THRE
+ LSR(6) <= '0'; -- TEMT
+ end if;
+ end if;
+ end process;
+
+end;
diff --git a/t80/T80.vhd b/t80/T80.vhd
new file mode 100644
index 0000000..398fa0d
--- /dev/null
+++ b/t80/T80.vhd
@@ -0,0 +1,1073 @@
+--
+-- Z80 compatible microprocessor core
+--
+-- Version : 0247
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0208 : First complete release
+--
+-- 0210 : Fixed wait and halt
+--
+-- 0211 : Fixed Refresh addition and IM 1
+--
+-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
+--
+-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
+--
+-- 0235 : Added clock enable and IM 2 fix by Mike Johnson
+--
+-- 0237 : Changed 8080 I/O address output, added IntE output
+--
+-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
+--
+-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
+--
+-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
+--
+-- 0247 : Fixed bus req/ack cycle
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use work.T80_Pack.all;
+
+entity T80 is
+ generic(
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ CEN : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ IORQ : out std_logic;
+ NoRead : out std_logic;
+ Write : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DInst : in std_logic_vector(7 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0);
+ MC : out std_logic_vector(2 downto 0);
+ TS : out std_logic_vector(2 downto 0);
+ IntCycle_n : out std_logic;
+ IntE : out std_logic;
+ Stop : out std_logic
+ );
+end T80;
+
+architecture rtl of T80 is
+
+ constant aNone : std_logic_vector(2 downto 0) := "111";
+ constant aBC : std_logic_vector(2 downto 0) := "000";
+ constant aDE : std_logic_vector(2 downto 0) := "001";
+ constant aXY : std_logic_vector(2 downto 0) := "010";
+ constant aIOA : std_logic_vector(2 downto 0) := "100";
+ constant aSP : std_logic_vector(2 downto 0) := "101";
+ constant aZI : std_logic_vector(2 downto 0) := "110";
+
+ -- Registers
+ signal ACC, F : std_logic_vector(7 downto 0);
+ signal Ap, Fp : std_logic_vector(7 downto 0);
+ signal I : std_logic_vector(7 downto 0);
+ signal R : unsigned(7 downto 0);
+ signal SP, PC : unsigned(15 downto 0);
+ signal RegDIH : std_logic_vector(7 downto 0);
+ signal RegDIL : std_logic_vector(7 downto 0);
+ signal RegBusA : std_logic_vector(15 downto 0);
+ signal RegBusB : std_logic_vector(15 downto 0);
+ signal RegBusC : std_logic_vector(15 downto 0);
+ signal RegAddrA_r : std_logic_vector(2 downto 0);
+ signal RegAddrA : std_logic_vector(2 downto 0);
+ signal RegAddrB_r : std_logic_vector(2 downto 0);
+ signal RegAddrB : std_logic_vector(2 downto 0);
+ signal RegAddrC : std_logic_vector(2 downto 0);
+ signal RegWEH : std_logic;
+ signal RegWEL : std_logic;
+ signal Alternate : std_logic;
+
+ -- Help Registers
+ signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register
+ signal IR : std_logic_vector(7 downto 0); -- Instruction register
+ signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
+ signal RegBusA_r : std_logic_vector(15 downto 0);
+
+ signal ID16 : signed(15 downto 0);
+ signal Save_Mux : std_logic_vector(7 downto 0);
+
+ signal TState : unsigned(2 downto 0);
+ signal MCycle : std_logic_vector(2 downto 0);
+ signal IntE_FF1 : std_logic;
+ signal IntE_FF2 : std_logic;
+ signal Halt_FF : std_logic;
+ signal BusReq_s : std_logic;
+ signal BusAck : std_logic;
+ signal ClkEn : std_logic;
+ signal NMI_s : std_logic;
+ signal INT_s : std_logic;
+ signal IStatus : std_logic_vector(1 downto 0);
+
+ signal DI_Reg : std_logic_vector(7 downto 0);
+ signal T_Res : std_logic;
+ signal XY_State : std_logic_vector(1 downto 0);
+ signal Pre_XY_F_M : std_logic_vector(2 downto 0);
+ signal NextIs_XY_Fetch : std_logic;
+ signal XY_Ind : std_logic;
+ signal No_BTR : std_logic;
+ signal BTR_r : std_logic;
+ signal Auto_Wait : std_logic;
+ signal Auto_Wait_t1 : std_logic;
+ signal Auto_Wait_t2 : std_logic;
+ signal IncDecZ : std_logic;
+
+ -- ALU signals
+ signal BusB : std_logic_vector(7 downto 0);
+ signal BusA : std_logic_vector(7 downto 0);
+ signal ALU_Q : std_logic_vector(7 downto 0);
+ signal F_Out : std_logic_vector(7 downto 0);
+
+ -- Registered micro code outputs
+ signal Read_To_Reg_r : std_logic_vector(4 downto 0);
+ signal Arith16_r : std_logic;
+ signal Z16_r : std_logic;
+ signal ALU_Op_r : std_logic_vector(3 downto 0);
+ signal Save_ALU_r : std_logic;
+ signal PreserveC_r : std_logic;
+ signal MCycles : std_logic_vector(2 downto 0);
+
+ -- Micro code outputs
+ signal MCycles_d : std_logic_vector(2 downto 0);
+ signal TStates : std_logic_vector(2 downto 0);
+ signal IntCycle : std_logic;
+ signal NMICycle : std_logic;
+ signal Inc_PC : std_logic;
+ signal Inc_WZ : std_logic;
+ signal IncDec_16 : std_logic_vector(3 downto 0);
+ signal Prefix : std_logic_vector(1 downto 0);
+ signal Read_To_Acc : std_logic;
+ signal Read_To_Reg : std_logic;
+ signal Set_BusB_To : std_logic_vector(3 downto 0);
+ signal Set_BusA_To : std_logic_vector(3 downto 0);
+ signal ALU_Op : std_logic_vector(3 downto 0);
+ signal Save_ALU : std_logic;
+ signal PreserveC : std_logic;
+ signal Arith16 : std_logic;
+ signal Set_Addr_To : std_logic_vector(2 downto 0);
+ signal Jump : std_logic;
+ signal JumpE : std_logic;
+ signal JumpXY : std_logic;
+ signal Call : std_logic;
+ signal RstP : std_logic;
+ signal LDZ : std_logic;
+ signal LDW : std_logic;
+ signal LDSPHL : std_logic;
+ signal IORQ_i : std_logic;
+ signal Special_LD : std_logic_vector(2 downto 0);
+ signal ExchangeDH : std_logic;
+ signal ExchangeRp : std_logic;
+ signal ExchangeAF : std_logic;
+ signal ExchangeRS : std_logic;
+ signal I_DJNZ : std_logic;
+ signal I_CPL : std_logic;
+ signal I_CCF : std_logic;
+ signal I_SCF : std_logic;
+ signal I_RETN : std_logic;
+ signal I_BT : std_logic;
+ signal I_BC : std_logic;
+ signal I_BTR : std_logic;
+ signal I_RLD : std_logic;
+ signal I_RRD : std_logic;
+ signal I_INRC : std_logic;
+ signal SetDI : std_logic;
+ signal SetEI : std_logic;
+ signal IMode : std_logic_vector(1 downto 0);
+ signal Halt : std_logic;
+
+begin
+
+ mcode : T80_MCode
+ generic map(
+ Mode => Mode,
+ Flag_C => Flag_C,
+ Flag_N => Flag_N,
+ Flag_P => Flag_P,
+ Flag_X => Flag_X,
+ Flag_H => Flag_H,
+ Flag_Y => Flag_Y,
+ Flag_Z => Flag_Z,
+ Flag_S => Flag_S)
+ port map(
+ IR => IR,
+ ISet => ISet,
+ MCycle => MCycle,
+ F => F,
+ NMICycle => NMICycle,
+ IntCycle => IntCycle,
+ MCycles => MCycles_d,
+ TStates => TStates,
+ Prefix => Prefix,
+ Inc_PC => Inc_PC,
+ Inc_WZ => Inc_WZ,
+ IncDec_16 => IncDec_16,
+ Read_To_Acc => Read_To_Acc,
+ Read_To_Reg => Read_To_Reg,
+ Set_BusB_To => Set_BusB_To,
+ Set_BusA_To => Set_BusA_To,
+ ALU_Op => ALU_Op,
+ Save_ALU => Save_ALU,
+ PreserveC => PreserveC,
+ Arith16 => Arith16,
+ Set_Addr_To => Set_Addr_To,
+ IORQ => IORQ_i,
+ Jump => Jump,
+ JumpE => JumpE,
+ JumpXY => JumpXY,
+ Call => Call,
+ RstP => RstP,
+ LDZ => LDZ,
+ LDW => LDW,
+ LDSPHL => LDSPHL,
+ Special_LD => Special_LD,
+ ExchangeDH => ExchangeDH,
+ ExchangeRp => ExchangeRp,
+ ExchangeAF => ExchangeAF,
+ ExchangeRS => ExchangeRS,
+ I_DJNZ => I_DJNZ,
+ I_CPL => I_CPL,
+ I_CCF => I_CCF,
+ I_SCF => I_SCF,
+ I_RETN => I_RETN,
+ I_BT => I_BT,
+ I_BC => I_BC,
+ I_BTR => I_BTR,
+ I_RLD => I_RLD,
+ I_RRD => I_RRD,
+ I_INRC => I_INRC,
+ SetDI => SetDI,
+ SetEI => SetEI,
+ IMode => IMode,
+ Halt => Halt,
+ NoRead => NoRead,
+ Write => Write);
+
+ alu : T80_ALU
+ generic map(
+ Mode => Mode,
+ Flag_C => Flag_C,
+ Flag_N => Flag_N,
+ Flag_P => Flag_P,
+ Flag_X => Flag_X,
+ Flag_H => Flag_H,
+ Flag_Y => Flag_Y,
+ Flag_Z => Flag_Z,
+ Flag_S => Flag_S)
+ port map(
+ Arith16 => Arith16_r,
+ Z16 => Z16_r,
+ ALU_Op => ALU_Op_r,
+ IR => IR(5 downto 0),
+ ISet => ISet,
+ BusA => BusA,
+ BusB => BusB,
+ F_In => F,
+ Q => ALU_Q,
+ F_Out => F_Out);
+
+ ClkEn <= CEN and not BusAck;
+
+ T_Res <= '1' when TState = unsigned(TStates) else '0';
+
+ NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
+ ((Set_Addr_To = aXY) or
+ (MCycle = "001" and IR = "11001011") or
+ (MCycle = "001" and IR = "00110110")) else '0';
+
+ Save_Mux <= BusB when ExchangeRp = '1' else
+ DI_Reg when Save_ALU_r = '0' else
+ ALU_Q;
+
+ process (RESET_n, CLK_n)
+ begin
+ if RESET_n = '0' then
+ PC <= (others => '0'); -- Program Counter
+ A <= (others => '0');
+ TmpAddr <= (others => '0');
+ IR <= "00000000";
+ ISet <= "00";
+ XY_State <= "00";
+ IStatus <= "00";
+ MCycles <= "000";
+ DO <= "00000000";
+
+ ACC <= (others => '1');
+ F <= (others => '1');
+ Ap <= (others => '1');
+ Fp <= (others => '1');
+ I <= (others => '0');
+ R <= (others => '0');
+ SP <= (others => '1');
+ Alternate <= '0';
+
+ Read_To_Reg_r <= "00000";
+ F <= (others => '1');
+ Arith16_r <= '0';
+ BTR_r <= '0';
+ Z16_r <= '0';
+ ALU_Op_r <= "0000";
+ Save_ALU_r <= '0';
+ PreserveC_r <= '0';
+ XY_Ind <= '0';
+
+ elsif CLK_n'event and CLK_n = '1' then
+
+ if ClkEn = '1' then
+
+ ALU_Op_r <= "0000";
+ Save_ALU_r <= '0';
+ Read_To_Reg_r <= "00000";
+
+ MCycles <= MCycles_d;
+
+ if IMode /= "11" then
+ IStatus <= IMode;
+ end if;
+
+ Arith16_r <= Arith16;
+ PreserveC_r <= PreserveC;
+ if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
+ Z16_r <= '1';
+ else
+ Z16_r <= '0';
+ end if;
+
+ if MCycle = "001" and TState(2) = '0' then
+ -- MCycle = 1 and TState = 1, 2, or 3
+
+ if TState = 2 and Wait_n = '1' then
+ if Mode < 2 then
+ A(7 downto 0) <= std_logic_vector(R);
+ A(15 downto 8) <= I;
+ R(6 downto 0) <= R(6 downto 0) + 1;
+ end if;
+
+ if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
+ PC <= PC + 1;
+ end if;
+
+ if IntCycle = '1' and IStatus = "01" then
+ IR <= "11111111";
+ elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
+ IR <= "00000000";
+ else
+ IR <= DInst;
+ end if;
+
+ ISet <= "00";
+ if Prefix /= "00" then
+ if Prefix = "11" then
+ if IR(5) = '1' then
+ XY_State <= "10";
+ else
+ XY_State <= "01";
+ end if;
+ else
+ if Prefix = "10" then
+ XY_State <= "00";
+ XY_Ind <= '0';
+ end if;
+ ISet <= Prefix;
+ end if;
+ else
+ XY_State <= "00";
+ XY_Ind <= '0';
+ end if;
+ end if;
+
+ else
+ -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
+
+ if MCycle = "110" then
+ XY_Ind <= '1';
+ if Prefix = "01" then
+ ISet <= "01";
+ end if;
+ end if;
+
+ if T_Res = '1' then
+ BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
+ if Jump = '1' then
+ A(15 downto 8) <= DI_Reg;
+ A(7 downto 0) <= TmpAddr(7 downto 0);
+ PC(15 downto 8) <= unsigned(DI_Reg);
+ PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
+ elsif JumpXY = '1' then
+ A <= RegBusC;
+ PC <= unsigned(RegBusC);
+ elsif Call = '1' or RstP = '1' then
+ A <= TmpAddr;
+ PC <= unsigned(TmpAddr);
+ elsif MCycle = MCycles and NMICycle = '1' then
+ A <= "0000000001100110";
+ PC <= "0000000001100110";
+ elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
+ A(15 downto 8) <= I;
+ A(7 downto 0) <= TmpAddr(7 downto 0);
+ PC(15 downto 8) <= unsigned(I);
+ PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
+ else
+ case Set_Addr_To is
+ when aXY =>
+ if XY_State = "00" then
+ A <= RegBusC;
+ else
+ if NextIs_XY_Fetch = '1' then
+ A <= std_logic_vector(PC);
+ else
+ A <= TmpAddr;
+ end if;
+ end if;
+ when aIOA =>
+ if Mode = 3 then
+ -- Memory map I/O on GBZ80
+ A(15 downto 8) <= (others => '1');
+ elsif Mode = 2 then
+ -- Duplicate I/O address on 8080
+ A(15 downto 8) <= DI_Reg;
+ else
+ A(15 downto 8) <= ACC;
+ end if;
+ A(7 downto 0) <= DI_Reg;
+ when aSP =>
+ A <= std_logic_vector(SP);
+ when aBC =>
+ if Mode = 3 and IORQ_i = '1' then
+ -- Memory map I/O on GBZ80
+ A(15 downto 8) <= (others => '1');
+ A(7 downto 0) <= RegBusC(7 downto 0);
+ else
+ A <= RegBusC;
+ end if;
+ when aDE =>
+ A <= RegBusC;
+ when aZI =>
+ if Inc_WZ = '1' then
+ A <= std_logic_vector(unsigned(TmpAddr) + 1);
+ else
+ A(15 downto 8) <= DI_Reg;
+ A(7 downto 0) <= TmpAddr(7 downto 0);
+ end if;
+ when others =>
+ A <= std_logic_vector(PC);
+ end case;
+ end if;
+
+ Save_ALU_r <= Save_ALU;
+ ALU_Op_r <= ALU_Op;
+
+ if I_CPL = '1' then
+ -- CPL
+ ACC <= not ACC;
+ F(Flag_Y) <= not ACC(5);
+ F(Flag_H) <= '1';
+ F(Flag_X) <= not ACC(3);
+ F(Flag_N) <= '1';
+ end if;
+ if I_CCF = '1' then
+ -- CCF
+ F(Flag_C) <= not F(Flag_C);
+ F(Flag_Y) <= ACC(5);
+ F(Flag_H) <= F(Flag_C);
+ F(Flag_X) <= ACC(3);
+ F(Flag_N) <= '0';
+ end if;
+ if I_SCF = '1' then
+ -- SCF
+ F(Flag_C) <= '1';
+ F(Flag_Y) <= ACC(5);
+ F(Flag_H) <= '0';
+ F(Flag_X) <= ACC(3);
+ F(Flag_N) <= '0';
+ end if;
+ end if;
+
+ if TState = 2 and Wait_n = '1' then
+ if ISet = "01" and MCycle = "111" then
+ IR <= DInst;
+ end if;
+ if JumpE = '1' then
+ PC <= unsigned(signed(PC) + signed(DI_Reg));
+ elsif Inc_PC = '1' then
+ PC <= PC + 1;
+ end if;
+ if BTR_r = '1' then
+ PC <= PC - 2;
+ end if;
+ if RstP = '1' then
+ TmpAddr <= (others =>'0');
+ TmpAddr(5 downto 3) <= IR(5 downto 3);
+ end if;
+ end if;
+ if TState = 3 and MCycle = "110" then
+ TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
+ end if;
+
+ if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
+ if IncDec_16(2 downto 0) = "111" then
+ if IncDec_16(3) = '1' then
+ SP <= SP - 1;
+ else
+ SP <= SP + 1;
+ end if;
+ end if;
+ end if;
+
+ if LDSPHL = '1' then
+ SP <= unsigned(RegBusC);
+ end if;
+ if ExchangeAF = '1' then
+ Ap <= ACC;
+ ACC <= Ap;
+ Fp <= F;
+ F <= Fp;
+ end if;
+ if ExchangeRS = '1' then
+ Alternate <= not Alternate;
+ end if;
+ end if;
+
+ if TState = 3 then
+ if LDZ = '1' then
+ TmpAddr(7 downto 0) <= DI_Reg;
+ end if;
+ if LDW = '1' then
+ TmpAddr(15 downto 8) <= DI_Reg;
+ end if;
+
+ if Special_LD(2) = '1' then
+ case Special_LD(1 downto 0) is
+ when "00" =>
+ ACC <= I;
+ F(Flag_P) <= IntE_FF2;
+ when "01" =>
+ ACC <= std_logic_vector(R);
+ F(Flag_P) <= IntE_FF2;
+ when "10" =>
+ I <= ACC;
+ when others =>
+ R <= unsigned(ACC);
+ end case;
+ end if;
+ end if;
+
+ if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
+ if Mode = 3 then
+ F(6) <= F_Out(6);
+ F(5) <= F_Out(5);
+ F(7) <= F_Out(7);
+ if PreserveC_r = '0' then
+ F(4) <= F_Out(4);
+ end if;
+ else
+ F(7 downto 1) <= F_Out(7 downto 1);
+ if PreserveC_r = '0' then
+ F(Flag_C) <= F_Out(0);
+ end if;
+ end if;
+ end if;
+ if T_Res = '1' and I_INRC = '1' then
+ F(Flag_H) <= '0';
+ F(Flag_N) <= '0';
+ if DI_Reg(7 downto 0) = "00000000" then
+ F(Flag_Z) <= '1';
+ else
+ F(Flag_Z) <= '0';
+ end if;
+ F(Flag_S) <= DI_Reg(7);
+ F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
+ DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
+ end if;
+
+ if TState = 1 and Auto_Wait_t1 = '0' then
+ DO <= BusB;
+ if I_RLD = '1' then
+ DO(3 downto 0) <= BusA(3 downto 0);
+ DO(7 downto 4) <= BusB(3 downto 0);
+ end if;
+ if I_RRD = '1' then
+ DO(3 downto 0) <= BusB(7 downto 4);
+ DO(7 downto 4) <= BusA(3 downto 0);
+ end if;
+ end if;
+
+ if T_Res = '1' then
+ Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
+ Read_To_Reg_r(4) <= Read_To_Reg;
+ if Read_To_Acc = '1' then
+ Read_To_Reg_r(3 downto 0) <= "0111";
+ Read_To_Reg_r(4) <= '1';
+ end if;
+ end if;
+
+ if TState = 1 and I_BT = '1' then
+ F(Flag_X) <= ALU_Q(3);
+ F(Flag_Y) <= ALU_Q(1);
+ F(Flag_H) <= '0';
+ F(Flag_N) <= '0';
+ end if;
+ if I_BC = '1' or I_BT = '1' then
+ F(Flag_P) <= IncDecZ;
+ end if;
+
+ if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
+ (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
+ case Read_To_Reg_r is
+ when "10111" =>
+ ACC <= Save_Mux;
+ when "10110" =>
+ DO <= Save_Mux;
+ when "11000" =>
+ SP(7 downto 0) <= unsigned(Save_Mux);
+ when "11001" =>
+ SP(15 downto 8) <= unsigned(Save_Mux);
+ when "11011" =>
+ F <= Save_Mux;
+ when others =>
+ end case;
+ end if;
+
+ end if;
+
+ end if;
+
+ end process;
+
+---------------------------------------------------------------------------
+--
+-- BC('), DE('), HL('), IX and IY
+--
+---------------------------------------------------------------------------
+ process (CLK_n)
+ begin
+ if CLK_n'event and CLK_n = '1' then
+ if ClkEn = '1' then
+ -- Bus A / Write
+ RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
+ if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
+ RegAddrA_r <= XY_State(1) & "11";
+ end if;
+
+ -- Bus B
+ RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
+ if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
+ RegAddrB_r <= XY_State(1) & "11";
+ end if;
+
+ -- Address from register
+ RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
+ -- Jump (HL), LD SP,HL
+ if (JumpXY = '1' or LDSPHL = '1') then
+ RegAddrC <= Alternate & "10";
+ end if;
+ if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
+ RegAddrC <= XY_State(1) & "11";
+ end if;
+
+ if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
+ IncDecZ <= F_Out(Flag_Z);
+ end if;
+ if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
+ if ID16 = 0 then
+ IncDecZ <= '0';
+ else
+ IncDecZ <= '1';
+ end if;
+ end if;
+
+ RegBusA_r <= RegBusA;
+ end if;
+ end if;
+ end process;
+
+ RegAddrA <=
+ -- 16 bit increment/decrement
+ Alternate & IncDec_16(1 downto 0) when (TState = 2 or
+ (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
+ XY_State(1) & "11" when (TState = 2 or
+ (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
+ -- EX HL,DL
+ Alternate & "10" when ExchangeDH = '1' and TState = 3 else
+ Alternate & "01" when ExchangeDH = '1' and TState = 4 else
+ -- Bus A / Write
+ RegAddrA_r;
+
+ RegAddrB <=
+ -- EX HL,DL
+ Alternate & "01" when ExchangeDH = '1' and TState = 3 else
+ -- Bus B
+ RegAddrB_r;
+
+ ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
+ signed(RegBusA) + 1;
+
+ process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
+ ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
+ begin
+ RegWEH <= '0';
+ RegWEL <= '0';
+ if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
+ (Save_ALU_r = '1' and ALU_OP_r /= "0111") then
+ case Read_To_Reg_r is
+ when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
+ RegWEH <= not Read_To_Reg_r(0);
+ RegWEL <= Read_To_Reg_r(0);
+ when others =>
+ end case;
+ end if;
+
+ if ExchangeDH = '1' and (TState = 3 or TState = 4) then
+ RegWEH <= '1';
+ RegWEL <= '1';
+ end if;
+
+ if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
+ case IncDec_16(1 downto 0) is
+ when "00" | "01" | "10" =>
+ RegWEH <= '1';
+ RegWEL <= '1';
+ when others =>
+ end case;
+ end if;
+ end process;
+
+ process (Save_Mux, RegBusB, RegBusA_r, ID16,
+ ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
+ begin
+ RegDIH <= Save_Mux;
+ RegDIL <= Save_Mux;
+
+ if ExchangeDH = '1' and TState = 3 then
+ RegDIH <= RegBusB(15 downto 8);
+ RegDIL <= RegBusB(7 downto 0);
+ end if;
+ if ExchangeDH = '1' and TState = 4 then
+ RegDIH <= RegBusA_r(15 downto 8);
+ RegDIL <= RegBusA_r(7 downto 0);
+ end if;
+
+ if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
+ RegDIH <= std_logic_vector(ID16(15 downto 8));
+ RegDIL <= std_logic_vector(ID16(7 downto 0));
+ end if;
+ end process;
+
+ Regs : T80_Reg
+ port map(
+ Clk => CLK_n,
+ CEN => ClkEn,
+ WEH => RegWEH,
+ WEL => RegWEL,
+ AddrA => RegAddrA,
+ AddrB => RegAddrB,
+ AddrC => RegAddrC,
+ DIH => RegDIH,
+ DIL => RegDIL,
+ DOAH => RegBusA(15 downto 8),
+ DOAL => RegBusA(7 downto 0),
+ DOBH => RegBusB(15 downto 8),
+ DOBL => RegBusB(7 downto 0),
+ DOCH => RegBusC(15 downto 8),
+ DOCL => RegBusC(7 downto 0));
+
+---------------------------------------------------------------------------
+--
+-- Buses
+--
+---------------------------------------------------------------------------
+ process (CLK_n)
+ begin
+ if CLK_n'event and CLK_n = '1' then
+ if ClkEn = '1' then
+ case Set_BusB_To is
+ when "0111" =>
+ BusB <= ACC;
+ when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
+ if Set_BusB_To(0) = '1' then
+ BusB <= RegBusB(7 downto 0);
+ else
+ BusB <= RegBusB(15 downto 8);
+ end if;
+ when "0110" =>
+ BusB <= DI_Reg;
+ when "1000" =>
+ BusB <= std_logic_vector(SP(7 downto 0));
+ when "1001" =>
+ BusB <= std_logic_vector(SP(15 downto 8));
+ when "1010" =>
+ BusB <= "00000001";
+ when "1011" =>
+ BusB <= F;
+ when "1100" =>
+ BusB <= std_logic_vector(PC(7 downto 0));
+ when "1101" =>
+ BusB <= std_logic_vector(PC(15 downto 8));
+ when "1110" =>
+ BusB <= "00000000";
+ when others =>
+ BusB <= "--------";
+ end case;
+
+ case Set_BusA_To is
+ when "0111" =>
+ BusA <= ACC;
+ when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
+ if Set_BusA_To(0) = '1' then
+ BusA <= RegBusA(7 downto 0);
+ else
+ BusA <= RegBusA(15 downto 8);
+ end if;
+ when "0110" =>
+ BusA <= DI_Reg;
+ when "1000" =>
+ BusA <= std_logic_vector(SP(7 downto 0));
+ when "1001" =>
+ BusA <= std_logic_vector(SP(15 downto 8));
+ when "1010" =>
+ BusA <= "00000000";
+ when others =>
+ BusB <= "--------";
+ end case;
+ end if;
+ end if;
+ end process;
+
+---------------------------------------------------------------------------
+--
+-- Generate external control signals
+--
+---------------------------------------------------------------------------
+ process (RESET_n,CLK_n)
+ begin
+ if RESET_n = '0' then
+ RFSH_n <= '1';
+ elsif CLK_n'event and CLK_n = '1' then
+ if CEN = '1' then
+ if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
+ RFSH_n <= '0';
+ else
+ RFSH_n <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ MC <= std_logic_vector(MCycle);
+ TS <= std_logic_vector(TState);
+ DI_Reg <= DI;
+ HALT_n <= not Halt_FF;
+ BUSAK_n <= not BusAck;
+ IntCycle_n <= not IntCycle;
+ IntE <= IntE_FF1;
+ IORQ <= IORQ_i;
+ Stop <= I_DJNZ;
+
+-------------------------------------------------------------------------
+--
+-- Syncronise inputs
+--
+-------------------------------------------------------------------------
+ process (RESET_n, CLK_n)
+ variable OldNMI_n : std_logic;
+ begin
+ if RESET_n = '0' then
+ BusReq_s <= '0';
+ INT_s <= '0';
+ NMI_s <= '0';
+ OldNMI_n := '0';
+ elsif CLK_n'event and CLK_n = '1' then
+ if CEN = '1' then
+ BusReq_s <= not BUSRQ_n;
+ INT_s <= not INT_n;
+ if NMICycle = '1' then
+ NMI_s <= '0';
+ elsif NMI_n = '0' and OldNMI_n = '1' then
+ NMI_s <= '1';
+ end if;
+ OldNMI_n := NMI_n;
+ end if;
+ end if;
+ end process;
+
+-------------------------------------------------------------------------
+--
+-- Main state machine
+--
+-------------------------------------------------------------------------
+ process (RESET_n, CLK_n)
+ begin
+ if RESET_n = '0' then
+ MCycle <= "001";
+ TState <= "000";
+ Pre_XY_F_M <= "000";
+ Halt_FF <= '0';
+ BusAck <= '0';
+ NMICycle <= '0';
+ IntCycle <= '0';
+ IntE_FF1 <= '0';
+ IntE_FF2 <= '0';
+ No_BTR <= '0';
+ Auto_Wait_t1 <= '0';
+ Auto_Wait_t2 <= '0';
+ M1_n <= '1';
+ elsif CLK_n'event and CLK_n = '1' then
+ if CEN = '1' then
+ if T_Res = '1' then
+ Auto_Wait_t1 <= '0';
+ else
+ Auto_Wait_t1 <= Auto_Wait or IORQ_i;
+ end if;
+ Auto_Wait_t2 <= Auto_Wait_t1;
+ No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
+ (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
+ (I_BTR and (not IR(4) or F(Flag_Z)));
+ if TState = 2 then
+ if SetEI = '1' then
+ IntE_FF1 <= '1';
+ IntE_FF2 <= '1';
+ end if;
+ if I_RETN = '1' then
+ IntE_FF1 <= IntE_FF2;
+ end if;
+ end if;
+ if TState = 3 then
+ if SetDI = '1' then
+ IntE_FF1 <= '0';
+ IntE_FF2 <= '0';
+ end if;
+ end if;
+ if IntCycle = '1' or NMICycle = '1' then
+ Halt_FF <= '0';
+ end if;
+ if MCycle = "001" and TState = 2 and Wait_n = '1' then
+ M1_n <= '1';
+ end if;
+ if BusReq_s = '1' and BusAck = '1' then
+ else
+ BusAck <= '0';
+ if TState = 2 and Wait_n = '0' then
+ elsif T_Res = '1' then
+ if Halt = '1' then
+ Halt_FF <= '1';
+ end if;
+ if BusReq_s = '1' then
+ BusAck <= '1';
+ else
+ TState <= "001";
+ if NextIs_XY_Fetch = '1' then
+ MCycle <= "110";
+ Pre_XY_F_M <= MCycle;
+ if IR = "00110110" and Mode = 0 then
+ Pre_XY_F_M <= "010";
+ end if;
+ elsif (MCycle = "111") or
+ (MCycle = "110" and Mode = 1 and ISet /= "01") then
+ MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
+ elsif (MCycle = MCycles) or
+ No_BTR = '1' or
+ (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
+ M1_n <= '0';
+ MCycle <= "001";
+ IntCycle <= '0';
+ NMICycle <= '0';
+ if NMI_s = '1' and Prefix = "00" then
+ NMICycle <= '1';
+ IntE_FF1 <= '0';
+ elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
+ IntCycle <= '1';
+ IntE_FF1 <= '0';
+ IntE_FF2 <= '0';
+ end if;
+ else
+ MCycle <= std_logic_vector(unsigned(MCycle) + 1);
+ end if;
+ end if;
+ else
+ if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor
+ (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then
+ TState <= TState + 1;
+ end if;
+ end if;
+ end if;
+ if TState = 0 then
+ M1_n <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process (IntCycle, NMICycle, MCycle)
+ begin
+ Auto_Wait <= '0';
+ if IntCycle = '1' or NMICycle = '1' then
+ if MCycle = "001" then
+ Auto_Wait <= '1';
+ end if;
+ end if;
+ end process;
+
+end;
diff --git a/t80/T8080se.vhd b/t80/T8080se.vhd
new file mode 100644
index 0000000..2b6d28f
--- /dev/null
+++ b/t80/T8080se.vhd
@@ -0,0 +1,185 @@
+--
+-- 8080 compatible microprocessor core, synchronous top level with clock enable
+-- Different timing than the original 8080
+-- Inputs needs to be synchronous and outputs may glitch
+--
+-- Version : 0242
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+-- STACK status output not supported
+--
+-- File history :
+--
+-- 0237 : First version
+--
+-- 0238 : Updated for T80 interface change
+--
+-- 0240 : Updated for T80 interface change
+--
+-- 0242 : Updated for T80 interface change
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use work.T80_Pack.all;
+
+entity T8080se is
+ generic(
+ Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK : in std_logic;
+ CLKEN : in std_logic;
+ READY : in std_logic;
+ HOLD : in std_logic;
+ INT : in std_logic;
+ INTE : out std_logic;
+ DBIN : out std_logic;
+ SYNC : out std_logic;
+ VAIT : out std_logic;
+ HLDA : out std_logic;
+ WR_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0)
+ );
+end T8080se;
+
+architecture rtl of T8080se is
+
+ signal IntCycle_n : std_logic;
+ signal NoRead : std_logic;
+ signal Write : std_logic;
+ signal IORQ : std_logic;
+ signal INT_n : std_logic;
+ signal HALT_n : std_logic;
+ signal BUSRQ_n : std_logic;
+ signal BUSAK_n : std_logic;
+ signal DO_i : std_logic_vector(7 downto 0);
+ signal DI_Reg : std_logic_vector(7 downto 0);
+ signal MCycle : std_logic_vector(2 downto 0);
+ signal TState : std_logic_vector(2 downto 0);
+ signal One : std_logic;
+
+begin
+
+ INT_n <= not INT;
+ BUSRQ_n <= HOLD;
+ HLDA <= not BUSAK_n;
+ SYNC <= '1' when TState = "001" else '0';
+ VAIT <= '1' when TState = "010" else '0';
+ One <= '1';
+
+ DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA
+ DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n
+ DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!!
+ DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA
+ DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT
+ DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1
+ DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP
+ DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR
+
+ u0 : T80
+ generic map(
+ Mode => Mode,
+ IOWait => 0)
+ port map(
+ CEN => CLKEN,
+ M1_n => open,
+ IORQ => IORQ,
+ NoRead => NoRead,
+ Write => Write,
+ RFSH_n => open,
+ HALT_n => HALT_n,
+ WAIT_n => READY,
+ INT_n => INT_n,
+ NMI_n => One,
+ RESET_n => RESET_n,
+ BUSRQ_n => One,
+ BUSAK_n => BUSAK_n,
+ CLK_n => CLK,
+ A => A,
+ DInst => DI,
+ DI => DI_Reg,
+ DO => DO_i,
+ MC => MCycle,
+ TS => TState,
+ IntCycle_n => IntCycle_n,
+ IntE => INTE);
+
+ process (RESET_n, CLK)
+ begin
+ if RESET_n = '0' then
+ DBIN <= '0';
+ WR_n <= '1';
+ DI_Reg <= "00000000";
+ elsif CLK'event and CLK = '1' then
+ if CLKEN = '1' then
+ DBIN <= '0';
+ WR_n <= '1';
+ if MCycle = "001" then
+ if TState = "001" or (TState = "010" and READY = '0') then
+ DBIN <= IntCycle_n;
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then
+ DBIN <= '1';
+ end if;
+ if T2Write = 0 then
+ if TState = "010" and Write = '1' then
+ WR_n <= '0';
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then
+ WR_n <= '0';
+ end if;
+ end if;
+ end if;
+ if TState = "010" and READY = '1' then
+ DI_Reg <= DI;
+ end if;
+ end if;
+ end if;
+ end process;
+
+end;
diff --git a/t80/T80_ALU.vhd b/t80/T80_ALU.vhd
new file mode 100644
index 0000000..86fddce
--- /dev/null
+++ b/t80/T80_ALU.vhd
@@ -0,0 +1,351 @@
+--
+-- Z80 compatible microprocessor core
+--
+-- Version : 0247
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
+--
+-- 0238 : Fixed zero flag for 16 bit SBC and ADC
+--
+-- 0240 : Added GB operations
+--
+-- 0242 : Cleanup
+--
+-- 0247 : Cleanup
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity T80_ALU is
+ generic(
+ Mode : integer := 0;
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ Arith16 : in std_logic;
+ Z16 : in std_logic;
+ ALU_Op : in std_logic_vector(3 downto 0);
+ IR : in std_logic_vector(5 downto 0);
+ ISet : in std_logic_vector(1 downto 0);
+ BusA : in std_logic_vector(7 downto 0);
+ BusB : in std_logic_vector(7 downto 0);
+ F_In : in std_logic_vector(7 downto 0);
+ Q : out std_logic_vector(7 downto 0);
+ F_Out : out std_logic_vector(7 downto 0)
+ );
+end T80_ALU;
+
+architecture rtl of T80_ALU is
+
+ procedure AddSub(A : std_logic_vector;
+ B : std_logic_vector;
+ Sub : std_logic;
+ Carry_In : std_logic;
+ signal Res : out std_logic_vector;
+ signal Carry : out std_logic) is
+ variable B_i : unsigned(A'length - 1 downto 0);
+ variable Res_i : unsigned(A'length + 1 downto 0);
+ begin
+ if Sub = '1' then
+ B_i := not unsigned(B);
+ else
+ B_i := unsigned(B);
+ end if;
+ Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
+ Carry <= Res_i(A'length + 1);
+ Res <= std_logic_vector(Res_i(A'length downto 1));
+ end;
+
+ -- AddSub variables (temporary signals)
+ signal UseCarry : std_logic;
+ signal Carry7_v : std_logic;
+ signal Overflow_v : std_logic;
+ signal HalfCarry_v : std_logic;
+ signal Carry_v : std_logic;
+ signal Q_v : std_logic_vector(7 downto 0);
+
+ signal BitMask : std_logic_vector(7 downto 0);
+
+begin
+
+ with IR(5 downto 3) select BitMask <= "00000001" when "000",
+ "00000010" when "001",
+ "00000100" when "010",
+ "00001000" when "011",
+ "00010000" when "100",
+ "00100000" when "101",
+ "01000000" when "110",
+ "10000000" when others;
+
+ UseCarry <= not ALU_Op(2) and ALU_Op(0);
+ 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);
+ AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
+ AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
+ OverFlow_v <= Carry_v xor Carry7_v;
+
+ process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
+ variable Q_t : std_logic_vector(7 downto 0);
+ variable DAA_Q : unsigned(8 downto 0);
+ begin
+ Q_t := "--------";
+ F_Out <= F_In;
+ DAA_Q := "---------";
+ case ALU_Op is
+ when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
+ F_Out(Flag_N) <= '0';
+ F_Out(Flag_C) <= '0';
+ case ALU_OP(2 downto 0) is
+ when "000" | "001" => -- ADD, ADC
+ Q_t := Q_v;
+ F_Out(Flag_C) <= Carry_v;
+ F_Out(Flag_H) <= HalfCarry_v;
+ F_Out(Flag_P) <= OverFlow_v;
+ when "010" | "011" | "111" => -- SUB, SBC, CP
+ Q_t := Q_v;
+ F_Out(Flag_N) <= '1';
+ F_Out(Flag_C) <= not Carry_v;
+ F_Out(Flag_H) <= not HalfCarry_v;
+ F_Out(Flag_P) <= OverFlow_v;
+ when "100" => -- AND
+ Q_t(7 downto 0) := BusA and BusB;
+ F_Out(Flag_H) <= '1';
+ when "101" => -- XOR
+ Q_t(7 downto 0) := BusA xor BusB;
+ F_Out(Flag_H) <= '0';
+ when others => -- OR "110"
+ Q_t(7 downto 0) := BusA or BusB;
+ F_Out(Flag_H) <= '0';
+ end case;
+ if ALU_Op(2 downto 0) = "111" then -- CP
+ F_Out(Flag_X) <= BusB(3);
+ F_Out(Flag_Y) <= BusB(5);
+ else
+ F_Out(Flag_X) <= Q_t(3);
+ F_Out(Flag_Y) <= Q_t(5);
+ end if;
+ if Q_t(7 downto 0) = "00000000" then
+ F_Out(Flag_Z) <= '1';
+ if Z16 = '1' then
+ F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
+ end if;
+ else
+ F_Out(Flag_Z) <= '0';
+ end if;
+ F_Out(Flag_S) <= Q_t(7);
+ case ALU_Op(2 downto 0) is
+ when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
+ when others =>
+ F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
+ Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
+ end case;
+ if Arith16 = '1' then
+ F_Out(Flag_S) <= F_In(Flag_S);
+ F_Out(Flag_Z) <= F_In(Flag_Z);
+ F_Out(Flag_P) <= F_In(Flag_P);
+ end if;
+ when "1100" =>
+ -- DAA
+ F_Out(Flag_H) <= F_In(Flag_H);
+ F_Out(Flag_C) <= F_In(Flag_C);
+ DAA_Q(7 downto 0) := unsigned(BusA);
+ DAA_Q(8) := '0';
+ if F_In(Flag_N) = '0' then
+ -- After addition
+ -- Alow > 9 or H = 1
+ if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
+ if (DAA_Q(3 downto 0) > 9) then
+ F_Out(Flag_H) <= '1';
+ else
+ F_Out(Flag_H) <= '0';
+ end if;
+ DAA_Q := DAA_Q + 6;
+ end if;
+ -- new Ahigh > 9 or C = 1
+ if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
+ DAA_Q := DAA_Q + 96; -- 0x60
+ end if;
+ else
+ -- After subtraction
+ if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
+ if DAA_Q(3 downto 0) > 5 then
+ F_Out(Flag_H) <= '0';
+ end if;
+ DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
+ end if;
+ if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
+ DAA_Q := DAA_Q - 352; -- 0x160
+ end if;
+ end if;
+ F_Out(Flag_X) <= DAA_Q(3);
+ F_Out(Flag_Y) <= DAA_Q(5);
+ F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
+ Q_t := std_logic_vector(DAA_Q(7 downto 0));
+ if DAA_Q(7 downto 0) = "00000000" then
+ F_Out(Flag_Z) <= '1';
+ else
+ F_Out(Flag_Z) <= '0';
+ end if;
+ F_Out(Flag_S) <= DAA_Q(7);
+ F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
+ DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
+ when "1101" | "1110" =>
+ -- RLD, RRD
+ Q_t(7 downto 4) := BusA(7 downto 4);
+ if ALU_Op(0) = '1' then
+ Q_t(3 downto 0) := BusB(7 downto 4);
+ else
+ Q_t(3 downto 0) := BusB(3 downto 0);
+ end if;
+ F_Out(Flag_H) <= '0';
+ F_Out(Flag_N) <= '0';
+ F_Out(Flag_X) <= Q_t(3);
+ F_Out(Flag_Y) <= Q_t(5);
+ if Q_t(7 downto 0) = "00000000" then
+ F_Out(Flag_Z) <= '1';
+ else
+ F_Out(Flag_Z) <= '0';
+ end if;
+ F_Out(Flag_S) <= Q_t(7);
+ F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
+ Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
+ when "1001" =>
+ -- BIT
+ Q_t(7 downto 0) := BusB and BitMask;
+ F_Out(Flag_S) <= Q_t(7);
+ if Q_t(7 downto 0) = "00000000" then
+ F_Out(Flag_Z) <= '1';
+ F_Out(Flag_P) <= '1';
+ else
+ F_Out(Flag_Z) <= '0';
+ F_Out(Flag_P) <= '0';
+ end if;
+ F_Out(Flag_H) <= '1';
+ F_Out(Flag_N) <= '0';
+ F_Out(Flag_X) <= '0';
+ F_Out(Flag_Y) <= '0';
+ if IR(2 downto 0) /= "110" then
+ F_Out(Flag_X) <= BusB(3);
+ F_Out(Flag_Y) <= BusB(5);
+ end if;
+ when "1010" =>
+ -- SET
+ Q_t(7 downto 0) := BusB or BitMask;
+ when "1011" =>
+ -- RES
+ Q_t(7 downto 0) := BusB and not BitMask;
+ when "1000" =>
+ -- ROT
+ case IR(5 downto 3) is
+ when "000" => -- RLC
+ Q_t(7 downto 1) := BusA(6 downto 0);
+ Q_t(0) := BusA(7);
+ F_Out(Flag_C) <= BusA(7);
+ when "010" => -- RL
+ Q_t(7 downto 1) := BusA(6 downto 0);
+ Q_t(0) := F_In(Flag_C);
+ F_Out(Flag_C) <= BusA(7);
+ when "001" => -- RRC
+ Q_t(6 downto 0) := BusA(7 downto 1);
+ Q_t(7) := BusA(0);
+ F_Out(Flag_C) <= BusA(0);
+ when "011" => -- RR
+ Q_t(6 downto 0) := BusA(7 downto 1);
+ Q_t(7) := F_In(Flag_C);
+ F_Out(Flag_C) <= BusA(0);
+ when "100" => -- SLA
+ Q_t(7 downto 1) := BusA(6 downto 0);
+ Q_t(0) := '0';
+ F_Out(Flag_C) <= BusA(7);
+ when "110" => -- SLL (Undocumented) / SWAP
+ if Mode = 3 then
+ Q_t(7 downto 4) := BusA(3 downto 0);
+ Q_t(3 downto 0) := BusA(7 downto 4);
+ F_Out(Flag_C) <= '0';
+ else
+ Q_t(7 downto 1) := BusA(6 downto 0);
+ Q_t(0) := '1';
+ F_Out(Flag_C) <= BusA(7);
+ end if;
+ when "101" => -- SRA
+ Q_t(6 downto 0) := BusA(7 downto 1);
+ Q_t(7) := BusA(7);
+ F_Out(Flag_C) <= BusA(0);
+ when others => -- SRL
+ Q_t(6 downto 0) := BusA(7 downto 1);
+ Q_t(7) := '0';
+ F_Out(Flag_C) <= BusA(0);
+ end case;
+ F_Out(Flag_H) <= '0';
+ F_Out(Flag_N) <= '0';
+ F_Out(Flag_X) <= Q_t(3);
+ F_Out(Flag_Y) <= Q_t(5);
+ F_Out(Flag_S) <= Q_t(7);
+ if Q_t(7 downto 0) = "00000000" then
+ F_Out(Flag_Z) <= '1';
+ else
+ F_Out(Flag_Z) <= '0';
+ end if;
+ F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
+ Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
+ if ISet = "00" then
+ F_Out(Flag_P) <= F_In(Flag_P);
+ F_Out(Flag_S) <= F_In(Flag_S);
+ F_Out(Flag_Z) <= F_In(Flag_Z);
+ end if;
+ when others =>
+ null;
+ end case;
+ Q <= Q_t;
+ end process;
+
+end;
diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd
new file mode 100644
index 0000000..4cc30f3
--- /dev/null
+++ b/t80/T80_MCode.vhd
@@ -0,0 +1,1934 @@
+--
+-- Z80 compatible microprocessor core
+--
+-- Version : 0242
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0208 : First complete release
+--
+-- 0211 : Fixed IM 1
+--
+-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
+--
+-- 0235 : Added IM 2 fix by Mike Johnson
+--
+-- 0238 : Added NoRead signal
+--
+-- 0238b: Fixed instruction timing for POP and DJNZ
+--
+-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
+--
+-- 0242 : Fixed I/O instruction timing, cleanup
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity T80_MCode is
+ generic(
+ Mode : integer := 0;
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ IR : in std_logic_vector(7 downto 0);
+ ISet : in std_logic_vector(1 downto 0);
+ MCycle : in std_logic_vector(2 downto 0);
+ F : in std_logic_vector(7 downto 0);
+ NMICycle : in std_logic;
+ IntCycle : in std_logic;
+ MCycles : out std_logic_vector(2 downto 0);
+ TStates : out std_logic_vector(2 downto 0);
+ Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
+ Inc_PC : out std_logic;
+ Inc_WZ : out std_logic;
+ IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
+ Read_To_Reg : out std_logic;
+ Read_To_Acc : out std_logic;
+ 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
+ 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
+ ALU_Op : out std_logic_vector(3 downto 0);
+ -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
+ Save_ALU : out std_logic;
+ PreserveC : out std_logic;
+ Arith16 : out std_logic;
+ Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
+ IORQ : out std_logic;
+ Jump : out std_logic;
+ JumpE : out std_logic;
+ JumpXY : out std_logic;
+ Call : out std_logic;
+ RstP : out std_logic;
+ LDZ : out std_logic;
+ LDW : out std_logic;
+ LDSPHL : out std_logic;
+ Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
+ ExchangeDH : out std_logic;
+ ExchangeRp : out std_logic;
+ ExchangeAF : out std_logic;
+ ExchangeRS : out std_logic;
+ I_DJNZ : out std_logic;
+ I_CPL : out std_logic;
+ I_CCF : out std_logic;
+ I_SCF : out std_logic;
+ I_RETN : out std_logic;
+ I_BT : out std_logic;
+ I_BC : out std_logic;
+ I_BTR : out std_logic;
+ I_RLD : out std_logic;
+ I_RRD : out std_logic;
+ I_INRC : out std_logic;
+ SetDI : out std_logic;
+ SetEI : out std_logic;
+ IMode : out std_logic_vector(1 downto 0);
+ Halt : out std_logic;
+ NoRead : out std_logic;
+ Write : out std_logic
+ );
+end T80_MCode;
+
+architecture rtl of T80_MCode is
+
+ constant aNone : std_logic_vector(2 downto 0) := "111";
+ constant aBC : std_logic_vector(2 downto 0) := "000";
+ constant aDE : std_logic_vector(2 downto 0) := "001";
+ constant aXY : std_logic_vector(2 downto 0) := "010";
+ constant aIOA : std_logic_vector(2 downto 0) := "100";
+ constant aSP : std_logic_vector(2 downto 0) := "101";
+ constant aZI : std_logic_vector(2 downto 0) := "110";
+-- constant aNone : std_logic_vector(2 downto 0) := "000";
+-- constant aXY : std_logic_vector(2 downto 0) := "001";
+-- constant aIOA : std_logic_vector(2 downto 0) := "010";
+-- constant aSP : std_logic_vector(2 downto 0) := "011";
+-- constant aBC : std_logic_vector(2 downto 0) := "100";
+-- constant aDE : std_logic_vector(2 downto 0) := "101";
+-- constant aZI : std_logic_vector(2 downto 0) := "110";
+
+ function is_cc_true(
+ F : std_logic_vector(7 downto 0);
+ cc : bit_vector(2 downto 0)
+ ) return boolean is
+ begin
+ if Mode = 3 then
+ case cc is
+ when "000" => return F(7) = '0'; -- NZ
+ when "001" => return F(7) = '1'; -- Z
+ when "010" => return F(4) = '0'; -- NC
+ when "011" => return F(4) = '1'; -- C
+ when "100" => return false;
+ when "101" => return false;
+ when "110" => return false;
+ when "111" => return false;
+ end case;
+ else
+ case cc is
+ when "000" => return F(6) = '0'; -- NZ
+ when "001" => return F(6) = '1'; -- Z
+ when "010" => return F(0) = '0'; -- NC
+ when "011" => return F(0) = '1'; -- C
+ when "100" => return F(2) = '0'; -- PO
+ when "101" => return F(2) = '1'; -- PE
+ when "110" => return F(7) = '0'; -- P
+ when "111" => return F(7) = '1'; -- M
+ end case;
+ end if;
+ end;
+
+begin
+
+ process (IR, ISet, MCycle, F, NMICycle, IntCycle)
+ variable DDD : std_logic_vector(2 downto 0);
+ variable SSS : std_logic_vector(2 downto 0);
+ variable DPair : std_logic_vector(1 downto 0);
+ variable IRB : bit_vector(7 downto 0);
+ begin
+ DDD := IR(5 downto 3);
+ SSS := IR(2 downto 0);
+ DPair := IR(5 downto 4);
+ IRB := to_bitvector(IR);
+
+ MCycles <= "001";
+ if MCycle = "001" then
+ TStates <= "100";
+ else
+ TStates <= "011";
+ end if;
+ Prefix <= "00";
+ Inc_PC <= '0';
+ Inc_WZ <= '0';
+ IncDec_16 <= "0000";
+ Read_To_Acc <= '0';
+ Read_To_Reg <= '0';
+ Set_BusB_To <= "0000";
+ Set_BusA_To <= "0000";
+ ALU_Op <= "0" & IR(5 downto 3);
+ Save_ALU <= '0';
+ PreserveC <= '0';
+ Arith16 <= '0';
+ IORQ <= '0';
+ Set_Addr_To <= aNone;
+ Jump <= '0';
+ JumpE <= '0';
+ JumpXY <= '0';
+ Call <= '0';
+ RstP <= '0';
+ LDZ <= '0';
+ LDW <= '0';
+ LDSPHL <= '0';
+ Special_LD <= "000";
+ ExchangeDH <= '0';
+ ExchangeRp <= '0';
+ ExchangeAF <= '0';
+ ExchangeRS <= '0';
+ I_DJNZ <= '0';
+ I_CPL <= '0';
+ I_CCF <= '0';
+ I_SCF <= '0';
+ I_RETN <= '0';
+ I_BT <= '0';
+ I_BC <= '0';
+ I_BTR <= '0';
+ I_RLD <= '0';
+ I_RRD <= '0';
+ I_INRC <= '0';
+ SetDI <= '0';
+ SetEI <= '0';
+ IMode <= "11";
+ Halt <= '0';
+ NoRead <= '0';
+ Write <= '0';
+
+ case ISet is
+ when "00" =>
+
+------------------------------------------------------------------------------
+--
+-- Unprefixed instructions
+--
+------------------------------------------------------------------------------
+
+ case IRB is
+-- 8 BIT LOAD GROUP
+ when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
+ |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
+ |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
+ |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
+ |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
+ |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
+ |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
+ -- LD r,r'
+ Set_BusB_To(2 downto 0) <= SSS;
+ ExchangeRp <= '1';
+ Set_BusA_To(2 downto 0) <= DDD;
+ Read_To_Reg <= '1';
+ when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" =>
+ -- LD r,n
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_BusA_To(2 downto 0) <= DDD;
+ Read_To_Reg <= '1';
+ when others => null;
+ end case;
+ when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" =>
+ -- LD r,(HL)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ Set_BusA_To(2 downto 0) <= DDD;
+ Read_To_Reg <= '1';
+ when others => null;
+ end case;
+ when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" =>
+ -- LD (HL),r
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusB_To(3) <= '0';
+ when 2 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "00110110" =>
+ -- LD (HL),n
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_Addr_To <= aXY;
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusB_To(3) <= '0';
+ when 3 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "00001010" =>
+ -- LD A,(BC)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ when 2 =>
+ Read_To_Acc <= '1';
+ when others => null;
+ end case;
+ when "00011010" =>
+ -- LD A,(DE)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aDE;
+ when 2 =>
+ Read_To_Acc <= '1';
+ when others => null;
+ end case;
+ when "00111010" =>
+ if Mode = 3 then
+ -- LDD A,(HL)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ Read_To_Acc <= '1';
+ IncDec_16 <= "1110";
+ when others => null;
+ end case;
+ else
+ -- LD A,(nn)
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ when 4 =>
+ Read_To_Acc <= '1';
+ when others => null;
+ end case;
+ end if;
+ when "00000010" =>
+ -- LD (BC),A
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ Set_BusB_To <= "0111";
+ when 2 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "00010010" =>
+ -- LD (DE),A
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aDE;
+ Set_BusB_To <= "0111";
+ when 2 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "00110010" =>
+ if Mode = 3 then
+ -- LDD (HL),A
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ Set_BusB_To <= "0111";
+ when 2 =>
+ Write <= '1';
+ IncDec_16 <= "1110";
+ when others => null;
+ end case;
+ else
+ -- LD (nn),A
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ Set_BusB_To <= "0111";
+ when 4 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ end if;
+
+-- 16 BIT LOAD GROUP
+ when "00000001"|"00010001"|"00100001"|"00110001" =>
+ -- LD dd,nn
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Read_To_Reg <= '1';
+ if DPAIR = "11" then
+ Set_BusA_To(3 downto 0) <= "1000";
+ else
+ Set_BusA_To(2 downto 1) <= DPAIR;
+ Set_BusA_To(0) <= '1';
+ end if;
+ when 3 =>
+ Inc_PC <= '1';
+ Read_To_Reg <= '1';
+ if DPAIR = "11" then
+ Set_BusA_To(3 downto 0) <= "1001";
+ else
+ Set_BusA_To(2 downto 1) <= DPAIR;
+ Set_BusA_To(0) <= '0';
+ end if;
+ when others => null;
+ end case;
+ when "00101010" =>
+ if Mode = 3 then
+ -- LDI A,(HL)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ Read_To_Acc <= '1';
+ IncDec_16 <= "0110";
+ when others => null;
+ end case;
+ else
+ -- LD HL,(nn)
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ when 4 =>
+ Set_BusA_To(2 downto 0) <= "101"; -- L
+ Read_To_Reg <= '1';
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ when 5 =>
+ Set_BusA_To(2 downto 0) <= "100"; -- H
+ Read_To_Reg <= '1';
+ when others => null;
+ end case;
+ end if;
+ when "00100010" =>
+ if Mode = 3 then
+ -- LDI (HL),A
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ Set_BusB_To <= "0111";
+ when 2 =>
+ Write <= '1';
+ IncDec_16 <= "0110";
+ when others => null;
+ end case;
+ else
+ -- LD (nn),HL
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ Set_BusB_To <= "0101"; -- L
+ when 4 =>
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ Write <= '1';
+ Set_BusB_To <= "0100"; -- H
+ when 5 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ end if;
+ when "11111001" =>
+ -- LD SP,HL
+ TStates <= "110";
+ LDSPHL <= '1';
+ when "11000101"|"11010101"|"11100101"|"11110101" =>
+ -- PUSH qq
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ IncDec_16 <= "1111";
+ Set_Addr_TO <= aSP;
+ if DPAIR = "11" then
+ Set_BusB_To <= "0111";
+ else
+ Set_BusB_To(2 downto 1) <= DPAIR;
+ Set_BusB_To(0) <= '0';
+ Set_BusB_To(3) <= '0';
+ end if;
+ when 2 =>
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ if DPAIR = "11" then
+ Set_BusB_To <= "1011";
+ else
+ Set_BusB_To(2 downto 1) <= DPAIR;
+ Set_BusB_To(0) <= '1';
+ Set_BusB_To(3) <= '0';
+ end if;
+ Write <= '1';
+ when 3 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "11000001"|"11010001"|"11100001"|"11110001" =>
+ -- POP qq
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aSP;
+ when 2 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ Read_To_Reg <= '1';
+ if DPAIR = "11" then
+ Set_BusA_To(3 downto 0) <= "1011";
+ else
+ Set_BusA_To(2 downto 1) <= DPAIR;
+ Set_BusA_To(0) <= '1';
+ end if;
+ when 3 =>
+ IncDec_16 <= "0111";
+ Read_To_Reg <= '1';
+ if DPAIR = "11" then
+ Set_BusA_To(3 downto 0) <= "0111";
+ else
+ Set_BusA_To(2 downto 1) <= DPAIR;
+ Set_BusA_To(0) <= '0';
+ end if;
+ when others => null;
+ end case;
+
+-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP
+ when "11101011" =>
+ if Mode /= 3 then
+ -- EX DE,HL
+ ExchangeDH <= '1';
+ end if;
+ when "00001000" =>
+ if Mode = 3 then
+ -- LD (nn),SP
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ Set_BusB_To <= "1000";
+ when 4 =>
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ Write <= '1';
+ Set_BusB_To <= "1001";
+ when 5 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ elsif Mode < 2 then
+ -- EX AF,AF'
+ ExchangeAF <= '1';
+ end if;
+ when "11011001" =>
+ if Mode = 3 then
+ -- RETI
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_TO <= aSP;
+ when 2 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ LDZ <= '1';
+ when 3 =>
+ Jump <= '1';
+ IncDec_16 <= "0111";
+ I_RETN <= '1';
+ SetEI <= '1';
+ when others => null;
+ end case;
+ elsif Mode < 2 then
+ -- EXX
+ ExchangeRS <= '1';
+ end if;
+ when "11100011" =>
+ if Mode /= 3 then
+ -- EX (SP),HL
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aSP;
+ when 2 =>
+ Read_To_Reg <= '1';
+ Set_BusA_To <= "0101";
+ Set_BusB_To <= "0101";
+ Set_Addr_To <= aSP;
+ when 3 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ TStates <= "100";
+ Write <= '1';
+ when 4 =>
+ Read_To_Reg <= '1';
+ Set_BusA_To <= "0100";
+ Set_BusB_To <= "0100";
+ Set_Addr_To <= aSP;
+ when 5 =>
+ IncDec_16 <= "1111";
+ TStates <= "101";
+ Write <= '1';
+ when others => null;
+ end case;
+ end if;
+
+-- 8 BIT ARITHMETIC AND LOGICAL GROUP
+ when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
+ |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
+ |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
+ |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
+ |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
+ |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
+ |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
+ |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
+ -- ADD A,r
+ -- ADC A,r
+ -- SUB A,r
+ -- SBC A,r
+ -- AND A,r
+ -- OR A,r
+ -- XOR A,r
+ -- CP A,r
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusA_To(2 downto 0) <= "111";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
+ -- ADD A,(HL)
+ -- ADC A,(HL)
+ -- SUB A,(HL)
+ -- SBC A,(HL)
+ -- AND A,(HL)
+ -- OR A,(HL)
+ -- XOR A,(HL)
+ -- CP A,(HL)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusA_To(2 downto 0) <= "111";
+ when others => null;
+ end case;
+ when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
+ -- ADD A,n
+ -- ADC A,n
+ -- SUB A,n
+ -- SBC A,n
+ -- AND A,n
+ -- OR A,n
+ -- XOR A,n
+ -- CP A,n
+ MCycles <= "010";
+ if MCycle = "010" then
+ Inc_PC <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusA_To(2 downto 0) <= "111";
+ end if;
+ when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" =>
+ -- INC r
+ Set_BusB_To <= "1010";
+ Set_BusA_To(2 downto 0) <= DDD;
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ PreserveC <= '1';
+ ALU_Op <= "0000";
+ when "00110100" =>
+ -- INC (HL)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ TStates <= "100";
+ Set_Addr_To <= aXY;
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ PreserveC <= '1';
+ ALU_Op <= "0000";
+ Set_BusB_To <= "1010";
+ Set_BusA_To(2 downto 0) <= DDD;
+ when 3 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" =>
+ -- DEC r
+ Set_BusB_To <= "1010";
+ Set_BusA_To(2 downto 0) <= DDD;
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ PreserveC <= '1';
+ ALU_Op <= "0010";
+ when "00110101" =>
+ -- DEC (HL)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ TStates <= "100";
+ Set_Addr_To <= aXY;
+ ALU_Op <= "0010";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ PreserveC <= '1';
+ Set_BusB_To <= "1010";
+ Set_BusA_To(2 downto 0) <= DDD;
+ when 3 =>
+ Write <= '1';
+ when others => null;
+ end case;
+
+-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS
+ when "00100111" =>
+ -- DAA
+ Set_BusA_To(2 downto 0) <= "111";
+ Read_To_Reg <= '1';
+ ALU_Op <= "1100";
+ Save_ALU <= '1';
+ when "00101111" =>
+ -- CPL
+ I_CPL <= '1';
+ when "00111111" =>
+ -- CCF
+ I_CCF <= '1';
+ when "00110111" =>
+ -- SCF
+ I_SCF <= '1';
+ when "00000000" =>
+ if NMICycle = '1' then
+ -- NMI
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1101";
+ when 2 =>
+ TStates <= "100";
+ Write <= '1';
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1100";
+ when 3 =>
+ TStates <= "100";
+ Write <= '1';
+ when others => null;
+ end case;
+ elsif IntCycle = '1' then
+ -- INT (IM 2)
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ LDZ <= '1';
+ TStates <= "101";
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1101";
+ when 2 =>
+ TStates <= "100";
+ Write <= '1';
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1100";
+ when 3 =>
+ TStates <= "100";
+ Write <= '1';
+ when 4 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 5 =>
+ Jump <= '1';
+ when others => null;
+ end case;
+ else
+ -- NOP
+ end if;
+ when "01110110" =>
+ -- HALT
+ Halt <= '1';
+ when "11110011" =>
+ -- DI
+ SetDI <= '1';
+ when "11111011" =>
+ -- EI
+ SetEI <= '1';
+
+-- 16 BIT ARITHMETIC GROUP
+ when "00001001"|"00011001"|"00101001"|"00111001" =>
+ -- ADD HL,ss
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ NoRead <= '1';
+ ALU_Op <= "0000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To(2 downto 0) <= "101";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '1';
+ when others =>
+ Set_BusB_To <= "1000";
+ end case;
+ TStates <= "100";
+ Arith16 <= '1';
+ when 3 =>
+ NoRead <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0001";
+ Set_BusA_To(2 downto 0) <= "100";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ when others =>
+ Set_BusB_To <= "1001";
+ end case;
+ Arith16 <= '1';
+ when others =>
+ end case;
+ when "00000011"|"00010011"|"00100011"|"00110011" =>
+ -- INC ss
+ TStates <= "110";
+ IncDec_16(3 downto 2) <= "01";
+ IncDec_16(1 downto 0) <= DPair;
+ when "00001011"|"00011011"|"00101011"|"00111011" =>
+ -- DEC ss
+ TStates <= "110";
+ IncDec_16(3 downto 2) <= "11";
+ IncDec_16(1 downto 0) <= DPair;
+
+-- ROTATE AND SHIFT GROUP
+ when "00000111"
+ -- RLCA
+ |"00010111"
+ -- RLA
+ |"00001111"
+ -- RRCA
+ |"00011111" =>
+ -- RRA
+ Set_BusA_To(2 downto 0) <= "111";
+ ALU_Op <= "1000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+
+-- JUMP GROUP
+ when "11000011" =>
+ -- JP nn
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Inc_PC <= '1';
+ Jump <= '1';
+ when others => null;
+ end case;
+ when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
+ if IR(5) = '1' and Mode = 3 then
+ case IRB(4 downto 3) is
+ when "00" =>
+ -- LD ($FF00+C),A
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ Set_BusB_To <= "0111";
+ when 2 =>
+ Write <= '1';
+ IORQ <= '1';
+ when others =>
+ end case;
+ when "01" =>
+ -- LD (nn),A
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ Set_BusB_To <= "0111";
+ when 4 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "10" =>
+ -- LD A,($FF00+C)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ when 2 =>
+ Read_To_Acc <= '1';
+ IORQ <= '1';
+ when others =>
+ end case;
+ when "11" =>
+ -- LD A,(nn)
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ when 4 =>
+ Read_To_Acc <= '1';
+ when others => null;
+ end case;
+ end case;
+ else
+ -- JP cc,nn
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Inc_PC <= '1';
+ if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
+ Jump <= '1';
+ end if;
+ when others => null;
+ end case;
+ end if;
+ when "00011000" =>
+ if Mode /= 2 then
+ -- JR e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+ when "00111000" =>
+ if Mode /= 2 then
+ -- JR C,e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ if F(Flag_C) = '0' then
+ MCycles <= "010";
+ end if;
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+ when "00110000" =>
+ if Mode /= 2 then
+ -- JR NC,e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ if F(Flag_C) = '1' then
+ MCycles <= "010";
+ end if;
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+ when "00101000" =>
+ if Mode /= 2 then
+ -- JR Z,e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ if F(Flag_Z) = '0' then
+ MCycles <= "010";
+ end if;
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+ when "00100000" =>
+ if Mode /= 2 then
+ -- JR NZ,e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ if F(Flag_Z) = '1' then
+ MCycles <= "010";
+ end if;
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+ when "11101001" =>
+ -- JP (HL)
+ JumpXY <= '1';
+ when "00010000" =>
+ if Mode = 3 then
+ I_DJNZ <= '1';
+ elsif Mode < 2 then
+ -- DJNZ,e
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ I_DJNZ <= '1';
+ Set_BusB_To <= "1010";
+ Set_BusA_To(2 downto 0) <= "000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0010";
+ when 2 =>
+ I_DJNZ <= '1';
+ Inc_PC <= '1';
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+
+-- CALL AND RETURN GROUP
+ when "11001101" =>
+ -- CALL nn
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ IncDec_16 <= "1111";
+ Inc_PC <= '1';
+ TStates <= "100";
+ Set_Addr_To <= aSP;
+ LDW <= '1';
+ Set_BusB_To <= "1101";
+ when 4 =>
+ Write <= '1';
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1100";
+ when 5 =>
+ Write <= '1';
+ Call <= '1';
+ when others => null;
+ end case;
+ when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
+ if IR(5) = '0' or Mode /= 3 then
+ -- CALL cc,nn
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Inc_PC <= '1';
+ LDW <= '1';
+ if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
+ IncDec_16 <= "1111";
+ Set_Addr_TO <= aSP;
+ TStates <= "100";
+ Set_BusB_To <= "1101";
+ else
+ MCycles <= "011";
+ end if;
+ when 4 =>
+ Write <= '1';
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1100";
+ when 5 =>
+ Write <= '1';
+ Call <= '1';
+ when others => null;
+ end case;
+ end if;
+ when "11001001" =>
+ -- RET
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ Set_Addr_TO <= aSP;
+ when 2 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ LDZ <= '1';
+ when 3 =>
+ Jump <= '1';
+ IncDec_16 <= "0111";
+ when others => null;
+ end case;
+ when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
+ if IR(5) = '1' and Mode = 3 then
+ case IRB(4 downto 3) is
+ when "00" =>
+ -- LD ($FF00+nn),A
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_Addr_To <= aIOA;
+ Set_BusB_To <= "0111";
+ when 3 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "01" =>
+ -- ADD SP,n
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ ALU_Op <= "0000";
+ Inc_PC <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To <= "1000";
+ Set_BusB_To <= "0110";
+ when 3 =>
+ NoRead <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0001";
+ Set_BusA_To <= "1001";
+ Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
+ when others =>
+ end case;
+ when "10" =>
+ -- LD A,($FF00+nn)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_Addr_To <= aIOA;
+ when 3 =>
+ Read_To_Acc <= '1';
+ when others => null;
+ end case;
+ when "11" =>
+ -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ when 4 =>
+ Set_BusA_To(2 downto 0) <= "101"; -- L
+ Read_To_Reg <= '1';
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ when 5 =>
+ Set_BusA_To(2 downto 0) <= "100"; -- H
+ Read_To_Reg <= '1';
+ when others => null;
+ end case;
+ end case;
+ else
+ -- RET cc
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
+ Set_Addr_TO <= aSP;
+ else
+ MCycles <= "001";
+ end if;
+ TStates <= "101";
+ when 2 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ LDZ <= '1';
+ when 3 =>
+ Jump <= '1';
+ IncDec_16 <= "0111";
+ when others => null;
+ end case;
+ end if;
+ when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
+ -- RST p
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1101";
+ when 2 =>
+ Write <= '1';
+ IncDec_16 <= "1111";
+ Set_Addr_To <= aSP;
+ Set_BusB_To <= "1100";
+ when 3 =>
+ Write <= '1';
+ RstP <= '1';
+ when others => null;
+ end case;
+
+-- INPUT AND OUTPUT GROUP
+ when "11011011" =>
+ if Mode /= 3 then
+ -- IN A,(n)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_Addr_To <= aIOA;
+ when 3 =>
+ Read_To_Acc <= '1';
+ IORQ <= '1';
+ when others => null;
+ end case;
+ end if;
+ when "11010011" =>
+ if Mode /= 3 then
+ -- OUT (n),A
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ Set_Addr_To <= aIOA;
+ Set_BusB_To <= "0111";
+ when 3 =>
+ Write <= '1';
+ IORQ <= '1';
+ when others => null;
+ end case;
+ end if;
+
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+-- MULTIBYTE INSTRUCTIONS
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+ when "11001011" =>
+ if Mode /= 2 then
+ Prefix <= "01";
+ end if;
+
+ when "11101101" =>
+ if Mode < 2 then
+ Prefix <= "10";
+ end if;
+
+ when "11011101"|"11111101" =>
+ if Mode < 2 then
+ Prefix <= "11";
+ end if;
+
+ end case;
+
+ when "01" =>
+
+------------------------------------------------------------------------------
+--
+-- CB prefixed instructions
+--
+------------------------------------------------------------------------------
+
+ Set_BusA_To(2 downto 0) <= IR(2 downto 0);
+ Set_BusB_To(2 downto 0) <= IR(2 downto 0);
+
+ case IRB is
+ when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111"
+ |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111"
+ |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111"
+ |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111"
+ |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111"
+ |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111"
+ |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111"
+ |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" =>
+ -- RLC r
+ -- RL r
+ -- RRC r
+ -- RR r
+ -- SLA r
+ -- SRA r
+ -- SRL r
+ -- SLL r (Undocumented) / SWAP r
+ if MCycle = "001" then
+ ALU_Op <= "1000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ end if;
+ when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" =>
+ -- RLC (HL)
+ -- RL (HL)
+ -- RRC (HL)
+ -- RR (HL)
+ -- SRA (HL)
+ -- SRL (HL)
+ -- SLA (HL)
+ -- SLL (HL) (Undocumented) / SWAP (HL)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 | 7 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ ALU_Op <= "1000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_Addr_To <= aXY;
+ TStates <= "100";
+ when 3 =>
+ Write <= '1';
+ when others =>
+ end case;
+ when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
+ |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
+ |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
+ |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
+ |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
+ |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
+ |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111"
+ |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
+ -- BIT b,r
+ if MCycle = "001" then
+ Set_BusB_To(2 downto 0) <= IR(2 downto 0);
+ ALU_Op <= "1001";
+ end if;
+ when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" =>
+ -- BIT b,(HL)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 | 7 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ ALU_Op <= "1001";
+ TStates <= "100";
+ when others =>
+ end case;
+ when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111"
+ |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111"
+ |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111"
+ |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111"
+ |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111"
+ |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111"
+ |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111"
+ |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" =>
+ -- SET b,r
+ if MCycle = "001" then
+ ALU_Op <= "1010";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ end if;
+ when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
+ -- SET b,(HL)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 | 7 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ ALU_Op <= "1010";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_Addr_To <= aXY;
+ TStates <= "100";
+ when 3 =>
+ Write <= '1';
+ when others =>
+ end case;
+ when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
+ |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
+ |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
+ |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
+ |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
+ |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
+ |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
+ |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
+ -- RES b,r
+ if MCycle = "001" then
+ ALU_Op <= "1011";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ end if;
+ when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
+ -- RES b,(HL)
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 | 7 =>
+ Set_Addr_To <= aXY;
+ when 2 =>
+ ALU_Op <= "1011";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_Addr_To <= aXY;
+ TStates <= "100";
+ when 3 =>
+ Write <= '1';
+ when others =>
+ end case;
+ end case;
+
+ when others =>
+
+------------------------------------------------------------------------------
+--
+-- ED prefixed instructions
+--
+------------------------------------------------------------------------------
+
+ case IRB is
+ when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111"
+ |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111"
+ |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111"
+ |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111"
+ |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111"
+ |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111"
+ |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111"
+ |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111"
+
+
+ |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111"
+ |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111"
+ |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111"
+ |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111"
+ | "10100100"|"10100101"|"10100110"|"10100111"
+ | "10101100"|"10101101"|"10101110"|"10101111"
+ | "10110100"|"10110101"|"10110110"|"10110111"
+ | "10111100"|"10111101"|"10111110"|"10111111"
+ |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
+ |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
+ |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
+ |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
+ |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
+ |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111"
+ |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111"
+ |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
+ null; -- NOP, undocumented
+ when "01111110"|"01111111" =>
+ -- NOP, undocumented
+ null;
+-- 8 BIT LOAD GROUP
+ when "01010111" =>
+ -- LD A,I
+ Special_LD <= "100";
+ TStates <= "101";
+ when "01011111" =>
+ -- LD A,R
+ Special_LD <= "101";
+ TStates <= "101";
+ when "01000111" =>
+ -- LD I,A
+ Special_LD <= "110";
+ TStates <= "101";
+ when "01001111" =>
+ -- LD R,A
+ Special_LD <= "111";
+ TStates <= "101";
+-- 16 BIT LOAD GROUP
+ when "01001011"|"01011011"|"01101011"|"01111011" =>
+ -- LD dd,(nn)
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ when 4 =>
+ Read_To_Reg <= '1';
+ if IR(5 downto 4) = "11" then
+ Set_BusA_To <= "1000";
+ else
+ Set_BusA_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusA_To(0) <= '1';
+ end if;
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ when 5 =>
+ Read_To_Reg <= '1';
+ if IR(5 downto 4) = "11" then
+ Set_BusA_To <= "1001";
+ else
+ Set_BusA_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusA_To(0) <= '0';
+ end if;
+ when others => null;
+ end case;
+ when "01000011"|"01010011"|"01100011"|"01110011" =>
+ -- LD (nn),dd
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Set_Addr_To <= aZI;
+ Inc_PC <= '1';
+ LDW <= '1';
+ if IR(5 downto 4) = "11" then
+ Set_BusB_To <= "1000";
+ else
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '1';
+ Set_BusB_To(3) <= '0';
+ end if;
+ when 4 =>
+ Inc_WZ <= '1';
+ Set_Addr_To <= aZI;
+ Write <= '1';
+ if IR(5 downto 4) = "11" then
+ Set_BusB_To <= "1001";
+ else
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '0';
+ Set_BusB_To(3) <= '0';
+ end if;
+ when 5 =>
+ Write <= '1';
+ when others => null;
+ end case;
+ when "10100000" | "10101000" | "10110000" | "10111000" =>
+ -- LDI, LDD, LDIR, LDDR
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ IncDec_16 <= "1100"; -- BC
+ when 2 =>
+ Set_BusB_To <= "0110";
+ Set_BusA_To(2 downto 0) <= "111";
+ ALU_Op <= "0000";
+ Set_Addr_To <= aDE;
+ if IR(3) = '0' then
+ IncDec_16 <= "0110"; -- IX
+ else
+ IncDec_16 <= "1110";
+ end if;
+ when 3 =>
+ I_BT <= '1';
+ TStates <= "101";
+ Write <= '1';
+ if IR(3) = '0' then
+ IncDec_16 <= "0101"; -- DE
+ else
+ IncDec_16 <= "1101";
+ end if;
+ when 4 =>
+ NoRead <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ when "10100001" | "10101001" | "10110001" | "10111001" =>
+ -- CPI, CPD, CPIR, CPDR
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aXY;
+ IncDec_16 <= "1100"; -- BC
+ when 2 =>
+ Set_BusB_To <= "0110";
+ Set_BusA_To(2 downto 0) <= "111";
+ ALU_Op <= "0111";
+ Save_ALU <= '1';
+ PreserveC <= '1';
+ if IR(3) = '0' then
+ IncDec_16 <= "0110";
+ else
+ IncDec_16 <= "1110";
+ end if;
+ when 3 =>
+ NoRead <= '1';
+ I_BC <= '1';
+ TStates <= "101";
+ when 4 =>
+ NoRead <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" =>
+ -- NEG
+ Alu_OP <= "0010";
+ Set_BusB_To <= "0111";
+ Set_BusA_To <= "1010";
+ Read_To_Acc <= '1';
+ Save_ALU <= '1';
+ when "01000110"|"01001110"|"01100110"|"01101110" =>
+ -- IM 0
+ IMode <= "00";
+ when "01010110"|"01110110" =>
+ -- IM 1
+ IMode <= "01";
+ when "01011110"|"01110111" =>
+ -- IM 2
+ IMode <= "10";
+-- 16 bit arithmetic
+ when "01001010"|"01011010"|"01101010"|"01111010" =>
+ -- ADC HL,ss
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ NoRead <= '1';
+ ALU_Op <= "0001";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To(2 downto 0) <= "101";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '1';
+ when others =>
+ Set_BusB_To <= "1000";
+ end case;
+ TStates <= "100";
+ when 3 =>
+ NoRead <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0001";
+ Set_BusA_To(2 downto 0) <= "100";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '0';
+ when others =>
+ Set_BusB_To <= "1001";
+ end case;
+ when others =>
+ end case;
+ when "01000010"|"01010010"|"01100010"|"01110010" =>
+ -- SBC HL,ss
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ NoRead <= '1';
+ ALU_Op <= "0011";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To(2 downto 0) <= "101";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ Set_BusB_To(0) <= '1';
+ when others =>
+ Set_BusB_To <= "1000";
+ end case;
+ TStates <= "100";
+ when 3 =>
+ NoRead <= '1';
+ ALU_Op <= "0011";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To(2 downto 0) <= "100";
+ case to_integer(unsigned(IR(5 downto 4))) is
+ when 0|1|2 =>
+ Set_BusB_To(2 downto 1) <= IR(5 downto 4);
+ when others =>
+ Set_BusB_To <= "1001";
+ end case;
+ when others =>
+ end case;
+ when "01101111" =>
+ -- RLD
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ NoRead <= '1';
+ Set_Addr_To <= aXY;
+ when 3 =>
+ Read_To_Reg <= '1';
+ Set_BusB_To(2 downto 0) <= "110";
+ Set_BusA_To(2 downto 0) <= "111";
+ ALU_Op <= "1101";
+ TStates <= "100";
+ Set_Addr_To <= aXY;
+ Save_ALU <= '1';
+ when 4 =>
+ I_RLD <= '1';
+ Write <= '1';
+ when others =>
+ end case;
+ when "01100111" =>
+ -- RRD
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Set_Addr_To <= aXY;
+ when 3 =>
+ Read_To_Reg <= '1';
+ Set_BusB_To(2 downto 0) <= "110";
+ Set_BusA_To(2 downto 0) <= "111";
+ ALU_Op <= "1110";
+ TStates <= "100";
+ Set_Addr_To <= aXY;
+ Save_ALU <= '1';
+ when 4 =>
+ I_RRD <= '1';
+ Write <= '1';
+ when others =>
+ end case;
+ when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" =>
+ -- RETI, RETN
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_TO <= aSP;
+ when 2 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ LDZ <= '1';
+ when 3 =>
+ Jump <= '1';
+ IncDec_16 <= "0111";
+ I_RETN <= '1';
+ when others => null;
+ end case;
+ when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" =>
+ -- IN r,(C)
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ when 2 =>
+ IORQ <= '1';
+ if IR(5 downto 3) /= "110" then
+ Read_To_Reg <= '1';
+ Set_BusA_To(2 downto 0) <= IR(5 downto 3);
+ end if;
+ I_INRC <= '1';
+ when others =>
+ end case;
+ when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" =>
+ -- OUT (C),r
+ -- OUT (C),0
+ MCycles <= "010";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ Set_BusB_To(2 downto 0) <= IR(5 downto 3);
+ if IR(5 downto 3) = "110" then
+ Set_BusB_To(3) <= '1';
+ end if;
+ when 2 =>
+ Write <= '1';
+ IORQ <= '1';
+ when others =>
+ end case;
+ when "10100010" | "10101010" | "10110010" | "10111010" =>
+ -- INI, IND, INIR, INDR
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ Set_Addr_To <= aBC;
+ Set_BusB_To <= "1010";
+ Set_BusA_To <= "0000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0010";
+ when 2 =>
+ IORQ <= '1';
+ Set_BusB_To <= "0110";
+ Set_Addr_To <= aXY;
+ when 3 =>
+ if IR(3) = '0' then
+ IncDec_16 <= "0010";
+ else
+ IncDec_16 <= "1010";
+ end if;
+ TStates <= "100";
+ Write <= '1';
+ I_BTR <= '1';
+ when 4 =>
+ NoRead <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ when "10100011" | "10101011" | "10110011" | "10111011" =>
+ -- OUTI, OUTD, OTIR, OTDR
+ MCycles <= "100";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ TStates <= "101";
+ Set_Addr_To <= aXY;
+ Set_BusB_To <= "1010";
+ Set_BusA_To <= "0000";
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0010";
+ when 2 =>
+ Set_BusB_To <= "0110";
+ Set_Addr_To <= aBC;
+ when 3 =>
+ if IR(3) = '0' then
+ IncDec_16 <= "0010";
+ else
+ IncDec_16 <= "1010";
+ end if;
+ IORQ <= '1';
+ Write <= '1';
+ I_BTR <= '1';
+ when 4 =>
+ NoRead <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end case;
+
+ end case;
+
+ if Mode = 1 then
+ if MCycle = "001" then
+-- TStates <= "100";
+ else
+ TStates <= "011";
+ end if;
+ end if;
+
+ if Mode = 3 then
+ if MCycle = "001" then
+-- TStates <= "100";
+ else
+ TStates <= "100";
+ end if;
+ end if;
+
+ if Mode < 2 then
+ if MCycle = "110" then
+ Inc_PC <= '1';
+ if Mode = 1 then
+ Set_Addr_To <= aXY;
+ TStates <= "100";
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusB_To(3) <= '0';
+ end if;
+ if IRB = "00110110" or IRB = "11001011" then
+ Set_Addr_To <= aNone;
+ end if;
+ end if;
+ if MCycle = "111" then
+ if Mode = 0 then
+ TStates <= "101";
+ end if;
+ if ISet /= "01" then
+ Set_Addr_To <= aXY;
+ end if;
+ Set_BusB_To(2 downto 0) <= SSS;
+ Set_BusB_To(3) <= '0';
+ if IRB = "00110110" or ISet = "01" then
+ -- LD (HL),n
+ Inc_PC <= '1';
+ else
+ NoRead <= '1';
+ end if;
+ end if;
+ end if;
+
+ end process;
+
+end;
diff --git a/t80/T80_Pack.vhd b/t80/T80_Pack.vhd
new file mode 100644
index 0000000..ac7d34d
--- /dev/null
+++ b/t80/T80_Pack.vhd
@@ -0,0 +1,208 @@
+--
+-- Z80 compatible microprocessor core
+--
+-- Version : 0242
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package T80_Pack is
+
+ component T80
+ generic(
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ CEN : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ IORQ : out std_logic;
+ NoRead : out std_logic;
+ Write : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DInst : in std_logic_vector(7 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0);
+ MC : out std_logic_vector(2 downto 0);
+ TS : out std_logic_vector(2 downto 0);
+ IntCycle_n : out std_logic;
+ IntE : out std_logic;
+ Stop : out std_logic
+ );
+ end component;
+
+ component T80_Reg
+ port(
+ Clk : in std_logic;
+ CEN : in std_logic;
+ WEH : in std_logic;
+ WEL : in std_logic;
+ AddrA : in std_logic_vector(2 downto 0);
+ AddrB : in std_logic_vector(2 downto 0);
+ AddrC : in std_logic_vector(2 downto 0);
+ DIH : in std_logic_vector(7 downto 0);
+ DIL : in std_logic_vector(7 downto 0);
+ DOAH : out std_logic_vector(7 downto 0);
+ DOAL : out std_logic_vector(7 downto 0);
+ DOBH : out std_logic_vector(7 downto 0);
+ DOBL : out std_logic_vector(7 downto 0);
+ DOCH : out std_logic_vector(7 downto 0);
+ DOCL : out std_logic_vector(7 downto 0)
+ );
+ end component;
+
+ component T80_MCode
+ generic(
+ Mode : integer := 0;
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ IR : in std_logic_vector(7 downto 0);
+ ISet : in std_logic_vector(1 downto 0);
+ MCycle : in std_logic_vector(2 downto 0);
+ F : in std_logic_vector(7 downto 0);
+ NMICycle : in std_logic;
+ IntCycle : in std_logic;
+ MCycles : out std_logic_vector(2 downto 0);
+ TStates : out std_logic_vector(2 downto 0);
+ Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
+ Inc_PC : out std_logic;
+ Inc_WZ : out std_logic;
+ IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
+ Read_To_Reg : out std_logic;
+ Read_To_Acc : out std_logic;
+ 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
+ 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
+ ALU_Op : out std_logic_vector(3 downto 0);
+ -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
+ Save_ALU : out std_logic;
+ PreserveC : out std_logic;
+ Arith16 : out std_logic;
+ Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
+ IORQ : out std_logic;
+ Jump : out std_logic;
+ JumpE : out std_logic;
+ JumpXY : out std_logic;
+ Call : out std_logic;
+ RstP : out std_logic;
+ LDZ : out std_logic;
+ LDW : out std_logic;
+ LDSPHL : out std_logic;
+ Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
+ ExchangeDH : out std_logic;
+ ExchangeRp : out std_logic;
+ ExchangeAF : out std_logic;
+ ExchangeRS : out std_logic;
+ I_DJNZ : out std_logic;
+ I_CPL : out std_logic;
+ I_CCF : out std_logic;
+ I_SCF : out std_logic;
+ I_RETN : out std_logic;
+ I_BT : out std_logic;
+ I_BC : out std_logic;
+ I_BTR : out std_logic;
+ I_RLD : out std_logic;
+ I_RRD : out std_logic;
+ I_INRC : out std_logic;
+ SetDI : out std_logic;
+ SetEI : out std_logic;
+ IMode : out std_logic_vector(1 downto 0);
+ Halt : out std_logic;
+ NoRead : out std_logic;
+ Write : out std_logic
+ );
+ end component;
+
+ component T80_ALU
+ generic(
+ Mode : integer := 0;
+ Flag_C : integer := 0;
+ Flag_N : integer := 1;
+ Flag_P : integer := 2;
+ Flag_X : integer := 3;
+ Flag_H : integer := 4;
+ Flag_Y : integer := 5;
+ Flag_Z : integer := 6;
+ Flag_S : integer := 7
+ );
+ port(
+ Arith16 : in std_logic;
+ Z16 : in std_logic;
+ ALU_Op : in std_logic_vector(3 downto 0);
+ IR : in std_logic_vector(5 downto 0);
+ ISet : in std_logic_vector(1 downto 0);
+ BusA : in std_logic_vector(7 downto 0);
+ BusB : in std_logic_vector(7 downto 0);
+ F_In : in std_logic_vector(7 downto 0);
+ Q : out std_logic_vector(7 downto 0);
+ F_Out : out std_logic_vector(7 downto 0)
+ );
+ end component;
+
+end;
diff --git a/t80/T80_Reg.vhd b/t80/T80_Reg.vhd
new file mode 100644
index 0000000..828485f
--- /dev/null
+++ b/t80/T80_Reg.vhd
@@ -0,0 +1,105 @@
+--
+-- T80 Registers, technology independent
+--
+-- Version : 0244
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t51/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0242 : Initial release
+--
+-- 0244 : Changed to single register file
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity T80_Reg is
+ port(
+ Clk : in std_logic;
+ CEN : in std_logic;
+ WEH : in std_logic;
+ WEL : in std_logic;
+ AddrA : in std_logic_vector(2 downto 0);
+ AddrB : in std_logic_vector(2 downto 0);
+ AddrC : in std_logic_vector(2 downto 0);
+ DIH : in std_logic_vector(7 downto 0);
+ DIL : in std_logic_vector(7 downto 0);
+ DOAH : out std_logic_vector(7 downto 0);
+ DOAL : out std_logic_vector(7 downto 0);
+ DOBH : out std_logic_vector(7 downto 0);
+ DOBL : out std_logic_vector(7 downto 0);
+ DOCH : out std_logic_vector(7 downto 0);
+ DOCL : out std_logic_vector(7 downto 0)
+ );
+end T80_Reg;
+
+architecture rtl of T80_Reg is
+
+ type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
+ signal RegsH : Register_Image(0 to 7);
+ signal RegsL : Register_Image(0 to 7);
+
+begin
+
+ process (Clk)
+ begin
+ if Clk'event and Clk = '1' then
+ if CEN = '1' then
+ if WEH = '1' then
+ RegsH(to_integer(unsigned(AddrA))) <= DIH;
+ end if;
+ if WEL = '1' then
+ RegsL(to_integer(unsigned(AddrA))) <= DIL;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ DOAH <= RegsH(to_integer(unsigned(AddrA)));
+ DOAL <= RegsL(to_integer(unsigned(AddrA)));
+ DOBH <= RegsH(to_integer(unsigned(AddrB)));
+ DOBL <= RegsL(to_integer(unsigned(AddrB)));
+ DOCH <= RegsH(to_integer(unsigned(AddrC)));
+ DOCL <= RegsL(to_integer(unsigned(AddrC)));
+
+end;
diff --git a/t80/T80_RegX.vhd b/t80/T80_RegX.vhd
new file mode 100644
index 0000000..36b90cb
--- /dev/null
+++ b/t80/T80_RegX.vhd
@@ -0,0 +1,170 @@
+--
+-- T80 Registers for Xilinx Select RAM
+--
+-- Version : 0244
+--
+-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t51/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0242 : Initial release
+--
+-- 0244 : Removed UNISIM library and added componet declaration
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity T80_Reg is
+ port(
+ Clk : in std_logic;
+ CEN : in std_logic;
+ WEH : in std_logic;
+ WEL : in std_logic;
+ AddrA : in std_logic_vector(2 downto 0);
+ AddrB : in std_logic_vector(2 downto 0);
+ AddrC : in std_logic_vector(2 downto 0);
+ DIH : in std_logic_vector(7 downto 0);
+ DIL : in std_logic_vector(7 downto 0);
+ DOAH : out std_logic_vector(7 downto 0);
+ DOAL : out std_logic_vector(7 downto 0);
+ DOBH : out std_logic_vector(7 downto 0);
+ DOBL : out std_logic_vector(7 downto 0);
+ DOCH : out std_logic_vector(7 downto 0);
+ DOCL : out std_logic_vector(7 downto 0)
+ );
+end T80_Reg;
+
+architecture rtl of T80_Reg is
+
+ component RAM16X1D
+ port(
+ DPO : out std_ulogic;
+ SPO : out std_ulogic;
+ A0 : in std_ulogic;
+ A1 : in std_ulogic;
+ A2 : in std_ulogic;
+ A3 : in std_ulogic;
+ D : in std_ulogic;
+ DPRA0 : in std_ulogic;
+ DPRA1 : in std_ulogic;
+ DPRA2 : in std_ulogic;
+ DPRA3 : in std_ulogic;
+ WCLK : in std_ulogic;
+ WE : in std_ulogic);
+ end component;
+
+ signal ENH : std_logic;
+ signal ENL : std_logic;
+
+begin
+
+ ENH <= CEN and WEH;
+ ENL <= CEN and WEL;
+
+ bG1: for I in 0 to 7 generate
+ begin
+ Reg1H : RAM16X1D
+ port map(
+ DPO => DOBH(i),
+ SPO => DOAH(i),
+ A0 => AddrA(0),
+ A1 => AddrA(1),
+ A2 => AddrA(2),
+ A3 => '0',
+ D => DIH(i),
+ DPRA0 => AddrB(0),
+ DPRA1 => AddrB(1),
+ DPRA2 => AddrB(2),
+ DPRA3 => '0',
+ WCLK => Clk,
+ WE => ENH);
+ Reg1L : RAM16X1D
+ port map(
+ DPO => DOBL(i),
+ SPO => DOAL(i),
+ A0 => AddrA(0),
+ A1 => AddrA(1),
+ A2 => AddrA(2),
+ A3 => '0',
+ D => DIL(i),
+ DPRA0 => AddrB(0),
+ DPRA1 => AddrB(1),
+ DPRA2 => AddrB(2),
+ DPRA3 => '0',
+ WCLK => Clk,
+ WE => ENL);
+ Reg2H : RAM16X1D
+ port map(
+ DPO => DOCH(i),
+ SPO => open,
+ A0 => AddrA(0),
+ A1 => AddrA(1),
+ A2 => AddrA(2),
+ A3 => '0',
+ D => DIH(i),
+ DPRA0 => AddrC(0),
+ DPRA1 => AddrC(1),
+ DPRA2 => AddrC(2),
+ DPRA3 => '0',
+ WCLK => Clk,
+ WE => ENH);
+ Reg2L : RAM16X1D
+ port map(
+ DPO => DOCL(i),
+ SPO => open,
+ A0 => AddrA(0),
+ A1 => AddrA(1),
+ A2 => AddrA(2),
+ A3 => '0',
+ D => DIL(i),
+ DPRA0 => AddrC(0),
+ DPRA1 => AddrC(1),
+ DPRA2 => AddrC(2),
+ DPRA3 => '0',
+ WCLK => Clk,
+ WE => ENL);
+ end generate;
+
+end;
diff --git a/t80/T80a.vhd b/t80/T80a.vhd
new file mode 100644
index 0000000..5e18902
--- /dev/null
+++ b/t80/T80a.vhd
@@ -0,0 +1,253 @@
+--
+-- Z80 compatible microprocessor core, asynchronous top level
+--
+-- Version : 0247
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0208 : First complete release
+--
+-- 0211 : Fixed interrupt cycle
+--
+-- 0235 : Updated for T80 interface change
+--
+-- 0238 : Updated for T80 interface change
+--
+-- 0240 : Updated for T80 interface change
+--
+-- 0242 : Updated for T80 interface change
+--
+-- 0247 : Fixed bus req/ack cycle
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use work.T80_Pack.all;
+
+entity T80a is
+ generic(
+ Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ MREQ_n : out std_logic;
+ IORQ_n : out std_logic;
+ RD_n : out std_logic;
+ WR_n : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ D : inout std_logic_vector(7 downto 0)
+ );
+end T80a;
+
+architecture rtl of T80a is
+
+ signal CEN : std_logic;
+ signal Reset_s : std_logic;
+ signal IntCycle_n : std_logic;
+ signal IORQ : std_logic;
+ signal NoRead : std_logic;
+ signal Write : std_logic;
+ signal MREQ : std_logic;
+ signal MReq_Inhibit : std_logic;
+ signal Req_Inhibit : std_logic;
+ signal RD : std_logic;
+ signal MREQ_n_i : std_logic;
+ signal IORQ_n_i : std_logic;
+ signal RD_n_i : std_logic;
+ signal WR_n_i : std_logic;
+ signal RFSH_n_i : std_logic;
+ signal BUSAK_n_i : std_logic;
+ signal A_i : std_logic_vector(15 downto 0);
+ signal DO : std_logic_vector(7 downto 0);
+ signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
+ signal Wait_s : std_logic;
+ signal MCycle : std_logic_vector(2 downto 0);
+ signal TState : std_logic_vector(2 downto 0);
+
+begin
+
+ CEN <= '1';
+
+ BUSAK_n <= BUSAK_n_i;
+ MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
+ RD_n_i <= not RD or Req_Inhibit;
+
+ MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
+ IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
+ RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
+ WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
+ RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
+ A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
+ D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
+
+ process (RESET_n, CLK_n)
+ begin
+ if RESET_n = '0' then
+ Reset_s <= '0';
+ elsif CLK_n'event and CLK_n = '1' then
+ Reset_s <= '1';
+ end if;
+ end process;
+
+ u0 : T80
+ generic map(
+ Mode => Mode,
+ IOWait => 1)
+ port map(
+ CEN => CEN,
+ M1_n => M1_n,
+ IORQ => IORQ,
+ NoRead => NoRead,
+ Write => Write,
+ RFSH_n => RFSH_n_i,
+ HALT_n => HALT_n,
+ WAIT_n => Wait_s,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ RESET_n => Reset_s,
+ BUSRQ_n => BUSRQ_n,
+ BUSAK_n => BUSAK_n_i,
+ CLK_n => CLK_n,
+ A => A_i,
+ DInst => D,
+ DI => DI_Reg,
+ DO => DO,
+ MC => MCycle,
+ TS => TState,
+ IntCycle_n => IntCycle_n);
+
+ process (CLK_n)
+ begin
+ if CLK_n'event and CLK_n = '0' then
+ Wait_s <= WAIT_n;
+ if TState = "011" and BUSAK_n_i = '1' then
+ DI_Reg <= to_x01(D);
+ end if;
+ end if;
+ end process;
+
+ process (Reset_s,CLK_n)
+ begin
+ if Reset_s = '0' then
+ WR_n_i <= '1';
+ elsif CLK_n'event and CLK_n = '1' then
+ WR_n_i <= '1';
+ if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
+ WR_n_i <= not Write;
+ end if;
+ end if;
+ end process;
+
+ process (Reset_s,CLK_n)
+ begin
+ if Reset_s = '0' then
+ Req_Inhibit <= '0';
+ elsif CLK_n'event and CLK_n = '1' then
+ if MCycle = "001" and TState = "010" then
+ Req_Inhibit <= '1';
+ else
+ Req_Inhibit <= '0';
+ end if;
+ end if;
+ end process;
+
+ process (Reset_s,CLK_n)
+ begin
+ if Reset_s = '0' then
+ MReq_Inhibit <= '0';
+ elsif CLK_n'event and CLK_n = '0' then
+ if MCycle = "001" and TState = "010" then
+ MReq_Inhibit <= '1';
+ else
+ MReq_Inhibit <= '0';
+ end if;
+ end if;
+ end process;
+
+ process(Reset_s,CLK_n)
+ begin
+ if Reset_s = '0' then
+ RD <= '0';
+ IORQ_n_i <= '1';
+ MREQ <= '0';
+ elsif CLK_n'event and CLK_n = '0' then
+
+ if MCycle = "001" then
+ if TState = "001" then
+ RD <= IntCycle_n;
+ MREQ <= IntCycle_n;
+ IORQ_n_i <= IntCycle_n;
+ end if;
+ if TState = "011" then
+ RD <= '0';
+ IORQ_n_i <= '1';
+ MREQ <= '1';
+ end if;
+ if TState = "100" then
+ MREQ <= '0';
+ end if;
+ else
+ if TState = "001" and NoRead = '0' then
+ RD <= not Write;
+ IORQ_n_i <= not IORQ;
+ MREQ <= not IORQ;
+ end if;
+ if TState = "011" then
+ RD <= '0';
+ IORQ_n_i <= '1';
+ MREQ <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+end;
diff --git a/t80/T80s.vhd b/t80/T80s.vhd
new file mode 100644
index 0000000..75dc37f
--- /dev/null
+++ b/t80/T80s.vhd
@@ -0,0 +1,227 @@
+--
+-- Z80 compatible microprocessor core, synchronous top level
+-- Different timing than the original z80
+-- Inputs needs to be synchronous and outputs may glitch
+--
+-- Version : 0242
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0208 : First complete release
+--
+-- 0210 : Fixed read with wait
+--
+-- 0211 : Fixed interrupt cycle
+--
+-- 0235 : Updated for T80 interface change
+--
+-- 0236 : Added T2Write generic
+--
+-- 0237 : Fixed T2Write with wait state
+--
+-- 0238 : Updated for T80 interface change
+--
+-- 0240 : Updated for T80 interface change
+--
+-- 0242 : Updated for T80 interface change
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+package T80s_pack is
+ component T80s
+ generic(
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
+ IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ MREQ_n : out std_logic;
+ IORQ_n : out std_logic;
+ RD_n : out std_logic;
+ WR_n : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0)
+ );
+ end component;
+end package T80s_pack;
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use work.T80_Pack.all;
+
+entity T80s is
+ generic(
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
+ IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ MREQ_n : out std_logic;
+ IORQ_n : out std_logic;
+ RD_n : out std_logic;
+ WR_n : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0)
+ );
+end T80s;
+
+architecture rtl of T80s is
+
+ signal CEN : std_logic;
+ signal IntCycle_n : std_logic;
+ signal NoRead : std_logic;
+ signal Write : std_logic;
+ signal IORQ : std_logic;
+ signal DI_Reg : std_logic_vector(7 downto 0);
+ signal MCycle : std_logic_vector(2 downto 0);
+ signal TState : std_logic_vector(2 downto 0);
+
+begin
+
+ CEN <= '1';
+
+ u0 : T80
+ generic map(
+ Mode => Mode,
+ IOWait => IOWait)
+ port map(
+ CEN => CEN,
+ M1_n => M1_n,
+ IORQ => IORQ,
+ NoRead => NoRead,
+ Write => Write,
+ RFSH_n => RFSH_n,
+ HALT_n => HALT_n,
+ WAIT_n => Wait_n,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ RESET_n => RESET_n,
+ BUSRQ_n => BUSRQ_n,
+ BUSAK_n => BUSAK_n,
+ CLK_n => CLK_n,
+ A => A,
+ DInst => DI,
+ DI => DI_Reg,
+ DO => DO,
+ MC => MCycle,
+ TS => TState,
+ IntCycle_n => IntCycle_n,
+ IntE => open,
+ Stop => open);
+
+ process (RESET_n, CLK_n)
+ begin
+ if RESET_n = '0' then
+ RD_n <= '1';
+ WR_n <= '1';
+ IORQ_n <= '1';
+ MREQ_n <= '1';
+ DI_Reg <= "00000000";
+ elsif CLK_n'event and CLK_n = '1' then
+ if WAIT_n = '1' then
+ RD_n <= '1';
+ WR_n <= '1';
+ IORQ_n <= '1';
+ MREQ_n <= '1';
+ if MCycle = "001" then
+ if TState = "001" or (TState = "010" and Wait_n = '0') then
+ RD_n <= not IntCycle_n;
+ MREQ_n <= not IntCycle_n;
+ IORQ_n <= IntCycle_n;
+ end if;
+ if TState = "011" then
+ MREQ_n <= '0';
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
+ RD_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ if T2Write = 0 then
+ if TState = "010" and Write = '1' then
+ WR_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
+ WR_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ end if;
+ end if;
+ if TState = "010" and Wait_n = '1' then
+ DI_Reg <= DI;
+ end if;
+ end if;
+ end if;
+ end process;
+
+end;
diff --git a/t80/T80se.vhd b/t80/T80se.vhd
new file mode 100644
index 0000000..ac8886a
--- /dev/null
+++ b/t80/T80se.vhd
@@ -0,0 +1,184 @@
+--
+-- Z80 compatible microprocessor core, synchronous top level with clock enable
+-- Different timing than the original z80
+-- Inputs needs to be synchronous and outputs may glitch
+--
+-- Version : 0242
+--
+-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- Please report bugs to the author, but before you do so, please
+-- make sure that this is not a derivative work and that
+-- you have the latest version of this file.
+--
+-- The latest version of this file can be found at:
+-- http://www.opencores.org/cvsweb.shtml/t80/
+--
+-- Limitations :
+--
+-- File history :
+--
+-- 0235 : First release
+--
+-- 0236 : Added T2Write generic
+--
+-- 0237 : Fixed T2Write with wait state
+--
+-- 0238 : Updated for T80 interface change
+--
+-- 0240 : Updated for T80 interface change
+--
+-- 0242 : Updated for T80 interface change
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use work.T80_Pack.all;
+
+entity T80se is
+ generic(
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
+ IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
+ );
+ port(
+ RESET_n : in std_logic;
+ CLK_n : in std_logic;
+ CLKEN : in std_logic;
+ WAIT_n : in std_logic;
+ INT_n : in std_logic;
+ NMI_n : in std_logic;
+ BUSRQ_n : in std_logic;
+ M1_n : out std_logic;
+ MREQ_n : out std_logic;
+ IORQ_n : out std_logic;
+ RD_n : out std_logic;
+ WR_n : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ A : out std_logic_vector(15 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0)
+ );
+end T80se;
+
+architecture rtl of T80se is
+
+ signal IntCycle_n : std_logic;
+ signal NoRead : std_logic;
+ signal Write : std_logic;
+ signal IORQ : std_logic;
+ signal DI_Reg : std_logic_vector(7 downto 0);
+ signal MCycle : std_logic_vector(2 downto 0);
+ signal TState : std_logic_vector(2 downto 0);
+
+begin
+
+ u0 : T80
+ generic map(
+ Mode => Mode,
+ IOWait => IOWait)
+ port map(
+ CEN => CLKEN,
+ M1_n => M1_n,
+ IORQ => IORQ,
+ NoRead => NoRead,
+ Write => Write,
+ RFSH_n => RFSH_n,
+ HALT_n => HALT_n,
+ WAIT_n => Wait_n,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ RESET_n => RESET_n,
+ BUSRQ_n => BUSRQ_n,
+ BUSAK_n => BUSAK_n,
+ CLK_n => CLK_n,
+ A => A,
+ DInst => DI,
+ DI => DI_Reg,
+ DO => DO,
+ MC => MCycle,
+ TS => TState,
+ IntCycle_n => IntCycle_n);
+
+ process (RESET_n, CLK_n)
+ begin
+ if RESET_n = '0' then
+ RD_n <= '1';
+ WR_n <= '1';
+ IORQ_n <= '1';
+ MREQ_n <= '1';
+ DI_Reg <= "00000000";
+ elsif CLK_n'event and CLK_n = '1' then
+ if CLKEN = '1' then
+ RD_n <= '1';
+ WR_n <= '1';
+ IORQ_n <= '1';
+ MREQ_n <= '1';
+ if MCycle = "001" then
+ if TState = "001" or (TState = "010" and Wait_n = '0') then
+ RD_n <= not IntCycle_n;
+ MREQ_n <= not IntCycle_n;
+ IORQ_n <= IntCycle_n;
+ end if;
+ if TState = "011" then
+ MREQ_n <= '0';
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
+ RD_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ if T2Write = 0 then
+ if TState = "010" and Write = '1' then
+ WR_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ else
+ if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
+ WR_n <= '0';
+ IORQ_n <= not IORQ;
+ MREQ_n <= IORQ;
+ end if;
+ end if;
+ end if;
+ if TState = "010" and Wait_n = '1' then
+ DI_Reg <= DI;
+ end if;
+ end if;
+ end if;
+ end process;
+
+end;