Initial commit.

This commit is contained in:
Stephen Checkoway 2017-08-12 13:12:35 -05:00
commit 88638f076a
23 changed files with 5774 additions and 0 deletions

1462
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2008 Steve Checkoway
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.

172
Makefile Normal file
View File

@ -0,0 +1,172 @@
# Copyright (c) 2008 Steve Checkoway
#
# 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.
CPPFLAGS += -Iinclude
CFLAGS += -O3
package := zel
version := 0.1
distname := lib$(package)-$(version)
prefix := /usr/local
exec_prefix := $(prefix)
includedir := $(prefix)/include
datarootdir := $(prefix)/share
datadir := $(datarootdir)
docdir := $(datarootdir)/doc/$(package)
htmldir := $(docdir)
pdfdir := $(docdir)
libdir := $(exec_prefix)/lib
mandir := $(datarootdir)/man
man3dir := $(mandir)/man3
INSTALL := install
INSTALL_PROGRAM := $(INSTALL) -m 0755
INSTALL_DATA := $(INSTALL) -m 0644
spec := $(wildcard tables/*.spec)
itables := $(spec:.spec=.tab)
here := $(shell pwd)
dist_source := z80.c \
z80_instructions.c \
include/zel/z80.h \
include/zel/z80_instructions.h \
include/zel/z80_types.h \
include/zel/z80_types.tab \
tables/gen.pl \
$(spec) \
$(itables) \
Makefile \
Doxyfile \
LICENSE \
tests/Makefile \
$(wildcard tests/*.c) \
doc/$(distname).pdf
.PHONY: all check clean distclean mostlyclean maintainer-clean dist distcheck doc-clean \
install install-html install-pdf html pdf uninstall uninstall-doc install-doc installcheck
all: libzel.a
libzel.a: z80.o z80_instructions.o
$(AR) -cr $@ $?
ranlib $@
tables/%.tab: tables/%.spec tables/gen.pl
perl tables/gen.pl $< > $@
include/zel/z80_types.tab: $(itables)
awk '{ split($$2,a,/_/); sub(/,/,"",a[1]); printf "%s //!< %s\n", $$2, tolower(a[1]) }' \
$(itables) |sort|uniq > $@
z80.o: z80.c include/zel/z80.h include/zel/z80_instructions.h include/zel/z80_types.h include/zel/z80_types.tab
z80_instructions.o: z80_instructions.c include/zel/z80_instructions.h include/zel/z80.h include/zel/z80_types.h include/zel/z80_types.tab $(itables)
check: all
$(MAKE) -C tests check
installcheck:
$(MAKE) -C tests LDFLAGS='-L$(DESTDIR)$(libdir)' CPPFLAGS='-I$(DESTDIR)$(includedir)' check
doc-clean:
$(RM) -r doc
clean: doc-clean
$(MAKE) -C tests clean
$(RM) libzel.a z80.o z80_instructions.o *~
doc: Doxyfile $(wildcard include/zel/*.h) include/zel/z80_types.tab
doxygen
pdf: doc/$(distname).pdf
doc/$(distname).pdf: doc
$(MAKE) -C doc/latex -j1
cp doc/latex/refman.pdf doc/$(distname).pdf
html: doc
man: doc
# XXX: Install the man pages once those get sorted out
install:
$(INSTALL) -d $(DESTDIR)$(libdir)
$(INSTALL_PROGRAM) libzel.a $(DESTDIR)$(libdir)
$(INSTALL) -d $(DESTDIR)$(includedir)/zel
$(INSTALL_DATA) include/zel/z80.h $(DESTDIR)$(includedir)/zel
$(INSTALL_DATA) include/zel/z80_instructions.h $(DESTDIR)$(includedir)/zel
$(INSTALL_DATA) include/zel/z80_types.h $(DESTDIR)$(includedir)/zel
$(INSTALL_DATA) include/zel/z80_types.tab $(DESTDIR)$(includedir)/zel
uninstall: uninstall-doc
$(RM) $(DESTDIR)$(libdir)/libzel.a
$(RM) $(DESTDIR)$(includedir)/zel/z80.h
$(RM) $(DESTDIR)$(includedir)/zel/z80_instructions.h
$(RM) $(DESTDIR)$(includedir)/zel/z80_types.h
$(RM) $(DESTDIR)$(includedir)/zel/z80_types.tab
rmdir $(DESTDIR)$(includedir)/zel
install-doc: install-html install-pdf
uninstall-doc:
$(RM) -r $(DESTDIR)$(htmldir)/html
$(RM) $(DESTDIR)$(pdfdir)/$(distname).pdf
rmdir $(DESTDIR)$(htmldir)
if [ x$(DESTDIR)$(htmldir) != x$(DESTDIR)$(pdfdir) ]; then \
rmdir $(DESTDIR)$(pdfdir); \
fi
install-html:
$(INSTALL) -d $(DESTDIR)$(htmldir)/html
$(INSTALL_DATA) doc/html/* $(DESTDIR)$(htmldir)/html
install-pdf:
$(INSTALL) -d $(DESTDIR)$(pdfdir)
$(INSTALL_DATA) doc/$(distname).pdf $(DESTDIR)$(pdfdir)
dist: $(distname).tar.gz
$(distname).tar.gz: $(dist_source)
mkdir $(distname)
for i in $(dist_source); do \
d=`dirname $$i`; \
mkdir -p $(distname)/$$d; \
cp $$i $(distname)/$$i; \
done
cp -r doc/html $(distname)/doc
cp -r doc/man $(distname)/doc
tar zcf $(distname).tar.gz $(distname)
$(RM) -r $(distname)
distcheck: $(distname).tar.gz
tar zxf $(distname).tar.gz
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst check
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst doc
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst install
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst install-doc
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst installcheck
$(MAKE) -C $(distname) prefix=$(here)/$(distname)/_inst uninstall
$(RM) -r $(distname)
distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) include/zel/z80_types.tab $(itables)

219
include/zel/z80.h Normal file
View File

@ -0,0 +1,219 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
/*! \file
*
* Create and run a z80 processor instance.
* \author Steve Checkoway
* \version 0.1
* \date 2008
*/
#ifndef ZEL_Z80_H
#define ZEL_Z80_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif
#include <zel/z80_types.h>
/*! Opaque type representing a z80 processor. */
typedef struct Z80_t *Z80;
/* NOTE: Changing the order of these requires changing z80_instructions.h! */
/*! 16 bit paired z80 registers. The registers ending in P are the
* primed registers.
*/
enum
{
REG_BC, //!< z80 register bc.
REG_DE, //!< z80 register de.
REG_HL, //!< z80 register hl.
REG_AF, //!< z80 register af.
REG_IX, //!< z80 register ix.
REG_IY, //!< z80 register iy.
REG_PC, //!< z80 register pc.
REG_SP, //!< z80 register sp.
REG_BCP, //!< z80 register bc'.
REG_DEP, //!< z80 register de'.
REG_HLP, //!< z80 register hl'.
REG_AFP, //!< z80 register af'.
REG_IR, //!< z80 register ir.
NUM_REG, //!< Number of 16 bit z80 paired registers.
};
/*! Enumerated value describing the control flow of the processor.
* \sa Z80FunctionBlock
*/
typedef enum
{
CF_CALL, //!< Call instruction.
CF_JUMP, //!< Jump instruction.
CF_RETURN, //!< Return instruction.
CF_RETURN_I, //!< Return from interrupt instruction.
CF_RETURN_N, //!< Return from nonmaskable interrupt instruction.
CF_RESTART, //!< Restart instruction.
CF_INTERRUPT, //!< Maskable interrupt.
CF_NMI, //!< Nonmaskable interrupt.
CF_HALT, //!< Halt instruction.
} ControlFlowType;
/*! A block of callbacks used by Z80_New() to control how the
* z80 interracts with its peripherials.
* \headerfile z80.h zel/z80.h
*/
typedef struct
{
/*! Read a byte of memory.
* \param addr The address to read.
* \param inst True if the z80 is reading instructions.
* \param cpu The \c Z80 instance making the read call.
* \return The byte from memory.
*/
byte (*ReadMem)(word addr, bool inst, Z80 cpu);
/*! Write a byte of memory.
* \param addr The address to write.
* \param val The byte to write.
* \param cpu The \c Z80 instance making the write call.
*/
void (*WriteMem)(word addr, byte val, Z80 cpu);
/*! Read the interrupt data.
* \param n Read the \a n th byte of data.
* \param cpu The \c Z80 instance making the read call.
*/
byte (*ReadInterruptData)(word n, Z80 cpu);
/*! Read a byte from an I/O port.
* \param addr The contents of the address bus during the
* request. The low 8 bits specify the port.
* \param cpu The \c Z80 instance making the read call.
* \return The byte from the I/O port.
*/
byte (*ReadIO)(word addr, Z80 cpu);
/*! Write a byte from an I/O port.
* \param addr The contents of the address bus during the
* request. The low 8 bits specify the port.
* \param val The byte to write.
* \param cpu The \c Z80 instance making the read call.
*/
void (*WriteIO)(word addr, byte val, Z80 cpu);
/*! Notify the peripherials that a return from interrupt
* instruction has occured.
* \param cpu The \c Z80 instance performing the notification.
*/
void (*InterruptComplete)(Z80 cpu);
/*! Optional notification of control flow. This can be set to
* \c NULL if notification is not desired.
* \param pc The address of the current instruction.
* \param target The target address of the instruction. For
* example, the jump target.
* \param type The type of control flow.
* \param cpu The \c Z80 instance performing the notification.
*/
void (*ControlFlow)(word pc, word target, ControlFlowType type, Z80 cpu);
} Z80FunctionBlock;
/*! Create a new \c Z80 instance using the callbacks specified in \a blk.
* \param blk A pointer to a block of callbacks. Only
* Z80FunctionBlock.ControlFlow() may be \c NULL.
* \return The new \c Z80 instance.
*/
Z80 Z80_New( const Z80FunctionBlock *blk );
/*! Frees the memory associated with \a cpu.
* \param cpu The \c Z80 instance to free.
*/
void Z80_Free( Z80 cpu );
/*! Perform a single step of the processor cpu.
* \param outPC If non\c NULL, \a *outPC is set to the program counter after
* the current instruction is executed.
* \param cpu The \c Z80 instance to step.
* \return The number of clock ticks that have elapsed while executing
* the instruction.
*/
int Z80_Step( word *outPC, Z80 cpu );
/*! Check if \a cpu has halted.
* \param cpu The \c Z80 instance.
* \return \c true if \a cpu has halted.
*/
bool Z80_HasHalted( Z80 cpu );
/*! Get a 16 bit paired register.
* \param reg The register to get.
* \param cpu The \c Z80 instance.
* \return The contents of the register specified by \a reg.
*/
word Z80_GetReg( int reg, Z80 cpu );
/*! Set a 16 bit paired register.
* \param reg The register to set.
* \param value The value to assign to the register.
* \param cpu The \c Z80 instance.
*/
void Z80_SetReg( int reg, word value, Z80 cpu );
/*! Disassemble the z80 instruction pointed to by \a address into \a buffer.
* \param address The address of the beginning the instruction.
* \param buffer A pointer to at least 25 bytes of storage. If buffer
* is \c NULL, then the instruction is not disassembled and only the
* length is returned.
* \param cpu The \c Z80 instance. The Z80FunctionBlock.ReadMem()
* function will be called to read the instructions.
* \return The length of the instruction in bytes.
*/
int Z80_Disassemble( word address, char *buffer, Z80 cpu );
/*! Simulate the NMI pin going active. This causes the z80 to jump to
* the nmi handler.
* \param cpu The Z80 instance.
*/
void Z80_RaiseNMI( Z80 cpu );
/*! Simulate the interrupt pin going active. If interrupts are not
* disabled, then the z80 handles the interrupt according to the
* interrupt mode.
* \param cpu The Z80 instance.
*/
void Z80_RaiseInterrupt( Z80 cpu );
/*! Cause the z80 to reissue the I/O instruction. This only has an
* effect when called during the Z80FunctionBlock.ReadIO() or
* Z80FunctionBlock.WriteIO() callbacks. It is to enable debugging by
* breaking on I/O.
* \param cpu The \c Z80 instance.
*/
void Z80_RestartIO( Z80 cpu );
/*! Clear the halt condition. Causes the processor to continue
* fetching instructions rather than performing NOPs.
* \param cpu The \c Z80 instance.
*/
void Z80_ClearHalt( Z80 cpu );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,252 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
/*! \file
*
* Functions for decoding and disassembling z80 instructions.
* \author Steve Checkoway
* \version 0.1
* \date 2008
*/
#ifndef ZEL_Z80_INSTRUCTIONS_H
#define ZEL_Z80_INSTRUCTIONS_H
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif
#include <zel/z80_types.h>
/*! The type of a z80 instruction. Many z80 instructions are similar
* and share a common type. For example, <code>add a,b</code> and
* <code>add a,c</code> have the same type.
*
* The type of each instruction can be decoded as follows. Given an
* instruction \c FOO_BAR_BAZ, \c FOO is the mnemonic, \c BAR is the
* type of the first operand and \c BAZ is the type of the second. The
* operand types are as follows:
* - \c N 8 bit immediate
* - \c NN 16 bit immediate
* - \c I 8 bit signed displacement from an index register
* - \c R 8 bit register
* - \c RR 16 bit paired register
* - \c MRR 16 bit paired register used as an address
* - \c MNN 16 bit immediate used as an address
*/
typedef enum
{
#include <zel/z80_types.tab>
//! \includedoc z80_types.tab
} InstructionType;
#ifndef BYTE_ORDER
#error define BYTE_ORDER
#endif
#if BYTE_ORDER == BIG_ENDIAN
/*! Register values for the 8 bit registers which comprise the 16 bit
* paired registers.
*/
enum
{
REG_B, //!< z80 register b.
REG_C, //!< z80 register c.
REG_D, //!< z80 register d.
REG_E, //!< z80 register e.
REG_H, //!< z80 register h.
REG_L, //!< z80 register l.
REG_A, //!< z80 register a.
REG_F, //!< z80 register f.
REG_IXH, //!< z80 register ixh.
REG_IXL, //!< z80 register ixl.
REG_IYH, //!< z80 register iyh.
REG_IYL, //!< z80 register iyl.
REG_PCH, //!< z80 register pch.
REG_PCL, //!< z80 register pcl.
/* No REG_SPH */
/* No REG_SPL */
/* No REG_BP */
/* No REG_CP */
/* No REG_DP */
/* No REG_EP */
/* No REG_HP */
/* No REG_LP */
/* No REG_AP */
/* No REG_FP */
REG_I = 24, //!< z80 register I. Interrupt page address register.
REG_R, //!< z80 register r. Memory refresh register.
INV = 0xff, //!< Invalid.
};
#elif BYTE_ORDER == LITTLE_ENDIAN
/*! Register values for the 8 bit registers which comprise the 16 bit
* paired registers.
*/
enum
{
REG_C, //!< z80 register c.
REG_B, //!< z80 register b.
REG_E, //!< z80 register e.
REG_D, //!< z80 register d.
REG_L, //!< z80 register l.
REG_H, //!< z80 register h.
REG_F, //!< z80 register f.
REG_A, //!< z80 register a.
REG_IXL, //!< z80 register ixl.
REG_IXH, //!< z80 register ixh.
REG_IYL, //!< z80 register iyl.
REG_IYH, //!< z80 register iyh.
REG_PCL, //!< z80 register pcl.
REG_PCH, //!< z80 register pch.
/* No single byte regs */
REG_R = 24, //!< z80 register r. Memory refresh register.
REG_I, //!< z80 register I. Interrupt page address register.
INV = 0xff, //!< Invalid.
};
#else
#error What endianness are you using?
#endif
/*! Condition flag bits as stored in register \c f.
* The flags \c x and \c y are listed as unspecified by the z80 CPU
* User's Manual but they are modified by a number of instructions.
*/
enum
{
FLAG_C, //!< Carry flag.
FLAG_N, //!< Add/subtract flag.
FLAG_P, //!< Parity/overflow flag (P/V).
FLAG_X, //!< Flag 3.
FLAG_H, //!< Half-carry flag.
FLAG_Y, //!< Flag 5.
FLAG_Z, //!< Zero flag.
FLAG_S, //!< Sign flag.
};
/*! Condition flags. The condition is met if the corresponding flag is
* set appropriately.
*/
enum
{
COND_NZ = -FLAG_Z-1, //!< Flag Z is reset.
COND_Z = FLAG_Z, //!< Flag Z is set.
COND_NC = -FLAG_C-1, //!< Flag C is reset.
COND_C = FLAG_C, //!< Flag C is set.
COND_PO = -FLAG_P-1, //!< Flag P/V is reset.
COND_PE = FLAG_P, //!< Flag P/V is set.
COND_P = -FLAG_S-1, //!< Flag S is reset.
COND_M = FLAG_S, //!< Flag S is set.
};
/* Exactly two instructions contain both an offset and an immediate:
* dd36 d n: ld (ix+d),n
* fd36 d n: ld (iy+d),n */
/*! Describes the layout of the operands for an instruction. */
enum
{
TYPE_NONE, //!< No operands.
TYPE_IMM_N, //!< 8 bit immediate.
TYPE_IMM_NN, //!< 16 bit immediate.
TYPE_OFFSET, //!< 8 bit signed offset.
TYPE_DISP, //!< 8 bit signed offset - 2.
TYPE_OFFSET_IMM_N, //!< 8 bit signed offset and 8 bit immediate.
};
// 4 (3) words native sized words on 32 (64) bit machine.
/*! Uniform template for the instruction tables.
* \headerfile z80_instructions.h zel/z80_instructions.h
*/
typedef struct
{
InstructionType type; //!< Type of the instruction.
int16_t operand1; //!< Type of the first operand, if any.
int16_t operand2; //!< Type of the second operand, if any.
int16_t extra; //!< Type of third operand or tstates when a branch is taken, if applicable.
uint8_t tstates; //!< Base number of clock ticks the instruction takes.
uint8_t operand_types; //!< Operand layout in memory for the instruction.
const char *format; //!< Format specifier string for disassembly.
} InstructionTemplate;
/*! Completely describes an instruction.
* \headerfile z80_instructions.h zel/z80_instructions.h
*/
typedef struct
{
const InstructionTemplate *IT; //!< Template for the instruction.
unsigned int immediate; //!< Immediate value, if any.
unsigned int additional_tstates;//!< Additional clock ticks.
unsigned int r_increment; //!< Amount by which the \c r register is incremented.
int offset; //!< Offset, if any.
} Instruction;
/*! Instruction table for unprefixed instructions. */
extern const InstructionTemplate Unprefixed[256];
/*! Instruction table for cb prefixed instructions. */
extern const InstructionTemplate CB_Prefixed[256];
/*! Instruction table for dd prefixed instructions. */
extern const InstructionTemplate DD_Prefixed[256];
/*! Instruction table for ddcb prefixed instructions. */
extern const InstructionTemplate DDCB_Prefixed[256];
/*! Instruction table for ed prefixed instructions. */
extern const InstructionTemplate ED_Prefixed[256];
/*! Instruction table for fd prefixed instructions. */
extern const InstructionTemplate FD_Prefixed[256];
/*! Instruction table for fdcb prefixed instructions. */
extern const InstructionTemplate FDCB_Prefixed[256];
/*! Memory reading callback.
* \param addr The address to read.
* \param data Callback data from IF_ID().
* \return The value at address \a addr.
*/
typedef byte (*ReadMemFunction)(word addr, void *data);
/*! Instruction fetch and instruction decode. Fetchs and decodes the
* instruction pointed to by \a address into \a *inst.
* \param inst Pointer to an \c Instruction. \a *inst is set to the
* decoded instruction.
* \param address The address of the instruction.
* \param ReadMem Called repeatedly to get bytes of the instruction.
* \a data is passed as the \c data argument.
* \param data Arbitrary data passed to the \a ReadMem callback.
* \return The length of the instruction.
*/
int IF_ID( Instruction *inst, word address, ReadMemFunction ReadMem, void *data );
/*! Disassemble the instruction pointed to by \a inst into \a buffer.
* \param inst Pointer to an \c Instruction.
* \param buffer Buffer into which the disassembly is written. It must
* be large enough to hold 25 bytes.
*/
void DisassembleInstruction( const Instruction *inst, char *buffer );
#ifdef __cplusplus
}
#endif
#endif

