OpenCores
URL https://opencores.org/ocsvn/tv80/tv80/trunk

Subversion Repositories tv80

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 46 to Rev 47
    Reverse comparison

Rev 46 → Rev 47

/branches/restruc2/scripts/run2
0,0 → 1,57
#!/usr/bin/env python
# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
import sys, os, getopt
 
def print_help ():
print "Usage: run [-dh] <testname>"
print " -d : instruction decode"
print " -h : option help (this list)"
sys.exit(0)
 
# parse command line options
# d : instruction trace
# h : help
(options, args) = getopt.getopt (sys.argv[1:], "dh")
if len(args) == 0:
print_help()
testname = args[0]
simulator = "cver"
 
filelist = " -f env/tb.vf"
testdef = " +incdir+env -l logs/%s.log +define+DUMPFILE_NAME=\\\"logs/%s.dump\\\" +define+ROM_FILE=\\\"tests/%s.vmem\\\" +define+RAM_FILE=\\\"tests/%s.vmem\\\"" % (testname, testname, testname+"_rom", testname+"_ram")
 
for option in options:
if option[0] == "-d":
print "Adding TV80_INSTRUCTION_DECODE"
testdef += " +define+TV80_INSTRUCTION_DECODE=1"
if option[0] == "-h":
print_help()
 
os.chdir ("tests")
os.system ("make %s.vmem" % testname)
os.chdir ("..")
 
command = simulator + filelist + testdef
 
print "command:",command
os.system (command)
 
