zemu 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/zemu/config.rb +312 -0
- data/lib/zemu/instance.rb +179 -0
- data/lib/zemu.rb +172 -0
- data/src/debug.c +118 -0
- data/src/debug.h +30 -0
- data/src/external/Z/API/Z/ABIs/generic/allocator.h +36 -0
- data/src/external/Z/API/Z/ABIs/generic/cipher.h +47 -0
- data/src/external/Z/API/Z/ABIs/generic/data codec.h +33 -0
- data/src/external/Z/API/Z/ABIs/generic/emulation.h +103 -0
- data/src/external/Z/API/Z/ABIs/generic/hash function.h +33 -0
- data/src/external/Z/API/Z/ABIs/generic/module.h +33 -0
- data/src/external/Z/API/Z/ABIs/generic/wave codec.h +40 -0
- data/src/external/Z/API/Z/classes/base/InitializerList.hpp +34 -0
- data/src/external/Z/API/Z/classes/base/OpaqueFunctionPointer.hpp +26 -0
- data/src/external/Z/API/Z/classes/base/OpaqueMemberFunctionPointer.hpp +26 -0
- data/src/external/Z/API/Z/classes/base/Pair.hpp +46 -0
- data/src/external/Z/API/Z/classes/base/Range.hpp +111 -0
- data/src/external/Z/API/Z/classes/base/SizedString.hpp +66 -0
- data/src/external/Z/API/Z/classes/base/Status.hpp +89 -0
- data/src/external/Z/API/Z/classes/base/Symbol.hpp +39 -0
- data/src/external/Z/API/Z/classes/base/Tuple.hpp +111 -0
- data/src/external/Z/API/Z/classes/base/Value2D.hpp +389 -0
- data/src/external/Z/API/Z/classes/base/Value3D.hpp +368 -0
- data/src/external/Z/API/Z/classes/buffering/RingBuffer.hpp +93 -0
- data/src/external/Z/API/Z/classes/buffering/TripleBuffer.hpp +68 -0
- data/src/external/Z/API/Z/classes/functional/Functor.hpp +265 -0
- data/src/external/Z/API/Z/classes/functional/MemberFunction.hpp +98 -0
- data/src/external/Z/API/Z/classes/functional/ObjectMemberFunction.hpp +172 -0
- data/src/external/Z/API/Z/classes/functional/ObjectSelector.hpp +219 -0
- data/src/external/Z/API/Z/classes/functional/Selector.hpp +146 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/AABB.hpp +81 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/AABR.hpp +685 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Box.hpp +219 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Circle.hpp +80 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Line2D.hpp +93 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Line3D.hpp +80 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Rectangle.hpp +675 -0
- data/src/external/Z/API/Z/classes/mathematics/geometry/euclidean/Sphere.hpp +0 -0
- data/src/external/Z/API/Z/classes/memory/Shared.hpp +90 -0
- data/src/external/Z/API/Z/constants/base.h +35 -0
- data/src/external/Z/API/Z/constants/chemical elements.h +6385 -0
- data/src/external/Z/API/Z/constants/numbers.h +963 -0
- data/src/external/Z/API/Z/constants/version.h +15 -0
- data/src/external/Z/API/Z/formats/character set/ASCII.h +158 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP437.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP737.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP775.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP850.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP852.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP855.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP857.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP858.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP860.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP861.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP862.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP863.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP864.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP865.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP866.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP869.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP872.h +159 -0
- data/src/external/Z/API/Z/formats/character set/DOS CP874.h +159 -0
- data/src/external/Z/API/Z/formats/character set/Unicode.h +30119 -0
- data/src/external/Z/API/Z/formats/data model/I16LP32.h +19 -0
- data/src/external/Z/API/Z/formats/data model/ILP32.h +19 -0
- data/src/external/Z/API/Z/formats/data model/ILP64.h +19 -0
- data/src/external/Z/API/Z/formats/data model/IP16L32.h +19 -0
- data/src/external/Z/API/Z/formats/data model/LLP64.h +19 -0
- data/src/external/Z/API/Z/formats/data model/LP32.h +19 -0
- data/src/external/Z/API/Z/formats/data model/LP64.h +19 -0
- data/src/external/Z/API/Z/formats/data model/SILP64.h +19 -0
- data/src/external/Z/API/Z/formats/file system/FAT12.h +61 -0
- data/src/external/Z/API/Z/formats/floating-point/IEEE 754.h +141 -0
- data/src/external/Z/API/Z/formats/floating-point/x87.h +74 -0
- data/src/external/Z/API/Z/formats/image/ICNS.h +39 -0
- data/src/external/Z/API/Z/formats/keymap/Mac OS.h +284 -0
- data/src/external/Z/API/Z/formats/keymap/Z.h +141 -0
- data/src/external/Z/API/Z/formats/multimedia/Creative Voice.h +106 -0
- data/src/external/Z/API/Z/formats/multimedia/Microsoft Wave.h +49 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/ACH.h +44 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/FRZ.h +54 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/PRG.h +33 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/SEM.h +46 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/SIT.h +34 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/SNA.h +117 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/SNP.h +37 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/SP.h +62 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/Z80.h +117 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/ZX.h +56 -0
- data/src/external/Z/API/Z/formats/snapshot/machine/computer/ZX Spectrum/ZX82.h +70 -0
- data/src/external/Z/API/Z/formats/storage medium image/NES Game Pak/UNIF.h +26 -0
- data/src/external/Z/API/Z/formats/storage medium image/NES Game Pak/iNES.h +76 -0
- data/src/external/Z/API/Z/formats/storage medium image/audio/TAP.h +25 -0
- data/src/external/Z/API/Z/formats/storage medium image/audio/TZX.h +1185 -0
- data/src/external/Z/API/Z/formats/storage medium image/audio/Warajevo TAP.h +32 -0
- data/src/external/Z/API/Z/formats/storage medium image/floppy disk/FDI.h +45 -0
- data/src/external/Z/API/Z/functions/base/Z2D.h +583 -0
- data/src/external/Z/API/Z/functions/base/Z3D.h +712 -0
- data/src/external/Z/API/Z/functions/base/ZRange.h +137 -0
- data/src/external/Z/API/Z/functions/base/all.h +16 -0
- data/src/external/Z/API/Z/functions/base/casting.hpp +37 -0
- data/src/external/Z/API/Z/functions/base/character.h +38 -0
- data/src/external/Z/API/Z/functions/base/constructors.h +326 -0
- data/src/external/Z/API/Z/functions/base/structure.hpp +26 -0
- data/src/external/Z/API/Z/functions/base/type.hpp +60 -0
- data/src/external/Z/API/Z/functions/base/value.h +1901 -0
- data/src/external/Z/API/Z/functions/base/value.hpp +112 -0
- data/src/external/Z/API/Z/functions/buffering/ZRingBuffer.h +85 -0
- data/src/external/Z/API/Z/functions/buffering/ZTripleBuffer.h +65 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/Z2DLine.h +179 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/Z3DLine.h +168 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZAABB.h +361 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZAABR.h +1081 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZBox.h +340 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZCircle.h +142 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZRectangle.h +1267 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/ZSphere.h +156 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/all.h +18 -0
- data/src/external/Z/API/Z/functions/mathematics/geometry/euclidean/constructors.h +620 -0
- data/src/external/Z/API/Z/functions/time/date.h +29 -0
- data/src/external/Z/API/Z/hardware/CPU/architecture/6502.h +90 -0
- data/src/external/Z/API/Z/hardware/CPU/architecture/Z80.h +245 -0
- data/src/external/Z/API/Z/hardware/CPU/architecture/i4004.h +37 -0
- data/src/external/Z/API/Z/hardware/PSG/General Instrument/AY-3-891x.h +180 -0
- data/src/external/Z/API/Z/hardware/VDC/Ricoh/RP2C0x.h +625 -0
- data/src/external/Z/API/Z/hardware/bus/AGP.h +24 -0
- data/src/external/Z/API/Z/hardware/bus/USB.h +510 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/Inves Spectrum +.h +47 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/Pentagon.h +13 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/Scorpion.h +13 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum + 128K.h +158 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum +.h +82 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum +2.h +13 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum +2A.h +13 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum +3.h +13 -0
- data/src/external/Z/API/Z/hardware/machine/model/computer/ZX Spectrum/ZX Spectrum.h +109 -0
- data/src/external/Z/API/Z/hardware/machine/model/console/Nintendo Entertainment System/NES-001 (NTSC).h +29 -0
- data/src/external/Z/API/Z/hardware/machine/model/console/Nintendo Entertainment System/NES-001 (PAL).h +29 -0
- data/src/external/Z/API/Z/hardware/machine/platform/computer/ZX Spectrum.h +405 -0
- data/src/external/Z/API/Z/hardware/machine/platform/console/Game Boy.h +49 -0
- data/src/external/Z/API/Z/hardware/machine/platform/console/Nintendo Entertainment System.h +350 -0
- data/src/external/Z/API/Z/hardware/storage medium/ROM cartridge/SNES Game Pak.h +238 -0
- data/src/external/Z/API/Z/inspection/C/completion.h +178 -0
- data/src/external/Z/API/Z/inspection/C/modules/C11.h +41 -0
- data/src/external/Z/API/Z/inspection/C/modules/C18.h +13 -0
- data/src/external/Z/API/Z/inspection/C/modules/C89.h +19 -0
- data/src/external/Z/API/Z/inspection/C/modules/C90.h +13 -0
- data/src/external/Z/API/Z/inspection/C/modules/C94.h +15 -0
- data/src/external/Z/API/Z/inspection/C/modules/C99.h +29 -0
- data/src/external/Z/API/Z/inspection/C/modules/KR C.h +19 -0
- data/src/external/Z/API/Z/inspection/C++/completion.h +512 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++03.h +15 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++11.h +80 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++14.h +26 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++17.h +55 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++85.h +11 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++89.h +13 -0
- data/src/external/Z/API/Z/inspection/C++/modules/C++98.h +17 -0
- data/src/external/Z/API/Z/inspection/C++.h +78 -0
- data/src/external/Z/API/Z/inspection/C.h +79 -0
- data/src/external/Z/API/Z/inspection/CPU/completion.h +56 -0
- data/src/external/Z/API/Z/inspection/CPU/detection.h +714 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/6502.h +25 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/AArch32.h +32 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/AArch64.h +32 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/Z80.h +26 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/x86-32.h +31 -0
- data/src/external/Z/API/Z/inspection/CPU/modules/x86-64.h +312 -0
- data/src/external/Z/API/Z/inspection/CPU.h +209 -0
- data/src/external/Z/API/Z/inspection/OS/completion.h +36 -0
- data/src/external/Z/API/Z/inspection/OS/detection.h +768 -0
- data/src/external/Z/API/Z/inspection/OS/modules/Linux.h +22 -0
- data/src/external/Z/API/Z/inspection/OS/modules/MS-DOS.h +16 -0
- data/src/external/Z/API/Z/inspection/OS/modules/Mac OS X.h +23 -0
- data/src/external/Z/API/Z/inspection/OS/modules/Windows.h +19 -0
- data/src/external/Z/API/Z/inspection/OS/modules/iPhone OS.h +23 -0
- data/src/external/Z/API/Z/inspection/OS.h +236 -0
- data/src/external/Z/API/Z/inspection/Objective-C/completion.h +8 -0
- data/src/external/Z/API/Z/inspection/Objective-C/modules/Objective-C v1.0.h +11 -0
- data/src/external/Z/API/Z/inspection/Objective-C/modules/Objective-C v2.0.h +15 -0
- data/src/external/Z/API/Z/inspection/Objective-C.h +51 -0
- data/src/external/Z/API/Z/inspection/Z.h +19 -0
- data/src/external/Z/API/Z/inspection/build.h +22 -0
- data/src/external/Z/API/Z/inspection/character set.h +66 -0
- data/src/external/Z/API/Z/inspection/compiler/completion.h +2885 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/Apple LLVM.h +26 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/Clang.h +1664 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/GCC.h +1366 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/SCCZ80.h +473 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/Visual C++.h +606 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/cc65.h +529 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/generic.h +13 -0
- data/src/external/Z/API/Z/inspection/compiler/modules/template.h +650 -0
- data/src/external/Z/API/Z/inspection/compiler.h +299 -0
- data/src/external/Z/API/Z/inspection/data model/completion.h +128 -0
- data/src/external/Z/API/Z/inspection/data model/deduction.h +9 -0
- data/src/external/Z/API/Z/inspection/data model/detection.h +45 -0
- data/src/external/Z/API/Z/inspection/data model.h +362 -0
- data/src/external/Z/API/Z/inspection/floating-point/completion.h +50 -0
- data/src/external/Z/API/Z/inspection/floating-point.h +324 -0
- data/src/external/Z/API/Z/inspection/language.h +163 -0
- data/src/external/Z/API/Z/inspection/platform/detection.h +9 -0
- data/src/external/Z/API/Z/inspection/platform.h +29 -0
- data/src/external/Z/API/Z/keys/C++.h +27 -0
- data/src/external/Z/API/Z/keys/C.h +29 -0
- data/src/external/Z/API/Z/keys/CPU.h +80 -0
- data/src/external/Z/API/Z/keys/OS.h +182 -0
- data/src/external/Z/API/Z/keys/Objective-C.h +17 -0
- data/src/external/Z/API/Z/keys/chemistry.h +26 -0
- data/src/external/Z/API/Z/keys/compiler.h +178 -0
- data/src/external/Z/API/Z/keys/data model.h +32 -0
- data/src/external/Z/API/Z/keys/endianness.h +24 -0
- data/src/external/Z/API/Z/keys/language.h +21 -0
- data/src/external/Z/API/Z/keys/layout.h +20 -0
- data/src/external/Z/API/Z/keys/mathematics/geometry.h +29 -0
- data/src/external/Z/API/Z/keys/mathematics/number.h +21 -0
- data/src/external/Z/API/Z/keys/order.h +18 -0
- data/src/external/Z/API/Z/keys/platform.h +87 -0
- data/src/external/Z/API/Z/keys/program.h +39 -0
- data/src/external/Z/API/Z/keys/science/chemical elements.h +200 -0
- data/src/external/Z/API/Z/keys/science/electricity.h +18 -0
- data/src/external/Z/API/Z/keys/science/magnetism.h +19 -0
- data/src/external/Z/API/Z/keys/status.h +69 -0
- data/src/external/Z/API/Z/keys/text.h +27 -0
- data/src/external/Z/API/Z/keys/value.h +88 -0
- data/src/external/Z/API/Z/macros/arguments.h +25 -0
- data/src/external/Z/API/Z/macros/casting.h +22 -0
- data/src/external/Z/API/Z/macros/character.h +159 -0
- data/src/external/Z/API/Z/macros/date.h +14 -0
- data/src/external/Z/API/Z/macros/key.h +20 -0
- data/src/external/Z/API/Z/macros/language.h +126 -0
- data/src/external/Z/API/Z/macros/language.hpp +81 -0
- data/src/external/Z/API/Z/macros/members.h +86 -0
- data/src/external/Z/API/Z/macros/pasting.h +308 -0
- data/src/external/Z/API/Z/macros/pointer.h +33 -0
- data/src/external/Z/API/Z/macros/repetition.h +283 -0
- data/src/external/Z/API/Z/macros/structure.h +104 -0
- data/src/external/Z/API/Z/macros/templating.h +407 -0
- data/src/external/Z/API/Z/macros/tokens.h +14 -0
- data/src/external/Z/API/Z/macros/type enumeration.h +43 -0
- data/src/external/Z/API/Z/macros/type selection.hpp +76 -0
- data/src/external/Z/API/Z/macros/value.h +489 -0
- data/src/external/Z/API/Z/macros/variadic pasting.h +21 -0
- data/src/external/Z/API/Z/macros/variadic selection.h +56 -0
- data/src/external/Z/API/Z/macros/variadic.h +46 -0
- data/src/external/Z/API/Z/macros/version.h +17 -0
- data/src/external/Z/API/Z/network/3/IP.h +36 -0
- data/src/external/Z/API/Z/network/4/TCP.h +24 -0
- data/src/external/Z/API/Z/network/4/UDP.h +26 -0
- data/src/external/Z/API/Z/network/7/ED2K.h +104 -0
- data/src/external/Z/API/Z/network/7/HTTP.h +100 -0
- data/src/external/Z/API/Z/traits/SelectType.hpp +71 -0
- data/src/external/Z/API/Z/traits/TernaryType.hpp +20 -0
- data/src/external/Z/API/Z/traits/Type.hpp +4516 -0
- data/src/external/Z/API/Z/traits/TypeCount.hpp +52 -0
- data/src/external/Z/API/Z/traits/TypeList.hpp +376 -0
- data/src/external/Z/API/Z/traits/base.hpp +19 -0
- data/src/external/Z/API/Z/traits/filtering.hpp +30 -0
- data/src/external/Z/API/Z/traits/mathematics.hpp +48 -0
- data/src/external/Z/API/Z/types/arguments.h +19 -0
- data/src/external/Z/API/Z/types/base.h +1655 -0
- data/src/external/Z/API/Z/types/base.hpp +169 -0
- data/src/external/Z/API/Z/types/buffering.h +27 -0
- data/src/external/Z/API/Z/types/mathematics.h +135 -0
- data/src/external/Z/API/Z/types/time.h +23 -0
- data/src/external/Z/COPYING.LESSER +165 -0
- data/src/external/Z/development/Qt Creator/Z.pro +253 -0
- data/src/external/Z/distribution/CocoaPods/Zeta.podspec +18 -0
- data/src/external/Z/distribution/Gentoo Linux/Zeta-0.1.ebuild +22 -0
- data/src/external/Z/distribution/Gentoo Linux/metadata.xml +8 -0
- data/src/external/Z/distribution/Homebrew/Zeta.rb +11 -0
- data/src/external/z80/API/emulation/CPU/Z80.h +201 -0
- data/src/external/z80/README.md +229 -0
- data/src/external/z80/building/premake4.lua +33 -0
- data/src/external/z80/development/Xcode/Z80.xcodeproj/project.pbxproj +520 -0
- data/src/external/z80/sources/Z80.c +1660 -0
- data/src/interrupt.c +6 -0
- data/src/interrupt.h +3 -0
- data/src/io.c.erb +115 -0
- data/src/io.h.erb +18 -0
- data/src/main.c +69 -0
- data/src/memory.c.erb +43 -0
- data/src/memory.h.erb +9 -0
- metadata +329 -0
@@ -0,0 +1,1660 @@
|
|
1
|
+
/* ______ ______ ______
|
2
|
+
/\___ \ /\ __ \/\ __ \
|
3
|
+
\/__/ /_\ \ __ \ \ \/\ \
|
4
|
+
/\_____\ \_____\ \_____\
|
5
|
+
Zilog \/_____/\/_____/\/_____/ CPU Emulator ----------------------------------
|
6
|
+
Copyright (C) 1999-2018 Manuel Sainz de Baranda y Goñi.
|
7
|
+
|
8
|
+
This emulator is free software: you can redistribute it and/or modify it under
|
9
|
+
the terms of the GNU General Public License as published by the Free Software
|
10
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
11
|
+
version.
|
12
|
+
|
13
|
+
This emulator is distributed in the hope that it will be useful, but WITHOUT
|
14
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU General Public License along with
|
18
|
+
this emulator. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
--------------------------------------------------------------------------- */
|
20
|
+
|
21
|
+
#ifndef CPU_Z80_DEPENDENCIES_H
|
22
|
+
# include <Z/macros/value.h>
|
23
|
+
# include <Z/macros/pointer.h>
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#if defined(CPU_Z80_HIDE_API)
|
27
|
+
# define CPU_Z80_API static
|
28
|
+
#elif defined(CPU_Z80_STATIC)
|
29
|
+
# define CPU_Z80_API
|
30
|
+
#else
|
31
|
+
# define CPU_Z80_API Z_API_EXPORT
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#if defined(CPU_Z80_WITH_MODULE_ABI) && !defined(CPU_Z80_WITH_ABI)
|
35
|
+
# define CPU_Z80_WITH_ABI
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#ifdef CPU_Z80_WITH_ABI
|
39
|
+
# if defined(CPU_Z80_HIDE_ABI)
|
40
|
+
# define CPU_Z80_ABI static
|
41
|
+
# elif defined(CPU_Z80_STATIC)
|
42
|
+
# define CPU_Z80_ABI
|
43
|
+
# else
|
44
|
+
# define CPU_Z80_ABI Z_API_EXPORT
|
45
|
+
# endif
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#ifdef CPU_Z80_USE_LOCAL_HEADER
|
49
|
+
# include "Z80.h"
|
50
|
+
#else
|
51
|
+
# include <emulation/CPU/Z80.h>
|
52
|
+
#endif
|
53
|
+
|
54
|
+
|
55
|
+
/* MARK: - Types */
|
56
|
+
|
57
|
+
typedef zuint8 (* Instruction)(Z80 *object);
|
58
|
+
|
59
|
+
|
60
|
+
/* MARK: - Macros: External */
|
61
|
+
|
62
|
+
#define O(member) Z_OFFSET_OF(Z80, member)
|
63
|
+
#define ROL(value) value = (zuint8)Z_8BIT_ROTATE_LEFT( value, 1)
|
64
|
+
#define ROR(value) value = (zuint8)Z_8BIT_ROTATE_RIGHT(value, 1)
|
65
|
+
|
66
|
+
|
67
|
+
/* MARK: - Macros & Functions: Callback */
|
68
|
+
|
69
|
+
#define READ_8(address) object->read (object->context, (zuint16)(address))
|
70
|
+
#define WRITE_8(address, value) object->write (object->context, (zuint16)(address), (zuint8)(value))
|
71
|
+
#define IN(port) object->in (object->context, (zuint16)(port ))
|
72
|
+
#define OUT(port, value) object->out (object->context, (zuint16)(port ), (zuint8)(value))
|
73
|
+
#define INT_DATA object->int_data(object->context)
|
74
|
+
#define READ_OFFSET(address) ((zsint8)READ_8(address))
|
75
|
+
#define SET_HALT if (object->halt != NULL) object->halt(object->context, TRUE )
|
76
|
+
#define CLEAR_HALT if (object->halt != NULL) object->halt(object->context, FALSE)
|
77
|
+
|
78
|
+
|
79
|
+
static Z_INLINE zuint16 read_16bit(Z80 *object, zuint16 address)
|
80
|
+
{return (zuint16)(READ_8(address) | (zuint16)READ_8(address + 1) << 8);}
|
81
|
+
|
82
|
+
|
83
|
+
static Z_INLINE void write_16bit(Z80 *object, zuint16 address, zuint16 value)
|
84
|
+
{
|
85
|
+
WRITE_8(address, (zuint8)value);
|
86
|
+
WRITE_8(address + 1, value >> 8);
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
#define READ_16(address) read_16bit (object, (zuint16)(address))
|
91
|
+
#define WRITE_16(address, value) write_16bit(object, (zuint16)(address), (zuint16)(value))
|
92
|
+
|
93
|
+
|
94
|
+
/* MARK: - Macros: Registers */
|
95
|
+
|
96
|
+
#define AF object->state.Z_Z80_STATE_MEMBER_AF
|
97
|
+
#define BC object->state.Z_Z80_STATE_MEMBER_BC
|
98
|
+
#define DE object->state.Z_Z80_STATE_MEMBER_DE
|
99
|
+
#define HL object->state.Z_Z80_STATE_MEMBER_HL
|
100
|
+
#define IX object->state.Z_Z80_STATE_MEMBER_IX
|
101
|
+
#define IY object->state.Z_Z80_STATE_MEMBER_IY
|
102
|
+
#define PC object->state.Z_Z80_STATE_MEMBER_PC
|
103
|
+
#define SP object->state.Z_Z80_STATE_MEMBER_SP
|
104
|
+
#define AF_ object->state.Z_Z80_STATE_MEMBER_AF_
|
105
|
+
#define BC_ object->state.Z_Z80_STATE_MEMBER_BC_
|
106
|
+
#define DE_ object->state.Z_Z80_STATE_MEMBER_DE_
|
107
|
+
#define HL_ object->state.Z_Z80_STATE_MEMBER_HL_
|
108
|
+
#define A object->state.Z_Z80_STATE_MEMBER_A
|
109
|
+
#define F object->state.Z_Z80_STATE_MEMBER_F
|
110
|
+
#define B object->state.Z_Z80_STATE_MEMBER_B
|
111
|
+
#define C object->state.Z_Z80_STATE_MEMBER_C
|
112
|
+
#define L object->state.Z_Z80_STATE_MEMBER_L
|
113
|
+
#define I object->state.Z_Z80_STATE_MEMBER_I
|
114
|
+
#define R object->state.Z_Z80_STATE_MEMBER_R
|
115
|
+
#define R_ALL ((R & 127) | (R7 & 128))
|
116
|
+
|
117
|
+
|
118
|
+
/* MARK: - Macros: Internal Bits */
|
119
|
+
|
120
|
+
#define HALT object->state.Z_Z80_STATE_MEMBER_HALT
|
121
|
+
#define IFF1 object->state.Z_Z80_STATE_MEMBER_IFF1
|
122
|
+
#define IFF2 object->state.Z_Z80_STATE_MEMBER_IFF2
|
123
|
+
#define EI object->state.Z_Z80_STATE_MEMBER_EI
|
124
|
+
#define IM object->state.Z_Z80_STATE_MEMBER_IM
|
125
|
+
#define NMI object->state.Z_Z80_STATE_MEMBER_NMI
|
126
|
+
#define INT object->state.Z_Z80_STATE_MEMBER_IRQ
|
127
|
+
|
128
|
+
|
129
|
+
/* MARK: - Macros: Temporal Data */
|
130
|
+
|
131
|
+
#define CYCLES object->cycles
|
132
|
+
#define R7 object->r7
|
133
|
+
#define BYTE(index) object->data.array_uint8[index]
|
134
|
+
#define BYTE0 BYTE(0)
|
135
|
+
#define BYTE1 BYTE(1)
|
136
|
+
#define BYTE2 BYTE(2)
|
137
|
+
#define BYTE3 BYTE(3)
|
138
|
+
#define XY object->xy.value_uint16
|
139
|
+
#define XY_ADDRESS ((zuint16)(XY + object->data.array_sint8[2]))
|
140
|
+
|
141
|
+
|
142
|
+
/* MARK: - Macros: Flags */
|
143
|
+
|
144
|
+
#define SF 128
|
145
|
+
#define ZF 64
|
146
|
+
#define YF 32
|
147
|
+
#define HF 16
|
148
|
+
#define XF 8
|
149
|
+
#define PF 4
|
150
|
+
#define NF 2
|
151
|
+
#define CF 1
|
152
|
+
|
153
|
+
#define SZPF (SF | ZF | PF)
|
154
|
+
#define SYXF (SF | YF | XF)
|
155
|
+
#define ZPF (ZF | PF )
|
156
|
+
#define YXCF (YF | XF | CF)
|
157
|
+
#define YXF (YF | XF )
|
158
|
+
#define PNF (PF | NF )
|
159
|
+
#define HCF (HF | CF )
|
160
|
+
|
161
|
+
#define F_H (F & HF)
|
162
|
+
#define F_N (F & NF)
|
163
|
+
#define F_C (F & CF)
|
164
|
+
#define F_SZP (F & SZPF)
|
165
|
+
#define A_SYX (A & SYXF)
|
166
|
+
#define A_YX (A & YXF)
|
167
|
+
|
168
|
+
#define ZF_ZERO(value) (!(value) << 6)
|
169
|
+
|
170
|
+
|
171
|
+
/* MARK: - P/V Flag Computation */
|
172
|
+
|
173
|
+
static zuint8 const pf_parity_table[256] = {
|
174
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
175
|
+
/* 0 */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
176
|
+
/* 1 */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
177
|
+
/* 2 */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
178
|
+
/* 3 */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
179
|
+
/* 4 */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
180
|
+
/* 5 */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
181
|
+
/* 6 */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
182
|
+
/* 7 */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
183
|
+
/* 8 */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
184
|
+
/* 9 */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
185
|
+
/* A */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
186
|
+
/* B */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
187
|
+
/* C */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
|
188
|
+
/* D */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
189
|
+
/* E */ 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
|
190
|
+
/* F */ 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4
|
191
|
+
};
|
192
|
+
|
193
|
+
#define PF_PARITY(value) pf_parity_table[value]
|
194
|
+
|
195
|
+
#define VF(function, operand) \
|
196
|
+
static Z_INLINE zuint8 pf_overflow_##function##8(zuint8 a, zuint8 b) \
|
197
|
+
{ \
|
198
|
+
zsint total = ((zsint)((zsint8)a)) operand ((zsint)((zsint8)b)); \
|
199
|
+
\
|
200
|
+
return total < -128 || total > 127 ? PF : 0; \
|
201
|
+
}
|
202
|
+
|
203
|
+
VF(add, +)
|
204
|
+
VF(sub, -)
|
205
|
+
|
206
|
+
#undef VF
|
207
|
+
#define VF(function, bits, type, operand, minimum, maximum) \
|
208
|
+
static Z_INLINE zuint8 pf_overflow_##function##bits(zuint##bits a, zuint##bits b, zuint8 carry) \
|
209
|
+
{ \
|
210
|
+
type total = ((type)((zsint##bits)a)) operand ((type)((zsint##bits)b)) operand carry; \
|
211
|
+
\
|
212
|
+
return total < minimum || total > maximum ? PF : 0; \
|
213
|
+
}
|
214
|
+
|
215
|
+
VF(adc, 8, zsint, +, -128, 127)
|
216
|
+
VF(sbc, 8, zsint, -, -128, 127)
|
217
|
+
VF(adc, 16, zsint32, +, -32768, 32767)
|
218
|
+
VF(sbc, 16, zsint32, -, -32768, 32767)
|
219
|
+
|
220
|
+
|
221
|
+
/* MARK: - 8-Bit Register Resolution
|
222
|
+
|
223
|
+
.----------. .---------. .-----------. .-----------.
|
224
|
+
| 76543210 | | X / Y | | J / K | | P / Q |
|
225
|
+
|----------| |---------| |-----------| |-----------|
|
226
|
+
| __xxx___ | | 000 = b | | 000 = b | | 000 = b |
|
227
|
+
| _____yyy | | 001 = c | | 001 = c | | 001 = c |
|
228
|
+
| __jjj___ | | 010 = d | | 010 = d | | 010 = d |
|
229
|
+
| _____kkk | | 011 = e | | 011 = e | | 011 = e |
|
230
|
+
| __ppp___ | | 100 = h | | 100 = ixh | | 100 = iyh |
|
231
|
+
| _____qqq | | 101 = l | | 101 = ixl | | 101 = iyl |
|
232
|
+
'----------' | 111 = a | | 111 = a | | 111 = a |
|
233
|
+
'---------' '-----------' '----------*/
|
234
|
+
|
235
|
+
static zuint8 const x_y_table[8] = {
|
236
|
+
O(state.Z_Z80_STATE_MEMBER_B),
|
237
|
+
O(state.Z_Z80_STATE_MEMBER_C),
|
238
|
+
O(state.Z_Z80_STATE_MEMBER_D),
|
239
|
+
O(state.Z_Z80_STATE_MEMBER_E),
|
240
|
+
O(state.Z_Z80_STATE_MEMBER_H),
|
241
|
+
O(state.Z_Z80_STATE_MEMBER_L),
|
242
|
+
0,
|
243
|
+
O(state.Z_Z80_STATE_MEMBER_A)
|
244
|
+
};
|
245
|
+
|
246
|
+
static zuint8 const j_k_p_q_table[8] = {
|
247
|
+
O(state.Z_Z80_STATE_MEMBER_B),
|
248
|
+
O(state.Z_Z80_STATE_MEMBER_C),
|
249
|
+
O(state.Z_Z80_STATE_MEMBER_D),
|
250
|
+
O(state.Z_Z80_STATE_MEMBER_E),
|
251
|
+
O(xy.values_uint8.index1 ),
|
252
|
+
O(xy.values_uint8.index0 ),
|
253
|
+
0,
|
254
|
+
O(state.Z_Z80_STATE_MEMBER_A)
|
255
|
+
};
|
256
|
+
|
257
|
+
#define R_8(name, table, offset, mask, shift) \
|
258
|
+
static Z_INLINE zuint8 *name(Z80 *object) \
|
259
|
+
{return ((zuint8 *)object) + table[(BYTE(offset) & mask) shift];}
|
260
|
+
|
261
|
+
R_8(__xxx___0, x_y_table, 0, 56, >> 3 )
|
262
|
+
R_8(__xxx___1, x_y_table, 1, 56, >> 3 )
|
263
|
+
R_8(_____yyy0, x_y_table, 0, 7, Z_EMPTY)
|
264
|
+
R_8(_____yyy1, x_y_table, 1, 7, Z_EMPTY)
|
265
|
+
R_8(_____yyy3, x_y_table, 3, 7, Z_EMPTY)
|
266
|
+
R_8(__jjj___ , j_k_p_q_table, 1, 56, >> 3 )
|
267
|
+
R_8(_____kkk , j_k_p_q_table, 1, 7, Z_EMPTY)
|
268
|
+
|
269
|
+
|
270
|
+
/* MARK: - 16-Bit Register Resolution
|
271
|
+
|
272
|
+
.----------. .---------. .---------. .---------.
|
273
|
+
| 76543210 | | S | | T | | W |
|
274
|
+
|----------| |---------| |---------| |---------|
|
275
|
+
| __ss____ | | 00 = bc | | 00 = bc | | 00 = bc |
|
276
|
+
| __tt____ | | 01 = de | | 01 = de | | 01 = de |
|
277
|
+
'----------' | 10 = hl | | 10 = hl | | 10 = XY |
|
278
|
+
| 11 = sp | | 11 = af | | 11 = sp |
|
279
|
+
'---------' '---------' '--------*/
|
280
|
+
|
281
|
+
static zuint8 const s_table[4] = {
|
282
|
+
O(state.Z_Z80_STATE_MEMBER_BC),
|
283
|
+
O(state.Z_Z80_STATE_MEMBER_DE),
|
284
|
+
O(state.Z_Z80_STATE_MEMBER_HL),
|
285
|
+
O(state.Z_Z80_STATE_MEMBER_SP)
|
286
|
+
};
|
287
|
+
|
288
|
+
static zuint8 const t_table[4] = {
|
289
|
+
O(state.Z_Z80_STATE_MEMBER_BC),
|
290
|
+
O(state.Z_Z80_STATE_MEMBER_DE),
|
291
|
+
O(state.Z_Z80_STATE_MEMBER_HL),
|
292
|
+
O(state.Z_Z80_STATE_MEMBER_AF)
|
293
|
+
};
|
294
|
+
|
295
|
+
static zuint8 const w_table[4] = {
|
296
|
+
O(state.Z_Z80_STATE_MEMBER_BC),
|
297
|
+
O(state.Z_Z80_STATE_MEMBER_DE),
|
298
|
+
O(xy ),
|
299
|
+
O(state.Z_Z80_STATE_MEMBER_SP)
|
300
|
+
};
|
301
|
+
|
302
|
+
#define R_16(name, table, offset) \
|
303
|
+
static Z_INLINE zuint16 *name(Z80 *object) \
|
304
|
+
{return Z_BOP(zuint16 *, object, table[(BYTE(offset) & 48) >> 4]);}
|
305
|
+
|
306
|
+
R_16(__ss____0, s_table, 0)
|
307
|
+
R_16(__ss____1, s_table, 1)
|
308
|
+
R_16(__tt____ , t_table, 0)
|
309
|
+
|
310
|
+
|
311
|
+
/* MARK: - Condition Resolution
|
312
|
+
|
313
|
+
.----------. .----------.
|
314
|
+
| 76543210 | | Z |
|
315
|
+
|----------| |----------|
|
316
|
+
| __zzz___ | | 000 = nz |
|
317
|
+
| ___zz___ | | 001 = z |
|
318
|
+
'----------' | 010 = nc |
|
319
|
+
| 011 = c |
|
320
|
+
| 100 = po |
|
321
|
+
| 101 = pe |
|
322
|
+
| 110 = p |
|
323
|
+
| 111 = m |
|
324
|
+
'---------*/
|
325
|
+
|
326
|
+
static zuint8 const z_table[8] = {ZF, ZF, CF, CF, PF, PF, SF, SF};
|
327
|
+
|
328
|
+
static Z_INLINE zboolean __zzz___(Z80 *object)
|
329
|
+
{
|
330
|
+
zuint8 z = (BYTE0 & 56) >> 3;
|
331
|
+
|
332
|
+
return (F & (z_table[z]))
|
333
|
+
? (z & 1) /* Flag is 1 */
|
334
|
+
: !(z & 1); /* Flag is 0 */
|
335
|
+
}
|
336
|
+
|
337
|
+
|
338
|
+
/* MARK: - 8-Bit Arithmetic and Logical Operation Resolution and Execution
|
339
|
+
|
340
|
+
.----------. .-----------. .-------------------------------.
|
341
|
+
| 76543210 | | U | | S | Z | Y | H | X | P | N | C |
|
342
|
+
|----------| |-----------| .-----+---+---+---+---+---+---+---+---|
|
343
|
+
| __uuu___ | | 000 = add | | add | S | Z | 5 | H | 3 | V | 0 | C |
|
344
|
+
| _____vvv | | 001 = adc | |-----+---+---+---+---+---+---+---+---|
|
345
|
+
'----------' | 010 = sub | | adc | S | Z | 5 | H | 3 | V | 0 | C |
|
346
|
+
| 011 = sbc | |-----+---+---+---+---+---+---+---+---|
|
347
|
+
| 100 = and | | sub | S | Z | 5 | H | 3 | V | 1 | C |
|
348
|
+
| 101 = xor | |-----+---+---+---+---+---+---+---+---|
|
349
|
+
| 110 = or | | sbc | S | Z | 5 | H | 3 | V | 1 | C |
|
350
|
+
| 111 = cp | |-----+---+---+---+---+---+---+---+---|
|
351
|
+
|-----------| | and | S | Z | 5 | 1 | 3 | P | 0 | 0 |
|
352
|
+
| V | |-----+---+---+---+---+---+---+---+---|
|
353
|
+
|-----------| | xor | S | Z | 5 | 0 | 3 | P | 0 | 0 |
|
354
|
+
| 100 = inc | |-----+---+---+---+---+---+---+---+---|
|
355
|
+
| 101 = dec | | or | S | Z | 5 | 0 | 3 | P | 0 | 0 |
|
356
|
+
'-----------' |-----+---+---+---+---+---+---+---+---|
|
357
|
+
| cp | S | Z |v.5| H |v.3| V | 1 | C |
|
358
|
+
|-----+---+---+---+---+---+---+---+---|
|
359
|
+
| inc | S | Z |v.5| H |v.3| V | 0 | . |
|
360
|
+
|-----+---+---+---+---+---+---+---+---|
|
361
|
+
| dec | S | Z |v.5| H |v.3| V | 1 | . |
|
362
|
+
'------------------------------------*/
|
363
|
+
|
364
|
+
static void __uuu___(Z80 *object, zuint8 offset, zuint8 value)
|
365
|
+
{
|
366
|
+
zuint8 t;
|
367
|
+
|
368
|
+
switch ((object->data.array_uint8[offset] >> 3) & 7)
|
369
|
+
{
|
370
|
+
case 0: /* ADD */
|
371
|
+
t = A + value;
|
372
|
+
|
373
|
+
F = ((zuint)A + value > 255) /* CF = Carry */
|
374
|
+
| pf_overflow_add8(A, value) /* PF = Overflow */
|
375
|
+
| ((A ^ value ^ t) & HF); /* HF = Half-carry */
|
376
|
+
A = t; /* NF = 0 */
|
377
|
+
break;
|
378
|
+
|
379
|
+
case 1: /* ADC */
|
380
|
+
t = F_C;
|
381
|
+
|
382
|
+
F = ((zuint)A + value + t > 255) /* CF = Carry */
|
383
|
+
| pf_overflow_adc8(A, value, t) /* PF = Overflow */
|
384
|
+
| (((A & 0xF) + (value & 0xF) + t) & HF); /* HF = Half-carry */
|
385
|
+
/* NF = 0 */
|
386
|
+
A += value + t;
|
387
|
+
break;
|
388
|
+
|
389
|
+
case 2: /* SUB */
|
390
|
+
t = A - value;
|
391
|
+
|
392
|
+
F = (A < value) /* CF = Borrow */
|
393
|
+
| NF /* NF = 1 */
|
394
|
+
| pf_overflow_sub8(A, value) /* PF = Overflow */
|
395
|
+
| ((A ^ value ^ t) & HF); /* HF = Half-Borrow */
|
396
|
+
A = t;
|
397
|
+
break;
|
398
|
+
|
399
|
+
case 3: /* SBC */
|
400
|
+
t = F_C;
|
401
|
+
|
402
|
+
F = ((zsint)A - (zsint)value - (zsint)t < 0) /* CF = Borrow */
|
403
|
+
| NF /* NF = 1 */
|
404
|
+
| pf_overflow_sbc8(A, value, t) /* PF = Overflow */
|
405
|
+
| (((A & 0xF) - (value & 0xF) - t) & HF); /* HF = Half-Borrow */
|
406
|
+
|
407
|
+
A -= value + t;
|
408
|
+
break;
|
409
|
+
|
410
|
+
case 4: /* AND */
|
411
|
+
A &= value;
|
412
|
+
F = HF | PF_PARITY(A); /* HF = 1; PF = Parity */
|
413
|
+
break; /* NF, CF = 0 */
|
414
|
+
|
415
|
+
case 5: /* XOR */
|
416
|
+
A ^= value;
|
417
|
+
F = PF_PARITY(A); /* PF = Parity */
|
418
|
+
break; /* HF, NF, CF = 0 */
|
419
|
+
|
420
|
+
case 6: /* OR */
|
421
|
+
A |= value;
|
422
|
+
F = PF_PARITY(A); /* PF = Parity */
|
423
|
+
break; /* HF, NF, CF = 0 */
|
424
|
+
|
425
|
+
case 7: /* CP */
|
426
|
+
t = A - value;
|
427
|
+
|
428
|
+
F = (zuint8)
|
429
|
+
((A < value) /* CF = Borrow */
|
430
|
+
| NF /* NF = 1 */
|
431
|
+
| pf_overflow_sub8(A, value) /* PF = Overflow */
|
432
|
+
| ((A ^ value ^ t) & HF) /* HF = Half-Borrow */
|
433
|
+
| (value & YXF) /* YF = v.5, XF = v.3 */
|
434
|
+
| ZF_ZERO(t) /* ZF = !(A - v) */
|
435
|
+
| (t & SF)); /* SF = (A - v).7 */
|
436
|
+
return;
|
437
|
+
}
|
438
|
+
|
439
|
+
F = (zuint8)
|
440
|
+
((F & (HF | PF | NF | CF)) /* CF, NF, PF and HF already changed */
|
441
|
+
| A_SYX /* SF = A.7; YF = A.5; XF = A.3 */
|
442
|
+
| ZF_ZERO(A)); /* ZF = !A */
|
443
|
+
}
|
444
|
+
|
445
|
+
|
446
|
+
static zuint8 _____vvv(Z80 *object, zuint8 offset, zuint8 value)
|
447
|
+
{
|
448
|
+
zuint8 t, pn;
|
449
|
+
|
450
|
+
/* DEC */
|
451
|
+
if (object->data.array_uint8[offset] & 1)
|
452
|
+
{ /* PF = Overflow */
|
453
|
+
pn = value == 128 ? PNF : NF; /* NF = 1 */
|
454
|
+
t = value - 1;
|
455
|
+
}
|
456
|
+
|
457
|
+
/* INC */
|
458
|
+
else { /* PF = Overflow */
|
459
|
+
pn = value == 127 ? PF : 0; /* NF = 0 */
|
460
|
+
t = value + 1;
|
461
|
+
}
|
462
|
+
|
463
|
+
F = (zuint8)
|
464
|
+
((F & CF) /* CF unchanged */
|
465
|
+
| pn /* PF and NF already calculated */
|
466
|
+
| (t & SYXF) /* SF = v.7; YF = v.5; XF = v.3 */
|
467
|
+
| ((value ^ 1 ^ t) & HF) /* HF = Half-Borrow */
|
468
|
+
| ZF_ZERO(t)); /* ZF = !v */
|
469
|
+
|
470
|
+
return t;
|
471
|
+
}
|
472
|
+
|
473
|
+
|
474
|
+
/* MARK: - Rotation and Shift Operation Resolution and Execution
|
475
|
+
|
476
|
+
.----------. .-----------.
|
477
|
+
| 76543210 | | G |
|
478
|
+
|----------| |-----------|
|
479
|
+
| __ggg___ | | 000 = rlc |
|
480
|
+
'----------' | 001 = rrc |
|
481
|
+
| 010 = rl |
|
482
|
+
| 011 = rr |
|
483
|
+
| 100 = sla |
|
484
|
+
| 101 = sra |
|
485
|
+
| 110 = sll |
|
486
|
+
| 111 = srl |
|
487
|
+
'----------*/
|
488
|
+
|
489
|
+
static zuint8 __ggg___(Z80 *object, zuint8 offset, zuint8 value)
|
490
|
+
{
|
491
|
+
zuint8 c;
|
492
|
+
|
493
|
+
switch ((object->data.array_uint8[offset] >> 3) & 7)
|
494
|
+
{
|
495
|
+
/* RLC .----------------.
|
496
|
+
.----. | .---------. |
|
497
|
+
| CF |<-----| 7 <-- 0 |<--'
|
498
|
+
'----' '--------*/
|
499
|
+
case 0:
|
500
|
+
ROL(value);
|
501
|
+
c = value & CF;
|
502
|
+
break;
|
503
|
+
|
504
|
+
/* RRC .----------------.
|
505
|
+
| .---------. | .----.
|
506
|
+
'-->| 7 --> 0 |----->| CF |
|
507
|
+
'---------' '---*/
|
508
|
+
case 1:
|
509
|
+
c = value & CF;
|
510
|
+
ROR(value);
|
511
|
+
break;
|
512
|
+
|
513
|
+
/* RL .-------------------------.
|
514
|
+
| .----. .---------. |
|
515
|
+
'--| CF |<--| 7 <-- 0 |<--'
|
516
|
+
'----' '--------*/
|
517
|
+
case 2:
|
518
|
+
c = value >> 7;
|
519
|
+
value = (zuint8)((value << 1) | F_C);
|
520
|
+
break;
|
521
|
+
|
522
|
+
/* RR .-------------------------.
|
523
|
+
| .---------. .----. |
|
524
|
+
'-->| 7 --> 0 |-->| CF |--'
|
525
|
+
'---------' '---*/
|
526
|
+
case 3:
|
527
|
+
c = value & CF;
|
528
|
+
value = (zuint8)((value >> 1) | (F_C << 7));
|
529
|
+
break;
|
530
|
+
|
531
|
+
/* SLA .----. .---------.
|
532
|
+
| CF |<--| 7 <-- 0 |<-- 0
|
533
|
+
'----' '--------*/
|
534
|
+
case 4:
|
535
|
+
c = value >> 7;
|
536
|
+
value <<= 1;
|
537
|
+
break;
|
538
|
+
|
539
|
+
/* SRA .---------. .----.
|
540
|
+
.-->| 7 --> 0 |-->| CF |
|
541
|
+
| '---------' '----'
|
542
|
+
| |
|
543
|
+
'----*/
|
544
|
+
case 5:
|
545
|
+
c = value & CF;
|
546
|
+
value = (value & 128) | (value >> 1);
|
547
|
+
break;
|
548
|
+
|
549
|
+
/* SLL .----. .---------.
|
550
|
+
| CF |<--| 7 <-- 0 |<-- 1
|
551
|
+
'----' '--------*/
|
552
|
+
case 6:
|
553
|
+
c = value >> 7;
|
554
|
+
value = (value << 1) & 1;
|
555
|
+
break;
|
556
|
+
|
557
|
+
/* SRL .---------. .----.
|
558
|
+
0 -->| 7 --> 0 |-->| CF |
|
559
|
+
'---------' '---*/
|
560
|
+
case 7:
|
561
|
+
c = value & CF;
|
562
|
+
value >>= 1;
|
563
|
+
break;
|
564
|
+
|
565
|
+
/* Uncoment to Avoid a compiler warning */
|
566
|
+
/*default: c = 0; break;*/
|
567
|
+
}
|
568
|
+
|
569
|
+
F = (zuint8)((value & SYXF) | ZF_ZERO(value) | PF_PARITY(value) | c);
|
570
|
+
return value;
|
571
|
+
}
|
572
|
+
|
573
|
+
|
574
|
+
/* MARK: - Bit Set and Reset Operation Resolution and Execution
|
575
|
+
|
576
|
+
.----------. .---------.
|
577
|
+
| 76543210 | | M |
|
578
|
+
|----------| |---------|
|
579
|
+
| _m______ | | 0 = res |
|
580
|
+
'----------' | 1 = set |
|
581
|
+
'--------*/
|
582
|
+
|
583
|
+
static Z_INLINE zuint8 _m______(Z80 *object, zuint8 offset, zuint8 value)
|
584
|
+
{
|
585
|
+
zuint8 t = object->data.array_uint8[offset];
|
586
|
+
|
587
|
+
return (zuint8)((t & 64)
|
588
|
+
? value | (1 << ((t & 56) >> 3)) /* SET */
|
589
|
+
: value & ~(1 << ((t & 56) >> 3))); /* RES */
|
590
|
+
}
|
591
|
+
|
592
|
+
|
593
|
+
/* MARK: - Macros: Shortening */
|
594
|
+
|
595
|
+
#define N(x) ((BYTE##x & 56) >> 3)
|
596
|
+
#define X0 (*__xxx___0(object))
|
597
|
+
#define X1 (*__xxx___1(object))
|
598
|
+
#define Y0 (*_____yyy0(object))
|
599
|
+
#define Y1 (*_____yyy1(object))
|
600
|
+
#define Y3 (*_____yyy3(object))
|
601
|
+
#define JP (*__jjj___ (object))
|
602
|
+
#define KQ (*_____kkk (object))
|
603
|
+
#define SS0 (*__ss____0(object))
|
604
|
+
#define SS1 (*__ss____1(object))
|
605
|
+
#define TT (*__tt____ (object))
|
606
|
+
#define Z __zzz___ (object)
|
607
|
+
#define U0(value) __uuu___ (object, 0, value)
|
608
|
+
#define U1(value) __uuu___ (object, 1, value)
|
609
|
+
#define V0(value) _____vvv (object, 0, value)
|
610
|
+
#define V1(value) _____vvv (object, 1, value)
|
611
|
+
#define G1(value) __ggg___ (object, 1, value)
|
612
|
+
#define G3(value) __ggg___ (object, 3, value)
|
613
|
+
#define M1(value) _m______ (object, 1, value)
|
614
|
+
#define M3(value) _m______ (object, 3, value)
|
615
|
+
#define WW (*Z_BOP(zuint16 *, object, w_table[(BYTE1 >> 4) & 3]))
|
616
|
+
|
617
|
+
|
618
|
+
/* MARK: - Macros & Functions: Reusable Code */
|
619
|
+
|
620
|
+
#define INSTRUCTION(name) static zuint8 name(Z80 *object)
|
621
|
+
#define EXIT_HALT if (HALT) {PC++; HALT = FALSE; CLEAR_HALT;}
|
622
|
+
#define PUSH(value) WRITE_16(SP -= 2, value)
|
623
|
+
|
624
|
+
|
625
|
+
#define LD_A_I_LD_A_R \
|
626
|
+
F = (zuint8) /* HF = 0 / NF = 0 */ \
|
627
|
+
(A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
|
628
|
+
| ZF_ZERO(A) /* ZF = !A */ \
|
629
|
+
| (IFF2 << 2) /* PF = IFF2 */ \
|
630
|
+
| F_C); /* CF unchanged */
|
631
|
+
|
632
|
+
|
633
|
+
#define EX(a, b) t = a; a = b; b = t;
|
634
|
+
|
635
|
+
|
636
|
+
#define EX_VSP_X(register) \
|
637
|
+
t = READ_16(SP); \
|
638
|
+
WRITE_16(SP, register); \
|
639
|
+
register = t;
|
640
|
+
|
641
|
+
|
642
|
+
#define LDX(operator) \
|
643
|
+
zuint8 n; \
|
644
|
+
\
|
645
|
+
PC += 2; \
|
646
|
+
WRITE_8(DE operator, n = READ_8(HL operator)); \
|
647
|
+
n += A; \
|
648
|
+
\
|
649
|
+
F = (zuint8) /* HF = 0, NF = 0 */ \
|
650
|
+
((F & (SF | ZF | CF)) /* SF, ZF, CF unchanged */ \
|
651
|
+
| ((n & 2) << 4) /* YF = ([HL] + A).1 */ \
|
652
|
+
| (n & XF) /* XF = ([HL] + A).3 */ \
|
653
|
+
| (!!(--BC) << 2)); /* PF = 1 if BC != 0, else PF = 0 */
|
654
|
+
|
655
|
+
|
656
|
+
#define LDXR(operator) \
|
657
|
+
LDX(operator) \
|
658
|
+
if (!BC) return 16; \
|
659
|
+
PC -= 2; return 21;
|
660
|
+
|
661
|
+
|
662
|
+
#define CPX(operator) \
|
663
|
+
zuint8 v, n0, n1; \
|
664
|
+
\
|
665
|
+
PC += 2; \
|
666
|
+
n1 = (n0 = A - (v = READ_8(HL operator))) - !!F_H; \
|
667
|
+
\
|
668
|
+
F = (zuint8) \
|
669
|
+
((n0 & SF) /* SF = (A - [HL]).7 */ \
|
670
|
+
| ZF_ZERO(n0) /* ZF = !(A - [HL]) */ \
|
671
|
+
| ((A ^ v ^ n0) & HF) /* HF = borrow from bit 5 */ \
|
672
|
+
| ((n1 & 2) << 4) /* YF = (A - [HL] - HF).1 */ \
|
673
|
+
| (n1 & XF) /* XF = (A - [HL] - HF).3 */ \
|
674
|
+
| (!!(--BC) << 2) /* PF = !!BC */ \
|
675
|
+
| NF /* NF = 1 */ \
|
676
|
+
| F_C); /* CF unchanged */
|
677
|
+
|
678
|
+
|
679
|
+
#define CPXR(operator) \
|
680
|
+
CPX(operator) \
|
681
|
+
if (!BC || !n0) return 16; \
|
682
|
+
PC -= 2; return 21;
|
683
|
+
|
684
|
+
|
685
|
+
static Z_INLINE void add_RR_NN(Z80 *object, zuint16 *r, zuint16 v)
|
686
|
+
{
|
687
|
+
zuint16 t = *r + v;
|
688
|
+
|
689
|
+
F = F_SZP /* SF, ZF, PF unchanged */
|
690
|
+
| ((t >> 8) & YXF) /* YF = RR.13; XF = RR.11 */
|
691
|
+
| (((*r ^ v ^ t) >> 8) & HF) /* HF = RRh half-carry */
|
692
|
+
| ((zuint32)*r + v > 65535); /* CF = Carry */
|
693
|
+
*r = t; /* NF = 0 */
|
694
|
+
}
|
695
|
+
|
696
|
+
|
697
|
+
#define ADD_RR_NN(register, value) \
|
698
|
+
add_RR_NN(object, (zuint16 *)®ister, value);
|
699
|
+
|
700
|
+
|
701
|
+
#define ADC_SBC_HL_SS(function, sign, cf_test, set_nf) \
|
702
|
+
zuint8 c = F_C; \
|
703
|
+
zuint16 v = SS1, t = HL sign v sign c; \
|
704
|
+
\
|
705
|
+
F = (zuint8) \
|
706
|
+
(((t >> 8) & SYXF) /* SF = HL.15; YF = HL.13; XF = HL.11 */ \
|
707
|
+
| ZF_ZERO(t) /* ZF = !HL */ \
|
708
|
+
| ((((HL & 0xFFF) sign (v & 0xFFF) sign c) >> 8) & HF) /* HF = Half-carry of H */ \
|
709
|
+
| pf_overflow_##function##16(HL, v, c) /* PF = Overflow */ \
|
710
|
+
| !!(cf_test) /* CF = Carry */ \
|
711
|
+
set_nf); /* ADC: NF = 0; SBC: NF = 1 */ \
|
712
|
+
\
|
713
|
+
HL = t; \
|
714
|
+
PC += 2; \
|
715
|
+
return 15;
|
716
|
+
|
717
|
+
|
718
|
+
#define RXA \
|
719
|
+
F = F_SZP /* SF, ZF, PF unchanged */ \
|
720
|
+
| A_YX /* YF = A.5; XF = A.3 */ \
|
721
|
+
| c; /* CF = Ai.7 (rla) / Ai.0 (rra) */
|
722
|
+
|
723
|
+
|
724
|
+
#define RXD(a, b, c) \
|
725
|
+
zuint8 t; \
|
726
|
+
\
|
727
|
+
PC += 2; \
|
728
|
+
WRITE_8(HL, ((t = READ_8(HL)) a 4) | (A b)); \
|
729
|
+
A = (A & 0xF0) | (t c); \
|
730
|
+
\
|
731
|
+
F = (zuint8) \
|
732
|
+
(A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
|
733
|
+
| ZF_ZERO(A) /* ZF = !A */ \
|
734
|
+
| PF_PARITY(A) /* PF = Parity of A */ \
|
735
|
+
| F_C); /* CF unchanged */ \
|
736
|
+
/* HF = 0, NF = 0; */
|
737
|
+
|
738
|
+
|
739
|
+
#define BIT_N_VALUE(value) \
|
740
|
+
zuint8 n = value & (1 << N(1)); /* SF = value.N && N == 7 */ \
|
741
|
+
/* ZF, PF = !value.N */ \
|
742
|
+
F = (n ? n & SYXF : ZPF) /* YF = value.N && N == 5 */ \
|
743
|
+
| HF /* HF = 1; NF = 0; CF unchanged */ \
|
744
|
+
| F_C; /* XF = value.N && N == 3 */
|
745
|
+
|
746
|
+
|
747
|
+
#define BIT_N_VADDRESS(address) \
|
748
|
+
Z16Bit a; \
|
749
|
+
zuint8 n = READ_8(a.value_uint16 = address) & (1 << N(3)); \
|
750
|
+
\
|
751
|
+
F = (n ? (n & SF) : ZPF) \
|
752
|
+
| (a.values_uint8.index1 & YXF) \
|
753
|
+
| HF \
|
754
|
+
| F_C;
|
755
|
+
|
756
|
+
|
757
|
+
#define IN_VC \
|
758
|
+
zuint8 t; \
|
759
|
+
\
|
760
|
+
PC += 2; \
|
761
|
+
t = IN(BC); \
|
762
|
+
\
|
763
|
+
F = (zuint8) \
|
764
|
+
((t & SYXF) \
|
765
|
+
| ZF_ZERO(t) \
|
766
|
+
| PF_PARITY(t) \
|
767
|
+
| F_C);
|
768
|
+
|
769
|
+
|
770
|
+
#define INX(hl_operator, c_operator) \
|
771
|
+
zuint8 v; \
|
772
|
+
zuint t; \
|
773
|
+
\
|
774
|
+
PC += 2; \
|
775
|
+
t = (zuint)(v = IN(BC)) + ((C c_operator 1) & 255); \
|
776
|
+
WRITE_8(HL, v); \
|
777
|
+
HL hl_operator; \
|
778
|
+
B--; \
|
779
|
+
\
|
780
|
+
F = (zuint8) \
|
781
|
+
((B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
|
782
|
+
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
|
783
|
+
| PF_PARITY((t & 7) ^ B) /* PF = Parity of (([HL] + ((C +/- 1) & 255)) and 7) xor B */ \
|
784
|
+
| (v & 128)); /* NF = IN(BC).7 */ \
|
785
|
+
/* if (([HL] + ((C +/- 1) & 255)) > 255) HF = 1; else HF = 0 */ \
|
786
|
+
if (t > 255) F |= HCF; /* if (([HL] + ((C +/- 1) & 255)) > 255) HF = 1; else HF = 0 */
|
787
|
+
|
788
|
+
|
789
|
+
#define INXR(hl_operator, c_operator) \
|
790
|
+
INX(hl_operator, c_operator); \
|
791
|
+
if (!B) return 16; \
|
792
|
+
PC -= 2; return 21;
|
793
|
+
|
794
|
+
|
795
|
+
#define OUTX(operator) \
|
796
|
+
zuint8 t; \
|
797
|
+
\
|
798
|
+
PC += 2; \
|
799
|
+
OUT(BC, t = READ_8(HL)); \
|
800
|
+
HL operator; \
|
801
|
+
B--; \
|
802
|
+
\
|
803
|
+
F = (zuint8) \
|
804
|
+
((B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
|
805
|
+
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
|
806
|
+
| PF_PARITY(((L + t) & 7) ^ B) /* PF = Parity of ((L + [HL]) and 7) xor B */ \
|
807
|
+
| (t & 128)); /* NF = IN(BC).7 */ \
|
808
|
+
/* if (L + [HL] > 255) HF = 1; else HF = 0 */ \
|
809
|
+
if ((zuint)t + L > 255) F |= HCF; /* if (L + [HL] > 255) CF = 1; else CF = 0 */
|
810
|
+
|
811
|
+
|
812
|
+
#define OTXR(operator) \
|
813
|
+
OUTX(operator); \
|
814
|
+
if (!B) return 16; \
|
815
|
+
PC -= 2; return 21;
|
816
|
+
|
817
|
+
|
818
|
+
#define RET PC = READ_16(SP); SP += 2;
|
819
|
+
|
820
|
+
|
821
|
+
/* MARK: - Instructions: 8-Bit Load Group
|
822
|
+
.---------------------------------------------------------------------------.
|
823
|
+
| 0 1 2 3 Flags |
|
824
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
825
|
+
| ----------------------------------------------------------------------- |
|
826
|
+
| ld X,Y 01xxxyyy ........ 1 / 4 |
|
827
|
+
| ld J,K < DD >01jjjkkk ........ 2 / 8 |
|
828
|
+
| ld P,Q < FD >01pppqqq ........ 2 / 8 |
|
829
|
+
| ld X,BYTE 00xxx110< BYTE > ........ 2 / 7 |
|
830
|
+
| ld J,BYTE < DD >00jjj110< BYTE > ........ 3 / 11 |
|
831
|
+
| ld P,BYTE < FD >00ppp110< BYTE > ........ 3 / 11 |
|
832
|
+
| ld X,(hl) 01xxx110 ........ 2 / 7 |
|
833
|
+
| ld X,(ix+OFFSET) < DD >01xxx110<OFFSET> ........ 5 / 19 |
|
834
|
+
| ld X,(iy+OFFSET) < FD >01xxx110<OFFSET> ........ 5 / 19 |
|
835
|
+
| ld (hl),Y 01110yyy ........ 2 / 7 |
|
836
|
+
| ld (ix+OFFSET),Y < DD >01110yyy<OFFSET> ........ 5 / 19 |
|
837
|
+
| ld (iy+OFFSET),Y < FD >01110yyy<OFFSET> ........ 5 / 19 |
|
838
|
+
| ld (hl),BYTE < 36 >< BYTE > ........ 3 / 10 |
|
839
|
+
| ld (ix+OFFSET),BYTE < DD >< 36 ><OFFSET>< BYTE > ........ 5 / 19 |
|
840
|
+
| ld (iy+OFFSET),BYTE < FD >< 36 ><OFFSET>< BYTE > ........ 5 / 19 |
|
841
|
+
| ld a,(bc) < 0A > ........ 2 / 7 |
|
842
|
+
| ld a,(de) < 1A > ........ 2 / 7 |
|
843
|
+
| ld a,(WORD) < 3A >< WORD > ........ 4 / 13 |
|
844
|
+
| ld (bc),a < 02 > ........ 2 / 7 |
|
845
|
+
| ld (de),a < 12 > ........ 2 / 7 |
|
846
|
+
| ld (WORD),a < 32 >< WORD > ........ 4 / 13 |
|
847
|
+
| ld a,i < ED >< 57 > szy0xi0. 2 / 9 |
|
848
|
+
| ld a,r < ED >< 5F > szy0xi0. 2 / 9 |
|
849
|
+
| ld i,a < ED >< 47 > ........ 2 / 9 |
|
850
|
+
| ld r,a < ED >< 4F > ........ 2 / 9 |
|
851
|
+
'--------------------------------------------------------------------------*/
|
852
|
+
|
853
|
+
INSTRUCTION(ld_X_Y) {PC++; X0 = Y0; return 4;}
|
854
|
+
INSTRUCTION(ld_JP_KQ) {PC += 2; JP = KQ; return 8;}
|
855
|
+
INSTRUCTION(ld_X_BYTE) {X0 = READ_8((PC += 2) - 1); return 7;}
|
856
|
+
INSTRUCTION(ld_JP_BYTE) {JP = READ_8((PC += 3) - 1); return 11;}
|
857
|
+
INSTRUCTION(ld_X_vhl) {PC++; X0 = READ_8(HL); return 7;}
|
858
|
+
INSTRUCTION(ld_X_vXYOFFSET) {X1 = READ_8(XY + READ_OFFSET((PC += 3) - 1)); return 19;}
|
859
|
+
INSTRUCTION(ld_vhl_Y) {PC++; WRITE_8(HL, Y0); return 7;}
|
860
|
+
INSTRUCTION(ld_vXYOFFSET_Y) {WRITE_8(XY + READ_OFFSET((PC += 3) - 1), Y1); return 19;}
|
861
|
+
INSTRUCTION(ld_vhl_BYTE) {WRITE_8(HL, READ_8((PC += 2) - 1)); return 10;}
|
862
|
+
INSTRUCTION(ld_vXYOFFSET_BYTE) {PC += 4; WRITE_8(XY + READ_OFFSET(PC - 2), READ_8(PC - 1)); return 19;}
|
863
|
+
INSTRUCTION(ld_a_vbc) {PC++; A = READ_8(BC); return 7;}
|
864
|
+
INSTRUCTION(ld_a_vde) {PC++; A = READ_8(DE); return 7;}
|
865
|
+
INSTRUCTION(ld_a_vWORD) {A = READ_8(READ_16((PC += 3) - 2)); return 13;}
|
866
|
+
INSTRUCTION(ld_vbc_a) {PC++; WRITE_8(BC, A); return 7;}
|
867
|
+
INSTRUCTION(ld_vde_a) {PC++; WRITE_8(DE, A); return 7;}
|
868
|
+
INSTRUCTION(ld_vWORD_a) {WRITE_8(READ_16((PC += 3) - 2), A); return 13;}
|
869
|
+
INSTRUCTION(ld_a_i) {PC += 2; A = I; LD_A_I_LD_A_R; return 9;}
|
870
|
+
INSTRUCTION(ld_a_r) {PC += 2; A = R_ALL; LD_A_I_LD_A_R; return 9;}
|
871
|
+
INSTRUCTION(ld_i_a) {PC += 2; I = A; return 9;}
|
872
|
+
INSTRUCTION(ld_r_a) {PC += 2; R = R7 = A; return 9;}
|
873
|
+
|
874
|
+
|
875
|
+
/* MARK: - Instructions: 16-Bit Load Group
|
876
|
+
.---------------------------------------------------------------------------.
|
877
|
+
| 0 1 2 3 Flags |
|
878
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
879
|
+
| ----------------------------------------------------------------------- |
|
880
|
+
| ld SS,WORD 00ss0001< WORD > ........ 3 / 10 |
|
881
|
+
| ld ix,WORD < DD >< 21 >< WORD > ........ 4 / 14 |
|
882
|
+
| ld iy,WORD < FD >< 21 >< WORD > ........ 4 / 14 |
|
883
|
+
| ld hl,(WORD) < 2A >< WORD > ........ 5 / 16 |
|
884
|
+
| ld SS,(WORD) < ED >01ss1011< WORD > ........ 6 / 20 |
|
885
|
+
| ld ix,(WORD) < DD >< 2A >< WORD > ........ 6 / 20 |
|
886
|
+
| ld iy,(WORD) < FD >< 2A >< WORD > ........ 6 / 20 |
|
887
|
+
| ld (WORD),hl < 22 >< WORD > ........ 5 / 16 |
|
888
|
+
| ld (WORD),SS < ED >01ss0011< WORD > ........ 6 / 20 |
|
889
|
+
| ld (WORD),ix < DD >< 22 >< WORD > ........ 6 / 20 |
|
890
|
+
| ld (WORD),iy < FD >< 22 >< WORD > ........ 6 / 20 |
|
891
|
+
| ld sp,hl < F9 > ........ 1 / 6 |
|
892
|
+
| ld sp,ix < DD >< F9 > ........ 2 / 10 |
|
893
|
+
| ld sp,iy < FD >< F9 > ........ 2 / 10 |
|
894
|
+
| push TT 11tt0101 ........ 3 / 11 |
|
895
|
+
| push ix < DD >< E5 > ........ 4 / 15 |
|
896
|
+
| push iy < FD >< E5 > ........ 4 / 15 |
|
897
|
+
| pop TT 11tt0001 ........ 3 / 10 |
|
898
|
+
| pop ix < DD >< E1 > ........ 4 / 14 |
|
899
|
+
| pop iy < FD >< E1 > ........ 4 / 14 |
|
900
|
+
'--------------------------------------------------------------------------*/
|
901
|
+
|
902
|
+
INSTRUCTION(ld_SS_WORD) {SS0 = READ_16((PC += 3) - 2); return 10;}
|
903
|
+
INSTRUCTION(ld_XY_WORD) {XY = READ_16((PC += 4) - 2); return 14;}
|
904
|
+
INSTRUCTION(ld_hl_vWORD) {HL = READ_16(READ_16((PC += 3) - 2)); return 16;}
|
905
|
+
INSTRUCTION(ld_SS_vWORD) {SS1 = READ_16(READ_16((PC += 4) - 2)); return 20;}
|
906
|
+
INSTRUCTION(ld_XY_vWORD) {XY = READ_16(READ_16((PC += 4) - 2)); return 20;}
|
907
|
+
INSTRUCTION(ld_vWORD_hl) {WRITE_16(READ_16((PC += 3) - 2), HL); return 16;}
|
908
|
+
INSTRUCTION(ld_vWORD_SS) {WRITE_16(READ_16((PC += 4) - 2), SS1); return 20;}
|
909
|
+
INSTRUCTION(ld_vWORD_XY) {WRITE_16(READ_16((PC += 4) - 2), XY); return 20;}
|
910
|
+
INSTRUCTION(ld_sp_hl) {PC++; SP = HL; return 6;}
|
911
|
+
INSTRUCTION(ld_sp_XY) {PC += 2; SP = XY; return 10;}
|
912
|
+
INSTRUCTION(push_TT) {PC++; WRITE_16(SP -= 2, TT); return 11;}
|
913
|
+
INSTRUCTION(push_XY) {PC += 2; WRITE_16(SP -= 2, XY); return 15;}
|
914
|
+
INSTRUCTION(pop_TT) {PC++; TT = READ_16(SP); SP += 2; return 10;}
|
915
|
+
INSTRUCTION(pop_XY) {PC += 2; XY = READ_16(SP); SP += 2; return 14;}
|
916
|
+
|
917
|
+
|
918
|
+
/* MARK: - Instructions: Exchange, Block Transfer and Search Groups
|
919
|
+
.--------------------------------------------------------------------------------.
|
920
|
+
| 0 1 2 3 Flags |
|
921
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
922
|
+
| ---------------------------------------------------------------------------- |
|
923
|
+
| ex de,hl < EB > ........ 1 / 4 |
|
924
|
+
| ex af,af' < 08 > ........ 1 / 4 |
|
925
|
+
| exx < D9 > ........ 1 / 4 |
|
926
|
+
| ex (sp),hl < E3 > ........ 5 / 19 |
|
927
|
+
| ex (sp),ix < DD >< E3 > ........ 6 / 23 |
|
928
|
+
| ex (sp),iy < FD >< E3 > ........ 6 / 23 |
|
929
|
+
| ldi < ED >< A0 > ..*0**0. 4 / 16 |
|
930
|
+
| ldir < ED >< B0 > ..*0*00. 5,4 / 21,16 |
|
931
|
+
| ldd < ED >< A8 > ..*0**0. 4 / 16 |
|
932
|
+
| lddr < ED >< B8 > ..*0*00. 5,4 / 21,16 |
|
933
|
+
| cpi < ED >< A1 > ******1. 4 / 16 |
|
934
|
+
| cpir < ED >< B1 > ******1. 5,4 / 21,16 |
|
935
|
+
| cpd < ED >< A9 > ******1. 4 / 16 |
|
936
|
+
| cpdr < ED >< B9 > ******1. 5,4 / 21,16 |
|
937
|
+
'-------------------------------------------------------------------------------*/
|
938
|
+
|
939
|
+
INSTRUCTION(ex_de_hl) {zuint16 t; PC++; EX(DE, HL) return 4;}
|
940
|
+
INSTRUCTION(ex_af_af_) {zuint16 t; PC++; EX(AF, AF_) return 4;}
|
941
|
+
INSTRUCTION(exx) {zuint16 t; PC++; EX(BC, BC_) EX(DE, DE_) EX(HL, HL_) return 4;}
|
942
|
+
INSTRUCTION(ex_vsp_hl) {zuint16 t; PC++; EX_VSP_X(HL) return 19;}
|
943
|
+
INSTRUCTION(ex_vsp_XY) {zuint16 t; PC += 2; EX_VSP_X(XY) return 23;}
|
944
|
+
INSTRUCTION(ldi) {LDX (++) return 16;}
|
945
|
+
INSTRUCTION(ldir) {LDXR(++) }
|
946
|
+
INSTRUCTION(ldd) {LDX (--) return 16;}
|
947
|
+
INSTRUCTION(lddr) {LDXR(--) }
|
948
|
+
INSTRUCTION(cpi) {CPX (++) return 16;}
|
949
|
+
INSTRUCTION(cpir) {CPXR(++) }
|
950
|
+
INSTRUCTION(cpd) {CPX (--) return 16;}
|
951
|
+
INSTRUCTION(cpdr) {CPXR(--) }
|
952
|
+
|
953
|
+
|
954
|
+
/* MARK: - Instructions: 8-Bit Arithmetic and Logical Group
|
955
|
+
.---------------------------------------------------------------------------.
|
956
|
+
| 0 1 2 3 Flags |
|
957
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
958
|
+
| ----------------------------------------------------------------------- |
|
959
|
+
| U [a,]Y 10uuuyyy sz5h3*** 1 / 4 |
|
960
|
+
| U [a,]K < DD >10uuukkk sz5h3*** 2 / 8 |
|
961
|
+
| U [a,]Q < FD >10uuuqqq sz5h3*** 2 / 8 |
|
962
|
+
| U [a,]BYTE 11uuu110< BYTE > sz5h3*** 2 / 7 |
|
963
|
+
| U [a,](hl) 10uuu110 sz5h3*** 2 / 7 |
|
964
|
+
| U [a,](ix+OFFSET) < DD >10uuu110<OFFSET> sz5h3*** 5 / 19 |
|
965
|
+
| U [a,](iy+OFFSET) < FD >10uuu110<OFFSET> sz5h3*** 5 / 19 |
|
966
|
+
| V X 00xxxvvv sz5h3v0. 1 / 4 |
|
967
|
+
| V J < DD >00jjjvvv sz5h3v0. 2 / 8 |
|
968
|
+
| V P < FD >00pppvvv sz5h3v0. 2 / 8 |
|
969
|
+
| V (hl) 00110vvv sz5h3v*. 3 / 11 |
|
970
|
+
| V (ix+OFFSET) < DD >00110vvv<OFFSET> sz5h3v*. 6 / 23 |
|
971
|
+
| V (iy+OFFSET) < FD >00110vvv<OFFSET> sz5h3v*. 6 / 23 |
|
972
|
+
'--------------------------------------------------------------------------*/
|
973
|
+
|
974
|
+
INSTRUCTION(U_a_Y) {PC++; U0(Y0); return 4;}
|
975
|
+
INSTRUCTION(U_a_KQ) {PC += 2; U1(KQ); return 8;}
|
976
|
+
INSTRUCTION(U_a_BYTE) {U0(READ_8((PC += 2) - 1)); return 7;}
|
977
|
+
INSTRUCTION(U_a_vhl) {PC++; U0(READ_8(HL)); return 7;}
|
978
|
+
INSTRUCTION(U_a_vXYOFFSET) {U1(READ_8(XY + READ_OFFSET((PC += 3) - 1))); return 19;}
|
979
|
+
INSTRUCTION(V_X) {zuint8 *r; PC++; r = __xxx___0(object); *r = V0(*r); return 4;}
|
980
|
+
INSTRUCTION(V_JP) {zuint8 *r; PC += 2; r = __jjj___ (object); *r = V1(*r); return 8;}
|
981
|
+
INSTRUCTION(V_vhl) {PC++; WRITE_8(HL, V0(READ_8(HL))); return 11;}
|
982
|
+
INSTRUCTION(V_vXYOFFSET) {zuint16 a = (zuint16)(XY + READ_OFFSET((PC += 3) - 1));
|
983
|
+
WRITE_8(a, V1(READ_8(a))); return 23;}
|
984
|
+
|
985
|
+
|
986
|
+
/* MARK: - Instructions: General-Purpose Arithmetic and CPU Control Group
|
987
|
+
.---------------------------------------------------------------------------.
|
988
|
+
| 0 1 2 3 Flags |
|
989
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
990
|
+
| ----------------------------------------------------------------------- |
|
991
|
+
| nop < 00 > ........ 1 / 4 |
|
992
|
+
| halt < 76 > ........ 1 / 4 |
|
993
|
+
| di < F3 > ........ 1 / 4 |
|
994
|
+
| ei < FB > ........ 1 / 4 |
|
995
|
+
| im 0 < ED >< 46 > ........ 2 / 8 |
|
996
|
+
| < ED >< 4E > |
|
997
|
+
| < ED >< 66 > |
|
998
|
+
| < ED >< 6E > |
|
999
|
+
| im 1 < ED >< 56 > ........ 2 / 8 |
|
1000
|
+
| < ED >< 76 > |
|
1001
|
+
| im 2 < ED >< 5E > ........ 2 / 8 |
|
1002
|
+
| < ED >< 7E > |
|
1003
|
+
| daa < 27 > szyhxp.c 1 / 4 |
|
1004
|
+
| cpl < 2F > ..y1x.1. 1 / 4 |
|
1005
|
+
| neg < ED >< 44 > szyhxv1c 2 / 8 |
|
1006
|
+
| < ED >< 4C > |
|
1007
|
+
| < ED >< 54 > |
|
1008
|
+
| < ED >< 5C > |
|
1009
|
+
| < ED >< 64 > |
|
1010
|
+
| < ED >< 6C > |
|
1011
|
+
| < ED >< 74 > |
|
1012
|
+
| < ED >< 7C > |
|
1013
|
+
| ccf < 3F > ..***.0c 1 / 4 |
|
1014
|
+
| scf < 37 > ..*0*.01 1 / 4 |
|
1015
|
+
'--------------------------------------------------------------------------*/
|
1016
|
+
|
1017
|
+
INSTRUCTION(nop) {PC++; return 4;}
|
1018
|
+
INSTRUCTION(halt) {HALT = 1; SET_HALT; return 4;}
|
1019
|
+
INSTRUCTION(di) {PC++; IFF1 = IFF2 = 0; EI = TRUE; return 4;}
|
1020
|
+
INSTRUCTION(ei) {PC++; IFF1 = IFF2 = 1; EI = TRUE; return 4;}
|
1021
|
+
INSTRUCTION(im_0) {PC += 2; IM = 0; return 8;}
|
1022
|
+
INSTRUCTION(im_1) {PC += 2; IM = 1; return 8;}
|
1023
|
+
INSTRUCTION(im_2) {PC += 2; IM = 2; return 8;}
|
1024
|
+
|
1025
|
+
|
1026
|
+
INSTRUCTION(daa)
|
1027
|
+
{
|
1028
|
+
zuint8 t = (F_H || (A & 0xF ) > 9) ? 6 : 0;
|
1029
|
+
|
1030
|
+
if (F_C || A > 0x99) t |= 0x60;
|
1031
|
+
t = (F_N) ? A - t : A + t;
|
1032
|
+
PC++;
|
1033
|
+
|
1034
|
+
F = (zuint8)
|
1035
|
+
((F_N) /* NF unchanged */
|
1036
|
+
| (t & SYXF) /* SF = A.7; YF = A.5; XF = A.3 */
|
1037
|
+
| ZF_ZERO(t) /* ZF = !Af */
|
1038
|
+
| ((A & HF) ^ (t & HF)) /* HF = Ai.4 xor Af.4 */
|
1039
|
+
| PF_PARITY(t) /* PF = Parity of Af */
|
1040
|
+
| (F_C | (A > 0x99))); /* CF = CF | (Ai > 0x99) */
|
1041
|
+
|
1042
|
+
A = t;
|
1043
|
+
return 4;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
|
1047
|
+
INSTRUCTION(cpl)
|
1048
|
+
{
|
1049
|
+
PC++; A = ~A;
|
1050
|
+
|
1051
|
+
F = (F & (SF | ZF | PF | CF)) /* SF, ZF, PF, CF unchanged */
|
1052
|
+
| HF /* HF = 1 */
|
1053
|
+
| NF /* NF = 1 */
|
1054
|
+
| A_YX; /* YF = A.5; XF = A.3 */
|
1055
|
+
|
1056
|
+
return 4;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
|
1060
|
+
INSTRUCTION(neg)
|
1061
|
+
{
|
1062
|
+
zuint8 t = -A; PC += 2;
|
1063
|
+
|
1064
|
+
F = (zuint8)
|
1065
|
+
((t & SYXF) /* SF = -A.7; YF = -A.5; XF = -A.3 */
|
1066
|
+
| ZF_ZERO(t) /* ZF = !-A */
|
1067
|
+
| ((0 ^ A ^ t) & HF) /* HF = Half-borrow */
|
1068
|
+
| ((t == 128) << 2) /* PF = Overflow */
|
1069
|
+
| NF /* NF = 1 */
|
1070
|
+
| !!A); /* CF = !!A */
|
1071
|
+
|
1072
|
+
A = t;
|
1073
|
+
return 8;
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
|
1077
|
+
INSTRUCTION(ccf)
|
1078
|
+
{
|
1079
|
+
PC++;
|
1080
|
+
|
1081
|
+
F = (zuint8)
|
1082
|
+
(F_SZP /* SF, ZF, PF unchanged */
|
1083
|
+
| A_YX /* YF = A.5; XF = A.3 */
|
1084
|
+
| (F_C << 4) /* HF = CF */
|
1085
|
+
| (~F & CF)); /* CF = ~CF */
|
1086
|
+
/* NF = 0 */
|
1087
|
+
return 4;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
|
1091
|
+
INSTRUCTION(scf)
|
1092
|
+
{
|
1093
|
+
PC++;
|
1094
|
+
|
1095
|
+
F = F_SZP /* SF, ZF, PF unchanged */
|
1096
|
+
| A_YX /* YF = A.5; XF = A.3 */
|
1097
|
+
| CF; /* CF = 1 */
|
1098
|
+
/* HF = 0; NF = 0 */
|
1099
|
+
return 4;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
|
1103
|
+
/* MARK: - Instructions: 16-Bit Arithmetic Group
|
1104
|
+
.---------------------------------------------------------------------------.
|
1105
|
+
| 0 1 2 3 Flags |
|
1106
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1107
|
+
| ----------------------------------------------------------------------- |
|
1108
|
+
| add hl,SS 00ss1001 ..***.0* 3 / 11 |
|
1109
|
+
| adc hl,SS < ED >01ss1010 *****v0* 4 / 15 |
|
1110
|
+
| sbc hl,SS < ED >01ss0010 *****v0* 4 / 15 |
|
1111
|
+
| add ix,WW < DD >00ww1001 ..***.0* 4 / 15 |
|
1112
|
+
| add iy,WW < FD >00ww1001 ..***.0* 4 / 15 |
|
1113
|
+
| inc SS 00ss0011 ........ 1 / 6 |
|
1114
|
+
| inc ix < DD >< 23 > ........ 2 / 10 |
|
1115
|
+
| inc iy < FD >< 23 > ........ 2 / 10 |
|
1116
|
+
| dec SS 00ss1011 ........ 1 / 6 |
|
1117
|
+
| dec ix < DD >< 2B > ........ 2 / 10 |
|
1118
|
+
| dec iy < FD >< 2B > ........ 2 / 10 |
|
1119
|
+
'--------------------------------------------------------------------------*/
|
1120
|
+
|
1121
|
+
INSTRUCTION(add_hl_SS) {PC++; ADD_RR_NN(HL, SS0) return 11;}
|
1122
|
+
INSTRUCTION(adc_hl_SS) {ADC_SBC_HL_SS(adc, +, (zuint32)v + c + HL > 65535, Z_EMPTY)}
|
1123
|
+
INSTRUCTION(sbc_hl_SS) {ADC_SBC_HL_SS(sbc, -, (zuint32)v + c > HL, | NF) }
|
1124
|
+
INSTRUCTION(add_XY_WW) {PC += 2; ADD_RR_NN(XY, WW) return 15;}
|
1125
|
+
INSTRUCTION(inc_SS) {PC++; SS0++; return 6;}
|
1126
|
+
INSTRUCTION(inc_XY) {PC += 2; XY++; return 10;}
|
1127
|
+
INSTRUCTION(dec_SS) {PC++; SS0--; return 6;}
|
1128
|
+
INSTRUCTION(dec_XY) {PC += 2; XY--; return 15;}
|
1129
|
+
|
1130
|
+
|
1131
|
+
/* MARK: - Instructions: Rotate and Shift Group
|
1132
|
+
.---------------------------------------------------------------------------.
|
1133
|
+
| 0 1 2 3 Flags |
|
1134
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1135
|
+
| ----------------------------------------------------------------------- |
|
1136
|
+
| rlca < 07 > ..y0x.0c 1 / 4 |
|
1137
|
+
| rla < 17 > ..y0x.0c 1 / 4 |
|
1138
|
+
| rrca < 0F > ..y0x.0c 1 / 4 |
|
1139
|
+
| rra < 1F > ..y0x.0c 1 / 4 |
|
1140
|
+
| G Y < CB >00gggyyy szy0xp0c 2 / 8 |
|
1141
|
+
| G (hl) < CB >00ggg110 szy0xp0c 4 / 15 |
|
1142
|
+
| G (ix+OFFSET) < DD >< CB ><OFFSET>00ggg110 szy0xp0c 6 / 23 |
|
1143
|
+
| G (iy+OFFSET) < FD >< CB ><OFFSET>00ggg110 szy0xp0c 6 / 23 |
|
1144
|
+
| G (ix+OFFSET),Y < DD >< CB ><OFFSET>00gggyyy szy0xp0c 6 / 23 |
|
1145
|
+
| G (iy+OFFSET),Y < FD >< CB ><OFFSET>00gggyyy szy0xp0c 6 / 23 |
|
1146
|
+
| rld < ED >< 6F > szy0xp0. 5 / 18 |
|
1147
|
+
| rrd < ED >< 67 > szy0xp0. 5 / 18 |
|
1148
|
+
'--------------------------------------------------------------------------*/
|
1149
|
+
|
1150
|
+
INSTRUCTION(rlca) {PC++; ROL(A); F = F_SZP | (A & YXCF); return 4;}
|
1151
|
+
INSTRUCTION(rla) {zuint8 c; PC++; c = A >> 7; A = (zuint8)((A << 1) | F_C); RXA return 4;}
|
1152
|
+
INSTRUCTION(rrca) {PC++; ROR(A); F = F_SZP | A_YX | (A >> 7); return 4;}
|
1153
|
+
INSTRUCTION(rra) {zuint8 c; PC++; c = A & 1; A = (zuint8)((A >> 1) | (F << 7)); RXA return 4;}
|
1154
|
+
INSTRUCTION(G_Y) {zuint8 *r = _____yyy1(object); *r = G1(*r); return 8;}
|
1155
|
+
INSTRUCTION(G_vhl) {WRITE_8(HL, G1(READ_8(HL))); return 15;}
|
1156
|
+
INSTRUCTION(G_vXYOFFSET) {zuint16 a = XY_ADDRESS; WRITE_8(a, G3(READ_8(a))); return 23;}
|
1157
|
+
INSTRUCTION(G_vXYOFFSET_Y) {zuint16 a = XY_ADDRESS; WRITE_8(a, Y3 = G3(READ_8(a))); return 23;}
|
1158
|
+
INSTRUCTION(rld) {RXD(<<, & 0xF, >> 4) return 18;}
|
1159
|
+
INSTRUCTION(rrd) {RXD(>>, << 4, & 0xF) return 18;}
|
1160
|
+
|
1161
|
+
|
1162
|
+
/* MARK: - Instructions: Bit Set, Reset and Test Group
|
1163
|
+
.---------------------------------------------------------------------------.
|
1164
|
+
| 0 1 2 3 Flags |
|
1165
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1166
|
+
| ----------------------------------------------------------------------- |
|
1167
|
+
| bit N,Y < CB >01nnnyyy szy1xz0. 2 / 8 |
|
1168
|
+
| bit N,(hl) < CB >01nnn110 sz?1?z0. 3 / 12 |
|
1169
|
+
| bit N,(ix+OFFSET) < DD >< CB ><OFFSET>01nnn*** sz*1*z0. 5 / 20 |
|
1170
|
+
| bit N,(iy+OFFSET) < FD >< CB ><OFFSET>01nnn*** sz*1*z0. 5 / 20 |
|
1171
|
+
| M N,Y < CB >1mnnnyyy ........ 2 / 8 |
|
1172
|
+
| M N,(hl) < CB >1mnnn110 ........ 4 / 15 |
|
1173
|
+
| M N,(ix+OFFSET) < DD >< CB ><OFFSET>1mnnn110 ........ 6 / 23 |
|
1174
|
+
| M N,(iy+OFFSET) < FD >< CB ><OFFSET>1mnnn110 ........ 6 / 23 |
|
1175
|
+
| M N,(ix+OFFSET),Y < DD >< CB ><OFFSET>1mnnnyyy ........ 6 / 23 |
|
1176
|
+
| M N,(iy+OFFSET),Y < FD >< CB ><OFFSET>1mnnnyyy ........ 6 / 23 |
|
1177
|
+
'--------------------------------------------------------------------------*/
|
1178
|
+
|
1179
|
+
INSTRUCTION(bit_N_Y) {BIT_N_VALUE(Y1) return 8;}
|
1180
|
+
INSTRUCTION(bit_N_vhl) {BIT_N_VALUE(READ_8(HL)) return 12;}
|
1181
|
+
INSTRUCTION(bit_N_vXYOFFSET) {BIT_N_VADDRESS(XY_ADDRESS) return 20;}
|
1182
|
+
INSTRUCTION(M_N_Y) {zuint8 *t = _____yyy1(object); *t = M1(*t); return 8;}
|
1183
|
+
INSTRUCTION(M_N_vhl) {WRITE_8(HL, M1(READ_8(HL))); return 15;}
|
1184
|
+
INSTRUCTION(M_N_vXYOFFSET) {zuint16 a = XY_ADDRESS; WRITE_8(a, M3(READ_8(a))); return 23;}
|
1185
|
+
INSTRUCTION(M_N_vXYOFFSET_Y) {zuint16 a = XY_ADDRESS; WRITE_8(a, Y3 = M3(READ_8(a))); return 23;}
|
1186
|
+
|
1187
|
+
|
1188
|
+
/* MARK: - Instructions: Jump Group
|
1189
|
+
.-------------------------------------------------------------------------------.
|
1190
|
+
| 0 1 2 3 Flags |
|
1191
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1192
|
+
| --------------------------------------------------------------------------- |
|
1193
|
+
| jp WORD < C3 >< WORD > ........ 3 / 10 |
|
1194
|
+
| jp Z,WORD 11zzz010< WORD > ........ 3 / 10 |
|
1195
|
+
| jr OFFSET < 18 ><OFFSET> ........ 3 / 12 |
|
1196
|
+
| jr Z,OFFSET 001zz000<OFFSET> ........ 3,2 / 12,7 |
|
1197
|
+
| jp (hl) < E9 > ........ 1 / 4 |
|
1198
|
+
| jp (ix) < DD >< E9 > ........ 2 / 8 |
|
1199
|
+
| jp (iy) < FD >< E9 > ........ 2 / 8 |
|
1200
|
+
| djnz OFFSET < 10 ><OFFSET> ........ 3,2 / 13,8 |
|
1201
|
+
'------------------------------------------------------------------------------*/
|
1202
|
+
|
1203
|
+
INSTRUCTION(jp_WORD) {PC = READ_16(PC + 1); return 10;}
|
1204
|
+
INSTRUCTION(jp_Z_WORD) {PC = Z ? READ_16(PC + 1) : PC + 3; return 10;}
|
1205
|
+
INSTRUCTION(jr_OFFSET) {PC += (2 + READ_OFFSET(PC + 1)); return 12;}
|
1206
|
+
INSTRUCTION(jr_Z_OFFSET) {BYTE0 &= 223; PC += 2; if (Z) {PC += READ_OFFSET(PC - 1); return 12;} return 7;}
|
1207
|
+
INSTRUCTION(jp_hl) {PC = HL; return 4;}
|
1208
|
+
INSTRUCTION(jp_XY) {PC = XY; return 8;}
|
1209
|
+
INSTRUCTION(djnz_OFFSET) {PC += 2; if (--B) {PC += READ_OFFSET(PC - 1); return 13;} return 8;}
|
1210
|
+
|
1211
|
+
|
1212
|
+
/* MARK: - Instructions: Call and Return Group
|
1213
|
+
.--------------------------------------------------------------------------------.
|
1214
|
+
| 0 1 2 3 Flags |
|
1215
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1216
|
+
| ---------------------------------------------------------------------------- |
|
1217
|
+
| call WORD < CD >< WORD > ........ 5 / 17 |
|
1218
|
+
| call Z,WORD 11zzz100< WORD > ........ 3,5 / 10,17 |
|
1219
|
+
| ret < C9 > ........ 3 / 10 |
|
1220
|
+
| ret Z 11zzz000 ........ 1,3 / 5,11 |
|
1221
|
+
| reti < ED >< 4D > ........ 4 / 14 |
|
1222
|
+
| retn < ED >< 45 > ........ 4 / 14 |
|
1223
|
+
| < ED >< 55 > |
|
1224
|
+
| < ED >< 5D > |
|
1225
|
+
| < ED >< 65 > |
|
1226
|
+
| < ED >< 6D > |
|
1227
|
+
| < ED >< 75 > |
|
1228
|
+
| < ED >< 7D > |
|
1229
|
+
| rst N 11nnn111 ........ 3 / 11 |
|
1230
|
+
'-------------------------------------------------------------------------------*/
|
1231
|
+
|
1232
|
+
INSTRUCTION(call_WORD) {PUSH(PC + 3); PC = READ_16(PC + 1); return 17;}
|
1233
|
+
INSTRUCTION(call_Z_WORD) {if (Z) return call_WORD(object); PC += 3; return 10;}
|
1234
|
+
INSTRUCTION(ret) {RET; return 10;}
|
1235
|
+
INSTRUCTION(ret_Z) {if (Z) {RET; return 11;} PC++; return 5;}
|
1236
|
+
INSTRUCTION(reti) {IFF1 = IFF2; RET; return 14;}
|
1237
|
+
INSTRUCTION(retn) {IFF1 = IFF2; RET; return 14;}
|
1238
|
+
INSTRUCTION(rst_N) {PUSH(PC + 1); PC = BYTE0 & 56; return 11;}
|
1239
|
+
|
1240
|
+
|
1241
|
+
/* MARK: - Instructions: Input and Output Group
|
1242
|
+
.--------------------------------------------------------------------------------.
|
1243
|
+
| 0 1 2 3 Flags |
|
1244
|
+
| Assembly 76543210765432107654321076543210 szyhxpnc Cycles |
|
1245
|
+
| ---------------------------------------------------------------------------- |
|
1246
|
+
| in a,(BYTE) < DB >< BYTE > ........ 3 / 11 |
|
1247
|
+
| in X,(c) < ED >01xxx000 szy0xp0. 3 / 12 |
|
1248
|
+
| in 0,(c) < ED >< 70 > szy0xp0. 3 / 12 |
|
1249
|
+
| ini < ED >< A2 > ******** 4 / 16 |
|
1250
|
+
| inir < ED >< B2 > 010*0*** 5,4 / 21,16 |
|
1251
|
+
| ind < ED >< AA > ******** 4 / 16 |
|
1252
|
+
| indr < ED >< BA > 010*0*** 5,4 / 21,16 |
|
1253
|
+
| out (BYTE),a < D3 >< BYTE > ........ 3 / 11 |
|
1254
|
+
| out (c),X < ED >01xxx001 ........ 3 / 12 |
|
1255
|
+
| out (c),0 < ED >< 71 > ........ 3 / 12 |
|
1256
|
+
| outi < ED >< A3 > ******** 4 / 16 |
|
1257
|
+
| otir < ED >< B3 > 010*0_** 5,4 / 21,16 |
|
1258
|
+
| outd < ED >< AB > ******** 4 / 16 |
|
1259
|
+
| otdr < ED >< BB > 010*0*** 5,4 / 21,16 |
|
1260
|
+
'-------------------------------------------------------------------------------*/
|
1261
|
+
|
1262
|
+
INSTRUCTION(in_a_BYTE) {A = IN((A << 8) | READ_8((PC += 2) - 1)); return 11;}
|
1263
|
+
INSTRUCTION(in_X_vc) {IN_VC; X1 = t; return 12;}
|
1264
|
+
INSTRUCTION(in_0_vc) {IN_VC; return 16;}
|
1265
|
+
INSTRUCTION(ini) {INX (++, +) return 16;}
|
1266
|
+
INSTRUCTION(inir) {INXR(++, +) }
|
1267
|
+
INSTRUCTION(ind) {INX (--, -) return 16;}
|
1268
|
+
INSTRUCTION(indr) {INXR(--, -) }
|
1269
|
+
INSTRUCTION(out_vBYTE_a) {OUT((A << 8) | READ_8((PC += 2) - 1), A); return 11;}
|
1270
|
+
INSTRUCTION(out_vc_X) {PC += 2; OUT(BC, X1); return 12;}
|
1271
|
+
INSTRUCTION(out_vc_0) {PC += 2; OUT(BC, 0); return 12;}
|
1272
|
+
INSTRUCTION(outi) {OUTX(++) return 16;}
|
1273
|
+
INSTRUCTION(otir) {OTXR(++) }
|
1274
|
+
INSTRUCTION(outd) {OUTX(--) return 16;}
|
1275
|
+
INSTRUCTION(otdr) {OTXR(--) }
|
1276
|
+
|
1277
|
+
|
1278
|
+
/* MARK: - Opcode Selector Prototypes */
|
1279
|
+
|
1280
|
+
INSTRUCTION(CB);
|
1281
|
+
INSTRUCTION(DD);
|
1282
|
+
INSTRUCTION(ED);
|
1283
|
+
INSTRUCTION(FD);
|
1284
|
+
INSTRUCTION(XY_CB);
|
1285
|
+
INSTRUCTION(ED_illegal);
|
1286
|
+
INSTRUCTION(XY_illegal);
|
1287
|
+
|
1288
|
+
|
1289
|
+
/* MARK: - Instruction Function Tables */
|
1290
|
+
|
1291
|
+
static Instruction const instruction_table[256] = {
|
1292
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
1293
|
+
/* 0 */ nop, ld_SS_WORD, ld_vbc_a, inc_SS, V_X, V_X, ld_X_BYTE, rlca, ex_af_af_, add_hl_SS, ld_a_vbc, dec_SS, V_X, V_X, ld_X_BYTE, rrca,
|
1294
|
+
/* 1 */ djnz_OFFSET, ld_SS_WORD, ld_vde_a, inc_SS, V_X, V_X, ld_X_BYTE, rla, jr_OFFSET, add_hl_SS, ld_a_vde, dec_SS, V_X, V_X, ld_X_BYTE, rra,
|
1295
|
+
/* 2 */ jr_Z_OFFSET, ld_SS_WORD, ld_vWORD_hl, inc_SS, V_X, V_X, ld_X_BYTE, daa, jr_Z_OFFSET, add_hl_SS, ld_hl_vWORD, dec_SS, V_X, V_X, ld_X_BYTE, cpl,
|
1296
|
+
/* 3 */ jr_Z_OFFSET, ld_SS_WORD, ld_vWORD_a, inc_SS, V_vhl, V_vhl, ld_vhl_BYTE, scf, jr_Z_OFFSET, add_hl_SS, ld_a_vWORD, dec_SS, V_X, V_X, ld_X_BYTE, ccf,
|
1297
|
+
/* 4 */ ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y,
|
1298
|
+
/* 5 */ ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y,
|
1299
|
+
/* 6 */ ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y,
|
1300
|
+
/* 7 */ ld_vhl_Y, ld_vhl_Y, ld_vhl_Y, ld_vhl_Y, ld_vhl_Y, ld_vhl_Y, halt, ld_vhl_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_Y, ld_X_vhl, ld_X_Y,
|
1301
|
+
/* 8 */ U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y,
|
1302
|
+
/* 9 */ U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y,
|
1303
|
+
/* A */ U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y,
|
1304
|
+
/* B */ U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_Y, U_a_vhl, U_a_Y,
|
1305
|
+
/* C */ ret_Z, pop_TT, jp_Z_WORD, jp_WORD, call_Z_WORD, push_TT, U_a_BYTE, rst_N, ret_Z, ret, jp_Z_WORD, CB, call_Z_WORD, call_WORD, U_a_BYTE, rst_N,
|
1306
|
+
/* D */ ret_Z, pop_TT, jp_Z_WORD, out_vBYTE_a, call_Z_WORD, push_TT, U_a_BYTE, rst_N, ret_Z, exx, jp_Z_WORD, in_a_BYTE, call_Z_WORD, DD, U_a_BYTE, rst_N,
|
1307
|
+
/* E */ ret_Z, pop_TT, jp_Z_WORD, ex_vsp_hl, call_Z_WORD, push_TT, U_a_BYTE, rst_N, ret_Z, jp_hl, jp_Z_WORD, ex_de_hl, call_Z_WORD, ED, U_a_BYTE, rst_N,
|
1308
|
+
/* F */ ret_Z, pop_TT, jp_Z_WORD, di, call_Z_WORD, push_TT, U_a_BYTE, rst_N, ret_Z, ld_sp_hl, jp_Z_WORD, ei, call_Z_WORD, FD, U_a_BYTE, rst_N
|
1309
|
+
};
|
1310
|
+
|
1311
|
+
static Instruction const instruction_table_CB[256] = {
|
1312
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
1313
|
+
/* 0 */ G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y,
|
1314
|
+
/* 1 */ G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y,
|
1315
|
+
/* 2 */ G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y,
|
1316
|
+
/* 3 */ G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_Y, G_vhl, G_Y,
|
1317
|
+
/* 4 */ bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y,
|
1318
|
+
/* 5 */ bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y,
|
1319
|
+
/* 6 */ bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y,
|
1320
|
+
/* 7 */ bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_Y, bit_N_vhl, bit_N_Y,
|
1321
|
+
/* 8 */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1322
|
+
/* 9 */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1323
|
+
/* A */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1324
|
+
/* B */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1325
|
+
/* C */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1326
|
+
/* D */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1327
|
+
/* E */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y,
|
1328
|
+
/* F */ M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_Y, M_N_vhl, M_N_Y
|
1329
|
+
};
|
1330
|
+
|
1331
|
+
static Instruction const instruction_table_XY_CB[256] = {
|
1332
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
1333
|
+
/* 0 */ G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y,
|
1334
|
+
/* 1 */ G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y,
|
1335
|
+
/* 2 */ G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y,
|
1336
|
+
/* 3 */ G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET_Y, G_vXYOFFSET, G_vXYOFFSET_Y,
|
1337
|
+
/* 4 */ bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET,
|
1338
|
+
/* 5 */ bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET,
|
1339
|
+
/* 6 */ bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET,
|
1340
|
+
/* 7 */ bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET, bit_N_vXYOFFSET,
|
1341
|
+
/* 8 */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1342
|
+
/* 9 */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1343
|
+
/* A */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1344
|
+
/* B */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1345
|
+
/* C */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1346
|
+
/* D */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1347
|
+
/* E */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y,
|
1348
|
+
/* F */ M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET_Y, M_N_vXYOFFSET, M_N_vXYOFFSET_Y
|
1349
|
+
};
|
1350
|
+
|
1351
|
+
static Instruction const instruction_table_XY[256] = {
|
1352
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
1353
|
+
/* 0 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, add_XY_WW, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1354
|
+
/* 1 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, add_XY_WW, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1355
|
+
/* 2 */ XY_illegal, ld_XY_WORD, ld_vWORD_XY, inc_XY, V_JP, V_JP, ld_JP_BYTE, XY_illegal, XY_illegal, add_XY_WW, ld_XY_vWORD, dec_XY, V_JP, V_JP, ld_JP_BYTE, XY_illegal,
|
1356
|
+
/* 3 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, V_vXYOFFSET, V_vXYOFFSET, ld_vXYOFFSET_BYTE, XY_illegal, XY_illegal, add_XY_WW, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1357
|
+
/* 4 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, XY_illegal,
|
1358
|
+
/* 5 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, XY_illegal,
|
1359
|
+
/* 6 */ ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, ld_JP_KQ,
|
1360
|
+
/* 7 */ ld_vXYOFFSET_Y, ld_vXYOFFSET_Y, ld_vXYOFFSET_Y, ld_vXYOFFSET_Y, ld_vXYOFFSET_Y, ld_vXYOFFSET_Y, XY_illegal, ld_vXYOFFSET_Y, XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_JP_KQ, ld_JP_KQ, ld_X_vXYOFFSET, XY_illegal,
|
1361
|
+
/* 8 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal,
|
1362
|
+
/* 9 */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal,
|
1363
|
+
/* A */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal,
|
1364
|
+
/* B */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, U_a_KQ, U_a_KQ, U_a_vXYOFFSET, XY_illegal,
|
1365
|
+
/* C */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_CB, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1366
|
+
/* D */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1367
|
+
/* E */ XY_illegal, pop_XY, XY_illegal, ex_vsp_XY, XY_illegal, push_XY, XY_illegal, XY_illegal, XY_illegal, jp_XY, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal,
|
1368
|
+
/* F */ XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, ld_sp_XY, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal, XY_illegal
|
1369
|
+
};
|
1370
|
+
|
1371
|
+
static Instruction const instruction_table_ED[256] = {
|
1372
|
+
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
1373
|
+
/* 0 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1374
|
+
/* 1 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1375
|
+
/* 2 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1376
|
+
/* 3 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1377
|
+
/* 4 */ in_X_vc, out_vc_X, sbc_hl_SS, ld_vWORD_SS, neg, retn, im_0, ld_i_a, in_X_vc, out_vc_X, adc_hl_SS, ld_SS_vWORD, neg, reti, im_0, ld_r_a,
|
1378
|
+
/* 5 */ in_X_vc, out_vc_X, sbc_hl_SS, ld_vWORD_SS, neg, retn, im_1, ld_a_i, in_X_vc, out_vc_X, adc_hl_SS, ld_SS_vWORD, neg, retn, im_2, ld_a_r,
|
1379
|
+
/* 6 */ in_X_vc, out_vc_X, sbc_hl_SS, ld_vWORD_SS, neg, retn, im_0, rrd, in_X_vc, out_vc_X, adc_hl_SS, ld_SS_vWORD, neg, retn, im_0, rld,
|
1380
|
+
/* 7 */ in_0_vc, out_vc_0, sbc_hl_SS, ld_vWORD_SS, neg, retn, im_1, ED_illegal, in_X_vc, out_vc_X, adc_hl_SS, ld_SS_vWORD, neg, retn, im_2, ED_illegal,
|
1381
|
+
/* 8 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1382
|
+
/* 9 */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1383
|
+
/* A */ ldi, cpi, ini, outi, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ldd, cpd, ind, outd, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1384
|
+
/* B */ ldir, cpir, inir, otir, ED_illegal, ED_illegal, ED_illegal, ED_illegal, lddr, cpdr, indr, otdr, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1385
|
+
/* C */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1386
|
+
/* D */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1387
|
+
/* E */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal,
|
1388
|
+
/* F */ ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal, ED_illegal
|
1389
|
+
};
|
1390
|
+
|
1391
|
+
|
1392
|
+
/* MARK: - Prefixed Instruction Set Selection and Execution */
|
1393
|
+
|
1394
|
+
#define DD_FD(register) \
|
1395
|
+
zuint8 cycles; \
|
1396
|
+
\
|
1397
|
+
XY = register; \
|
1398
|
+
R++; \
|
1399
|
+
cycles = instruction_table_XY[BYTE1 = READ_8(PC + 1)](object); \
|
1400
|
+
register = XY; \
|
1401
|
+
return cycles;
|
1402
|
+
|
1403
|
+
|
1404
|
+
INSTRUCTION(DD) {DD_FD(IX)}
|
1405
|
+
INSTRUCTION(FD) {DD_FD(IY)}
|
1406
|
+
INSTRUCTION(CB) {R++; return instruction_table_CB[BYTE1 = READ_8((PC += 2) - 1)](object);}
|
1407
|
+
INSTRUCTION(ED) {R++; return instruction_table_ED[BYTE1 = READ_8( PC + 1)](object);}
|
1408
|
+
|
1409
|
+
|
1410
|
+
INSTRUCTION(XY_CB)
|
1411
|
+
{
|
1412
|
+
PC += 4;
|
1413
|
+
BYTE2 = READ_8(PC - 2);
|
1414
|
+
return instruction_table_XY_CB[BYTE3 = READ_8(PC - 1)](object);
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
|
1418
|
+
/* MARK: - Illegal Instruction Handling */
|
1419
|
+
|
1420
|
+
INSTRUCTION(XY_illegal) {PC += 1; return instruction_table[BYTE0 = BYTE1](object) + 4;}
|
1421
|
+
INSTRUCTION(ED_illegal) {PC += 2; return 8;}
|
1422
|
+
|
1423
|
+
|
1424
|
+
/* MARK: - Main Functions */
|
1425
|
+
|
1426
|
+
CPU_Z80_API void z80_power(Z80 *object, zboolean state)
|
1427
|
+
{
|
1428
|
+
if (state)
|
1429
|
+
{
|
1430
|
+
# ifdef Z_Z80_RESET_IS_EQUAL_TO_POWER_ON
|
1431
|
+
z80_reset(object);
|
1432
|
+
# else
|
1433
|
+
PC = Z_Z80_VALUE_AFTER_POWER_ON_PC;
|
1434
|
+
SP = Z_Z80_VALUE_AFTER_POWER_ON_SP;
|
1435
|
+
IX = Z_Z80_VALUE_AFTER_POWER_ON_IX;
|
1436
|
+
IY = Z_Z80_VALUE_AFTER_POWER_ON_IY;
|
1437
|
+
AF = Z_Z80_VALUE_AFTER_POWER_ON_AF;
|
1438
|
+
BC = Z_Z80_VALUE_AFTER_POWER_ON_BC;
|
1439
|
+
DE = Z_Z80_VALUE_AFTER_POWER_ON_DE;
|
1440
|
+
HL = Z_Z80_VALUE_AFTER_POWER_ON_HL;
|
1441
|
+
AF_ = Z_Z80_VALUE_AFTER_POWER_ON_AF_;
|
1442
|
+
BC_ = Z_Z80_VALUE_AFTER_POWER_ON_BC_;
|
1443
|
+
DE_ = Z_Z80_VALUE_AFTER_POWER_ON_DE_;
|
1444
|
+
HL_ = Z_Z80_VALUE_AFTER_POWER_ON_HL_;
|
1445
|
+
R = Z_Z80_VALUE_AFTER_POWER_ON_R;
|
1446
|
+
I = Z_Z80_VALUE_AFTER_POWER_ON_I;
|
1447
|
+
IFF1 = Z_Z80_VALUE_AFTER_POWER_ON_IFF1;
|
1448
|
+
IFF2 = Z_Z80_VALUE_AFTER_POWER_ON_IFF2;
|
1449
|
+
IM = Z_Z80_VALUE_AFTER_POWER_ON_IM;
|
1450
|
+
|
1451
|
+
EI = HALT = INT = NMI = 0;
|
1452
|
+
# endif
|
1453
|
+
}
|
1454
|
+
|
1455
|
+
else PC = SP = IX = IY = AF = BC = DE = HL = AF_ = BC_ = DE_ = HL_ = I = R =
|
1456
|
+
IFF1 = IFF2 = IM = EI = HALT = INT = NMI = 0;
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
|
1460
|
+
CPU_Z80_API void z80_reset(Z80 *object)
|
1461
|
+
{
|
1462
|
+
PC = Z_Z80_VALUE_AFTER_RESET_PC;
|
1463
|
+
SP = Z_Z80_VALUE_AFTER_RESET_SP;
|
1464
|
+
IX = Z_Z80_VALUE_AFTER_RESET_IX;
|
1465
|
+
IY = Z_Z80_VALUE_AFTER_RESET_IY;
|
1466
|
+
AF = Z_Z80_VALUE_AFTER_RESET_AF;
|
1467
|
+
BC = Z_Z80_VALUE_AFTER_RESET_BC;
|
1468
|
+
DE = Z_Z80_VALUE_AFTER_RESET_DE;
|
1469
|
+
HL = Z_Z80_VALUE_AFTER_RESET_HL;
|
1470
|
+
AF_ = Z_Z80_VALUE_AFTER_RESET_AF_;
|
1471
|
+
BC_ = Z_Z80_VALUE_AFTER_RESET_BC_;
|
1472
|
+
DE_ = Z_Z80_VALUE_AFTER_RESET_DE_;
|
1473
|
+
HL_ = Z_Z80_VALUE_AFTER_RESET_HL_;
|
1474
|
+
R = Z_Z80_VALUE_AFTER_RESET_R;
|
1475
|
+
I = Z_Z80_VALUE_AFTER_RESET_I;
|
1476
|
+
IFF1 = Z_Z80_VALUE_AFTER_RESET_IFF1;
|
1477
|
+
IFF2 = Z_Z80_VALUE_AFTER_RESET_IFF2;
|
1478
|
+
IM = Z_Z80_VALUE_AFTER_RESET_IM;
|
1479
|
+
|
1480
|
+
EI = HALT = INT = NMI = 0;
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
|
1484
|
+
CPU_Z80_API zusize z80_run(Z80 *object, zusize cycles)
|
1485
|
+
{
|
1486
|
+
zuint32 data;
|
1487
|
+
|
1488
|
+
/*-------------.
|
1489
|
+
| Clear cycles |
|
1490
|
+
'-------------*/
|
1491
|
+
CYCLES = 0;
|
1492
|
+
|
1493
|
+
/*--------------.
|
1494
|
+
| Backup R7 bit |
|
1495
|
+
'--------------*/
|
1496
|
+
R7 = R;
|
1497
|
+
|
1498
|
+
/*------------------------------.
|
1499
|
+
| Execute until cycles consumed |
|
1500
|
+
'------------------------------*/
|
1501
|
+
while (CYCLES < cycles)
|
1502
|
+
{
|
1503
|
+
/*--------------------------------------.
|
1504
|
+
| Jump to NMI handler if NMI pending... |
|
1505
|
+
'--------------------------------------*/
|
1506
|
+
if (NMI)
|
1507
|
+
{
|
1508
|
+
EXIT_HALT; /* Resume CPU if halted. */
|
1509
|
+
R++; /* Consume memory refresh. */
|
1510
|
+
NMI = FALSE; /* Clear the NMI pulse. */
|
1511
|
+
/*IFF2 = IFF1;*/ /* Backup IFF1 (it doesn't occur, acording to Sean Young). */
|
1512
|
+
IFF1 = 0; /* Reset IFF1 to don't bother the NMI routine. */
|
1513
|
+
PUSH(PC); /* Save return addres in the stack. */
|
1514
|
+
PC = Z_Z80_ADDRESS_NMI_POINTER; /* Make PC point to the NMI routine. */
|
1515
|
+
CYCLES += 11; /* Accepting a NMI consumes 11 cycles. */
|
1516
|
+
continue;
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
/*--------------------------.
|
1520
|
+
| Execute INT if pending... |
|
1521
|
+
'--------------------------*/
|
1522
|
+
if (INT && IFF1 && !EI)
|
1523
|
+
{
|
1524
|
+
EXIT_HALT; /* Resume CPU on halt. */
|
1525
|
+
R++; /* Consume memory refresh. */
|
1526
|
+
IFF1 = IFF2 = 0; /* Clear interrupt flip-flops. */
|
1527
|
+
|
1528
|
+
switch (IM)
|
1529
|
+
{
|
1530
|
+
/*------------------------------.
|
1531
|
+
| IM 0: Execute bus instruction |
|
1532
|
+
'------------------------------*/
|
1533
|
+
case 0:
|
1534
|
+
|
1535
|
+
if ((data = INT_DATA)) switch (data & Z_UINT32(0xFF000000))
|
1536
|
+
{
|
1537
|
+
case Z_UINT32(0xC3000000): /* JP */
|
1538
|
+
PC = (zuint16)(data >> 8);
|
1539
|
+
CYCLES += 10;
|
1540
|
+
break;
|
1541
|
+
|
1542
|
+
case Z_UINT32(0xCD000000): /* CALL */
|
1543
|
+
PUSH(PC);
|
1544
|
+
PC = (zuint16)(data >> 8);
|
1545
|
+
CYCLES += 17;
|
1546
|
+
break;
|
1547
|
+
|
1548
|
+
default: /* RST (and possibly others) */
|
1549
|
+
PUSH(PC);
|
1550
|
+
PC = (zuint16)((data >> 8) & 0x38);
|
1551
|
+
CYCLES += 11;
|
1552
|
+
}
|
1553
|
+
|
1554
|
+
CYCLES += 2;
|
1555
|
+
break;
|
1556
|
+
|
1557
|
+
/*----------------------.
|
1558
|
+
| IM 1: Execute rst 38h |
|
1559
|
+
'----------------------*/
|
1560
|
+
case 1:
|
1561
|
+
PUSH(PC);
|
1562
|
+
PC = 0x38;
|
1563
|
+
CYCLES += (11 + 2);
|
1564
|
+
break;
|
1565
|
+
|
1566
|
+
/*---------------------------.
|
1567
|
+
| IM 2: Execute rst [i:byte] |
|
1568
|
+
'---------------------------*/
|
1569
|
+
case 2:
|
1570
|
+
PUSH(PC);
|
1571
|
+
PC = READ_16(((zuint16)(I << 8)) | (INT_DATA & 0xFF));
|
1572
|
+
CYCLES += (17 + 2);
|
1573
|
+
break;
|
1574
|
+
}
|
1575
|
+
|
1576
|
+
continue;
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
/*---------------------------------------.
|
1580
|
+
| Consume memory refresh and update bits |
|
1581
|
+
'---------------------------------------*/
|
1582
|
+
R++;
|
1583
|
+
EI = FALSE;
|
1584
|
+
|
1585
|
+
/*-----------------------------------------------.
|
1586
|
+
| Execute instruction and update consumed cycles |
|
1587
|
+
'-----------------------------------------------*/
|
1588
|
+
CYCLES += instruction_table[BYTE0 = READ_8(PC)](object);
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
/*---------------.
|
1592
|
+
| Restore R7 bit |
|
1593
|
+
'---------------*/
|
1594
|
+
R = R_ALL;
|
1595
|
+
|
1596
|
+
/*-----------------------.
|
1597
|
+
| Return consumed cycles |
|
1598
|
+
'-----------------------*/
|
1599
|
+
return CYCLES;
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
|
1603
|
+
CPU_Z80_API void z80_nmi(Z80 *object) {NMI = TRUE ;}
|
1604
|
+
CPU_Z80_API void z80_int(Z80 *object, zboolean state) {INT = state;}
|
1605
|
+
|
1606
|
+
|
1607
|
+
/* MARK: - ABI */
|
1608
|
+
|
1609
|
+
#ifdef CPU_Z80_WITH_ABI
|
1610
|
+
|
1611
|
+
static void will_read_state(Z80 *object) {R = R_ALL;}
|
1612
|
+
static void did_write_state(Z80 *object) {R7 = R; }
|
1613
|
+
|
1614
|
+
static ZCPUEmulatorExport const exports[7] = {
|
1615
|
+
{Z_EMULATOR_FUNCTION_POWER, {(void (*)(void))z80_power }},
|
1616
|
+
{Z_EMULATOR_FUNCTION_RESET, {(void (*)(void))z80_reset }},
|
1617
|
+
{Z_EMULATOR_FUNCTION_RUN, {(void (*)(void))z80_run }},
|
1618
|
+
{Z_EMULATOR_FUNCTION_WILL_READ_STATE, {(void (*)(void))will_read_state}},
|
1619
|
+
{Z_EMULATOR_FUNCTION_DID_WRITE_STATE, {(void (*)(void))did_write_state}},
|
1620
|
+
{Z_EMULATOR_FUNCTION_NMI, {(void (*)(void))z80_nmi }},
|
1621
|
+
{Z_EMULATOR_FUNCTION_IRQ, {(void (*)(void))z80_int }}
|
1622
|
+
};
|
1623
|
+
|
1624
|
+
static ZCPUEmulatorInstanceImport const instance_imports[6] = {
|
1625
|
+
{Z_EMULATOR_FUNCTION_READ_8BIT, O(read )},
|
1626
|
+
{Z_EMULATOR_FUNCTION_WRITE_8BIT, O(write )},
|
1627
|
+
{Z_EMULATOR_FUNCTION_IN_8BIT, O(in )},
|
1628
|
+
{Z_EMULATOR_FUNCTION_OUT_8BIT, O(out )},
|
1629
|
+
{Z_EMULATOR_FUNCTION_IRQ_DATA, O(int_data)},
|
1630
|
+
{Z_EMULATOR_FUNCTION_HALT, O(halt )}
|
1631
|
+
};
|
1632
|
+
|
1633
|
+
CPU_Z80_ABI ZCPUEmulatorABI const abi_emulation_cpu_z80 = {
|
1634
|
+
/* dependency_count */ 0,
|
1635
|
+
/* dependencies */ NULL,
|
1636
|
+
/* export_count */ 7,
|
1637
|
+
/* exports */ exports,
|
1638
|
+
/* instance_size */ sizeof(Z80),
|
1639
|
+
/* instance_state_offset */ O(state),
|
1640
|
+
/* instance_state_size */ sizeof(ZZ80State),
|
1641
|
+
/* instance_import_count */ 6,
|
1642
|
+
/* instance_imports */ instance_imports
|
1643
|
+
};
|
1644
|
+
|
1645
|
+
#endif
|
1646
|
+
|
1647
|
+
#ifdef CPU_Z80_WITH_MODULE_ABI
|
1648
|
+
|
1649
|
+
# ifndef CPU_Z80_DEPENDENCIES_H
|
1650
|
+
# include <Z/ABIs/generic/module.h>
|
1651
|
+
# endif
|
1652
|
+
|
1653
|
+
static ZModuleUnit const unit = {"Z80", "Z80", Z_VERSION(0, 1, 0), &abi_emulation_cpu_z80};
|
1654
|
+
static ZModuleDomain const domain = {"Emulation.CPU", Z_VERSION(1, 0, 0), 1, &unit};
|
1655
|
+
Z_API_WEAK_EXPORT ZModuleABI const __module_abi__ = {1, &domain};
|
1656
|
+
|
1657
|
+
#endif
|
1658
|
+
|
1659
|
+
|
1660
|
+
/* Z80.c EOF */
|