46
include/zel/z80_types.h Normal file
View File

@ -0,0 +1,46 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
/*! \file
*
* Types used by the z80.
* \author Steve Checkoway
* \version 0.1
* \date 2008
*/
#ifndef ZEL_Z80_TYPES_H
#define ZEL_Z80_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*! A single byte. */
typedef uint8_t byte;
/*! A signed byte used for displacement. */
typedef int8_t sbyte;
/*! A 16 bit z80 word. */
typedef uint16_t word;
#ifdef __cplusplus
}
#endif
#endif

256
tables/cb_prefix.spec Normal file
View File

@ -0,0 +1,256 @@
CB00 RLC B 8 2 2
CB01 RLC C 8 2 2
CB02 RLC D 8 2 2
CB03 RLC E 8 2 2
CB04 RLC H 8 2 2
CB05 RLC L 8 2 2
CB06 RLC (HL) 15 4 2
CB07 RLC A 8 2 2
CB08 RRC B 8 2 2
CB09 RRC C 8 2 2
CB0A RRC D 8 2 2
CB0B RRC E 8 2 2
CB0C RRC H 8 2 2
CB0D RRC L 8 2 2
CB0E RRC (HL) 15 4 2
CB0F RRC A 8 2 2
CB10 RL B 8 2 2
CB11 RL C 8 2 2
CB12 RL D 8 2 2
CB13 RL E 8 2 2
CB14 RL H 8 2 2
CB15 RL L 8 2 2
CB16 RL (HL) 15 4 2
CB17 RL A 8 2 2
CB18 RR B 8 2 2
CB19 RR C 8 2 2
CB1A RR D 8 2 2
CB1B RR E 8 2 2
CB1C RR H 8 2 2
CB1D RR L 8 2 2
CB1E RR (HL) 15 4 2
CB1F RR A 8 2 2
CB20 SLA B 8 2 2
CB21 SLA C 8 2 2
CB22 SLA D 8 2 2
CB23 SLA E 8 2 2
CB24 SLA H 8 2 2
CB25 SLA L 8 2 2
CB26 SLA (HL) 15 4 2
CB27 SLA A 8 2 2
CB28 SRA B 8 2 2
CB29 SRA C 8 2 2
CB2A SRA D 8 2 2
CB2B SRA E 8 2 2
CB2C SRA H 8 2 2
CB2D SRA L 8 2 2
CB2E SRA (HL) 15 4 2
CB2F SRA A 8 2 2
CB30 SLL B 8 2 2
CB31 SLL C 8 2 2
CB32 SLL D 8 2 2
CB33 SLL E 8 2 2
CB34 SLL H 8 2 2
CB35 SLL L 8 2 2
CB36 SLL (HL) 15 4 2
CB37 SLL A 8 2 2
CB38 SRL B 8 2 2
CB39 SRL C 8 2 2
CB3A SRL D 8 2 2
CB3B SRL E 8 2 2
CB3C SRL H 8 2 2
CB3D SRL L 8 2 2
CB3E SRL (HL) 15 4 2
CB3F SRL A 8 2 2
CB40 BIT 0,B 8 2 2
CB41 BIT 0,C 8 2 2
CB42 BIT 0,D 8 2 2
CB43 BIT 0,E 8 2 2
CB44 BIT 0,H 8 2 2
CB45 BIT 0,L 8 2 2
CB46 BIT 0,(HL) 12 3 2
CB47 BIT 0,A 8 2 2
CB48 BIT 1,B 8 2 2
CB49 BIT 1,C 8 2 2
CB4A BIT 1,D 8 2 2
CB4B BIT 1,E 8 2 2
CB4C BIT 1,H 8 2 2
CB4D BIT 1,L 8 2 2
CB4E BIT 1,(HL) 12 3 2
CB4F BIT 1,A 8 2 2
CB50 BIT 2,B 8 2 2
CB51 BIT 2,C 8 2 2
CB52 BIT 2,D 8 2 2
CB53 BIT 2,E 8 2 2
CB54 BIT 2,H 8 2 2
CB55 BIT 2,L 8 2 2
CB56 BIT 2,(HL) 12 3 2
CB57 BIT 2,A 8 2 2
CB58 BIT 3,B 8 2 2
CB59 BIT 3,C 8 2 2
CB5A BIT 3,D 8 2 2
CB5B BIT 3,E 8 2 2
CB5C BIT 3,H 8 2 2
CB5D BIT 3,L 8 2 2
CB5E BIT 3,(HL) 12 3 2
CB5F BIT 3,A 8 2 2
CB60 BIT 4,B 8 2 2
CB61 BIT 4,C 8 2 2
CB62 BIT 4,D 8 2 2
CB63 BIT 4,E 8 2 2
CB64 BIT 4,H 8 2 2
CB65 BIT 4,L 8 2 2
CB66 BIT 4,(HL) 12 3 2
CB67 BIT 4,A 8 2 2
CB68 BIT 5,B 8 2 2
CB69 BIT 5,C 8 2 2
CB6A BIT 5,D 8 2 2
CB6B BIT 5,E 8 2 2
CB6C BIT 5,H 8 2 2
CB6D BIT 5,L 8 2 2
CB6E BIT 5,(HL) 12 3 2
CB6F BIT 5,A 8 2 2
CB70 BIT 6,B 8 2 2
CB71 BIT 6,C 8 2 2
CB72 BIT 6,D 8 2 2
CB73 BIT 6,E 8 2 2
CB74 BIT 6,H 8 2 2
CB75 BIT 6,L 8 2 2
CB76 BIT 6,(HL) 12 3 2
CB77 BIT 6,A 8 2 2
CB78 BIT 7,B 8 2 2
CB79 BIT 7,C 8 2 2
CB7A BIT 7,D 8 2 2
CB7B BIT 7,E 8 2 2
CB7C BIT 7,H 8 2 2
CB7D BIT 7,L 8 2 2
CB7E BIT 7,(HL) 12 3 2
CB7F BIT 7,A 8 2 2
CB80 RES 0,B 8 2 2
CB81 RES 0,C 8 2 2
CB82 RES 0,D 8 2 2
CB83 RES 0,E 8 2 2
CB84 RES 0,H 8 2 2
CB85 RES 0,L 8 2 2
CB86 RES 0,(HL) 15 4 2
CB87 RES 0,A 8 2 2
CB88 RES 1,B 8 2 2
CB89 RES 1,C 8 2 2
CB8A RES 1,D 8 2 2
CB8B RES 1,E 8 2 2
CB8C RES 1,H 8 2 2
CB8D RES 1,L 8 2 2
CB8E RES 1,(HL) 15 4 2
CB8F RES 1,A 8 2 2
CB90 RES 2,B 8 2 2
CB91 RES 2,C 8 2 2
CB92 RES 2,D 8 2 2
CB93 RES 2,E 8 2 2
CB94 RES 2,H 8 2 2
CB95 RES 2,L 8 2 2
CB96 RES 2,(HL) 15 4 2
CB97 RES 2,A 8 2 2
CB98 RES 3,B 8 2 2
CB99 RES 3,C 8 2 2
CB9A RES 3,D 8 2 2
CB9B RES 3,E 8 2 2
CB9C RES 3,H 8 2 2
CB9D RES 3,L 8 2 2
CB9E RES 3,(HL) 15 4 2
CB9F RES 3,A 8 2 2
CBA0 RES 4,B 8 2 2
CBA1 RES 4,C 8 2 2
CBA2 RES 4,D 8 2 2
CBA3 RES 4,E 8 2 2
CBA4 RES 4,H 8 2 2
CBA5 RES 4,L 8 2 2
CBA6 RES 4,(HL) 15 4 2
CBA7 RES 4,A 8 2 2
CBA8 RES 5,B 8 2 2
CBA9 RES 5,C 8 2 2
CBAA RES 5,D 8 2 2
CBAB RES 5,E 8 2 2
CBAC RES 5,H 8 2 2
CBAD RES 5,L 8 2 2
CBAE RES 5,(HL) 15 4 2
CBAF RES 5,A 8 2 2
CBB0 RES 6,B 8 2 2
CBB1 RES 6,C 8 2 2
CBB2 RES 6,D 8 2 2
CBB3 RES 6,E 8 2 2
CBB4 RES 6,H 8 2 2
CBB5 RES 6,L 8 2 2
CBB6 RES 6,(HL) 15 4 2
CBB7 RES 6,A 8 2 2
CBB8 RES 7,B 8 2 2
CBB9 RES 7,C 8 2 2
CBBA RES 7,D 8 2 2
CBBB RES 7,E 8 2 2
CBBC RES 7,H 8 2 2
CBBD RES 7,L 8 2 2
CBBE RES 7,(HL) 15 4 2
CBBF RES 7,A 8 2 2
CBC0 SET 0,B 8 2 2
CBC1 SET 0,C 8 2 2
CBC2 SET 0,D 8 2 2
CBC3 SET 0,E 8 2 2
CBC4 SET 0,H 8 2 2
CBC5 SET 0,L 8 2 2
CBC6 SET 0,(HL) 15 4 2
CBC7 SET 0,A 8 2 2
CBC8 SET 1,B 8 2 2
CBC9 SET 1,C 8 2 2
CBCA SET 1,D 8 2 2
CBCB SET 1,E 8 2 2
CBCC SET 1,H 8 2 2
CBCD SET 1,L 8 2 2
CBCE SET 1,(HL) 15 4 2
CBCF SET 1,A 8 2 2
CBD0 SET 2,B 8 2 2
CBD1 SET 2,C 8 2 2
CBD2 SET 2,D 8 2 2
CBD3 SET 2,E 8 2 2
CBD4 SET 2,H 8 2 2
CBD5 SET 2,L 8 2 2
CBD6 SET 2,(HL) 15 4 2
CBD7 SET 2,A 8 2 2
CBD8 SET 3,B 8 2 2
CBD9 SET 3,C 8 2 2
CBDA SET 3,D 8 2 2
CBDB SET 3,E 8 2 2
CBDC SET 3,H 8 2 2
CBDD SET 3,L 8 2 2
CBDE SET 3,(HL) 15 4 2
CBDF SET 3,A 8 2 2
CBE0 SET 4,B 8 2 2
CBE1 SET 4,C 8 2 2
CBE2 SET 4,D 8 2 2
CBE3 SET 4,E 8 2 2
CBE4 SET 4,H 8 2 2
CBE5 SET 4,L 8 2 2
CBE6 SET 4,(HL) 15 4 2
CBE7 SET 4,A 8 2 2
CBE8 SET 5,B 8 2 2
CBE9 SET 5,C 8 2 2
CBEA SET 5,D 8 2 2
CBEB SET 5,E 8 2 2
CBEC SET 5,H 8 2 2
CBED SET 5,L 8 2 2
CBEE SET 5,(HL) 15 4 2
CBEF SET 5,A 8 2 2
CBF0 SET 6,B 8 2 2
CBF1 SET 6,C 8 2 2
CBF2 SET 6,D 8 2 2
CBF3 SET 6,E 8 2 2
CBF4 SET 6,H 8 2 2
CBF5 SET 6,L 8 2 2
CBF6 SET 6,(HL) 15 4 2
CBF7 SET 6,A 8 2 2
CBF8 SET 7,B 8 2 2
CBF9 SET 7,C 8 2 2
CBFA SET 7,D 8 2 2
CBFB SET 7,E 8 2 2
CBFC SET 7,H 8 2 2
CBFD SET 7,L 8 2 2
CBFE SET 7,(HL) 15 4 2
CBFF SET 7,A 8 2 2