branches/restruc2/scripts/run2 Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/restruc2/scripts/run =================================================================== --- branches/restruc2/scripts/run (nonexistent) +++ branches/restruc2/scripts/run (revision 47) @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import sys, os, getopt + +def print_help (): + print "Usage: run [-th] [-d ###] " + print " -t : instruction decode (trace)" + print " -d : enable dumping start at time ###" + print " -h : option help (this list)" + sys.exit(0) + +# parse command line options +# t : instruction trace +# d : dump starting at +# h : help +(options, args) = getopt.getopt (sys.argv[1:], "thd:") +if len(args) == 0: + print_help() +testname = args[0] +simulator = "cver" + +filelist = " -f env/tb.vf" +testdef = " +incdir+env -l logs/%s.log +define+DUMPFILE_NAME=\\\"logs/%s.dump\\\" +define+PROGRAM_FILE=\\\"tests/%s.vmem\\\"" % (testname, testname, testname) + +for option in options: + if option[0] == "-t": + print "Adding TV80_INSTRUCTION_DECODE" + testdef += " +define+TV80_INSTRUCTION_DECODE=1" + elif option[0] == "-d": + testdef += " +define+DUMP_START=%s" % option[1] + elif option[0] == "-h": + print_help() + else: + print_help() + +os.chdir ("tests") +os.system ("make %s.vmem" % testname) +os.chdir ("..") + +command = simulator + filelist + testdef + +print "command:",command +os.system (command) +
branches/restruc2/scripts/run Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/restruc2/scripts/s80_convert.py =================================================================== --- branches/restruc2/scripts/s80_convert.py (nonexistent) +++ branches/restruc2/scripts/s80_convert.py (revision 47) @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import mem_image +import sys + +ram_start = 0x8000 +ram_end = 0xffff +rom_start = 0x0000 +rom_end = 0x7fff +src_file = "tests/tvs80.ihx" +rom_file = "tests/tvs80_rom.vmem" +ram_file = "tests/tvs80_ram.vmem" + +conv = mem_image.mem_image() +conv.load_ihex (src_file) +conv.save_vmem (rom_file, rom_start, rom_end) +conv.save_vmem (ram_file, ram_start, ram_end)
branches/restruc2/scripts/s80_convert.py Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/restruc2/scripts/ihex2mem.py =================================================================== --- branches/restruc2/scripts/ihex2mem.py (nonexistent) +++ branches/restruc2/scripts/ihex2mem.py (revision 47) @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# +# Intel Hex to Verilog Memory format converter +# +# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +class mem_image: + def __init__ (self): + self.min = 100000 + self.max = -1 + self.map = {} + self.bcount = 0 + + def load_ihex (self, infile): + ifh = open (infile, 'r') + + line = ifh.readline() + while (line != ''): + if (line[0] == ':'): + rlen = int(line[1:3], 16) + addr = int(line[3:7], 16) + rtyp = int(line[7:9], 16) + ptr = 9 + for i in range (0, rlen): + laddr = addr + i + val = int(line[9+i*2:9+i*2+2], 16) + self.map[laddr] = val + self.bcount += 1 + if (laddr > self.max): self.max = laddr + if (laddr < self.min): self.min = laddr + + line = ifh.readline() + + ifh.close() + + def save_vmem (self, outfile, start=-1, stop=-1): + if (start == -1): start = self.min + if (stop == -1): stop = self.max + + ofh = open (outfile, 'w') + for addr in range(start, stop+1): + if self.map.has_key (addr): + ofh.write ("@%02x %02x\n" % (addr, self.map[addr])) + ofh.close() + +def ihex2mem (infile, outfile): + ifh = open (infile, 'r') + ofh = open (outfile, 'w') + + bcount = 0 + line = ifh.readline() + while (line != ''): + if (line[0] == ':'): + rlen = int(line[1:3], 16) + addr = int(line[3:7], 16) + rtyp = int(line[7:9], 16) + ptr = 9 + for i in range (0, rlen): + val = int(line[9+i*2:9+i*2+2], 16) + ofh.write ("@%02x %02x\n" % (addr+i, val)) + bcount += 1 + + line = ifh.readline() + + ifh.close() + ofh.close() + + return bcount + +def cmdline (): + import sys + + infile = sys.argv[1] + outfile = sys.argv[2] + + #bc = ihex2mem (infile, outfile) + conv = mem_image() + conv.load_ihex(infile) + conv.save_vmem(outfile) + print "Converted %d bytes from %s to %s" % (conv.bcount, infile, outfile) + +if __name__ == '__main__': + cmdline() +
branches/restruc2/scripts/ihex2mem.py Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: branches/restruc2/scripts/mem_image.py =================================================================== --- branches/restruc2/scripts/mem_image.py (nonexistent) +++ branches/restruc2/scripts/mem_image.py (revision 47) @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +class mem_image: + def __init__ (self): + self.min = 100000 + self.max = -1 + self.map = {} + self.bcount = 0 + + def load_ihex (self, infile): + ifh = open (infile, 'r') + + line = ifh.readline() + while (line != ''): + if (line[0] == ':'): + rlen = int(line[1:3], 16) + addr = int(line[3:7], 16) + rtyp = int(line[7:9], 16) + ptr = 9 + for i in range (0, rlen): + laddr = addr + i + val = int(line[9+i*2:9+i*2+2], 16) + self.map[laddr] = val + self.bcount += 1 + if (laddr > self.max): self.max = laddr + if (laddr < self.min): self.min = laddr + + line = ifh.readline() + + ifh.close() + + def save_vmem (self, outfile, start=-1, stop=-1): + if (start == -1): start = self.min + if (stop == -1): stop = self.max + + ofh = open (outfile, 'w') + for addr in range(start, stop+1): + if self.map.has_key (addr): + ofh.write ("@%02x %02x\n" % (addr-start, self.map[addr])) + ofh.close() + Index: branches/restruc2/rtl/core/tv80n.v =================================================================== --- branches/restruc2/rtl/core/tv80n.v (nonexistent) +++ branches/restruc2/rtl/core/tv80n.v (revision 47) @@ -0,0 +1,182 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Negative-edge based wrapper allows memory wait_n signal to work +// correctly without resorting to asynchronous logic. + +module tv80n (/*AUTOARG*/ + // Outputs + m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do, + // Inputs + reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di + ); + + parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2 + parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle + + + input reset_n; + input clk; + input wait_n; + input int_n; + input nmi_n; + input busrq_n; + output m1_n; + output mreq_n; + output iorq_n; + output rd_n; + output wr_n; + output rfsh_n; + output halt_n; + output busak_n; + output [15:0] A; + input [7:0] di; + output [7:0] do; + + reg mreq_n; + reg iorq_n; + reg rd_n; + reg wr_n; + reg nxt_mreq_n; + reg nxt_iorq_n; + reg nxt_rd_n; + reg nxt_wr_n; + + wire cen; + wire intcycle_n; + wire no_read; + wire write; + wire iorq; + reg [7:0] di_reg; + wire [6:0] mcycle; + wire [6:0] tstate; + + assign cen = 1; + + tv80_core #(Mode, IOWait) i_tv80_core + ( + .cen (cen), + .m1_n (m1_n), + .iorq (iorq), + .no_read (no_read), + .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 (clk), + .IntE (), + .stop (), + .A (A), + .dinst (di), + .di (di_reg), + .do (do), + .mc (mcycle), + .ts (tstate), + .intcycle_n (intcycle_n) + ); + + always @* + begin + nxt_mreq_n = 1; + nxt_rd_n = 1; + nxt_iorq_n = 1; + nxt_wr_n = 1; + + if (mcycle[0]) + begin + if (tstate[1] || tstate[2]) + begin + nxt_rd_n = ~ intcycle_n; + nxt_mreq_n = ~ intcycle_n; + nxt_iorq_n = intcycle_n; + end + end // if (mcycle[0]) + else + begin + if ((tstate[1] || tstate[2]) && !no_read && !write) + begin + nxt_rd_n = 1'b0; + nxt_iorq_n = ~ iorq; + nxt_mreq_n = iorq; + end + if (T2Write == 0) + begin + if (tstate[2] && write) + begin + nxt_wr_n = 1'b0; + nxt_iorq_n = ~ iorq; + nxt_mreq_n = iorq; + end + end + else + begin + if ((tstate[1] || (tstate[2] && !wait_n)) && write) + begin + nxt_wr_n = 1'b0; + nxt_iorq_n = ~ iorq; + nxt_mreq_n = iorq; + end + end // else: !if(T2write == 0) + end // else: !if(mcycle[0]) + end // always @ * + + always @(negedge clk) + begin + if (!reset_n) + begin + rd_n <= #1 1'b1; + wr_n <= #1 1'b1; + iorq_n <= #1 1'b1; + mreq_n <= #1 1'b1; + end + else + begin + rd_n <= #1 nxt_rd_n; + wr_n <= #1 nxt_wr_n; + iorq_n <= #1 nxt_iorq_n; + mreq_n <= #1 nxt_mreq_n; + end // else: !if(!reset_n) + end // always @ (posedge clk or negedge reset_n) + + always @(posedge clk) + begin + if (!reset_n) + begin + di_reg <= #1 0; + end + else + begin + if (tstate[2] && wait_n == 1'b1) + di_reg <= #1 di; + end // else: !if(!reset_n) + end // always @ (posedge clk) + +endmodule // t80n + Index: branches/restruc2/rtl/core/tv80_mcode.v =================================================================== --- branches/restruc2/rtl/core/tv80_mcode.v (nonexistent) +++ branches/restruc2/rtl/core/tv80_mcode.v (revision 47) @@ -0,0 +1,2727 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module tv80_mcode + (/*AUTOARG*/ + // Outputs + MCycles, TStates, Prefix, Inc_PC, Inc_WZ, IncDec_16, Read_To_Reg, + Read_To_Acc, Set_BusA_To, Set_BusB_To, ALU_Op, Save_ALU, PreserveC, + Arith16, Set_Addr_To, IORQ, Jump, JumpE, JumpXY, Call, RstP, LDZ, + LDW, LDSPHL, Special_LD, ExchangeDH, ExchangeRp, ExchangeAF, + ExchangeRS, I_DJNZ, I_CPL, I_CCF, I_SCF, I_RETN, I_BT, I_BC, I_BTR, + I_RLD, I_RRD, I_INRC, SetDI, SetEI, IMode, Halt, NoRead, Write, + // Inputs + IR, ISet, MCycle, F, NMICycle, IntCycle + ); + + parameter Mode = 0; + parameter Flag_C = 0; + parameter Flag_N = 1; + parameter Flag_P = 2; + parameter Flag_X = 3; + parameter Flag_H = 4; + parameter Flag_Y = 5; + parameter Flag_Z = 6; + parameter Flag_S = 7; + + input [7:0] IR; + input [1:0] ISet ; + input [6:0] MCycle ; + input [7:0] F ; + input NMICycle ; + input IntCycle ; + output [2:0] MCycles ; + output [2:0] TStates ; + output [1:0] Prefix ; // None,BC,ED,DD/FD + output Inc_PC ; + output Inc_WZ ; + output [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc + output Read_To_Reg ; + output Read_To_Acc ; + output [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + output [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + output [3:0] ALU_Op ; + output Save_ALU ; + output PreserveC ; + output Arith16 ; + output [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI + output IORQ ; + output Jump ; + output JumpE ; + output JumpXY ; + output Call ; + output RstP ; + output LDZ ; + output LDW ; + output LDSPHL ; + output [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None + output ExchangeDH ; + output ExchangeRp ; + output ExchangeAF ; + output ExchangeRS ; + output I_DJNZ ; + output I_CPL ; + output I_CCF ; + output I_SCF ; + output I_RETN ; + output I_BT ; + output I_BC ; + output I_BTR ; + output I_RLD ; + output I_RRD ; + output I_INRC ; + output SetDI ; + output SetEI ; + output [1:0] IMode ; + output Halt ; + output NoRead ; + output Write ; + + // regs + reg [2:0] MCycles ; + reg [2:0] TStates ; + reg [1:0] Prefix ; // None,BC,ED,DD/FD + reg Inc_PC ; + reg Inc_WZ ; + reg [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc + reg Read_To_Reg ; + reg Read_To_Acc ; + reg [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + reg [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + reg [3:0] ALU_Op ; + reg Save_ALU ; + reg PreserveC ; + reg Arith16 ; + reg [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI + reg IORQ ; + reg Jump ; + reg JumpE ; + reg JumpXY ; + reg Call ; + reg RstP ; + reg LDZ ; + reg LDW ; + reg LDSPHL ; + reg [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None + reg ExchangeDH ; + reg ExchangeRp ; + reg ExchangeAF ; + reg ExchangeRS ; + reg I_DJNZ ; + reg I_CPL ; + reg I_CCF ; + reg I_SCF ; + reg I_RETN ; + reg I_BT ; + reg I_BC ; + reg I_BTR ; + reg I_RLD ; + reg I_RRD ; + reg I_INRC ; + reg SetDI ; + reg SetEI ; + reg [1:0] IMode ; + reg Halt ; + reg NoRead ; + reg Write ; + + parameter aNone = 3'b111; + parameter aBC = 3'b000; + parameter aDE = 3'b001; + parameter aXY = 3'b010; + parameter aIOA = 3'b100; + parameter aSP = 3'b101; + parameter aZI = 3'b110; + // constant aNone : std_logic_vector[2:0] = 3'b000; + // constant aXY : std_logic_vector[2:0] = 3'b001; + // constant aIOA : std_logic_vector[2:0] = 3'b010; + // constant aSP : std_logic_vector[2:0] = 3'b011; + // constant aBC : std_logic_vector[2:0] = 3'b100; + // constant aDE : std_logic_vector[2:0] = 3'b101; + // constant aZI : std_logic_vector[2:0] = 3'b110; + + function is_cc_true; + input [7:0] F; + input [2:0] cc; + begin + if (Mode == 3 ) + begin + case (cc) + 3'b000 : is_cc_true = F[7] == 1'b0; // NZ + 3'b001 : is_cc_true = F[7] == 1'b1; // Z + 3'b010 : is_cc_true = F[4] == 1'b0; // NC + 3'b011 : is_cc_true = F[4] == 1'b1; // C + 3'b100 : is_cc_true = 0; + 3'b101 : is_cc_true = 0; + 3'b110 : is_cc_true = 0; + 3'b111 : is_cc_true = 0; + endcase + end + else + begin + case (cc) + 3'b000 : is_cc_true = F[6] == 1'b0; // NZ + 3'b001 : is_cc_true = F[6] == 1'b1; // Z + 3'b010 : is_cc_true = F[0] == 1'b0; // NC + 3'b011 : is_cc_true = F[0] == 1'b1; // C + 3'b100 : is_cc_true = F[2] == 1'b0; // PO + 3'b101 : is_cc_true = F[2] == 1'b1; // PE + 3'b110 : is_cc_true = F[7] == 1'b0; // P + 3'b111 : is_cc_true = F[7] == 1'b1; // M + endcase + end + end + endfunction // is_cc_true + + + reg [2:0] DDD; + reg [2:0] SSS; + reg [1:0] DPAIR; + reg [7:0] IRB; + + always @ (/*AUTOSENSE*/F or IR or ISet or IntCycle or MCycle + or NMICycle) + begin + DDD = IR[5:3]; + SSS = IR[2:0]; + DPAIR = IR[5:4]; + IRB = IR; + + MCycles = 3'b001; + if (MCycle[0] ) + begin + TStates = 3'b100; + end + else + begin + TStates = 3'b011; + end + Prefix = 2'b00; + Inc_PC = 1'b0; + Inc_WZ = 1'b0; + IncDec_16 = 4'b0000; + Read_To_Acc = 1'b0; + Read_To_Reg = 1'b0; + Set_BusB_To = 4'b0000; + Set_BusA_To = 4'b0000; + ALU_Op = { 1'b0, IR[5:3] }; + Save_ALU = 1'b0; + PreserveC = 1'b0; + Arith16 = 1'b0; + IORQ = 1'b0; + Set_Addr_To = aNone; + Jump = 1'b0; + JumpE = 1'b0; + JumpXY = 1'b0; + Call = 1'b0; + RstP = 1'b0; + LDZ = 1'b0; + LDW = 1'b0; + LDSPHL = 1'b0; + Special_LD = 3'b000; + ExchangeDH = 1'b0; + ExchangeRp = 1'b0; + ExchangeAF = 1'b0; + ExchangeRS = 1'b0; + I_DJNZ = 1'b0; + I_CPL = 1'b0; + I_CCF = 1'b0; + I_SCF = 1'b0; + I_RETN = 1'b0; + I_BT = 1'b0; + I_BC = 1'b0; + I_BTR = 1'b0; + I_RLD = 1'b0; + I_RRD = 1'b0; + I_INRC = 1'b0; + SetDI = 1'b0; + SetEI = 1'b0; + IMode = 2'b11; + Halt = 1'b0; + NoRead = 1'b0; + Write = 1'b0; + + case (ISet) + 2'b00 : + begin + + //---------------------------------------------------------------------------- + // + // Unprefixed instructions + // + //---------------------------------------------------------------------------- + + casex (IRB) + // 8 BIT LOAD GROUP + 8'b01xxxxxx : + begin + if (IRB[5:0] == 6'b110110) + Halt = 1'b1; + else if (IRB[2:0] == 3'b110) + begin + // LD r,(HL) + MCycles = 3'b010; + if (MCycle[0]) + Set_Addr_To = aXY; + if (MCycle[1]) + begin + Set_BusA_To[2:0] = DDD; + Read_To_Reg = 1'b1; + end + end // if (IRB[2:0] == 3'b110) + else if (IRB[5:3] == 3'b110) + begin + // LD (HL),r + MCycles = 3'b010; + if (MCycle[0]) + begin + Set_Addr_To = aXY; + Set_BusB_To[2:0] = SSS; + Set_BusB_To[3] = 1'b0; + end + if (MCycle[1]) + Write = 1'b1; + end // if (IRB[5:3] == 3'b110) + else + begin + Set_BusB_To[2:0] = SSS; + ExchangeRp = 1'b1; + Set_BusA_To[2:0] = DDD; + Read_To_Reg = 1'b1; + end // else: !if(IRB[5:3] == 3'b110) + end // case: 8'b01xxxxxx + + 8'b00xxx110 : + begin + if (IRB[5:3] == 3'b110) + begin + // LD (HL),n + MCycles = 3'b011; + if (MCycle[1]) + begin + Inc_PC = 1'b1; + Set_Addr_To = aXY; + Set_BusB_To[2:0] = SSS; + Set_BusB_To[3] = 1'b0; + end + if (MCycle[2]) + Write = 1'b1; + end // if (IRB[5:3] == 3'b110) + else + begin + // LD r,n + MCycles = 3'b010; + if (MCycle[1]) + begin + Inc_PC = 1'b1; + Set_BusA_To[2:0] = DDD; + Read_To_Reg = 1'b1; + end + end + end + + 8'b00001010 : + begin + // LD A,(BC) + MCycles = 3'b010; + if (MCycle[0]) + Set_Addr_To = aBC; + if (MCycle[1]) + Read_To_Acc = 1'b1; + end // case: 8'b00001010 + + 8'b00011010 : + begin + // LD A,(DE) + MCycles = 3'b010; + if (MCycle[0]) + Set_Addr_To = aDE; + if (MCycle[1]) + Read_To_Acc = 1'b1; + end // case: 8'b00011010 + + 8'b00111010 : + begin + if (Mode == 3 ) + begin + // LDD A,(HL) + MCycles = 3'b010; + if (MCycle[0]) + Set_Addr_To = aXY; + if (MCycle[1]) + begin + Read_To_Acc = 1'b1; + IncDec_16 = 4'b1110; + end + end + else + begin + // LD A,(nn) + MCycles = 3'b100; + if (MCycle[1]) + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + if (MCycle[2]) + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + end + if (MCycle[3]) + begin + Read_To_Acc = 1'b1; + end + end // else: !if(Mode == 3 ) + end // case: 8'b00111010 + + 8'b00000010 : + begin + // LD (BC),A + MCycles = 3'b010; + if (MCycle[0]) + begin + Set_Addr_To = aBC; + Set_BusB_To = 4'b0111; + end + if (MCycle[1]) + begin + Write = 1'b1; + end + end // case: 8'b00000010 + + 8'b00010010 : + begin + // LD (DE),A + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aDE; + Set_BusB_To = 4'b0111; + end + MCycle[1] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b00010010 + + 8'b00110010 : + begin + if (Mode == 3 ) + begin + // LDD (HL),A + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aXY; + Set_BusB_To = 4'b0111; + end + MCycle[1] : + begin + Write = 1'b1; + IncDec_16 = 4'b1110; + end + default :; + endcase // case(MCycle) + + end + else + begin + // LD (nn),A + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + Set_BusB_To = 4'b0111; + end + MCycle[3] : + begin + Write = 1'b1; + end + default :; + endcase + end // else: !if(Mode == 3 ) + end // case: 8'b00110010 + + + // 16 BIT LOAD GROUP + 8'b00000001,8'b00010001,8'b00100001,8'b00110001 : + begin + // LD dd,nn + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + Read_To_Reg = 1'b1; + if (DPAIR == 2'b11 ) + begin + Set_BusA_To[3:0] = 4'b1000; + end + else + begin + Set_BusA_To[2:1] = DPAIR; + Set_BusA_To[0] = 1'b1; + end + end // case: 2 + + MCycle[2] : + begin + Inc_PC = 1'b1; + Read_To_Reg = 1'b1; + if (DPAIR == 2'b11 ) + begin + Set_BusA_To[3:0] = 4'b1001; + end + else + begin + Set_BusA_To[2:1] = DPAIR; + Set_BusA_To[0] = 1'b0; + end + end // case: 3 + + default :; + endcase // case(MCycle) + end // case: 8'b00000001,8'b00010001,8'b00100001,8'b00110001 + + 8'b00101010 : + begin + if (Mode == 3 ) + begin + // LDI A,(HL) + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aXY; + MCycle[1] : + begin + Read_To_Acc = 1'b1; + IncDec_16 = 4'b0110; + end + + default :; + endcase + end + else + begin + // LD HL,(nn) + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + end + MCycle[3] : + begin + Set_BusA_To[2:0] = 3'b101; // L + Read_To_Reg = 1'b1; + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + end + MCycle[4] : + begin + Set_BusA_To[2:0] = 3'b100; // H + Read_To_Reg = 1'b1; + end + default :; + endcase + end // else: !if(Mode == 3 ) + end // case: 8'b00101010 + + 8'b00100010 : + begin + if (Mode == 3 ) + begin + // LDI (HL),A + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aXY; + Set_BusB_To = 4'b0111; + end + MCycle[1] : + begin + Write = 1'b1; + IncDec_16 = 4'b0110; + end + default :; + endcase + end + else + begin + // LD (nn),HL + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + Set_BusB_To = 4'b0101; // L + end + + MCycle[3] : + begin + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + Write = 1'b1; + Set_BusB_To = 4'b0100; // H + end + MCycle[4] : + Write = 1'b1; + default :; + endcase + end // else: !if(Mode == 3 ) + end // case: 8'b00100010 + + 8'b11111001 : + begin + // LD SP,HL + TStates = 3'b110; + LDSPHL = 1'b1; + end + + 8'b11xx0101 : + begin + // PUSH qq + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + if (DPAIR == 2'b11 ) + begin + Set_BusB_To = 4'b0111; + end + else + begin + Set_BusB_To[2:1] = DPAIR; + Set_BusB_To[0] = 1'b0; + Set_BusB_To[3] = 1'b0; + end + end // case: 1 + + MCycle[1] : + begin + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + if (DPAIR == 2'b11 ) + begin + Set_BusB_To = 4'b1011; + end + else + begin + Set_BusB_To[2:1] = DPAIR; + Set_BusB_To[0] = 1'b1; + Set_BusB_To[3] = 1'b0; + end + Write = 1'b1; + end // case: 2 + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b11000101,8'b11010101,8'b11100101,8'b11110101 + + 8'b11xx0001 : + begin + // POP qq + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aSP; + MCycle[1] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + Read_To_Reg = 1'b1; + if (DPAIR == 2'b11 ) + begin + Set_BusA_To[3:0] = 4'b1011; + end + else + begin + Set_BusA_To[2:1] = DPAIR; + Set_BusA_To[0] = 1'b1; + end + end // case: 2 + + MCycle[2] : + begin + IncDec_16 = 4'b0111; + Read_To_Reg = 1'b1; + if (DPAIR == 2'b11 ) + begin + Set_BusA_To[3:0] = 4'b0111; + end + else + begin + Set_BusA_To[2:1] = DPAIR; + Set_BusA_To[0] = 1'b0; + end + end // case: 3 + + default :; + endcase // case(MCycle) + end // case: 8'b11000001,8'b11010001,8'b11100001,8'b11110001 + + + // EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + 8'b11101011 : + begin + if (Mode != 3 ) + begin + // EX DE,HL + ExchangeDH = 1'b1; + end + end + + 8'b00001000 : + begin + if (Mode == 3 ) + begin + // LD (nn),SP + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + Set_BusB_To = 4'b1000; + end + + MCycle[3] : + begin + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + Write = 1'b1; + Set_BusB_To = 4'b1001; + end + + MCycle[4] : + Write = 1'b1; + default :; + endcase + end + else if (Mode < 2 ) + begin + // EX AF,AF' + ExchangeAF = 1'b1; + end + end // case: 8'b00001000 + + 8'b11011001 : + begin + if (Mode == 3 ) + begin + // RETI + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aSP; + MCycle[1] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Jump = 1'b1; + IncDec_16 = 4'b0111; + I_RETN = 1'b1; + SetEI = 1'b1; + end + default :; + endcase + end + else if (Mode < 2 ) + begin + // EXX + ExchangeRS = 1'b1; + end + end // case: 8'b11011001 + + 8'b11100011 : + begin + if (Mode != 3 ) + begin + // EX (SP),HL + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aSP; + MCycle[1] : + begin + Read_To_Reg = 1'b1; + Set_BusA_To = 4'b0101; + Set_BusB_To = 4'b0101; + Set_Addr_To = aSP; + end + MCycle[2] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + TStates = 3'b100; + Write = 1'b1; + end + MCycle[3] : + begin + Read_To_Reg = 1'b1; + Set_BusA_To = 4'b0100; + Set_BusB_To = 4'b0100; + Set_Addr_To = aSP; + end + MCycle[4] : + begin + IncDec_16 = 4'b1111; + TStates = 3'b101; + Write = 1'b1; + end + + default :; + endcase + end // if (Mode != 3 ) + end // case: 8'b11100011 + + + // 8 BIT ARITHMETIC AND LOGICAL GROUP + 8'b10xxxxxx : + begin + if (IR[2:0] == 3'b110) + begin + // 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 = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aXY; + MCycle[1] : + begin + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusB_To[2:0] = SSS; + Set_BusA_To[2:0] = 3'b111; + end + + default :; + endcase // case(MCycle) + end // if (IR[2:0] == 3'b110) + else + begin + // 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:0] = SSS; + Set_BusA_To[2:0] = 3'b111; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + end // else: !if(IR[2:0] == 3'b110) + end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,... + + 8'b11xxx110 : + begin + // 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 = 3'b010; + if (MCycle[1] ) + begin + Inc_PC = 1'b1; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusB_To[2:0] = SSS; + Set_BusA_To[2:0] = 3'b111; + end + end + + 8'b00xxx100 : + begin + if (IRB[5:3] == 3'b110) + begin + // INC (HL) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aXY; + MCycle[1] : + begin + TStates = 3'b100; + Set_Addr_To = aXY; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + PreserveC = 1'b1; + ALU_Op = 4'b0000; + Set_BusB_To = 4'b1010; + Set_BusA_To[2:0] = DDD; + end // case: 2 + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b00110100 + else + begin + // INC r + Set_BusB_To = 4'b1010; + Set_BusA_To[2:0] = DDD; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + PreserveC = 1'b1; + ALU_Op = 4'b0000; + end + end + + 8'b00xxx101 : + begin + if (IRB[5:3] == 3'b110) + begin + // DEC (HL) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aXY; + MCycle[1] : + begin + TStates = 3'b100; + Set_Addr_To = aXY; + ALU_Op = 4'b0010; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + PreserveC = 1'b1; + Set_BusB_To = 4'b1010; + Set_BusA_To[2:0] = DDD; + end // case: 2 + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end + else + begin + // DEC r + Set_BusB_To = 4'b1010; + Set_BusA_To[2:0] = DDD; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + PreserveC = 1'b1; + ALU_Op = 4'b0010; + end + end + + // GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + 8'b00100111 : + begin + // DAA + Set_BusA_To[2:0] = 3'b111; + Read_To_Reg = 1'b1; + ALU_Op = 4'b1100; + Save_ALU = 1'b1; + end + + 8'b00101111 : + // CPL + I_CPL = 1'b1; + + 8'b00111111 : + // CCF + I_CCF = 1'b1; + + 8'b00110111 : + // SCF + I_SCF = 1'b1; + + 8'b00000000 : + begin + if (NMICycle == 1'b1 ) + begin + // NMI + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1101; + end + + MCycle[1] : + begin + TStates = 3'b100; + Write = 1'b1; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1100; + end + + MCycle[2] : + begin + TStates = 3'b100; + Write = 1'b1; + end + + default :; + endcase // case(MCycle) + + end + else if (IntCycle == 1'b1 ) + begin + // INT (IM 2) + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[0] : + begin + LDZ = 1'b1; + TStates = 3'b101; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1101; + end + + MCycle[1] : + begin + TStates = 3'b100; + Write = 1'b1; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1100; + end + + MCycle[2] : + begin + TStates = 3'b100; + Write = 1'b1; + end + + MCycle[3] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[4] : + Jump = 1'b1; + default :; + endcase + end + end // case: 8'b00000000 + + 8'b11110011 : + // DI + SetDI = 1'b1; + + 8'b11111011 : + // EI + SetEI = 1'b1; + + // 16 BIT ARITHMETIC GROUP + 8'b00001001,8'b00011001,8'b00101001,8'b00111001 : + begin + // ADD HL,ss + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + NoRead = 1'b1; + ALU_Op = 4'b0000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusA_To[2:0] = 3'b101; + case (IR[5:4]) + 0,1,2 : + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b1; + end + + default : + Set_BusB_To = 4'b1000; + endcase // case(IR[5:4]) + + TStates = 3'b100; + Arith16 = 1'b1; + end // case: 2 + + MCycle[2] : + begin + NoRead = 1'b1; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0001; + Set_BusA_To[2:0] = 3'b100; + case (IR[5:4]) + 0,1,2 : + Set_BusB_To[2:1] = IR[5:4]; + default : + Set_BusB_To = 4'b1001; + endcase + Arith16 = 1'b1; + end // case: 3 + + default :; + endcase // case(MCycle) + end // case: 8'b00001001,8'b00011001,8'b00101001,8'b00111001 + + 8'b00000011,8'b00010011,8'b00100011,8'b00110011 : + begin + // INC ss + TStates = 3'b110; + IncDec_16[3:2] = 2'b01; + IncDec_16[1:0] = DPAIR; + end + + 8'b00001011,8'b00011011,8'b00101011,8'b00111011 : + begin + // DEC ss + TStates = 3'b110; + IncDec_16[3:2] = 2'b11; + IncDec_16[1:0] = DPAIR; + end + + // ROTATE AND SHIFT GROUP + 8'b00000111, + // RLCA + 8'b00010111, + // RLA + 8'b00001111, + // RRCA + 8'b00011111 : + // RRA + begin + Set_BusA_To[2:0] = 3'b111; + ALU_Op = 4'b1000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + end // case: 8'b00000111,... + + + // JUMP GROUP + 8'b11000011 : + begin + // JP nn + MCycles = 3'b011; + if (MCycle[1]) + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + if (MCycle[2]) + begin + Inc_PC = 1'b1; + Jump = 1'b1; + end + + end // case: 8'b11000011 + + 8'b11000010,8'b11001010,8'b11010010,8'b11011010,8'b11100010,8'b11101010,8'b11110010,8'b11111010 : + begin + if (IR[5] == 1'b1 && Mode == 3 ) + begin + case (IRB[4:3]) + 2'b00 : + begin + // LD ($FF00+C),A + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aBC; + Set_BusB_To = 4'b0111; + end + MCycle[1] : + begin + Write = 1'b1; + IORQ = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 2'b00 + + 2'b01 : + begin + // LD (nn),A + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + Set_BusB_To = 4'b0111; + end + + MCycle[3] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: default :... + + 2'b10 : + begin + // LD A,($FF00+C) + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aBC; + MCycle[1] : + begin + Read_To_Acc = 1'b1; + IORQ = 1'b1; + end + default :; + endcase // case(MCycle) + end // case: 2'b10 + + 2'b11 : + begin + // LD A,(nn) + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + end + MCycle[3] : + Read_To_Acc = 1'b1; + default :; + endcase // case(MCycle) + end + endcase + end + else + begin + // JP cc,nn + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + Inc_PC = 1'b1; + if (is_cc_true(F, IR[5:3]) ) + begin + Jump = 1'b1; + end + end + + default :; + endcase + end // else: !if(DPAIR == 2'b11 ) + end // case: 8'b11000010,8'b11001010,8'b11010010,8'b11011010,8'b11100010,8'b11101010,8'b11110010,8'b11111010 + + 8'b00011000 : + begin + if (Mode != 2 ) + begin + // JR e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + Inc_PC = 1'b1; + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + default :; + endcase + end // if (Mode != 2 ) + end // case: 8'b00011000 + + 8'b00111000 : + begin + if (Mode != 2 ) + begin + // JR C,e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + if (F[Flag_C] == 1'b0 ) + begin + MCycles = 3'b010; + end + end + + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + default :; + endcase + end // if (Mode != 2 ) + end // case: 8'b00111000 + + 8'b00110000 : + begin + if (Mode != 2 ) + begin + // JR NC,e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + if (F[Flag_C] == 1'b1 ) + begin + MCycles = 3'b010; + end + end + + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + default :; + endcase + end // if (Mode != 2 ) + end // case: 8'b00110000 + + 8'b00101000 : + begin + if (Mode != 2 ) + begin + // JR Z,e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + if (F[Flag_Z] == 1'b0 ) + begin + MCycles = 3'b010; + end + end + + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + + default :; + endcase + end // if (Mode != 2 ) + end // case: 8'b00101000 + + 8'b00100000 : + begin + if (Mode != 2 ) + begin + // JR NZ,e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + if (F[Flag_Z] == 1'b1 ) + begin + MCycles = 3'b010; + end + end + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + default :; + endcase + end // if (Mode != 2 ) + end // case: 8'b00100000 + + 8'b11101001 : + // JP (HL) + JumpXY = 1'b1; + + 8'b00010000 : + begin + if (Mode == 3 ) + begin + I_DJNZ = 1'b1; + end + else if (Mode < 2 ) + begin + // DJNZ,e + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + I_DJNZ = 1'b1; + Set_BusB_To = 4'b1010; + Set_BusA_To[2:0] = 3'b000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0010; + end + MCycle[1] : + begin + I_DJNZ = 1'b1; + Inc_PC = 1'b1; + end + MCycle[2] : + begin + NoRead = 1'b1; + JumpE = 1'b1; + TStates = 3'b101; + end + default :; + endcase + end // if (Mode < 2 ) + end // case: 8'b00010000 + + + // CALL AND RETURN GROUP + 8'b11001101 : + begin + // CALL nn + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + IncDec_16 = 4'b1111; + Inc_PC = 1'b1; + TStates = 3'b100; + Set_Addr_To = aSP; + LDW = 1'b1; + Set_BusB_To = 4'b1101; + end + MCycle[3] : + begin + Write = 1'b1; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1100; + end + MCycle[4] : + begin + Write = 1'b1; + Call = 1'b1; + end + default :; + endcase // case(MCycle) + end // case: 8'b11001101 + + 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100 : + begin + if (IR[5] == 1'b0 || Mode != 3 ) + begin + // CALL cc,nn + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + MCycle[2] : + begin + Inc_PC = 1'b1; + LDW = 1'b1; + if (is_cc_true(F, IR[5:3]) ) + begin + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + TStates = 3'b100; + Set_BusB_To = 4'b1101; + end + else + begin + MCycles = 3'b011; + end // else: !if(is_cc_true(F, IR[5:3]) ) + end // case: 3 + + MCycle[3] : + begin + Write = 1'b1; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1100; + end + + MCycle[4] : + begin + Write = 1'b1; + Call = 1'b1; + end + + default :; + endcase + end // if (IR[5] == 1'b0 || Mode != 3 ) + end // case: 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100 + + 8'b11001001 : + begin + // RET + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + Set_Addr_To = aSP; + end + + MCycle[1] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Jump = 1'b1; + IncDec_16 = 4'b0111; + end + + default :; + endcase // case(MCycle) + end // case: 8'b11001001 + + 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 : + begin + if (IR[5] == 1'b1 && Mode == 3 ) + begin + case (IRB[4:3]) + 2'b00 : + begin + // LD ($FF00+nn),A + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + Set_Addr_To = aIOA; + Set_BusB_To = 4'b0111; + end + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 2'b00 + + 2'b01 : + begin + // ADD SP,n + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + ALU_Op = 4'b0000; + Inc_PC = 1'b1; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusA_To = 4'b1000; + Set_BusB_To = 4'b0110; + end + + MCycle[2] : + begin + NoRead = 1'b1; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0001; + Set_BusA_To = 4'b1001; + Set_BusB_To = 4'b1110; // Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + end + + default :; + endcase // case(MCycle) + end // case: 2'b01 + + 2'b10 : + begin + // LD A,($FF00+nn) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + Set_Addr_To = aIOA; + end + + MCycle[2] : + Read_To_Acc = 1'b1; + default :; + endcase // case(MCycle) + end // case: 2'b10 + + 2'b11 : + begin + // LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + end + + MCycle[3] : + begin + Set_BusA_To[2:0] = 3'b101; // L + Read_To_Reg = 1'b1; + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + end + + MCycle[4] : + begin + Set_BusA_To[2:0] = 3'b100; // H + Read_To_Reg = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 2'b11 + + endcase // case(IRB[4:3]) + + end + else + begin + // RET cc + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + if (is_cc_true(F, IR[5:3]) ) + begin + Set_Addr_To = aSP; + end + else + begin + MCycles = 3'b001; + end + TStates = 3'b101; + end // case: 1 + + MCycle[1] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + LDZ = 1'b1; + end + MCycle[2] : + begin + Jump = 1'b1; + IncDec_16 = 4'b0111; + end + default :; + endcase + end // else: !if(IR[5] == 1'b1 && Mode == 3 ) + end // case: 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 + + 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 : + begin + // RST p + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1101; + end + + MCycle[1] : + begin + Write = 1'b1; + IncDec_16 = 4'b1111; + Set_Addr_To = aSP; + Set_BusB_To = 4'b1100; + end + + MCycle[2] : + begin + Write = 1'b1; + RstP = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 + + // INPUT AND OUTPUT GROUP + 8'b11011011 : + begin + if (Mode != 3 ) + begin + // IN A,(n) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + Set_Addr_To = aIOA; + end + + MCycle[2] : + begin + Read_To_Acc = 1'b1; + IORQ = 1'b1; + end + + default :; + endcase + end // if (Mode != 3 ) + end // case: 8'b11011011 + + 8'b11010011 : + begin + if (Mode != 3 ) + begin + // OUT (n),A + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + Set_Addr_To = aIOA; + Set_BusB_To = 4'b0111; + end + + MCycle[2] : + begin + Write = 1'b1; + IORQ = 1'b1; + end + + default :; + endcase + end // if (Mode != 3 ) + end // case: 8'b11010011 + + + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + // MULTIBYTE INSTRUCTIONS + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + + 8'b11001011 : + begin + if (Mode != 2 ) + begin + Prefix = 2'b01; + end + end + + 8'b11101101 : + begin + if (Mode < 2 ) + begin + Prefix = 2'b10; + end + end + + 8'b11011101,8'b11111101 : + begin + if (Mode < 2 ) + begin + Prefix = 2'b11; + end + end + + endcase // case(IRB) + end // case: 2'b00 + + + 2'b01 : + begin + + + //---------------------------------------------------------------------------- + // + // CB prefixed instructions + // + //---------------------------------------------------------------------------- + + Set_BusA_To[2:0] = IR[2:0]; + Set_BusB_To[2:0] = IR[2:0]; + + case (IRB) + 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111, + 8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010111, + 8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001111, + 8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011111, + 8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100111, + 8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101111, + 8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110111, + 8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111111 : + begin + // RLC r + // RL r + // RRC r + // RR r + // SLA r + // SRA r + // SRL r + // SLL r (Undocumented) / SWAP r + if (MCycle[0] ) begin + ALU_Op = 4'b1000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + end + end // case: 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,... + + 8'b00000110,8'b00010110,8'b00001110,8'b00011110,8'b00101110,8'b00111110,8'b00100110,8'b00110110 : + begin + // RLC (HL) + // RL (HL) + // RRC (HL) + // RR (HL) + // SRA (HL) + // SRL (HL) + // SLA (HL) + // SLL (HL) (Undocumented) / SWAP (HL) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0], MCycle[6] : + Set_Addr_To = aXY; + MCycle[1] : + begin + ALU_Op = 4'b1000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_Addr_To = aXY; + TStates = 3'b100; + end + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b00000110,8'b00010110,8'b00001110,8'b00011110,8'b00101110,8'b00111110,8'b00100110,8'b00110110 + + 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111, + 8'b01001000,8'b01001001,8'b01001010,8'b01001011,8'b01001100,8'b01001101,8'b01001111, + 8'b01010000,8'b01010001,8'b01010010,8'b01010011,8'b01010100,8'b01010101,8'b01010111, + 8'b01011000,8'b01011001,8'b01011010,8'b01011011,8'b01011100,8'b01011101,8'b01011111, + 8'b01100000,8'b01100001,8'b01100010,8'b01100011,8'b01100100,8'b01100101,8'b01100111, + 8'b01101000,8'b01101001,8'b01101010,8'b01101011,8'b01101100,8'b01101101,8'b01101111, + 8'b01110000,8'b01110001,8'b01110010,8'b01110011,8'b01110100,8'b01110101,8'b01110111, + 8'b01111000,8'b01111001,8'b01111010,8'b01111011,8'b01111100,8'b01111101,8'b01111111 : + begin + // BIT b,r + if (MCycle[0] ) + begin + Set_BusB_To[2:0] = IR[2:0]; + ALU_Op = 4'b1001; + end + end // case: 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,... + + 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 : + begin + // BIT b,(HL) + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0], MCycle[6] : + Set_Addr_To = aXY; + MCycle[1] : + begin + ALU_Op = 4'b1001; + TStates = 3'b100; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 + + 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111, + 8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001111, + 8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010111, + 8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011111, + 8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100111, + 8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101111, + 8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110111, + 8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111111 : + begin + // SET b,r + if (MCycle[0] ) + begin + ALU_Op = 4'b1010; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + end + end // case: 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,... + + 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 : + begin + // SET b,(HL) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0], MCycle[6] : + Set_Addr_To = aXY; + MCycle[1] : + begin + ALU_Op = 4'b1010; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_Addr_To = aXY; + TStates = 3'b100; + end + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 + + 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111, + 8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001111, + 8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010111, + 8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011111, + 8'b10100000,8'b10100001,8'b10100010,8'b10100011,8'b10100100,8'b10100101,8'b10100111, + 8'b10101000,8'b10101001,8'b10101010,8'b10101011,8'b10101100,8'b10101101,8'b10101111, + 8'b10110000,8'b10110001,8'b10110010,8'b10110011,8'b10110100,8'b10110101,8'b10110111, + 8'b10111000,8'b10111001,8'b10111010,8'b10111011,8'b10111100,8'b10111101,8'b10111111 : + begin + // RES b,r + if (MCycle[0] ) + begin + ALU_Op = 4'b1011; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + end + end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,... + + 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 : + begin + // RES b,(HL) + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0], MCycle[6] : + Set_Addr_To = aXY; + MCycle[1] : + begin + ALU_Op = 4'b1011; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_Addr_To = aXY; + TStates = 3'b100; + end + + MCycle[2] : + Write = 1'b1; + default :; + endcase // case(MCycle) + end // case: 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 + + endcase // case(IRB) + end // case: 2'b01 + + + default : + begin : default_ed_block + + //---------------------------------------------------------------------------- + // + // ED prefixed instructions + // + //---------------------------------------------------------------------------- + + case (IRB) + 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000110,8'b00000111 + ,8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001110,8'b00001111 + ,8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010110,8'b00010111 + ,8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011110,8'b00011111 + ,8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100110,8'b00100111 + ,8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101110,8'b00101111 + ,8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110110,8'b00110111 + ,8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111110,8'b00111111 + + + ,8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000110,8'b10000111 + ,8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001110,8'b10001111 + ,8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010110,8'b10010111 + ,8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011110,8'b10011111 + , 8'b10100100,8'b10100101,8'b10100110,8'b10100111 + , 8'b10101100,8'b10101101,8'b10101110,8'b10101111 + , 8'b10110100,8'b10110101,8'b10110110,8'b10110111 + , 8'b10111100,8'b10111101,8'b10111110,8'b10111111 + ,8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000110,8'b11000111 + ,8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001110,8'b11001111 + ,8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010110,8'b11010111 + ,8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011110,8'b11011111 + ,8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100110,8'b11100111 + ,8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101110,8'b11101111 + ,8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110110,8'b11110111 + ,8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111110,8'b11111111 : + ; // NOP, undocumented + + 8'b01111110,8'b01111111 : + // NOP, undocumented + ; + // 8 BIT LOAD GROUP + 8'b01010111 : + begin + // LD A,I + Special_LD = 3'b100; + TStates = 3'b101; + end + + 8'b01011111 : + begin + // LD A,R + Special_LD = 3'b101; + TStates = 3'b101; + end + + 8'b01000111 : + begin + // LD I,A + Special_LD = 3'b110; + TStates = 3'b101; + end + + 8'b01001111 : + begin + // LD R,A + Special_LD = 3'b111; + TStates = 3'b101; + end + + // 16 BIT LOAD GROUP + 8'b01001011,8'b01011011,8'b01101011,8'b01111011 : + begin + // LD dd,(nn) + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + end + + MCycle[3] : + begin + Read_To_Reg = 1'b1; + if (IR[5:4] == 2'b11 ) + begin + Set_BusA_To = 4'b1000; + end + else + begin + Set_BusA_To[2:1] = IR[5:4]; + Set_BusA_To[0] = 1'b1; + end + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + end // case: 4 + + MCycle[4] : + begin + Read_To_Reg = 1'b1; + if (IR[5:4] == 2'b11 ) + begin + Set_BusA_To = 4'b1001; + end + else + begin + Set_BusA_To[2:1] = IR[5:4]; + Set_BusA_To[0] = 1'b0; + end + end // case: 5 + + default :; + endcase // case(MCycle) + end // case: 8'b01001011,8'b01011011,8'b01101011,8'b01111011 + + + 8'b01000011,8'b01010011,8'b01100011,8'b01110011 : + begin + // LD (nn),dd + MCycles = 3'b101; + case (1'b1) // MCycle + MCycle[1] : + begin + Inc_PC = 1'b1; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Set_Addr_To = aZI; + Inc_PC = 1'b1; + LDW = 1'b1; + if (IR[5:4] == 2'b11 ) + begin + Set_BusB_To = 4'b1000; + end + else + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b1; + Set_BusB_To[3] = 1'b0; + end + end // case: 3 + + MCycle[3] : + begin + Inc_WZ = 1'b1; + Set_Addr_To = aZI; + Write = 1'b1; + if (IR[5:4] == 2'b11 ) + begin + Set_BusB_To = 4'b1001; + end + else + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b0; + Set_BusB_To[3] = 1'b0; + end + end // case: 4 + + MCycle[4] : + begin + Write = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01000011,8'b01010011,8'b01100011,8'b01110011 + + 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 : + begin + // LDI, LDD, LDIR, LDDR + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aXY; + IncDec_16 = 4'b1100; // BC + end + + MCycle[1] : + begin + Set_BusB_To = 4'b0110; + Set_BusA_To[2:0] = 3'b111; + ALU_Op = 4'b0000; + Set_Addr_To = aDE; + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0110; // IX + end + else + begin + IncDec_16 = 4'b1110; + end + end // case: 2 + + MCycle[2] : + begin + I_BT = 1'b1; + TStates = 3'b101; + Write = 1'b1; + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0101; // DE + end + else + begin + IncDec_16 = 4'b1101; + end + end // case: 3 + + MCycle[3] : + begin + NoRead = 1'b1; + TStates = 3'b101; + end + + default :; + endcase // case(MCycle) + end // case: 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 + + 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 : + begin + // CPI, CPD, CPIR, CPDR + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aXY; + IncDec_16 = 4'b1100; // BC + end + + MCycle[1] : + begin + Set_BusB_To = 4'b0110; + Set_BusA_To[2:0] = 3'b111; + ALU_Op = 4'b0111; + Save_ALU = 1'b1; + PreserveC = 1'b1; + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0110; + end + else + begin + IncDec_16 = 4'b1110; + end + end // case: 2 + + MCycle[2] : + begin + NoRead = 1'b1; + I_BC = 1'b1; + TStates = 3'b101; + end + + MCycle[3] : + begin + NoRead = 1'b1; + TStates = 3'b101; + end + + default :; + endcase // case(MCycle) + end // case: 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 + + 8'b01000100,8'b01001100,8'b01010100,8'b01011100,8'b01100100,8'b01101100,8'b01110100,8'b01111100 : + begin + // NEG + ALU_Op = 4'b0010; + Set_BusB_To = 4'b0111; + Set_BusA_To = 4'b1010; + Read_To_Acc = 1'b1; + Save_ALU = 1'b1; + end + + 8'b01000110,8'b01001110,8'b01100110,8'b01101110 : + begin + // IM 0 + IMode = 2'b00; + end + + 8'b01010110,8'b01110110 : + // IM 1 + IMode = 2'b01; + + 8'b01011110,8'b01110111 : + // IM 2 + IMode = 2'b10; + + // 16 bit arithmetic + 8'b01001010,8'b01011010,8'b01101010,8'b01111010 : + begin + // ADC HL,ss + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + NoRead = 1'b1; + ALU_Op = 4'b0001; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusA_To[2:0] = 3'b101; + case (IR[5:4]) + 0,1,2 : + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b1; + end + default : + Set_BusB_To = 4'b1000; + endcase + TStates = 3'b100; + end // case: 2 + + MCycle[2] : + begin + NoRead = 1'b1; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0001; + Set_BusA_To[2:0] = 3'b100; + case (IR[5:4]) + 0,1,2 : + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b0; + end + default : + Set_BusB_To = 4'b1001; + endcase // case(IR[5:4]) + end // case: 3 + + default :; + endcase // case(MCycle) + end // case: 8'b01001010,8'b01011010,8'b01101010,8'b01111010 + + 8'b01000010,8'b01010010,8'b01100010,8'b01110010 : + begin + // SBC HL,ss + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[1] : + begin + NoRead = 1'b1; + ALU_Op = 4'b0011; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusA_To[2:0] = 3'b101; + case (IR[5:4]) + 0,1,2 : + begin + Set_BusB_To[2:1] = IR[5:4]; + Set_BusB_To[0] = 1'b1; + end + default : + Set_BusB_To = 4'b1000; + endcase + TStates = 3'b100; + end // case: 2 + + MCycle[2] : + begin + NoRead = 1'b1; + ALU_Op = 4'b0011; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + Set_BusA_To[2:0] = 3'b100; + case (IR[5:4]) + 0,1,2 : + Set_BusB_To[2:1] = IR[5:4]; + default : + Set_BusB_To = 4'b1001; + endcase + end // case: 3 + + default :; + + endcase // case(MCycle) + end // case: 8'b01000010,8'b01010010,8'b01100010,8'b01110010 + + 8'b01101111 : + begin + // RLD + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[1] : + begin + NoRead = 1'b1; + Set_Addr_To = aXY; + end + + MCycle[2] : + begin + Read_To_Reg = 1'b1; + Set_BusB_To[2:0] = 3'b110; + Set_BusA_To[2:0] = 3'b111; + ALU_Op = 4'b1101; + TStates = 3'b100; + Set_Addr_To = aXY; + Save_ALU = 1'b1; + end + + MCycle[3] : + begin + I_RLD = 1'b1; + Write = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01101111 + + 8'b01100111 : + begin + // RRD + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[1] : + Set_Addr_To = aXY; + MCycle[2] : + begin + Read_To_Reg = 1'b1; + Set_BusB_To[2:0] = 3'b110; + Set_BusA_To[2:0] = 3'b111; + ALU_Op = 4'b1110; + TStates = 3'b100; + Set_Addr_To = aXY; + Save_ALU = 1'b1; + end + + MCycle[3] : + begin + I_RRD = 1'b1; + Write = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01100111 + + 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 : + begin + // RETI, RETN + MCycles = 3'b011; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aSP; + + MCycle[1] : + begin + IncDec_16 = 4'b0111; + Set_Addr_To = aSP; + LDZ = 1'b1; + end + + MCycle[2] : + begin + Jump = 1'b1; + IncDec_16 = 4'b0111; + I_RETN = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 + + 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 : + begin + // IN r,(C) + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + Set_Addr_To = aBC; + + MCycle[1] : + begin + IORQ = 1'b1; + if (IR[5:3] != 3'b110 ) + begin + Read_To_Reg = 1'b1; + Set_BusA_To[2:0] = IR[5:3]; + end + I_INRC = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 + + 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 : + begin + // OUT (C),r + // OUT (C),0 + MCycles = 3'b010; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aBC; + Set_BusB_To[2:0] = IR[5:3]; + if (IR[5:3] == 3'b110 ) + begin + Set_BusB_To[3] = 1'b1; + end + end + + MCycle[1] : + begin + Write = 1'b1; + IORQ = 1'b1; + end + + default :; + endcase // case(MCycle) + end // case: 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 + + 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 : + begin + // INI, IND, INIR, INDR + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[0] : + begin + Set_Addr_To = aBC; + Set_BusB_To = 4'b1010; + Set_BusA_To = 4'b0000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0010; + end + + MCycle[1] : + begin + IORQ = 1'b1; + Set_BusB_To = 4'b0110; + Set_Addr_To = aXY; + end + + MCycle[2] : + begin + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0110; + end + else + begin + IncDec_16 = 4'b1110; + end + TStates = 3'b100; + Write = 1'b1; + I_BTR = 1'b1; + end // case: 3 + + MCycle[3] : + begin + NoRead = 1'b1; + TStates = 3'b101; + end + + default :; + endcase // case(MCycle) + end // case: 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 + + 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 : + begin + // OUTI, OUTD, OTIR, OTDR + MCycles = 3'b100; + case (1'b1) // MCycle + MCycle[0] : + begin + TStates = 3'b101; + Set_Addr_To = aXY; + Set_BusB_To = 4'b1010; + Set_BusA_To = 4'b0000; + Read_To_Reg = 1'b1; + Save_ALU = 1'b1; + ALU_Op = 4'b0010; + end + + MCycle[1] : + begin + Set_BusB_To = 4'b0110; + Set_Addr_To = aBC; + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0110; + end + else + begin + IncDec_16 = 4'b1110; + end + end + + MCycle[2] : + begin + if (IR[3] == 1'b0 ) + begin + IncDec_16 = 4'b0010; + end + else + begin + IncDec_16 = 4'b1010; + end + IORQ = 1'b1; + Write = 1'b1; + I_BTR = 1'b1; + end // case: 3 + + MCycle[3] : + begin + NoRead = 1'b1; + TStates = 3'b101; + end + + default :; + endcase // case(MCycle) + end // case: 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 + + endcase // case(IRB) + end // block: default_ed_block + endcase // case(ISet) + + if (Mode == 1 ) + begin + if (MCycle[0] ) + begin + //TStates = 3'b100; + end + else + begin + TStates = 3'b011; + end + end + + if (Mode == 3 ) + begin + if (MCycle[0] ) + begin + //TStates = 3'b100; + end + else + begin + TStates = 3'b100; + end + end + + if (Mode < 2 ) + begin + if (MCycle[5] ) + begin + Inc_PC = 1'b1; + if (Mode == 1 ) + begin + Set_Addr_To = aXY; + TStates = 3'b100; + Set_BusB_To[2:0] = SSS; + Set_BusB_To[3] = 1'b0; + end + if (IRB == 8'b00110110 || IRB == 8'b11001011 ) + begin + Set_Addr_To = aNone; + end + end + if (MCycle[6] ) + begin + if (Mode == 0 ) + begin + TStates = 3'b101; + end + if (ISet != 2'b01 ) + begin + Set_Addr_To = aXY; + end + Set_BusB_To[2:0] = SSS; + Set_BusB_To[3] = 1'b0; + if (IRB == 8'b00110110 || ISet == 2'b01 ) + begin + // LD (HL),n + Inc_PC = 1'b1; + end + else + begin + NoRead = 1'b1; + end + end + end // if (Mode < 2 ) + + end // always @ (IR, ISet, MCycle, F, NMICycle, IntCycle) + + // synopsys dc_script_begin + // set_attribute current_design "revision" "$Id: tv80_mcode.v,v 1.5 2004-11-03 00:14:26 ghutchis Exp $" -type string -quiet + // synopsys dc_script_end +endmodule // T80_MCode Index: branches/restruc2/rtl/core/tv80s.v =================================================================== --- branches/restruc2/rtl/core/tv80s.v (nonexistent) +++ branches/restruc2/rtl/core/tv80s.v (revision 47) @@ -0,0 +1,160 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module tv80s (/*AUTOARG*/ + // Outputs + m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do, + // Inputs + reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di + ); + + parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2 + parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle + + + input reset_n; + input clk; + input wait_n; + input int_n; + input nmi_n; + input busrq_n; + output m1_n; + output mreq_n; + output iorq_n; + output rd_n; + output wr_n; + output rfsh_n; + output halt_n; + output busak_n; + output [15:0] A; + input [7:0] di; + output [7:0] do; + + reg mreq_n; + reg iorq_n; + reg rd_n; + reg wr_n; + + wire cen; + wire intcycle_n; + wire no_read; + wire write; + wire iorq; + reg [7:0] di_reg; + wire [6:0] mcycle; + wire [6:0] tstate; + + assign cen = 1; + + tv80_core #(Mode, IOWait) i_tv80_core + ( + .cen (cen), + .m1_n (m1_n), + .iorq (iorq), + .no_read (no_read), + .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 (clk), + .IntE (), + .stop (), + .A (A), + .dinst (di), + .di (di_reg), + .do (do), + .mc (mcycle), + .ts (tstate), + .intcycle_n (intcycle_n) + ); + + always @(posedge clk) + begin + if (!reset_n) + begin + rd_n <= #1 1'b1; + wr_n <= #1 1'b1; + iorq_n <= #1 1'b1; + mreq_n <= #1 1'b1; + di_reg <= #1 0; + end + else + begin + rd_n <= #1 1'b1; + wr_n <= #1 1'b1; + iorq_n <= #1 1'b1; + mreq_n <= #1 1'b1; + if (mcycle[0]) + begin + if (tstate[1] || (tstate[2] && wait_n == 1'b0)) + begin + rd_n <= #1 ~ intcycle_n; + mreq_n <= #1 ~ intcycle_n; + iorq_n <= #1 intcycle_n; + end + if (tstate[3]) + mreq_n <= #1 1'b0; + end // if (mcycle[0]) + else + begin + if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0) + begin + rd_n <= #1 1'b0; + iorq_n <= #1 ~ iorq; + mreq_n <= #1 iorq; + end + if (T2Write == 0) + begin + if (tstate[2] && write == 1'b1) + begin + wr_n <= #1 1'b0; + iorq_n <= #1 ~ iorq; + mreq_n <= #1 iorq; + end + end + else + begin + if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1) + begin + wr_n <= #1 1'b0; + iorq_n <= #1 ~ iorq; + mreq_n <= #1 iorq; + end + end // else: !if(T2write == 0) + + end // else: !if(mcycle[0]) + + if (tstate[2] && wait_n == 1'b1) + di_reg <= #1 di; + end // else: !if(!reset_n) + end // always @ (posedge clk or negedge reset_n) + +endmodule // t80s + Index: branches/restruc2/rtl/core/tv80_core.v =================================================================== --- branches/restruc2/rtl/core/tv80_core.v (nonexistent) +++ branches/restruc2/rtl/core/tv80_core.v (revision 47) @@ -0,0 +1,1347 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module tv80_core (/*AUTOARG*/ + // Outputs + m1_n, iorq, no_read, write, rfsh_n, halt_n, busak_n, A, do, mc, ts, + intcycle_n, IntE, stop, + // Inputs + reset_n, clk, cen, wait_n, int_n, nmi_n, busrq_n, dinst, di + ); + // Beginning of automatic inputs (from unused autoinst inputs) + // End of automatics + + parameter Mode = 1; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle + parameter Flag_C = 0; + parameter Flag_N = 1; + parameter Flag_P = 2; + parameter Flag_X = 3; + parameter Flag_H = 4; + parameter Flag_Y = 5; + parameter Flag_Z = 6; + parameter Flag_S = 7; + + input reset_n; + input clk; + input cen; + input wait_n; + input int_n; + input nmi_n; + input busrq_n; + output m1_n; + output iorq; + output no_read; + output write; + output rfsh_n; + output halt_n; + output busak_n; + output [15:0] A; + input [7:0] dinst; + input [7:0] di; + output [7:0] do; + output [6:0] mc; + output [6:0] ts; + output intcycle_n; + output IntE; + output stop; + + reg m1_n; + reg iorq; + reg rfsh_n; + reg halt_n; + reg busak_n; + reg [15:0] A; + reg [7:0] do; + reg [6:0] mc; + reg [6:0] ts; + reg intcycle_n; + reg IntE; + reg stop; + + parameter aNone = 3'b111; + parameter aBC = 3'b000; + parameter aDE = 3'b001; + parameter aXY = 3'b010; + parameter aIOA = 3'b100; + parameter aSP = 3'b101; + parameter aZI = 3'b110; + + // Registers + reg [7:0] ACC, F; + reg [7:0] Ap, Fp; + reg [7:0] I; + reg [7:0] R; + reg [15:0] SP, PC; + reg [7:0] RegDIH; + reg [7:0] RegDIL; + wire [15:0] RegBusA; + wire [15:0] RegBusB; + wire [15:0] RegBusC; + reg [2:0] RegAddrA_r; + reg [2:0] RegAddrA; + reg [2:0] RegAddrB_r; + reg [2:0] RegAddrB; + reg [2:0] RegAddrC; + reg RegWEH; + reg RegWEL; + reg Alternate; + + // Help Registers + reg [15:0] TmpAddr; // Temporary address register + reg [7:0] IR; // Instruction register + reg [1:0] ISet; // Instruction set selector + reg [15:0] RegBusA_r; + + reg [15:0] ID16; + reg [7:0] Save_Mux; + + reg [6:0] tstate; + reg [6:0] mcycle; + reg last_mcycle, last_tstate; + reg IntE_FF1; + reg IntE_FF2; + reg Halt_FF; + reg BusReq_s; + reg BusAck; + reg ClkEn; + reg NMI_s; + reg INT_s; + reg [1:0] IStatus; + + reg [7:0] DI_Reg; + reg T_Res; + reg [1:0] XY_State; + reg [2:0] Pre_XY_F_M; + reg NextIs_XY_Fetch; + reg XY_Ind; + reg No_BTR; + reg BTR_r; + reg Auto_Wait; + reg Auto_Wait_t1; + reg Auto_Wait_t2; + reg IncDecZ; + + // ALU signals + reg [7:0] BusB; + reg [7:0] BusA; + wire [7:0] ALU_Q; + wire [7:0] F_Out; + + // Registered micro code outputs + reg [4:0] Read_To_Reg_r; + reg Arith16_r; + reg Z16_r; + reg [3:0] ALU_Op_r; + reg Save_ALU_r; + reg PreserveC_r; + reg [2:0] mcycles; + + // Micro code outputs + wire [2:0] mcycles_d; + wire [2:0] tstates; + reg IntCycle; + reg NMICycle; + wire Inc_PC; + wire Inc_WZ; + wire [3:0] IncDec_16; + wire [1:0] Prefix; + wire Read_To_Acc; + wire Read_To_Reg; + wire [3:0] Set_BusB_To; + wire [3:0] Set_BusA_To; + wire [3:0] ALU_Op; + wire Save_ALU; + wire PreserveC; + wire Arith16; + wire [2:0] Set_Addr_To; + wire Jump; + wire JumpE; + wire JumpXY; + wire Call; + wire RstP; + wire LDZ; + wire LDW; + wire LDSPHL; + wire iorq_i; + wire [2:0] Special_LD; + wire ExchangeDH; + wire ExchangeRp; + wire ExchangeAF; + wire ExchangeRS; + wire I_DJNZ; + wire I_CPL; + wire I_CCF; + wire I_SCF; + wire I_RETN; + wire I_BT; + wire I_BC; + wire I_BTR; + wire I_RLD; + wire I_RRD; + wire I_INRC; + wire SetDI; + wire SetEI; + wire [1:0] IMode; + wire Halt; + + reg [15:0] PC16; + reg [15:0] PC16_B; + reg [15:0] SP16, SP16_A, SP16_B; + reg [15:0] ID16_B; + reg Oldnmi_n; + + tv80_mcode #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_mcode + ( + .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 (no_read), + .Write (write) + ); + + tv80_alu #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_alu + ( + .Arith16 (Arith16_r), + .Z16 (Z16_r), + .ALU_Op (ALU_Op_r), + .IR (IR[5:0]), + .ISet (ISet), + .BusA (BusA), + .BusB (BusB), + .F_In (F), + .Q (ALU_Q), + .F_Out (F_Out) + ); + + function [6:0] number_to_bitvec; + input [2:0] num; + begin + case (num) + 1 : number_to_bitvec = 7'b0000001; + 2 : number_to_bitvec = 7'b0000010; + 3 : number_to_bitvec = 7'b0000100; + 4 : number_to_bitvec = 7'b0001000; + 5 : number_to_bitvec = 7'b0010000; + 6 : number_to_bitvec = 7'b0100000; + 7 : number_to_bitvec = 7'b1000000; + default : number_to_bitvec = 7'bx; + endcase // case(num) + end + endfunction // number_to_bitvec + + always @(/*AUTOSENSE*/mcycle or mcycles or tstate or tstates) + begin + case (mcycles) + 1 : last_mcycle = mcycle[0]; + 2 : last_mcycle = mcycle[1]; + 3 : last_mcycle = mcycle[2]; + 4 : last_mcycle = mcycle[3]; + 5 : last_mcycle = mcycle[4]; + 6 : last_mcycle = mcycle[5]; + 7 : last_mcycle = mcycle[6]; + default : last_mcycle = 1'bx; + endcase // case(mcycles) + + case (tstates) + 0 : last_tstate = tstate[0]; + 1 : last_tstate = tstate[1]; + 2 : last_tstate = tstate[2]; + 3 : last_tstate = tstate[3]; + 4 : last_tstate = tstate[4]; + 5 : last_tstate = tstate[5]; + 6 : last_tstate = tstate[6]; + default : last_tstate = 1'bx; + endcase + end // always @ (... + + + always @(/*AUTOSENSE*/ALU_Q or BusAck or BusB or DI_Reg + or ExchangeRp or IR or Save_ALU_r or Set_Addr_To or XY_Ind + or XY_State or cen or last_tstate or mcycle) + begin + ClkEn = cen && ~ BusAck; + + if (last_tstate) + T_Res = 1'b1; + else T_Res = 1'b0; + + if (XY_State != 2'b00 && XY_Ind == 1'b0 && + ((Set_Addr_To == aXY) || + (mcycle[0] && IR == 8'b11001011) || + (mcycle[0] && IR == 8'b00110110))) + NextIs_XY_Fetch = 1'b1; + else + NextIs_XY_Fetch = 1'b0; + + if (ExchangeRp) + Save_Mux = BusB; + else if (!Save_ALU_r) + Save_Mux = DI_Reg; + else + Save_Mux = ALU_Q; + end // always @ * + + always @ (posedge clk) + begin + if (reset_n == 1'b0 ) + begin + PC <= #1 0; // Program Counter + A <= #1 0; + TmpAddr <= #1 0; + IR <= #1 8'b00000000; + ISet <= #1 2'b00; + XY_State <= #1 2'b00; + IStatus <= #1 2'b00; + mcycles <= #1 3'b000; + do <= #1 8'b00000000; + + ACC <= #1 8'hFF; + F <= #1 8'hFF; + Ap <= #1 8'hFF; + Fp <= #1 8'hFF; + I <= #1 0; + R <= #1 0; + SP <= #1 16'hFFFF; + Alternate <= #1 1'b0; + + Read_To_Reg_r <= #1 5'b00000; + Arith16_r <= #1 1'b0; + BTR_r <= #1 1'b0; + Z16_r <= #1 1'b0; + ALU_Op_r <= #1 4'b0000; + Save_ALU_r <= #1 1'b0; + PreserveC_r <= #1 1'b0; + XY_Ind <= #1 1'b0; + end + else + begin + + if (ClkEn == 1'b1 ) + begin + + ALU_Op_r <= #1 4'b0000; + Save_ALU_r <= #1 1'b0; + Read_To_Reg_r <= #1 5'b00000; + + mcycles <= #1 mcycles_d; + + if (IMode != 2'b11 ) + begin + IStatus <= #1 IMode; + end + + Arith16_r <= #1 Arith16; + PreserveC_r <= #1 PreserveC; + if (ISet == 2'b10 && ALU_Op[2] == 1'b0 && ALU_Op[0] == 1'b1 && mcycle[2] ) + begin + Z16_r <= #1 1'b1; + end + else + begin + Z16_r <= #1 1'b0; + end + + if (mcycle[0] && (tstate[1] | tstate[2] | tstate[3] )) + begin + // mcycle == 1 && tstate == 1, 2, || 3 + + if (tstate[2] && wait_n == 1'b1 ) + begin + if (Mode < 2 ) + begin + A[7:0] <= #1 R; + A[15:8] <= #1 I; + R[6:0] <= #1 R[6:0] + 1; + end + + if (Jump == 1'b0 && Call == 1'b0 && NMICycle == 1'b0 && IntCycle == 1'b0 && ~ (Halt_FF == 1'b1 || Halt == 1'b1) ) + begin + PC <= #1 PC16; + end + + if (IntCycle == 1'b1 && IStatus == 2'b01 ) + begin + IR <= #1 8'b11111111; + end + else if (Halt_FF == 1'b1 || (IntCycle == 1'b1 && IStatus == 2'b10) || NMICycle == 1'b1 ) + begin + IR <= #1 8'b00000000; + end + else + begin + IR <= #1 dinst; + end + + ISet <= #1 2'b00; + if (Prefix != 2'b00 ) + begin + if (Prefix == 2'b11 ) + begin + if (IR[5] == 1'b1 ) + begin + XY_State <= #1 2'b10; + end + else + begin + XY_State <= #1 2'b01; + end + end + else + begin + if (Prefix == 2'b10 ) + begin + XY_State <= #1 2'b00; + XY_Ind <= #1 1'b0; + end + ISet <= #1 Prefix; + end + end + else + begin + XY_State <= #1 2'b00; + XY_Ind <= #1 1'b0; + end + end // if (tstate == 2 && wait_n == 1'b1 ) + + + end + else + begin + // either (mcycle > 1) OR (mcycle == 1 AND tstate > 3) + + if (mcycle[5] ) + begin + XY_Ind <= #1 1'b1; + if (Prefix == 2'b01 ) + begin + ISet <= #1 2'b01; + end + end + + if (T_Res == 1'b1 ) + begin + BTR_r <= #1 (I_BT || I_BC || I_BTR) && ~ No_BTR; + if (Jump == 1'b1 ) + begin + A[15:8] <= #1 DI_Reg; + A[7:0] <= #1 TmpAddr[7:0]; + PC[15:8] <= #1 DI_Reg; + PC[7:0] <= #1 TmpAddr[7:0]; + end + else if (JumpXY == 1'b1 ) + begin + A <= #1 RegBusC; + PC <= #1 RegBusC; + end else if (Call == 1'b1 || RstP == 1'b1 ) + begin + A <= #1 TmpAddr; + PC <= #1 TmpAddr; + end + else if (last_mcycle && NMICycle == 1'b1 ) + begin + A <= #1 16'b0000000001100110; + PC <= #1 16'b0000000001100110; + end + else if (mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) + begin + A[15:8] <= #1 I; + A[7:0] <= #1 TmpAddr[7:0]; + PC[15:8] <= #1 I; + PC[7:0] <= #1 TmpAddr[7:0]; + end + else + begin + case (Set_Addr_To) + aXY : + begin + if (XY_State == 2'b00 ) + begin + A <= #1 RegBusC; + end + else + begin + if (NextIs_XY_Fetch == 1'b1 ) + begin + A <= #1 PC; + end + else + begin + A <= #1 TmpAddr; + end + end // else: !if(XY_State == 2'b00 ) + end // case: aXY + + aIOA : + begin + if (Mode == 3 ) + begin + // Memory map I/O on GBZ80 + A[15:8] <= #1 8'hFF; + end + else if (Mode == 2 ) + begin + // Duplicate I/O address on 8080 + A[15:8] <= #1 DI_Reg; + end + else + begin + A[15:8] <= #1 ACC; + end + A[7:0] <= #1 DI_Reg; + end // case: aIOA + + + aSP : + begin + A <= #1 SP; + end + + aBC : + begin + if (Mode == 3 && iorq_i == 1'b1 ) + begin + // Memory map I/O on GBZ80 + A[15:8] <= #1 8'hFF; + A[7:0] <= #1 RegBusC[7:0]; + end + else + begin + A <= #1 RegBusC; + end + end // case: aBC + + aDE : + begin + A <= #1 RegBusC; + end + + aZI : + begin + if (Inc_WZ == 1'b1 ) + begin + A <= #1 TmpAddr + 1; + end + else + begin + A[15:8] <= #1 DI_Reg; + A[7:0] <= #1 TmpAddr[7:0]; + end + end // case: aZI + + default : + begin + A <= #1 PC; + end + endcase // case(Set_Addr_To) + + end // else: !if(mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) + + + Save_ALU_r <= #1 Save_ALU; + ALU_Op_r <= #1 ALU_Op; + + if (I_CPL == 1'b1 ) + begin + // CPL + ACC <= #1 ~ ACC; + F[Flag_Y] <= #1 ~ ACC[5]; + F[Flag_H] <= #1 1'b1; + F[Flag_X] <= #1 ~ ACC[3]; + F[Flag_N] <= #1 1'b1; + end + if (I_CCF == 1'b1 ) + begin + // CCF + F[Flag_C] <= #1 ~ F[Flag_C]; + F[Flag_Y] <= #1 ACC[5]; + F[Flag_H] <= #1 F[Flag_C]; + F[Flag_X] <= #1 ACC[3]; + F[Flag_N] <= #1 1'b0; + end + if (I_SCF == 1'b1 ) + begin + // SCF + F[Flag_C] <= #1 1'b1; + F[Flag_Y] <= #1 ACC[5]; + F[Flag_H] <= #1 1'b0; + F[Flag_X] <= #1 ACC[3]; + F[Flag_N] <= #1 1'b0; + end + end // if (T_Res == 1'b1 ) + + + if (tstate[2] && wait_n == 1'b1 ) + begin + if (ISet == 2'b01 && mcycle[6] ) + begin + IR <= #1 dinst; + end + if (JumpE == 1'b1 ) + begin + PC <= #1 PC16; + end + else if (Inc_PC == 1'b1 ) + begin + //PC <= #1 PC + 1; + PC <= #1 PC16; + end + if (BTR_r == 1'b1 ) + begin + //PC <= #1 PC - 2; + PC <= #1 PC16; + end + if (RstP == 1'b1 ) + begin + TmpAddr <= #1 { 10'h0, IR[5:3], 3'h0 }; + //TmpAddr <= #1 (others =>1'b0); + //TmpAddr[5:3] <= #1 IR[5:3]; + end + end + if (tstate[3] && mcycle[5] ) + begin + TmpAddr <= #1 SP16; + end + + if ((tstate[2] && wait_n == 1'b1) || (tstate[4] && mcycle[0]) ) + begin + if (IncDec_16[2:0] == 3'b111 ) + begin + SP <= #1 SP16; + end + end + + if (LDSPHL == 1'b1 ) + begin + SP <= #1 RegBusC; + end + if (ExchangeAF == 1'b1 ) + begin + Ap <= #1 ACC; + ACC <= #1 Ap; + Fp <= #1 F; + F <= #1 Fp; + end + if (ExchangeRS == 1'b1 ) + begin + Alternate <= #1 ~ Alternate; + end + end // else: !if(mcycle == 3'b001 && tstate(2) == 1'b0 ) + + + if (tstate[3] ) + begin + if (LDZ == 1'b1 ) + begin + TmpAddr[7:0] <= #1 DI_Reg; + end + if (LDW == 1'b1 ) + begin + TmpAddr[15:8] <= #1 DI_Reg; + end + + if (Special_LD[2] == 1'b1 ) + begin + case (Special_LD[1:0]) + 2'b00 : + begin + ACC <= #1 I; + F[Flag_P] <= #1 IntE_FF2; + end + + 2'b01 : + begin + ACC <= #1 R; + F[Flag_P] <= #1 IntE_FF2; + end + + 2'b10 : + I <= #1 ACC; + + default : + R <= #1 ACC; + endcase + end + end // if (tstate == 3 ) + + + if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) + begin + if (Mode == 3 ) + begin + F[6] <= #1 F_Out[6]; + F[5] <= #1 F_Out[5]; + F[7] <= #1 F_Out[7]; + if (PreserveC_r == 1'b0 ) + begin + F[4] <= #1 F_Out[4]; + end + end + else + begin + F[7:1] <= #1 F_Out[7:1]; + if (PreserveC_r == 1'b0 ) + begin + F[Flag_C] <= #1 F_Out[0]; + end + end + end // if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) + + if (T_Res == 1'b1 && I_INRC == 1'b1 ) + begin + F[Flag_H] <= #1 1'b0; + F[Flag_N] <= #1 1'b0; + if (DI_Reg[7:0] == 8'b00000000 ) + begin + F[Flag_Z] <= #1 1'b1; + end + else + begin + F[Flag_Z] <= #1 1'b0; + end + F[Flag_S] <= #1 DI_Reg[7]; + F[Flag_P] <= #1 ~ (^DI_Reg[7:0]); + end // if (T_Res == 1'b1 && I_INRC == 1'b1 ) + + + if (tstate[1] && Auto_Wait_t1 == 1'b0 ) + begin + do <= #1 BusB; + if (I_RLD == 1'b1 ) + begin + do[3:0] <= #1 BusA[3:0]; + do[7:4] <= #1 BusB[3:0]; + end + if (I_RRD == 1'b1 ) + begin + do[3:0] <= #1 BusB[7:4]; + do[7:4] <= #1 BusA[3:0]; + end + end + + if (T_Res == 1'b1 ) + begin + Read_To_Reg_r[3:0] <= #1 Set_BusA_To; + Read_To_Reg_r[4] <= #1 Read_To_Reg; + if (Read_To_Acc == 1'b1 ) + begin + Read_To_Reg_r[3:0] <= #1 4'b0111; + Read_To_Reg_r[4] <= #1 1'b1; + end + end + + if (tstate[1] && I_BT == 1'b1 ) + begin + F[Flag_X] <= #1 ALU_Q[3]; + F[Flag_Y] <= #1 ALU_Q[1]; + F[Flag_H] <= #1 1'b0; + F[Flag_N] <= #1 1'b0; + end + if (I_BC == 1'b1 || I_BT == 1'b1 ) + begin + F[Flag_P] <= #1 IncDecZ; + end + + if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) || + (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) ) + begin + case (Read_To_Reg_r) + 5'b10111 : + ACC <= #1 Save_Mux; + 5'b10110 : + do <= #1 Save_Mux; + 5'b11000 : + SP[7:0] <= #1 Save_Mux; + 5'b11001 : + SP[15:8] <= #1 Save_Mux; + 5'b11011 : + F <= #1 Save_Mux; + endcase + end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... + end // if (ClkEn == 1'b1 ) + end // else: !if(reset_n == 1'b0 ) + end + + + //------------------------------------------------------------------------- + // + // BC('), DE('), HL('), IX && IY + // + //------------------------------------------------------------------------- + always @ (posedge clk) + begin + if (ClkEn == 1'b1 ) + begin + // Bus A / Write + RegAddrA_r <= #1 { Alternate, Set_BusA_To[2:1] }; + if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusA_To[2:1] == 2'b10 ) + begin + RegAddrA_r <= #1 { XY_State[1], 2'b11 }; + end + + // Bus B + RegAddrB_r <= #1 { Alternate, Set_BusB_To[2:1] }; + if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusB_To[2:1] == 2'b10 ) + begin + RegAddrB_r <= #1 { XY_State[1], 2'b11 }; + end + + // Address from register + RegAddrC <= #1 { Alternate, Set_Addr_To[1:0] }; + // Jump (HL), LD SP,HL + if ((JumpXY == 1'b1 || LDSPHL == 1'b1) ) + begin + RegAddrC <= #1 { Alternate, 2'b10 }; + end + if (((JumpXY == 1'b1 || LDSPHL == 1'b1) && XY_State != 2'b00) || (mcycle[5]) ) + begin + RegAddrC <= #1 { XY_State[1], 2'b11 }; + end + + if (I_DJNZ == 1'b1 && Save_ALU_r == 1'b1 && Mode < 2 ) + begin + IncDecZ <= #1 F_Out[Flag_Z]; + end + if ((tstate[2] || (tstate[3] && mcycle[0])) && IncDec_16[2:0] == 3'b100 ) + begin + if (ID16 == 0 ) + begin + IncDecZ <= #1 1'b0; + end + else + begin + IncDecZ <= #1 1'b1; + end + end + + RegBusA_r <= #1 RegBusA; + end + + end // always @ (posedge clk) + + + always @(/*AUTOSENSE*/Alternate or ExchangeDH or IncDec_16 + or RegAddrA_r or RegAddrB_r or XY_State or mcycle or tstate) + begin + if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && XY_State == 2'b00) + RegAddrA = { Alternate, IncDec_16[1:0] }; + else if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && IncDec_16[1:0] == 2'b10) + RegAddrA = { XY_State[1], 2'b11 }; + else if (ExchangeDH == 1'b1 && tstate[3]) + RegAddrA = { Alternate, 2'b10 }; + else if (ExchangeDH == 1'b1 && tstate[4]) + RegAddrA = { Alternate, 2'b01 }; + else + RegAddrA = RegAddrA_r; + + if (ExchangeDH == 1'b1 && tstate[3]) + RegAddrB = { Alternate, 2'b01 }; + else + RegAddrB = RegAddrB_r; + end // always @ * + + + always @(/*AUTOSENSE*/ALU_Op_r or Auto_Wait_t1 or ExchangeDH + or IncDec_16 or Read_To_Reg_r or Save_ALU_r or mcycle + or tstate or wait_n) + begin + RegWEH = 1'b0; + RegWEL = 1'b0; + if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) || + (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) ) + begin + case (Read_To_Reg_r) + 5'b10000 , 5'b10001 , 5'b10010 , 5'b10011 , 5'b10100 , 5'b10101 : + begin + RegWEH = ~ Read_To_Reg_r[0]; + RegWEL = Read_To_Reg_r[0]; + end + endcase // case(Read_To_Reg_r) + + end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... + + + if (ExchangeDH == 1'b1 && (tstate[3] || tstate[4]) ) + begin + RegWEH = 1'b1; + RegWEL = 1'b1; + end + + if (IncDec_16[2] == 1'b1 && ((tstate[2] && wait_n == 1'b1 && mcycle != 3'b001) || (tstate[3] && mcycle[0])) ) + begin + case (IncDec_16[1:0]) + 2'b00 , 2'b01 , 2'b10 : + begin + RegWEH = 1'b1; + RegWEL = 1'b1; + end + endcase + end + end // always @ * + + + always @(/*AUTOSENSE*/ExchangeDH or ID16 or IncDec_16 or RegBusA_r + or RegBusB or Save_Mux or mcycle or tstate) + begin + RegDIH = Save_Mux; + RegDIL = Save_Mux; + + if (ExchangeDH == 1'b1 && tstate[3] ) + begin + RegDIH = RegBusB[15:8]; + RegDIL = RegBusB[7:0]; + end + else if (ExchangeDH == 1'b1 && tstate[4] ) + begin + RegDIH = RegBusA_r[15:8]; + RegDIL = RegBusA_r[7:0]; + end + else if (IncDec_16[2] == 1'b1 && ((tstate[2] && mcycle != 3'b001) || (tstate[3] && mcycle[0])) ) + begin + RegDIH = ID16[15:8]; + RegDIL = ID16[7:0]; + end + end + + tv80_reg i_reg + ( + .clk (clk), + .CEN (ClkEn), + .WEH (RegWEH), + .WEL (RegWEL), + .AddrA (RegAddrA), + .AddrB (RegAddrB), + .AddrC (RegAddrC), + .DIH (RegDIH), + .DIL (RegDIL), + .DOAH (RegBusA[15:8]), + .DOAL (RegBusA[7:0]), + .DOBH (RegBusB[15:8]), + .DOBL (RegBusB[7:0]), + .DOCH (RegBusC[15:8]), + .DOCL (RegBusC[7:0]) + ); + + //------------------------------------------------------------------------- + // + // Buses + // + //------------------------------------------------------------------------- + + always @ (posedge clk) + begin + if (ClkEn == 1'b1 ) + begin + case (Set_BusB_To) + 4'b0111 : + BusB <= #1 ACC; + 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : + begin + if (Set_BusB_To[0] == 1'b1 ) + begin + BusB <= #1 RegBusB[7:0]; + end + else + begin + BusB <= #1 RegBusB[15:8]; + end + end + 4'b0110 : + BusB <= #1 DI_Reg; + 4'b1000 : + BusB <= #1 SP[7:0]; + 4'b1001 : + BusB <= #1 SP[15:8]; + 4'b1010 : + BusB <= #1 8'b00000001; + 4'b1011 : + BusB <= #1 F; + 4'b1100 : + BusB <= #1 PC[7:0]; + 4'b1101 : + BusB <= #1 PC[15:8]; + 4'b1110 : + BusB <= #1 8'b00000000; + default : + BusB <= #1 8'hxx; + endcase + + case (Set_BusA_To) + 4'b0111 : + BusA <= #1 ACC; + 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : + begin + if (Set_BusA_To[0] == 1'b1 ) + begin + BusA <= #1 RegBusA[7:0]; + end + else + begin + BusA <= #1 RegBusA[15:8]; + end + end + 4'b0110 : + BusA <= #1 DI_Reg; + 4'b1000 : + BusA <= #1 SP[7:0]; + 4'b1001 : + BusA <= #1 SP[15:8]; + 4'b1010 : + BusA <= #1 8'b00000000; + default : + BusB <= #1 8'hxx; + endcase + end + end + + //------------------------------------------------------------------------- + // + // Generate external control signals + // + //------------------------------------------------------------------------- + always @ (posedge clk) + begin + if (reset_n == 1'b0 ) + begin + rfsh_n <= #1 1'b1; + end + else + begin + if (cen == 1'b1 ) + begin + if (mcycle[0] && ((tstate[2] && wait_n == 1'b1) || tstate[3]) ) + begin + rfsh_n <= #1 1'b0; + end + else + begin + rfsh_n <= #1 1'b1; + end + end + end + end + + + always @(/*AUTOSENSE*/BusAck or Halt_FF or I_DJNZ or IntCycle + or IntE_FF1 or di or iorq_i or mcycle or tstate) + begin + mc = mcycle; + ts = tstate; + DI_Reg = di; + halt_n = ~ Halt_FF; + busak_n = ~ BusAck; + intcycle_n = ~ IntCycle; + IntE = IntE_FF1; + iorq = iorq_i; + stop = I_DJNZ; + end + + //----------------------------------------------------------------------- + // + // Syncronise inputs + // + //----------------------------------------------------------------------- + + always @ (posedge clk) + begin : sync_inputs + + if (reset_n == 1'b0 ) + begin + BusReq_s <= #1 1'b0; + INT_s <= #1 1'b0; + NMI_s <= #1 1'b0; + Oldnmi_n <= #1 1'b0; + end + else + begin + if (cen == 1'b1 ) + begin + BusReq_s <= #1 ~ busrq_n; + INT_s <= #1 ~ int_n; + if (NMICycle == 1'b1 ) + begin + NMI_s <= #1 1'b0; + end + else if (nmi_n == 1'b0 && Oldnmi_n == 1'b1 ) + begin + NMI_s <= #1 1'b1; + end + Oldnmi_n <= #1 nmi_n; + end + end + end + + //----------------------------------------------------------------------- + // + // Main state machine + // + //----------------------------------------------------------------------- + + always @ (posedge clk) + begin + if (reset_n == 1'b0 ) + begin + mcycle <= #1 7'b0000001; + tstate <= #1 7'b0000001; + Pre_XY_F_M <= #1 3'b000; + Halt_FF <= #1 1'b0; + BusAck <= #1 1'b0; + NMICycle <= #1 1'b0; + IntCycle <= #1 1'b0; + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + No_BTR <= #1 1'b0; + Auto_Wait_t1 <= #1 1'b0; + Auto_Wait_t2 <= #1 1'b0; + m1_n <= #1 1'b1; + end + else + begin + if (cen == 1'b1 ) + begin + if (T_Res == 1'b1 ) + begin + Auto_Wait_t1 <= #1 1'b0; + end + else + begin + Auto_Wait_t1 <= #1 Auto_Wait || iorq_i; + end + Auto_Wait_t2 <= #1 Auto_Wait_t1; + No_BTR <= #1 (I_BT && (~ IR[4] || ~ F[Flag_P])) || + (I_BC && (~ IR[4] || F[Flag_Z] || ~ F[Flag_P])) || + (I_BTR && (~ IR[4] || F[Flag_Z])); + if (tstate[2] ) + begin + if (SetEI == 1'b1 ) + begin + IntE_FF1 <= #1 1'b1; + IntE_FF2 <= #1 1'b1; + end + if (I_RETN == 1'b1 ) + begin + IntE_FF1 <= #1 IntE_FF2; + end + end + if (tstate[3] ) + begin + if (SetDI == 1'b1 ) + begin + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + end + end + if (IntCycle == 1'b1 || NMICycle == 1'b1 ) + begin + Halt_FF <= #1 1'b0; + end + if (mcycle[0] && tstate[2] && wait_n == 1'b1 ) + begin + m1_n <= #1 1'b1; + end + if (BusReq_s == 1'b1 && BusAck == 1'b1 ) + begin + end + else + begin + BusAck <= #1 1'b0; + if (tstate[2] && wait_n == 1'b0 ) + begin + end + else if (T_Res == 1'b1 ) + begin + if (Halt == 1'b1 ) + begin + Halt_FF <= #1 1'b1; + end + if (BusReq_s == 1'b1 ) + begin + BusAck <= #1 1'b1; + end + else + begin + tstate <= #1 7'b0000010; + if (NextIs_XY_Fetch == 1'b1 ) + begin + mcycle <= #1 7'b0100000; + Pre_XY_F_M <= #1 mcycle; + if (IR == 8'b00110110 && Mode == 0 ) + begin + Pre_XY_F_M <= #1 3'b010; + end + end + else if ((mcycle[6]) || (mcycle[5] && Mode == 1 && ISet != 2'b01) ) + begin + mcycle <= #1 number_to_bitvec(Pre_XY_F_M + 1); + end + else if ((last_mcycle) || + No_BTR == 1'b1 || + (mcycle[1] && I_DJNZ == 1'b1 && IncDecZ == 1'b1) ) + begin + m1_n <= #1 1'b0; + mcycle <= #1 7'b0000001; + IntCycle <= #1 1'b0; + NMICycle <= #1 1'b0; + if (NMI_s == 1'b1 && Prefix == 2'b00 ) + begin + NMICycle <= #1 1'b1; + IntE_FF1 <= #1 1'b0; + end + else if ((IntE_FF1 == 1'b1 && INT_s == 1'b1) && Prefix == 2'b00 && SetEI == 1'b0 ) + begin + IntCycle <= #1 1'b1; + IntE_FF1 <= #1 1'b0; + IntE_FF2 <= #1 1'b0; + end + end + else + begin + mcycle <= #1 { mcycle[5:0], mcycle[6] }; + end + end + end + else + begin // verilog has no "nor" operator + if ( ~(Auto_Wait == 1'b1 && Auto_Wait_t2 == 1'b0) && + ~(IOWait == 1 && iorq_i == 1'b1 && Auto_Wait_t1 == 1'b0) ) + begin + tstate <= #1 { tstate[5:0], tstate[6] }; + end + end + end + if (tstate[0]) + begin + m1_n <= #1 1'b0; + end + end + end + end + + always @(/*AUTOSENSE*/BTR_r or DI_Reg or IncDec_16 or JumpE or PC + or RegBusA or RegBusC or SP or tstate) + begin + if (JumpE == 1'b1 ) + begin + PC16_B = { {8{DI_Reg[7]}}, DI_Reg }; + end + else if (BTR_r == 1'b1 ) + begin + PC16_B = -2; + end + else + begin + PC16_B = 1; + end + + if (tstate[3]) + begin + SP16_A = RegBusC; + SP16_B = { {8{DI_Reg[7]}}, DI_Reg }; + end + else + begin + // suspect that ID16 and SP16 could be shared + SP16_A = SP; + + if (IncDec_16[3] == 1'b1) + SP16_B = -1; + else + SP16_B = 1; + end + + if (IncDec_16[3]) + ID16_B = -1; + else + ID16_B = 1; + + ID16 = RegBusA + ID16_B; + PC16 = PC + PC16_B; + SP16 = SP16_A + SP16_B; + end // always @ * + + + always @(/*AUTOSENSE*/IntCycle or NMICycle or mcycle) + begin + Auto_Wait = 1'b0; + if (IntCycle == 1'b1 || NMICycle == 1'b1 ) + begin + if (mcycle[0] ) + begin + Auto_Wait = 1'b1; + end + end + end // always @ * + +// synopsys dc_script_begin +// set_attribute current_design "revision" "$Id: tv80_core.v,v 1.4 2004-10-05 08:09:43 ghutchis Exp $" -type string -quiet +// synopsys dc_script_end +endmodule // T80 + Index: branches/restruc2/rtl/core/tv80_reg.v =================================================================== --- branches/restruc2/rtl/core/tv80_reg.v (nonexistent) +++ branches/restruc2/rtl/core/tv80_reg.v (revision 47) @@ -0,0 +1,71 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module tv80_reg (/*AUTOARG*/ + // Outputs + DOBH, DOAL, DOCL, DOBL, DOCH, DOAH, + // Inputs + AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL + ); + input [2:0] AddrC; + output [7:0] DOBH; + input [2:0] AddrA; + input [2:0] AddrB; + input [7:0] DIH; + output [7:0] DOAL; + output [7:0] DOCL; + input [7:0] DIL; + output [7:0] DOBL; + output [7:0] DOCH; + output [7:0] DOAH; + input clk, CEN, WEH, WEL; + + reg [7:0] RegsH [0:7]; + reg [7:0] RegsL [0:7]; + + always @(posedge clk) + begin + if (CEN) + begin + if (WEH) RegsH[AddrA] <= DIH; + if (WEL) RegsL[AddrA] <= DIL; + end + end + + assign DOAH = RegsH[AddrA]; + assign DOAL = RegsL[AddrA]; + assign DOBH = RegsH[AddrB]; + assign DOBL = RegsL[AddrB]; + assign DOCH = RegsH[AddrC]; + assign DOCL = RegsL[AddrC]; + + // break out ram bits for waveform debug + wire [7:0] H = RegsH[2]; + wire [7:0] L = RegsL[2]; + +// synopsys dc_script_begin +// set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004-05-16 17:39:57 ghutchis Exp $" -type string -quiet +// synopsys dc_script_end +endmodule + Index: branches/restruc2/rtl/core/tv80_alu.v =================================================================== --- branches/restruc2/rtl/core/tv80_alu.v (nonexistent) +++ branches/restruc2/rtl/core/tv80_alu.v (revision 47) @@ -0,0 +1,442 @@ +// +// TV80 8-Bit Microprocessor Core +// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) +// +// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module tv80_alu (/*AUTOARG*/ + // Outputs + Q, F_Out, + // Inputs + Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In + ); + + parameter Mode = 0; + parameter Flag_C = 0; + parameter Flag_N = 1; + parameter Flag_P = 2; + parameter Flag_X = 3; + parameter Flag_H = 4; + parameter Flag_Y = 5; + parameter Flag_Z = 6; + parameter Flag_S = 7; + + input Arith16; + input Z16; + input [3:0] ALU_Op ; + input [5:0] IR; + input [1:0] ISet; + input [7:0] BusA; + input [7:0] BusB; + input [7:0] F_In; + output [7:0] Q; + output [7:0] F_Out; + reg [7:0] Q; + reg [7:0] F_Out; + + function [4:0] AddSub4; + input [3:0] A; + input [3:0] B; + input Sub; + input Carry_In; + begin + AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; + end + endfunction // AddSub4 + + function [3:0] AddSub3; + input [2:0] A; + input [2:0] B; + input Sub; + input Carry_In; + begin + AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; + end + endfunction // AddSub4 + + function [1:0] AddSub1; + input A; + input B; + input Sub; + input Carry_In; + begin + AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; + end + endfunction // AddSub4 + + // AddSub variables (temporary signals) + reg UseCarry; + reg Carry7_v; + reg OverFlow_v; + reg HalfCarry_v; + reg Carry_v; + reg [7:0] Q_v; + + reg [7:0] BitMask; + + + always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR) + begin + case (IR[5:3]) + 3'b000 : BitMask = 8'b00000001; + 3'b001 : BitMask = 8'b00000010; + 3'b010 : BitMask = 8'b00000100; + 3'b011 : BitMask = 8'b00001000; + 3'b100 : BitMask = 8'b00010000; + 3'b101 : BitMask = 8'b00100000; + 3'b110 : BitMask = 8'b01000000; + default: BitMask = 8'b10000000; + endcase // case(IR[5:3]) + + UseCarry = ~ ALU_Op[2] && ALU_Op[0]; + { HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) ); + { Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v); + { Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v); + OverFlow_v = Carry_v ^ Carry7_v; + end // always @ * + + reg [7:0] Q_t; + reg [8:0] DAA_Q; + + always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB + or Carry_v or F_In or HalfCarry_v or IR or ISet + or OverFlow_v or Q_v or Z16) + begin + Q_t = 8'hxx; + DAA_Q = {9{1'bx}}; + + F_Out = F_In; + case (ALU_Op) + 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 : + begin + F_Out[Flag_N] = 1'b0; + F_Out[Flag_C] = 1'b0; + + case (ALU_Op[2:0]) + + 3'b000, 3'b001 : // ADD, ADC + begin + Q_t = Q_v; + F_Out[Flag_C] = Carry_v; + F_Out[Flag_H] = HalfCarry_v; + F_Out[Flag_P] = OverFlow_v; + end + + 3'b010, 3'b011, 3'b111 : // SUB, SBC, CP + begin + Q_t = Q_v; + F_Out[Flag_N] = 1'b1; + F_Out[Flag_C] = ~ Carry_v; + F_Out[Flag_H] = ~ HalfCarry_v; + F_Out[Flag_P] = OverFlow_v; + end + + 3'b100 : // AND + begin + Q_t[7:0] = BusA & BusB; + F_Out[Flag_H] = 1'b1; + end + + 3'b101 : // XOR + begin + Q_t[7:0] = BusA ^ BusB; + F_Out[Flag_H] = 1'b0; + end + + default : // OR 3'b110 + begin + Q_t[7:0] = BusA | BusB; + F_Out[Flag_H] = 1'b0; + end + + endcase // case(ALU_OP[2:0]) + + if (ALU_Op[2:0] == 3'b111 ) + begin // CP + F_Out[Flag_X] = BusB[3]; + F_Out[Flag_Y] = BusB[5]; + end + else + begin + F_Out[Flag_X] = Q_t[3]; + F_Out[Flag_Y] = Q_t[5]; + end + + if (Q_t[7:0] == 8'b00000000 ) + begin + F_Out[Flag_Z] = 1'b1; + if (Z16 == 1'b1 ) + begin + F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC + end + end + else + begin + F_Out[Flag_Z] = 1'b0; + end // else: !if(Q_t[7:0] == 8'b00000000 ) + + F_Out[Flag_S] = Q_t[7]; + case (ALU_Op[2:0]) + 3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP + ; + + default : + F_Out[Flag_P] = ~(^Q_t); + endcase // case(ALU_Op[2:0]) + + if (Arith16 == 1'b1 ) + begin + 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 + end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 + + 4'b1100 : + begin + // DAA + F_Out[Flag_H] = F_In[Flag_H]; + F_Out[Flag_C] = F_In[Flag_C]; + DAA_Q[7:0] = BusA; + DAA_Q[8] = 1'b0; + if (F_In[Flag_N] == 1'b0 ) + begin + // After addition + // Alow > 9 || H == 1 + if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) + begin + if ((DAA_Q[3:0] > 9) ) + begin + F_Out[Flag_H] = 1'b1; + end + else + begin + F_Out[Flag_H] = 1'b0; + end + DAA_Q = DAA_Q + 6; + end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) + + // new Ahigh > 9 || C == 1 + if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 ) + begin + DAA_Q = DAA_Q + 96; // 0x60 + end + end + else + begin + // After subtraction + if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) + begin + if (DAA_Q[3:0] > 5 ) + begin + F_Out[Flag_H] = 1'b0; + end + DAA_Q[7:0] = DAA_Q[7:0] - 6; + end + if (BusA > 153 || F_In[Flag_C] == 1'b1 ) + begin + DAA_Q = DAA_Q - 352; // 0x160 + end + end // else: !if(F_In[Flag_N] == 1'b0 ) + + F_Out[Flag_X] = DAA_Q[3]; + F_Out[Flag_Y] = DAA_Q[5]; + F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8]; + Q_t = DAA_Q[7:0]; + + if (DAA_Q[7:0] == 8'b00000000 ) + begin + F_Out[Flag_Z] = 1'b1; + end + else + begin + F_Out[Flag_Z] = 1'b0; + end + + F_Out[Flag_S] = DAA_Q[7]; + F_Out[Flag_P] = ~ (^DAA_Q); + end // case: 4'b1100 + + 4'b1101, 4'b1110 : + begin + // RLD, RRD + Q_t[7:4] = BusA[7:4]; + if (ALU_Op[0] == 1'b1 ) + begin + Q_t[3:0] = BusB[7:4]; + end + else + begin + Q_t[3:0] = BusB[3:0]; + end + F_Out[Flag_H] = 1'b0; + F_Out[Flag_N] = 1'b0; + F_Out[Flag_X] = Q_t[3]; + F_Out[Flag_Y] = Q_t[5]; + if (Q_t[7:0] == 8'b00000000 ) + begin + F_Out[Flag_Z] = 1'b1; + end + else + begin + F_Out[Flag_Z] = 1'b0; + end + F_Out[Flag_S] = Q_t[7]; + F_Out[Flag_P] = ~(^Q_t); + end // case: when 4'b1101, 4'b1110 + + 4'b1001 : + begin + // BIT + Q_t[7:0] = BusB & BitMask; + F_Out[Flag_S] = Q_t[7]; + if (Q_t[7:0] == 8'b00000000 ) + begin + F_Out[Flag_Z] = 1'b1; + F_Out[Flag_P] = 1'b1; + end + else + begin + F_Out[Flag_Z] = 1'b0; + F_Out[Flag_P] = 1'b0; + end + F_Out[Flag_H] = 1'b1; + F_Out[Flag_N] = 1'b0; + F_Out[Flag_X] = 1'b0; + F_Out[Flag_Y] = 1'b0; + if (IR[2:0] != 3'b110 ) + begin + F_Out[Flag_X] = BusB[3]; + F_Out[Flag_Y] = BusB[5]; + end + end // case: when 4'b1001 + + 4'b1010 : + // SET + Q_t[7:0] = BusB | BitMask; + + 4'b1011 : + // RES + Q_t[7:0] = BusB & ~ BitMask; + + 4'b1000 : + begin + // ROT + case (IR[5:3]) + 3'b000 : // RLC + begin + Q_t[7:1] = BusA[6:0]; + Q_t[0] = BusA[7]; + F_Out[Flag_C] = BusA[7]; + end + + 3'b010 : // RL + begin + Q_t[7:1] = BusA[6:0]; + Q_t[0] = F_In[Flag_C]; + F_Out[Flag_C] = BusA[7]; + end + + 3'b001 : // RRC + begin + Q_t[6:0] = BusA[7:1]; + Q_t[7] = BusA[0]; + F_Out[Flag_C] = BusA[0]; + end + + 3'b011 : // RR + begin + Q_t[6:0] = BusA[7:1]; + Q_t[7] = F_In[Flag_C]; + F_Out[Flag_C] = BusA[0]; + end + + 3'b100 : // SLA + begin + Q_t[7:1] = BusA[6:0]; + Q_t[0] = 1'b0; + F_Out[Flag_C] = BusA[7]; + end + + 3'b110 : // SLL (Undocumented) / SWAP + begin + if (Mode == 3 ) + begin + Q_t[7:4] = BusA[3:0]; + Q_t[3:0] = BusA[7:4]; + F_Out[Flag_C] = 1'b0; + end + else + begin + Q_t[7:1] = BusA[6:0]; + Q_t[0] = 1'b1; + F_Out[Flag_C] = BusA[7]; + end // else: !if(Mode == 3 ) + end // case: 3'b110 + + 3'b101 : // SRA + begin + Q_t[6:0] = BusA[7:1]; + Q_t[7] = BusA[7]; + F_Out[Flag_C] = BusA[0]; + end + + default : // SRL + begin + Q_t[6:0] = BusA[7:1]; + Q_t[7] = 1'b0; + F_Out[Flag_C] = BusA[0]; + end + endcase // case(IR[5:3]) + + F_Out[Flag_H] = 1'b0; + F_Out[Flag_N] = 1'b0; + 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:0] == 8'b00000000 ) + begin + F_Out[Flag_Z] = 1'b1; + end + else + begin + F_Out[Flag_Z] = 1'b0; + end + F_Out[Flag_P] = ~(^Q_t); + + if (ISet == 2'b00 ) + begin + 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 + end // case: 4'b1000 + + + default : + ; + + endcase // case(ALU_Op) + + Q = Q_t; + end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) + +endmodule // T80_ALU Index: branches/restruc2/tests/blk_mem_inst.c =================================================================== --- branches/restruc2/tests/blk_mem_inst.c (nonexistent) +++ branches/restruc2/tests/blk_mem_inst.c (revision 47) @@ -0,0 +1,162 @@ +/* + * This test covers the four block move instructions LDI, + * LDIR, LDD, and LDDR. + * + * The test creates a buffer full of random data, copies + * the buffer using one of the move instructions, then + * checks the target buffer to make sure it contains the + * same data as the source buffer. + */ + +#include "tv80_env.h" + +#define BUF_SIZE 128 + +char bufa[BUF_SIZE]; +char bufb[BUF_SIZE]; + +void rand_buf (char *buf) { + int i; + + for (i=0; i 0) { + digits[cd++] = (num % 10) + '0'; + num /= 10; + } + for (i=cd; i>0; i--) + msg_port = digits[i-1]; +} + +#define sim_ctl(code) sim_ctl_port = code + +void set_timeout (unsigned int max_timeout) +{ + timeout_port = 0x02; + + max_timeout_low = (max_timeout & 0xFF); + max_timeout_high = (max_timeout >> 8); + + timeout_port = 0x01; +} + +#endif Index: branches/restruc2/tests/blk_out_inst.c =================================================================== --- branches/restruc2/tests/blk_out_inst.c (nonexistent) +++ branches/restruc2/tests/blk_out_inst.c (revision 47) @@ -0,0 +1,158 @@ +/* + * This test covers the four block OUT instructions OUTI, OUTD, + * OTIR, and OTDR. The test works by first creating a buffer + * of data, then doing a block-out instruction from the buffer + * to a special checksum output port. + * + * The test self-checks by performing a checksum of the buffer + * and comparing it with the result read out of the checksum + * port. + */ + +#include "tv80_env.h" + +#define BUF_SIZE 128 + +char buf[BUF_SIZE]; + +char cksum_up (char *buf, char len) { + // pointer should be in 4(ix) and 5(ix), length in 6(ix) + cksum_value = 0; + _asm + ld l, 4(ix) + ld h, 5(ix) + ld b, 6(ix) + ld c, #_cksum_accum + otir + in a, (_cksum_value) + ld l, a + _endasm; +} + +char cksum_dn (char *buf, char len) { + // pointer should be in 4(ix) and 5(ix), length in 6(ix) + cksum_value = 0; + //buf += BUF_SIZE-1; + _asm + ld de, #127 + ld l, 4(ix) + ld h, 5(ix) + add hl, de + ld b, 6(ix) + ld c, #_cksum_accum + otdr + in a, (_cksum_value) + ld l, a + _endasm; +} + +char cksum_up_sn (char *buf, char len) { + // pointer should be in 4(ix) and 5(ix), length in 6(ix) + cksum_value = 0; + + _asm + ld l, 4(ix) + ld h, 5(ix) + ld b, 6(ix) + ld c, #_cksum_accum + ld a, #0 + +cksum_up_sn_loop: + outi + cp b + jp nz, cksum_up_sn_loop + + in a, (_cksum_value) + ld l, a + _endasm; +} + +char cksum_dn_sn (char *buf, char len) { + // pointer should be in 4(ix) and 5(ix), length in 6(ix) + cksum_value = 0; + + _asm + ld de, #127 + ld l, 4(ix) + ld h, 5(ix) + add hl, de + ld b, 6(ix) + ld c, #_cksum_accum + ld a, #0 + +cksum_dn_sn_loop: + outd + cp b + jp nz, cksum_dn_sn_loop + + in a, (_cksum_value) + ld l, a + _endasm; +} + +char cksum_asm (char *buf, char len) { + _asm + ld l, 4(ix) + ld h, 5(ix) + ld b, 6(ix) + ld c, #0 + cksum_asm_loop: + ld a, c + add a, (hl) + ld c, a + inc hl + djnz cksum_asm_loop + ld l, c + _endasm; +} + +char cksum_sw (char *buf, char len) { + char rv, i; + + rv = 0; + for (i=0; i 5) { + test_pass = 1; + intr_cntdwn = 255; + intr_cntdwn = 0; + } else + intr_cntdwn = 32; +} + +int main () +{ + int i; + unsigned char check; + + test_pass = 0; + triggers = 0; + + // start interrupt countdown + intr_cntdwn = 64; + + for (i=0; i<200; i++) + check = sim_ctl_port; + + if (test_pass) + sim_ctl (SC_TEST_PASSED); + else + sim_ctl (SC_TEST_FAILED); + + return 0; +} + Index: branches/restruc2/tests/bintr_crt0.asm =================================================================== --- branches/restruc2/tests/bintr_crt0.asm (nonexistent) +++ branches/restruc2/tests/bintr_crt0.asm (revision 47) @@ -0,0 +1,70 @@ + ;; Generic crt0.s for a Z80 + .module bintr_crt0 + .globl _main + .globl _isr + + .area _HEADER (ABS) + ;; Reset vector + .org 0 + jp init + + .org 0x08 + reti + .org 0x10 + reti + .org 0x18 + reti + .org 0x20 + reti + .org 0x28 + reti + .org 0x30 + reti + .org 0x38 + di + call _isr + ei + reti + + .org 0x100 +init: + ;; Stack at the top of memory. + ld sp,#0xffff + + ;; enable interrupts + im 1 + ei + + ;; Initialise global variables + call _main + jp _exit + + ;; Ordering of segments for the linker. + .area _HOME + .area _CODE + .area _GSINIT + .area _GSFINAL + + .area _DATA + .area _BSS + .area _HEAP + + .area _CODE +__clock:: + ld a,#2 + rst 0x08 + ret + +_exit:: + ;; Exit - special code to the emulator + ld a,#0 + rst 0x08 +1$: + halt + jr 1$ + + .area _GSINIT +gsinit:: + + .area _GSFINAL + ret Index: branches/restruc2/tests/Makefile =================================================================== --- branches/restruc2/tests/Makefile (nonexistent) +++ branches/restruc2/tests/Makefile (revision 47) @@ -0,0 +1,39 @@ +# Makefile for Z80 C/Assembly files +# SDCC_HOME environment variable should be set to SDCC install location + +SDCC_ROOT=$(SDCC_HOME) +CC=$(SDCC_ROOT)/bin/sdcc -mz80 +AS=$(SDCC_ROOT)/bin/as-z80 +LD=$(SDCC_ROOT)/bin/link-z80 +IHEX2MEM=../scripts/ihex2mem.py +LINK_OPTIONS=-- -m -j -x -b_CODE=0x0200 -b_DATA=0x8000 -k$(SDCC_ROOT)/device/lib/z80 -k$(SDCC_ROOT)/lib/z80 -lz80 +AS_LINK_OPTIONS=-bBOOT_VEC=0x0000 -bINT_VEC=0x0038 +C_LINK_OPTIONS=$(SDCC_ROOT)/share/sdcc/lib/z80/crt0.o + +%.vmem : %.ihx + $(IHEX2MEM) $^ $@ + +%.ihx : %.c + $(CC) $^ + +%.o : %.asm + $(AS) -o $*.o $^ + +%.ihx : %.o + $(LD) $(LINK_OPTIONS) $(AS_LINK_OPTIONS) -i $* $^ -e + +bintr.ihx : bintr.c bintr_crt0.o + $(CC) --no-std-crt0 bintr.c bintr_crt0.o + +clean : + rm -f *.map + rm -f *.mem + rm -f *.rel + rm -f *.rst + rm -f *.sym + rm -f *.o + rm -f *.lnk + rm -f *.ihx + rm -f *.lst + rm -f *.vmem + Index: branches/restruc2/tests/tvs80/build =================================================================== --- branches/restruc2/tests/tvs80/build (nonexistent) +++ branches/restruc2/tests/tvs80/build (revision 47) @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +import os + +# Global config +tempfile = "dosbox.temp" +dosbox_home = "/scratch/ghutchis/tools/dosbox-0.60/src/" + +def replace_mount (filename, path): + rfh = open (filename, 'r') + wfh = open (tempfile, 'w') + + rline = rfh.readline() + + while (rline != ''): + if rline.find ("mount c") == 0: + wfh.write ("mount c " + path + "\n") + else: + wfh.write (rline) + rline = rfh.readline() + + rfh.close() + wfh.close() + os.rename (tempfile, filename) + +here = os.getcwd() +replace_mount ("dosbox.conf", here) + +os.system (dosbox_home + "dosbox") +os.rename ("TVS80TST.HEX", "../tvs80.ihx") +os.chdir ("..") +os.system ("../scripts/ihex2mem.py tvs80.ihx tvs80.vmem") Index: branches/restruc2/tests/tvs80/dosbox.conf =================================================================== --- branches/restruc2/tests/tvs80/dosbox.conf (nonexistent) +++ branches/restruc2/tests/tvs80/dosbox.conf (revision 47) @@ -0,0 +1,160 @@ +[sdl] +# fullscreen -- Start dosbox directly in fullscreen. +# fulldouble -- Use double buffering in fullscreen. +# fullfixed -- Don't resize the screen when in fullscreen. +# fullwidth/height -- What resolution to use for fullscreen, use together with fullfixed. +# output -- What to use for output: surface,overlay,opengl,openglnb. +# hwscale -- Extra scaling of window if the output device supports hardware scaling. +# autolock -- Mouse will automatically lock, if you click on the screen. +# sensitiviy -- Mouse sensitivity. +# waitonerror -- Wait before closing the console if dosbox has an error. + +fullscreen=false +fulldouble=false +fullfixed=false +fullwidth=0 +fullheight=0 +output=surface +hwscale=1.00 +autolock=true +sensitivity=100 +waitonerror=true + +[dosbox] +# language -- Select another language file. +# memsize -- Amount of memory dosbox has in megabytes. +# machine -- The type of machine tries to emulate:auto,hercules,cga,tandy,vga. +# Try a specific type if your game has problems with auto. + +language= +machine=auto +memsize=16 + +[render] +# frameskip -- How many frames dosbox skips before drawing one. +# snapdir -- Directory where screenshots get saved. +# aspect -- Do aspect correction. +# scaler -- Scaler used to enlarge/enhance low resolution modes. +# Supported are none,normal2x,advmame2x + +frameskip=0 +snapdir=snaps +aspect=false +scaler=normal2x + +[cpu] +# core -- CPU Core used in emulation: normal,full,dynamic. +# cycles -- Amount of instructions dosbox tries to emulate each millisecond. +# Setting this higher than your machine can handle is bad! +# cycleup -- Amount of cycles to increase/decrease with keycombo. +# cycledown Setting it lower than 100 will be a percentage. + +core=normal +cycles=10000 +cycleup=500 +cycledown=20 + +[mixer] +# nosound -- Enable silent mode, sound is still emulated though. +# rate -- Mixer sample rate, setting any devices higher than this will +# probably lower their sound quality. +# blocksize -- Mixer block size, larger blocks might help sound stuttering +# but sound will also be more lagged. +# wavedir -- Directory where saved sound output goes when you use the +# sound record key-combination, check README file. + +nosound=true +rate=22050 +blocksize=2048 +wavedir=waves + +[midi] +# mpu401 -- Enable MPU-401 Emulation. +# device -- Device that will receive the MIDI data from MPU-401. +# This can be default,alsa,oss,win32,coreaudio,none. +# config -- Special configuration options for the device. + +mpu401=false +device=default +config= + +[sblaster] +# sblaster -- Enable the soundblaster emulation. +# base,irq,dma -- The IO/IRQ/DMA address of the soundblaster. +# sbrate -- Sample rate of soundblaster emulation. +# adlib -- Enable the adlib emulation. +# adlibrate -- Sample rate of adlib emulation. +# cms -- Enable the Creative Music System/Gameblaster emulation. +# Enabling both the adlib and cms might give conflicts! +# cmsrate -- Sample rate of cms emulation. + +sblaster=false +base=220 +irq=7 +dma=1 +sbrate=22050 +adlib=true +adlibrate=22050 +adlibmode=adlib +cms=false +cmsrate=22050 + +[gus] +# gus -- Enable the Gravis Ultrasound emulation. +# base,irq1,irq2,dma1,dma2 -- The IO/IRQ/DMA addresses of the +# Gravis Ultrasound. (Same IRQ's and DMA's are OK.) +# rate -- Sample rate of Ultrasound emulation. +# ultradir -- Path to Ultrasound directory. In this directory +# there should be a MIDI directory that contains +# the patch files for GUS playback. Patch sets used +# with Timidity should work fine. + +gus=false +rate=22050 +base=240 +irq1=5 +irq2=5 +dma1=3 +dma2=3 +ultradir=C:\ULTRASND + +[speaker] +# pcspeaker -- Enable PC-Speaker emulation. +# pcrate -- Sample rate of the PC-Speaker sound generation. +# tandy -- Enable Tandy 3-Voice emulation. +# tandyrate -- Sample rate of the Tandy 3-Voice generation. +# disney -- Enable Disney Sound Source emulation. + +pcspeaker=false +pcrate=22050 +tandy=true +tandyrate=22050 +disney=true + +[bios] +# Nothing to setup yet! + + +[dos] +# xms -- Enable XMS support. +# ems -- Enable EMS support. + +xms=true +ems=true + +[modem] +# modem -- Enable virtual modem emulation. +# comport -- COM Port modem is connected to. +# listenport -- TCP Port the momdem listens on for incoming connections. + +modem=false +comport=2 +listenport=23 + +[autoexec] +# Lines in this section will be run at startup. +mount c /scratch/ghutchis/tv80/tests/tvs80 +c: +as80 -s2 -x3 -l tvs80tst +exit + Index: branches/restruc2/tests/tvs80/as80.exe =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: branches/restruc2/tests/tvs80/as80.exe =================================================================== --- branches/restruc2/tests/tvs80/as80.exe (nonexistent) +++ branches/restruc2/tests/tvs80/as80.exe (revision 47)
branches/restruc2/tests/tvs80/as80.exe Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: branches/restruc2/tests/tvs80/tvs80tst.asm =================================================================== --- branches/restruc2/tests/tvs80/tvs80tst.asm (nonexistent) +++ branches/restruc2/tests/tvs80/tvs80tst.asm (revision 47) @@ -0,0 +1,6573 @@ +; bjp modified to assemble on as80. +; minor mods to account for changes in interrupt structure and I/O +; all such are flagged with my initials..... +; +; The origional code used operators < and > on symbols to extract the +; lower and higher bytes respectively. It appears that as80 has no equivaltent. +; I have hand coded such ---- hopefully correctly. +; This is only a significant issue with such constructs as t_var1 + jr z,ld_66 + fail_msg 65 +ld_66: ld (hl),l + ld a,(hl) + cp l + jr z,ld_67 + fail_msg 66 +ld_67: cp a, #00 ;bjp guess data_1234 + cp b + jr z,ld_126 + fail_msg 125 +ld_126: ld a, #34 ;bjp guess data_1234 + cp h + jr z,ld_136 + fail_msg 135 +ld_136: ld a,#34 ;bjp was >data_1234 + cp l + jr z,ld_137 + fail_msg 136 +ld_137: ld hl,(w_var2) + ld a,data_55 + cp h + jr z,ld_138 + fail_msg 137 +ld_138: ld a,data_aa + cp l + jr z,ld_139 + fail_msg 138 +ld_139: ld bc,(w_var1) + ld a,#12 ;bjp was >data_1234 + cp b + jr z,ld_140 + fail_msg 139 +ld_140: ld a,#34 ;bjp was >data_1234 + cp c + jr z,ld_141 + fail_msg 140 +ld_141: ld de,(w_var3) + ld a,data_7f + cp d + jr z,ld_142 + fail_msg 141 +ld_142: ld a,data_ff + cp e + jr z,ld_143 + fail_msg 142 +ld_143: ld hl,(w_var4) + ld a,data_80 + cp h + jr z,ld_144 + fail_msg 143 +ld_144: ld a,0 + cp l + jr z,ld_145 + fail_msg 144 +ld_145: ld sp,(w_var5) + ld hl,0 + add hl,sp + ld a,data_aa + cp h + jr z,ld_146 + fail_msg 145 +ld_146: ld a,data_55 + cp l + jr z,ld_147 + fail_msg 146 +ld_147: ld ix,(w_var6) + ld hl,0 + ld sp,ix + add hl,sp + ld a,data_ff + cp h + jr z,ld_148 + fail_msg 147 +ld_148: cp l + jr z,ld_149 + fail_msg 148 +ld_149: ld iy,(w_var1) + ld hl,0 + ld sp,iy + add hl,sp + ld a,#12 ;bjp was >data_1234 + cp h + jr z,ld_150 + fail_msg 149 +ld_150: + ld sp, stack_end ; reset stack pointer to EOM + ld a,#34 ;bjp was >data_1234 + cp l + jr z,ld_151 + fail_msg 150 +ld_151: ld hl,data_1234 + ld (tw_var1),hl + ld bc,(tw_var1) + ld a,#12 ;bjp was >data_1234 + cp b + jr z,ld_152 + fail_msg 151 +ld_152: ld a,#34 ;bjp was >data_1234 + cp c + jr z,ld_153 + fail_msg 152 +ld_153: ld bc,data_55aa + ld (tw_var2),bc + ld hl,(tw_var2) + ld a,data_55 + cp h + jr z,ld_154 + fail_msg 153 +ld_154: ld a,data_aa + cp l + jr z,ld_155 + fail_msg 154 +ld_155: ld de,data_7fff + ld (tw_var3),de + ld hl,(tw_var3) + ld a,data_7f + cp h + jr z,ld_156 + fail_msg 155 +ld_156: ld a,data_ff + cp l + jr z,ld_157 + fail_msg 156 +ld_157: ld hl,data_8000 + ld (tw_var4),hl + ld bc,(tw_var4) + ld a,data_80 + cp b + jr z,ld_158 + fail_msg 157 +ld_158: ld a,0 + cp c + jr z,ld_159 + fail_msg 158 +ld_159: ld sp,data_aa55 + ld (tw_var5),sp + ld hl,(tw_var5) + ld a,data_aa + cp h + jr z,ld_160 + fail_msg 159 +ld_160: ld a,data_55 + cp l + jr z,ld_161 + fail_msg 160 +ld_161: ld ix,data_ffff + ld (tw_var6),ix + ld hl,(tw_var6) + ld a,data_ff + cp h + jr z,ld_162 + fail_msg 161 +ld_162: cp l + jr z,ld_163 + fail_msg 162 +ld_163: ld iy,data_1234 + ld (tw_var7),iy + ld hl,(tw_var7) + ld a,#12 ;bjp was >data_1234 + cp h + jr z,ld_164 + fail_msg 163 +ld_164: ld a,#34 ;bjp was >data_1234 + cp l + jr z,ld_165 + fail_msg 164 +ld_165: ld hl,data_55aa + ld sp,hl + ld hl,0 + add hl,sp + ld a,data_55 + cp h + jr z,ld_166 + fail_msg 165 +ld_166: ld a,data_aa + cp l + jr z,push_0 + fail_msg 166 +push_0: ld sp,stack_end + print "push_0" + ld bc,data_1234 + push bc + ld bc,0 + pop bc + ld a,#12 ;bjp was >data_1234 + cp b + jr z,push_1 + fail_msg 0 +push_1: ld a,#34 ;bjp was >data_1234 + cp c + jr z,push_2 + fail_msg 1 +push_2: ld de,data_55aa + push de + ld de,0 + pop de + ld a,data_55 + cp d + jr z,push_3 + fail_msg 2 +push_3: ld a,data_aa + cp e + jr z,push_4 + fail_msg 3 +push_4: ld hl,data_7fff + push hl + ld hl,0 + pop hl + ld a,data_7f + cp h + jr z,push_5 + fail_msg 4 +push_5: ld a,data_ff + cp l + jr z,push_6 + fail_msg 5 +push_6: ld a,data_80 + push af ;f depends on previous compare + ld hl,0 + pop hl + cp h + jr z,push_7 + fail_msg 6 +push_7: ld a,l + cp #42 + jr z,push_8 +push_8: ld h,data_55 + ld l,data_80+#41 + ld a,0 + push hl + pop af + jp m,push_9 + fail_msg 8 +push_9: jr z,push_10 + fail_msg 9 +push_10: jr c,push_11 + fail_msg 10 +push_11: cp data_55 + jr z,push_12 + fail_msg 11 +push_12: ld ix,data_aa55 + ld bc,0 + push ix + pop bc + ld a,data_aa + cp b + jr z,push_13 + fail_msg 12 +push_13: ld a,data_55 + cp c + jr z,push_14 + fail_msg 13 +push_14: ld iy,data_7fff + ld de,0 + push iy + pop de + ld a,data_7f + cp d + jr z,push_15 + fail_msg 14 +push_15: ld a,data_ff + cp e + jr z,push_16 + fail_msg 15 +push_16: ld de,data_1234 + ld ix,0 + ld hl,0 + push de + pop ix + ld sp,ix + add hl,sp + ld a,#12 ;bjp was >data_1234 + cp h + jr z,push_17 + fail_msg 16 +push_17: ld a,#34 ;bjp was >data_1234 + cp l + jr z,push_18 + fail_msg 17 +push_18: ld sp,stack_end + ld bc,data_55aa + ld iy,0 + ld hl,0 + push bc + pop iy + ld sp,iy + add hl,sp + ld a,data_55 + cp h + jr z,push_19 + fail_msg 18 +push_19: ld a,data_aa + cp l + jr z,push_20 + fail_msg 19 +push_20: ld sp,stack_end + print "ex_0" +ex_0: ld de,data_1234 + ld hl,data_ffff + ex de,hl + ld a,data_ff + cp d + jr z,ex_1 + fail_msg 0 +ex_1: cp e + jr z,ex_2 + fail_msg 1 +ex_2: ld a,#12 ;bjp was >data_1234 + cp h + jr z,ex_3 + fail_msg 2 +ex_3: ld a,#34 ;bjp was >data_1234 + cp l + jr z,ex_4 + fail_msg 3 +ex_4: ld h,0 + ld l,0 + push hl + pop af + ex af,af' + ld h,data_7f + ld l,data_80+#41 + push hl + pop af + ex af,af' + cp 0 + jr z,ex_5 + fail_msg 4 +ex_5: ex af,af' + jp m,ex_6 + fail_msg 5 +ex_6: jr z,ex_7 + fail_msg 6 +ex_7: cp data_7f + jr z,ex_8 + fail_msg 7 +ex_8: ld hl,0 + ld bc,0 + ld de,0 + exx + ld hl,data_1234 + ld bc,data_7fff + ld de,data_aa55 + exx + ld a,0 + cp h + jr z,ex_9 + fail_msg 8 +ex_9: cp l + jr z,ex_10 + fail_msg 9 +ex_10: cp d + jr z,ex_11 + fail_msg 10 +ex_11: cp e + jr z,ex_12 + fail_msg 11 +ex_12: cp b + jr z,ex_13 + fail_msg 12 +ex_13: cp c + jr z,ex_14 + fail_msg 13 +ex_14: exx + ld a,#12 ;bjp was >data_1234 + cp h + jr z,ex_15 + fail_msg 14 +ex_15: ld a,#34 ;bjp was >data_1234 + cp l + jr z,ex_16 + fail_msg 15 +ex_16: ld a,data_aa + cp d + jr z,ex_17 + fail_msg 16 +ex_17: ld a,data_55 + cp e + jr z,ex_18 + fail_msg 17 +ex_18: ld a,data_7f + cp b + jr z,ex_19 + fail_msg 18 +ex_19: ld a,data_ff + cp c + jr z,ex_20 + fail_msg 19 +ex_20: ld bc,data_55aa + ld hl,data_7fff + push bc + ex (sp),hl + pop bc + ld a,data_7f + cp b + jr z,ex_21 + fail_msg 20 +ex_21: ld a,data_ff + cp c + jr z,ex_22 + fail_msg 21 +ex_22: ld a,data_55 + cp h + jr z,ex_23 + fail_msg 22 +ex_23: ld a,data_aa + cp l + jr z,ex_24 + fail_msg 23 +ex_24: ld bc,data_ffff + ld ix,data_8000 + ld hl,0 + push bc + ex (sp),ix + pop bc + ld sp,ix + add hl,sp + ld a,data_80 + cp b + jr z,ex_25 + fail_msg 24 +ex_25: ld a,0 + cp c + jr z,ex_26 + fail_msg 25 +ex_26: ld a,data_ff + cp h + jr z,ex_27 + fail_msg 26 +ex_27: cp l + jr z,ex_28 + fail_msg 27 +ex_28: ld sp,stack_end + ld bc,data_1234 + ld iy,data_7fff + ld hl,0 + push bc + ex (sp),iy + pop bc + ld sp,iy + add hl,sp + ld a,data_7f + cp b + jr z,ex_29 + fail_msg 28 +ex_29: ld a,data_ff + cp c + jr z,ex_30 + fail_msg 29 +ex_30: ld a,#12 ;bjp was >data_1234 + cp h + jr z,ex_31 + fail_msg 30 +ex_31: ld a,#34 ;bjp was >data_1234 + cp l + jr z,add_0 + fail_msg 31 +add_0: ld sp,stack_end ; reset stack after EX operations + print "add_0" + ld a,0 + ld b,data_7f + add a,b + cp data_7f + jr z,add_1 + fail_msg 0 +add_1: ld a,0 + ld b,0 + add a,b + jr z,add_2 + fail_msg 1 +add_2: ld b,data_55 + add a,b + jr nz,add_3 + fail_msg 2 +add_3: cp data_55 + jr z,add_4 + fail_msg 3 +add_4: ld a,data_ff + ld b,1 + add a,b + jr c,add_5 + fail_msg 4 +add_5: add a,b + jr nc,add_6 + fail_msg 5 +add_6: ld a,data_ff + ld b,0 + add a,b + jp m,add_7 + fail_msg 6 +add_7: ld b,1 + add a,b + jp p,add_8 + fail_msg 7 +add_8: ld a,data_7f + ld b,1 + add a,b + jp pe,add_9 + fail_msg 8 +add_9: add a,b + jp po,add_10 + fail_msg 9 +add_10: ld a,data_55 + ld c,2 + add a,c + cp data_55+2 + jr z,add_11 + fail_msg 10 +add_11: ld a,data_80 + add a,c + cp data_80+2 + jr z,add_12 + fail_msg 11 +add_12: ld a,data_aa + ld d,data_55 + add a,d + cp data_aa+data_55 + jr z,add_13 + fail_msg 12 +add_13: ld a,data_aa + ld e,2 + add a,e + cp data_aa+2 + jr z,add_14 + fail_msg 13 +add_14: ld a,data_55 + ld h,24 + add a,h + cp data_55+24 + jr z,add_15 + fail_msg 14 +add_15: ld a,data_7f-10 + ld l,10 + add a,l + cp data_7f + jr z,add_16 + fail_msg 15 +add_16: ld a,1 + add a,data_7f + jp pe,add_17 + fail_msg 16 +add_17: jp m,add_18 + fail_msg 17 +add_18: jr nz,add_19 + fail_msg 18 +add_19: cp data_80 + jr z,add_20 + fail_msg 19 +add_20: ld a,data_55 + add a,1 + jp po,add_21 + fail_msg 20 +add_21: jp p,add_22 + fail_msg 21 +add_22: jr nc,add_23 + fail_msg 22 +add_23: cp data_55+1 + jr z,add_24 + fail_msg 23 +add_24: ld a,data_ff + add a,1 + jr c,add_25 + fail_msg 24 +add_25: jr z,add_26 + fail_msg 25 +add_26: add a,1 + jr nc,add_27 + fail_msg 26 +add_27: jr nz,add_28 + fail_msg 27 +add_28: cp 1 + jr z,add_29 + fail_msg 28 +add_29: ld hl,var2 + ld a,2 + add a,(hl) + jp po,add_30 + fail_msg 29 +add_30: jp p,add_31 + fail_msg 30 +add_31: jr nz,add_32 + fail_msg 31 +add_32: jr nc,add_33 + fail_msg 32 +add_33: cp data_55+2 + jr z,add_34 + fail_msg 33 +add_34: ld hl,var1 + ld a,1 + add a,(hl) + jr c,add_35 + fail_msg 34 +add_35: jr z,add_36 + fail_msg 35 +add_36: ld hl,var5 + ld a,1 + add a,(hl) + jp m,add_37 + fail_msg 36 +add_37: jp pe,add_38 + fail_msg 37 +add_38: cp data_80 + jr z,add_39 + fail_msg 38 +add_39: ld ix,var3 + ld a,1 + add a,(ix-1) + jp po,add_40 + fail_msg 39 +add_40: jp p,add_41 + fail_msg 40 +add_41: jr nz,add_42 + fail_msg 41 +add_42: jr nc,add_43 + fail_msg 42 +add_43: cp data_55+1 + jr z,add_44 + fail_msg 43 +add_44: ld a,1 + add a,(ix+2) + jp pe,add_45 + fail_msg 44 +add_45: jp m,add_46 + fail_msg 45 +add_46: cp data_80 + jr z,add_47 + fail_msg 46 +add_47: ld a,1 + add a,(ix-2) + jr c,add_48 + fail_msg 47 +add_48: jr z,add_49 + fail_msg 48 +add_49: add a,1 + jr nc,add_50 + fail_msg 49 +add_50: jr nz,add_51 + fail_msg 50 +add_51: cp 1 + jr z,add_52 + fail_msg 51 +add_52: ld iy,var3 + ld a,10 + add a,(iy-1) + jp po,add_53 + fail_msg 52 +add_53: jp p,add_54 + fail_msg 53 +add_54: jr nz,add_55 + fail_msg 54 +add_55: jr nc,add_56 + fail_msg 55 +add_56: cp data_55+10 + jr z,add_57 + fail_msg 56 +add_57: ld a,1 + add a,(iy+2) + jp pe,add_58 + fail_msg 57 +add_58: jp m,add_59 + fail_msg 58 +add_59: add a,1 + jp po,add_60 + fail_msg 59 +add_60: cp data_80+1 + jr z,add_61 + fail_msg 60 +add_61: ld a,1 + add a,(iy-2) + jr z,add_62 + fail_msg 61 +add_62: jr c,add_63 + fail_msg 62 +add_63: add a,1 + jr nc,add_64 + fail_msg 63 +add_64: jr nz,add_65 + fail_msg 64 +add_65: cp 1 + jr z,add_66 + fail_msg 65 +add_66: ld a,data_ff + add a,data_80 + jp p,add_67 + fail_msg 66 +add_67: jp pe,add_68 + fail_msg 67 +add_68: jr c,add_69 + fail_msg 68 +add_69: add a,1 + jp pe,add_70 + fail_msg 69 +add_70: jp m,add_71 + fail_msg 70 +add_71: jr nc,add_72 + fail_msg 71 +add_72: add a,1 + jp po,add_73 + fail_msg 72 +add_73: cp data_80+1 + jr z,adc_0 + fail_msg 73 +adc_0: nop + print "adc_0" + ld a,0 ;clear cry + add a,0 + ld b,data_7f + adc a,b ;a=7f cry=0 + jp p,adc_1 + fail_msg 0 +adc_1: jp po,adc_2 + fail_msg 1 +adc_2: jr nc,adc_3 + fail_msg 2 +adc_3: jr nz,adc_4 + fail_msg 3 +adc_4: ld b,1 + adc a,b ;a=80 cry=0 + jp pe,adc_5 ;jp ofl + fail_msg 4 +adc_5: jp m,adc_6 + fail_msg 5 +adc_6: cp data_80 + jr z,adc_7 ;z=0 ofl=0 cry=0 (borrow) + fail_msg 6 +adc_7: ld a,data_ff + ld b,1 + adc a,b ;ff+1+0 + jr c,adc_8 + fail_msg 7 +adc_8: jr z,adc_9 + fail_msg 8 +adc_9: adc a,b + jr nc,adc_10 + fail_msg 9 +adc_10: jr nz,adc_11 + fail_msg 10 +adc_11: cp 2 + jr z,adc_12 + fail_msg 11 +adc_12: ld a,data_ff + ld c,0 + adc a,c + jp m,adc_13 + fail_msg 12 +adc_13: jr nc,adc_14 + fail_msg 13 +adc_14: ld c,2 + adc a,c + jp p,adc_15 + fail_msg 14 +adc_15: jr c,adc_16 + fail_msg 15 +adc_16: ld c,0 + adc a,c + cp 2 + jr z,adc_17 + fail_msg 16 +adc_17: ld a,data_ff + ld d,1 + adc a,d + jr c,adc_18 + fail_msg 17 +adc_18: ld d,0 + adc a,d + jr nc,adc_19 + fail_msg 18 +adc_19: cp 1 + jr z,adc_20 + fail_msg 19 +adc_20: ld a,data_aa + ld e,data_7f + adc a,e + jr c,adc_21 + fail_msg 20 +adc_21: ld e,#2b + adc a,e + cp data_55 + jr z,adc_22 + fail_msg 21 +adc_22: ld a,data_ff + ld h,1 + adc a,h + jr c,adc_23 + fail_msg 22 +adc_23: adc a,h + cp 2 + jr z,adc_24 + fail_msg 23 +adc_24: ld a,data_ff + ld l,1 + adc a,l + jr c,adc_25 + fail_msg 24 +adc_25: adc a,l + cp 2 + jr z,adc_26 + fail_msg 25 +adc_26: ld a,0 + adc a,data_7f + jp po,adc_27 + fail_msg 26 +adc_27: jp p,adc_28 + fail_msg 27 +adc_28: jr nc,adc_29 + fail_msg 28 +adc_29: jr nz,adc_30 + fail_msg 29 +adc_30: adc a,1 + jp pe,adc_31 + fail_msg 30 +adc_31: jp m,adc_32 + fail_msg 31 +adc_32: cp data_80 + jr z,adc_33 + fail_msg 32 +adc_33: ld a,data_ff + adc a,1 + jr c,adc_34 + fail_msg 33 +adc_34: jr z,adc_35 + fail_msg 34 +adc_35: adc a,1 + jr nc,adc_36 + fail_msg 35 +adc_36: jr nz,adc_37 + fail_msg 36 +adc_37: cp 2 + jr z,adc_38 + fail_msg 37 +adc_38: ld hl,var5 + ld a,0 + adc a,(hl) + jp p,adc_39 + fail_msg 38 +adc_39: jp po,adc_40 + fail_msg 39 +adc_40: jr nz,adc_41 + fail_msg 40 +adc_41: jr nc,adc_42 + fail_msg 41 +adc_42: ld a,1 + adc a,(hl) + jp m,adc_43 + fail_msg 42 +adc_43: jp pe,adc_44 + fail_msg 43 +adc_44: cp data_80 + jr z,adc_45 + fail_msg 44 +adc_45: ld hl,var1 + ld a,1 + adc a,(hl) + jr z,adc_46 + fail_msg 45 +adc_46: jr c,adc_47 + fail_msg 46 +adc_47: ld hl,var2 + adc a,(hl) + jr nc,adc_48 + fail_msg 47 +adc_48: jr nz,adc_49 + fail_msg 48 +adc_49: cp data_55+1 + jr z,adc_50 + fail_msg 49 +adc_50: ld ix,var3 + ld a,0 + adc a,(ix+2) + jp p,adc_51 + fail_msg 50 +adc_51: jp po,adc_52 + fail_msg 51 +adc_52: jr nc,adc_53 + fail_msg 52 +adc_53: jr nz,adc_54 + fail_msg 53 +adc_54: ld a,1 + adc a,(ix+2) + jp m,adc_55 + fail_msg 54 +adc_55: jp pe,adc_56 + fail_msg 55 +adc_56: cp data_80 + jr z,adc_57 + fail_msg 56 +adc_57: ld a,1 + adc a,(ix-2) + jr c,adc_58 + fail_msg 57 +adc_58: jr z,adc_59 + fail_msg 58 +adc_59: adc a,(ix-1) + jr nc,adc_60 + fail_msg 59 +adc_60: jr nz,adc_61 + fail_msg 60 +adc_61: cp data_55+1 + jr z,adc_62 + fail_msg 61 +adc_62: ld iy,var3 + ld a,0 + adc a,(ix+2) + jp p,adc_63 + fail_msg 62 +adc_63: jp po,adc_64 + fail_msg 63 +adc_64: jr nc,adc_65 + fail_msg 64 +adc_65: jr nz,adc_66 + fail_msg 65 +adc_66: ld a,1 + adc a,(iy+2) + jp m,adc_67 + fail_msg 66 +adc_67: jp pe,adc_68 + fail_msg 67 +adc_68: cp data_80 + jr z,adc_69 + fail_msg 68 +adc_69: ld a,1 + adc a,(iy-2) + jr c,adc_70 + fail_msg 69 +adc_70: jr z,adc_71 + fail_msg 70 +adc_71: adc a,(iy-1) + jr nc,adc_72 + fail_msg 71 +adc_72: jr nz,adc_73 + fail_msg 72 +adc_73: cp data_55+1 + jr z,adc_74 + fail_msg 73 +adc_74: ld a,data_ff + add a,0 + adc a,data_80 + jp p,adc_75 + fail_msg 74 +adc_75: jp pe,adc_76 + fail_msg 75 +adc_76: jr nz,adc_77 + fail_msg 76 +adc_77: adc a,0 + jp m,adc_78 + fail_msg 77 +adc_78: jp pe,adc_79 + fail_msg 78 +adc_79: adc a,1 + jp po,adc_80 + fail_msg 79 +adc_80: cp data_80+1 + jr z,sub_0 + fail_msg 80 +sub_0: nop + print "sub_0" + ld a,0 + ld b,1 + sub a,b + jp m,sub_1 + fail_msg 0 +sub_1: jp po,sub_2 + fail_msg 1 +sub_2: jr c,sub_3 + fail_msg 2 +sub_3: jr nz,sub_4 + fail_msg 3 +sub_4: sub a,b + jr nc,sub_5 + fail_msg 4 +sub_5: cp data_ff-1 + jr z,sub_6 + fail_msg 5 +sub_6: ld a,1 + ld b,0 + sub a,b + jr nz,sub_7 + fail_msg 6 +sub_7: jp p,sub_8 + fail_msg 7 +sub_8: ld b,1 + sub a,b + jr z,sub_9 + fail_msg 8 +sub_9: sub a,b + jp m,sub_10 + fail_msg 9 +sub_10: cp data_ff + jr z,sub_11 + fail_msg 10 +sub_11: ld a,data_80 + ld b,data_7f + sub a,b + jp pe,sub_12 + fail_msg 11 +sub_12: sub a,b + jp po,sub_13 + fail_msg 12 +sub_13: cp data_80+2 + jr z,sub_14 + fail_msg 13 +sub_14: ld a,data_55 + ld c,data_55 + sub a,c + jr z,sub_15 + fail_msg 14 +sub_15: ld c,1 + sub a,c + jp m,sub_16 + fail_msg 15 +sub_16: jr c,sub_17 + fail_msg 16 +sub_17: cp data_ff + jr z,sub_18 + fail_msg 17 +sub_18: ld a,data_55 + ld d,data_7f + sub a,d + jr c,sub_19 + fail_msg 18 +sub_19: cp data_55-data_7f + jr z,sub_20 + fail_msg 19 +sub_20: ld a,0 + ld e,data_ff + sub a,e + jr c,sub_21 + fail_msg 20 +sub_21: cp 1 + jr z,sub_22 + fail_msg 21 +sub_22: ld a,data_ff + ld h,data_80 + sub a,h + jp p,sub_23 + fail_msg 22 +sub_23: cp data_7f + jr z,sub_24 + fail_msg 23 +sub_24: ld a,data_aa + ld l,data_ff + sub a,l + jr c,sub_25 + fail_msg 24 +sub_25: cp data_aa+1 + jr z,sub_26 + fail_msg 25 +sub_26: ld a,data_7f + sub a,data_ff + jp pe,sub_27 + fail_msg 26 +sub_27: jp m,sub_28 + fail_msg 27 +sub_28: sub a,1 + jp p,sub_29 + fail_msg 28 +sub_29: sub a,1 + jp po,sub_30 + fail_msg 29 +sub_30: jr nz,sub_31 + fail_msg 30 +sub_31: sub a,data_7f-1 + jr z,sub_32 + fail_msg 31 +sub_32: ld a,0 + sub a,data_ff + jr c,sub_33 + fail_msg 32 +sub_33: sub a,1 + jr z,sub_34 + fail_msg 33 +sub_34: jr nc,sub_35 + fail_msg 34 +sub_35: ld hl,var1 + ld a,data_7f + sub a,(hl) + jp m,sub_36 + fail_msg 35 +sub_36: jp pe,sub_37 + fail_msg 36 +sub_37: jr c,sub_38 + fail_msg 37 +sub_38: ld hl,var3 + sub a,(hl) + jp p,sub_39 + fail_msg 38 +sub_39: jp po,sub_40 + fail_msg 39 +sub_40: jr nc,sub_41 + fail_msg 40 +sub_41 jr z,sub_42 + fail_msg 40 +sub_42: ld hl,var2 + sub a,(hl) + jr nz,sub_43 + fail_msg 42 +sub_43: cp data_aa+1 + jr z,sub_44 + fail_msg 43 +sub_44: ld ix,var3 + ld a,data_7f + sub a,(ix-2) + jp m,sub_45 + fail_msg 44 +sub_45: jp pe,sub_46 + fail_msg 45 +sub_46: jr c,sub_47 + fail_msg 46 +sub_47: sub a,(ix+0) + jp p,sub_48 + fail_msg 47 +sub_48: jp po,sub_49 + fail_msg 48 +sub_49: jr nc,sub_50 + fail_msg 49 +sub_50: jr z,sub_51 + fail_msg 50 +sub_51: sub a,(ix+2) + jr nz,sub_52 + fail_msg 51 +sub_52: cp data_80+1 + jr z,sub_53 + fail_msg 52 +sub_53: ld iy,var3 + ld a,data_7f + sub a,(iy-2) + jp m,sub_54 + fail_msg 53 +sub_54: jp pe,sub_55 + fail_msg 54 +sub_55: jr c,sub_56 + fail_msg 55 +sub_56: jr nz,sub_57 + fail_msg 56 +sub_57: sub a,(iy+0) + jp p,sub_58 + fail_msg 57 +sub_58: jp po,sub_59 + fail_msg 58 +sub_59: jr nc,sub_60 + fail_msg 59 +sub_60: jr z,sub_61 + fail_msg 60 +sub_61: sub a,(iy+2) + jr nz,sub_62 + fail_msg 61 +sub_62: cp data_80+1 + jr z,sbc_0 + fail_msg 62 +sbc_0: nop + print "sbc_0" + ld a,data_7f + ld b,0 + sub a,b ;clear carry flag + ld b,data_ff + sbc a,b + jp m,sbc_1 + fail_msg 0 +sbc_1: jp pe,sbc_2 + fail_msg 1 +sbc_2: jr c,sbc_3 + fail_msg 2 +sbc_3: jr nz,sbc_4 + fail_msg 3 +sbc_4: ld b,data_7f + sbc a,b + jp p,sbc_5 + fail_msg 4 +sbc_5: jp pe,sbc_6 + fail_msg 5 +sbc_6: jr nc,sbc_7 + fail_msg 6 +sbc_7: jr z,sbc_8 + fail_msg 7 +sbc_8: ld b,data_ff + sbc a,b + jp po,sbc_9 + fail_msg 8 +sbc_9: jr nz,sbc_10 + fail_msg 9 +sbc_10: ld b,0 + sbc a,b + jr z,sbc_11 + fail_msg 10 +sbc_11: ld a,data_aa + ld c,data_ff + sbc a,c + jr c,sbc_12 + fail_msg 11 +sbc_12: ld c,0 + sbc a,c + jr nc,sbc_13 + fail_msg 12 +sbc_13: cp data_aa + jr z,sbc_14 + fail_msg 13 +sbc_14: ld a,data_55 + ld d,data_ff + sbc a,d + jr c,sbc_15 + fail_msg 14 +sbc_15: ld d,0 + sbc a,d + jr nc,sbc_16 + fail_msg 15 +sbc_16: cp data_55 + jr z,sbc_17 + fail_msg 16 +sbc_17: ld a,data_aa + ld e,data_ff + sbc a,e + jr c,sbc_18 + fail_msg 17 +sbc_18: ld e,0 + sbc a,e + jr nc,sbc_19 + fail_msg 18 +sbc_19: cp data_aa + jr z,sbc_20 + fail_msg 19 +sbc_20: ld a,data_55 + ld h,data_ff + sbc a,h + jr c,sbc_21 + fail_msg 20 +sbc_21: ld h,0 + sbc a,h + jr nc,sbc_22 + fail_msg 21 +sbc_22: cp data_55 + jr z,sbc_23 + fail_msg 22 +sbc_23: ld a,data_aa + ld l,data_ff + sbc a,l + jr c,sbc_24 + fail_msg 23 +sbc_24: ld l,0 + sbc a,l + jr nc,sbc_25 + fail_msg 24 +sbc_25: cp data_aa + jr z,sbc_26 + fail_msg 25 +sbc_26: ld a,data_7f + sbc a,data_ff + jp m,sbc_27 + fail_msg 26 +sbc_27: jp pe,sbc_28 + fail_msg 27 +sbc_28: jr c,sbc_29 + fail_msg 28 +sbc_29: jr nz,sbc_30 + fail_msg 29 +sbc_30: sbc a,data_7f + jp p,sbc_31 + fail_msg 30 +sbc_31: jp pe,sbc_32 + fail_msg 31 +sbc_32: jr nc,sbc_33 + fail_msg 32 +sbc_33: jr z,sbc_34 + fail_msg 33 +sbc_34: sbc a,data_ff + jr nz,sbc_35 + fail_msg 34 +sbc_35: cp 1 + jr z,sbc_36 + fail_msg 35 +sbc_36: ld hl,var1 + ld a,data_7f + sbc a,(hl) + jp m,sbc_37 + fail_msg 36 +sbc_37: jp pe,sbc_38 + fail_msg 37 +sbc_38: jr c,sbc_39 + fail_msg 38 +sbc_39: jr nz,sbc_40 + fail_msg 39 +sbc_40: ld hl,var5 + sbc a,(hl) + jp p,sbc_41 + fail_msg 40 +sbc_41: jp pe,sbc_42 + fail_msg 41 +sbc_42: jr nc,sbc_43 + fail_msg 42 +sbc_43: jr z,sbc_44 + fail_msg 43 +sbc_44: ld hl,var2 + sbc a,(hl) + jr nz,sbc_45 + fail_msg 44 +sbc_45: cp data_aa+1 + jr z,sbc_46 + fail_msg 45 +sbc_46: ld ix,var3 + ld a,data_7f + sbc a,(ix-2) + jp m,sbc_47 + fail_msg 46 +sbc_47: jp pe,sbc_48 + fail_msg 47 +sbc_48: jr c,sbc_49 + fail_msg 48 +sbc_49: jr nz,sbc_50 + fail_msg 49 +sbc_50: sbc a,(ix+2) + jp p,sbc_51 + fail_msg 50 +sbc_51: jp pe,sbc_52 + fail_msg 51 +sbc_52: jr nc,sbc_53 + fail_msg 52 +sbc_53: jr z,sbc_54 + fail_msg 53 +sbc_54: sbc a,(ix-1) + jr nz,sbc_55 + fail_msg 54 +sbc_55: cp data_aa+1 + jr z,sbc_56 + fail_msg 55 +sbc_56: ld iy,var3 + ld a,data_7f + sbc a,(ix-2) + jp m,sbc_57 + fail_msg 56 +sbc_57: jp pe,sbc_58 + fail_msg 57 +sbc_58: jr c,sbc_59 + fail_msg 58 +sbc_59: jr nz,sbc_60 + fail_msg 59 +sbc_60: sbc a,(ix+2) + jp p,sbc_61 + fail_msg 60 +sbc_61: jp pe,sbc_62 + fail_msg 61 +sbc_62: jr nc,sbc_63 + fail_msg 62 +sbc_63: jr z,sbc_64 + fail_msg 63 +sbc_64: sbc a,(ix+1) + jr nz,sbc_65 + fail_msg 64 +sbc_65: cp data_55+1 + jr z,and_0 + fail_msg 65 +and_0: nop + print "and_0" + ld a,data_ff + add a,1 ;set carry + ld a,data_ff + ld b,data_aa + and a,b + jr nc,and_1 + fail_msg 0 +and_1: jp m,and_2 + fail_msg 1 +and_2: jp pe,and_3 + fail_msg 2 +and_3: jr nz,and_4 + fail_msg 3 +and_4: ld b,data_55 + and a,b + jp p,and_5 + fail_msg 4 +and_5: jr z,and_6 + fail_msg 5 +and_6: ld a,data_ff + ld b,data_7f + and a,b + jp po,and_7 + fail_msg 6 +and_7: ld b,data_55 + and a,b + jp pe,and_8 + fail_msg 7 +and_8: ld a,data_ff + ld c,data_80 + and a,c + jp m,and_9 + fail_msg 8 +and_9: cp data_80 + jr z,and_10 + fail_msg 9 +and_10: ld a,data_ff + ld d,data_7f + and a,d + jp p,and_11 + fail_msg 10 +and_11: cp data_7f + jr z,and_12 + fail_msg 11 +and_12: ld a,data_ff + ld e,data_aa + and a,e + jp m,and_13 + fail_msg 12 +and_13: cp data_aa + jr z,and_14 + fail_msg 13 +and_14: ld a,data_ff + ld h,data_55 + and a,h + jp p,and_15 + fail_msg 14 +and_15: cp data_55 + jr z,and_16 + fail_msg 15 +and_16: ld a,data_ff + ld l,data_aa + and a,l + jp m,and_17 + fail_msg 16 +and_17: cp data_aa + jr z,and_18 + fail_msg 17 +and_18: ld a,data_ff + and a,data_aa + jp m,and_19 + fail_msg 18 +and_19: jr nz,and_20 + fail_msg 19 +and_20: and a,data_55 + jp p,and_21 + fail_msg 20 +and_21: jr z,and_22 + fail_msg 21 +and_22: ld a,data_ff + and a,data_7f + jp po,and_23 + fail_msg 22 +and_23: and a,data_55 + jp pe,and_24 + fail_msg 23 +and_24: jr nz,and_25 + fail_msg 24 +and_25: and a,data_aa + jr z,and_26 + fail_msg 25 +and_26: ld a,data_ff + and a,data_aa + cp data_aa + jr z,and_27 + fail_msg 26 +and_27: ld hl,var4 + ld a,data_ff + and a,(hl) + jp m,and_28 + fail_msg 27 +and_28: jr nz,and_29 + fail_msg 28 +and_29: ld hl,var2 + and a,(hl) + jp p,and_30 + fail_msg 29 +and_30: jr z,and_31 + fail_msg 30 +and_31: ld a,data_ff + ld hl,var5 + and a,(hl) + jp po,and_32 + fail_msg 31 +and_32: ld hl,var2 + and a,(hl) + jp pe,and_33 + fail_msg 32 +and_33: cp data_55 + jr z,and_34 + fail_msg 33 +and_34: ld ix,var3 + ld a,data_ff + and a,(ix+1) + jp m,and_35 + fail_msg 34 +and_35: jr nz,and_36 + fail_msg 35 +and_36: and a,(ix-1) + jp p,and_37 + fail_msg 36 +and_37: jr z,and_38 + fail_msg 37 +and_38: ld a,data_ff + and a,(ix+2) + jp po,and_39 + fail_msg 38 +and_39: and a,(ix-1) + jp pe,and_40 + fail_msg 39 +and_40: cp data_55 + jr z,and_41 + fail_msg 40 +and_41: ld iy,var3 + ld a,data_ff + and a,(iy+1) + jp m,and_42 + fail_msg 41 +and_42: jr nz,and_43 + fail_msg 42 +and_43: and a,(iy-1) + jp p,and_44 + fail_msg 43 +and_44: jr z,and_45 + fail_msg 44 +and_45: ld a,data_ff + and a,(iy+2) + jp po,and_46 + fail_msg 45 +and_46: and a,(iy-1) + jp pe,and_47 + fail_msg 46 +and_47: cp data_55 + jr z,or_0 + fail_msg 47 +or_0: nop + print "or_0" + ld a,0 + ld b,data_7f + or a,b + jp p,or_1 + fail_msg 0 +or_1: jp po,or_2 + fail_msg 1 +or_2: ld b,data_80 + or a,b + jp m,or_3 + fail_msg 2 +or_3: jp pe,or_4 + fail_msg 3 +or_4: cp data_ff + jr z,or_5 + fail_msg 4 +or_5: ld a,0 + ld b,0 + or a,b + jr z,or_6 + fail_msg 5 +or_6: ld b,data_55 + or a,b + jr nz,or_7 + fail_msg 6 +or_7: cp data_55 + jr z,or_8 + fail_msg 7 +or_8: ld a,data_ff + add a,1 + jr c,or_9 + fail_msg 8 +or_9: ld b,data_7f + or a,b + jr nc,or_10 + fail_msg 9 +or_10: cp data_7f + jr z,or_11 + fail_msg 10 +or_11: ld a,0 + ld c,data_55 + or a,c + cp data_55 + jr z,or_12 + fail_msg 11 +or_12: ld c,data_aa + or a,c + cp data_ff + jr z,or_13 + fail_msg 12 +or_13: ld a,0 + ld d,data_aa + or a,d + cp data_aa + jr z,or_14 + fail_msg 13 +or_14: ld e,data_55 + or a,e + cp data_ff + jr z,or_15 + fail_msg 14 +or_15: ld a,0 + ld h,data_80 + or a,h + cp data_80 + jr z,or_16 + fail_msg 15 +or_16: ld l,data_7f + or a,l + cp data_ff + jr z,or_17 + fail_msg 16 +or_17: ld a,0 + or a,data_7f + jp p,or_18 + fail_msg 17 +or_18: jp po,or_19 + fail_msg 18 +or_19: or a,data_80 + jp m,or_20 + fail_msg 19 +or_20: jp pe,or_21 + fail_msg 20 +or_21: cp data_ff + jr z,or_22 + fail_msg 21 +or_22: ld a,0 + or a,0 + jr z,or_23 + fail_msg 22 +or_23: or a,data_7f + jr nz,or_24 + fail_msg 23 +or_24: ld a,data_ff + add a,1 + jr c,or_25 + fail_msg 24 +or_25: or a,data_55 + jr nc,or_26 + fail_msg 25 +or_26: cp data_55 + jr z,or_27 + fail_msg 26 +or_27: ld hl,var5 + ld a,0 + or a,(hl) + jp p,or_28 + fail_msg 27 +or_28: jp po,or_29 + fail_msg 28 +or_29: ld hl,var3 + or a,(hl) + jp m,or_30 + fail_msg 29 +or_30: jp pe,or_31 + fail_msg 30 +or_31: cp data_ff + jr z,or_32 + fail_msg 31 +or_32: ld hl,t_var1 + ld a,0 + ld (hl),a + or a,(hl) + jr z,or_33 + fail_msg 32 +or_33: ld hl,var2 + or a,(hl) + jr nz,or_34 + fail_msg 33 +or_34: cp data_55 + jr z,or_35 + fail_msg 34 +or_35: ld ix,var3 + ld a,0 + or a,(ix+2) + jp p,or_36 + fail_msg 35 +or_36: jp po,or_37 + fail_msg 36 +or_37: or a,(ix+0) + jp m,or_38 + fail_msg 37 +or_38: jp pe,or_39 + fail_msg 38 +or_39: cp data_ff + jr z,or_40 + fail_msg 39 +or_40: ld ix,t_var3 + ld a,0 + ld (ix-2),a + or a,(ix-2) + jr z,or_41 + fail_msg 40 +or_41: ld (ix+2),data_aa + or a,(ix+2) + jr nz,or_42 + fail_msg 41 +or_42: cp data_aa + jr z,or_43 + fail_msg 42 +or_43: ld iy,var3 + ld a,0 + or a,(iy+2) + jp p,or_44 + fail_msg 43 +or_44: jp po,or_45 + fail_msg 44 +or_45: or a,(iy+0) + jp m,or_46 + fail_msg 45 +or_46: jp pe,or_47 + fail_msg 46 +or_47: cp data_ff + jr z,or_48 + fail_msg 47 +or_48: ld iy,t_var3 + ld a,0 + ld (iy-2),a + or a,(iy-2) + jr z,or_49 + fail_msg 48 +or_49: ld (iy+2),data_55 + or a,(iy+2) + jr nz,or_50 + fail_msg 49 +or_50: cp data_55 + jr z,xor_0 + fail_msg 50 +xor_0: nop + print "xor_0" + ld a,data_ff + ld b,data_55 + xor a,b + jp m,xor_1 + fail_msg 0 +xor_1: jp pe,xor_2 + fail_msg 1 +xor_2: ld b,data_80 + xor a,b + jp p,xor_3 + fail_msg 2 +xor_3: jp po,xor_4 + fail_msg 3 +xor_4: cp #2a + jr z,xor_5 + fail_msg 4 +xor_5: ld a,data_ff + ld b,data_ff + xor a,b + jr z,xor_6 + fail_msg 5 +xor_6: ld b,data_55 + xor a,b + jr nz,xor_7 + fail_msg 6 +xor_7: cp data_55 + jr z,xor_8 + fail_msg 7 +xor_8: ld a,data_ff + add a,1 + jr c,xor_9 + fail_msg 8 +xor_9: ld b,data_aa + xor a,b + jr nc,xor_10 + fail_msg 9 +xor_10: cp data_aa + jr z,xor_11 + fail_msg 10 +xor_11: ld a,data_ff + ld c,data_7f + xor a,c + jp m,xor_12 + fail_msg 11 +xor_12: cp data_80 + jr z,xor_13 + fail_msg 12 +xor_13: ld a,data_ff + ld d,data_55 + xor a,d + jp m,xor_14 + fail_msg 13 +xor_14: cp data_aa + jr z,xor_15 + fail_msg 14 +xor_15: ld e,data_55 + xor a,e + jp m,xor_16 + fail_msg 15 +xor_16: cp data_ff + jr z,xor_17 + fail_msg 16 +xor_17: ld a,data_ff + ld h,data_7f + xor a,h + jp po,xor_18 + fail_msg 17 +xor_18: ld l,data_7f + xor a,l + jp pe,xor_19 + fail_msg 18 +xor_19: cp data_ff + jr z,xor_20 + fail_msg 19 +xor_20: ld a,data_ff + add a,1 + jr c,xor_21 + fail_msg 20 +xor_21: ld b,data_7f + xor a,b + jr nc,xor_22 + fail_msg 21 +xor_22: cp data_7f + jr z,xor_23 + fail_msg 22 +xor_23: ld a,data_ff + xor a,data_7f + jp po,xor_24 + fail_msg 23 +xor_24: jp m,xor_25 + fail_msg 24 +xor_25: xor a,data_7f + jp pe,xor_26 + fail_msg 25 +xor_26: jp m,xor_27 + fail_msg 26 +xor_27: xor a,data_aa + jp p,xor_28 + fail_msg 27 +xor_28: cp data_55 + jr z,xor_29 + fail_msg 28 +xor_29: ld a,data_ff + xor a,data_ff + jr z,xor_30 + fail_msg 29 +xor_30: xor a,data_80 + jr nz,xor_31 + fail_msg 30 +xor_31: cp data_80 + jr z,xor_32 + fail_msg 31 +xor_32: ld hl,var5 + ld a,data_ff + xor a,(hl) + jp m,xor_33 + fail_msg 32 +xor_33: jp po,xor_34 + fail_msg 33 +xor_34: xor a,(hl) + jp m,xor_35 + fail_msg 34 +xor_35: jp pe,xor_36 + fail_msg 35 +xor_36: ld hl,var3 + xor a,(hl) + jp p,xor_37 + fail_msg 36 +xor_37: cp data_7f + jr z,xor_38 + fail_msg 37 +xor_38: ld hl,var1 + ld a,data_ff + xor a,(hl) + jr z,xor_39 + fail_msg 38 +xor_39: ld hl,var2 + xor a,(hl) + jr nz,xor_40 + fail_msg 39 +xor_40: cp data_55 + jr z,xor_41 + fail_msg 40 +xor_41: ld ix,var3 + ld a,data_ff + xor a,(ix+2) + jp m,xor_42 + fail_msg 41 +xor_42: jp po,xor_43 + fail_msg 42 +xor_43: xor a,(ix+2) + jp m,xor_44 + fail_msg 43 +xor_44: jp pe,xor_45 + fail_msg 44 +xor_45: xor a,(ix+1) + jp p,xor_46 + fail_msg 45 +xor_46: cp data_55 + jr z,xor_47 + fail_msg 46 +xor_47: ld a,data_ff + xor a,(ix-2) + jr z,xor_48 + fail_msg 47 +xor_48: xor a,(ix+1) + jr nz,xor_49 + fail_msg 48 +xor_49: cp data_aa + jr z,xor_50 + fail_msg 49 +xor_50: ld iy,var3 + ld a,data_ff + xor a,(iy+2) + jp m,xor_51 + fail_msg 50 +xor_51: jp po,xor_52 + fail_msg 51 +xor_52: xor a,(iy+2) + jp m,xor_53 + fail_msg 52 +xor_53: jp pe,xor_54 + fail_msg 53 +xor_54: xor a,(iy+1) + jp p,xor_55 + fail_msg 54 +xor_55: cp data_55 + jr z,xor_56 + fail_msg 55 +xor_56: ld a,data_ff + xor a,(iy-2) + jr z,xor_57 + fail_msg 56 +xor_57: xor a,(iy-1) + jr nz,xor_58 + fail_msg 57 +xor_58: cp data_55 + jr z,cp_0 + fail_msg 58 +cp_0: nop + print "cp_0" + ld a,0 + ld b,0 + cp a,b + jr z,cp_1 + fail_msg 0 +cp_1: jp p,cp_2 + fail_msg 1 +cp_2: jr nc,cp_3 + fail_msg 2 +cp_3: ld b,data_55 + cp a,b + jr nz,cp_4 + fail_msg 3 +cp_4: jp m,cp_5 + fail_msg 4 +cp_5: jr c,cp_6 + fail_msg 5 +cp_6: ld a,data_80 + ld b,data_7f + cp a,b + jp pe,cp_7 + fail_msg 6 +cp_7: jr nc,cp_8 + fail_msg 7 +cp_8: ld a,data_7f + ld b,data_80 + cp a,b + jp pe,cp_9 + fail_msg 8 +cp_9: jr c,cp_10 + fail_msg 9 +cp_10: ld b,0 + cp a,b + jp po,cp_11 + fail_msg 10 +cp_11: jr nc,cp_12 + fail_msg 11 +cp_12: ld a,data_80 + ld c,0 + cp a,c + jp m,cp_13 + fail_msg 12 +cp_13: ld c,data_80 + cp a,c + jr z,cp_14 + fail_msg 13 +cp_14: ld a,data_7f + ld d,data_55 + cp a,d + jp p,cp_15 + fail_msg 14 +cp_15: jr nz,cp_16 + fail_msg 15 +cp_16: ld e,data_7f + cp a,e + jr z,cp_17 + fail_msg 16 +cp_17: ld a,data_80 + ld h,data_ff + cp a,h + jp m,cp_18 + fail_msg 17 +cp_18: jr c,cp_19 + fail_msg 18 +cp_19: ld l,data_80 + cp a,l + jr z,cp_20 + fail_msg 19 +cp_20: ld a,data_80 + cp a,data_7f + jp p,cp_21 + fail_msg 20 +cp_21: jp pe,cp_22 + fail_msg 21 +cp_22: jr nz,cp_23 + fail_msg 22 +cp_23: cp a,data_80 + jp p,cp_24 + fail_msg 23 +cp_24: jp po,cp_25 + fail_msg 24 +cp_25: jr z,cp_26 + fail_msg 25 +cp_26: ld a,data_55 + cp a,data_7f + jr c,cp_27 + fail_msg 26 +cp_27: jp m,cp_28 + fail_msg 27 +cp_28: cp a,data_55 + jr nc,cp_29 + fail_msg 28 +cp_29: jr z,cp_30 + fail_msg 29 +cp_30: ld a,data_80 + ld hl,var5 + cp a,(hl) + jp p,cp_31 + fail_msg 30 +cp_31: jp pe,cp_32 + fail_msg 31 +cp_32: jr nz,cp_33 + fail_msg 32 +cp_33: ld hl,var3 + cp a,(hl) + jp p,cp_34 + fail_msg 33 +cp_34: jp po,cp_35 + fail_msg 34 +cp_35: jr z,cp_36 + fail_msg 35 +cp_36: ld a,data_55 + ld hl,var5 + cp a,(hl) + jr c,cp_37 + fail_msg 36 +cp_37: jp m,cp_38 + fail_msg 37 +cp_38: ld hl,var2 + cp a,(hl) + jr nc,cp_39 + fail_msg 38 +cp_39: jp p,cp_40 + fail_msg 39 +cp_40: jr z,cp_41 + fail_msg 40 +cp_41: ld a,data_80 + ld ix,var3 + cp a,(ix+2) + jp p,cp_42 + fail_msg 41 +cp_42: jp pe,cp_43 + fail_msg 42 +cp_43: jr nz,cp_44 + fail_msg 43 +cp_44: cp a,(ix+0) + jp p,cp_45 + fail_msg 44 +cp_45: jp po,cp_46 + fail_msg 45 +cp_46: jr z,cp_47 + fail_msg 46 +cp_47: ld a,data_55 + cp a,(ix-2) + jr nz,cp_48 + fail_msg 47 +cp_48: jr c,cp_49 + fail_msg 48 +cp_49: cp a,(ix-1) + jr z,cp_50 + fail_msg 49 +cp_50: jr nc,cp_51 + fail_msg 50 +cp_51: ld iy,var3 + ld a,data_80 + cp a,(iy+2) + jp p,cp_52 + fail_msg 51 +cp_52: jp pe,cp_53 + fail_msg 52 +cp_53: jr nz,cp_54 + fail_msg 53 +cp_54: cp a,(iy+0) + jp p,cp_55 + fail_msg 54 +cp_55: jp po,cp_56 + fail_msg 55 +cp_56: jr z,cp_57 + fail_msg 56 +cp_57: ld a,data_55 + cp a,(iy-2) + jr nz,cp_58 + fail_msg 57 +cp_58: jr c,cp_59 + fail_msg 58 +cp_59: cp a,(iy-1) + jr z,cp_60 + fail_msg 59 +cp_60: jr nc,inc_0 + fail_msg 60 +inc_0: nop + print "inc" + ld a,data_7f + cp a,data_7f + jr z,inc_1 + fail_msg 0 +inc_1: inc a + jp pe,inc_2 + fail_msg 1 +inc_2: jp m,inc_3 + fail_msg 2 +inc_3: jr nz,inc_4 + fail_msg 3 +inc_4: ld a,data_55 + inc a + jp po,inc_5 + fail_msg 4 +inc_5: jp p,inc_6 + fail_msg 5 +inc_6: cp a,data_55+1 + jr z,inc_7 + fail_msg 6 +inc_7: ld a,data_ff-1 + inc a + jr nz,inc_8 + fail_msg 7 +inc_8: jp m,inc_9 + fail_msg 8 +inc_9: inc a + jr z,inc_10 + fail_msg 9 +inc_10: ld b,data_aa + inc b + jp m,inc_11 + fail_msg 10 +inc_11: ld a,b + cp a,data_aa+1 + jr z,inc_12 + fail_msg 11 +inc_12: ld c,data_80 + inc c + jp m,inc_13 + fail_msg 12 +inc_13: ld a,c + cp a,data_80+1 + jr z,inc_14 + fail_msg 13 +inc_14: ld d,data_ff + inc d + jr z,inc_15 + fail_msg 14 +inc_15: ld e,data_55 + inc e + jp p,inc_16 + fail_msg 15 +inc_16: ld a,e + cp a,data_55+1 + jr z,inc_17 + fail_msg 16 +inc_17: ld h,data_7f + inc h + jp pe,inc_18 + fail_msg 17 +inc_18: ld a,h + cp a,data_80 + jr z,inc_19 + fail_msg 18 +inc_19: ld l,data_aa + inc l + jp m,inc_20 + fail_msg 19 +inc_20: ld a,l + cp a,data_aa+1 + jr z,inc_21 + fail_msg 20 +inc_21: ld hl,t_var1 + ld a,data_7f + ld (hl),a + cp a,(hl) + jr z,inc_22 + fail_msg 21 +inc_22: inc (hl) + jp m,inc_23 + fail_msg 22 +inc_23: jp pe,inc_24 + fail_msg 23 +inc_24: ld a,data_55 + ld (hl),a + inc (hl) + jp p,inc_25 + fail_msg 24 +inc_25: jp po,inc_26 + fail_msg 25 +inc_26: ld a,(hl) + cp a,data_55+1 + jr z,inc_27 + fail_msg 26 +inc_27: ld a,data_ff + ld (hl),a + inc (hl) + jr z,inc_28 + fail_msg 27 +inc_28: inc (hl) + jr nz,inc_29 + fail_msg 28 +inc_29: ld a,(hl) + cp a,1 + jr z,inc_30 + fail_msg 29 +inc_30: ld a,data_aa + ld (hl),a + inc (hl) + jp m,inc_31 + fail_msg 30 +inc_31: ld a,(hl) + cp a,data_aa+1 + jr z,inc_32 + fail_msg 31 +inc_32: ld ix,t_var3 + ld a,data_7f + ld (ix-2),a + cp a,data_7f + jr z,inc_33 + fail_msg 32 +inc_33: inc (ix-2) + jp m,inc_34 + fail_msg 33 +inc_34: jp pe,inc_35 + fail_msg 34 +inc_35: ld a,data_55 + ld (ix+2),a + inc (ix+2) + jp p,inc_36 + fail_msg 35 +inc_36: jp po,inc_37 + fail_msg 36 +inc_37: ld a,(ix+2) + cp a,data_55+1 + jr z,inc_38 + fail_msg 37 +inc_38: ld a,data_ff + ld (ix-1),a + inc (ix-1) + jr z,inc_39 + fail_msg 38 +inc_39: inc (ix-1) + jr nz,inc_40 + fail_msg 39 +inc_40: ld a,(ix-1) + cp a,1 + jr z,inc_41 + fail_msg 40 +inc_41: ld a,data_aa + ld (ix+1),a + inc (ix+1) + jp m,inc_42 + fail_msg 41 +inc_42: ld a,(ix+1) + cp a,data_aa+1 + jr z,inc_43 + fail_msg 42 +inc_43: ld iy,t_var3 + ld a,data_7f + ld (iy+2),a + cp a,data_7f + jr z,inc_44 + fail_msg 43 +inc_44: inc (iy+2) + jp m,inc_45 + fail_msg 44 +inc_45: jp pe,inc_46 + fail_msg 45 +inc_46: ld a,data_55 + ld (iy-2),a + inc (iy-2) + jp p,inc_47 + fail_msg 46 +inc_47: jp po,inc_48 + fail_msg 47 +inc_48: ld a,(iy-2) + cp a,data_55+1 + jr z,inc_49 + fail_msg 48 +inc_49: ld a,data_ff + ld (iy+1),a + inc (iy+1) + jr z,inc_50 + fail_msg 49 +inc_50: inc (iy+1) + jr nz,inc_51 + fail_msg 50 +inc_51: ld a,(iy+1) + cp a,1 + jr z,inc_52 + fail_msg 51 +inc_52: ld a,data_80 + ld (iy-1),a + inc (iy-1) + jp m,inc_53 + fail_msg 52 +inc_53: ld a,(iy-1) + cp a,data_80+1 + jr z,dec_0 + fail_msg 53 +dec_0: nop + print "dec" + ld a,data_80 + cp a,data_80 + jr z,dec_1 + fail_msg 0 +dec_1: dec a + jp p,dec_2 + fail_msg 1 +dec_2: jp pe,dec_3 + fail_msg 2 +dec_3: ld a,0 + dec a + jp m,dec_4 + fail_msg 3 +dec_4: jp po,dec_5 + fail_msg 4 +dec_5: cp a,data_ff + jr z,dec_6 + fail_msg 5 +dec_6: ld a,1 + dec a + jr z,dec_7 + fail_msg 6 +dec_7: dec a + jr nz,dec_8 + fail_msg 7 +dec_8: cp a,data_ff + jr z,dec_9 + fail_msg 8 +dec_9: ld a,data_aa + dec a + cp a,data_aa-1 + jr z,dec_10 + fail_msg 9 +dec_10: ld b,data_7f + dec b + ld a,b + cp a,data_7f-1 + jr z,dec_11 + fail_msg 10 +dec_11: ld c,data_55 + dec c + ld a,c + cp a,data_55-1 + jr z,dec_12 + fail_msg 11 +dec_12: ld d,data_aa + dec d + ld a,d + cp a,data_aa-1 + jr z,dec_13 + fail_msg 12 +dec_13: ld e,data_80 + dec e + ld a,e + cp a,data_80-1 + jr z,dec_14 + fail_msg 13 +dec_14: ld h,data_ff + dec h + ld a,h + cp a,data_ff-1 + jr z,dec_15 + fail_msg 14 +dec_15: ld l,data_55 + dec l + ld a,l + cp a,data_55-1 + jr z,dec_16 + fail_msg 15 +dec_16: ld hl,t_var5 + ld a,data_80 + ld (hl),a + cp a,(hl) + jr z,dec_17 + fail_msg 16 +dec_17: dec (hl) + jp p,dec_18 + fail_msg 17 +dec_18: jp pe,dec_19 + fail_msg 18 +dec_19: ld a,0 + ld (hl),a + dec (hl) + jp m,dec_20 + fail_msg 19 +dec_20: jp po,dec_21 + fail_msg 20 +dec_21: ld a,(hl) + cp a,data_ff + jr z,dec_22 + fail_msg 21 +dec_22: ld a,1 + ld (hl),a + dec (hl) + jr z,dec_23 + fail_msg 22 +dec_23: dec (hl) + jr nz,dec_24 + fail_msg 23 +dec_24: ld a,(hl) + cp a,data_ff + jr z,dec_25 + fail_msg 24 +dec_25: ld a,data_aa + ld (hl),a + dec (hl) + ld a,(hl) + cp a,data_aa-1 + jr z,dec_26 + fail_msg 25 +dec_26: ld ix,t_var3 + ld a,data_80 + ld (ix-2),a + cp a,(ix-2) + jr z,dec_27 + fail_msg 26 +dec_27: dec (ix-2) + jp p,dec_28 + fail_msg 27 +dec_28: jp pe,dec_29 + fail_msg 28 +dec_29: ld a,0 + ld (ix+2),a + dec (ix+2) + jp m,dec_30 + fail_msg 29 +dec_30: jp po,dec_31 + fail_msg 30 +dec_31: ld a,(ix+2) + cp a,data_ff + jr z,dec_32 + fail_msg 31 +dec_32: ld a,1 + ld (ix-1),a + dec (ix-1) + jr z,dec_33 + fail_msg 32 +dec_33: dec (ix-1) + jr nz,dec_34 + fail_msg 33 +dec_34: ld a,(ix-1) + cp a,data_ff + jr z,dec_35 + fail_msg 34 +dec_35: ld a,data_7f + ld (ix+1),a + dec (ix+1) + ld a,(ix+1) + cp a,data_7f-1 + jr z,dec_36 + fail_msg 35 +dec_36: ld iy,t_var3 + ld a,data_80 + ld (iy-2),a + cp a,(iy-2) + jr z,dec_37 + fail_msg 36 +dec_37: dec (iy-2) + jp p,dec_38 + fail_msg 37 +dec_38: jp pe,dec_39 + fail_msg 38 +dec_39: ld a,0 + ld (iy+2),a + dec (iy+2) + jp m,dec_40 + fail_msg 39 +dec_40: jp po,dec_41 + fail_msg 40 +dec_41: ld a,(iy+2) + cp a,data_ff + jr z,dec_42 + fail_msg 41 +dec_42: ld a,1 + ld (iy+1),a + dec (iy+1) + jr z,dec_43 + fail_msg 42 +dec_43: dec (iy+1) + jr nz,dec_44 + fail_msg 43 +dec_44: ld a,(iy+1) + cp a,data_ff + jr z,dec_45 + fail_msg 44 +dec_45: ld a,data_aa + ld (iy-1),a + dec (iy-1) + ld a,(iy-1) + cp a,data_aa-1 + jr z,cpl_0 + fail_msg 45 +cpl_0: ld a,data_ff + cpl + cp a,0 + jr z,cpl_1 + fail_msg 0 +cpl_1: ld a,data_aa + cpl + cp a,data_55 + jr z,cpl_2 + fail_msg 1 +cpl_2: cpl + cp a,data_aa + jr z,neg_0 + fail_msg 2 +neg_0: nop + print "neg" + ld a,data_80 + cp a,data_80 + jp po,neg_1 + fail_msg 0 +neg_1: neg + jp pe,neg_2 + fail_msg 1 +neg_2: jr nz,neg_3 + fail_msg 2 +neg_3: jr c,neg_4 + fail_msg 3 +neg_4: ld a,0 + neg + jp po,neg_5 + fail_msg 4 +neg_5: jr z,neg_6 + fail_msg 5 +neg_6: jr nc,neg_7 + fail_msg 6 +neg_7: ld a,data_55 + cp a,data_55 + jp p,neg_8 + fail_msg 7 +neg_8: neg + jp m,neg_9 + fail_msg 8 +neg_9: neg + jp p,neg_10 + fail_msg 9 +neg_10: cp a,data_55 + jr z,ccf_0 + fail_msg 10 +ccf_0: nop + print "ccf/im" + scf + jr c,ccf_1 + fail_msg 0 +ccf_1: ccf + jr nc,ccf_2 + fail_msg 1 +ccf_2: ccf + jr c,im_0 + fail_msg 2 +im_0: im 0 + im 1 + im 2 +daa_0: nop + print "daa" + ld a,#99 + ld b,#1 + add a,b + daa + jr c,daa_1 + fail_msg 0 +daa_1: jr z,daa_2 + fail_msg 1 +daa_2: add a,b + jr nc,daa_3 + fail_msg 2 +daa_3: jr nz,daa_4 + fail_msg 3 +daa_4: cp a,1 + jr z,daa_5 + fail_msg 4 +daa_5: ld a,#98 + ld b,1 + add a,b + daa + jp m,daa_6 + fail_msg 5 +daa_6: add a,b + daa + jp p,daa_7 + fail_msg 6 +daa_7: ld a,1 + ld b,1 + add a,b + daa + jp po,daa_8 + fail_msg 7 +daa_8: add a,b + daa + jp pe,daa_9 + fail_msg 8 +daa_9: cp a,3 + jr z,add_74 + fail_msg 9 +add_74: nop + print "add" + ld hl,data_1234 + add hl,hl + jr nc,add_75 + fail_msg 74 +add_75: ld a,h + cp a,#24 + jr z,add_76 + fail_msg 75 +add_76: ld a,l + cp a,#68 + jr z,add_77 + fail_msg 76 +add_77: ld hl,data_7fff + ld bc,data_8000 + add hl,bc + jr nc,add_78 + fail_msg 77 +add_78: ld bc,1 + add hl,bc + jr c,add_79 + fail_msg 78 +add_79: ld a,h + cp a,0 + jr z,add_80 + fail_msg 79 +add_80: ld a,l + cp a,0 + jr z,add_81 + fail_msg 80 +add_81: ld hl,data_aa55 + ld de,data_ffff + add hl,de + jr c,add_82 + fail_msg 81 +add_82: ld a,h + cp a,data_aa + jr z,add_83 + fail_msg 82 +add_83: ld a,l + cp a,data_55-1 + jr z,add_84 + fail_msg 83 +add_84: ld hl,data_aa55 + ld sp,data_8000 + add hl,sp + jr c,add_85 + fail_msg 84 +add_85: ld a,h + cp a,#2a + jr z,add_86 + fail_msg 85 +add_86: ld a,l + cp a,data_55 + jr z,add_87 + fail_msg 86 +add_87: ld sp,stack_end + ld hl,data_1234 + scf + ccf + adc hl,hl + jr nz,add_88 + fail_msg 87 +add_88: jr nc,add_89 + fail_msg 88 +add_89: jp p,add_90 + fail_msg 89 +add_90: jp po,add_91 + fail_msg 90 +add_91: ld bc,data_8000 + adc hl,bc + jp m,add_92 + fail_msg 91 +add_92: jr nc,add_93 + fail_msg 92 +add_93: jp po,add_94 + fail_msg 93 +add_94: jp nz,add_95 + fail_msg 94 +add_95: adc hl,bc + jp p,add_96 + fail_msg 95 +add_96: jp pe,add_97 + fail_msg 96 +add_97: jr c,add_98 + fail_msg 97 +add_98: jr nz,add_99 + fail_msg 98 +add_99: ld de,#db97 + adc hl,de + jr z,add_100 + fail_msg 99 +add_100: jr c,add_101 + fail_msg 100 +add_101: jp po,add_102 + fail_msg 101 +add_102: ld de,0 + adc hl,de + jr nc,add_103 + fail_msg 102 +add_103: jr nz,add_104 + fail_msg 103 +add_104: ld a,h + cp a,0 + jr z,add_105 + fail_msg 104 +add_105: ld a,l + cp a,1 + jr z,add_106 + fail_msg 105 +add_106: ld hl,data_1234 + ld sp,data_ffff + adc hl,sp + jr c,add_107 + fail_msg 106 +add_107: ld a,h + cp a,#12 + jr z,add_108 + fail_msg 107 +add_108: ld a,l + cp a,#33 + jr z,sbc_66 + fail_msg 108 +sbc_66: ld sp,stack_end + print "sbc" + scf + ccf + ld hl,data_1234 + sbc hl,hl + jr z,sbc_67 + fail_msg 66 +sbc_67: jp p,sbc_68 + fail_msg 67 +sbc_68: jp po,sbc_69 + fail_msg 68 +sbc_69: jr nc,sbc_70 + fail_msg 69 +sbc_70: ld bc,data_1234 + sbc hl,bc + jr nz,sbc_71 + fail_msg 70 +sbc_71: jr c,sbc_72 + fail_msg 71 +sbc_72: jp m,sbc_73 + fail_msg 72 +sbc_73: jp po,sbc_74 + fail_msg 73 +sbc_74: ld de,data_7fff + sbc hl,de + jr nz,sbc_75 + fail_msg 74 +sbc_75: jr nc,sbc_76 + fail_msg 75 +sbc_76: jp p,sbc_77 + fail_msg 76 +sbc_77: jp pe,sbc_78 + fail_msg 77 +sbc_78: ld sp,data_1234 + sbc hl,sp + jr nz,sbc_79 + fail_msg 78 +sbc_79: ld a,h + cp a,#5b + jr z,sbc_80 + fail_msg 79 +sbc_80: ld a,l + cp a,#98 + jr z,add_109 + fail_msg 80 +add_109: ld sp,stack_end + print "add" + ld ix,0 + add ix,sp + jr nc,add_110 + fail_msg 109 +add_110: push ix + pop hl + ld a,h + cp a,stack_end_hi ; >stack_end + jr z,add_111 + fail_msg 110 +add_111: ld a,l + cp a,stack_end_lo ; (data_1234+data_1234) + jr z,add_117 + fail_msg 116 +add_117: ld a,l + cp a,#68 ;<(data_1234+data_1234) + jr z,add_118 + fail_msg 117 +add_118: ld ix,data_1234 + add ix,ix + push ix + pop bc + ld a,b + cp a,#24 ;>(data_1234+data_1234) + jr z,add_119 + fail_msg 118 +add_119: ld a,c + cp a,#68 ;<(data_1234+data_1234) + jr z,add_120 + fail_msg 119 +add_120: ld sp,stack_end + ld iy,0 + add iy,sp + jr nc,add_121 + fail_msg 120 +add_121: push iy + pop hl + ld a,h + cp a,stack_end_hi ;>stack_end + jr z,add_122 + fail_msg 121 +add_122: ld a,l + cp a,stack_end_lo ;(data_1234+data_1234) + jr z,add_128 + fail_msg 127 +add_128: ld a,l + cp a,#68 ;<(data_1234+data_1234) + jr z,add_129 + fail_msg 128 +add_129: ld iy,data_1234 + add iy,iy + push iy + pop bc + ld a,b + cp a,#24 ;>(data_1234+data_1234) + jr z,add_130 + fail_msg 129 +add_130: ld a,c + cp a,#68 ;<(data_1234+data_1234) + jr z,inc_54 + fail_msg 130 +inc_54: ld sp,stack_end + print "inc" + ld bc,data_1234 + inc bc + ld a,b + cp a,#12 ;bjp was >data_1234 + jr z,inc_55 + fail_msg 54 +inc_55: ld a,c + cp a,#34+1 ;bjp was >data_1234+1 + jr z,inc_56 + fail_msg 55 +inc_56: ld de,data_55aa + inc de + ld a,d + cp a,#55 ;>data_55aa + jr z,inc_57 + fail_msg 56 +inc_57: ld a,e + cp a,#ab ;data_7fff+1 + jr z,inc_59 + fail_msg 58 +inc_59: ld a,l + cp a,#00 ;stack_end+1 + jr z,inc_61 + fail_msg 60 +inc_61: ld a,l + cp a,stack_end_lo+1 ;data_8000 + jr z,inc_63 + fail_msg 62 +inc_63: ld a,e + cp a,#01 ;data_7fff+1 + jr z,inc_65 + fail_msg 64 +inc_65: ld a,c + cp a,#00 ;data_1234 + jr z,dec_47 + fail_msg 46 +dec_47: ld a,c + cp a,#34-1 ;bjp was >data_1234-1 + jr z,dec_48 + fail_msg 47 +dec_48: ld de,data_8000 + dec de + ld a,d + cp a,#7f ;>data_7fff + jr z,dec_49 + fail_msg 48 +dec_49: ld a,e + cp a,#ff ;data_aa55 + jr z,dec_51 + fail_msg 50 +dec_51: ld a,l + cp a,#54 ;stack_end-1 + jr z,dec_53 + fail_msg 52 +dec_53: ld a,l + cp a,stack_end_lo-1 ;data_ffff + jr z,dec_55 + fail_msg 54 +dec_55: ld a,c + cp a,#fe ;data_aa55 + jr z,dec_57 + fail_msg 56 +dec_57: ld a,e + cp a,#54 ;data_1234 + ld l,#34 ;bjp was >data_1234 + sla h + jp p,sla_18 + fail_msg 17 +sla_18: ld a,h + cp a,#24 + jr z,sla_19 + fail_msg 18 +sla_19: sla l + jp p,sla_20 + fail_msg 19 +sla_20: ld a,l + cp a,#68 + jr z,sla_21 + fail_msg 20 +sla_21: ld hl,t_var3 + ld (hl),data_55 + sla (hl) + jp m,sla_22 + fail_msg 21 +sla_22: jp pe,sla_23 + fail_msg 22 +sla_23: jr nc,sla_24 + fail_msg 23 +sla_24: jr nz,sla_25 + fail_msg 24 +sla_25: sla (hl) + jp p,sla_26 + fail_msg 25 +sla_26: jp po,sla_27 + fail_msg 26 +sla_27: jr c,sla_28 + fail_msg 27 +sla_28: ld a,(hl) + cp a,data_55-1 + jr z,sla_29 + fail_msg 28 +sla_29: ld (hl),0 + sla (hl) + jr z,sla_30 + fail_msg 29 +sla_30: ld ix,t_var3 + ld a,data_55 + ld (ix-2),a + sla (ix-2) + jp m,sla_31 + fail_msg 30 +sla_31: jp pe,sla_32 + fail_msg 31 +sla_32: jr nc,sla_33 + fail_msg 32 +sla_33: jr nz,sla_34 + fail_msg 33 +sla_34: sla (ix-2) + jp p,sla_35 + fail_msg 34 +sla_35: jp po,sla_36 + fail_msg 35 +sla_36: jr c,sla_37 + fail_msg 36 +sla_37: ld a,(ix-2) + cp a,data_55-1 + jr z,sla_38 + fail_msg 37 +sla_38: ld a,data_80 + ld (ix+2),a + sla (ix+2) + jr z,sla_39 + fail_msg 38 +sla_39: jr c,sla_40 + fail_msg 39 +sla_40: ld iy,t_var3 + ld a,data_55 + ld (iy+2),a + sla (iy+2) + jp m,sla_41 + fail_msg 40 +sla_41: jp pe,sla_42 + fail_msg 41 +sla_42: jr nc,sla_43 + fail_msg 42 +sla_43: jr nz,sla_44 + fail_msg 43 +sla_44: sla (iy+2) + jp p,sla_45 + fail_msg 44 +sla_45: jp po,sla_46 + fail_msg 45 +sla_46: jr c,sla_47 + fail_msg 46 +sla_47: ld a,(iy+2) + cp a,data_55-1 + jr z,sla_48 + fail_msg 47 +sla_48: ld a,data_80 + ld (iy-2),a + sla (iy-2) + jr z,sla_49 + fail_msg 48 +sla_49: jr c,sra_0 + fail_msg 49 +sra_0: nop + print "sra" + ld a,data_55 + sra a + jp p,sra_1 + fail_msg 0 +sra_1: jp po,sra_2 + fail_msg 1 +sra_2: jr c,sra_3 + fail_msg 2 +sra_3: jr nz,sra_4 + fail_msg 3 +sra_4: sra a + jp po,sra_5 + fail_msg 4 +sra_5: jr nc,sra_6 + fail_msg 5 +sra_6: sra a + jp pe,sra_7 + fail_msg 6 +sra_7: cp a,#0a ;data_aa.and.#0f + jr z,sra_8 + fail_msg 7 +sra_8: ld a,1 + sra a + jr c,sra_9 + fail_msg 8 +sra_9: jr z,sra_10 + fail_msg 9 +sra_10: ld a,data_80 + sra a + jp m,sra_11 + fail_msg 10 +sra_11: cp a,#c0 + jr z,sra_12 + fail_msg 11 +sra_12: ld b,data_7f + ld c,data_aa + sra b + jr c,sra_13 + fail_msg 12 +sra_13: ld a,b + cp a,#3f + jr z,sra_14 + fail_msg 13 +sra_14: sra c + jr nc,sra_15 + fail_msg 14 +sra_15: ld a,c + cp a,#d5 + jr z,sra_16 + fail_msg 15 +sra_16: ld d,data_55 + ld e,data_ff + sra d + jr c,sra_17 + fail_msg 16 +sra_17: ld a,d + cp a,#2a + jr z,sra_18 + fail_msg 17 +sra_18: sra e + jp m,sra_19 + fail_msg 18 +sra_19: ld a,e + cp a,data_ff + jr z,sra_20 + fail_msg 19 +sra_20: ld h,data_aa + ld l,data_7f + sra h + jp m,sra_21 + fail_msg 20 +sra_21: ld a,h + cp a,#d5 + jr z,sra_22 + fail_msg 21 +sra_22: sra l + jr c,sra_23 + fail_msg 22 +sra_23: ld a,l + cp a,#3f + jr z,sra_24 + fail_msg 23 +sra_24: ld hl,t_var1 + ld (hl),data_55 + sra (hl) + jp p,sra_25 + fail_msg 24 +sra_25: jp po,sra_26 + fail_msg 25 +sra_26: jr c,sra_27 + fail_msg 26 +sra_27: jr nz,sra_28 + fail_msg 27 +sra_28: sra (hl) + jr nc,sra_29 + fail_msg 28 +sra_29: sra (hl) + jp pe,sra_30 + fail_msg 29 +sra_30: ld a,(hl) + cp a,#0a ;data_aa.and.#0f + jr z,sra_31 + fail_msg 30 +sra_31: ld (hl),data_80 + sra (hl) + jp m,sra_32 + fail_msg 31 +sra_32: ld a,(hl) + cp a,#c0 + jr z,sra_33 + fail_msg 32 +sra_33: ld (hl),1 + sra (hl) + jr c,sra_34 + fail_msg 33 +sra_34: jr z,sra_35 + fail_msg 34 +sra_35: ld ix,t_var3 + ld a,data_55 + ld (ix-2),a + sra (ix-2) + jp p,sra_36 + fail_msg 35 +sra_36: jp po,sra_37 + fail_msg 36 +sra_37: jr c,sra_38 + fail_msg 37 +sra_38: jr nz,sra_39 + fail_msg 38 +sra_39: sra (ix-2) + jr nc,sra_40 + fail_msg 39 +sra_40: sra (ix-2) + jp pe,sra_41 + fail_msg 40 +sra_41: ld a,(ix-2) + cp a,#0a ;data_aa.and.#0f + jr z,sra_42 + fail_msg 41 +sra_42: ld a,data_80 + ld (ix+2),a + sra (ix+2) + jp m,sra_43 + fail_msg 42 +sra_43: ld a,(ix+2) + cp a,#c0 + jr z,sra_44 + fail_msg 43 +sra_44: ld a,1 + ld (ix-1),a + sra (ix-1) + jr c,sra_45 + fail_msg 44 +sra_45: jr z,sra_46 + fail_msg 45 +sra_46: ld iy,t_var3 + ld a,data_55 + ld (iy-2),a + sra (iy-2) + jp p,sra_47 + fail_msg 46 +sra_47: jp po,sra_48 + fail_msg 47 +sra_48: jr c,sra_49 + fail_msg 48 +sra_49: jr nz,sra_50 + fail_msg 49 +sra_50: sra (iy-2) + jr nc,sra_51 + fail_msg 50 +sra_51: sra (iy-2) + jp pe,sra_52 + fail_msg 51 +sra_52: ld a,(iy-2) + cp a,#0a ;data_aa.and.#0f + jr z,sra_53 + fail_msg 52 +sra_53: ld a,data_80 + ld (iy+2),a + sra (iy+2) + jp m,sra_54 + fail_msg 53 +sra_54: ld a,(iy+2) + cp a,#c0 + jr z,sra_55 + fail_msg 54 +sra_55: ld a,1 + ld (iy-1),a + sra (iy-1) + jr c,sra_56 + fail_msg 55 +sra_56: jr z,srl_0 + fail_msg 56 +srl_0: nop + print "srl" + ld a,data_55 + srl a + jr c,srl_1 + fail_msg 0 +srl_1: jp po,srl_2 + fail_msg 1 +srl_2: srl a + jr nc,srl_3 + fail_msg 2 +srl_3: srl a + jp pe,srl_4 + fail_msg 3 +srl_4: cp a,#0a ;data_aa.and.#0f + jr z,srl_5 + fail_msg 4 +srl_5: ld a,data_80 + and a + jp m,srl_6 + fail_msg 5 +srl_6: srl a + jp p,srl_7 + fail_msg 6 +srl_7: ld a,2 + srl a + jr nz,srl_8 + fail_msg 7 +srl_8: srl a + jr z,srl_9 + fail_msg 8 +srl_9: jr c,srl_10 + fail_msg 9 +srl_10: ld b,data_aa + srl b + jp p,srl_11 + fail_msg 10 +srl_11: ld a,b + cp a,data_55 + jr z,srl_12 + fail_msg 11 +srl_12: ld c,data_7f + srl c + jr c,srl_13 + fail_msg 12 +srl_13: ld a,c + cp a,#3f + jr z,srl_14 + fail_msg 13 +srl_14: ld d,data_55 + srl d + jr c,srl_15 + fail_msg 14 +srl_15: ld a,d + cp a,#2a + jr z,srl_16 + fail_msg 15 +srl_16: ld e,data_ff + srl e + jr c,srl_17 + fail_msg 16 +srl_17: ld a,e + cp a,data_7f + jr z,srl_18 + fail_msg 17 +srl_18: ld h,#12 ;bjp was >data_1234 + srl h + jr nc,srl_19 + fail_msg 18 +srl_19: ld a,h + cp a,9 + jr z,srl_20 + fail_msg 19 +srl_20: ld l,#34 ;bjp was >data_1234 + srl l + jr nc,srl_21 + fail_msg 20 +srl_21: ld a,l + cp a,#1a + jr z,srl_22 + fail_msg 21 +srl_22: ld hl,t_var1 + ld (hl),data_55 + srl (hl) + jr c,srl_23 + fail_msg 22 +srl_23: jp po,srl_24 + fail_msg 23 +srl_24: srl (hl) + jr nc,srl_25 + fail_msg 24 +srl_25: srl (hl) + jp pe,srl_26 + fail_msg 25 +srl_26: ld a,(hl) + cp a,#0a ;data_aa.and.#0f + jr z,srl_27 + fail_msg 26 +srl_27: ld (hl),data_80 + and (hl) + jp z,srl_28 + fail_msg 27 +srl_28: srl (hl) + jp p,srl_29 + fail_msg 28 +srl_29: ld a,(hl) + cp a,#40 + jr z,srl_30 + fail_msg 29 +srl_30: ld (hl),2 + srl (hl) + jr nz,srl_31 + fail_msg 30 +srl_31: srl (hl) + jr z,srl_32 + fail_msg 31 +srl_32: jr c,srl_33 + fail_msg 32 +srl_33: ld ix,t_var3 + ld a,data_55 + ld (ix+2),a + srl (ix+2) + jr c,srl_34 + fail_msg 33 +srl_34: jp po,srl_35 + fail_msg 34 +srl_35: srl (ix+2) + jr nc,srl_36 + fail_msg 35 +srl_36: srl (ix+2) + jp pe,srl_37 + fail_msg 36 +srl_37: ld a,(ix+2) + cp a,#0a ;data_aa.and.#0f + jr z,srl_38 + fail_msg 37 +srl_38: ld a,data_80 + ld (ix-2),a + and (ix-2) + jp m,srl_39 + fail_msg 38 +srl_39: srl (ix-2) + jp p,srl_40 + fail_msg 39 +srl_40: ld a,(ix-2) + cp a,#40 + jr z,srl_41 + fail_msg 40 +srl_41: ld a,2 + ld (ix+1),a + srl (ix+1) + jr nz,srl_42 + fail_msg 41 +srl_42: srl (ix+1) + jr z,srl_43 + fail_msg 42 +srl_43: jr c,srl_44 + fail_msg 43 +srl_44: ld iy,t_var3 + ld a,data_55 + ld (iy+2),a + srl (iy+2) + jr c,srl_45 + fail_msg 44 +srl_45: jp po,srl_46 + fail_msg 45 +srl_46: srl (iy+2) + jr nc,srl_47 + fail_msg 46 +srl_47: srl (iy+2) + jp pe,srl_48 + fail_msg 47 +srl_48: ld a,(iy+2) + cp a,#0a ;data_aa.and.#0f + jr z,srl_49 + fail_msg 48 +srl_49: ld a,data_80 + ld (iy-2),a + and (iy-2) + jp m,srl_50 + fail_msg 49 +srl_50: srl (iy-2) + jp p,srl_51 + fail_msg 50 +srl_51: ld a,(iy-2) + cp a,#40 + jr z,srl_52 + fail_msg 51 +srl_52: ld a,2 + ld (iy+1),a + srl (iy+1) + jr nz,srl_53 + fail_msg 52 +srl_53: srl (iy+1) + jr z,srl_54 + fail_msg 53 +srl_54: jr c,rld_0 + fail_msg 54 +rld_0: nop + print "rld/rrd" + ld hl,t_var5 + ld a,data_55 + ld (hl),data_aa + rld + jp p,rld_1 + fail_msg 0 +rld_1: cp a,data_55+5 + jr z,rld_2 + fail_msg 1 +rld_2: ld a,(hl) + cp a,data_aa-5 + jr z,rld_3 + fail_msg 2 +rld_3: ld (hl),data_7f + ld a,data_80 + rld + jp m,rld_4 + fail_msg 3 +rld_4: jp pe,rld_5 + fail_msg 4 +rld_5: rld + jp po,rld_6 + fail_msg 5 +rld_6: cp a,data_80+15 + jr z,rld_7 + fail_msg 6 +rld_7: ld a,(hl) + cp a,7 + jr z,rld_8 + fail_msg 7 +rld_8: ld a,#05 ;data_55.and.#0f + ld (hl),#0a ;data_aa.and.#0f + rld + jr z,rld_9 + fail_msg 8 +rld_9: ld a,(hl) + cp a,#a5 + jr z,rrd_0 + fail_msg 9 +rrd_0: ld hl,t_var3 + ld a,data_55 + ld (hl),data_aa + rrd + jp p,rrd_1 + fail_msg 0 +rrd_1: jp pe,rrd_2 + fail_msg 1 +rrd_2: jr nz,rrd_3 + fail_msg 2 +rrd_3: cp a,data_55+5 + jr z,rrd_4 + fail_msg 3 +rrd_4: ld a,(hl) + cp a,data_55+5 + jr z,rrd_5 + fail_msg 4 +rrd_5: ld (hl),data_7f + ld a,data_80 + rrd + jp m,rrd_6 + fail_msg 5 +rrd_6: jp po,rrd_7 + fail_msg 6 +rrd_7: cp a,data_80+15 + jr z,rrd_8 + fail_msg 7 +rrd_8: ld a,(hl) + cp a,7 + jr z,rrd_9 + fail_msg 8 +rrd_9: ld a,8 + ld (hl),0 + rrd + jr z,rrd_10 + fail_msg 9 +rrd_10: ld a,(hl) + cp a,data_80 + jr z,bit_0 + fail_msg 10 +bit_0: nop + print "bit" + ld a,data_ff + bit 0,a + jr nz,bit_1 + fail_msg 0 +bit_1: bit 1,a + jr nz,bit_2 + fail_msg 1 +bit_2: bit 2,a + jr nz,bit_3 + fail_msg 2 +bit_3: bit 3,a + jr nz,bit_4 + fail_msg 3 +bit_4: bit 4,a + jr nz,bit_5 + fail_msg 4 +bit_5: bit 5,a + jr nz,bit_6 + fail_msg 5 +bit_6: bit 6,a + jr nz,bit_7 + fail_msg 6 +bit_7: bit 7,a + jr nz,bit_8 + fail_msg 7 +bit_8: ld a,0 + bit 0,a + jr z,bit_9 + fail_msg 8 +bit_9: bit 1,a + jr z,bit_10 + fail_msg 9 +bit_10: bit 2,a + jr z,bit_11 + fail_msg 10 +bit_11: bit 3,a + jr z,bit_12 + fail_msg 11 +bit_12: bit 4,a + jr z,bit_13 + fail_msg 12 +bit_13: bit 5,a + jr z,bit_14 + fail_msg 13 +bit_14: bit 6,a + jr z,bit_15 + fail_msg 14 +bit_15: bit 7,a + jr z,bit_16 + fail_msg 15 +bit_16: ld b,data_80 + bit 2,b + jr z,bit_17 + fail_msg 16 +bit_17: bit 7,b + jr nz,bit_18 + fail_msg 17 +bit_18: ld c,data_55 + bit 7,c + jr z,bit_19 + fail_msg 18 +bit_19: bit 0,c + jr nz,bit_20 + fail_msg 19 +bit_20: ld d,data_aa + bit 7,d + jr nz,bit_21 + fail_msg 20 +bit_21: bit 4,d + jr z,bit_22 + fail_msg 21 +bit_22: ld e,data_7f + bit 7,e + jr z,bit_23 + fail_msg 22 +bit_23: bit 3,e + jr nz,bit_24 + fail_msg 23 +bit_24: ld h,#12 ;bjp was >data_1234 + bit 4,h + jr nz,bit_25 + fail_msg 24 +bit_25: bit 2,h + jr z,bit_26 + fail_msg 25 +bit_26: ld l,#34 ;bjp was >data_1234 + bit 3,l + jr z,bit_27 + fail_msg 26 +bit_27: bit 2,l + jr nz,bit_28 + fail_msg 27 +bit_28: ld hl,t_var4 + ld (hl),data_55 + bit 0,(hl) + jr nz,bit_29 + fail_msg 28 +bit_29: bit 1,(hl) + jr z,bit_30 + fail_msg 29 +bit_30: bit 2,(hl) + jr nz,bit_31 + fail_msg 30 +bit_31: bit 3,(hl) + jr z,bit_32 + fail_msg 31 +bit_32: bit 4,(hl) + jr nz,bit_33 + fail_msg 32 +bit_33: bit 5,(hl) + jr z,bit_34 + fail_msg 33 +bit_34: bit 6,(hl) + jr nz,bit_35 + fail_msg 34 +bit_35: bit 7,(hl) + jr z,bit_36 + fail_msg 35 +bit_36: ld ix,t_var3 + ld a,data_aa + ld (ix-2),a + bit 0,(ix-2) + jr z,bit_37 + fail_msg 36 +bit_37: bit 1,(ix-2) + jr nz,bit_38 + fail_msg 37 +bit_38: bit 2,(ix-2) + jr z,bit_39 + fail_msg 38 +bit_39: bit 3,(ix-2) + jr nz,bit_40 + fail_msg 39 +bit_40: bit 4,(ix-2) + jr z,bit_41 + fail_msg 40 +bit_41: bit 5,(ix-2) + jr nz,bit_42 + fail_msg 41 +bit_42: bit 6,(ix-2) + jr z,bit_43 + fail_msg 42 +bit_43: bit 7,(ix-2) + jr nz,bit_44 + fail_msg 43 +bit_44: ld iy,t_var3 + ld a,data_55 + ld (iy+2),a + bit 0,(iy+2) + jr nz,bit_45 + fail_msg 44 +bit_45: bit 1,(iy+2) + jr z,bit_46 + fail_msg 45 +bit_46: bit 2,(iy+2) + jr nz,bit_47 + fail_msg 46 +bit_47: bit 3,(iy+2) + jr z,bit_48 + fail_msg 47 +bit_48: bit 4,(iy+2) + jr nz,bit_49 + fail_msg 48 +bit_49: bit 5,(iy+2) + jr z,bit_50 + fail_msg 49 +bit_50: bit 6,(iy+2) + jr nz,bit_51 + fail_msg 50 +bit_51: bit 7,(iy+2) + jr z,set_0 + fail_msg 51 +set_0: nop + print "set" + ld a,0 + set 0,a + set 2,a + set 4,a + set 6,a + cp a,data_55 + jr z,set_1 + fail_msg 0 +set_1: set 1,a + set 3,a + set 5,a + set 7,a + cp a,data_ff + jr z,set_2 + fail_msg 1 +set_2: ld b,0 + set 1,b + set 3,b + ld a,b + cp a,#0a ;data_aa.and.#0f + jr z,set_3 + fail_msg 2 +set_3: ld c,0 + set 1,c + set 4,c + ld a,c + cp a,#12 ;bjp was >data_1234 + jr z,set_4 + fail_msg 3 +set_4: ld d,0 + set 2,d + set 4,d + set 5,d + ld a,d + cp a,#34 ;bjp was >data_1234 + jr z,set_5 + fail_msg 4 +set_5: ld e,0 + set 7,e + ld a,e + cp a,data_80 + jr z,set_6 + fail_msg 5 +set_6: ld h,0 + set 0,h + set 2,h + set 4,h + set 6,h + ld a,h + cp a,data_55 + jr z,set_7 + fail_msg 6 +set_7: ld l,0 + set 1,l + set 3,l + set 5,l + set 7,l + ld a,l + cp a,data_aa + jr z,set_8 + fail_msg 7 +set_8: ld hl,t_var5 + ld (hl),0 + set 0,(hl) + set 2,(hl) + set 4,(hl) + set 6,(hl) + ld a,(hl) + cp a,data_55 + jr z,set_9 + fail_msg 8 +set_9: ld (hl),0 + set 1,(hl) + set 3,(hl) + set 5,(hl) + set 7,(hl) + ld a,(hl) + cp a,data_aa + jr z,set_10 + fail_msg 9 +set_10: ld ix,t_var3 + ld a,0 + ld (ix-2),a + ld (ix+2),a + set 0,(ix-2) + set 2,(ix-2) + set 4,(ix-2) + set 6,(ix-2) + ld a,(ix-2) + cp a,data_55 + jr z,set_11 + fail_msg 10 +set_11: set 1,(ix+2) + set 3,(ix+2) + set 5,(ix+2) + set 7,(ix+2) + ld a,(ix+2) + cp a,data_aa + jr z,set_12 + fail_msg 11 +set_12: ld iy,t_var3 + ld a,0 + ld (iy-1),a + ld (iy+1),a + set 0,(iy-1) + set 2,(iy-1) + set 4,(iy-1) + set 6,(iy-1) + ld a,(iy-1) + cp a,data_55 + jr z,set_13 + fail_msg 12 +set_13: set 1,(iy+1) + set 3,(iy+1) + set 5,(iy+1) + set 7,(iy+1) + ld a,(iy+1) + cp a,data_aa + jr z,res_0 + fail_msg 13 +res_0: nop + print "res" + ld a,data_ff + res 7,a + cp a,data_7f + jr z,res_1 + fail_msg 0 +res_1: res 5,a + res 3,a + res 1,a + cp a,data_55 + jr z,res_2 + fail_msg 1 +res_2: ld a,data_ff + res 0,a + res 2,a + res 4,a + res 6,a + cp a,data_aa + jr z,res_3 + fail_msg 2 +res_3: ld b,data_ff + res 7,b + ld a,b + cp a,data_7f + jr z,res_4 + fail_msg 3 +res_4: ld c,data_ff + res 0,c + res 1,c + res 2,c + res 3,c + res 4,c + res 5,c + res 6,c + ld a,c + cp a,data_80 + jr z,res_5 + fail_msg 4 +res_5: ld d,data_ff + res 0,d + res 2,d + res 4,d + res 6,d + ld a,d + cp a,data_aa + jr z,res_6 + fail_msg 5 +res_6: ld e,data_ff + res 1,e + res 3,e + res 5,e + res 7,e + ld a,e + cp a,data_55 + jr z,res_7 + fail_msg 6 +res_7: ld h,data_ff + res 0,h + res 2,h + res 3,h + res 5,h + res 6,h + res 7,h + ld a,h + cp a,#12 ;bjp was >data_1234 + jr z,res_8 + fail_msg 7 +res_8: ld l,data_ff + res 0,l + res 1,l + res 3,l + res 6,l + res 7,l + ld a,l + cp a,#34 ;bjp was >data_1234 + jr z,res_9 + fail_msg 8 +res_9: ld hl,t_var3 + ld (hl),data_ff + res 0,(hl) + res 2,(hl) + res 4,(hl) + res 6,(hl) + ld a,(hl) + cp a,data_aa + jr z,res_10 + fail_msg 9 +res_10: res 1,(hl) + res 3,(hl) + res 5,(hl) + res 7,(hl) + ld a,(hl) + cp a,0 + jr z,res_11 + fail_msg 10 +res_11: ld ix,t_var3 + ld a,data_ff + ld (ix-2),a + ld (ix+2),a + res 1,(ix-2) + res 3,(ix-2) + res 5,(ix-2) + res 7,(ix-2) + ld a,(ix-2) + cp a,data_55 + jr z,res_12 + fail_msg 11 +res_12: res 0,(ix+2) + res 2,(ix+2) + res 4,(ix+2) + res 6,(ix+2) + ld a,(ix+2) + cp a,data_aa + jr z,res_13 + fail_msg 12 +res_13: ld iy,t_var3 + ld a,data_ff + ld (iy-1),a + ld (iy+1),a + res 1,(iy-1) + res 3,(iy-1) + res 5,(iy-1) + res 7,(iy-1) + ld a,(iy-1) + cp a,data_55 + jr z,res_14 + fail_msg 13 +res_14: res 0,(iy+1) + res 2,(iy+1) + res 4,(iy+1) + res 6,(iy+1) + ld a,(iy+1) + cp a,data_aa + jr z,jp_0 + fail_msg 14 +jp_0: nop + print "jp" + jp jp_1 + nop + nop + fail_msg 0 +jp_1: ld a,0 + and a + jp z,jp_2 + fail_msg 1 +jp_2: jp nc,jp_3 + fail_msg 2 +jp_3: ld b,1 + sub a,b + jp nz,jp_4 + fail_msg 3 +jp_4: jp c,jp_5 + fail_msg 4 +jp_5: jp jp_7 + fail_msg 5 +jp_6: jp jr_0 + fail_msg 6 +jp_7: jp jp_6 + fail_msg 7 +jr_0: jr jr_2 + fail_msg 0 +jr_1: jr jr_3 + fail_msg 1 +jr_2: jr jr_1 + fail_msg 2 +jr_3: ld hl,jp_9 + jp (hl) + fail_msg 3 +jp_8: ld ix,jp_10 + jp (ix) + fail_msg 8 +jp_9: jp jp_8 + fail_msg 9 +jp_10: ld iy,djnz_0 + jp (iy) + fail_msg 10 +djnz_0: ld b,5 + ld a,0 +djnz_1: inc a + djnz djnz_1 + cp a,5 + jr z,call_0 + fail_msg 1 +call_0: nop + print "call" + ld a,0 + call sub1 + cp a,data_7f + jr z,call_1 + fail_msg 0 +call_1: ld a,0 + and a + call z,sub2 + cp a,data_55 + jr z,call_2 + fail_msg 1 +call_2: ld a,data_aa + and a + call nz,sub3 + cp a,data_aa+1 + jr z,call_3 + fail_msg 2 +call_3: ld a,0 + cp a,0 + call nc,sub4 + cp a,data_ff + jr z,call_4 + fail_msg 3 +call_4: ld a,0 + sub a,1 + call c,sub5 + cp a,data_ff-1 + jr z,call_5 + fail_msg 4 +call_5: ld a,data_7f + sla a + call po,sub6 + cp a,data_7f + jr z,call_6 + fail_msg 5 +call_6: ld a,data_aa + srl a + call pe,sub7 + cp a,data_aa + jr z,call_7 + fail_msg 6 +call_7: ld a,data_80 + sra a + call m,sub8 + cp a,data_80 + jr z,call_8 + fail_msg 7 +call_8: ld a,data_7f + sra a + call p,sub9 + cp a,data_7f + jr z,rst_0 + fail_msg 8 +rst_0: ld a, 1 + ld (rst_state),a + print "rst" + rst #00 + cp a,1 + jr z,rst_1 + fail_msg 0 +rst_1: rst #08 + cp a,2 + jr z,rst_2 + fail_msg 1 +rst_2: rst #10 + cp a,3 + jr z,rst_3 + fail_msg 2 +rst_3: rst #18 + cp a,4 + jr z,rst_4 + fail_msg 3 +rst_4: rst #20 + cp a,5 + jr z,rst_5 + fail_msg 4 +rst_5: rst #28 + cp a,6 + jr z,rst_6 + fail_msg 5 +rst_6: rst #30 + cp a,7 + jr z,rst_7 + fail_msg 6 +rst_7: rst #38 + cp a,8 + jp z,ldi_ops + fail_msg 7 + + ;; skip the in instructions, as they need to be reworked + ;; for TV80 environment. (gth) +in_0: in a,(in_port) + cp a,data_7f + jr z,in_1 + fail_msg 0 +in_1: ld c,in_port + in a,(c) + jr nz,in_2 + fail_msg 1 +in_2: jp p,in_3 + fail_msg 2 +in_3: jp pe,in_4 + fail_msg 3 +in_4: cp a,data_55 + jr z,in_5 + fail_msg 4 +in_5: in a,(c) + jp m,in_6 + fail_msg 5 +in_6: jp po,in_7 + fail_msg 6 +in_7: jr nz,in_8 + fail_msg 7 +in_8: cp a,data_80 + jr z,in_9 + fail_msg 8 +in_9: in a,(c) + jr z,in_10 + fail_msg 9 +in_10: in b,(c) + jp m,in_11 + fail_msg 10 +in_11: ld a,b + cp a,data_ff + jr z,in_12 + fail_msg 11 +in_12: in d,(c) + jp pe,in_13 + fail_msg 12 +in_13: ld a,d + cp a,data_aa + jr z,in_14 + fail_msg 13 +in_14: in e,(c) + jp p,in_15 + fail_msg 14 +in_15: ld a,e + cp a,data_7f + jr z,in_16 + fail_msg 15 +in_16: in h,(c) + jp pe,in_17 + fail_msg 16 +in_17: ld a,h + cp a,data_55 + jr z,in_18 + fail_msg 17 +in_18: in l,(c) + jp m,in_19 + fail_msg 18 +in_19: ld a,l + cp a,data_80 + jr z,in_20 + fail_msg 19 +in_20: in c,(c) + jr z,in_21 + fail_msg 20 +in_21: ld c,in_port + ld b,2 + ld hl,t_var1 + ini + jr nz,in_22 + fail_msg 21 +in_22: ini + jr z,in_23 + fail_msg 22 +in_23: ld hl,t_var1 + ld a,(hl) + cp a,data_ff + jr z,in_24 + fail_msg 23 +in_24: inc hl + ld a,(hl) + cp a,data_aa + jr z,in_25 + fail_msg 24 +in_25: ld b,5 + ld c,in_port + ld hl,t_var1 + inir + jr z,in_26 + fail_msg 25 +in_26: ld hl,t_var1 + ld a,(hl) + cp a,data_7f + jr z,in_27 + fail_msg 26 +in_27: inc hl + ld a,(hl) + cp a,data_55 + jr z,in_28 + fail_msg 27 +in_28: inc hl + ld a,(hl) + cp a,data_80 + jr z,in_29 + fail_msg 28 +in_29: inc hl + ld a,(hl) + cp a,0 + jr z,in_30 + fail_msg 29 +in_30: inc hl + ld a,(hl) + cp a,data_ff + jr z,in_31 + fail_msg 30 +in_31: ld b,2 + ld c,in_port + ld hl,t_var5 + ind + jr nz,in_32 + fail_msg 31 +in_32: ind + jr z,in_33 + fail_msg 32 +in_33: ld hl,t_var5 + ld a,(hl) + cp a,data_aa + jr z,in_34 + fail_msg 33 +in_34: dec hl + ld a,(hl) + cp a,data_7f + jr z,in_35 + fail_msg 34 +in_35: ld b,5 + ld c,in_port + ld hl,t_var5 + indr + jr z,in_36 + fail_msg 35 +in_36: ld hl,t_var5 + ld a,(hl) + cp a,data_55 + jr z,in_37 + fail_msg 36 +in_37: dec hl + ld a,(hl) + cp a,data_80 + jr z,in_38 + fail_msg 37 +in_38: dec hl + ld a,(hl) + cp a,0 + jr z,in_39 + fail_msg 38 +in_39: dec hl + ld a,(hl) + cp a,data_ff + jr z,in_40 + fail_msg 39 +in_40: dec hl + ld a,(hl) + cp a,data_aa + jr z,ldi_0 + fail_msg 40 + +ldi_ops: nop + print "ldi" +ldi_0: ld hl,t_var1 + ld a,#12 ;bjp was >data_1234 + ld (hl),a + inc hl + ld a,#34 ;bjp was >data_1234 + ld (hl),a + dec hl + ld de,t_var3 + ld bc,2 + ldi + jp pe,ldi_1 + fail_msg 0 +ldi_1: ldi + jp po,ldi_2 + fail_msg 1 +ldi_2: ld hl,t_var3 + ld a,(hl) + cp a,#12 ;bjp was >data_1234 + jr z,ldi_3 + fail_msg 2 +ldi_3: inc hl + ld a,(hl) + cp a,#34 ;bjp was >data_1234 + jr z,ldir_0 + fail_msg 3 +ldir_0: ld hl,var1 + ld de,t_var1 + ld bc,5 + ldir + jp po,ldir_1 + fail_msg 0 +ldir_1: ld hl,t_var1 + ld a,(hl) + cp a,data_ff + jr z,ldir_2 + fail_msg 1 +ldir_2: inc hl + ld a,(hl) + cp a,data_55 + jr z,ldir_3 + fail_msg 2 +ldir_3: inc hl + ld a,(hl) + cp a,data_80 + jr z,ldir_4 + fail_msg 3 +ldir_4: inc hl + ld a,(hl) + cp a,data_aa + jr z,ldir_5 + fail_msg 4 +ldir_5: inc hl + ld a,(hl) + cp a,data_7f + jr z,ldd_0 + fail_msg 5 +ldd_0: ld hl,t_var5 + ld a,#12 ;bjp was >data_1234 + ld (hl),a + dec hl + ld a,#34 ;bjp was >data_1234 + ld (hl),a + inc hl + ld bc,2 + ld de,t_var3 + ldd + jp pe,ldd_1 + fail_msg 0 +ldd_1: ldd + jp po,ldd_2 + fail_msg 1 +ldd_2: ld hl,t_var3 + ld a,(hl) + cp a,#12 ;bjp was >data_1234 + jr z,ldd_3 + fail_msg 2 +ldd_3: dec hl + ld a,(hl) + cp a,#34 ;bjp was >data_1234 + jr z,lddr_0 + fail_msg 3 +lddr_0: ld bc,5 + ld hl,var5 + ld de,t_var5 + lddr + jp po,lddr_1 + fail_msg 0 +lddr_1: ld hl,t_var1 + ld a,(hl) + cp a,data_ff + jr z,lddr_2 + fail_msg 1 +lddr_2: inc hl + ld a,(hl) + cp a,data_55 + jr z,lddr_3 + fail_msg 2 +lddr_3: inc hl + ld a,(hl) + cp a,data_80 + jr z,lddr_4 + fail_msg 3 +lddr_4: inc hl + ld a,(hl) + cp a,data_aa + jr z,lddr_5 + fail_msg 4 +lddr_5: inc hl + ld a,(hl) + cp a,data_7f + jr z,cpi_0 + fail_msg 5 +cpi_0: ld hl,t_var1 + ld bc,5 + ld a,data_7f + cpi + jp pe,cpi_1 + fail_msg 0 +cpi_1: jp m,cpi_2 + fail_msg 1 +cpi_2: jr nz,cpi_3 + fail_msg 2 +cpi_3: cpi + jp pe,cpi_4 + fail_msg 3 +cpi_4: jp p,cpi_5 + fail_msg 4 +cpi_5: jr nz,cpi_6 + fail_msg 5 +cpi_6: cpi + jp pe,cpi_7 + fail_msg 6 +cpi_7: jp m,cpi_8 + fail_msg 7 +cpi_8: jr nz,cpi_9 + fail_msg 8 +cpi_9: cpi + jp pe,cpi_10 + fail_msg 9 +cpi_10: jp m,cpi_11 + fail_msg 10 +cpi_11: jr nz,cpi_12 + fail_msg 11 +cpi_12: cpi + jp po,cpi_13 + fail_msg 12 +cpi_13: jp p,cpi_14 + fail_msg 13 +cpi_14: jr z,cpir_0 + fail_msg 14 +cpir_0: ld a,data_aa + ld hl,var1 + ld bc,5 + cpir + jr z,cpir_1 + fail_msg 0 +cpir_1: jp pe,cpir_2 + fail_msg 1 +cpir_2: ld a,b + cp a,0 + jr z,cpir_3 + fail_msg 2 +cpir_3: ld a,c + cp a,1 + jr z,cpir_4 + fail_msg 3 +cpir_4: ld a,data_7f + ld hl,var1 + ld bc,5 + cpir + jp po,cpir_5 + fail_msg 4 +cpir_5: jr z,cpir_6 + fail_msg 5 +cpir_6: ld a,#34 ;bjp was >data_1234 + ld hl,var1 + ld bc,5 + cpir + jp po,cpir_7 + fail_msg 6 +cpir_7: jr nz,cpir_8 + fail_msg 7 +cpir_8: jp m,cpir_9 + fail_msg 8 +cpir_9: ld a,data_aa + ld hl,var1 + ld bc,3 + cpir + jp po,cpir_10 + fail_msg 9 +cpir_10: jp p,cpir_11 + fail_msg 10 +cpir_11: jr nz,cpd_0 + fail_msg 11 +cpd_0: ld a,data_ff + ld hl,var5 + ld bc,5 + cpd + jp m,cpd_1 + fail_msg 0 +cpd_1: jp pe,cpd_2 + fail_msg 1 +cpd_2: jr nz,cpd_3 + fail_msg 2 +cpd_3: cpd + jp p,cpd_4 + fail_msg 3 +cpd_4: jp pe,cpd_5 + fail_msg 4 +cpd_5: jr nz,cpd_6 + fail_msg 5 +cpd_6: cpd + jp p,cpd_7 + fail_msg 6 +cpd_7: jp pe,cpd_8 + fail_msg 7 +cpd_8: jr nz,cpd_9 + fail_msg 8 +cpd_9: cpd + jp m,cpd_10 + fail_msg 9 +cpd_10: jp pe,cpd_11 + fail_msg 10 +cpd_11: jr nz,cpd_12 + fail_msg 11 +cpd_12: cpd + jp p,cpd_13 + fail_msg 12 +cpd_13: jp po,cpd_14 + fail_msg 13 +cpd_14: jr z,cpdr_0 + fail_msg 14 +cpdr_0: ld a,data_80 + ld hl,var5 + ld bc,5 + cpdr + jp pe,cpdr_1 + fail_msg 0 +cpdr_1: jp p,cpdr_2 + fail_msg 1 +cpdr_2: jr z,cpdr_3 + fail_msg 2 +cpdr_3: ld a,b + cp a,0 + jr z,cpdr_4 + fail_msg 3 +cpdr_4: ld a,c + cp a,2 + jr z,cpdr_5 + fail_msg 4 +cpdr_5: ld a,#34 ;bjp was >data_1234 + ld hl,var5 + ld bc,5 + cpdr + jp po,cpdr_6 + fail_msg 5 +cpdr_6: jr nz,cpdr_7 + fail_msg 6 +cpdr_7: jp p,cpdr_8 + fail_msg 7 +cpdr_8: ld a,#34 ;bjp was >data_1234 + ld hl,var5 + ld bc,3 + cpdr + jp po,cpdr_9 + fail_msg 8 +cpdr_9: jr nz,cpdr_10 + fail_msg 9 +cpdr_10: jp m,test_exit + fail_msg 10 + + ;; this section needs to be reworked for the TV80 environment. + ;; Since env uses ports for all its test control, this gets + ;; partially covered by normal operation. (gth) +; +;the file portfe.xxx must be examined to see if the proper output is generated +; +out_0: ld a,#30 + out (out_port),a + ld c,out_port + ld a,#31 + out (c),a + ld b,#32 + out (c),b + ld d,#33 + out (c),d + ld e,#34 + out (c),e + ld h,#35 + out (c),h + ld l,#36 + out (c),l + out (c),c ;output value divider +outi_0: ld a,#31 ;set up output values + ld b,5 + ld hl,t_var1 +outi_1: ld (hl),a + inc a + inc hl + djnz outi_1 +outi_2: ld c,out_port + ld b,5 + ld hl,t_var1 +outi_3: outi + jr nz,outi_3 +otir_0: out (c),c ;output value divider + ld hl,t_var1 + ld b,5 + otir + jr z,outd_0 + fail_msg 0 +outd_0: out (c),c + ld hl,t_var5 + ld b,5 +outd_1: outd + jr nz,outd_1 +otdr_0: out (c),c + ld b,5 + ld hl,t_var5 + otdr + jr z,otdr_1 + fail_msg 0 +otdr_1: out (c),c + ld a,#0d + out (c),a + ld a,#0a + out (c),a + +test_exit: + ;; complicated pass/fail computation no longer necessary + ;; if we got here, we passed + passed + +; +;subroutine 1, must load a with #7f +; +sub1: ld a,data_7f + ret +; +; +;subroutine 2, must load a with #55 +; +sub2: ld a,data_55 + cp a,data_55 + ret z +; +;subroutine 3, increments a +; +sub3: inc a + and a + ret nz +; +;subroutine 4, subtracts 1 from a +; +sub4: sub a,1 + ret c +; +;subroutine 5, subtracts 1 from a +; +sub5: sub a,1 + ret nc +; +;subroutine 6, shifts a right logically +; +sub6: srl a + ret po +; +;subroutine 7, shifts a left arithmetically +; +sub7: sla a + ret pe +; +;subroutine 8, shifts a left arithmetically +; +sub8: sla a + ret m +; +;subroutine 9, rotates a left +; +sub9: rl a + ret p +; +;restart 0 routine +; +rst_0000_1: + ld a, (rst_state) + cp 1 + jp z,rst_test_ret + + ld a, 0 + out (#82), a ; disable timeout count + + ld a,(pass_count) + or a + jp z,start + ld a,1 + ret + +rst_test_ret: ret +; +; data +; +var1: db data_ff +var2: db data_55 +var3: db data_80 +var4: db data_aa +var5: db data_7f +; + +mem_init_vals: + dw data_1234 + dw data_55aa + dw data_7fff + dw data_8000 + dw data_aa55 + dw data_ffff + +mem_init: + push bc + push de + push hl + + ;; initialize region from 8000 to 80FF + ld hl, #8000 + ld b, #ff + +mem_init_loop_1: + ld (hl), 0 + inc hl + djnz mem_init_loop_1 + + ;; initialize region from 8100 to 81FF + ld hl, #8100 + ld b, #ff + +mem_init_loop_2: + ld (hl), 0 + inc hl + djnz mem_init_loop_2 + + ;; populate special values from 8005 + ld de, #8005 + ld hl, mem_init_vals + ld b, 12 + +mem_init_loop_3: + ld a, (hl) + inc hl + ex de, hl + ld (hl), a + inc hl + ex de, hl + djnz mem_init_loop_3 + + ;; exit + pop hl + pop de + pop bc + ret + +t_var1: equ #8000 +t_var2: equ #8001 +t_var3: equ #8002 +t_var4: equ #8003 +t_var5: equ #8004 + +w_var1: equ #8005 +w_var2: equ #8007 +w_var3: equ #8009 +w_var4: equ #800B +w_var5: equ #800D +w_var6: equ #800F + +tw_var1: equ #8011 +tw_var2: equ #8013 +tw_var3: equ #8015 +tw_var4: equ #8017 +tw_var5: equ #8019 +tw_var6: equ #801B +tw_var7: equ #801D + +error_cnt: equ #801E +pass_count: equ #801F +fail_num: equ #8020 +rst_state: equ #8021 + +; org #8000 +;t_var1: db 0 +;t_var2: db 0 +;t_var3: db 0 +;t_var4: db 0 +;t_var5: db 0 +;; +;w_var1: dw data_1234 +;w_var2: dw data_55aa +;w_var3: dw data_7fff +;w_var4: dw data_8000 +;w_var5: dw data_aa55 +;w_var6: dw data_ffff +;; +;tw_var1: dw 0 +;tw_var2: dw 0 +;tw_var3: dw 0 +;tw_var4: dw 0 +;tw_var5: dw 0 +;tw_var6: dw 0 +;tw_var7: dw 0 +;; +;error_cnt: db 0 +;pass_count: db 0 +;fail_num db 0 +;rst_state db 0 +; +; org #8100 +;stack: ds 128 +;stack_end: equ $ +; + end start Index: branches/restruc2/tests/fib.c =================================================================== --- branches/restruc2/tests/fib.c (nonexistent) +++ branches/restruc2/tests/fib.c (revision 47) @@ -0,0 +1,54 @@ +// Recursively compute fibonnaci sequence, using a +// really inefficient algorithm. +// (Stack exercise test) + +#include "tv80_env.h" + +int answers[] = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, + 233, 377, 610, 987, 1597, 2584, 4181 }; + +int fib (int n) +{ + int rv; + timeout_port = 0x02; + + if (n < 2) rv = n; + else rv = fib(n-1) + fib(n-2); + + timeout_port = 0x01; + return rv; +} + +int main () +{ + int fn, fr; + char pass; + + set_timeout (60000); + pass = 1; + + for (fn = 1; fn < 20; fn++) { + print ("Computing Fibonacci number "); + print_num (fn); + print ("\n"); + + fr = fib(fn); + print ("Number is: "); + print_num (fr); + + if (fr == answers[fn-1]) { + print (" (correct)\n"); + } else { + print (" (incorrect)\n"); + print ("Correct result: "); + print_num (answers[fn-1]); + pass = 0; + print ("\n"); + } + } + + if (pass) + sim_ctl (SC_TEST_PASSED); + else + sim_ctl (SC_TEST_FAILED); +} Index: branches/restruc2/tests/hello.c =================================================================== --- branches/restruc2/tests/hello.c (nonexistent) +++ branches/restruc2/tests/hello.c (revision 47) @@ -0,0 +1,23 @@ + +sfr at 0x80 sim_ctl_port; +sfr at 0x81 msg_port; +sfr at 0x82 timeout_port; + +void print (char *string) +{ + char *iter; + + iter = string; + while (*iter != 0) { + msg_port = *iter++; + } +} + +int main () +{ + print ("Hello, world!\n"); + + sim_ctl_port = 0x01; + return 0; +} + Index: branches/restruc2/tests/malloc.c =================================================================== --- branches/restruc2/tests/malloc.c (nonexistent) +++ branches/restruc2/tests/malloc.c (revision 47) @@ -0,0 +1,39 @@ +#include + +#include "tv80_env.h" + +#define TEST_SIZE 200 +int main () +{ + char *foo; + int i; + int cksum_in, cksum_out; + + sim_ctl (SC_DUMPON); + + foo = malloc (TEST_SIZE); + set_timeout (30000); + + print ("Memory allocated\n"); + + cksum_in = 0; + for (i=0; i `DUMP_START) + dumpon; + #100; + end +`endif + + +/* + always + begin + while (mreq_n) @(posedge clk); + wait_n <= #1 0; + @(posedge clk); + wait_n <= #1 1; + while (!mreq_n) @(posedge clk); + end + */ + +`ifdef TV80_INSTRUCTION_DECODE + reg [7:0] state; + initial + state = 0; + + always @(posedge clk) + begin : inst_decode + if ((`TV80_CORE_PATH.mcycle[6:0] == 1) && + (`TV80_CORE_PATH.tstate[6:0] == 8)) + begin + op_decode.decode (`TV80_CORE_PATH.IR[7:0], state); + end + else if (`TV80_CORE_PATH.mcycle[6:0] != 1) + state = 0; + end +`endif + +`include "env_tasks.v" + +endmodule // tb_top Index: branches/restruc2/env/env_io.v =================================================================== --- branches/restruc2/env/env_io.v (nonexistent) +++ branches/restruc2/env/env_io.v (revision 47) @@ -0,0 +1,144 @@ + +module env_io (/*AUTOARG*/ + // Outputs + DI, + // Inputs + clk, iorq_n, rd_n, wr_n, addr, DO + ); + + input clk; + input iorq_n; + input rd_n; + input wr_n; + input [7:0] addr; + input [7:0] DO; + inout [7:0] DI; + + reg [7:0] io_data; + + reg [7:0] str_buf [0:255]; + reg io_cs; + integer buf_ptr, i; + + reg [7:0] timeout_ctl; + reg [15:0] cur_timeout; + reg [15:0] max_timeout; + + reg [7:0] int_countdown; + reg [7:0] checksum; + reg [7:0] ior_value; // increment-on-read value + + assign DI = (!iorq_n & !rd_n & io_cs) ? io_data : {8{1'bz}}; + + initial + begin + io_cs = 0; + buf_ptr = 0; + cur_timeout = 0; + max_timeout = 10000; + timeout_ctl = 1; + int_countdown = 0; + end + + always @* + begin + if (!iorq_n & !rd_n) + begin + io_cs = (addr[7:5] == 3'b100); + + case (addr) + 8'h83 : io_data = max_timeout[7:0]; + 8'h84 : io_data = max_timeout[15:8]; + + 8'h90 : io_data = int_countdown; + 8'h91 : io_data = checksum; + 8'h93 : io_data = ior_value; + 8'h94 : io_data = {$random}; + default : io_data = 8'hzz; + endcase // case(addr) + end // if (!iorq_n & !rd_n) + end // always @ * + + always @(posedge clk) + begin + if (!iorq_n & !wr_n) + case (addr) + 8'h80 : + begin + case (DO) + 1 : tb_top.test_pass; + + 2 : tb_top.test_fail; + + 3 : tb_top.dumpon; + + 4 : tb_top.dumpoff; + + default : + begin + $display ("%t: ERROR : Unknown I/O command %x", $time, DO); + end + endcase // case(DO) + end // case: :... + + 8'h81 : + begin + str_buf[buf_ptr] = DO; + buf_ptr = buf_ptr + 1; + + //$display ("%t: DEBUG : Detected write of character %x", $time, DO); + if (DO == 8'h0A) + begin + $write ("%t: PROGRAM : ", $time); + + for (i=0; i= max_timeout) + begin + $display ("%t: ERROR : Reached timeout %d cycles", $time, max_timeout); + tb_top.test_fail; + end + end // always @ (posedge clk) + + always @(posedge clk) + begin + if (int_countdown == 1) + begin + tb_top.int_n <= #1 1'b0; + int_countdown = 0; + end + else if (int_countdown > 1) + begin + int_countdown = int_countdown - 1; + tb_top.int_n <= #1 1'b1; + end + end + +endmodule // env_io Index: branches/restruc2/env/tb.vf =================================================================== --- branches/restruc2/env/tb.vf (nonexistent) +++ branches/restruc2/env/tb.vf (revision 47) @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2003-2004 by Cisco Systems Inc. + * $Id: tb.vf,v 1.2 2004-10-18 21:48:23 ghutchis Exp $ + * All rights reserved. + * + * Author: Guy Hutchison + * + */ + +rtl/core/tv80_alu.v +rtl/core/tv80_mcode.v +rtl/core/tv80_reg.v +rtl/core/tv80_core.v +rtl/core/tv80s.v +env/tb_top.v +env/env_io.v +env/op_decode.v +env/async_mem.v + Index: branches/restruc2/env/async_mem.v =================================================================== --- branches/restruc2/env/async_mem.v (nonexistent) +++ branches/restruc2/env/async_mem.v (revision 47) @@ -0,0 +1,29 @@ +module async_mem (/*AUTOARG*/ + // Outputs + rd_data, + // Inputs + wr_clk, wr_data, wr_cs, addr, rd_cs + ); + + parameter asz = 15, + depth = 32768; + + input wr_clk; + input [7:0] wr_data; + input wr_cs; + + input [asz-1:0] addr; + inout [7:0] rd_data; + input rd_cs; + + reg [7:0] mem [0:depth-1]; + + always @(posedge wr_clk) + begin + if (wr_cs) + mem[addr] <= #1 wr_data; + end + + assign rd_data = (rd_cs) ? mem[addr] : {8{1'bz}}; + +endmodule // async_mem Index: branches/restruc2/doc/tv80_docs.xml =================================================================== --- branches/restruc2/doc/tv80_docs.xml (nonexistent) +++ branches/restruc2/doc/tv80_docs.xml (revision 47) @@ -0,0 +1,177 @@ + + + + + + + +tv80 Core Documentation + +OpenCores.org +
+ghutchis@opencores.org +
+
+ +General +private +XML +Extensible Markup Language + +A synthesizable 8-bit microprocessor which is instruction-set compatable +with the Z80, targetted at embedded and system-on-a-chip designs. + +
+ +
+ The tv80 core was created as a Verilog port of the VHDL T80 core, for use as a maintenence processor inside an ASIC. + The tv80 has been modified since then for better synthesis + timing/area results, and to incorporate several bug-fixes. + The T80, and the tv80 derived from it, attempt to maintain the + original cycle timings of the Z80, but have radically different + internal designs and timings. With its target being ASIC and + embedded applications, the tv80 does not attempt to maintain + the original pinout of the Z80. +
+
+
+ +Environment memory space is divided into a 32k ROM region and a 32k RAM +region, as follows: + +
+ + 0000-7FFF: ROM + 8000-FFFF: RAM + +
+ +Environment I/O space is allocated as follows: + +
+ + 00-0F: Unused + 10-1F: Test devices + 20-7F: Unused + 80-9F: Environment control + A0-FF: Unused +
+
+
+
+The tv80 environment is controlled by the program under simulation. The +program can affect the environment through a set of control registers, +which are mapped into I/O space. + +
+ + + Write '01' to end simulation with test passed + Write '02' to end with test failed + Write '03' to turn on dumping + Write '04' to turn off dumping + +
+ +
+ + Write characters to this port one at a time. When the + newline ('\n', ASCII 0x0A) character is written, the + environment will print out the collected string. + +
+
+ + Bit[0] enables the timeout counter, + Bit[1] resets the counter to 0. + Timeout counter defaults to enabled at simulation start. + +
+ +
+ + Holds 16-bit timeout value (amount of time in clocks before + timeout error occurs). + +
+
+ + When set, starts a countdown (in clocks) until assertion of + the INT_N signal. + +
+
+ This register holds the checksum value of all data + written to the accumulate register. The checksum is a simple + twos-complement checksum, so it can be compared with a CPU-generated + checksum. + This register is readable and writeable. Writing the register sets + the current checksum value. +
+
+ This write-only register adds the written value to the value + contained in the Checksum Value register. +
+
+ This register increments every time it is read, so reading it + repeatedly generates an incrementing sequence. It can be reset + by writing it to a new starting value. +
+ +
+
+ The minimum toolchain required to simulate the tv80 is the + CVer Verilog simulator, and the + SDCC compiler/assembler/linker. In + addition, to run the tvs80 instruction + test suite, the DOSBox DOS emulator + is required. + +
+
+ Most of the tests in the tv80 environment are written in C, and should + be compiled with the sdcc compiler. + +
+ The tvs80 test is different than the rest of the tests, and is + written in its own flavor of assembly language. This test provides + a fairly comprehensive Z80 instruction test. + The assembler for this test only runs under DOS. To assemble + under Unix/Linux, the "dosbox" DOS emulator is required. A script + to run the assembler under dosbox, as well as the tvs80.asm source, + is checked in under the "tests/tvs80" directory. +
+
+
+
+ + + + + VHDL T80 Core + + OpenCores.org + + + + + + Small Device C Compiler + + + + + GPL Cver Simulator + + Pragmatic C Software + + + + + + DOSBox + + + + +
Index: branches/restruc2/doc/tv80_docs.html =================================================================== --- branches/restruc2/doc/tv80_docs.html (nonexistent) +++ branches/restruc2/doc/tv80_docs.html (revision 47) @@ -0,0 +1,322 @@ + +$Revision: 1.2 $: tv80 Core Documentation + + + + + + + + +
 TOC 