252
tables/dd_prefix.spec Normal file
View File

@ -0,0 +1,252 @@
DD00 NOP 8
DD01 n n LD BC,nn 14
DD02 LD (BC),A 11
DD03 INC BC 10
DD04 INC B 8
DD05 DEC B 8
DD06 n LD B,n 11
DD07 RLCA 8
DD08 EX AF,AF' 8
DD09 ADD IX,BC 15
DD0A LD A,(BC) 11
DD0B DEC BC 10
DD0C INC C 8
DD0D DEC C 8
DD0E n LD C,n 11
DD0F RRCA 8
DD10 e DJNZ (PC+e) 12/17
DD11 n n LD DE,nn 14
DD12 LD (DE),A 11
DD13 INC DE 10
DD14 INC D 8
DD15 DEC D 8
DD16 n LD D,n 11
DD17 RLA 8
DD18 e JR (PC+e) 16
DD19 ADD IX,DE 15
DD1A LD A,(DE) 11
DD1B DEC DE 10
DD1C INC E 8
DD1D DEC E 8
DD1E n LD E,n 11
DD1F RRA 8
DD20 e JR NZ,(PC+e) 16/11
DD21 n n LD IX,nn 14
DD22 n n LD (nn),IX 16
DD23 INC IX 10
DD24 INC IXH 10 guess
DD25 DEC IXH 10 guess
DD26 n LD IXH,n 11 guess
DD27 DAA 8
DD28 e JR Z,(PC+e) 16/11
DD29 ADD IX,IX 15
DD2A n n LD IX,(nn) 14
DD2B DEC IX 10
DD2C INC IXL 10 guess
DD2D DEC IXL 10 guess
DD2E n LD IXL,n 11 guess
DD2F CPL 8
DD30 e JR NC,(PC+e) 16/11
DD31 n n LD SP,nn 14
DD32 n n LD (nn),A 17
DD33 INC SP 10
DD34 d INC (IX+d) 23
DD35 d DEC (IX+d) 23
DD36 d n LD (IX+d),n 19
DD37 SCF 8
DD38 e JR c,(PC+e) 16/11
DD39 ADD IX,SP 15
DD3A n n LD A,(nn) 17
DD3B DEC SP 10
DD3C INC A 8
DD3D DEC A 8
DD3E n LD A,n 11
DD3F CCF 8
DD40 LD B,B 8
DD41 LD B,C 8
DD42 LD B,D 8
DD43 LD B,E 8
DD44 LD B,IXH 8 guess
DD45 LD B,IXL 8 guess
DD46 d LD B,(IX+d) 19
DD47 LD B,A 8
DD48 LD C,B 8
DD49 LD C,C 8
DD4A LD C,D 8
DD4B LD C,E 8
DD4C LD C,IXH 8 guess
DD4D LD C,IXL 8 guess
DD4E d LD C,(IX+d) 19
DD4F LD C,A 8
DD50 LD D,B 8
DD51 LD D,C 8
DD52 LD D,D 8
DD53 LD D,E 8
DD54 LD D,IXH 8 guess
DD55 LD D,IXL 8 guess
DD56 d LD D,(IX+d) 19
DD57 LD D,A 8
DD58 LD E,B 8
DD59 LD E,C 8
DD5A LD E,D 8
DD5B LD E,E 8
DD5C LD E,IXH 8 guess
DD5D LD E,IXL 8 guess
DD5E d LD E,(IX+d) 19
DD5F LD E,A 8
DD60 LD IXH,B 8 guess
DD61 LD IXH,C 8 guess
DD62 LD IXH,D 8 guess
DD63 LD IXH,E 8 guess
DD64 LD IXH,IXH 8 guess
DD65 LD IXH,IXL 8 guess
DD66 d LD H,(IX+d) 19
DD67 LD IXH,A 8 guess
DD68 LD IXL,B 8 guess
DD69 LD IXL,C 8 guess
DD6A LD IXL,D 8 guess
DD6B LD IXL,E 8 guess
DD6C LD IXL,IXH 8 guess
DD6D LD IXL,IXL 8 guess
DD6E d LD L,(IX+d) 19
DD6F LD IXL,A 8 guess
DD70 d LD (IX+d),B 19
DD71 d LD (IX+d),C 19
DD72 d LD (IX+d),D 19
DD73 d LD (IX+d),E 19
DD74 d LD (IX+d),H 19
DD75 d LD (IX+d),L 19
DD76 HALT 8
DD77 d LD (IX+d),A 19
DD78 LD A,B 8
DD79 LD A,C 8
DD7A LD A,D 8
DD7B LD A,E 8
DD7C LD A,IXH 8 guess
DD7D LD A,IXL 8 guess
DD7E d LD A,(IX+d) 19
DD7F LD A,A 8
DD80 ADD A,B 8
DD81 ADD A,C 8
DD82 ADD A,D 8
DD83 ADD A,E 8
DD84 ADD A,IXH 8 guess
DD85 ADD A,IXL 8 guess
DD86 d ADD A,(IX+d) 19
DD87 ADD A,A 8
DD88 ADC A,B 8
DD89 ADC A,C 8
DD8A ADC A,D 8
DD8B ADC A,E 8
DD8C ADC A,IXH 8 guess
DD8D ADC A,IXL 8 guess
DD8E d ADC A,(IX+d) 19
DD8F ADC A,A 8
DD90 SUB B 8
DD91 SUB C 8
DD92 SUB D 8
DD93 SUB E 8
DD94 SUB IXH 8 guess
DD95 SUB IXL 8 guess
DD96 d SUB (IX+d) 19
DD97 SUB A 8
DD98 SBC A,B 8
DD99 SBC A,C 8
DD9A SBC A,D 8
DD9B SBC A,E 8
DD9C SBC A,IXH 8 guess
DD9D SBC A,IXL 8 guess
DD9E d SBC A,(IX+d) 19
DD9F SBC A,A 8
DDA0 AND B 8
DDA1 AND C 8
DDA2 AND D 8
DDA3 AND E 8
DDA4 AND IXH 8 guess
DDA5 AND IXL 8 guess
DDA6 d AND (IX+d) 19
DDA7 AND A 8
DDA8 XOR B 8
DDA9 XOR C 8
DDAA XOR D 8
DDAB XOR E 8
DDAC XOR IXH 8 guess
DDAD XOR IXL 8 guess
DDAE d XOR (IX+d) 19
DDAF XOR A 8
DDB0 OR B 8
DDB1 OR C 8
DDB2 OR D 8
DDB3 OR E 8
DDB4 OR IXH 8 guess
DDB5 OR IXL 8 guess
DDB6 d OR (IX+d) 19
DDB7 OR A 8
DDB8 CP B 8
DDB9 CP C 8
DDBA CP D 8
DDBB CP E 8
DDBC CP IXH 8 guess
DDBD CP IXL 8 guess
DDBE d CP (IX+d) 19
DDBF CP A 8
DDC0 RET NZ 15/9
DDC1 POP BC 14
DDC2 n n JP NZ,(nn) 14
DDC3 n n JP (nn) 14
DDC4 n n CALL NZ,(nn) 21/14
DDC5 PUSH BC 15
DDC6 n ADD A,n 11
DDC7 RST 0H 15
DDC8 RET Z 15/9
DDC9 RET 14
DDCA n n JP Z,(nn) 14
DDCC n n CALL Z,(nn) 21/14
DDCD n n CALL (nn) 21
DDCE n ADC A,n 11
DDCF RST 8H 15
DDD0 RET NC 9
DDD1 POP DE 14
DDD2 n n JP NC,(nn) 14
DDD3 n OUT (n),A 15
DDD4 n n CALL NC,(nn) 21/14
DDD5 PUSH DE 15
DDD6 n SUB n 11
DDD7 RST 10H 15
DDD8 RET c 9
DDD9 EXX 8
DDDA n n JP c,(nn) 14
DDDB n IN A,(n) 15
DDDC n n CALL c,(nn) 21/14
DDDE n SBC A,n 19
DDDF RST 18H 15
DDE0 RET PO 15/9
DDE1 POP IX 14
DDE2 n n JP PO,(nn) 14
DDE3 EX (SP),IX 23
DDE4 n n CALL PO,(nn) 21/14
DDE5 PUSH IX 15
DDE6 n AND n 11
DDE7 RST 20H 15
DDE8 RET PE 15/9
DDE9 JP (IX) 8
DDEA n n JP PE,(nn) 14
DDEB EX DE,HL 8
DDEC n n CALL PE,(nn) 21/14
DDEE n XOR n 11
DDEF RST 28H 15
DDF0 RET P 15/9
DDF1 POP AF 14
DDF2 n n JP P,(nn) 14
DDF3 DI 8
DDF4 n n CALL P,(nn) 21/14
DDF5 PUSH AF 15
DDF6 n OR n 11
DDF7 RST 30H 15
DDF8 RET M 15/9
DDF9 LD SP,IX 10
DDFA n n JP M,(nn) 14
DDFB EI 8
DDFC n n CALL M,(nn) 21/14
DDFE n CP n 11
DDFF RST 38H 15

256
tables/ddcb_prefix.spec Normal file
View File

@ -0,0 +1,256 @@
DDCB d 00 LD B,RLC (IX+d) 23
DDCB d 01 LD C,RLC (IX+d) 23
DDCB d 02 LD D,RLC (IX+d) 23
DDCB d 03 LD E,RLC (IX+d) 23
DDCB d 04 LD H,RLC (IX+d) 23
DDCB d 05 LD L,RLC (IX+d) 23
DDCB d 06 RLC (IX+d) 23
DDCB d 07 LD A,RLC (IX+d) 23
DDCB d 08 LD B,RRC (IX+d) 23
DDCB d 09 LD C,RRC (IX+d) 23
DDCB d 0A LD D,RRC (IX+d) 23
DDCB d 0B LD E,RRC (IX+d) 23
DDCB d 0C LD H,RRC (IX+d) 23
DDCB d 0D LD L,RRC (IX+d) 23
DDCB d 0E RRC (IX+d) 23
DDCB d 0F LD A,RRC (IX+d) 23
DDCB d 10 LD B,RL (IX+d) 23
DDCB d 11 LD C,RL (IX+d) 23
DDCB d 12 LD D,RL (IX+d) 23
DDCB d 13 LD E,RL (IX+d) 23
DDCB d 14 LD H,RL (IX+d) 23
DDCB d 15 LD L,RL (IX+d) 23
DDCB d 16 RL (IX+d) 23
DDCB d 17 LD A,RL (IX+d) 23
DDCB d 18 LD B,RR (IX+d) 23
DDCB d 19 LD C,RR (IX+d) 23
DDCB d 1A LD D,RR (IX+d) 23
DDCB d 1B LD E,RR (IX+d) 23
DDCB d 1C LD H,RR (IX+d) 23
DDCB d 1D LD L,RR (IX+d) 23
DDCB d 1E RR (IX+d) 23
DDCB d 1F LD A,RR (IX+d) 23
DDCB d 20 LD B,SLA (IX+d) 23
DDCB d 21 LD C,SLA (IX+d) 23
DDCB d 22 LD D,SLA (IX+d) 23
DDCB d 23 LD E,SLA (IX+d) 23
DDCB d 24 LD H,SLA (IX+d) 23
DDCB d 25 LD L,SLA (IX+d) 23
DDCB d 26 SLA (IX+d) 23
DDCB d 27 LD A,SLA (IX+d) 23
DDCB d 28 LD B,SRA (IX+d) 23
DDCB d 29 LD C,SRA (IX+d) 23
DDCB d 2A LD D,SRA (IX+d) 23
DDCB d 2B LD E,SRA (IX+d) 23
DDCB d 2C LD H,SRA (IX+d) 23
DDCB d 2D LD L,SRA (IX+d) 23
DDCB d 2E SRA (IX+d) 23
DDCB d 2F LD A,SRA (IX+d) 23
DDCB d 30 LD B,SLL (IX+d) 23
DDCB d 31 LD C,SLL (IX+d) 23
DDCB d 32 LD D,SLL (IX+d) 23
DDCB d 33 LD E,SLL (IX+d) 23
DDCB d 34 LD H,SLL (IX+d) 23
DDCB d 35 LD L,SLL (IX+d) 23
DDCB d 36 SLL (IX+d) 23
DDCB d 37 LD A,SLL (IX+d) 23
DDCB d 38 LD B,SRL (IX+d) 23
DDCB d 39 LD C,SRL (IX+d) 23
DDCB d 3A LD D,SRL (IX+d) 23
DDCB d 3B LD E,SRL (IX+d) 23
DDCB d 3C LD H,SRL (IX+d) 23
DDCB d 3D LD L,SRL (IX+d) 23
DDCB d 3E SRL (IX+d) 23
DDCB d 3F LD A,SRL (IX+d) 23
DDCB d 40 BIT 0,(IX+d) 20
DDCB d 41 BIT 0,(IX+d) 20
DDCB d 42 BIT 0,(IX+d) 20
DDCB d 43 BIT 0,(IX+d) 20
DDCB d 44 BIT 0,(IX+d) 20
DDCB d 45 BIT 0,(IX+d) 20
DDCB d 46 BIT 0,(IX+d) 20
DDCB d 47 BIT 0,(IX+d) 20
DDCB d 48 BIT 1,(IX+d) 20
DDCB d 49 BIT 1,(IX+d) 20
DDCB d 4A BIT 1,(IX+d) 20
DDCB d 4B BIT 1,(IX+d) 20
DDCB d 4C BIT 1,(IX+d) 20
DDCB d 4D BIT 1,(IX+d) 20
DDCB d 4E BIT 1,(IX+d) 20
DDCB d 4F BIT 1,(IX+d) 20
DDCB d 50 BIT 2,(IX+d) 20
DDCB d 51 BIT 2,(IX+d) 20
DDCB d 52 BIT 2,(IX+d) 20
DDCB d 53 BIT 2,(IX+d) 20
DDCB d 54 BIT 2,(IX+d) 20
DDCB d 55 BIT 2,(IX+d) 20
DDCB d 56 BIT 2,(IX+d) 20
DDCB d 57 BIT 2,(IX+d) 20
DDCB d 58 BIT 3,(IX+d) 20
DDCB d 59 BIT 3,(IX+d) 20
DDCB d 5A BIT 3,(IX+d) 20
DDCB d 5B BIT 3,(IX+d) 20
DDCB d 5C BIT 3,(IX+d) 20
DDCB d 5D BIT 3,(IX+d) 20
DDCB d 5E BIT 3,(IX+d) 20
DDCB d 5F BIT 3,(IX+d) 20
DDCB d 60 BIT 4,(IX+d) 20
DDCB d 61 BIT 4,(IX+d) 20
DDCB d 62 BIT 4,(IX+d) 20
DDCB d 63 BIT 4,(IX+d) 20
DDCB d 64 BIT 4,(IX+d) 20
DDCB d 65 BIT 4,(IX+d) 20
DDCB d 66 BIT 4,(IX+d) 20
DDCB d 67 BIT 4,(IX+d) 20
DDCB d 68 BIT 5,(IX+d) 20
DDCB d 69 BIT 5,(IX+d) 20
DDCB d 6A BIT 5,(IX+d) 20
DDCB d 6B BIT 5,(IX+d) 20
DDCB d 6C BIT 5,(IX+d) 20
DDCB d 6D BIT 5,(IX+d) 20
DDCB d 6E BIT 5,(IX+d) 20
DDCB d 6F BIT 5,(IX+d) 20
DDCB d 70 BIT 6,(IX+d) 20
DDCB d 71 BIT 6,(IX+d) 20
DDCB d 72 BIT 6,(IX+d) 20
DDCB d 73 BIT 6,(IX+d) 20
DDCB d 74 BIT 6,(IX+d) 20
DDCB d 75 BIT 6,(IX+d) 20
DDCB d 76 BIT 6,(IX+d) 20
DDCB d 77 BIT 6,(IX+d) 20
DDCB d 78 BIT 7,(IX+d) 20
DDCB d 79 BIT 7,(IX+d) 20
DDCB d 7A BIT 7,(IX+d) 20
DDCB d 7B BIT 7,(IX+d) 20
DDCB d 7C BIT 7,(IX+d) 20
DDCB d 7D BIT 7,(IX+d) 20
DDCB d 7E BIT 7,(IX+d) 20
DDCB d 7F BIT 7,(IX+d) 20
DDCB d 80 LD B,RES 0,(IX+d) 23
DDCB d 81 LD C,RES 0,(IX+d) 23
DDCB d 82 LD D,RES 0,(IX+d) 23
DDCB d 83 LD E,RES 0,(IX+d) 23
DDCB d 84 LD H,RES 0,(IX+d) 23
DDCB d 85 LD L,RES 0,(IX+d) 23
DDCB d 86 RES 0,(IX+d) 23
DDCB d 87 LD A,RES 0,(IX+d) 23
DDCB d 88 LD B,RES 1,(IX+d) 23
DDCB d 89 LD C,RES 1,(IX+d) 23
DDCB d 8A LD D,RES 1,(IX+d) 23
DDCB d 8B LD E,RES 1,(IX+d) 23
DDCB d 8C LD H,RES 1,(IX+d) 23
DDCB d 8D LD L,RES 1,(IX+d) 23
DDCB d 8E RES 1,(IX+d) 23
DDCB d 8F LD A,RES 1,(IX+d) 23
DDCB d 90 LD B,RES 2,(IX+d) 23
DDCB d 91 LD C,RES 2,(IX+d) 23
DDCB d 92 LD D,RES 2,(IX+d) 23
DDCB d 93 LD E,RES 2,(IX+d) 23
DDCB d 94 LD H,RES 2,(IX+d) 23
DDCB d 95 LD L,RES 2,(IX+d) 23
DDCB d 96 RES 2,(IX+d) 23
DDCB d 97 LD A,RES 2,(IX+d) 23
DDCB d 98 LD B,RES 3,(IX+d) 23
DDCB d 99 LD C,RES 3,(IX+d) 23
DDCB d 9A LD D,RES 3,(IX+d) 23
DDCB d 9B LD E,RES 3,(IX+d) 23
DDCB d 9C LD H,RES 3,(IX+d) 23
DDCB d 9D LD L,RES 3,(IX+d) 23
DDCB d 9E RES 3,(IX+d) 23
DDCB d 9F LD A,RES 3,(IX+d) 23
DDCB d A0 LD B,RES 4,(IX+d) 23
DDCB d A1 LD C,RES 4,(IX+d) 23
DDCB d A2 LD D,RES 4,(IX+d) 23
DDCB d A3 LD E,RES 4,(IX+d) 23
DDCB d A4 LD H,RES 4,(IX+d) 23
DDCB d A5 LD L,RES 4,(IX+d) 23
DDCB d A6 RES 4,(IX+d) 23
DDCB d A7 LD A,RES 4,(IX+d) 23
DDCB d A8 LD B,RES 5,(IX+d) 23
DDCB d A9 LD C,RES 5,(IX+d) 23
DDCB d AA LD D,RES 5,(IX+d) 23
DDCB d AB LD E,RES 5,(IX+d) 23
DDCB d AC LD H,RES 5,(IX+d) 23
DDCB d AD LD L,RES 5,(IX+d) 23
DDCB d AE RES 5,(IX+d) 23
DDCB d AF LD A,RES 5,(IX+d) 23
DDCB d B0 LD B,RES 6,(IX+d) 23
DDCB d B1 LD C,RES 6,(IX+d) 23
DDCB d B2 LD D,RES 6,(IX+d) 23
DDCB d B3 LD E,RES 6,(IX+d) 23
DDCB d B4 LD H,RES 6,(IX+d) 23
DDCB d B5 LD L,RES 6,(IX+d) 23
DDCB d B6 RES 6,(IX+d) 23
DDCB d B7 LD A,RES 6,(IX+d) 23
DDCB d B8 LD B,RES 7,(IX+d) 23
DDCB d B9 LD C,RES 7,(IX+d) 23
DDCB d BA LD D,RES 7,(IX+d) 23
DDCB d BB LD E,RES 7,(IX+d) 23
DDCB d BC LD H,RES 7,(IX+d) 23
DDCB d BD LD L,RES 7,(IX+d) 23
DDCB d BE RES 7,(IX+d) 23
DDCB d BF LD A,RES 7,(IX+d) 23
DDCB d C0 LD B,SET 0,(IX+d) 23
DDCB d C1 LD C,SET 0,(IX+d) 23
DDCB d C2 LD D,SET 0,(IX+d) 23
DDCB d C3 LD E,SET 0,(IX+d) 23
DDCB d C4 LD H,SET 0,(IX+d) 23
DDCB d C5 LD L,SET 0,(IX+d) 23
DDCB d C6 SET 0,(IX+d) 23
DDCB d C7 LD A,SET 0,(IX+d) 23
DDCB d C8 LD B,SET 1,(IX+d) 23
DDCB d C9 LD C,SET 1,(IX+d) 23
DDCB d CA LD D,SET 1,(IX+d) 23
DDCB d CB LD E,SET 1,(IX+d) 23
DDCB d CC LD H,SET 1,(IX+d) 23
DDCB d CD LD L,SET 1,(IX+d) 23
DDCB d CE SET 1,(IX+d) 23
DDCB d CF LD A,SET 1,(IX+d) 23
DDCB d D0 LD B,SET 2,(IX+d) 23
DDCB d D1 LD C,SET 2,(IX+d) 23
DDCB d D2 LD D,SET 2,(IX+d) 23
DDCB d D3 LD E,SET 2,(IX+d) 23
DDCB d D4 LD H,SET 2,(IX+d) 23
DDCB d D5 LD L,SET 2,(IX+d) 23
DDCB d D6 SET 2,(IX+d) 23
DDCB d D7 LD A,SET 2,(IX+d) 23
DDCB d D8 LD B,SET 3,(IX+d) 23
DDCB d D9 LD C,SET 3,(IX+d) 23
DDCB d DA LD D,SET 3,(IX+d) 23
DDCB d DB LD E,SET 3,(IX+d) 23
DDCB d DC LD H,SET 3,(IX+d) 23
DDCB d DD LD L,SET 3,(IX+d) 23
DDCB d DE SET 3,(IX+d) 23
DDCB d DF LD A,SET 3,(IX+d) 23
DDCB d E0 LD B,SET 4,(IX+d) 23
DDCB d E1 LD C,SET 4,(IX+d) 23
DDCB d E2 LD D,SET 4,(IX+d) 23
DDCB d E3 LD E,SET 4,(IX+d) 23
DDCB d E4 LD H,SET 4,(IX+d) 23
DDCB d E5 LD L,SET 4,(IX+d) 23
DDCB d E6 SET 4,(IX+d) 23
DDCB d E7 LD A,SET 4,(IX+d) 23
DDCB d E8 LD B,SET 5,(IX+d) 23
DDCB d E9 LD C,SET 5,(IX+d) 23
DDCB d EA LD D,SET 5,(IX+d) 23
DDCB d EB LD E,SET 5,(IX+d) 23
DDCB d EC LD H,SET 5,(IX+d) 23
DDCB d ED LD L,SET 5,(IX+d) 23
DDCB d EE SET 5,(IX+d) 23
DDCB d EF LD A,SET 5,(IX+d) 23
DDCB d F0 LD B,SET 6,(IX+d) 23
DDCB d F1 LD C,SET 6,(IX+d) 23
DDCB d F2 LD D,SET 6,(IX+d) 23
DDCB d F3 LD E,SET 6,(IX+d) 23
DDCB d F4 LD H,SET 6,(IX+d) 23
DDCB d F5 LD L,SET 6,(IX+d) 23
DDCB d F6 SET 6,(IX+d) 23
DDCB d F7 LD A,SET 6,(IX+d) 23
DDCB d F8 LD B,SET 7,(IX+d) 23
DDCB d F9 LD C,SET 7,(IX+d) 23
DDCB d FA LD D,SET 7,(IX+d) 23
DDCB d FB LD E,SET 7,(IX+d) 23
DDCB d FC LD H,SET 7,(IX+d) 23
DDCB d FD LD L,SET 7,(IX+d) 23
DDCB d FE SET 7,(IX+d) 23
DDCB d FF LD A,SET 7,(IX+d) 23