+
+ + + +
$Revision: 1.2 $G. Hutchison
 OpenCores.org
 October 2004
+

tv80 Core Documentation
+ +

Abstract

+ +

+A synthesizable 8-bit microprocessor which is instruction-set compatable +with the Z80, targetted at embedded and system-on-a-chip designs. + +



+

Table of Contents

+

+1.  +Background
+2.  +Verification Environment
+    2.1  +Memory Map
+    2.2  +Control Registers
+        2.2.1  +Simulation control (0x80)
+        2.2.2  +Message output (0x81)
+        2.2.3  +Timeout control (0x82)
+        2.2.4  +Max timeout (0x84, 0x83)
+        2.2.5  +Interrupt countdown (0x90)
+        2.2.6  +Checksum value (0x91)
+        2.2.7  +Checksum accumulate (0x92)
+        2.2.8  +Increment on read (0x93)
+    2.3  +Tool Chain
+    2.4  +Tests
+        2.4.1  +tvs80 test
+3.  +References
+§  +Author's Address
+

+
+ +

+
 TOC 
+

1. Background

+ +

The tv80 core was created as a Verilog port of the VHDL T80 coreWallner, D., VHDL T80 Core, .[1], for use as a maintenence processor inside an ASIC. + The tv80 has been modified since then for better synthesis + timing/area results, and to incorporate several bug-fixes. +