78
tables/ed_prefix.spec Normal file
View File

@ -0,0 +1,78 @@
ED40 IN B,(C) 12
ED41 OUT (C),B 12
ED42 SBC HL,BC 15
ED43 n n LD (nn),BC 20
ED44 NEG 8
ED45 RETN 14
ED46 IM 0 8
ED47 LD I,A 9
ED48 IN C,(C) 12
ED49 OUT (C),C 12
ED4A ADC HL,BC 15
ED4B n n LD BC,(nn) 20
ED4C NEG 8
ED4D RETI 14
ED4E IM 0 8
ED4F LD R,A 9
ED50 IN D,(C) 12
ED51 OUT (C),D 12
ED52 SBC HL,DE 15
ED53 n n LD (nn),DE 20
ED54 NEG 8
ED55 RETN 14
ED56 IM 1 8
ED57 LD A,I 9
ED58 IN E,(C) 12
ED59 OUT (C),E 12
ED5A ADC HL,DE 15
ED5B n n LD DE,(nn) 20
ED5C NEG 8
ED5D RETN 14
ED5E IM 2 8
ED5F LD A,R 9
ED60 IN H,(C) 12
ED61 OUT (C),H 12
ED62 SBC HL,HL 15
ED63 n n LD (nn),HL 16
ED64 NEG 8
ED65 RETN 14
ED66 IM 0 8
ED67 RRD 18
ED68 IN L,(C) 12
ED69 OUT (C),L 12
ED6A ADC HL,HL 15
ED6B n n LD HL,(nn) 16
ED6C NEG 8
ED6D RETN 14
ED6E IM 0 8
ED6F RLD 18
ED70 IN F,(C) 12
ED71 OUT (C),0 12
ED72 SBC HL,SP 15
ED73 n n LD (nn),SP 20
ED74 NEG 8
ED75 RETN 14
ED76 IM 1 8
ED78 IN A,(C) 12
ED79 OUT (C),A 12
ED7A ADC HL,SP 15
ED7B n n LD SP,(nn) 20
ED7C NEG 8
ED7D RETN 14
ED7E IM 2 8
EDA0 LDI 16
EDA1 CPI 16
EDA2 INI 16
EDA3 OUTI 16
EDA8 LDD 16
EDA9 CPD 16
EDAA IND 16
EDAB OUTD 16
EDB0 LDIR 21/16
EDB1 CPIR 21/16
EDB2 INIR 21/16
EDB3 OTIR 21/16
EDB8 LDDR 21/16
EDB9 CPDR 21/16
EDBA INDR 21/16
EDBB OTDR 21/16

252
tables/fd_prefix.spec Normal file
View File

@ -0,0 +1,252 @@
FD00 NOP 8
FD01 n n LD BC,nn 14
FD02 LD (BC),A 11
FD03 INC BC 10
FD04 INC B 8
FD05 DEC B 8
FD06 n LD B,n 11
FD07 RLCA 8
FD08 EX AF,AF' 8
FD09 ADD IY,BC 15
FD0A LD A,(BC) 11
FD0B DEC BC 10
FD0C INC C 8
FD0D DEC C 8
FD0E n LD C,n 11
FD0F RRCA 8
FD10 e DJNZ (PC+e) 12/17
FD11 n n LD DE,nn 14
FD12 LD (DE),A 11
FD13 INC DE 10
FD14 INC D 8
FD15 DEC D 8
FD16 n LD D,n 11
FD17 RLA 8
FD18 e JR (PC+e) 16
FD19 ADD IY,DE 15
FD1A LD A,(DE) 11
FD1B DEC DE 10
FD1C INC E 8
FD1D DEC E 8
FD1E n LD E,n 11
FD1F RRA 8
FD20 e JR NZ,(PC+e) 16/11
FD21 n n LD IY,nn 14
FD22 n n LD (nn),IY 16
FD23 INC IY 10
FD24 INC IYH 10 guess
FD25 DEC IYH 10 guess
FD26 n LD IYH,n 11 guess
FD27 DAA 8
FD28 e JR Z,(PC+e) 16/11
FD29 ADD IY,IY 15
FD2A n n LD IY,(nn) 14
FD2B DEC IY 10
FD2C INC IYL 10 guess
FD2D DEC IYL 10 guess
FD2E n LD IYL,n 11 guess
FD2F CPL 8
FD30 e JR NC,(PC+e) 16/11
FD31 n n LD SP,nn 14
FD32 n n LD (nn),A 17
FD33 INC SP 10
FD34 d INC (IY+d) 23
FD35 d DEC (IY+d) 23
FD36 d n LD (IY+d),n 19
FD37 SCF 8
FD38 e JR c,(PC+e) 16/11
FD39 ADD IY,SP 15
FD3A n n LD A,(nn) 17
FD3B DEC SP 10
FD3C INC A 8
FD3D DEC A 8
FD3E n LD A,n 11
FD3F CCF 8
FD40 LD B,B 8
FD41 LD B,C 8
FD42 LD B,D 8
FD43 LD B,E 8
FD44 LD B,IYH 8 guess
FD45 LD B,IYL 8 guess
FD46 d LD B,(IY+d) 19
FD47 LD B,A 8
FD48 LD C,B 8
FD49 LD C,C 8
FD4A LD C,D 8
FD4B LD C,E 8
FD4C LD C,IYH 8 guess
FD4D LD C,IYL 8 guess
FD4E d LD C,(IY+d) 19
FD4F LD C,A 8
FD50 LD D,B 8
FD51 LD D,C 8
FD52 LD D,D 8
FD53 LD D,E 8
FD54 LD D,IYH 8 guess
FD55 LD D,IYL 8 guess
FD56 d LD D,(IY+d) 19
FD57 LD D,A 8
FD58 LD E,B 8
FD59 LD E,C 8
FD5A LD E,D 8
FD5B LD E,E 8
FD5C LD E,IYH 8 guess
FD5D LD E,IYL 8 guess
FD5E d LD E,(IY+d) 19
FD5F LD E,A 8
FD60 LD IYH,B 8 guess
FD61 LD IYH,C 8 guess
FD62 LD IYH,D 8 guess
FD63 LD IYH,E 8 guess
FD64 LD IYH,IYH 8 guess
FD65 LD IYH,IYL 8 guess
FD66 d LD H,(IY+d) 19
FD67 LD IYH,A 8 guess
FD68 LD IYL,B 8 guess
FD69 LD IYL,C 8 guess
FD6A LD IYL,D 8 guess
FD6B LD IYL,E 8 guess
FD6C LD IYL,IYH 8 guess
FD6D LD IYL,IYL 8 guess
FD6E d LD L,(IY+d) 19
FD6F LD IYL,A 8 guess
FD70 d LD (IY+d),B 19
FD71 d LD (IY+d),C 19
FD72 d LD (IY+d),D 19
FD73 d LD (IY+d),E 19
FD74 d LD (IY+d),H 19
FD75 d LD (IY+d),L 19
FD76 HALT 8
FD77 d LD (IY+d),A 19
FD78 LD A,B 8
FD79 LD A,C 8
FD7A LD A,D 8
FD7B LD A,E 8
FD7C LD A,IYH 8 guess
FD7D LD A,IYL 8 guess
FD7E d LD A,(IY+d) 19
FD7F LD A,A 8
FD80 ADD A,B 8
FD81 ADD A,C 8
FD82 ADD A,D 8
FD83 ADD A,E 8
FD84 ADD A,IYH 8 guess
FD85 ADD A,IYL 8 guess
FD86 d ADD A,(IY+d) 19
FD87 ADD A,A 8
FD88 ADC A,B 8
FD89 ADC A,C 8
FD8A ADC A,D 8
FD8B ADC A,E 8
FD8C ADC A,IYH 8 guess
FD8D ADC A,IYL 8 guess
FD8E d ADC A,(IY+d) 19
FD8F ADC A,A 8
FD90 SUB B 8
FD91 SUB C 8
FD92 SUB D 8
FD93 SUB E 8
FD94 SUB IYH 8 guess
FD95 SUB IYL 8 guess
FD96 d SUB (IY+d) 19
FD97 SUB A 8
FD98 SBC A,B 8
FD99 SBC A,C 8
FD9A SBC A,D 8
FD9B SBC A,E 8
FD9C SBC A,IYH 8 guess
FD9D SBC A,IYL 8 guess
FD9E d SBC A,(IY+d) 19
FD9F SBC A,A 8
FDA0 AND B 8
FDA1 AND C 8
FDA2 AND D 8
FDA3 AND E 8
FDA4 AND IYH 8 guess
FDA5 AND IYL 8 guess
FDA6 d AND (IY+d) 19
FDA7 AND A 8
FDA8 XOR B 8
FDA9 XOR C 8
FDAA XOR D 8
FDAB XOR E 8
FDAC XOR IYH 8 guess
FDAD XOR IYL 8 guess
FDAE d XOR (IY+d) 19
FDAF XOR A 8
FDB0 OR B 8
FDB1 OR C 8
FDB2 OR D 8
FDB3 OR E 8
FDB4 OR IYH 8 guess
FDB5 OR IYL 8 guess
FDB6 d OR (IY+d) 19
FDB7 OR A 8
FDB8 CP B 8
FDB9 CP C 8
FDBA CP D 8
FDBB CP E 8
FDBC CP IYH 8 guess
FDBD CP IYL 8 guess
FDBE d CP (IY+d) 19
FDBF CP A 8
FDC0 RET NZ 15/9
FDC1 POP BC 14
FDC2 n n JP NZ,(nn) 14
FDC3 n n JP (nn) 14
FDC4 n n CALL NZ,(nn) 21/14
FDC5 PUSH BC 15
FDC6 n ADD A,n 11
FDC7 RST 0H 15
FDC8 RET Z 15/9
FDC9 RET 14
FDCA n n JP Z,(nn) 14
FDCC n n CALL Z,(nn) 21/14
FDCD n n CALL (nn) 21
FDCE n ADC A,n 11
FDCF RST 8H 15
FDD0 RET NC 9
FDD1 POP DE 14
FDD2 n n JP NC,(nn) 14
FDD3 n OUT (n),A 15
FDD4 n n CALL NC,(nn) 21/14
FDD5 PUSH DE 15
FDD6 n SUB n 11
FDD7 RST 10H 15
FDD8 RET c 9
FDD9 EXX 8
FDDA n n JP c,(nn) 14
FDDB n IN A,(n) 15
FDDC n n CALL c,(nn) 21/14
FDDE n SBC A,n 19
FDDF RST 18H 15
FDE0 RET PO 15/9
FDE1 POP IY 14
FDE2 n n JP PO,(nn) 14
FDE3 EX (SP),IY 23
FDE4 n n CALL PO,(nn) 21/14
FDE5 PUSH IY 15
FDE6 n AND n 11
FDE7 RST 20H 15
FDE8 RET PE 15/9
FDE9 JP (IY) 8
FDEA n n JP PE,(nn) 14
FDEB EX DE,HL 8
FDEC n n CALL PE,(nn) 21/14
FDEE n XOR n 11
FDEF RST 28H 15
FDF0 RET P 15/9
FDF1 POP AF 14
FDF2 n n JP P,(nn) 14
FDF3 DI 8
FDF4 n n CALL P,(nn) 21/14
FDF5 PUSH AF 15
FDF6 n OR n 11
FDF7 RST 30H 15
FDF8 RET M 15/9
FDF9 LD SP,IY 10
FDFA n n JP M,(nn) 14
FDFB EI 8
FDFC n n CALL M,(nn) 21/14
FDFE n CP n 11
FDFF RST 38H 15

256
tables/fdcb_prefix.spec Normal file
View File

@ -0,0 +1,256 @@
FDCB d 00 LD B,RLC (IY+d) 23
FDCB d 01 LD C,RLC (IY+d) 23
FDCB d 02 LD D,RLC (IY+d) 23
FDCB d 03 LD E,RLC (IY+d) 23
FDCB d 04 LD H,RLC (IY+d) 23
FDCB d 05 LD L,RLC (IY+d) 23
FDCB d 06 RLC (IY+d) 23
FDCB d 07 LD A,RLC (IY+d) 23
FDCB d 08 LD B,RRC (IY+d) 23
FDCB d 09 LD C,RRC (IY+d) 23
FDCB d 0A LD D,RRC (IY+d) 23
FDCB d 0B LD E,RRC (IY+d) 23
FDCB d 0C LD H,RRC (IY+d) 23
FDCB d 0D LD L,RRC (IY+d) 23
FDCB d 0E RRC (IY+d) 23
FDCB d 0F LD A,RRC (IY+d) 23
FDCB d 10 LD B,RL (IY+d) 23
FDCB d 11 LD C,RL (IY+d) 23
FDCB d 12 LD D,RL (IY+d) 23
FDCB d 13 LD E,RL (IY+d) 23
FDCB d 14 LD H,RL (IY+d) 23
FDCB d 15 LD L,RL (IY+d) 23
FDCB d 16 RL (IY+d) 23
FDCB d 17 LD A,RL (IY+d) 23
FDCB d 18 LD B,RR (IY+d) 23
FDCB d 19 LD C,RR (IY+d) 23
FDCB d 1A LD D,RR (IY+d) 23
FDCB d 1B LD E,RR (IY+d) 23
FDCB d 1C LD H,RR (IY+d) 23
FDCB d 1D LD L,RR (IY+d) 23
FDCB d 1E RR (IY+d) 23
FDCB d 1F LD A,RR (IY+d) 23
FDCB d 20 LD B,SLA (IY+d) 23
FDCB d 21 LD C,SLA (IY+d) 23
FDCB d 22 LD D,SLA (IY+d) 23
FDCB d 23 LD E,SLA (IY+d) 23
FDCB d 24 LD H,SLA (IY+d) 23
FDCB d 25 LD L,SLA (IY+d) 23
FDCB d 26 SLA (IY+d) 23
FDCB d 27 LD A,SLA (IY+d) 23
FDCB d 28 LD B,SRA (IY+d) 23
FDCB d 29 LD C,SRA (IY+d) 23
FDCB d 2A LD D,SRA (IY+d) 23
FDCB d 2B LD E,SRA (IY+d) 23
FDCB d 2C LD H,SRA (IY+d) 23
FDCB d 2D LD L,SRA (IY+d) 23
FDCB d 2E SRA (IY+d) 23
FDCB d 2F LD A,SRA (IY+d) 23
FDCB d 30 LD B,SLL (IY+d) 23
FDCB d 31 LD C,SLL (IY+d) 23
FDCB d 32 LD D,SLL (IY+d) 23
FDCB d 33 LD E,SLL (IY+d) 23
FDCB d 34 LD H,SLL (IY+d) 23
FDCB d 35 LD L,SLL (IY+d) 23
FDCB d 36 SLL (IY+d) 23
FDCB d 37 LD A,SLL (IY+d) 23
FDCB d 38 LD B,SRL (IY+d) 23
FDCB d 39 LD C,SRL (IY+d) 23
FDCB d 3A LD D,SRL (IY+d) 23
FDCB d 3B LD E,SRL (IY+d) 23
FDCB d 3C LD H,SRL (IY+d) 23
FDCB d 3D LD L,SRL (IY+d) 23
FDCB d 3E SRL (IY+d) 23
FDCB d 3F LD A,SRL (IY+d) 23
FDCB d 40 BIT 0,(IY+d) 20
FDCB d 41 BIT 0,(IY+d) 20
FDCB d 42 BIT 0,(IY+d) 20
FDCB d 43 BIT 0,(IY+d) 20
FDCB d 44 BIT 0,(IY+d) 20
FDCB d 45 BIT 0,(IY+d) 20
FDCB d 46 BIT 0,(IY+d) 20
FDCB d 47 BIT 0,(IY+d) 20
FDCB d 48 BIT 1,(IY+d) 20
FDCB d 49 BIT 1,(IY+d) 20
FDCB d 4A BIT 1,(IY+d) 20
FDCB d 4B BIT 1,(IY+d) 20
FDCB d 4C BIT 1,(IY+d) 20
FDCB d 4D BIT 1,(IY+d) 20
FDCB d 4E BIT 1,(IY+d) 20
FDCB d 4F BIT 1,(IY+d) 20
FDCB d 50 BIT 2,(IY+d) 20
FDCB d 51 BIT 2,(IY+d) 20
FDCB d 52 BIT 2,(IY+d) 20
FDCB d 53 BIT 2,(IY+d) 20
FDCB d 54 BIT 2,(IY+d) 20
FDCB d 55 BIT 2,(IY+d) 20
FDCB d 56 BIT 2,(IY+d) 20
FDCB d 57 BIT 2,(IY+d) 20
FDCB d 58 BIT 3,(IY+d) 20
FDCB d 59 BIT 3,(IY+d) 20
FDCB d 5A BIT 3,(IY+d) 20
FDCB d 5B BIT 3,(IY+d) 20
FDCB d 5C BIT 3,(IY+d) 20
FDCB d 5D BIT 3,(IY+d) 20
FDCB d 5E BIT 3,(IY+d) 20
FDCB d 5F BIT 3,(IY+d) 20
FDCB d 60 BIT 4,(IY+d) 20
FDCB d 61 BIT 4,(IY+d) 20
FDCB d 62 BIT 4,(IY+d) 20
FDCB d 63 BIT 4,(IY+d) 20
FDCB d 64 BIT 4,(IY+d) 20
FDCB d 65 BIT 4,(IY+d) 20
FDCB d 66 BIT 4,(IY+d) 20
FDCB d 67 BIT 4,(IY+d) 20
FDCB d 68 BIT 5,(IY+d) 20
FDCB d 69 BIT 5,(IY+d) 20
FDCB d 6A BIT 5,(IY+d) 20
FDCB d 6B BIT 5,(IY+d) 20
FDCB d 6C BIT 5,(IY+d) 20
FDCB d 6D BIT 5,(IY+d) 20
FDCB d 6E BIT 5,(IY+d) 20
FDCB d 6F BIT 5,(IY+d) 20
FDCB d 70 BIT 6,(IY+d) 20
FDCB d 71 BIT 6,(IY+d) 20
FDCB d 72 BIT 6,(IY+d) 20
FDCB d 73 BIT 6,(IY+d) 20
FDCB d 74 BIT 6,(IY+d) 20
FDCB d 75 BIT 6,(IY+d) 20
FDCB d 76 BIT 6,(IY+d) 20
FDCB d 77 BIT 6,(IY+d) 20
FDCB d 78 BIT 7,(IY+d) 20
FDCB d 79 BIT 7,(IY+d) 20
FDCB d 7A BIT 7,(IY+d) 20
FDCB d 7B BIT 7,(IY+d) 20
FDCB d 7C BIT 7,(IY+d) 20
FDCB d 7D BIT 7,(IY+d) 20
FDCB d 7E BIT 7,(IY+d) 20
FDCB d 7F BIT 7,(IY+d) 20
FDCB d 80 LD B,RES 0,(IY+d) 23
FDCB d 81 LD C,RES 0,(IY+d) 23
FDCB d 82 LD D,RES 0,(IY+d) 23
FDCB d 83 LD E,RES 0,(IY+d) 23
FDCB d 84 LD H,RES 0,(IY+d) 23
FDCB d 85 LD L,RES 0,(IY+d) 23
FDCB d 86 RES 0,(IY+d) 23
FDCB d 87 LD A,RES 0,(IY+d) 23
FDCB d 88 LD B,RES 1,(IY+d) 23
FDCB d 89 LD C,RES 1,(IY+d) 23
FDCB d 8A LD D,RES 1,(IY+d) 23
FDCB d 8B LD E,RES 1,(IY+d) 23
FDCB d 8C LD H,RES 1,(IY+d) 23
FDCB d 8D LD L,RES 1,(IY+d) 23
FDCB d 8E RES 1,(IY+d) 23
FDCB d 8F LD A,RES 1,(IY+d) 23
FDCB d 90 LD B,RES 2,(IY+d) 23
FDCB d 91 LD C,RES 2,(IY+d) 23
FDCB d 92 LD D,RES 2,(IY+d) 23
FDCB d 93 LD E,RES 2,(IY+d) 23
FDCB d 94 LD H,RES 2,(IY+d) 23
FDCB d 95 LD L,RES 2,(IY+d) 23
FDCB d 96 RES 2,(IY+d) 23
FDCB d 97 LD A,RES 2,(IY+d) 23
FDCB d 98 LD B,RES 3,(IY+d) 23
FDCB d 99 LD C,RES 3,(IY+d) 23
FDCB d 9A LD D,RES 3,(IY+d) 23
FDCB d 9B LD E,RES 3,(IY+d) 23
FDCB d 9C LD H,RES 3,(IY+d) 23
FDCB d 9D LD L,RES 3,(IY+d) 23
FDCB d 9E RES 3,(IY+d) 23
FDCB d 9F LD A,RES 3,(IY+d) 23
FDCB d A0 LD B,RES 4,(IY+d) 23
FDCB d A1 LD C,RES 4,(IY+d) 23
FDCB d A2 LD D,RES 4,(IY+d) 23
FDCB d A3 LD E,RES 4,(IY+d) 23
FDCB d A4 LD H,RES 4,(IY+d) 23
FDCB d A5 LD L,RES 4,(IY+d) 23
FDCB d A6 RES 4,(IY+d) 23
FDCB d A7 LD A,RES 4,(IY+d) 23
FDCB d A8 LD B,RES 5,(IY+d) 23
FDCB d A9 LD C,RES 5,(IY+d) 23
FDCB d AA LD D,RES 5,(IY+d) 23
FDCB d AB LD E,RES 5,(IY+d) 23
FDCB d AC LD H,RES 5,(IY+d) 23
FDCB d AD LD L,RES 5,(IY+d) 23
FDCB d AE RES 5,(IY+d) 23
FDCB d AF LD A,RES 5,(IY+d) 23
FDCB d B0 LD B,RES 6,(IY+d) 23
FDCB d B1 LD C,RES 6,(IY+d) 23
FDCB d B2 LD D,RES 6,(IY+d) 23
FDCB d B3 LD E,RES 6,(IY+d) 23
FDCB d B4 LD H,RES 6,(IY+d) 23
FDCB d B5 LD L,RES 6,(IY+d) 23
FDCB d B6 RES 6,(IY+d) 23
FDCB d B7 LD A,RES 6,(IY+d) 23
FDCB d B8 LD B,RES 7,(IY+d) 23
FDCB d B9 LD C,RES 7,(IY+d) 23
FDCB d BA LD D,RES 7,(IY+d) 23
FDCB d BB LD E,RES 7,(IY+d) 23
FDCB d BC LD H,RES 7,(IY+d) 23
FDCB d BD LD L,RES 7,(IY+d) 23
FDCB d BE RES 7,(IY+d) 23
FDCB d BF LD A,RES 7,(IY+d) 23
FDCB d C0 LD B,SET 0,(IY+d) 23
FDCB d C1 LD C,SET 0,(IY+d) 23
FDCB d C2 LD D,SET 0,(IY+d) 23
FDCB d C3 LD E,SET 0,(IY+d) 23
FDCB d C4 LD H,SET 0,(IY+d) 23
FDCB d C5 LD L,SET 0,(IY+d) 23
FDCB d C6 SET 0,(IY+d) 23
FDCB d C7 LD A,SET 0,(IY+d) 23
FDCB d C8 LD B,SET 1,(IY+d) 23
FDCB d C9 LD C,SET 1,(IY+d) 23
FDCB d CA LD D,SET 1,(IY+d) 23
FDCB d CB LD E,SET 1,(IY+d) 23
FDCB d CC LD H,SET 1,(IY+d) 23
FDCB d CD LD L,SET 1,(IY+d) 23
FDCB d CE SET 1,(IY+d) 23
FDCB d CF LD A,SET 1,(IY+d) 23
FDCB d D0 LD B,SET 2,(IY+d) 23
FDCB d D1 LD C,SET 2,(IY+d) 23
FDCB d D2 LD D,SET 2,(IY+d) 23
FDCB d D3 LD E,SET 2,(IY+d) 23
FDCB d D4 LD H,SET 2,(IY+d) 23
FDCB d D5 LD L,SET 2,(IY+d) 23
FDCB d D6 SET 2,(IY+d) 23
FDCB d D7 LD A,SET 2,(IY+d) 23
FDCB d D8 LD B,SET 3,(IY+d) 23
FDCB d D9 LD C,SET 3,(IY+d) 23
FDCB d DA LD D,SET 3,(IY+d) 23
FDCB d DB LD E,SET 3,(IY+d) 23
FDCB d DC LD H,SET 3,(IY+d) 23
FDCB d DD LD L,SET 3,(IY+d) 23
FDCB d DE SET 3,(IY+d) 23
FDCB d DF LD A,SET 3,(IY+d) 23
FDCB d E0 LD B,SET 4,(IY+d) 23
FDCB d E1 LD C,SET 4,(IY+d) 23
FDCB d E2 LD D,SET 4,(IY+d) 23
FDCB d E3 LD E,SET 4,(IY+d) 23
FDCB d E4 LD H,SET 4,(IY+d) 23
FDCB d E5 LD L,SET 4,(IY+d) 23
FDCB d E6 SET 4,(IY+d) 23
FDCB d E7 LD A,SET 4,(IY+d) 23
FDCB d E8 LD B,SET 5,(IY+d) 23
FDCB d E9 LD C,SET 5,(IY+d) 23
FDCB d EA LD D,SET 5,(IY+d) 23
FDCB d EB LD E,SET 5,(IY+d) 23
FDCB d EC LD H,SET 5,(IY+d) 23
FDCB d ED LD L,SET 5,(IY+d) 23
FDCB d EE SET 5,(IY+d) 23
FDCB d EF LD A,SET 5,(IY+d) 23
FDCB d F0 LD B,SET 6,(IY+d) 23
FDCB d F1 LD C,SET 6,(IY+d) 23
FDCB d F2 LD D,SET 6,(IY+d) 23
FDCB d F3 LD E,SET 6,(IY+d) 23
FDCB d F4 LD H,SET 6,(IY+d) 23
FDCB d F5 LD L,SET 6,(IY+d) 23
FDCB d F6 SET 6,(IY+d) 23
FDCB d F7 LD A,SET 6,(IY+d) 23
FDCB d F8 LD B,SET 7,(IY+d) 23
FDCB d F9 LD C,SET 7,(IY+d) 23
FDCB d FA LD D,SET 7,(IY+d) 23
FDCB d FB LD E,SET 7,(IY+d) 23
FDCB d FC LD H,SET 7,(IY+d) 23
FDCB d FD LD L,SET 7,(IY+d) 23
FDCB d FE SET 7,(IY+d) 23
FDCB d FF LD A,SET 7,(IY+d) 23