+

The T80, and the tv80 derived from it, attempt to maintain the + original cycle timings of the Z80, but have radically different + internal designs and timings. With its target being ASIC and + embedded applications, the tv80 does not attempt to maintain + the original pinout of the Z80. +

+

+
 TOC 
+

2. Verification Environment

+ +

2.1 Memory Map

+ +

+Environment memory space is divided into a 32k ROM region and a 32k RAM +region, as follows: + +

+








    +  0000-7FFF:  ROM








    +  8000-FFFF:  RAM








    +
+

+ +

Environment I/O space is allocated as follows: +









    +  00-0F:  Unused








    +  10-1F:  Test devices








    +  20-7F:  Unused








    +  80-9F:  Environment control








    +  A0-FF:  Unused








    +
+ + +

2.2 Control Registers

+ +

2.2.1 Simulation control (0x80)

+ +
    +
  • Write '01' to end simulation with test passed +
  • +
  • Write '02' to end with test failed +
  • +
  • Write '03' to turn on dumping +
  • +
  • Write '04' to turn off dumping +
  • +
+

2.2.2 Message output (0x81)

+ +

+ Write characters to this port one at a time. When the + newline ('\n', ASCII 0x0A) character is written, the + environment will print out the collected string. + +

+

2.2.3 Timeout control (0x82)

+ +

+ Bit[0] enables the timeout counter, + Bit[1] resets the counter to 0. + Timeout counter defaults to enabled at simulation start. + +

+

2.2.4 Max timeout (0x84, 0x83)

+ +

+ Holds 16-bit timeout value (amount of time in clocks before + timeout error occurs). + +

+

2.2.5 Interrupt countdown (0x90)

+ +

+ When set, starts a countdown (in clocks) until assertion of + the INT_N signal. + +

+

2.2.6 Checksum value (0x91)

+ +

This register holds the checksum value of all data + written to the accumulate register. The checksum is a simple + twos-complement checksum, so it can be compared with a CPU-generated + checksum. +

+

This register is readable and writeable. Writing the register sets + the current checksum value. +

+

2.2.7 Checksum accumulate (0x92)

+ +

This write-only register adds the written value to the value + contained in the Checksum Value register. +

+

2.2.8 Increment on read (0x93)

+ +

This register increments every time it is read, so reading it + repeatedly generates an incrementing sequence. It can be reset + by writing it to a new starting value. +

+

2.3 Tool Chain

+ +

The minimum toolchain required to simulate the tv80 is the + CVerVanvick, A., GPL Cver Simulator, .[3] Verilog simulator, and the + SDCC, Small Device C Compiler, .[2] compiler/assembler/linker. In + addition, to run the tvs80tvs80 test instruction + test suite, the DOSBox, DOSBox, .[4] DOS emulator + is required. + +