154
tables/gen.pl Executable file
View File

@ -0,0 +1,154 @@
#!/usr/bin/perl
# Copyright (c) 2008 Steve Checkoway
#
# 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.
use strict;
use warnings;
sub parse_arg($)
{
my $arg = shift;
if( $arg =~ /^[ABCDEFHLIR]$/ or $arg =~ /^I[XY][HL]/)
{
return ( '_R', "REG_$arg", '', "\L$arg" );
}
if( $arg eq "AF'" )
{
return ( '_RR', 'REG_AFP', '', "\L$arg" );
}
if( $arg =~ /^(?:AF|BC|DE|HL|SP|IX|IY)$/ )
{
return ( '_RR', "REG_$arg", '', "\L$arg" );
}
if( $arg eq 'n' )
{
return ( '_N', 'INV', '_IMM_N', '%02hhXh' );
}
if( $arg eq 'nn' )
{
return ( '_NN', 'INV', '_IMM_NN', '%04hXh' );
}
if( $arg =~ /^\((BC|DE|HL|SP|IX|IY)\)$/ )
{
return ( '_MRR', "REG_$1", '', "\L$arg" );
}
if( $arg eq '(C)' )
{
return ( '_R', 'REG_C', '', '(c)' );
}
if( $arg eq '(n)' )
{
return ( '_MN', 'INV', '_IMM_N', '(%02hhXh)' );
}
if( $arg eq '(nn)' )
{
return ( '_MNN', 'INV', '_IMM_NN', '(%04hXh)' );
}
# Make c lowercae here so it doesn't match above.
if( $arg =~ /^(?:NZ|Z|NC|c|PE|PO|P|M)$/ )
{
return ( '_C', "COND_\u$arg", '', "\L$arg" );
}
if( $arg eq '(IX+d)' )
{
return ( '_I', 'REG_IX', '_OFFSET', '(ix%c%02Xh)' );
}
if( $arg eq '(IY+d)' )
{
return ( '_I', 'REG_IY', '_OFFSET', '(iy%c%02Xh)' );
}
if( $arg eq '(PC+e)' )
{
return ( '', 'INV', '_DISP', '(pc%c%Xh)' );
}
if( $arg =~ /^([123]?[08])H$/ )
{
return ( '', "0x$1", '', "$1h" );
}
if( $arg =~ /^[0-7]$/ )
{
return ( '', $arg, '', $arg );
}
die $arg;
}
my $previous = -1;
while( <> )
{
my @part = split /\t+/;
$part[0] =~ /^[DF]DCB d ([0-9A-F]{2})/ or
$part[0] =~ /^(?:CB|DD|ED|FD)?([0-9A-F]{2})(?: |$)/
or die 'bad opcode';
my $op = hex $1;
while( ++$previous < $op )
{
printf "{ NOP, INV, INV, INV, 8, TYPE_NONE, \"nop\" },\t// %02x\n",
$previous;
}
$previous = $op;
$part[2] =~ /^(\d+)(?:\/(\d+))?$/ or die $part[2];
my $tstate = $1;
my $extra = 'INV';
if( defined $2 )
{
$extra = $2;
($tstate,$extra) = ($extra,$tstate) if $tstate < $extra;
}
my $mnemonic = '';
if( $part[1] =~
/LD ([BCDEHLAF]),((?:RLC|RRC|RL|RR|SLA|SRA|SLL|SRL|BIT|RES|SET).*)/ )
{
$extra = "REG_$1";
$mnemonic = "LD $1,";
$part[1] = $2;
}
@part = split / /, $part[1];
my $type = $part[0];
$mnemonic = "\L$mnemonic$type";
print '{ ';
if( $#part == 1 )
{
my @args = split /,/, $part[1];
my ($suffix, $operand, $op_type, $fmt) = parse_arg $args[0];
if( $#args == 0 )
{
$op_type = '_NONE' unless $op_type ne '';
print "$type$suffix, $operand, INV, ",
"$extra, $tstate, TYPE$op_type, \"$mnemonic $fmt\"";
}
else
{
my ($suffix2, $operand2, $op_type2, $fmt2) = parse_arg $args[1];
$op_type = '_NONE' unless $op_type ne '' or $op_type2 ne '';
print "$type$suffix$suffix2, $operand, $operand2, ",
"$extra, $tstate, TYPE$op_type$op_type2, ",
qq{"$mnemonic $fmt,$fmt2"};
}
}
else
{
print qq/$type, INV, INV, $extra, $tstate, TYPE_NONE, "$mnemonic"/;
}
printf " },\t// %02x\n", $op;
}
while( ++$previous <= 0xff )
{
printf "{ NOP, INV, INV, INV, 8, TYPE_NONE, \"nop\" },\t// %02x\n", $previous;
}

252
tables/no_prefix.spec Normal file
View File

@ -0,0 +1,252 @@
00 NOP 4
01 n n LD BC,nn 10
02 LD (BC),A 7
03 INC BC 6
04 INC B 4
05 DEC B 4
06 n LD B,n 7
07 RLCA 4
08 EX AF,AF' 4
09 ADD HL,BC 11
0A LD A,(BC) 7
0B DEC BC 6
0C INC C 4
0D DEC C 4
0E n LD C,n 7
0F RRCA 4
10 e DJNZ (PC+e) 8/13
11 n n LD DE,nn 10
12 LD (DE),A 7
13 INC DE 6
14 INC D 4
15 DEC D 4
16 n LD D,n 7
17 RLA 4
18 e JR (PC+e) 12
19 ADD HL,DE 11
1A LD A,(DE) 7
1B DEC DE 6
1C INC E 4
1D DEC E 4
1E n LD E,n 7
1F RRA 4
20 e JR NZ,(PC+e) 12/7
21 n n LD HL,nn 10
22 n n LD (nn),HL 16
23 INC HL 6
24 INC H 4
25 DEC H 4
26 n LD H,n 7
27 DAA 4
28 e JR Z,(PC+e) 12/7
29 ADD HL,HL 11
2A n n LD HL,(nn) 16
2B DEC HL 6
2C INC L 4
2D DEC L 4
2E n LD L,n 7
2F CPL 4
30 e JR NC,(PC+e) 12/7
31 n n LD SP,nn 10
32 n n LD (nn),A 13
33 INC SP 6
34 INC (HL) 11
35 DEC (HL) 11
36 n LD (HL),n 10
37 SCF 4
38 e JR c,(PC+e) 12/7
39 ADD HL,SP 11
3A n n LD A,(nn) 13
3B DEC SP 6
3C INC A 4
3D DEC A 4
3E n LD A,n 7
3F CCF 4
40 LD B,B 4
41 LD B,C 4
42 LD B,D 4
43 LD B,E 4
44 LD B,H 4
45 LD B,L 4
46 LD B,(HL) 7
47 LD B,A 4
48 LD C,B 4
49 LD C,C 4
4A LD C,D 4
4B LD C,E 4
4C LD C,H 4
4D LD C,L 4
4E LD C,(HL) 7
4F LD C,A 4
50 LD D,B 4
51 LD D,C 4
52 LD D,D 4
53 LD D,E 4
54 LD D,H 4
55 LD D,L 4
56 LD D,(HL) 7
57 LD D,A 4
58 LD E,B 4
59 LD E,C 4
5A LD E,D 4
5B LD E,E 4
5C LD E,H 4
5D LD E,L 4
5E LD E,(HL) 7
5F LD E,A 4
60 LD H,B 4
61 LD H,C 4
62 LD H,D 4
63 LD H,E 4
64 LD H,H 4
65 LD H,L 4
66 LD H,(HL) 7
67 LD H,A 4
68 LD L,B 4
69 LD L,C 4
6A LD L,D 4
6B LD L,E 4
6C LD L,H 4
6D LD L,L 4
6E LD L,(HL) 7
6F LD L,A 4
70 LD (HL),B 7
71 LD (HL),C 7
72 LD (HL),D 7
73 LD (HL),E 7
74 LD (HL),H 7
75 LD (HL),L 7
76 HALT 4
77 LD (HL),A 7
78 LD A,B 4
79 LD A,C 4
7A LD A,D 4
7B LD A,E 4
7C LD A,H 4
7D LD A,L 4
7E LD A,(HL) 7
7F LD A,A 4
80 ADD A,B 4
81 ADD A,C 4
82 ADD A,D 4
83 ADD A,E 4
84 ADD A,H 4
85 ADD A,L 4
86 ADD A,(HL) 7
87 ADD A,A 4
88 ADC A,B 4
89 ADC A,C 4
8A ADC A,D 4
8B ADC A,E 4
8C ADC A,H 4
8D ADC A,L 4
8E ADC A,(HL) 7
8F ADC A,A 4
90 SUB B 4
91 SUB C 4
92 SUB D 4
93 SUB E 4
94 SUB H 4
95 SUB L 4
96 SUB (HL) 7
97 SUB A 4
98 SBC A,B 4
99 SBC A,C 4
9A SBC A,D 4
9B SBC A,E 4
9C SBC A,H 4
9D SBC A,L 4
9E SBC A,(HL) 7
9F SBC A,A 4
A0 AND B 4
A1 AND C 4
A2 AND D 4
A3 AND E 4
A4 AND H 4
A5 AND L 4
A6 AND (HL) 7
A7 AND A 4
A8 XOR B 4
A9 XOR C 4
AA XOR D 4
AB XOR E 4
AC XOR H 4
AD XOR L 4
AE XOR (HL) 7
AF XOR A 4
B0 OR B 4
B1 OR C 4
B2 OR D 4
B3 OR E 4
B4 OR H 4
B5 OR L 4
B6 OR (HL) 7
B7 OR A 4
B8 CP B 4
B9 CP C 4
BA CP D 4
BB CP E 4
BC CP H 4
BD CP L 4
BE CP (HL) 7
BF CP A 4
C0 RET NZ 11/5
C1 POP BC 10
C2 n n JP NZ,(nn) 10
C3 n n JP (nn) 10
C4 n n CALL NZ,(nn) 17/10
C5 PUSH BC 11
C6 n ADD A,n 7
C7 RST 0H 11
C8 RET Z 11/5
C9 RET 10
CA n n JP Z,(nn) 10
CC n n CALL Z,(nn) 17/10
CD n n CALL (nn) 17
CE n ADC A,n 7
CF RST 8H 11
D0 RET NC 5
D1 POP DE 10
D2 n n JP NC,(nn) 10
D3 n OUT (n),A 11
D4 n n CALL NC,(nn) 17/10
D5 PUSH DE 11
D6 n SUB n 7
D7 RST 10H 11
D8 RET c 5
D9 EXX 4
DA n n JP c,(nn) 10
DB n IN A,(n) 11
DC n n CALL c,(nn) 17/10
DE n SBC A,n 15
DF RST 18H 11
E0 RET PO 11/5
E1 POP HL 10
E2 n n JP PO,(nn) 10
E3 EX (SP),HL 19
E4 n n CALL PO,(nn) 17/10
E5 PUSH HL 11
E6 n AND n 7
E7 RST 20H 11
E8 RET PE 11/5
E9 JP (HL) 4
EA n n JP PE,(nn) 10
EB EX DE,HL 4
EC n n CALL PE,(nn) 17/10
EE n XOR n 7
EF RST 28H 11
F0 RET P 11/5
F1 POP AF 10
F2 n n JP P,(nn) 10
F3 DI 4
F4 n n CALL P,(nn) 17/10
F5 PUSH AF 11
F6 n OR n 7
F7 RST 30H 11
F8 RET M 11/5
F9 LD SP,HL 6
FA n n JP M,(nn) 10
FB EI 4
FC n n CALL M,(nn) 17/10
FE n CP n 7
FF RST 38H 11

57
tests/Makefile Normal file
View File

@ -0,0 +1,57 @@
# Copyright (c) 2008 Steve Checkoway
#
# 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.
sources = $(wildcard test_*.c)
tests = $(sources:.c=)
itests = $(subst test,itest,$(tests))
CPPFLAGS += -I../include
CFLAGS += -O3 -Wall -Werror
LDFLAGS += -L..
LIBS += -lzel
.PHONY: all check clean force
all:
force:
check: $(itests) $(tests)
@passed=0; \
total=0; \
for i in $^; do \
total=`expr $$total + 1`; \
if ./$$i; then \
echo PASS: $$i; \
passed=`expr $$passed + 1`; \
else \
echo FAIL: $$i; \
fi; \
done; \
echo $$passed of $$total tests passed
test_%: test_%.o test.o force
$(CC) $(LDFLAGS) -o $@ $< test.o $(LIBS)
itest_%: test_%.o itest.o force
$(CC) $(LDFLAGS) -o $@ $< itest.o $(LIBS)
test.o: test.c
itest.o: itest.c
clean:
$(RM) $(sources:.c=.o) $(itests) $(tests) itest.o test.o

52
tests/itest.c Normal file
View File

@ -0,0 +1,52 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
#include <stdio.h>
#include <string.h>
#include <zel/z80_instructions.h>
extern const char *disasm[];
extern byte data[];
static byte ReadMem( word address, void *unused )
{
return data[address];
}
int main()
{
int i;
word address = 0;
char buffer[25];
bool failed = false;
for( i = 0; disasm[i]; ++i )
{
Instruction inst;
address += IF_ID( &inst, address, ReadMem, NULL );
DisassembleInstruction( &inst, buffer );
if( strcmp(disasm[i], buffer) )
{
printf( "Expected \"%s\" got \"%s\"\n", disasm[i], buffer );
failed = true;
}
}
return failed;
}

21
tests/template.c Normal file
View File

@ -0,0 +1,21 @@
/* Written by Steve Checkoway, 2008. Released into the public domain. */
#include <stdlib.h>
#include <z80.h>
byte data[] = {};
const byte interrupt_data [] = {};
const byte input_data[] = {};
const byte input_port = 0;
const byte output_data[] = {};
const byte output_port = 0;
const word initial_state[NUM_REG] = { 0x0000, 0x0000, 0x0000, 0x0000, // BC, DE, HL, AF
0x0000, 0x0000, 0x0000, 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const word final_state[NUM_REG] = { 0x0000, 0x0000, 0x0000, 0x0000, // BC, DE, HL, AF
0x0000, 0x0000, sizeof(data), 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const size_t size = sizeof(data);
const size_t interrupt_size = sizeof(interrupt_data);
const size_t input_size = sizeof(input_data);
const size_t output_size = sizeof(output_data);

129
tests/test.c Normal file
View File

@ -0,0 +1,129 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <zel/z80.h>
extern byte data[];
extern const size_t size;
extern const byte interrupt_data[];
extern const size_t interrupt_size;
extern const byte input_data[];
extern const size_t input_size;
extern const byte input_port;
extern const byte output_data[];
extern const size_t output_size;
extern const byte output_port;
extern const word initial_state[NUM_REG-1]; // No REG_IR
extern const word final_state[NUM_REG-1]; // No REG_IR
static byte ReadMem( word address, bool instruction, Z80 cpu )
{
if( address >= size )
printf( "Tried to read address %hx.\n", address );
assert( address < size );
return data[address];
}
static void WriteMem( word address, byte b, Z80 cpu )
{
assert( address < size );
data[address] = b;
}
static byte ReadInterruptData( word address, Z80 cpu )
{
assert( address < interrupt_size );
return interrupt_data[address];
}
static byte ReadIO( word address, Z80 cpu )
{
assert( (address & 0xff) == input_port );
assert( address >> 8 < input_size );
return input_data[address];
}
static void WriteIO( word address, byte data, Z80 cpu )
{
assert( (address & 0xff) != output_port );
assert( address >> 8 < output_size );
assert( data == output_data[address>>8] );
}
static void InterruptComplete( Z80 cpu )
{
assert( ((void)"InterruptComplete()", false) );
}
int main( int argc, char **argv )
{
Z80FunctionBlock blk =
{
ReadMem,
WriteMem,
ReadInterruptData,
ReadIO,
WriteIO,
InterruptComplete,
NULL,
};
uint64_t ticks = 0;
Z80 cpu = Z80_New( &blk );
int i;
for( i = 0; i < NUM_REG-1; ++i )
Z80_SetReg( i, initial_state[i], cpu );
while( !Z80_HasHalted(cpu) && ticks < 10000 )
{
word pc;
ticks += Z80_Step( &pc, cpu );
if( argc > 1 )
{
char buffer[25];
Z80_Disassemble( pc, buffer, cpu );
printf( "%02hx: %s\t %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx"
"%04hx %04hx %04hx %04hx\n", pc, buffer,
Z80_GetReg( REG_BC, cpu ), Z80_GetReg( REG_DE, cpu ),
Z80_GetReg( REG_HL, cpu ), Z80_GetReg( REG_AF, cpu ),
Z80_GetReg( REG_IX, cpu ), Z80_GetReg( REG_IY, cpu ),
Z80_GetReg( REG_PC, cpu ), Z80_GetReg( REG_SP, cpu ),
Z80_GetReg( REG_BCP, cpu ), Z80_GetReg( REG_DEP, cpu ),
Z80_GetReg( REG_HLP, cpu ), Z80_GetReg( REG_AFP, cpu ) );
}
}
if( ticks >= 10000 )
{
puts( "Didn't halt." );
return 1;
}
for( i = 0; i < NUM_REG-1; ++i )
{
word reg = Z80_GetReg( i, cpu );
if( reg != final_state[i] )
{
printf( "%d: %hx %hx\n", i, reg, final_state[i] );
return 1;
}
}
return 0;
}

32
tests/test_arithmetic.c Normal file
View File

@ -0,0 +1,32 @@
/* Written by Steve Checkoway, 2008. Released into the public domain. */
#include <stdlib.h>
#include <zel/z80.h>
const char *disasm[] = {
"add a,b",
"sub c",
"adc a,d",
"sbc a,e",
"and h",
"or l",
"xor FFh",
"halt",
NULL,
};
byte data[] = { 0x80, 0x91, 0x8a, 0x9b, 0xa4, 0xb5, 0xee, 0xff, 0x76 };
const byte interrupt_data [] = {};
const byte input_data[] = {};
const byte input_port = 0;
const byte output_data[] = {};
const byte output_port = 0;
const word initial_state[NUM_REG] = { 0x35ff, 0x0005, 0x0f50, 0x1200, // BC, DE, HL, AF
0x0000, 0x0000, 0x0000, 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const word final_state[NUM_REG] = { 0x35ff, 0x0005, 0x0f50, 0xaba8, // BC, DE, HL, AF
0x0000, 0x0000, sizeof(data), 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const size_t size = sizeof(data);
const size_t interrupt_size = sizeof(interrupt_data);
const size_t input_size = sizeof(input_data);
const size_t output_size = sizeof(output_data);

35
tests/test_load.c Normal file
View File

@ -0,0 +1,35 @@
/* Written by Steve Checkoway, 2008. Released into the public domain. */
#include <stdlib.h>
#include <zel/z80.h>
const char *disasm[] = {
"ld a,15h",
"ld b,a",
"ld c,(hl)",
"ld d,(ix+02h)",
"ld iyl,03h",
"ld e,(iy-01h)",
"ld a,(hl)",
"ld ixh,a",
"ld a,(0007h)",
"halt",
NULL,
};
byte data[] = { 0x3e, 0x15, 0x47, 0x4e, 0xdd, 0x56, 0x02, 0xfd, 0x2e, 0x03, 0xfd, 0x5e, 0xff,
0x7e, 0xdd, 0x67, 0x3a, 0x07, 0x00, 0x76 };
const byte interrupt_data [] = {};
const byte input_data[] = {};
const byte input_port = 0;
const byte output_data[] = {};
const byte output_port = 0;
const word initial_state[NUM_REG] = { 0x0000, 0x0000, 0x0000, 0x0000, // BC, DE, HL, AF
0x0000, 0x0000, 0x0000, 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const word final_state[NUM_REG] = { 0x153e, 0x4747, 0x0000, 0xfd00, // BC, DE, HL, AF
0x3e00, 0x0003, sizeof(data), 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const size_t size = sizeof(data);
const size_t interrupt_size = sizeof(interrupt_data);
const size_t input_size = sizeof(input_data);
const size_t output_size = sizeof(output_data);

33
tests/test_set.c Normal file
View File

@ -0,0 +1,33 @@
/* Written by Steve Checkoway, 2008. Released into the public domain. */
#include <stdlib.h>
#include <zel/z80.h>
const char *disasm[] = {
"ld ix,0020h",
"set 0,(ix-10h)",
"set 4,(ix-10h)",
"ld b,(ix-10h)",
"halt",
NULL,
};
byte data[] = { 0xdd, 0x21, 0x20, 0x00, // ld ix 0020h
0xdd, 0xcb, 0xf0, 0xc6, // set 0,(ix-10h)
0xdd, 0xcb, 0xf0, 0xe6, // set 4,(ix-10h)
0xdd, 0x46, 0xf0, 0x76, // ld b,(ix-10h); halt
0x00 }; // byte 0x0010
const byte interrupt_data [] = {};
const byte input_data[] = {};
const byte input_port = 0;
const byte output_data[] = {};
const byte output_port = 0;
const word initial_state[NUM_REG] = { 0x0000, 0x0000, 0x0000, 0x0000, // BC, DE, HL, AF
0x0000, 0x0000, 0x0000, 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const word final_state[NUM_REG] = { 0x1100, 0x0000, 0x0000, 0x0000, // BC, DE, HL, AF
0x0020, 0x0000, 0x0010, 0x0000, // IX, IY, PC, SP
0x0000, 0x0000, 0x0000, 0x0000 }; // BC', DE', HL', AF'
const size_t size = sizeof(data);
const size_t interrupt_size = sizeof(interrupt_data);
const size_t input_size = sizeof(input_data);
const size_t output_size = sizeof(output_data);

1283
z80.c Normal file

File diff suppressed because it is too large Load Diff

206
z80_instructions.c Normal file
View File

@ -0,0 +1,206 @@
/* Copyright (c) 2008 Steve Checkoway
*
* 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.
*/
#include <stdio.h> /* for snprintf */
#include <string.h>
#include <zel/z80.h> /* Need registers */
#include <zel/z80_instructions.h>
const InstructionTemplate Unprefixed[] =
{
#include "tables/no_prefix.tab"
};
const InstructionTemplate CB_Prefixed[] =
{
#include "tables/cb_prefix.tab"
};
const InstructionTemplate DD_Prefixed[] =
{
#include "tables/dd_prefix.tab"
};
const InstructionTemplate DDCB_Prefixed[] =
{
#include "tables/ddcb_prefix.tab"
};
const InstructionTemplate ED_Prefixed[] =
{
#include "tables/ed_prefix.tab"
};
const InstructionTemplate FD_Prefixed[] =
{
#include "tables/fd_prefix.tab"
};
const InstructionTemplate FDCB_Prefixed[] =
{
#include "tables/fdcb_prefix.tab"
};
int IF_ID( Instruction *inst, word address, ReadMemFunction ReadMem, void *data )
{
byte opcode, opcode2 = 0;
int length = 1;
opcode = ReadMem( address, data );
inst->additional_tstates = 0;
inst->offset = 0;
inst->immediate = 0;
inst->r_increment = 1;
if( opcode == 0xdd || opcode == 0xfd )
{
++length;
++inst->r_increment;
opcode2 = ReadMem( ++address, data );
while( opcode2 == 0xdd || opcode2 == 0xfd )
{
inst->additional_tstates += 4;
opcode = opcode2;
++length;
++inst->r_increment;
opcode2 = ReadMem( ++address, data );
}
/* If cocode2 is 0xed, then the prefix should be
* completely ignored apart from the time it took to
* read and the length. */
if( opcode2 == 0xed )
opcode = opcode2;
}
switch( opcode )
{
case 0xcb:
++length;
++inst->r_increment;
opcode = ReadMem( ++address, data );
inst->IT = &CB_Prefixed[opcode];
return length; // No immediates/offset
case 0xdd:
if( opcode2 == 0xcb )
{
length += 2;
inst->offset = (sbyte)ReadMem( ++address, data );
opcode = ReadMem( ++address, data );
inst->IT = &DDCB_Prefixed[opcode];
return length; // No immediates and offset is done
}
inst->IT = &DD_Prefixed[opcode2];
break; // immediates
case 0xed:
++length;
++inst->r_increment;
opcode = ReadMem( ++address, data );
inst->IT = &ED_Prefixed[opcode];
break; // immediates
case 0xfd:
if( opcode2 == 0xcb )
{
length += 2;
inst->offset = (sbyte)ReadMem( ++address, data );
opcode = ReadMem( ++address, data );
inst->IT = &FDCB_Prefixed[opcode];
return length; // No immediates and offset is done
}
inst->IT = &FD_Prefixed[opcode2];
break; // immediates
default:
inst->IT = &Unprefixed[opcode];
break;
}
switch( inst->IT->operand_types )
{
case TYPE_NONE:
break;
case TYPE_IMM_N:
++length;
inst->immediate = ReadMem( ++address, data );
break;
case TYPE_OFFSET:
case TYPE_DISP:
++length;
inst->offset = (sbyte)ReadMem( ++address, data );
break;
case TYPE_IMM_NN:
length += 2;
inst->immediate = ReadMem( ++address, data );
inst->immediate |= ReadMem( ++address, data ) << 8;
break;
case TYPE_OFFSET_IMM_N:
length += 2;
inst->offset = (sbyte)ReadMem( ++address, data );
inst->immediate = ReadMem( ++address, data );
break;
}
return length;
}
void DisassembleInstruction( const Instruction *inst, char *buffer )
{
char c;
int v;
switch( inst->IT->operand_types )
{
case TYPE_NONE:
strncpy( buffer, inst->IT->format, 25 );
buffer[24] = '\0';
break;
case TYPE_IMM_N:
case TYPE_IMM_NN:
snprintf( buffer, 25, inst->IT->format, inst->immediate );
break;
case TYPE_OFFSET:
if( inst->offset >= 0 )
{
c = '+';
v = inst->offset;
}
else
{
c = '-';
v = -inst->offset;
}
snprintf( buffer, 25, inst->IT->format, c, v );
break;
case TYPE_DISP:
if( inst->offset >= -2 )
{
c = '+';
v = inst->offset+2;
}
else
{
c = '-';
v = -inst->offset - 2;
}
snprintf( buffer, 25, inst->IT->format, c, v );
break;
case TYPE_OFFSET_IMM_N:
if( inst->offset >= 0 )
{
c = '+';
v = inst->offset;
}
else
{
c = '-';
v = -inst->offset;
}
snprintf( buffer, 25, inst->IT->format, c, v, inst->immediate );
break;
}
}