+

2.4 Tests

+ +

Most of the tests in the tv80 environment are written in C, and should + be compiled with the sdcc, Small Device C Compiler, .[2] compiler. + +

+

2.4.1 tvs80 test

+ +

The tvs80 test is different than the rest of the tests, and is + written in its own flavor of assembly language. This test provides + a fairly comprehensive Z80 instruction test. +

+

The assembler for this test only runs under DOS. To assemble + under Unix/Linux, the "dosbox" DOS emulator, DOSBox, .[4] is required. A script + to run the assembler under dosbox, as well as the tvs80.asm source, + is checked in under the "tests/tvs80" directory. +

+

+
 TOC 
+

3 References

+ + + + + + + + + +
[1]Wallner, D., "VHDL T80 Core".
[2]"Small Device C Compiler".
[3]Vanvick, A., "GPL Cver Simulator".
[4]"DOSBox".
+ +

+
 TOC 
+

Author's Address

+ + + + + + + +
 Guy Hutchison
 OpenCores.org
EMail: ghutchis@opencores.org
+ Index: branches/restruc2/doc/env_io_map.txt =================================================================== --- branches/restruc2/doc/env_io_map.txt (nonexistent) +++ branches/restruc2/doc/env_io_map.txt (revision 47) @@ -0,0 +1,52 @@ + +================================================== +TV80 Microprocessor Core Environment Documentation +================================================== + +Environment Memory Map: + +Environment memory space is divided into a 32k ROM region and a 32k RAM +region, as follows: + + 0000-7FFF: ROM + 8000-FFFF: RAM + +Environment I/O space is allocated as follows: + + 00-0F: Unused + 10-1F: Test devices + 20-7F: Unused + 80-8F: Environment control + A0-FF: Unused + +The Environment control registers are: + + 80 : Simulation control + + Write '01' to end simulation with test passed + Write '02' to end with test failed + Write '03' to turn on dumping + Write '04' to turn off dumping + + 81 : Message output + + Write characters to this port one at a time. When the + newline ('\n', ASCII 0x0A) character is written, the + environment will print out the collected string. + + 82 : Timeout control + + Bit[0] enables the timeout counter + Bit[1] resets the counter to 0 + Timeout counter defaults to enabled at simulation start + + 83 : Max timeout [low] + 84 : Max timeout [high] + + Holds 16-bit timeout value (amount of time in clocks before + timeout error occurs). + + 90 : Interrupt countdown + + When set, starts a countdown (in clocks) until assertion of + the INT_N signal.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.