diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java
new file mode 100644
index 0000000000..62a91bf02d
--- /dev/null
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java
@@ -0,0 +1,142 @@
+/* ###
+ * IP: GHIDRA
+ * REVIEWED: YES
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.cmd.disassemble;
+
+import ghidra.framework.model.DomainObject;
+import ghidra.program.disassemble.DisassemblerContextImpl;
+import ghidra.program.model.address.*;
+import ghidra.program.model.lang.Register;
+import ghidra.program.model.lang.RegisterValue;
+import ghidra.program.model.listing.Program;
+import ghidra.util.exception.CancelledException;
+import ghidra.util.task.TaskMonitor;
+
+import java.math.BigInteger;
+
+/**
+ * Command object for performing HCS12/XGate disassembly
+ */
+public class Hcs12DisassembleCommand extends DisassembleCommand {
+
+ private boolean xgMode;
+
+ /**
+ * Constructor for Hcs12DisassembleCommand.
+ * @param startSet set of addresses to be the start of a disassembly. The
+ * Command object will attempt to start a disassembly at each address in this set.
+ * @param restrictedSet addresses that can be disassembled.
+ * a null set implies no restrictions
+ * @param xgMode pass true if the disassembling in XGATE Mode
+ */
+ public Hcs12DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
+ boolean xgMode) {
+ super("Disassemble " + (xgMode ? "XGate" : "HCS12"), startSet, restrictedSet, true);
+ this.xgMode = xgMode;
+ }
+
+ /**
+ * Constructor for DisassembleCommand.
+ * @param startSet set of addresses to be the start of a disassembly. The
+ * Command object will attempt to start a disassembly at each address in this set.
+ * @param restrictedSet addresses that can be disassembled.
+ * a null set implies no restrictions
+ * @param xgMode pass true if the disassembling in XGATE Mode
+ */
+ public Hcs12DisassembleCommand(Address start, AddressSetView restrictedSet, boolean xgMode) {
+ this(new AddressSet(start, start), restrictedSet, xgMode);
+ useDefaultRepeatPatternBehavior = true;
+ }
+
+ @Override
+ public void setSeedContext(DisassemblerContextImpl seedContext) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setInitialContext(RegisterValue initialContextValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ *
+ * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
+ */
+ @Override
+ synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
+ Program program = (Program) obj;
+
+ disassemblyPerformed = false;
+ unalignedStart = false;
+
+ // get the XGATE mode register and set accordingly
+ Register xgmodeReg = program.getProgramContext().getRegister("XGATE");
+ RegisterValue xgmodeValue = null;
+
+ // if doing xgate, and have no XGmode reg, no way to do disassemble in xgate
+ if (xgmodeReg == null) {
+ if (xgMode) {
+ return false;
+ }
+ }
+ else {
+ xgmodeValue = new RegisterValue(xgmodeReg, BigInteger.valueOf(xgMode ? 0x1 : 0x0));
+ super.setInitialContext(xgmodeValue);
+ }
+
+ int alignment = 1;
+
+ // Set XGate Mode context on undefined code units only
+ try {
+ if (startSet != null) {
+
+ // Align startSet so that context only affected at possible instruction starts
+
+ AddressSet alignedSet = new AddressSet();
+ for (AddressRange range : startSet) {
+ Address min = range.getMinAddress();
+ long minOfffset = min.getOffset();
+ if (minOfffset != min.getOffset()) {
+ min = min.getNewAddress(minOfffset);
+ }
+ Address max = range.getMaxAddress();
+ long maxOffset = max.getOffset();
+ if (maxOffset < minOfffset) {
+ // skip short unaligned range
+ continue;
+ }
+ if (maxOffset != max.getOffset()) {
+ max = max.getNewAddress(maxOffset);
+ }
+ alignedSet.addRange(min, max);
+ }
+ if (alignedSet.isEmpty()) {
+ unalignedStart = true;
+ return false; // alignedSet does not contain any aligned starts
+ }
+ startSet = program.getListing().getUndefinedRanges(alignedSet, true, monitor);
+ if (startSet.isEmpty()) {
+ return true; // startSet does not contain any aligned undefined starts
+ }
+ }
+ }
+ catch (CancelledException e) {
+ return true;
+ }
+
+ return doDisassembly(monitor, program, alignment);
+ }
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java
index 9f4fac5d3e..2a22ca800f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java
@@ -83,6 +83,8 @@ public class DisassemblerPlugin extends Plugin {
private DockingAction contextAction;
private DockingAction armDisassembleAction;
private DockingAction armThumbDisassembleAction;
+ private DockingAction hcs12DisassembleAction;
+ private DockingAction xgateDisassembleAction;
private DockingAction mipsDisassembleAction;
private DockingAction mips16DisassembleAction;
private DockingAction ppcDisassembleAction;
@@ -172,6 +174,8 @@ public class DisassemblerPlugin extends Plugin {
contextAction = new ContextAction(this, GROUP_NAME);
armDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, false);
armThumbDisassembleAction = new ArmDisassembleAction(this, GROUP_NAME, true);
+ hcs12DisassembleAction = new Hcs12DisassembleAction(this, GROUP_NAME, false);
+ xgateDisassembleAction = new Hcs12DisassembleAction(this, GROUP_NAME, true);
mipsDisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, false);
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
@@ -183,6 +187,8 @@ public class DisassemblerPlugin extends Plugin {
tool.addAction(disassembleStaticAction);
tool.addAction(armDisassembleAction);
tool.addAction(armThumbDisassembleAction);
+ tool.addAction(hcs12DisassembleAction);
+ tool.addAction(xgateDisassembleAction);
tool.addAction(mipsDisassembleAction);
tool.addAction(mips16DisassembleAction);
tool.addAction(ppcDisassembleAction);
@@ -350,6 +356,30 @@ public class DisassemblerPlugin extends Plugin {
}
}
+ public void disassembleHcs12Callback(ListingActionContext context, boolean xgMode) {
+ ProgramSelection currentSelection = context.getSelection();
+ ProgramLocation currentLocation = context.getLocation();
+ Program currentProgram = context.getProgram();
+ Hcs12DisassembleCommand cmd = null;
+
+ if ((currentSelection != null) && (!currentSelection.isEmpty())) {
+ cmd = new Hcs12DisassembleCommand(currentSelection, null, xgMode);
+ }
+ else {
+ Address addr = currentLocation.getAddress();
+ try {
+ currentProgram.getMemory().getByte(addr);
+ cmd = new Hcs12DisassembleCommand(addr, null, xgMode);
+ }
+ catch (MemoryAccessException e) {
+ tool.setStatusInfo("Can't disassemble unitialized memory!", true);
+ }
+ }
+ if (cmd != null) {
+ tool.executeBackgroundCommand(cmd, currentProgram);
+ }
+ }
+
public void disassembleMipsCallback(ListingActionContext context, boolean mips16) {
ProgramSelection currentSelection = context.getSelection();
ProgramLocation currentLocation = context.getLocation();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/Hcs12DisassembleAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/Hcs12DisassembleAction.java
new file mode 100644
index 0000000000..23f6c893aa
--- /dev/null
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/Hcs12DisassembleAction.java
@@ -0,0 +1,84 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.plugin.core.disassembler;
+
+import java.awt.event.KeyEvent;
+
+import docking.action.KeyBindingData;
+import docking.action.MenuData;
+import ghidra.app.context.ListingActionContext;
+import ghidra.app.context.ListingContextAction;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.lang.*;
+import ghidra.program.model.listing.Program;
+
+
+/**
+ * Action for HCS12 mode disassembly
+ */
+
+class Hcs12DisassembleAction extends ListingContextAction {
+ private DisassemblerPlugin plugin;
+ private boolean disassembleXgate = false;
+
+ public Hcs12DisassembleAction(DisassemblerPlugin plugin, String groupName, boolean disassembleXgate) {
+ super("Disassemble " + (disassembleXgate ? "HCS12" : "XGate"), plugin.getName());
+
+ this.plugin = plugin;
+ this.disassembleXgate = disassembleXgate;
+
+ setPopupMenuData( new MenuData(
+ new String[]{"Disassemble - "+ (disassembleXgate ? "XGate" : "HCS12") },
+ null,
+ groupName ) );
+
+ int keyEvent = (disassembleXgate ? KeyEvent.VK_F12 : KeyEvent.VK_F11);
+ setKeyBindingData( new KeyBindingData( keyEvent, 0 ) );
+ }
+
+ @Override
+ public void actionPerformed(ListingActionContext context) {
+ plugin.disassembleHcs12Callback(context, disassembleXgate);
+ }
+
+ @Override
+ public boolean isEnabledForContext(ListingActionContext context) {
+
+ // Action only intended for use where Xgate instructions are available.
+ // The presence of the XGATE context register can be used for this
+ // determination.
+
+ Address address = context.getAddress();
+ if ( address == null ) {
+ return false;
+ }
+
+ Program program = context.getProgram();
+ Language lang = program.getLanguage();
+ Processor proc = lang.getProcessor();
+
+ if (!"HCS12".equals(proc.toString())) {
+ return false;
+ }
+
+ Register register = context.getProgram().getProgramContext().getRegister("XGATE");
+ if (register == null) {
+ return false;
+ }
+
+ return plugin.checkDisassemblyEnabled(context, address, true);
+ }
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java
index 3da7000d45..0a7959ada9 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/extend/ElfLoadAdapter.java
@@ -143,6 +143,29 @@ public class ElfLoadAdapter {
// segment is not marked execute, use the data space by default
return program.getLanguage().getDefaultDataSpace();
}
+
+
+ /**
+ * Get the preferred load address for a program segment
+ * @param elfLoadHelper load helper object
+ * @param elfProgramHeader elf program segment header
+ * @return preferred load address
+ */
+ public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper, ElfProgramHeader elfProgramHeader) {
+
+ Program program = elfLoadHelper.getProgram();
+
+ AddressSpace space =
+ getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
+
+ long addrWordOffset = elfProgramHeader.getVirtualAddress();
+
+ if (space == program.getAddressFactory().getDefaultAddressSpace()) {
+ addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
+ }
+
+ return space.getTruncatedAddress(addrWordOffset, true);
+ }
/**
* Get the default alignment within the default address space.
@@ -174,6 +197,27 @@ public class ElfLoadAdapter {
// segment is not marked execute, use the data space by default
return program.getLanguage().getDefaultDataSpace();
}
+
+ /**
+ * Get the preferred load address for a program section
+ * @param elfLoadHelper load helper object
+ * @param elfSectionHeader elf program section header
+ * @return preferred load address
+ */
+ public Address getPreferredSectionAddress(ElfLoadHelper elfLoadHelper,
+ ElfSectionHeader elfSectionHeader) {
+ Program program = elfLoadHelper.getProgram();
+
+ AddressSpace space = getPreferredSectionAddressSpace(elfLoadHelper, elfSectionHeader);
+
+ long addrWordOffset = elfSectionHeader.getAddress();
+
+ if (space == program.getAddressFactory().getDefaultAddressSpace()) {
+ addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
+ }
+
+ return space.getTruncatedAddress(addrWordOffset, true);
+ }
/**
* Check if this extension can handle the specified elf header. If this method returns
@@ -429,5 +473,4 @@ public class ElfLoadAdapter {
public Class extends ElfRelocation> getRelocationClass(ElfHeader elfHeader) {
return null;
}
-
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java
index 7dffceadb3..9928e3b71c 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java
@@ -2170,16 +2170,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
private Address getPreferredSegmentLoadAddress(ElfProgramHeader elfProgramHeader)
throws AddressOutOfBoundsException {
- AddressSpace space =
- elf.getLoadAdapter().getPreferredSegmentAddressSpace(this, elfProgramHeader);
-
- long addrWordOffset = elfProgramHeader.getVirtualAddress();
-
- if (space == getDefaultAddressSpace()) {
- addrWordOffset += getImageBaseWordAdjustmentOffset();
- }
-
- return space.getTruncatedAddress(addrWordOffset, true);
+ return elf.getLoadAdapter().getPreferredSegmentAddress(this, elfProgramHeader);
}
/**
@@ -2216,15 +2207,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
private Address getPreferredSectionLoadAddress(ElfSectionHeader elfSectionHeader)
throws AddressOutOfBoundsException {
- AddressSpace space = getPreferredSectionAddressSpace(elfSectionHeader);
-
- long addrWordOffset = elfSectionHeader.getAddress();
-
- if (space == getDefaultAddressSpace()) {
- addrWordOffset += getImageBaseWordAdjustmentOffset();
- }
-
- return space.getTruncatedAddress(addrWordOffset, true);
+ return elf.getLoadAdapter().getPreferredSectionAddress(this, elfSectionHeader);
}
@Override
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/CommitParamsAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/CommitParamsAction.java
index 5bb5d6e7b1..b00fd7ed94 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/CommitParamsAction.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/CommitParamsAction.java
@@ -83,8 +83,9 @@ public class CommitParamsAction extends AbstractDecompilerAction {
if (hfunc.getFunction().getSignatureSource() == SourceType.USER_DEFINED) {
source = SourceType.USER_DEFINED;
}
- HighFunctionDBUtil.commitParamsToDatabase(hfunc, true, source);
+
HighFunctionDBUtil.commitReturnToDatabase(hfunc, source);
+ HighFunctionDBUtil.commitParamsToDatabase(hfunc, true, source);
}
catch (DuplicateNameException e) {
throw new AssertException("Unexpected exception", e);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableUtilities.java
index f6a9e0295e..a88c2c80a5 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableUtilities.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableUtilities.java
@@ -415,6 +415,8 @@ public class VariableUtilities {
" bytes: " + curStorage.toString());
}
}
+
+ vnAddr = newReg.getAddress();
if (bigEndian) {
vnAddr = vnAddr.add(newReg.getMinimumByteSize() - size);
return new Varnode(vnAddr, size);
diff --git a/Ghidra/Processors/HCS12/Module.manifest b/Ghidra/Processors/HCS12/Module.manifest
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Ghidra/Processors/HCS12/build.gradle b/Ghidra/Processors/HCS12/build.gradle
new file mode 100644
index 0000000000..2cfe0295d5
--- /dev/null
+++ b/Ghidra/Processors/HCS12/build.gradle
@@ -0,0 +1,5 @@
+apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
+apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
+apply plugin: 'eclipse'
+eclipse.project.name = 'Processors HCS12'
+
diff --git a/Ghidra/Processors/HCS12/certification.manifest b/Ghidra/Processors/HCS12/certification.manifest
new file mode 100644
index 0000000000..929bc8b859
--- /dev/null
+++ b/Ghidra/Processors/HCS12/certification.manifest
@@ -0,0 +1,13 @@
+##VERSION: 2.0
+.project||NONE||||END|
+Module.manifest||GHIDRA||||END|
+build.gradle||GHIDRA||||END|
+data/build.xml||GHIDRA||||END|
+data/languages/HCS12.cspec||GHIDRA||||END|
+data/languages/HCS12.ldefs||GHIDRA||||END|
+data/languages/HCS12.opinion||GHIDRA||||END|
+data/languages/HCS12.pspec||GHIDRA||||END|
+data/languages/HCS12.slaspec||GHIDRA||||END|
+data/languages/HCS_HC12.sinc||GHIDRA||||END|
+data/languages/XGATE.sinc||GHIDRA||||END|
+data/manuals/HCS12.idx||GHIDRA||||END|
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS12.cspec b/Ghidra/Processors/HCS12/data/languages/HCS12.cspec
new file mode 100644
index 0000000000..17a93d7bc5
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS12.cspec
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ R7 = SP;
+
+
+
+
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS12.ldefs b/Ghidra/Processors/HCS12/data/languages/HCS12.ldefs
new file mode 100644
index 0000000000..dc9cc2f7c2
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS12.ldefs
@@ -0,0 +1,17 @@
+
+
+
+
+ HCS12X Microcontroller Family
+
+
+
+
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS12.opinion b/Ghidra/Processors/HCS12/data/languages/HCS12.opinion
new file mode 100644
index 0000000000..97dcaa03b5
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS12.opinion
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS12.pspec b/Ghidra/Processors/HCS12/data/languages/HCS12.pspec
new file mode 100644
index 0000000000..90fb9f51c1
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS12.pspec
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS12.slaspec b/Ghidra/Processors/HCS12/data/languages/HCS12.slaspec
new file mode 100644
index 0000000000..5421a5d192
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS12.slaspec
@@ -0,0 +1,9 @@
+# sleigh specification file for Freescale HCS12 (68HCS12)
+
+@define HCS12 "1"
+@define HCS12X "1"
+
+@define MAXFLASHPage "0xFF"
+
+@include "HCS_HC12.sinc"
+@include "XGATE.sinc"
\ No newline at end of file
diff --git a/Ghidra/Processors/HCS12/data/languages/HCS_HC12.sinc b/Ghidra/Processors/HCS12/data/languages/HCS_HC12.sinc
new file mode 100644
index 0000000000..451bfb0a2a
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/HCS_HC12.sinc
@@ -0,0 +1,5791 @@
+# common include file for HCS12, and HC12 constructors
+
+define endian=big;
+define alignment=1;
+
+define space RAM type=ram_space size=3 default;
+define space register type=register_space size=2;
+
+@define VECTOR_SWI "0xFFF6"
+@define VECTOR_TRAP "0xFFF8"
+
+################################################################
+# Registers
+################################################################
+
+define register offset=0x00 size=1 [ A B ];
+define register offset=0x00 size=2 [ D ];
+
+# IX also referred to as X or x; but must be distinct from X bit in CCR
+# IY also referred to as Y or y; made IY to be consistent with IX
+define register offset=0x10 size=2 [ IX IY TMP2 TMP3 TMP1 ];
+define register offset=0x10 size=1 [ IXH IXL IYH IYL TMP2H TMP2L TMP3H TMP3L TMP1H TMP1L ];
+
+#define register offset=0x20 size=3 [ _ PCE _ SPE ];
+define register offset=0x20 size=3 [ _ PCE ];
+define register offset=0x20 size=2 [ _ _ PC _ _ SP ];
+define register offset=0x20 size=1 [ _ _ _ _ PCH PCL _ _ _ _ SPH SPL ];
+
+define register offset=0x30 size=2 [ CCRW ];
+define register offset=0x30 size=1 [ CCRH ];
+
+define register offset=0x31 size=1 [ CCR ];
+
+define register offset = 0x32 size=3 [physPage];
+
+
+define RAM offset=0x10 size=1 [GPAGE];
+define RAM offset=0x11 size=1 [DIRECT];
+define RAM offset=0x16 size=1 [RPAGE];
+define RAM offset=0x17 size=1 [EPAGE];
+define RAM offset=0x30 size=1 [PPAGE];
+
+
+# Define context bits
+# WARNING: when adjusting context keep compiler packing in mind
+# and make sure fields do not span a 32-bit boundary before or
+# after context packing
+define register offset=0x40 size=4 contextreg;
+define context contextreg
+ Prefix18 = (0,0) # 1 if 0x18 is the first byte
+ PrefixHCS12X = (0,0) # 1 if first byte is 0x18 so that HCS12X to use GPAGE for memory access
+ UseGPAGE = (1,1) # 1 if should use GPAGE concatenated to lower 16-bit EA
+ XGATE = (2,2) # 1 if in xgate instruction decode mode
+;
+
+
+# individual status bits within CCRH
+
+@define IPL_2 "CCRH[2,1]"
+@define IPL_1 "CCRH[1,1]"
+@define IPL_0 "CCRH[0,1]"
+
+@define IPL "CCRH[0,3]" # entire IPL
+
+# individual status bits within CCR
+
+@define S "CCR[7,1]" # STOP Enable
+@define X "CCR[6,1]" # Non-maskable interrupt control bit
+@define H "CCR[5,1]" # Half Carry Flag
+@define I "CCR[4,1]" # Maskable interrupt control bit
+@define N "CCR[3,1]" # Negative Flag
+@define Z "CCR[2,1]" # Zero Flag
+@define V "CCR[1,1]" # Two's complement overflow Flag
+@define C "CCR[0,1]" # Carry/Borrow Flag
+
+################################################################
+# Tokens
+################################################################
+
+define token opbyte8 (8)
+ op8 = (0,7)
+ op7_4 = (4,7)
+ op6_4 = (4,6)
+ nIndex = (1,3)
+ op0_0 = (0,0)
+ trapnum = (0,7)
+;
+
+define token xb8 (8)
+ rr7_6 = (6,7)
+ rr7_6a = (6,7)
+ xb5_5 = (5,5)
+ nn4_0 = (0,4) signed
+
+ xb7_5 = (5,7)
+ rr4_3 = (3,4)
+ xb2_2 = (2,2)
+ xb2_1 = (1,2) # actually needed this instead of xb2_2
+ z1_1 = (1,1)
+ s0_0 = (0,0)
+
+ xb2_0 = (0,2)
+
+ p4_4 = (4,4)
+ decrement3_3 = (3,3)
+ nn3_0 = (0,3)
+
+ aa1_0 = (0,1)
+ aa0_0 = (0,0) # actually needed this instead of aa1_0
+;
+
+define token eb8 (8)
+ notUsed7_7 = (7,7)
+ abcdxys6_4 = (4,6)
+ abc5_4 = (4,5)
+ dxys2_0 = (0,2)
+ abcdxys2_0 = (0,2)
+ columns7_4 = (4,7)
+ rows2_0 = (0,2)
+ rows3_0 = (0,3)
+ bytes_ABCl_6_4 = (4,6)
+ bytes_ABClT3lBXlYlSl_6_4 = (4,6)
+ bytes_ABChT3hBXhYhSh_6_4 = (4,6)
+ words_CT3DXYS_6_4 = (4,6)
+ words_T3DXYS_6_4 = (4,6)
+ bytes_ABCl_2_0 = (0,2)
+ bytes_T3lDlXlYlSl_6_4 = (4,6)
+ words_T2DXYS_2_0 = (0,2)
+ bytes_T2h_XhYhSh_2_0 = (0,2)
+ bytes_T2l_XlYlSl_2_0 = (0,2)
+ bytes_T3l_XlYlSl_6_4 = (4,6)
+ bytes_T3h_XhYhSh_6_4 = (4,6)
+ words_T3_XYS_6_4 = (4,6)
+ bytes_T2hDhXhYhSh_2_0 = (0,2)
+ bytes_T2lDlXlYlSl_2_0 = (0,2)
+;
+
+define token opbyte16 (16)
+ op16 = (0,15)
+ op15_13 = (13,15)
+ sign12_12 = (12,12) signed
+ not_used11 = (11,11)
+ size10_10 = (10,10)
+ byte9_8 = (8,9)
+ word9_8 = (8,9)
+ rr7_0 = (0,7)
+;
+
+define token data8 (8)
+ imm8 = (0,7)
+ simm8 = (0,7) signed
+ rel = (0,7) signed
+;
+
+define token data16 (16)
+ imm16 = (0,15)
+ imm16p = (12,15)
+ imm16e = (8,15)
+ imm16ev = (0,9)
+ imm16rv = (0,11)
+ imm16pv = (0,13)
+ simm16 = (0,15) signed
+;
+
+attach variables [ rr7_6 rr4_3 ] [ IX IY SP PC ];
+attach variables [ rr7_6a ] [ IX IY SP _ ]; # PC not valid choice in this case
+
+# TODO would be great if this worked
+# attach names [ rr7_6 rr4_3 ] [ "X" "Y" "SP" "PC" ];
+
+
+# TODO do the negative values work?
+attach values [ nn3_0 ] [ 1 2 3 4 5 6 7 8 -8 -7 -6 -5 -4 -3 -2 -1 ];
+
+attach variables [ aa0_0 ] [ A B ];
+
+attach variables [ byte9_8 ] [ A B _ _ ];
+
+attach variables [ word9_8 ] [ D IX IY SP ];
+
+attach variables [ abc5_4 ] [ A B CCR _ ];
+
+attach variables [ dxys2_0 ] [ _ _ _ TMP2 D IX IY SP ];
+
+attach variables [ bytes_ABCl_2_0 ] [ A B CCR _ _ _ _ _ ];
+
+attach variables [ bytes_ABClT3lBXlYlSl_6_4 ] [ A B CCR TMP3L B IXL IYL SPL ];
+
+attach variables [ bytes_ABChT3hBXhYhSh_6_4 ] [ A B CCRH TMP3H B IXH IYH SPH ];
+
+attach variables [ words_T2DXYS_2_0 ] [ _ _ _ TMP2 D IX IY SP ];
+
+attach variables [ bytes_T3lDlXlYlSl_6_4 ] [ _ _ _ TMP3L B IXL IYL SPL ];
+
+attach variables [ words_T3DXYS_6_4 ] [ _ _ _ TMP3 D IX IY SP ];
+
+attach variables [ words_CT3DXYS_6_4 ] [ _ _ CCRW TMP3 D IX IY SP ];
+
+attach variables [ bytes_T2l_XlYlSl_2_0 ] [ _ _ _ TMP2L _ IXL IYL SPL ];
+
+attach variables [ bytes_T2h_XhYhSh_2_0 ] [ _ _ _ TMP2H _ IXH IYH SPH ];
+
+attach variables [ bytes_T3l_XlYlSl_6_4 ] [ _ _ _ TMP3L _ IXL IYL SPL ];
+
+attach variables [ bytes_T3h_XhYhSh_6_4 ] [ _ _ _ TMP3H _ IXH IYH SPH ];
+
+attach variables [ words_T3_XYS_6_4 ] [ _ _ _ TMP3 _ IX IY SP ];
+
+attach variables [ bytes_ABCl_6_4 ] [ A B CCR _ _ _ _ _ ];
+
+attach variables [ bytes_T2hDhXhYhSh_2_0 ] [ _ _ _ TMP2H A IXH IYH SPH ];
+
+attach variables [ bytes_T2lDlXlYlSl_2_0 ] [ _ _ _ TMP2L B IXL IYL SPL ];
+
+################################################################
+# Pseudo Instructions
+################################################################
+define pcodeop segment; # Define special pcodeop that calculates the RAM address
+# given the segment selector and offset as input
+
+define pcodeop readIRQ;
+define pcodeop stop;
+define pcodeop WaitForInterrupt;
+
+define pcodeop decimalAdjustAccumulator;
+define pcodeop decimalAdjustCarry;
+define pcodeop EMACS;
+define pcodeop ETBL;
+define pcodeop ETBL_Cflag;
+define pcodeop GradeOfMembership;
+define pcodeop TableLookupAndInterpolate;
+define pcodeop TableLookupAndInterpolateRoundable;
+define pcodeop WeightedAverageSOPHigh;
+define pcodeop WeightedAverageSOPLow;
+define pcodeop WeightedAverageSOW;
+define pcodeop WeightedAverageResume;
+define pcodeop MinMaxRuleEvaluation;
+define pcodeop MinMaxRuleEvaluationCorrect;
+define pcodeop MinMaxRuleEvaluationWeighted;
+define pcodeop MinMaxRuleEvaluationWeightedCorrect;
+
+define pcodeop backgroundDebugMode;
+
+macro setHCSphysPage(addr) {
+ local a3:3 = zext(addr);
+
+ local isReg:1 = (a3 & 0xfC00) == 0x0;
+ local isEpage:1 = (a3 & 0xfc00) ==0x800;
+ local isEpage_FF:1 = (a3 & 0xfc00) ==0xC00;
+ local isRpage:1 = (a3 & 0xf000) ==0x1000;
+ local isRpage_FE:1 = (a3 & 0xf000) ==0x2000;
+ local isRpage_FF:1 = (a3 & 0xf000) ==0x3000;
+ local isPpage_FD:1 = (a3 & 0xc000) ==0x4000;
+ local isPpage:1 = (a3 & 0xc000) ==0x8000;
+ local isPpage_FF:1 = (a3 & 0xc000) ==0xC000;
+
+ physPage = (zext(isReg) * 0x0) +
+ (zext(isEpage) * (0x100000 | ((zext(EPAGE) << 10) ^ 0x800))) +
+ (zext(isEpage_FF) * ((0x4FF << 10) ^ 0xC00)) +
+ (zext(isRpage) * (((zext(RPAGE) << 12) ^ 0x1000))) +
+ (zext(isRpage_FE) * (((0xFE << 12) ^ 0x2000))) +
+ (zext(isRpage_FF) * (((0xFF << 12) ^ 0x3000))) +
+ (zext(isPpage_FD) * (0x400000 | ((0x3F4000) ^ 0x4000))) +
+ (zext(isPpage) * (0x400000 | ((zext(PPAGE) << 14 ) ^ 0x8000))) +
+ (zext(isPpage_FF) * (0x400000 | ((0x3FC000) ^ 0xC000))) ;
+}
+
+macro Load1(value, addr) {
+ setHCSphysPage(addr);
+
+ local paddr:3 = segment(physPage, addr);
+ value = *:1 paddr;
+}
+macro Load2(value, addr) {
+ setHCSphysPage(addr);
+
+ local paddr:3 = segment(physPage, addr);
+ value = *:2 paddr;
+}
+
+macro GetPagedAddr(addr,paddr) {
+ setHCSphysPage(addr);
+
+ paddr = segment(physPage, addr);
+}
+
+macro Store(addr, value) {
+ setHCSphysPage(addr);
+
+ local paddr:3 = segment(physPage, addr);
+
+ *paddr = value;
+}
+
+################################################################
+# Addressing tables
+################################################################
+
+#
+# TODO: Paging could be added here as these are constant addresses
+# could factor the overlapping addresses here, unless the
+# page register is always added in then will have to export as a constant
+# since don't know the real address
+#
+
+# known EPAGE offsets
+opr16a: imm16 is imm16e=0x8 & imm16 & imm16ev { local addr:3 = 0x100000 | (zext(EPAGE) << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0x9 & imm16 & imm16ev { local addr:3 = 0x100000 | (zext(EPAGE) << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0xa & imm16 & imm16ev { local addr:3 = 0x100000 | (zext(EPAGE) << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0xb & imm16 & imm16ev { local addr:3 = 0x100000 | (zext(EPAGE) << 10) | imm16ev; export addr; }
+
+opr16a: imm16 is imm16e=0xc & imm16 & imm16ev { local addr:3 = (0xFF << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0xd & imm16 & imm16ev { local addr:3 = (0xFF << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0xe & imm16 & imm16ev { local addr:3 = (0xFF << 10) | imm16ev; export addr; }
+opr16a: imm16 is imm16e=0xf & imm16 & imm16ev { local addr:3 = (0xFF << 10) | imm16ev; export addr; }
+
+# known RPAGE offsets
+opr16a: imm16 is imm16p=0x1 & imm16 & imm16rv { local addr:3 = (zext(RPAGE) << 12) | imm16rv; export addr; }
+opr16a: imm16 is imm16p=0x2 & imm16 & imm16rv { local addr:3 = (0xFE << 12) | imm16rv; export addr; }
+opr16a: imm16 is imm16p=0x3 & imm16 & imm16rv { local addr:3 = (0xFF << 12) | imm16rv; export addr; }
+
+# known PPAGE offsets
+opr16a: imm16 is imm16p=0x4 & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFD << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0x5 & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFD << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0x6 & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFD << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0x7 & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFD << 14) | imm16pv; export addr; }
+
+opr16a: imm16 is imm16p=0x8 & imm16 & imm16pv { local addr:3 = 0x400000 | (zext(PPAGE) << 14) | (imm16pv & 0x3fff); export addr; }
+opr16a: imm16 is imm16p=0x9 & imm16 & imm16pv { local addr:3 = 0x400000 | (zext(PPAGE) << 14) | (imm16pv & 0x3fff); export addr; }
+opr16a: imm16 is imm16p=0xa & imm16 & imm16pv { local addr:3 = 0x400000 | (zext(PPAGE) << 14) | (imm16pv & 0x3fff); export addr; }
+opr16a: imm16 is imm16p=0xb & imm16 & imm16pv { local addr:3 = 0x400000 | (zext(PPAGE) << 14) | (imm16pv & 0x3fff); export addr; }
+
+opr16a: imm16 is imm16p=0xC & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFF << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0xD & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFF << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0xE & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFF << 14) | imm16pv; export addr; }
+opr16a: imm16 is imm16p=0xF & imm16 & imm16pv { local addr:3 = 0x400000 | (0xFF << 14) | imm16pv; export addr; }
+
+opr16a: imm16 is imm16e & imm16 { local addr:3 = imm16; export addr; }
+
+opr8a: imm8 is imm8 { export *[const]:3 imm8; }
+
+opr8a_8: imm8 is UseGPAGE=0 & imm8 { export *:1 imm8; }
+opr8a_8: imm8 is UseGPAGE=1 & imm8 { local addr:3 = (zext(GPAGE) << 16) | imm8; export *:1 addr; }
+opr8a_16: imm8 is UseGPAGE=0 & imm8 { export *:2 imm8; }
+opr8a_16: imm8 is UseGPAGE=1 & imm8 { local addr:3 = (zext(GPAGE) << 16) | imm8; export *:2 addr; }
+
+opr16a_8: opr16a is UseGPAGE=0 & opr16a { export *:1 opr16a; }
+opr16a_8: imm16 is UseGPAGE=1 & imm16 { local addr:3 = (zext(GPAGE) << 16) | imm16; export *:1 addr; }
+opr16a_16: opr16a is UseGPAGE=0 & opr16a { export *:2 opr16a; }
+opr16a_16: imm16 is UseGPAGE=1 & imm16 { local addr:3 = (zext(GPAGE) << 16) | imm16; export *:2 addr; }
+
+iopr8i: "#"imm8 is imm8 { export *[const]:1 imm8; }
+iopr16i: "#"imm16 is imm16 { export *[const]:2 imm16; }
+msk8: imm8 is imm8 { export *[const]:1 imm8; }
+page: imm8 is imm8 { export *[const]:1 imm8; }
+
+#PageDest: dest is imm16p=0x8 & imm16 & imm16pv ; imm8 [ dest = (imm8 << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0x9 & imm16 & imm16pv ; imm8 [ dest = (imm8 << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xa & imm16 & imm16pv ; imm8 [ dest = (imm8 << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xb & imm16 & imm16pv ; imm8 [ dest = (imm8 << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xc & imm16 & imm16pv ; imm8 [ dest = ($(MAXFLASHPage) << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xd & imm16 & imm16pv ; imm8 [ dest = ($(MAXFLASHPage) << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xe & imm16 & imm16pv ; imm8 [ dest = ($(MAXFLASHPage) << 16) | imm16; ] { export *:1 dest; }
+#PageDest: dest is imm16p=0xf & imm16 & imm16pv ; imm8 [ dest = ($(MAXFLASHPage) << 16) | imm16; ] { export *:1 dest; }
+PageDest: opr16a is opr16a; page { export opr16a; }
+
+#
+# Postbyte Code (xb) address decoding
+# for indexed addressing modes: IDX, IDX1, IDX2, [D,IDX] and [IDX2]
+#
+#
+# per page 29, 30, and 33
+#
+
+#**********
+# IDX
+#**********
+#
+# rr0nnnnn
+#
+# 5-bit constant offset n = -16 to +15
+IDX_a: 0,rr7_6 is rr7_6 & xb5_5=0 & nn4_0=0
+ { export rr7_6; }
+
+# TODO make sure that nn4_0 is a signed extension
+IDX_b: nn4_0, rr7_6 is rr7_6 & xb5_5=0 & nn4_0
+ { address:2 = rr7_6 + nn4_0; export address; }
+
+# rr1pnnnn
+#
+# used xb7_5 in all of these to prevent rr7_6a from ever being 0b11, and overlapping the 111rr0zs decodes
+#
+# Auto pre-decrement
+IDX_c: nn3_0, -rr7_6a is (xb7_5=0b001 | xb7_5=0b011 | xb7_5=0b101) & rr7_6a & p4_4=0 & decrement3_3=1 & nn3_0
+ { rr7_6a = rr7_6a + nn3_0; address:2 = rr7_6a; export address; }
+
+# Auto pre-increment
+IDX_d: nn3_0, +rr7_6a is (xb7_5=0b001 | xb7_5=0b011 | xb7_5=0b101) & rr7_6a & p4_4=0 & decrement3_3=0 & nn3_0
+ { rr7_6a = rr7_6a + nn3_0; address:2 = rr7_6a; export address; }
+
+# Auto post-decrement
+IDX_e: nn3_0, rr7_6a- is (xb7_5=0b001 | xb7_5=0b011 | xb7_5=0b101) & rr7_6a & p4_4=1 & decrement3_3=1 & nn3_0
+ { address:2 = rr7_6a; rr7_6a = rr7_6a + nn3_0; export address; }
+
+# Auto post-increment
+IDX_f: nn3_0, rr7_6a+ is (xb7_5=0b001 | xb7_5=0b011 | xb7_5=0b101) & rr7_6a & p4_4=1 & decrement3_3=0 & nn3_0
+ { address:2 = rr7_6a; rr7_6a = rr7_6a + nn3_0; export address; }
+
+# 111rr1aa
+#
+# Accumulator unsigned 8-bit offset indexed
+IDX_g: aa0_0, rr4_3 is xb7_5=0b111 & rr4_3 & xb2_1=0b10 & aa0_0
+ { address:2 = rr4_3 + zext(aa0_0); export address; }
+
+# Accumulator 16-bit offset indexed
+IDX_h: D, rr4_3 is xb7_5=0b111 & rr4_3 & xb2_0=0b110 & D
+ { address:2 = rr4_3 + D; export address; }
+
+
+#**********
+# IDX1
+#**********
+#
+# 111rr0zs imm8
+#
+# Constant offset (9-bit signed, positive)
+IDX_i: imm8, rr4_3 is xb7_5=0b111 & rr4_3 & xb2_2=0 & z1_1=0 & s0_0=0; imm8
+ { address:2 = rr4_3 + imm8; export address; }
+
+# Constant offset (9-bit signed, negative)
+# TODO make sure that the -256 case works
+IDX_j: -neg, rr4_3 is xb7_5=0b111 & rr4_3 & xb2_2=0 & z1_1=0 & s0_0=1; imm8 [ neg = -imm8; ]
+ { address:2 = rr4_3 - neg; export address; }
+
+
+#**********
+# IDX2
+#**********
+#
+# 111rr0zs simm16
+#
+# Constant offset (16-bit signed)
+IDX_k: simm16, rr4_3 is xb7_5=0b111 & rr4_3 & xb2_2=0 & z1_1=1 & s0_0=0; simm16
+ { address:2 = rr4_3 + simm16; export address; }
+
+#**********
+# [IDX2]
+#**********
+#
+# 111rr011 simm16
+#
+# 16-bit offset indexed-indirect
+
+IDX_l: [simm16, rr4_3] is xb7_5=0b111 & rr4_3 & xb2_2=0 & z1_1=1 & s0_0=1; simm16
+ { address:2 = rr4_3 + simm16; Load2(address,address); export address; }
+
+IDX_l: [simm16, PC] is xb7_5=0b111 & rr4_3=3 & xb2_2=0 & z1_1=1 & s0_0=1; simm16 & PC
+ { address:2 = inst_next + simm16; Load2(address,address); export address; }
+
+#**********
+# [D,IDX]
+#**********
+#
+# 111rr111
+#
+# Accumulator D offset indexed-indirect
+IDX_m: [D, rr4_3] is xb7_5=0b111 & rr4_3 & xb2_0=0b111 & D
+ { address:2 = rr4_3 + D; Load2(address,address); export address; }
+
+
+######################################################################
+######################################################################
+#
+# effective address of IDX, IDX1, IDX2
+#
+indexed3: IDX_a is IDX_a { export IDX_a; }
+indexed3: IDX_b is IDX_b { export IDX_b; }
+indexed3: IDX_c is IDX_c { export IDX_c; }
+indexed3: IDX_d is IDX_d { export IDX_d; }
+indexed3: IDX_e is IDX_e { export IDX_e; }
+indexed3: IDX_f is IDX_f { export IDX_f; }
+indexed3: IDX_g is IDX_g { export IDX_g; }
+indexed3: IDX_h is IDX_h { export IDX_h; }
+indexed3: IDX_i is IDX_i { export IDX_i; }
+indexed3: IDX_j is IDX_j { export IDX_j; }
+indexed3: IDX_k is IDX_k { export IDX_k; }
+# not indexed3: IDX_l is IDX_l { export IDX_l; }
+# not indexed3: IDX_m is IDX_m { export IDX_m; }
+
+#
+# effective address of [IDX2], [D,IDX]
+#
+# not indexedindexed3: IDX_a is IDX_a { export IDX_a; }
+# not indexedindexed3: IDX_b is IDX_b { export IDX_b; }
+# not indexedindexed3: IDX_c is IDX_c { export IDX_c; }
+# not indexedindexed3: IDX_d is IDX_d { export IDX_d; }
+# not indexedindexed3: IDX_e is IDX_e { export IDX_e; }
+# not indexedindexed3: IDX_f is IDX_f { export IDX_f; }
+# not indexedindexed3: IDX_g is IDX_g { export IDX_g; }
+# not indexedindexed3: IDX_h is IDX_h { export IDX_h; }
+# not indexedindexed3: IDX_i is IDX_i { export IDX_i; }
+# not indexedindexed3: IDX_j is IDX_j { export IDX_j; }
+# not indexedindexed3: IDX_k is IDX_k { export IDX_k; }
+indexed2: IDX_l is IDX_l { export IDX_l; }
+indexed2: IDX_m is IDX_m { export IDX_m; }
+
+#
+# effective address of IDX, IDX1, IDX2, [IDX2], [D,IDX]
+#
+indexed5: IDX_a is IDX_a { export IDX_a; }
+indexed5: IDX_b is IDX_b { export IDX_b; }
+indexed5: IDX_c is IDX_c { export IDX_c; }
+indexed5: IDX_d is IDX_d { export IDX_d; }
+indexed5: IDX_e is IDX_e { export IDX_e; }
+indexed5: IDX_f is IDX_f { export IDX_f; }
+indexed5: IDX_g is IDX_g { export IDX_g; }
+indexed5: IDX_h is IDX_h { export IDX_h; }
+indexed5: IDX_i is IDX_i { export IDX_i; }
+indexed5: IDX_j is IDX_j { export IDX_j; }
+indexed5: IDX_k is IDX_k { export IDX_k; }
+indexed5: IDX_l is IDX_l { export IDX_l; }
+indexed5: IDX_m is IDX_m { export IDX_m; }
+
+#
+# effective address of IDX
+#
+indexed1: IDX_a is IDX_a { export IDX_a; }
+indexed1: IDX_b is IDX_b { export IDX_b; }
+indexed1: IDX_c is IDX_c { export IDX_c; }
+indexed1: IDX_d is IDX_d { export IDX_d; }
+indexed1: IDX_e is IDX_e { export IDX_e; }
+indexed1: IDX_f is IDX_f { export IDX_f; }
+indexed1: IDX_g is IDX_g { export IDX_g; }
+indexed1: IDX_h is IDX_h { export IDX_h; }
+# not indexed1: IDX_i is IDX_i { export IDX_i; }
+# not indexed1: IDX_j is IDX_j { export IDX_j; }
+# not indexed1: IDX_k is IDX_k { export IDX_k; }
+# not indexed1: iIDX_l is iIDX_l { export iIDX_l; }
+# not indexed1: IDX_m is IDX_m { export IDX_m; }
+
+
+#
+# indexed0_x - exports the effective address (EA)
+# indexed1_x - exports a single byte at the effective address
+# indexed2_x - exports a double byte at the effective address
+#
+
+indexed1_1: indexed1 is indexed1 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed1,paddr);
+ export *:1 paddr;
+}
+indexed2_1: indexed1 is indexed1 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed1,paddr);
+ export *:2 paddr;
+}
+
+indexed0_2: indexed2 is indexed2 {
+ local val = indexed2; export val;
+}
+
+indexed0_3: indexed3 is indexed3 {
+ local val = indexed3; export val;
+}
+indexed1_3: indexed3 is indexed3 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed3,paddr);
+ export *:1 paddr;
+}
+indexed2_3: indexed3 is indexed3 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed3,paddr);
+ export *:2 paddr;
+}
+
+indexedA_5: indexed5 is UseGPAGE=0 & indexed5 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed5,paddr);
+ export paddr;
+}
+indexedA_5: indexed5 is UseGPAGE=1 & indexed5 {
+ local addr:3 = (zext(GPAGE) << 16) | zext(indexed5);
+ export addr;
+}
+indexed1_5: indexed5 is UseGPAGE=0 & indexed5 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed5,paddr);
+ export *:1 paddr;
+}
+indexed1_5: indexed5 is UseGPAGE=1 & indexed5 {
+ local addr:3 = (zext(GPAGE) << 16) | zext(indexed5);
+ export *:1 addr;
+}
+indexed2_5: indexed5 is UseGPAGE=0 & indexed5 {
+ local paddr:3 = 0;
+ GetPagedAddr(indexed5,paddr);
+ export *:2 paddr;
+}
+indexed2_5: indexed5 is UseGPAGE=1 & indexed5 {
+ local addr:3 = (zext(GPAGE) << 16) | zext(indexed5);
+ export *:2 addr;
+}
+
+# range -128 through +127
+rel8: reloc is rel [ reloc = inst_next + rel; ] { export *:1 reloc; }
+
+# range -256 through +255
+rel9: reloc is XGATE=0 & sign12_12 & rr7_0 [ reloc = inst_next + ((sign12_12 << 8) | rr7_0); ] { export *:1 reloc; }
+
+# positive range 0 through +65535
+rel16: reloc is simm16 [ reloc = inst_next + simm16; ] { export *:1 reloc; }
+
+
+op2_opr16a_8: opr16a_8 is opr16a_8 { export opr16a_8; }
+op2_opr16a_16: opr16a_16 is opr16a_16 { export opr16a_16; }
+
+@if defined(HCS12X)
+op2_indexed1_5: indexed1_5 is indexed1_5 { export indexed1_5; }
+@else
+op2_indexed1_1: indexed1_1 is indexed1_1 { export indexed1_1; }
+@endif
+
+@if defined(HCS12X)
+op2_indexed2_5: indexed2_5 is indexed2_5 { export indexed2_5; }
+@else
+op2_indexed2_1: indexed2_1 is indexed2_1 { export indexed2_1; }
+@endif
+
+################################################################
+# Macros
+################################################################
+
+
+
+macro additionWithCarry(operand1, operand2, result) {
+ local Ccopy = zext($(C));
+ local AFmask = -1 >> 4;
+ $(H) = (((operand1 & AFmask) + (operand2 & AFmask) + Ccopy) & (AFmask + 1)) != 0;
+ $(C) = carry(operand1, operand2);
+ local tempResult = operand1 + operand2;
+ $(C) = $(C) || carry(tempResult, Ccopy);
+ $(V) = $(V) ^^ scarry(tempResult, Ccopy);
+ result = tempResult + Ccopy;
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+}
+
+
+
+macro addition_flags1(operand1, operand2,result) {
+ local AFmask = -1 >> 4;
+ $(H) = (((operand1 & AFmask) + (operand2 & AFmask)) & (AFmask + 1)) != 0;
+
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ $(V) = scarry(operand1,operand2);
+ $(C) = carry(operand1,operand2);
+}
+
+macro addition_flags2(operand1, operand2, result) {
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ $(V) = scarry(operand1,operand2);
+ $(C) = carry(operand1,operand2);
+}
+
+macro subtraction_flags1(register, operand, result) {
+ $(V) = sborrow(register,operand);
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ $(C) = register < operand;
+}
+
+macro subtraction_flags2(register, operand, result) {
+ $(V) = sborrow(register,operand);
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ $(C) = register < operand;
+}
+
+macro V_equals_0() {
+ $(V) = 0;
+}
+
+macro V_equals_C() {
+ $(V) = $(C);
+}
+
+macro V_equals_N_xor_C() {
+ $(V) = $(N) ^ $(C);
+}
+
+macro V_CMP_flag(register, operand) {
+ $(V) = sborrow(register,operand);
+}
+
+macro V_DEC_flag(operand) {
+ $(V) = sborrow(operand,1);
+}
+
+macro V_DEC_flag2(operand) {
+ $(V) = sborrow(operand,1);
+}
+
+macro V_INC_flag(operand) {
+ $(V) = scarry(operand,1);
+}
+
+macro V_INC_flag2(operand) {
+ $(V) = scarry(operand,1);
+}
+
+macro V_NEG_flag(operand) {
+ $(V) = sborrow(0,operand);
+}
+
+macro V_NEG_flag2(operand) {
+ $(V) = sborrow(0,operand);
+}
+
+macro Pull1(operand) {
+ setHCSphysPage(SP);
+
+ paddr:3 = segment(physPage,SP);
+ operand = *paddr;
+ SP = SP + 1;
+}
+
+macro Pull2(operand) {
+ setHCSphysPage(SP);
+
+ paddr:3 = segment(physPage,SP);
+ operand = *paddr;
+ SP = SP + 2;
+}
+
+macro Push1(operand) {
+ SP = SP - 1;
+
+ setHCSphysPage(SP);
+ paddr:3 = segment(physPage,SP);
+ *paddr = operand;
+}
+
+macro Push2(operand) {
+ SP = SP - 2;
+
+ setHCSphysPage(SP);
+
+ paddr:3 = segment(physPage,SP);
+ *paddr = operand;
+}
+
+macro setCCR( operand ) {
+ # when CCR is the destination, cannot set the X bit unless it is already set in CCR
+ CCR = operand & (CCR | 0b10111111);
+}
+
+macro setCCRW( operand ) {
+ # when CCRW is the destination, cannot set the X bit unless it is already set in CCRW
+ CCRW = operand & (CCRW | 0b1111111110111111);
+}
+
+:^instruction is XGATE=0 & op8=0x18; instruction [ Prefix18=1; ] {}
+
+################################################################
+# Constructors
+################################################################
+
+:ABA is XGATE=0 & (Prefix18=1 & op8=0x06)
+{
+ result:1 = A + B;
+ addition_flags1(A, B, result);
+ A = result;
+}
+
+:ABX is XGATE=0 & Prefix18=0 & (op16=0x1AE5)
+{
+ IX = zext(B) + IX;
+}
+
+:ABY is XGATE=0 & Prefix18=0 & (op16=0x19ED)
+{
+ IY = zext(B) + IY;
+}
+
+:ADCA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x89); iopr8i
+{
+ op1:1 = iopr8i;
+
+ local result:1;
+ additionWithCarry(A, op1, result);
+
+ A = result;
+}
+
+:ADCA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x99); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ local result:1;
+ additionWithCarry(A, op1, result);
+
+ A = result;
+}
+
+:ADCA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB9); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ local result:1;
+ additionWithCarry(A, op1, result);
+
+ A = result;
+}
+
+:ADCA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA9); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = A + op1 + $(C);
+ addition_flags1(A, op1, result);
+ A = result;
+}
+
+:ADCB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC9); iopr8i
+{
+ op1:1 = iopr8i;
+
+ local result:1;
+ additionWithCarry(A, op1, result);
+
+ B = result;
+}
+
+:ADCB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD9); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = B + op1 + $(C);
+ addition_flags1(B, op1, result);
+ B = result;
+}
+
+:ADCB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF9); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ local result:1;
+ additionWithCarry(B, op1, result);
+
+ B = result;
+}
+
+:ADCB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE9); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ local result:1;
+ additionWithCarry(B, op1, result);
+
+ B = result;
+}
+
+:ADDA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x8B); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = A + op1;
+ addition_flags1(A, op1, result);
+
+ A = result;
+}
+
+:ADDA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x9B); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = A + op1;
+ addition_flags1(A, op1, result);
+ A = result;
+}
+
+:ADDA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xBB); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = A + op1;
+ addition_flags1(A, op1, result);
+ A = result;
+}
+
+:ADDA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xAB); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = A + op1;
+ addition_flags1(A, op1, result);
+ A = result;
+}
+
+:ADDB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xCB); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = B + op1;
+ addition_flags1(B, op1, result);
+ B = result;
+}
+
+:ADDB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xDB); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = B + op1;
+ addition_flags1(B, op1, result);
+ B = result;
+}
+
+:ADDB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xFB); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = B + op1;
+ addition_flags1(B, op1, result);
+ B = result;
+}
+
+:ADDB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xEB); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = B + op1;
+ addition_flags1(B, op1, result);
+ B = result;
+}
+
+:ADDD iopr16i is XGATE=0 & Prefix18=0 & (op8=0xC3); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = D + op1;
+ addition_flags2(D, op1, result);
+ D = result;
+}
+
+:ADDD opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0xD3); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = D + op1;
+ addition_flags2(D, op1, result);
+ D = result;
+}
+
+:ADDD opr16a_16 is XGATE=0 & Prefix18=0 & (op8=0xF3); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = D + op1;
+ addition_flags2(D, op1, result);
+ D = result;
+}
+
+:ADDD indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xE3); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = D + op1;
+ addition_flags2(D, op1, result);
+ D = result;
+}
+
+@if defined(HCS12X)
+:ADDX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8B); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IX + op1;
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9B); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IX + op1;
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBB); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IX + op1;
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAB); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IX + op1;
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xCB); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IY + op1;
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xDB); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IY + op1;
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xFB); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IY + op1;
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADDY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xEB); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IY + op1;
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADED iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC3); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = D + op1 + zext($(C));
+ addition_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADED opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD3); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = D + op1 + zext($(C));
+ addition_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADED opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF3); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = D + op1 + zext($(C));
+ addition_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADED indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE3); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = D + op1 + zext($(C));
+ addition_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x89); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IX + op1 + zext($(C));
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x99); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IX + op1 + zext($(C));
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xb9); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IX + op1 + zext($(C));
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xa9); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IX + op1 + zext($(C));
+ addition_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC9); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IY + op1 + zext($(C));
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD9); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IY + op1 + zext($(C));
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF9); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IY + op1 + zext($(C));
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:ADEY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE9); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IY + op1 + zext($(C));
+ addition_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+:ANDA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x84); iopr8i
+{
+ A = A & iopr8i;
+ V_equals_0();
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+}
+
+:ANDA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x94); opr8a_8
+{
+ A = A & opr8a_8;
+ V_equals_0();
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+}
+
+:ANDA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB4); opr16a_8
+{
+ A = A & opr16a_8;
+ V_equals_0();
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+}
+
+:ANDA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA4); indexed1_5
+{
+ A = A & indexed1_5;
+ V_equals_0();
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+}
+
+:ANDB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC4); iopr8i
+{
+ B = B & iopr8i;
+ V_equals_0();
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+}
+
+:ANDB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD4); opr8a_8
+{
+ B = B & opr8a_8;
+ V_equals_0();
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+}
+
+:ANDB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF4); opr16a_8
+{
+ B = B & opr16a_8;
+ V_equals_0();
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+}
+
+:ANDB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE4); indexed1_5
+{
+ B = B & indexed1_5;
+ V_equals_0();
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+}
+
+:ANDCC iopr8i is XGATE=0 & Prefix18=0 & (op8=0x10); iopr8i
+{
+ CCR = CCR & iopr8i;
+}
+
+@if defined(HCS12X)
+:ANDX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x84); iopr16i
+{
+ IX = IX & iopr16i;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x94); opr8a_16
+{
+ IX = IX & opr8a_16;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB4); opr16a_16
+{
+ IX = IX & opr16a_16;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA4); indexed2_5
+{
+ IX = IX & indexed2_5;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC4); iopr16i
+{
+ IY = IY & iopr16i;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD4); opr8a_16
+{
+ IY = IY & opr8a_16;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF4); opr16a_16
+{
+ IY = IY & opr16a_16;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ANDY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE4); indexed2_5
+{
+ IY = IY & indexed2_5;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+:ASL opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x78); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ $(C) = tmp[7,1];
+ tmp = tmp << 1;
+ opr16a_8 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASL indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x68); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ $(C) = tmp[7,1];
+ tmp = tmp << 1;
+ indexed1_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASLA is XGATE=0 & Prefix18=0 & op8=0x48
+{
+ $(C) = A[7,1];
+ A = A << 1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASLB is XGATE=0 & Prefix18=0 & op8=0x58
+{
+ $(C) = B[7,1];
+ B = B << 1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASLD is XGATE=0 & Prefix18=0 & op8=0x59
+{
+ $(C) = D[15,1];
+ D = D << 1;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_N_xor_C();
+}
+
+@if defined(HCS12X)
+:ASLW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x78); opr16a_16
+{
+ local tmp = opr16a_16;
+ $(C) = tmp[15,1];
+ tmp = tmp << 1;
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASLW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x68); indexed2_5
+{
+ local tmp = indexed2_5;
+ $(C) = tmp[15,1];
+ tmp = tmp << 1;
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASLX is XGATE=0 & Prefix18=1 & op8=0x48
+{
+ $(C) = IX[15,1];
+ IX = IX << 1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASLY is XGATE=0 & Prefix18=1 & op8=0x58
+{
+ $(C) = IY[15,1];
+ IY = IY << 1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+:ASR opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x77); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ $(C) = tmp[0,1];
+ tmp = tmp s>> 1;
+ opr16a_8 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASR indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x67); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ $(C) = tmp[0,1];
+ tmp = tmp s>> 1;
+ indexed1_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASRA is XGATE=0 & Prefix18=0 & op8=0x47
+{
+ $(C) = A[0,1];
+ A = A s>> 1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_N_xor_C();
+}
+
+:ASRB is XGATE=0 & Prefix18=0 & op8=0x57
+{
+ $(C) = B[0,1];
+ B = B s>> 1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_N_xor_C();
+}
+
+@if defined(HCS12X)
+:ASRW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x77); opr16a_16
+{
+ local tmp = opr16a_16;
+ $(C) = tmp[0,1];
+ tmp = tmp s>> 1;
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASRW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x67); indexed2_5
+{
+ local tmp = indexed2_5;
+ $(C) = tmp[0,1];
+ tmp = tmp s>> 1;
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASRX is XGATE=0 & Prefix18=1 & op8=0x47
+{
+ $(C) = IX[0,1];
+ IX = IX s>> 1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ASRY is XGATE=0 & Prefix18=1 & op8=0x57
+{
+ $(C) = IY[0,1];
+ IY = IY s>> 1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+:BCC rel8 is XGATE=0 & Prefix18=0 & op8=0x24; rel8
+{
+ if ($(C) == 0) goto rel8;
+}
+
+:BCLR opr8a_8, msk8 is XGATE=0 & Prefix18=0 & (op8=0x4D); opr8a_8; msk8
+{
+ op1:1 = opr8a_8;
+ op1 = op1 & ~msk8;
+ opr8a_8 = op1;
+ $(N) = (op1 s< 0);
+ $(Z) = (op1 == 0);
+ V_equals_0();
+}
+
+:BCLR opr16a_8, msk8 is XGATE=0 & Prefix18=0 & (op8=0x1D); opr16a_8; msk8
+{
+ op1:1 = opr16a_8;
+ op1 = op1 & ~msk8;
+ opr16a_8 = op1;
+ $(N) = (op1 s< 0);
+ $(Z) = (op1 == 0);
+ V_equals_0();
+}
+
+:BCLR indexed1_3, msk8 is XGATE=0 & Prefix18=0 & (op8=0x0D); indexed1_3; msk8
+{
+ op1:1 = indexed1_3;
+ op1 = op1 & ~msk8;
+ indexed1_3 = op1;
+ $(N) = (op1 s< 0);
+ $(Z) = (op1 == 0);
+ V_equals_0();
+}
+
+:BCS rel8 is XGATE=0 & Prefix18=0 & op8=0x25; rel8
+{
+ if ($(C) == 1) goto rel8;
+}
+
+:BEQ rel8 is XGATE=0 & Prefix18=0 & op8=0x27; rel8
+{
+ if ($(Z) == 1) goto rel8;
+}
+
+:BGE rel8 is XGATE=0 & Prefix18=0 & op8=0x2C; rel8
+{
+ if (($(N) ^ $(V)) == 1) goto rel8;
+}
+
+@if defined(HCS12)
+:BGND is XGATE=0 & Prefix18=0 & op8=0x00
+{
+ BDM_return:3 = inst_next;
+ # this could return BDM location, or BDM_return
+ PCE = backgroundDebugMode(BDM_return);
+ goto [PCE];
+}
+@endif
+
+:BGT rel8 is XGATE=0 & Prefix18=0 & op8=0x2E; rel8
+{
+ if (($(Z) | ($(N) ^ $(V))) == 0) goto rel8;
+}
+
+:BHI rel8 is XGATE=0 & Prefix18=0 & op8=0x22; rel8
+{
+ if (($(C) | $(Z)) == 0) goto rel8;
+}
+
+#:BHS rel8 is op8=0x24; rel8 See BCC
+
+:BITA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x85); iopr8i
+{
+ result:1 = A & iopr8i;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x95); opr8a_8
+{
+ result:1 = A & opr8a_8;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB5); opr16a_8
+{
+ result:1 = A & opr16a_8;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA5); indexed1_5
+{
+ result:1 = A & indexed1_5;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC5); iopr8i
+{
+ result:1 = B & iopr8i;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD5); opr8a_8
+{
+ result:1 = B & opr8a_8;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF5); opr16a_8
+{
+ result:1 = B & opr16a_8;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+:BITB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE5); indexed1_5
+{
+ result:1 = B & indexed1_5;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+
+@if defined(HCS12X)
+:BITX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x85); iopr16i
+{
+ local result = IX & iopr16i;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x95); opr8a_16
+{
+ local result = IX & opr8a_16;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB5); opr16a_16
+{
+ local result = IX & opr16a_16;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA5); indexed2_5
+{
+ local result = IX & indexed2_5;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC5); iopr16i
+{
+ local result = IY & iopr16i;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD5); opr8a_16
+{
+ local result = IY & opr8a_16;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF5); opr16a_16
+{
+ local result = IY & opr16a_16;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:BITY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE5); indexed2_5
+{
+ local result = IY & indexed2_5;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_0();
+}
+@endif
+
+
+:BLE rel8 is XGATE=0 & Prefix18=0 & op8=0x2F; rel8
+{
+ if ($(Z) | ($(N) ^ $(V))) goto rel8;
+}
+
+#:BLO rel8 is op8=0x25; rel8 see BCS
+
+:BLS rel8 is XGATE=0 & Prefix18=0 & op8=0x23; rel8
+{
+ if (($(C) | $(Z)) == 1) goto rel8;
+}
+
+:BLT rel8 is XGATE=0 & Prefix18=0 & op8=0x2D; rel8
+{
+ if (($(N) ^ $(V)) ==1) goto rel8;
+}
+
+:BMI rel8 is XGATE=0 & Prefix18=0 & op8=0x2B; rel8
+{
+ if ($(N) == 1) goto rel8;
+}
+
+:BNE rel8 is XGATE=0 & Prefix18=0 & op8=0x26; rel8
+{
+ if ($(Z) == 0) goto rel8;
+}
+
+:BPL rel8 is XGATE=0 & Prefix18=0 & op8=0x2A; rel8
+{
+ if ($(N) == 0) goto rel8;
+}
+
+:BRA rel8 is XGATE=0 & Prefix18=0 & op8=0x20; rel8
+{
+ goto rel8;
+}
+
+:BRCLR opr8a_8, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x4F; opr8a_8; msk8; rel8
+{
+ result:1 = opr8a_8 & msk8;
+ if (result == 0) goto rel8;
+}
+
+:BRCLR opr16a_8, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x1F; opr16a_8; msk8; rel8
+{
+ result:1 = opr16a_8 & msk8;
+ if (result == 0) goto rel8;
+}
+
+:BRCLR indexed1_3, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x0F; indexed1_3; msk8; rel8
+{
+ result:1 = indexed1_3 & msk8;
+ if (result == 0) goto rel8;
+}
+
+# branch never is a two-byte nop
+SkipNextInstr: dest is epsilon [ dest = inst_next + 1; ] { export *[RAM]:1 dest; }
+
+:BRN SkipNextInstr is XGATE=0 & Prefix18=0 & op8=0x21 & SkipNextInstr
+{
+ goto SkipNextInstr;
+}
+
+:BRSET opr8a_8, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x4E; opr8a_8; msk8; rel8
+{
+ result:1 = ~opr8a_8 & msk8;
+ if (result != 0) goto rel8;
+}
+
+:BRSET opr16a_8, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x1E; opr16a_8; msk8; rel8
+{
+ result:1 = ~opr16a_8 & msk8;
+ if (result != 0) goto rel8;
+}
+
+:BRSET indexed1_3, msk8, rel8 is XGATE=0 & Prefix18=0 & op8=0x0E; indexed1_3; msk8; rel8
+{
+ result:1 = ~indexed1_3 & msk8;
+ if (result != 0) goto rel8;
+}
+
+:BSET opr8a_8, msk8 is XGATE=0 & Prefix18=0 & op8=0x4C; opr8a_8; msk8
+{
+ result:1 = opr8a_8 | msk8;
+ opr8a_8 = result;
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ V_equals_0();
+}
+
+:BSET opr16a_8, msk8 is XGATE=0 & Prefix18=0 & op8=0x1C; opr16a_8; msk8
+{
+ result:1 = opr16a_8 | msk8;
+ opr16a_8 = result;
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ V_equals_0();
+}
+
+:BSET indexed1_3, msk8 is XGATE=0 & Prefix18=0 & op8=0x0C; indexed1_3; msk8
+{
+ result:1 = indexed1_3 | msk8;
+ indexed1_3 = result;
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ V_equals_0();
+}
+
+:BSR rel8 is XGATE=0 & Prefix18=0 & op8=0x07; rel8
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ call rel8;
+}
+
+@if defined(HCS12X)
+:BTAS opr8a_8, msk8 is XGATE=0 & Prefix18=1 & (op8=0x35); opr8a_8; msk8
+{
+ op1:1 = opr8a_8;
+ tmp:1 = op1 & msk8;
+ $(N) = tmp[7,1];
+ $(Z) = (tmp == 0);
+ $(V) = 0;
+ opr8a_8 = op1 | msk8;
+}
+@endif
+
+@if defined(HCS12X)
+:BTAS opr16a_8, msk8 is XGATE=0 & Prefix18=1 & (op8=0x36); opr16a_8; msk8
+{
+ op1:1 = opr16a_8;
+ tmp:1 = op1 & msk8;
+ $(N) = tmp[7,1];
+ $(Z) = (tmp == 0);
+ $(V) = 0;
+ opr16a_8 = op1 | msk8;
+}
+@endif
+
+@if defined(HCS12X)
+:BTAS indexed1_3, msk8 is XGATE=0 & Prefix18=1 & (op8=0x37); indexed1_3; msk8
+{
+ op1:1 = indexed1_3;
+ tmp:1 = op1 & msk8;
+ $(N) = tmp[7,1];
+ $(Z) = (tmp == 0);
+ $(V) = 0;
+ indexed1_3 = op1 | msk8;
+}
+@endif
+
+
+:BVC rel8 is XGATE=0 & Prefix18=0 & op8=0x28; rel8
+{
+ if ($(V) == 0) goto rel8;
+}
+
+:BVS rel8 is XGATE=0 & Prefix18=0 & op8=0x29; rel8
+{
+ if ($(V) == 1) goto rel8;
+}
+
+CallDest: PageDest, imm8 is (imm16; imm8) & PageDest {
+ PPAGE = imm8;
+
+ build PageDest;
+
+ export PageDest;
+}
+
+:CALL CallDest is XGATE=0 & Prefix18=0 & op8=0x4A; CallDest
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ Push1( PPAGE );
+
+ build CallDest;
+
+ local dest:3 = CallDest;
+ call [dest];
+}
+
+:CALL indexed2_3, page is XGATE=0 & Prefix18=0 & (op8=0x4B); indexed2_3; page
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ Push1( PPAGE );
+ PPAGE = page;
+
+ build indexed2_3;
+
+ local dest:3;
+ GetPagedAddr(indexed2_3,dest);
+ call [dest];
+}
+
+:CALL indexed0_2 is XGATE=0 & Prefix18=0 & (op8=0x4B); indexed0_2
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ Push1( PPAGE );
+ Load1(PPAGE, indexed0_2 + 2);
+
+ local addr:2;
+ Load2(addr,indexed0_2);
+
+ local dest:3;
+ GetPagedAddr(addr,dest);
+ call [dest];
+}
+
+:CBA is XGATE=0 & (Prefix18=1 & op8=0x17)
+{
+ tmp:1 = A - B;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(A, B);
+ $(C) = (B > A);
+}
+
+:CLC is XGATE=0 & Prefix18=0 & op16=0x10FE
+{
+ $(C) = 0;
+}
+
+:CLI is XGATE=0 & Prefix18=0 & op16=0x10EF
+{
+ $(I) = 0;
+}
+
+:CLR opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x79); opr16a_8
+{
+ opr16a_8 = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+
+:CLR indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x69); indexed1_5
+{
+ indexed1_5 = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+
+:CLRA is XGATE=0 & Prefix18=0 & op8=0x87
+{
+ A = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+
+:CLRB is XGATE=0 & Prefix18=0 & op8=0xC7
+{
+ B = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+
+@if defined(HCS12X)
+:CLRW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x79); opr16a_16
+{
+ opr16a_16 = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+@if defined(HCS12X)
+:CLRW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x69); indexed2_5
+{
+ indexed2_5 = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+@if defined(HCS12X)
+:CLRX is XGATE=0 & Prefix18=1 & op8=0x87
+{
+ IX = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+@if defined(HCS12X)
+:CLRY is XGATE=0 & Prefix18=1 & op8=0xC7
+{
+ IY = 0;
+ $(N) = 0;
+ $(Z) = 1;
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+:CLV is XGATE=0 & Prefix18=0 & op16=0x10FD
+{
+ $(V) = 0;
+}
+
+:CMPA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x81); iopr8i
+{
+ op1:1 = iopr8i;
+ tmp:1 = A - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(A, op1);
+ $(C) = (op1 > A);
+}
+
+:CMPA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x91); opr8a_8
+{
+ op1:1 = opr8a_8;
+ tmp:1 = A - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(A, op1);
+ $(C) = (op1 > A);
+}
+
+:CMPA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB1); opr16a_8
+{
+ op1:1 = opr16a_8;
+ tmp:1 = A - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(A, op1);
+ $(C) = (op1 > A);
+}
+
+:CMPA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA1); indexed1_5
+{
+ op1:1 = indexed1_5;
+ tmp:1 = A - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(A, op1);
+ $(C) = (op1 > A);
+}
+
+:CMPB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC1); iopr8i
+{
+ op1:1 = iopr8i;
+ tmp:1 = B - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(B, op1);
+ $(C) = (op1 > B);
+}
+
+:CMPB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD1); opr8a_8
+{
+ op1:1 = opr8a_8;
+ tmp:1 = B - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(B, op1);
+ $(C) = (op1 > B);
+}
+
+:CMPB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF1); opr16a_8
+{
+ op1:1 = opr16a_8;
+ tmp:1 = B - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(B, op1);
+ $(C) = (op1 > B);
+}
+
+:CMPB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE1); indexed1_5
+{
+ op1:1 = indexed1_5;
+ tmp:1 = B - op1;
+ $(N) = (tmp s< 0);
+ $(Z) = (tmp == 0);
+ V_CMP_flag(B, op1);
+ $(C) = (op1 > B);
+}
+
+:COM opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x71); opr16a_8
+{
+ tmp:1 = ~opr16a_8;
+ opr16a_8 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+
+:COM indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x61); indexed1_5
+{
+ tmp:1 = ~indexed1_5;
+ indexed1_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+
+:COMA is XGATE=0 & Prefix18=0 & op8=0x41
+{
+ A = ~A;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+
+:COMB is XGATE=0 & Prefix18=0 & op8=0x51
+{
+ B = ~B;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+
+@if defined(HCS12X)
+:COMW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x71); opr16a_16
+{
+ local tmp = ~opr16a_16;
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:COMW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x61); indexed2_5
+{
+ local tmp = ~indexed2_5;
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:COMX is XGATE=0 & Prefix18=1 & op8=0x41
+{
+ IX = ~IX;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:COMY is XGATE=0 & Prefix18=1 & op8=0x51
+{
+ IY = ~IY;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ $(C) = 1;
+ V_equals_0();
+}
+@endif
+
+:CPD iopr16i is XGATE=0 & Prefix18=0 & (op8=0x8C); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = D - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+
+:CPD opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0x9C); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = D - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+
+:CPD opr16a_16 is XGATE=0 & Prefix18=0 & (op8=0xBC); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = D - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+
+:CPD indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xAC); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = D - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+
+@if defined(HCS12X)
+:CPED iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8C); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = D - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPED opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9C); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = D - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPED opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBC); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = D - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPED indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAC); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = D - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > D);
+ V_CMP_flag(D, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPES iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8F); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = SP - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPES opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9F); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = SP - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPES opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBF); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = SP - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPES indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAF); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = SP - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8E); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = IX - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9E); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = IX - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBE); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = IX - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAE); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = IX - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEY iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8D); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = IY - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9D); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = IY - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBD); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = IY - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+@endif
+
+@if defined(HCS12X)
+:CPEY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAD); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = IY - (op1 + zext($(C)));
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+@endif
+
+SkipNext2Bytes: dest is epsilon [ dest = inst_next + 2; ] { export *[RAM]:1 dest; }
+
+:CPS loc is XGATE=0 & Prefix18=0 & (op8=0x8F) & SkipNext2Bytes [ loc = (inst_next & 0xffffff); ]
+{
+ local addr:3 = inst_next;
+ local op1:2 = *[RAM]:2 addr;
+ tmp:2 = SP - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+ goto SkipNext2Bytes;
+}
+
+:CPS opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0x9F); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = SP - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+
+:CPS loc is XGATE=0 & Prefix18=0 & (op8=0xBF) & SkipNext2Bytes [ loc = (inst_next & 0xffffff); ]
+{
+ local addr:3 = inst_next;
+ local op1:2 = *[RAM]:2 addr;
+ Load2(op1, op1);
+ tmp:2 = SP - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+ goto SkipNext2Bytes;
+}
+
+:CPS indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xAF); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = SP - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > SP);
+ V_CMP_flag(SP, op1);
+}
+
+:CPX iopr16i is XGATE=0 & Prefix18=0 & (op8=0x8E); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = IX - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+
+:CPX opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0x9E); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = IX - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+
+:CPX opr16a_16 is XGATE=0 & Prefix18=0 & (op8=0xBE); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = IX - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+
+:CPX indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xAE); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = IX - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IX);
+ V_CMP_flag(IX, op1);
+}
+
+:CPY iopr16i is XGATE=0 & Prefix18=0 & (op8=0x8D); iopr16i
+{
+ op1:2 = iopr16i;
+ tmp:2 = IY - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+
+:CPY opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0x9D); opr8a_16
+{
+ op1:2 = opr8a_16;
+ tmp:2 = IY - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+
+:CPY opr16a_16 is XGATE=0 & Prefix18=0 & (op8=0xBD); opr16a_16
+{
+ op1:2 = opr16a_16;
+ tmp:2 = IY - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+
+:CPY indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xAD); indexed2_5
+{
+ op1:2 = indexed2_5;
+ tmp:2 = IY - op1;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ $(C) = (op1 > IY);
+ V_CMP_flag(IY, op1);
+}
+
+:DAA is XGATE=0 & Prefix18=1 & op8=0x07
+{
+ A = decimalAdjustAccumulator(A, $(C), $(H));
+ $(C) = decimalAdjustCarry(A, $(C), $(H));
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ #V is undefined
+}
+
+:DBEQ byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x0 & size10_10=0 & byte9_8 & rel9
+{
+ byte9_8 = byte9_8 - 1;
+ if (byte9_8 == 0) goto rel9;
+}
+
+:DBEQ word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x0 & size10_10=1 & word9_8 & rel9
+{
+ word9_8 = word9_8 - 1;
+ if (word9_8 == 0) goto rel9;
+}
+
+:DBNE byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x1 & size10_10=0 & byte9_8 & rel9
+{
+ byte9_8 = byte9_8 - 1;
+ if (byte9_8 != 0) goto rel9;
+}
+
+:DBNE word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x1 & size10_10=1 & word9_8 & rel9
+{
+ word9_8 = word9_8 - 1;
+ if (word9_8 != 0) goto rel9;
+}
+
+:DEC opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x73); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ result:1 = tmp - 1;
+ opr16a_8 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_DEC_flag(tmp);
+}
+
+:DEC indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x63); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:1 = tmp - 1;
+ indexed1_5 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_DEC_flag(tmp);
+}
+
+:DECA is XGATE=0 & Prefix18=0 & op8=0x43
+{
+ tmp:1 = A;
+ A = tmp - 1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_DEC_flag(tmp);
+}
+
+:DECB is XGATE=0 & Prefix18=0 & op8=0x53
+{
+ tmp:1 = B;
+ B = tmp - 1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_DEC_flag(tmp);
+}
+
+@if defined(HCS12X)
+:DECW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x73); opr16a_16
+{
+ local tmp = opr16a_16;
+ local result = tmp - 1;
+ opr16a_16 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_DEC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:DECW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x63); indexed2_5
+{
+ local tmp = indexed2_5;
+ local result = tmp - 1;
+ indexed2_5 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_DEC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:DECX is XGATE=0 & Prefix18=1 & op8=0x43
+{
+ local tmp = IX;
+ IX = tmp - 1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_DEC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:DECY is XGATE=0 & Prefix18=1 & op8=0x53
+{
+ local tmp = IY;
+ IY = tmp - 1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_DEC_flag2(tmp);
+}
+@endif
+
+:DES is XGATE=0 & Prefix18=0 & op16=0x1B9F
+{
+ SP = SP - 1;
+}
+
+:DEX is XGATE=0 & Prefix18=0 & op8=0x09
+{
+ IX = IX - 1;
+ $(Z) = (IX == 0);
+}
+
+:DEY is XGATE=0 & Prefix18=0 & op8=0x03
+{
+ IY = IY - 1;
+ $(Z) = (IY == 0);
+}
+
+:EDIV is XGATE=0 & Prefix18=0 & op8=0x11
+{
+ tmp:4 = (zext(IY) << 16) | (zext(D));
+ resultQ:4 = tmp / zext(IX);
+ resultR:4 = tmp % zext(IX);
+ IY = resultQ:2;
+ D = resultR:2;
+ $(N) = (IY s< 0);
+ $(Z) = (IY == 0);
+ $(V) = (resultQ > 0x0000FFFF);
+ $(C) = (IX == 0);
+}
+
+:EDIVS is XGATE=0 & Prefix18=1 & op8=0x14
+{
+ tmp:4 = (zext(IY) << 16) | (zext(D));
+ resultQ:4 = tmp s/ sext(IX);
+ resultR:4 = tmp s% sext(IX);
+ IY = resultQ:2;
+ D = resultR:2;
+ $(N) = (IY s< 0);
+ $(Z) = (IY == 0);
+ $(V) = (resultQ s> 0x00007FFF) | (resultQ s< 0x00008000);
+ $(C) = (IX == 0);
+}
+
+:EMACS opr16a is XGATE=0 & Prefix18=1 & op8=0x12; opr16a
+{
+ local valx:2 = 0;
+ local valy:2 = 0;
+ Load2(valx,IX);
+ Load2(valy,IY);
+ result:4 = sext(valx) * sext(valy);
+ Store(opr16a, result);
+ $(N) = (result s< 0);
+ $(Z) = (result == 0);
+ $(V) = (result s> 0x000000007FFFFFFF) | (result s< 0x0000000080000000);
+ $(C) = (result > 0x00000000FFFFFFFF);
+}
+
+:EMAXD indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x1A; indexed2_5
+{
+ result:4 = zext(D) - zext(indexed2_5);
+ if (D > indexed2_5) goto ;
+ D = indexed2_5;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x00007FFF) | (result s< 0x00008000);
+ $(C) = (result > 0x0000FFFF);
+}
+
+:EMAXM indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x1E; indexed2_5
+{
+ result:4 = zext(D) - zext(indexed2_5);
+ if (D > indexed2_5) goto ;
+ indexed2_5 = D;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x00007FFF) | (result s< 0x00008000);
+ $(C) = (result > 0x0000FFFF);
+}
+
+:EMIND indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x1B; indexed2_5
+{
+ result:4 = zext(D) - zext(indexed2_5);
+ if (D < indexed2_5) goto ;
+ D = indexed2_5;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x00007FFF) | (result s< 0x00008000);
+ $(C) = (result > 0x0000FFFF);
+}
+
+:EMINM indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x1F; indexed2_5
+{
+ result:4 = zext(D) - zext(indexed2_5);
+ if (D < indexed2_5) goto ;
+ indexed2_5 = D;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x00007FFF) | (result s< 0x00008000);
+ $(C) = (result > 0x0000FFFF);
+}
+
+:EMUL is XGATE=0 & Prefix18=0 & op8=0x13
+{
+ result:4 = zext(D) * zext(IY);
+ IY = result(2);
+ D = result:2;
+ $(N) = result[31,1];
+ $(Z) = (result == 0);
+ $(C) = result[15,1];
+}
+
+:EMULS is XGATE=0 & Prefix18=1 & op8=0x13
+{
+ result:4 = sext(D) * sext(IY);
+ IY = result(2);
+ D = result:2;
+ $(N) = result[31,1];
+ $(Z) = (result == 0);
+ $(C) = result[15,1];
+}
+
+:EORA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x88); iopr8i
+{
+ op1:1 = iopr8i;
+ A = A ^ op1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:EORA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x98); opr8a_8
+{
+ op1:1 = opr8a_8;
+ A = A ^ op1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:EORA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB8); opr16a_8
+{
+ op1:1 = opr16a_8;
+ A = A ^ op1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:EORA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA8); indexed1_5
+{
+ op1:1 = indexed1_5;
+ A = A ^ op1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:EORB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC8); iopr8i
+{
+ op1:1 = iopr8i;
+ B = B ^ op1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:EORB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD8); opr8a_8
+{
+ op1:1 = opr8a_8;
+ B = B ^ op1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:EORB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF8); opr16a_8
+{
+ op1:1 = opr16a_8;
+ B = B ^ op1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:EORB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE8); indexed1_5
+{
+ op1:1 = indexed1_5;
+ B = B ^ op1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+@if defined(HCS12X)
+:EORX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x88); iopr16i
+{
+ local op1 = iopr16i;
+ IX = IX ^ op1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x98); opr8a_16
+{
+ local op1 = opr8a_16;
+ IX = IX ^ op1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB8); opr16a_16
+{
+ local op1 = opr16a_16;
+ IX = IX ^ op1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA8); indexed2_5
+{
+ local op1 = indexed2_5;
+ IX = IX ^ op1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC8); iopr16i
+{
+ local op1 = iopr16i;
+ IY = IY ^ op1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD8); opr8a_16
+{
+ local op1 = opr8a_16;
+ IY = IY ^ op1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+@if defined(HCS12X)
+:EORY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF8); opr16a_16
+{
+ local op1 = opr16a_16;
+ IY = IY ^ op1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+@endif
+
+@if defined(HCS12X)
+:EORY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE8); indexed2_5
+{
+ local op1 = indexed2_5;
+ IY = IY ^ op1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+@endif
+
+:ETBL indexed2_1 is XGATE=0 & Prefix18=1 & op8=0x3F; indexed2_1
+{
+ D = ETBL( indexed2_1, B );
+ $(N) = (D s< 0);
+ $(Z) = (D == 0);
+ $(C) = ETBL_Cflag( indexed2_1, B );
+}
+
+# this case 'C0' or 'C8', does not display similarly to other members of either its row or column
+:EXG D, A is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x0 & ( columns7_4=0xC ) ) |
+
+ ( rows3_0=0x8 & ( columns7_4=0xC ) )
+ ) &
+ D & A
+{
+ tmp:1 = B;
+ B = A;
+ A = tmp;
+}
+
+# this case 'C1' or 'C9', does not work similarly to other members of either its row or column
+:EXG D, B is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x1 & ( columns7_4=0xC ) ) |
+
+ ( rows3_0=0x9 & ( columns7_4=0xC ) )
+ ) &
+ D & B
+{
+ B = B;
+ A = 0xFF;
+}
+
+# this case '84' or '8C', does not work similarly to other members of either its row or column
+:EXG A, D is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x4 & ( columns7_4=0x8 ) ) |
+
+ ( rows3_0=0xC & ( columns7_4=0x8 ) )
+ ) &
+ A & D
+{
+ D = zext(A);
+}
+
+# this case '94' or '9C', does not work similarly to other members of either its row or column
+:EXG B, D is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x4 & ( columns7_4=0x9 ) ) |
+
+ ( rows3_0=0xC & ( columns7_4=0x9 ) )
+ ) &
+ B & D
+{
+ D = zext(B);
+}
+
+# this case 'A8', does not work the same as 'A0'
+:EXG CCRH, A is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x8 & ( columns7_4=0xA ) )
+ ) &
+ CCRH & A
+{
+ tmp:1 = CCRH;
+ CCRH = A;
+ A = tmp;
+}
+
+# this case '8A', does not work the same as '82'
+:EXG A, CCRH is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xA & ( columns7_4=0x8 ) )
+ ) &
+ A & CCRH
+{
+ tmp:1 = A;
+ A = CCRH;
+ CCRH = tmp;
+}
+
+# this case 'AA', does not display the same as 'A2'
+:EXG CCRW, "CCRW" is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xA & ( columns7_4=0xA ) )
+ ) &
+ CCRW
+{
+ CCRW = CCRW;
+}
+
+:EXG bytes_ABCl_6_4, bytes_ABCl_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x0 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+ ( rows3_0=0x1 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+
+ ( rows3_0=0x8 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+ ( rows3_0=0x9 & ( columns7_4=0x8 | columns7_4=0x9 ) )
+ ) &
+ bytes_ABCl_6_4 & bytes_ABCl_2_0
+{
+ tmp:1 = bytes_ABCl_2_0;
+ bytes_ABCl_2_0 = bytes_ABCl_6_4;
+ bytes_ABCl_6_4 = tmp;
+}
+
+:EXG bytes_ABCl_6_4, CCR is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x2 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+
+ ( rows3_0=0xA & ( columns7_4=0x9 ) )
+ ) &
+ bytes_ABCl_6_4 & CCR
+{
+ tmp:1 = bytes_ABCl_6_4;
+ bytes_ABCl_6_4 = CCR;
+ setCCR( tmp );
+}
+
+:EXG CCR, bytes_ABCl_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x0 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x1 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x2 & ( columns7_4=0xA ) ) |
+
+ ( rows3_0=0x9 & ( columns7_4=0xA ) )
+ ) &
+ CCR & bytes_ABCl_2_0
+{
+ tmp:1 = bytes_ABCl_2_0;
+ bytes_ABCl_2_0 = CCR;
+ setCCR( tmp );
+}
+
+:EXG bytes_T3l_XlYlSl_6_4, A is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x0 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ bytes_T3l_XlYlSl_6_4 & words_T3_XYS_6_4 & A
+{
+ tmp:2 = zext(A);
+ A = bytes_T3l_XlYlSl_6_4;
+ words_T3_XYS_6_4 = tmp;
+}
+
+:EXG bytes_T3h_XhYhSh_6_4, A is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x8 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ bytes_T3h_XhYhSh_6_4 & words_T3_XYS_6_4 & A
+{
+ tmp:2 = zext(A);
+ A = bytes_T3h_XhYhSh_6_4;
+ words_T3_XYS_6_4 = tmp;
+}
+
+:EXG bytes_T3l_XlYlSl_6_4, B is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x1 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ bytes_T3l_XlYlSl_6_4 & words_T3_XYS_6_4 & B
+{
+ tmp:2 = 0xFF00 | zext(B);
+ B = bytes_T3l_XlYlSl_6_4;
+ words_T3_XYS_6_4 = tmp;
+}
+
+:EXG bytes_T3l_XlYlSl_6_4, B is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x9 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ bytes_T3l_XlYlSl_6_4 & B
+{
+ tmp:1 = B;
+ B = bytes_T3l_XlYlSl_6_4;
+ bytes_T3l_XlYlSl_6_4 = tmp;
+}
+
+:EXG bytes_T3lDlXlYlSl_6_4, CCR is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x2 & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ bytes_T3lDlXlYlSl_6_4 & words_T3DXYS_6_4 & CCR
+{
+ tmp:2 = 0xFF00 | zext(CCR);
+ # when CCR is the destination, cannot set the X bit unless it is already set in CCR
+ setCCR( bytes_T3lDlXlYlSl_6_4 );
+ words_T3DXYS_6_4 = tmp;
+}
+
+:EXG words_T3DXYS_6_4, CCRW is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xA & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ words_T3DXYS_6_4 & CCRW
+{
+ tmp:2 = CCRW;
+ setCCRW( words_T3DXYS_6_4 );
+ words_T3DXYS_6_4 = tmp;
+}
+
+# this case 'CB', does not work similarly to other members of either its row or column
+:EXG D, TMP1 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0xC ) )
+ ) &
+ D & TMP1
+{
+ tmp:2 = D;
+ D = TMP1;
+ TMP1 = tmp;
+}
+
+# this case 'BC', does not work similarly to other members of either its row or column
+:EXG TMP1, D is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xC & ( columns7_4=0xB ) )
+ ) &
+ TMP1 & D
+{
+ tmp:2 = TMP1;
+ TMP1 = D;
+ D = tmp;
+}
+
+:EXG words_T3DXYS_6_4, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+# Case "C5" is handled by XGDX
+# Case "C6" is handled by XGDY
+ ( rows3_0=0x3 & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0x4 & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0x5 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0x6 & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0x7 & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+
+ ( rows3_0=0xB & ( columns7_4=0xB | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0xC & ( columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0xD & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0xE & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) ) |
+ ( rows3_0=0xF & ( columns7_4=0xB | columns7_4=0xC | columns7_4=0xD | columns7_4=0xE | columns7_4=0xF ) )
+ ) &
+ words_T3DXYS_6_4 & words_T2DXYS_2_0
+{
+ tmp:2 = words_T3DXYS_6_4;
+ words_T3DXYS_6_4 = words_T2DXYS_2_0;
+ words_T2DXYS_2_0 = tmp;
+}
+
+:EXG bytes_ABCl_6_4, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x3 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+
+ ( rows3_0=0x5 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+ ( rows3_0=0x6 & ( columns7_4=0x8 | columns7_4=0x9 ) ) |
+ ( rows3_0=0x7 & ( columns7_4=0x8 | columns7_4=0x9 ) )
+ ) &
+ bytes_ABCl_6_4 & words_T2DXYS_2_0 & bytes_T2lDlXlYlSl_2_0
+{
+ tmp:2 = zext(bytes_ABCl_6_4);
+ bytes_ABCl_6_4 = bytes_T2lDlXlYlSl_2_0;
+ words_T2DXYS_2_0 = tmp;
+}
+
+:EXG bytes_ABCl_6_4, bytes_T2hDhXhYhSh_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x8 ) ) |
+
+ ( rows3_0=0xD & ( columns7_4=0x8 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x8 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x8 ) )
+ ) &
+ bytes_ABCl_6_4 & bytes_T2hDhXhYhSh_2_0
+{
+ tmp:1 = bytes_ABCl_6_4;
+ bytes_ABCl_6_4 = bytes_T2hDhXhYhSh_2_0;
+ bytes_T2hDhXhYhSh_2_0 = tmp;
+}
+
+# only column 9 with rows B, (skip C), D, E, and F
+:EXG bytes_ABCl_6_4, bytes_T2lDlXlYlSl_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x9 ) ) |
+
+ ( rows3_0=0xD & ( columns7_4=0x9 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x9 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x9 ) )
+ ) &
+ bytes_ABCl_6_4 & bytes_T2lDlXlYlSl_2_0
+{
+ tmp:1 = bytes_ABCl_6_4;
+ bytes_ABCl_6_4 = bytes_T2lDlXlYlSl_2_0;
+ bytes_T2lDlXlYlSl_2_0 = tmp;
+}
+
+:EXG CCR, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x3 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x4 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x5 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x6 & ( columns7_4=0xA ) ) |
+ ( rows3_0=0x7 & ( columns7_4=0xA ) )
+ ) &
+ CCR & words_T2DXYS_2_0 & bytes_T2lDlXlYlSl_2_0
+{
+ tmp:2 = zext(CCR);
+ setCCR( bytes_T2lDlXlYlSl_2_0 );
+ words_T2DXYS_2_0 = tmp;
+}
+
+:EXG CCRW, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0xA ) ) |
+ ( rows3_0=0xC & ( columns7_4=0xA ) ) |
+ ( rows3_0=0xD & ( columns7_4=0xA ) ) |
+ ( rows3_0=0xE & ( columns7_4=0xA ) ) |
+ ( rows3_0=0xF & ( columns7_4=0xA ) )
+ ) &
+ CCRW & words_T2DXYS_2_0
+{
+ tmp:2 = CCRW;
+ setCCRW( words_T2DXYS_2_0 );
+ words_T2DXYS_2_0 = tmp;
+}
+
+:FDIV is XGATE=0 & Prefix18=1 & op8=0x11
+{
+ $(V) = (IX <= D);
+ $(C) = (IX == 0);
+ tmp:4 = (zext(D) << 16);
+ resultQ:4 = tmp / zext(IX);
+ resultR:4 = tmp % zext(IX);
+ IX = resultQ:2;
+ D = resultR:2;
+ $(Z) = (IX == 0);
+}
+
+#:GLDAA is op16=0x1896 See GPAGE extended LDAA
+#:GLDAA is op16=0x18B6 See GPAGE extended LDAA
+#:GLDAA is op16=0x18A6 See GPAGE extended LDAA
+
+#:GLDAB is op16=0x18D6 See GPAGE extended LDAB
+#:GLDAB is op16=0x18F6 See GPAGE extended LDAB
+#:GLDAB is op16=0x18E6 See GPAGE extended LDAB
+
+#:GLDD is op16=0x18DC See GPAGE extended LDD
+#:GLDD is op16=0x18FC See GPAGE extended LDD
+#:GLDD is op16=0x18EC See GPAGE extended LDD
+
+#:GLDS is op16=0x18DF See GPAGE extended LDS
+#:GLDS is op16=0x18FF See GPAGE extended LDS
+#:GLDS is op16=0x18EF See GPAGE extended LDS
+
+#:GLDX is op16=0x18DE See GPAGE extended LDX
+#:GLDX is op16=0x18FE See GPAGE extended LDX
+#:GLDX is op16=0x18EE See GPAGE extended LDX
+
+#:GLDY is op16=0x18DD See GPAGE extended LDY
+#:GLDY is op16=0x18FD See GPAGE extended LDY
+#:GLDY is op16=0x18ED See GPAGE extended LDY
+
+#:GSTAA is op16=0x185A See GPAGE extended STAA
+#:GSTAA is op16=0x187A See GPAGE extended STAA
+#:GSTAA is op16=0x186A See GPAGE extended STAA
+
+#:GSTAB is op16=0x185B See GPAGE extended STAB
+#:GSTAB is op16=0x187B See GPAGE extended STAB
+#:GSTAB is op16=0x186B See GPAGE extended STAB
+
+#:GSTD is op16=0x185C See GPAGE extended STD
+#:GSTD is op16=0x187C See GPAGE extended STD
+#:GSTD is op16=0x186C See GPAGE extended STD
+
+#:GSTS is op16=0x185F See GPAGE extended STS
+#:GSTS is op16=0x187F See GPAGE extended STS
+#:GSTS is op16=0x186F See GPAGE extended STS
+
+#:GSTX is op16=0x185E See GPAGE extended STX
+#:GSTX is op16=0x187E See GPAGE extended STX
+#:GSTX is op16=0x186E See GPAGE extended STX
+
+#:GSTY is op16=0x185D See GPAGE extended STY
+#:GSTY is op16=0x187D See GPAGE extended STY
+#:GSTY is op16=0x186D See GPAGE extended STY
+
+
+:IBEQ byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x4 & size10_10=0 & byte9_8 & rel9
+{
+ byte9_8 = byte9_8 + 1;
+ if (byte9_8 == 0) goto rel9;
+}
+
+:IBEQ word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x4 & size10_10=1 & word9_8 & rel9
+{
+ word9_8 = word9_8 + 1;
+ if (word9_8 == 0) goto rel9;
+}
+
+:IBNE byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x5 & size10_10=0 & byte9_8 & rel9
+{
+ byte9_8 = byte9_8 + 1;
+ if (byte9_8 != 0) goto rel9;
+}
+
+:IBNE word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x5 & size10_10=1 & word9_8 & rel9
+{
+ word9_8 = word9_8 + 1;
+ if (word9_8 != 0) goto rel9;
+}
+
+:IDIV is XGATE=0 & Prefix18=1 & op8=0x10
+{
+ $(C) = (IX == 0);
+ resultQ:2 = D / IX;
+ resultR:2 = D % IX;
+ IX = resultQ;
+ D = resultR;
+ $(Z) = (IX == 0);
+ $(V) = 0;
+}
+
+:IDIVS is XGATE=0 & Prefix18=1 & op8=0x15
+{
+ $(C) = (IX == 0);
+ resultQ:4 = sext(D) s/ sext(IX);
+ resultR:4 = sext(D) s% sext(IX);
+ IX = resultQ:2;
+ D = resultR:2;
+ $(N) = (IX s< 0);
+ $(Z) = (IX == 0);
+ $(V) = (resultQ s> 0x00007FFF) | (resultQ s< 0x00008000);
+}
+
+:INC opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x72); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ result:1 = tmp + 1;
+ opr16a_8 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_INC_flag(tmp);
+}
+
+:INC indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x62); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:1 = tmp + 1;
+ indexed1_5 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_INC_flag(tmp);
+}
+
+:INCA is XGATE=0 & Prefix18=0 & op8=0x42
+{
+ tmp:1 = A;
+ A = tmp + 1;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_INC_flag(tmp);
+}
+
+:INCB is XGATE=0 & Prefix18=0 & op8=0x52
+{
+ tmp:1 = B;
+ B = tmp + 1;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_INC_flag(tmp);
+}
+
+@if defined(HCS12X)
+:INCW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x72); opr16a_16
+{
+ tmp:2 = opr16a_16;
+ result:2 = tmp + 1;
+ opr16a_16 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_INC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:INCW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x62); indexed2_5
+{
+ tmp:2 = indexed2_5;
+ result:2 = tmp + 1;
+ indexed2_5 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_INC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:INCX is XGATE=0 & Prefix18=1 & op8=0x42
+{
+ local tmp = IX;
+ IX = tmp + 1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_INC_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:INCY is XGATE=0 & Prefix18=1 & op8=0x52
+{
+ local tmp = IY;
+ IY = tmp + 1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_INC_flag2(tmp);
+}
+@endif
+
+:INS is XGATE=0 & Prefix18=0 & op16=0x1B81
+{
+ SP = SP + 1;
+}
+
+:INX is XGATE=0 & Prefix18=0 & op8=0x08
+{
+ IX = IX + 1;
+ $(Z) = (IX == 0);
+}
+
+:INY is XGATE=0 & Prefix18=0 & op8=0x02
+{
+ IY = IY + 1;
+ $(Z) = (IY == 0);
+}
+
+:JMP opr16a is XGATE=0 & Prefix18=0 & (op8=0x06); opr16a
+{
+ local target = opr16a;
+ goto [target];
+}
+
+:JMP indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0x05); indexed2_5
+{
+ goto [indexed2_5];
+}
+
+:JSR opr8a is XGATE=0 & Prefix18=0 & (op8=0x17); opr8a
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ local target = opr8a;
+ call [target];
+}
+
+:JSR opr16a is XGATE=0 & Prefix18=0 & (op8=0x16); opr16a
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ local target = opr16a;
+ call [target];
+}
+
+:JSR indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0x15); indexed2_5
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+
+ call [indexed2_5];
+}
+
+:LBCC rel16 is XGATE=0 & Prefix18=1 & op8=0x24; rel16
+{
+ if ($(C) == 0) goto rel16;
+}
+
+:LBCS rel16 is XGATE=0 & Prefix18=1 & op8=0x25; rel16
+{
+ if ($(C) == 1) goto rel16;
+}
+
+:LBEQ rel16 is XGATE=0 & Prefix18=1 & op8=0x27; rel16
+{
+ if ($(Z) == 1) goto rel16;
+}
+
+:LBGE rel16 is XGATE=0 & Prefix18=1 & op8=0x2C; rel16
+{
+ if (($(N) ^ $(V)) == 1) goto rel16;
+}
+
+:LBGT rel16 is XGATE=0 & Prefix18=1 & op8=0x2E; rel16
+{
+ if (($(Z) | ($(N) ^ $(V))) == 0) goto rel16;
+}
+
+:LBHI rel16 is XGATE=0 & Prefix18=1 & op8=0x22; rel16
+{
+ if (($(C) | $(Z)) == 0) goto rel16;
+}
+
+#:LBHS rel16 is XGATE=0 & Prefix18=1 & op8=0x24; rel16 See LBCC
+
+:LBLE rel16 is XGATE=0 & Prefix18=1 & op8=0x2F; rel16
+{
+ if ($(Z) | ($(N) ^ $(V))) goto rel16;
+}
+
+#:LBLO rel16 is XGATE=0 & Prefix18=1 & op8=0x25; rel16 see LBCS
+
+:LBLS rel16 is XGATE=0 & Prefix18=1 & op8=0x23; rel16
+{
+ if (($(C) | $(Z)) == 1) goto rel16;
+}
+
+:LBLT rel16 is XGATE=0 & Prefix18=1 & op8=0x2D; rel16
+{
+ if (($(N) ^ $(V)) == 1) goto rel16;
+}
+
+:LBMI rel16 is XGATE=0 & Prefix18=1 & op8=0x2B; rel16
+{
+ if ($(N) == 1) goto rel16;
+}
+
+:LBNE rel16 is XGATE=0 & Prefix18=1 & op8=0x26; rel16
+{
+ if ($(Z) == 0) goto rel16;
+}
+
+:LBPL rel16 is XGATE=0 & Prefix18=1 & op8=0x2A; rel16
+{
+ if ($(N) == 0) goto rel16;
+}
+
+:LBRA rel16 is XGATE=0 & Prefix18=1 & op8=0x20; rel16
+{
+ goto rel16;
+}
+
+# branch never is a four-byte nop
+:LBRN rel16 is XGATE=0 & Prefix18=1 & op8=0x21; rel16
+{
+}
+
+:LBVC rel16 is XGATE=0 & Prefix18=1 & op8=0x28; rel16
+{
+ if ($(V) == 0) goto rel16;
+}
+
+:LBVS rel16 is XGATE=0 & Prefix18=1 & op8=0x29; rel16
+{
+ if ($(V) == 1) goto rel16;
+}
+
+:LDAA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x86); iopr8i
+{
+ A = iopr8i;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+GPaged: "G" is XGATE=0 & Prefix18=1 [ UseGPAGE=1; ] {}
+GPaged: is XGATE=0 & Prefix18=0 [ UseGPAGE=0; ] {}
+
+:^GPaged^"LDAA" opr8a_8 is XGATE=0 & GPaged & (op8=0x96); opr8a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ A = opr8a_8;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDAA" opr16a_8 is XGATE=0 & GPaged & (op8=0xB6); opr16a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ A = opr16a_8;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDAA" indexed1_5 is XGATE=0 & GPaged & (op8=0xA6); indexed1_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ A = indexed1_5;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:LDAB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC6); iopr8i
+{
+ B = iopr8i;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDAB" opr8a_8 is XGATE=0 & GPaged & (op8=0xD6); opr8a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ B = opr8a_8;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDAB" opr16a_8 is XGATE=0 & GPaged & (op8=0xF6); opr16a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ B = opr16a_8;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDAB" indexed1_5 is XGATE=0 & GPaged & (op8=0xE6); indexed1_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ B = indexed1_5;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:LDD iopr16i is XGATE=0 & Prefix18=0 & (op8=0xCC); iopr16i
+{
+ D = iopr16i;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDD" opr8a_16 is XGATE=0 & GPaged & (op8=0xDC); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ D = opr8a_16;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDD" opr16a_16 is XGATE=0 & GPaged & (op8=0xFC); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ D = opr16a_16;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDD" indexed2_5 is XGATE=0 & GPaged & (op8=0xEC); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ D = indexed2_5;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+
+define pcodeop LoadStack;
+
+:LDS iopr16i is XGATE=0 & Prefix18=0 & (op8=0xCF); iopr16i
+{
+ SP = LoadStack(iopr16i);
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDS" opr8a_16 is XGATE=0 & GPaged & (op8=0xDF); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ SP = LoadStack(opr8a_16);
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDS" opr16a_16 is XGATE=0 & GPaged & (op8=0xFF); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ SP = LoadStack(opr16a_16);
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDS" indexed2_5 is XGATE=0 & GPaged & (op8=0xEF); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ SP = LoadStack(indexed2_5);
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:LDX iopr16i is XGATE=0 & Prefix18=0 & (op8=0xCE); iopr16i
+{
+ IX = iopr16i;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDX" opr8a_16 is XGATE=0 & GPaged & (op8=0xDE); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IX = opr8a_16;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDX" opr16a_16 is XGATE=0 & GPaged & (op8=0xFE); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IX = opr16a_16;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDX" indexed2_5 is XGATE=0 & GPaged & (op8=0xEE); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IX = indexed2_5;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:LDY iopr16i is XGATE=0 & Prefix18=0 & (op8=0xCD); iopr16i
+{
+ IY = iopr16i;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDY" opr8a_16 is XGATE=0 & GPaged & (op8=0xDD); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IY = opr8a_16;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDY" opr16a_16 is XGATE=0 & GPaged & (op8=0xFD); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IY = opr16a_16;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"LDY" indexed2_5 is XGATE=0 & GPaged & (op8=0xED); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ IY = indexed2_5;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:LEAS indexed0_3 is XGATE=0 & Prefix18=0 & (op8=0x1B); indexed0_3
+{
+ SP = indexed0_3;
+}
+
+:LEAX indexed0_3 is XGATE=0 & Prefix18=0 & (op8=0x1A); indexed0_3
+{
+ IX = indexed0_3;
+}
+
+:LEAY indexed0_3 is XGATE=0 & Prefix18=0 & (op8=0x19); indexed0_3
+{
+ IY = indexed0_3;
+}
+
+## Logical Shift left is same as arithmetic shift left
+#:LSL is (op8=0x68 | op8=0x78)
+#:LSLA is op8=0x48
+#:LSLB is op8=0x58
+#:LSLD is op8=0x59
+
+#:LSLW is op16=0x1878 | op16=0x1868 see ASLW
+#:LSLX is op16=0x1848 see ASLX
+#:LSLY is op16=0x1858 see ASLY
+
+:LSR opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x74); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ $(C) = tmp & 1;
+ tmp = tmp >> 1;
+ opr16a_8 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = 0;
+ V_equals_C();
+}
+
+:LSR indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x64); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ $(C) = tmp & 1;
+ tmp = tmp >> 1;
+ indexed1_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = 0;
+ V_equals_C();
+}
+
+:LSRA is XGATE=0 & Prefix18=0 & op8=0x44
+{
+ $(C) = A[0,1];
+ A = (A >> 1);
+ $(Z) = (A == 0);
+ $(N) = 0;
+ V_equals_C();
+}
+
+:LSRB is XGATE=0 & Prefix18=0 & op8=0x54
+{
+ $(C) = B[0,1];
+ B = (B >> 1);
+ $(Z) = (B == 0);
+ $(N) = 0;
+ V_equals_C();
+}
+
+:LSRD is XGATE=0 & Prefix18=0 & op8=0x49
+{
+ $(C) = D[0,1];
+ D = (D >> 1);
+ $(Z) = (D == 0);
+ $(N) = 0;
+ V_equals_C();
+}
+
+@if defined(HCS12X)
+:LSRW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x74); opr16a_16
+{
+ local tmp = opr16a_16;
+ $(C) = tmp[0,1];
+ tmp = tmp >> 1;
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:LSRW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x64); indexed2_5
+{
+ local tmp = indexed2_5;
+ $(C) = tmp[0,1];
+ tmp = tmp >> 1;
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:LSRX is XGATE=0 & Prefix18=1 & op8=0x44
+{
+ $(C) = IX[0,1];
+ IX = IX >> 1;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:LSRY is XGATE=0 & Prefix18=1 & op8=0x54
+{
+ $(C) = IY[0,1];
+ IY = IY >> 1;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+:MAXA indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x18; indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:2 = zext(A) - zext(tmp);
+ if (A > tmp) goto ;
+ A = tmp;
+
+
+ $(N) = (result:1 s< 0);
+ $(Z) = (result:1 == 0);
+ $(V) = (result s> 0x007F) | (result s< 0x0080);
+ $(C) = (result > 0x00FF);
+}
+
+:MAXM indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x1C; indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:4 = zext(A) - zext(tmp);
+ if (tmp > A) goto ;
+ indexed1_5 = A;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x007F) | (result s< 0x0080);
+ $(C) = (result > 0x00FF);
+}
+
+:MEM is XGATE=0 & Prefix18=0 & op8=0x01
+{
+ local val:1 = GradeOfMembership(A, IX, IY);
+ Store(IY, val);
+ IY = IY + 1;
+ IX = IX + 4;
+}
+
+:MINA indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x19; indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:2 = zext(A) - zext(tmp);
+ if (A < tmp) goto ;
+ A = tmp;
+
+
+ $(N) = (result:1 s< 0);
+ $(Z) = (result:1 == 0);
+ $(V) = (result s> 0x007F) | (result s< 0x0080);
+ $(C) = (result > 0x00FF);
+}
+
+:MINM indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x1D; indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:4 = zext(A) - zext(tmp);
+ if (tmp < A) goto ;
+ indexed1_5 = A;
+
+
+ $(N) = (result:2 s< 0);
+ $(Z) = (result:2 == 0);
+ $(V) = (result s> 0x007F) | (result s< 0x0080);
+ $(C) = (result > 0x00FF);
+}
+
+:MOVB iopr8i, opr16a_8 is XGATE=0 & Prefix18=1 & op8=0x0B; iopr8i; opr16a_8
+{
+ opr16a_8 = iopr8i;
+}
+
+@if defined(HCS12X)
+:MOVB iopr8i, indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x08; indexed1_5; iopr8i
+{
+ indexed1_5 = iopr8i;
+}
+@else
+:MOVB iopr8i, indexed1_1 is XGATE=0 & Prefix18=1 & op8=0x08; indexed1_1; iopr8i
+{
+ indexed1_1 = iopr8i;
+}
+@endif
+
+:MOVB opr16a_8, op2_opr16a_8 is XGATE=0 & Prefix18=1 & op8=0x0C; opr16a_8; op2_opr16a_8
+{
+ build opr16a_8;
+ local tmp = opr16a_8;
+ build op2_opr16a_8;
+ op2_opr16a_8 = tmp;
+}
+
+@if defined(HCS12X)
+:MOVB opr16a_8, indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x09; indexed1_5; opr16a_8
+{
+ indexed1_5 = opr16a_8;
+}
+@else
+:MOVB opr16a_8, indexed1_1 is XGATE=0 & Prefix18=1 & op8=0x09; indexed1_1; opr16a_8
+{
+ indexed1_1 = opr16a_8;
+}
+@endif
+
+@if defined(HCS12X)
+:MOVB indexed1_5, opr16a_8 is XGATE=0 & Prefix18=1 & op8=0x0D; indexed1_5; opr16a_8
+{
+ opr16a_8 = indexed1_5;
+}
+@else
+:MOVB indexed1_1, opr16a_8 is XGATE=0 & Prefix18=1 & op8=0x0D; indexed1_1; opr16a_8
+{
+ opr16a_8 = indexed1_1;
+}
+@endif
+
+@if defined(HCS12X)
+:MOVB indexed1_5, op2_indexed1_5 is XGATE=0 & Prefix18=1 & op8=0x0A; indexed1_5; op2_indexed1_5
+{
+ # two operands share a lower level subconstructor
+ # MUST do the builds and store the value, or the first operands results will be overwritten
+ build indexed1_5;
+ local tmp = indexed1_5;
+ build op2_indexed1_5;
+ op2_indexed1_5 = tmp;
+}
+@else
+:MOVB indexed1_1, op2_indexed1_1 is XGATE=0 & Prefix18=1 & op8=0x0A; indexed1_1; op2_indexed1_1
+{
+ # two operands share a lower level subconstructor
+ # MUST do the builds and store the value, or the first operands results will be overwritten
+ build indexed1_1;
+ local tmp = indexed1_1;
+ build op2_indexed1_1;
+ op2_indexed1_1 = tmp;
+}
+@endif
+
+:MOVW iopr16i, opr16a_16 is XGATE=0 & Prefix18=1 & op8=0x03; iopr16i; opr16a_16
+{
+ opr16a_16 = iopr16i;
+}
+
+@if defined(HCS12X)
+:MOVW iopr16i, indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x00; indexed2_5; iopr16i
+{
+ indexed2_5 = iopr16i;
+}
+@else
+:MOVW iopr16i, indexed2_1 is XGATE=0 & Prefix18=1 & op8=0x00; indexed2_1; iopr16i
+{
+ indexed2_1 = iopr16i;
+}
+@endif
+
+:MOVW opr16a_16, op2_opr16a_16 is XGATE=0 & Prefix18=1 & op8=0x04; opr16a_16; op2_opr16a_16
+{
+ # two operands share a lower level subconstructor
+ # MUST do the builds and store the value, or the first operands results will be overwritten
+ build opr16a_16;
+ local tmp = opr16a_16;
+ build op2_opr16a_16;
+ op2_opr16a_16 = tmp;
+}
+
+@if defined(HCS12X)
+:MOVW opr16a_16, indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x01; indexed2_5; opr16a_16
+{
+ indexed2_5 = opr16a_16;
+}
+@else
+:MOVW opr16a_16, indexed2_1 is XGATE=0 & Prefix18=1 & op8=0x01; indexed2_1; opr16a_16
+{
+ indexed2_1 = opr16a_16;
+}
+@endif
+
+@if defined(HCS12X)
+:MOVW indexed2_5, opr16a_16 is XGATE=0 & Prefix18=1 & op8=0x05; indexed2_5; opr16a_16
+{
+ opr16a_16 = indexed2_5;
+}
+@else
+:MOVW indexed2_1, opr16a_16 is XGATE=0 & Prefix18=1 & op8=0x05; indexed2_1; opr16a_16
+{
+ opr16a_16 = indexed2_1;
+}
+@endif
+
+@if defined(HCS12X)
+:MOVW indexed2_5, op2_indexed2_5 is XGATE=0 & Prefix18=1 & op8=0x02; indexed2_5; op2_indexed2_5
+{
+ # two operands share a lower level subconstructor
+ # MUST do the builds and store the value, or the first operands results will be overwritten
+ build indexed2_5;
+ local tmp = indexed2_5;
+ build op2_indexed2_5;
+ op2_indexed2_5 = tmp;
+}
+@else
+:MOVW indexed2_1, op2_indexed2_1 is XGATE=0 & Prefix18=1 & op8=0x02; indexed2_1; op2_indexed2_1
+{
+ # two operands share a lower level subconstructor
+ # MUST do the builds and store the value, or the first operands results will be overwritten
+ build indexed2_1;
+ local tmp = indexed2_1;
+ build op2_indexed2_1;
+ op2_indexed2_1 = tmp;
+}
+@endif
+
+
+:MUL is XGATE=0 & Prefix18=0 & op8=0x12
+{
+ D = zext(A) * zext(B);
+ $(C) = B[7,1];
+}
+
+:NEG opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x70); opr16a_8
+{
+ tmp:1 = opr16a_8;
+ result:1 = -tmp;
+ opr16a_8 = result;
+ $(C) = (result != 0);
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_NEG_flag(tmp);
+}
+
+:NEG indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x60); indexed1_5
+{
+ tmp:1 = indexed1_5;
+ result:1 = -tmp;
+ indexed1_5 = result;
+ $(C) = (result != 0);
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_NEG_flag(tmp);
+}
+
+:NEGA is XGATE=0 & Prefix18=0 & op8=0x40
+{
+ tmp:1 = A;
+ A = -tmp;
+ $(C) = (A != 0);
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_NEG_flag(tmp);
+}
+
+:NEGB is XGATE=0 & Prefix18=0 & op8=0x50
+{
+ tmp:1 = B;
+ B = -tmp;
+ $(C) = (B != 0);
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_NEG_flag(tmp);
+}
+
+@if defined(HCS12X)
+:NEGW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x70); opr16a_16
+{
+ tmp:2 = opr16a_16;
+ result:2 = -tmp;
+ opr16a_16 = result;
+ $(C) = (result != 0);
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_NEG_flag2(tmp);
+}
+
+@if defined(HCS12X)
+:NEGW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x60); indexed2_5
+{
+ tmp:2 = indexed2_5;
+ result:2 = -tmp;
+ indexed2_5 = result;
+ $(C) = (result != 0);
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_NEG_flag2(tmp);
+}
+@endif
+
+@if defined(HCS12X)
+:NEGX is XGATE=0 & Prefix18=1 & op8=0x40
+{
+ tmp:2 = IX;
+ IX = -tmp;
+ $(C) = (IX != 0);
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_NEG_flag2(tmp);
+}
+@endif
+
+:NEGY is XGATE=0 & Prefix18=1 & op8=0x50
+{
+ tmp:2 = IY;
+ IY = -tmp;
+ $(C) = (IY != 0);
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_NEG_flag2(tmp);
+}
+@endif
+
+:NOP is XGATE=0 & Prefix18=0 & op8=0xA7
+{
+}
+
+:ORAA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x8A); iopr8i
+{
+ A = A | iopr8i;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:ORAA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x9A); opr8a_8
+{
+ A = A | opr8a_8;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:ORAA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xBA); opr16a_8
+{
+ A = A | opr16a_8;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:ORAA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xAA); indexed1_5
+{
+ A = A | indexed1_5;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:ORAB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xCA); iopr8i
+{
+ B = B | iopr8i;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:ORAB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xDA); opr8a_8
+{
+ B = B | opr8a_8;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:ORAB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xFA); opr16a_8
+{
+ B = B | opr16a_8;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:ORAB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xEA); indexed1_5
+{
+ B = B | indexed1_5;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:ORCC iopr8i is XGATE=0 & Prefix18=0 & (op8=0x14); iopr8i
+{
+ CCR = CCR | (iopr8i & 0b10111111);
+}
+
+@if defined(HCS12X)
+:ORX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x8A); iopr16i
+{
+ IX = IX | iopr16i;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x9A); opr8a_16
+{
+ IX = IX | opr8a_16;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xBA); opr16a_16
+{
+ IX = IX | opr16a_16;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xAA); indexed2_5
+{
+ IX = IX | indexed2_5;
+ V_equals_0();
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xCA); iopr16i
+{
+ IY = IY | iopr16i;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xDA); opr8a_16
+{
+ IY = IY | opr8a_16;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xFA); opr16a_16
+{
+ IY = IY | opr16a_16;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+@if defined(HCS12X)
+:ORY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xEA); indexed2_5
+{
+ IY = IY | indexed2_5;
+ V_equals_0();
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+}
+@endif
+
+:PSHA is XGATE=0 & Prefix18=0 & op8=0x36
+{
+ Push1( A );
+}
+
+:PSHB is XGATE=0 & Prefix18=0 & op8=0x37
+{
+ Push1( B );
+}
+
+:PSHC is XGATE=0 & Prefix18=0 & op8=0x39
+{
+ Push1( CCR );
+}
+
+@if defined(HCS12X)
+:PSHCW is XGATE=0 & Prefix18=1 & op8=0x39
+{
+ Push2( CCRW );
+}
+@endif
+
+:PSHD is XGATE=0 & Prefix18=0 & op8=0x3B
+{
+ Push2( D );
+}
+
+:PSHX is XGATE=0 & Prefix18=0 & op8=0x34
+{
+ Push2( IX );
+}
+
+:PSHY is XGATE=0 & Prefix18=0 & op8=0x35
+{
+ Push2( IY );
+}
+
+:PULA is XGATE=0 & Prefix18=0 & op8=0x32
+{
+ Pull1( A );
+}
+
+:PULB is XGATE=0 & Prefix18=0 & op8=0x33
+{
+ Pull1( B );
+}
+
+:PULC is XGATE=0 & Prefix18=0 & op8=0x38
+{
+ Pull1( CCR );
+}
+
+@if defined(HCS12X)
+:PULCW is XGATE=0 & Prefix18=1 & op8=0x38
+{
+ Pull2( CCRW );
+}
+@endif
+
+:PULD is XGATE=0 & Prefix18=0 & op8=0x3A
+{
+ Pull2( D );
+}
+
+:PULX is XGATE=0 & Prefix18=0 & op8=0x30
+{
+ Pull2( IX );
+}
+
+:PULY is XGATE=0 & Prefix18=0 & op8=0x31
+{
+ Pull2( IY );
+}
+
+:REV is XGATE=0 & Prefix18=1 & op8=0x3A
+{
+ tempIX:2 = MinMaxRuleEvaluation(IX, IY, A, $(V));
+ $(V) = MinMaxRuleEvaluationCorrect(IX, IY, A, $(V));
+
+ IX = tempIX;
+}
+
+:REVW is XGATE=0 & Prefix18=1 & op8=0x3B
+{
+ tempIX:2 = MinMaxRuleEvaluationWeighted(IX, IY, A, $(V), $(C));
+ tempIY:2 = MinMaxRuleEvaluationWeighted(IX, IY, A, $(V), $(C));
+ $(V) = MinMaxRuleEvaluationWeightedCorrect(IX, IY, A, $(V), $(C));
+
+ IX = tempIX;
+ IY = tempIY;
+}
+
+:ROL opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x75); opr16a_8
+{
+ tmpC:1 = $(C);
+ op1:1 = opr16a_8;
+ $(C) = op1 >> 7;
+ result:1 = op1 << 1;
+ result = result | tmpC;
+ opr16a_8 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_N_xor_C();
+}
+
+:ROL indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x65); indexed1_5
+{
+ tmpC:1 = $(C);
+ op1:1 = indexed1_5;
+ $(C) = op1 >> 7;
+ result:1 = op1 << 1;
+ result = result | tmpC;
+ indexed1_5 = result;
+ $(Z) = (result == 0);
+ $(N) = (result s< 0);
+ V_equals_N_xor_C();
+}
+
+:ROLA is XGATE=0 & Prefix18=0 & op8=0x45
+{
+ tmpC:1 = $(C) ;
+ $(C) = A >> 7;
+ A = A << 1;
+ A = A | tmpC;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_N_xor_C();
+}
+
+:ROLB is XGATE=0 & Prefix18=0 & op8=0x55
+{
+ tmpC:1 = $(C) ;
+ $(C) = B >> 7;
+ B = B << 1;
+ B = B | tmpC;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_N_xor_C();
+}
+
+@if defined(HCS12X)
+:ROLW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x75); opr16a_16
+{
+ local tmp = opr16a_16;
+ local tmpC = $(C);
+ $(C) = tmp[15,1];
+ tmp = tmp << 1;
+ tmp = tmp | zext(tmpC);
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ROLW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x65); indexed2_5
+{
+ local tmp = indexed2_5;
+ local tmpC = $(C);
+ $(C) = tmp[15,1];
+ tmp = tmp << 1;
+ tmp = tmp | zext(tmpC);
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ROLX is XGATE=0 & Prefix18=1 & op8=0x45
+{
+ local tmpC = $(C);
+ $(C) = IX[15,1];
+ IX = IX << 1;
+ IX = IX | zext(tmpC);
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:ROLY is XGATE=0 & Prefix18=1 & op8=0x55
+{
+ local tmpC = $(C);
+ $(C) = IY[15,1];
+ IY = IY << 1;
+ IY = IY | zext(tmpC);
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+:ROR opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0x76); opr16a_8
+{
+ tmpC:1 = $(C) << 7;
+ tmp:1 = opr16a_8;
+ $(C) = tmp & 1;
+ tmp = tmp >> 1;
+ tmp = tmp | tmpC;
+ opr16a_8 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:ROR indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0x66); indexed1_5
+{
+ tmpC:1 = $(C) << 7;
+ tmp:1 = indexed1_5;
+ $(C) = tmp & 1;
+ tmp = tmp >> 1;
+ tmp = tmp | tmpC;
+ indexed1_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+
+:RORA is XGATE=0 & Prefix18=0 & op8=0x46
+{
+ tmpC:1 = $(C) << 7;
+ $(C) = A & 1;
+ A = A >> 1;
+ A = A | tmpC;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_N_xor_C();
+}
+
+:RORB is XGATE=0 & Prefix18=0 & op8=0x56
+{
+ tmpC:1 = $(C) << 7;
+ $(C) = B & 1;
+ B = B >> 1;
+ B = B | tmpC;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_N_xor_C();
+}
+
+@if defined(HCS12X)
+:RORW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0x76); opr16a_16
+{
+ local tmp = opr16a_16;
+ local tmpC = $(C);
+ $(C) = tmp[0,1];
+ tmp = tmp >> 1;
+ tmp = tmp | (zext(tmpC) << 15);
+ opr16a_16 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:RORW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0x66); indexed2_5
+{
+ local tmp = indexed2_5;
+ local tmpC = $(C);
+ $(C) = tmp[0,1];
+ tmp = tmp >> 1;
+ tmp = tmp | (zext(tmpC) << 15);
+ indexed2_5 = tmp;
+ $(Z) = (tmp == 0);
+ $(N) = (tmp s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:RORX is XGATE=0 & Prefix18=1 & op8=0x46
+{
+ local tmpC = $(C);
+ $(C) = IX[0,1];
+ IX = IX >> 1;
+ IX = IX | (zext(tmpC) << 15);
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+@if defined(HCS12X)
+:RORY is XGATE=0 & Prefix18=1 & op8=0x56
+{
+ local tmpC = $(C);
+ $(C) = IY[0,1];
+ IY = IY >> 1;
+ IY = IY | (zext(tmpC) << 15);
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_N_xor_C();
+}
+@endif
+
+:RTC is XGATE=0 & Prefix18=0 & op8=0x0A
+{
+ Pull1( PPAGE );
+
+ tmp:2 = 0;
+ Pull2( tmp );
+
+ return [tmp];
+}
+
+:RTI is XGATE=0 & Prefix18=0 & op8=0x0B
+{
+ tmp:2 = 0;
+ Pull1( CCR );
+ Pull1( B );
+ Pull1( A );
+ Pull2( IX );
+ Pull2( IY );
+ Pull2( tmp ); # as ordered on page 289, not as documented in RTI description
+
+ return [tmp];
+}
+
+:RTS is XGATE=0 & Prefix18=0 & op8=0x3D
+{
+ tmp:2 = 0;
+ Pull2( tmp );
+
+ return [tmp];
+}
+
+:SBA is XGATE=0 & Prefix18=1 & (op8=0x16)
+{
+ result:1 = A - B;
+ subtraction_flags1(A, B, result);
+ A = result;
+}
+
+:SBCA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x82); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = A - op1 - $(C);
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SBCA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x92); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = A - op1 - $(C);
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SBCA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB2); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = A - op1 - $(C);
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SBCA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA2); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = A - op1 - $(C);
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SBCB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC2); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = B - op1 - $(C);
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SBCB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD2); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = B - op1 - $(C);
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SBCB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF2); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = B - op1 - $(C);
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SBCB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE2); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = B - op1 - $(C);
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+@if defined(HCS12X)
+:SBED iopr16i is XGATE=0 & Prefix18=1 & (op8=0x83); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = D - op1 - zext($(C));
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBED opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x93); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = D - op1 - zext($(C));
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBED opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB3); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = D - op1 - zext($(C));
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBED indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA3); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = D - op1 - zext($(C));
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x82); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IX - op1 - zext($(C));
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x92); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IX - op1 - zext($(C));
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB2); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IX - op1 - zext($(C));
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA2); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IX - op1 - zext($(C));
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC2); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IY - op1 - zext($(C));
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD2); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IY - op1 - zext($(C));
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF2); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IY - op1 - zext($(C));
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SBEY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE2); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IY - op1 - zext($(C));
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+:SEC is XGATE=0 & Prefix18=0 & op16=0x1401
+{
+ $(C) = 1;
+}
+
+:SEI is XGATE=0 & Prefix18=0 & op16=0x1410
+{
+ $(I) = 1;
+}
+
+:SEV is XGATE=0 & Prefix18=0 & op16=0x1402
+{
+ $(V) = 1;
+}
+
+
+
+@if defined(HCS12X)
+:SEX A, D is XGATE=0 & Prefix18=0 & op8=0xB7;
+ (
+ ( rows3_0=0xC & ( columns7_4=0x0 ) )
+ ) &
+ A & D
+{
+ D = sext( A );
+}
+@endif
+
+@if defined(HCS12X)
+:SEX B, D is XGATE=0 & Prefix18=0 & op8=0xB7;
+ (
+ ( rows3_0=0xC & ( columns7_4=0x1 ) )
+ ) &
+ B & D
+{
+ D = sext( B );
+}
+@endif
+
+@if defined(HCS12X)
+:SEX D, IX is XGATE=0 & Prefix18=0 & op8=0xB7;
+ (
+ ( rows3_0=0xD & ( columns7_4=0x4 ) )
+ ) &
+ D & IX
+{
+ # generate the sign extension upper word and assign it to destination
+ local tmp:4 = sext( D );
+ IX = tmp(2);
+}
+@endif
+
+@if defined(HCS12X)
+:SEX D, IY is XGATE=0 & Prefix18=0 & op8=0xB7;
+ (
+ ( rows3_0=0xE & ( columns7_4=0x4 ) )
+ ) &
+ D & IY
+{
+ # generate the sign extension upper word and assign it to destination
+ local tmp:4 = sext( D );
+ IY = tmp(2);
+}
+@endif
+
+:SEX abc5_4, dxys2_0 is XGATE=0 & Prefix18=0 & op8=0xB7;
+ (
+ ( rows3_0=0x3 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 ) ) |
+ ( rows3_0=0x4 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 ) ) |
+ ( rows3_0=0x5 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 ) ) |
+ ( rows3_0=0x6 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 ) ) |
+ ( rows3_0=0x7 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 ) )
+ ) &
+ abc5_4 & dxys2_0
+{
+ dxys2_0 = sext(abc5_4);
+}
+
+:^GPaged^"STAA" opr8a_8 is XGATE=0 & GPaged & (op8=0x5A); opr8a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_8 = A;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STAA" opr16a_8 is XGATE=0 & GPaged & (op8=0x7A); opr16a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_8 = A;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STAA" indexed1_5 is XGATE=0 & GPaged & (op8=0x6A); indexed1_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed1_5 = A;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STAB" opr8a_8 is XGATE=0 & GPaged & (op8=0x5B); opr8a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_8 = B;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STAB" opr16a_8 is XGATE=0 & GPaged & (op8=0x7B); opr16a_8 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_8 = B;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STAB" indexed1_5 is XGATE=0 & GPaged & (op8=0x6B); indexed1_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed1_5 = B;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STD" opr8a_16 is XGATE=0 & GPaged & (op8=0x5C); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_16 = D;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STD" opr16a_16 is XGATE=0 & GPaged & (op8=0x7C); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_16 = D;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STD" indexed2_5 is XGATE=0 & GPaged & (op8=0x6C); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed2_5 = D;
+ $(Z) = (D == 0);
+ $(N) = (D s< 0);
+ V_equals_0();
+}
+
+:STOP is XGATE=0 & Prefix18=1 & op8=0x3E
+{
+ if ($(S) == 0) goto ;
+ tmp:2 = inst_next;
+ Push2( tmp );
+ Push2( IY );
+ Push2( IX );
+ Push1( A );
+ Push1( B );
+ Push1( CCR );
+ stop();
+
+}
+
+:^GPaged^"STS" opr8a_16 is XGATE=0 & GPaged & (op8=0x5F); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_16 = SP;
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STS" opr16a_16 is XGATE=0 & GPaged & (op8=0x7F); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_16 = SP;
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STS" indexed2_5 is XGATE=0 & GPaged & (op8=0x6F); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed2_5 = SP;
+ $(Z) = (SP == 0);
+ $(N) = (SP s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STX" opr8a_16 is XGATE=0 & GPaged & (op8=0x5E); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_16 = IX;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STX" opr16a_16 is XGATE=0 & GPaged & (op8=0x7E); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_16 = IX;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STX" indexed2_5 is XGATE=0 & GPaged & (op8=0x6E); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed2_5 = IX;
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STY" opr8a_16 is XGATE=0 & GPaged & (op8=0x5D); opr8a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr8a_16 = IY;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STY" opr16a_16 is XGATE=0 & GPaged & (op8=0x7D); opr16a_16 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ opr16a_16 = IY;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:^GPaged^"STY" indexed2_5 is XGATE=0 & GPaged & (op8=0x6D); indexed2_5 [ UseGPAGE=Prefix18; ]
+{
+ build GPaged;
+ indexed2_5 = IY;
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:SUBA iopr8i is XGATE=0 & Prefix18=0 & (op8=0x80); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = A - op1;
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SUBA opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0x90); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = A - op1;
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SUBA opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xB0); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = A - op1;
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SUBA indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xA0); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = A - op1;
+ subtraction_flags1(A, op1, result);
+ A = result;
+}
+
+:SUBB iopr8i is XGATE=0 & Prefix18=0 & (op8=0xC0); iopr8i
+{
+ op1:1 = iopr8i;
+
+ result:1 = B - op1;
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SUBB opr8a_8 is XGATE=0 & Prefix18=0 & (op8=0xD0); opr8a_8
+{
+ op1:1 = opr8a_8;
+
+ result:1 = B - op1;
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SUBB opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF0); opr16a_8
+{
+ op1:1 = opr16a_8;
+
+ result:1 = B - op1;
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SUBB indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE0); indexed1_5
+{
+ op1:1 = indexed1_5;
+
+ result:1 = B - op1;
+ subtraction_flags1(B, op1, result);
+ B = result;
+}
+
+:SUBD iopr16i is XGATE=0 & Prefix18=0 & (op8=0x83); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = D - op1;
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+
+:SUBD opr8a_16 is XGATE=0 & Prefix18=0 & (op8=0x93); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = D - op1;
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+
+:SUBD opr16a_16 is XGATE=0 & Prefix18=0 & (op8=0xB3); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = D - op1;
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+
+:SUBD indexed2_5 is XGATE=0 & Prefix18=0 & (op8=0xA3); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = D - op1;
+ subtraction_flags2(D, op1, result);
+ D = result;
+}
+
+@if defined(HCS12X)
+:SUBX iopr16i is XGATE=0 & Prefix18=1 & (op8=0x80); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IX - op1;
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBX opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0x90); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IX - op1;
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBX opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xB0); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IX - op1;
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBX indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xA0); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IX - op1;
+ subtraction_flags2(IX, op1, result);
+ IX = result;
+}
+
+@if defined(HCS12X)
+:SUBY iopr16i is XGATE=0 & Prefix18=1 & (op8=0xC0); iopr16i
+{
+ op1:2 = iopr16i;
+
+ result:2 = IY - op1;
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBY opr8a_16 is XGATE=0 & Prefix18=1 & (op8=0xD0); opr8a_16
+{
+ op1:2 = opr8a_16;
+
+ result:2 = IY - op1;
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBY opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF0); opr16a_16
+{
+ op1:2 = opr16a_16;
+
+ result:2 = IY - op1;
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+@if defined(HCS12X)
+:SUBY indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE0); indexed2_5
+{
+ op1:2 = indexed2_5;
+
+ result:2 = IY - op1;
+ subtraction_flags2(IY, op1, result);
+ IY = result;
+}
+@endif
+
+:SWI is XGATE=0 & Prefix18=0 & op8=0x3F
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+ Push2( IY );
+ Push2( IX );
+ Push1( A );
+ Push1( B );
+ Push1( CCR );
+
+ $(I) = 1;
+
+ addr:2 = $(VECTOR_SWI);
+ call [addr];
+}
+
+:TAB is XGATE=0 & Prefix18=1 & op8=0x0E
+{
+ B = A;
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ V_equals_0();
+}
+
+:TAP is XGATE=0 & Prefix18=0 & op16=0xB702
+{
+ setCCR( A );
+}
+
+:TBA is XGATE=0 & Prefix18=1 & op8=0x0F
+{
+ A = B;
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:TBEQ byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x2 & size10_10=0 & byte9_8 & rel9
+{
+ if (byte9_8 == 0) goto rel9;
+}
+
+:TBEQ word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x2 & size10_10=1 & word9_8 & rel9
+{
+ if (word9_8 == 0) goto rel9;
+}
+
+:TBL indexed1_3 is XGATE=0 & Prefix18=1 & op8=0x3D; indexed1_3
+{
+ A = TableLookupAndInterpolate(indexed1_3, B);
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+@if defined(HC12)
+ $(C) = TableLookupAndInterpolateRoundable(indexed1_3, B);
+@endif
+}
+
+:TBNE byte9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x3 & size10_10=0 & byte9_8 & rel9
+{
+ if (byte9_8 != 0) goto rel9;
+}
+
+:TBNE word9_8, rel9 is XGATE=0 & Prefix18=0 & op8=0x04; op15_13=0x3 & size10_10=1 & word9_8 & rel9
+{
+ if (word9_8 != 0) goto rel9;
+}
+
+:TFR bytes_ABClT3lBXlYlSl_6_4, bytes_ABCl_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+# The case "20" is covered by TPA
+ ( rows3_0=0x0 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0x1 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 | columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+
+ ( rows3_0=0x8 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x4 ) ) |
+ ( rows3_0=0x9 & ( columns7_4=0x0 | columns7_4=0x1 | columns7_4=0x2 | columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) )
+ ) &
+ bytes_ABClT3lBXlYlSl_6_4 & bytes_ABCl_2_0
+{
+ bytes_ABCl_2_0 = bytes_ABClT3lBXlYlSl_6_4;
+}
+
+:TFR bytes_ABClT3lBXlYlSl_6_4, CCR is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+# The case "02" is covered by TAP
+ ( rows3_0=0x2 & ( columns7_4=0x1 | columns7_4=0x2 | columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+
+ ( rows3_0=0xA & ( columns7_4=0x1 ) )
+ ) &
+ bytes_ABClT3lBXlYlSl_6_4 & CCR
+{
+ setCCR( bytes_ABClT3lBXlYlSl_6_4 );
+}
+
+:TFR bytes_ABChT3hBXhYhSh_6_4, A is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0x8 & ( columns7_4=0x2 | columns7_4=0x3 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) )
+ ) &
+ bytes_ABChT3hBXhYhSh_6_4 & A
+{
+ A = bytes_ABChT3hBXhYhSh_6_4;
+}
+
+:TFR A, CCRH is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xA & ( columns7_4=0x0 ) )
+ ) &
+ A & CCRH
+{
+ CCRH = A;
+}
+
+:TFR words_CT3DXYS_6_4, CCRW is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xA & ( columns7_4=0x2 | columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) )
+ ) &
+ words_CT3DXYS_6_4 & CCRW
+{
+ setCCRW( words_CT3DXYS_6_4 );
+}
+
+:TFR words_T3DXYS_6_4, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+# The case "57" is covered by TXS
+# The case "67" is covered by TYS
+# The case "75" is covered by TSX
+# The case "76" is covered by TSY
+ ( rows3_0=0x3 & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0x4 & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0x5 & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 ) ) |
+ ( rows3_0=0x6 & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 ) ) |
+ ( rows3_0=0x7 & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x7 ) ) |
+
+ ( rows3_0=0xB & ( columns7_4=0x3 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0xC & ( columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0xD & ( columns7_4=0x3 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x3 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x3 | columns7_4=0x4 | columns7_4=0x5 | columns7_4=0x6 | columns7_4=0x7 ) )
+ ) &
+ words_T3DXYS_6_4 & words_T2DXYS_2_0
+{
+ words_T2DXYS_2_0 = words_T3DXYS_6_4;
+}
+
+:TFR D, TMP1 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x4 ) )
+ ) &
+ D & TMP1
+{
+ TMP1 = D;
+}
+
+:TFR TMP1, D is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xC & ( columns7_4=0x3 ) )
+ ) &
+ TMP1 & D
+{
+ D = TMP1;
+}
+
+:TFR CCRW, words_T2DXYS_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x2 ) ) |
+ ( rows3_0=0xC & ( columns7_4=0x2 ) ) |
+ ( rows3_0=0xD & ( columns7_4=0x2 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x2 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x2 ) )
+ ) &
+ CCRW & words_T2DXYS_2_0
+{
+ words_T2DXYS_2_0 = CCRW;
+}
+
+:TFR A, bytes_T2h_XhYhSh_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x0 ) ) |
+
+ ( rows3_0=0xD & ( columns7_4=0x0 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x0 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x0 ) )
+ ) &
+ A & bytes_T2h_XhYhSh_2_0
+{
+ bytes_T2h_XhYhSh_2_0 = A;
+}
+
+:TFR A, bytes_T2l_XlYlSl_2_0 is XGATE=0 & Prefix18=0 & ( op8=0xB7 );
+ (
+ ( rows3_0=0xB & ( columns7_4=0x1 ) ) |
+
+ ( rows3_0=0xD & ( columns7_4=0x1 ) ) |
+ ( rows3_0=0xE & ( columns7_4=0x1 ) ) |
+ ( rows3_0=0xF & ( columns7_4=0x1 ) )
+ ) &
+ A & bytes_T2l_XlYlSl_2_0
+{
+ bytes_T2l_XlYlSl_2_0 = A;
+}
+
+:TPA is XGATE=0 & Prefix18=0 & op16=0xB720
+{
+ A = CCR;
+}
+
+# TODO Not working properly with context regis XGATE=0 & ter for Prefix18
+:TRAP trapnum is XGATE=0 & Prefix18=1 & op8=0x30 & trapnum
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+ Push2( IY );
+ Push2( IX );
+ Push1( A );
+ Push1( B );
+ Push1( CCR );
+
+ $(I) = 1;
+
+ addr:2 = $(VECTOR_TRAP);
+ call [addr];
+}
+
+:TST opr16a_8 is XGATE=0 & Prefix18=0 & (op8=0xF7); opr16a_8
+{
+ op1:1 = opr16a_8;
+ $(Z) = (op1 == 0);
+ $(N) = (op1 s< 0);
+ V_equals_0();
+ $(C) = 0;
+}
+
+:TST indexed1_5 is XGATE=0 & Prefix18=0 & (op8=0xE7); indexed1_5
+{
+ op1:1 = indexed1_5;
+ $(Z) = (op1 == 0);
+ $(N) = (op1 s< 0);
+ V_equals_0();
+ $(C) = 0;
+}
+
+:TSTA is XGATE=0 & Prefix18=0 & op8=0x97
+{
+ $(Z) = (A == 0);
+ $(N) = (A s< 0);
+ V_equals_0();
+}
+
+:TSTB is XGATE=0 & Prefix18=0 & op8=0xD7
+{
+ $(Z) = (B == 0);
+ $(N) = (B s< 0);
+ $(V) = 0;
+ $(C) = 0;
+}
+
+@if defined(HCS12X)
+:TSTW opr16a_16 is XGATE=0 & Prefix18=1 & (op8=0xF7); opr16a_16
+{
+ op1:2 = opr16a_16;
+ $(Z) = (op1 == 0);
+ $(N) = (op1 s< 0);
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+@if defined(HCS12X)
+:TSTW indexed2_5 is XGATE=0 & Prefix18=1 & (op8=0xE7); indexed2_5
+{
+ op1:2 = indexed2_5;
+ $(Z) = (op1 == 0);
+ $(N) = (op1 s< 0);
+ V_equals_0();
+ $(C) = 0;
+}
+@endif
+
+:TSTX is XGATE=0 & Prefix18=1 & op8=0x97
+{
+ $(Z) = (IX == 0);
+ $(N) = (IX s< 0);
+ V_equals_0();
+}
+
+
+:TSTY is XGATE=0 & Prefix18=1 & op8=0xD7
+{
+ $(Z) = (IY == 0);
+ $(N) = (IY s< 0);
+ V_equals_0();
+}
+
+:TSX is XGATE=0 & Prefix18=0 & op16=0xB775
+{
+ IX = SP;
+}
+
+:TSY is XGATE=0 & Prefix18=0 & op16=0xB776
+{
+ IY = SP;
+}
+
+:TXS is XGATE=0 & Prefix18=0 & op16=0xB757
+{
+ SP = IX;
+}
+
+:TYS is XGATE=0 & Prefix18=0 & op16=0xB767
+{
+ SP = IY;
+}
+
+:WAI is XGATE=0 & Prefix18=0 & op8=0x3E
+{
+ tmp:2 = inst_next;
+ Push2( tmp );
+ Push2( IY );
+ Push2( IX );
+ Push1( A );
+ Push1( B );
+ Push1( CCR );
+
+ WaitForInterrupt();
+}
+
+:WAV is XGATE=0 & Prefix18=1 & op8=0x3C
+{
+ tempIY:2 = WeightedAverageSOPHigh(B, IY, IX);
+ tempD:2 = WeightedAverageSOPLow (B, IY, IX);
+ tempIX:2 = WeightedAverageSOW(B, IY, IX);
+
+ B = 0;
+
+ IY = tempIY;
+ D = tempD;
+ IX = tempIX;
+}
+
+:WAVR is XGATE=0 & Prefix18=0 & op8=0x3C
+{
+ WeightedAverageResume();
+}
+
+:XGDX is XGATE=0 & Prefix18=0 & op16=0xB7C5
+{
+ tmp:2 = IX;
+ IX = D;
+ D = tmp;
+}
+
+:XGDY is XGATE=0 & Prefix18=0 & op16=0xB7C6
+{
+ tmp:2 = IY;
+ IY = D;
+ D = tmp;
+}
diff --git a/Ghidra/Processors/HCS12/data/languages/XGATE.sinc b/Ghidra/Processors/HCS12/data/languages/XGATE.sinc
new file mode 100644
index 0000000000..56c78c7d8d
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/languages/XGATE.sinc
@@ -0,0 +1,993 @@
+# sleigh specification file for XGATE MCU peripheral co-processor
+
+################################################################
+# Registers
+################################################################
+
+# register R0 always contains the value 0
+define register offset=0x100 size=2 [R0 R1 R2 R3 R4 R5 R6 R7];
+define register offset=0x100 size=1 [R0.H R0.L R1.H R1.L R2.H R2.L R3.H R3.L R4.H R4.L R5.H R5.L R6.H R6.L R7.H R7.L];
+define register offset=0x110 size=2 [XPC XCCR];
+define register offset=0x120 size=1 [XC XV XZ XN];
+
+# Individual status bits within the XCCR
+@define XN "XN" # XCCR[3,1] # Negative Flag
+@define XZ "XZ" # XCCR[2,1] # Zero Flag
+@define XV "XV" # XCCR[1,1] # Overflow Flag
+@define XC "XC" # XCCR[0,1] # Carry Flag
+
+################################################################
+# Tokens
+################################################################
+define token XOpWord16 (16)
+ xop16 = (0,15)
+ opcode = (11,15)
+ reg8 = (8,10)
+ reg8_lo = (8,10)
+ reg8_hi = (8,10)
+ imm3 = (8,10)
+ op9_10 = (9,10)
+ bit_10 = (10,10)
+ immrel9 = (0,9) signed
+ immrel8 = (0,8) signed
+ xop8 = (0,7)
+ reg5 = (5,7)
+ ximm4 = (4,7)
+ ximm8 = (0,7)
+ op4 = (0,4)
+ op3 = (0,3)
+ offs5 = (0,5)
+ reg2 = (2,4)
+ op2 = (0,1)
+;
+
+################################################################
+# Attach variables
+################################################################
+
+attach variables [reg8 reg5 reg2] [R0 R1 R2 R3 R4 R5 R6 R7];
+
+attach variables [reg8_lo ] [R0.L R1.L R2.L R3.L R4.L R5.L R6.L R7.L];
+attach variables [reg8_hi ] [R0.H R1.H R2.H R3.H R4.H R5.H R6.H R7.H];
+
+################################################################
+# Pseudo Instructions
+################################################################
+
+define pcodeop findFirstOne;
+define pcodeop leftShiftCarry;
+define pcodeop rightShiftCarry;
+define pcodeop parity;
+define pcodeop clearSemaphore;
+define pcodeop setSemaphore;
+define pcodeop setInterruptFlag;
+define pcodeop TerminateThread;
+
+################################################################
+# Macros Instructions
+################################################################
+
+macro default_flags(result)
+{
+ $(XZ) = (result == 0);
+ $(XN) = (result s< 0);
+ $(XV) = 0;
+ #$(XC) not affected
+}
+
+macro addition_flags(operand1, operand2, result)
+{
+ $(XN) = (result s< 0);
+ $(XZ) = ((result == 0) & ($(XZ)==1));
+ $(XV) = (((operand1 & operand2 & ~result) | (~operand1 & ~operand2 & result)) & 0x8000) != 0;
+ $(XC) = (((operand1 & operand2) | (operand2 & ~result) | (~result & operand1)) & 0x8000) != 0;
+}
+
+macro subtraction_flags(register, operand, result) {
+ $(XN) = (result s< 0);
+ $(XZ) = (result == 0);
+ $(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x8000 ) != 0;
+ $(XC) = ( ((~register & operand) | (operand & result) | (~register & result)) & 0x8000 ) != 0;
+}
+
+macro subtraction_flagsB(register, operand, result) {
+ $(XN) = (result s< 0);
+ $(XZ) = (result == 0);
+ $(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x80 ) != 0;
+ $(XC) = ( ((~register & operand) | (operand & result) | (result & ~register)) & 0x80 ) != 0;
+}
+
+macro subtraction_flagsC(register, operand, result) {
+ $(XN) = (result s< 0);
+ $(XZ) = ( (result == 0) & ($(XZ) == 1));
+ $(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x8000 ) != 0;
+ $(XC) = ( ((~register & operand) | (operand & result) | (~register & result)) & 0x8000 ) != 0;
+}
+
+macro shiftFlags(result,old)
+{
+ $(XN) = (result s< 0);
+ $(XZ) = (result == 0);
+ tmp:2 = (old >> 15) ^ (result >> 15);
+ $(XV) = tmp(1);
+}
+
+macro getbit(res,in,bitnum) {
+ res = ((in >> bitnum) & 1) != 0;
+}
+
+#
+# computes a fake PPAGE page mapping based on the 16 bit input address
+# The XGATE memory is mapped to the pages of physical memory
+# Warning: This might not be the correct mapping on all XGATE processors
+#
+# 0000-07ff = 0x00_0000 - 0x00_07ff
+# 0800-7fff = 0x78_0800 - XGFLASH_HIGH
+# 8000-ffff = 0x0f_0800 - 0x0f_ffff
+#
+macro computePage(addr) {
+ local isReg:1 = addr < 0x800;
+ local isFlash:1 = addr >= 0x800 & addr < 0x7fff;
+ local isRam:1 = addr >= 0x8000;
+ physPage = (zext(isReg) * 0x0)+ (zext(isFlash) * (0x78 << 16)) + (zext(isRam) * (0xf<<16));
+}
+
+################################################################
+# Constructors
+################################################################
+
+#rel9 defined in HCS_HC12.sinc
+# range -256 through +255
+with : XGATE=1 {
+rel9: reloc is immrel8 [ reloc = inst_next + (immrel8 * 2); ] { export * reloc; }
+
+# range -512 through +512
+rel10: reloc is immrel9 [ reloc = inst_next + (immrel9 * 2); ] { export * reloc; }
+
+rd : reg8 is reg8 { export reg8; }
+
+rs1: reg5 is reg5 & reg5=0 { export 0:2; }
+rs1: reg5 is reg5 { export reg5; }
+
+rs2: reg2 is reg2 & reg2=0 { export 0:2; }
+rs2: reg2 is reg2 { export reg2; }
+
+
+rd_lo: reg8 is reg8 & reg8_lo { export reg8_lo; }
+rd_hi: reg8 is reg8 & reg8_hi { export reg8_hi; }
+
+
+
+# Add with carry
+:ADC rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x3
+{
+ local result:2 = rs1 + rs2 + zext($(XC));
+ rd = result;
+
+ addition_flags(rs1, rs2, result);
+}
+
+# Add without carry
+:ADD rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x2
+{
+ local result:2 = rs1 + rs2;
+ rd = result;
+
+ addition_flags(rs1, rs2, result);
+}
+
+# Add immediate 8-bit constant (high byte)
+:ADDH rd, ximm8 is opcode=0x1d & rd & ximm8
+{
+ local val:2 = ximm8 << 8;
+ local result:2 = rd + val;
+
+ addition_flags(rd, val, result);
+
+ rd = result;
+}
+
+# Add immediate 8-bit constant (low byte)
+:ADDL rd, ximm8 is opcode=0x1c & rd & ximm8
+{
+ local result:2 = rd + ximm8;
+
+ $(XN) = (result s< 0);
+ $(XZ) = ((result == 0) & ($(XZ)==1));
+ $(XV) = ((~rd & result) & 0x8000) != 0;
+ $(XC) = ((rd & ~result) & 0x8000) != 0;
+ rd = result;
+}
+
+# Logical AND
+:AND rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x0
+{
+ rd = rs1 & rs2;
+
+ default_flags(rd);
+}
+
+# Logical AND immediate 8-bit constant (high byte)
+:ANDH rd, ximm8 is opcode=0x11 & rd & ximm8 & rd_hi
+{
+ rd_hi = rd_hi & ximm8;
+
+ default_flags(rd_hi);
+}
+
+# Logical AND immediate 8-bit constant (low byte)
+:ANDL rd, ximm8 is opcode=0x10 & rd & ximm8 & rd_lo
+{
+ rd_lo = rd_lo & ximm8;
+
+ default_flags(rd_lo);
+}
+
+# Arithmetic Shift Right
+:ASR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0x9
+{
+ getbit($(XC), rd, ximm4-1);
+ rd = rd s>> ximm4;
+
+ default_flags(rd);
+}
+
+:ASR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x11
+{
+ getbit($(XC), rd, rs1-1);
+ rd = rd s>> rs1;
+
+ default_flags(rd);
+}
+
+# Branch if Carry Cleared
+:BCC rel9 is opcode=0x4 & op9_10=0x0 & rel9
+{
+ if ($(XC) == 0) goto rel9;
+}
+
+
+# Branch if Carry Set
+:BCS rel9 is opcode=0x4 & op9_10=0x1 & rel9
+{
+ if ($(XC) == 1) goto rel9;
+}
+
+# Branch of Equal
+:BEQ rel9 is opcode=0x4 & op9_10=0x3 & rel9
+{
+ if ($(XZ) == 1) goto rel9;
+}
+
+# Bit Field Extract
+:BFEXT rd, rs1, rs2 is opcode=0xc & rd & rs1 & rs2 & op2=0x3
+{
+ local origin:2 = rs2 & 0xf;
+ local width:2 = (rs2 >> 4) & 0xf;
+ local mask:2 = (0xffff >> (16-(width + 1))) << origin;
+ local result:2 = (rs1 & mask) >> origin;
+
+ rd = result;
+
+ default_flags(rd);
+}
+
+# Bit Field Find First One
+:BFFO rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x10
+{
+ # 15 - count leading zeros
+ tmp:2 = rs1;
+ $(XC) = (rd == 0);
+ #TODO: implement findFirstOne behavior
+ rd = findFirstOne(tmp);
+
+ default_flags(rd);
+}
+
+# Bit Field Insert
+:BFINS rd, rs1, rs2 is opcode=0xd & rd & rs1 & rs2 & op2=0x3
+{
+ local origin:2 = rs2 & 0xf;
+ local width:2 = (rs2 >> 4) & 0xf;
+ local mask:2 = (0xffff >> (16-(width + 1))) << origin;
+ local result:2 = (rs1 & mask);
+
+ rd = (rd & ~mask) | result;
+
+ default_flags(rd);
+}
+
+# Bit Field Insert and Invert
+:BFINSI rd, rs1, rs2 is opcode=0xe & rd & rs1 & rs2 & op2=0x3
+{
+ local origin:2 = rs2 & 0xf;
+ local width:2 = (rs2 >> 4) & 0xf;
+ local mask:2 = (0xffff >> (16-(width + 1))) << origin;
+ local result:2 = (~rs1 & mask);
+
+ rd = (rd & ~mask) | result;
+
+ default_flags(rd);
+}
+
+# Bit Field Insert and XNOR
+:BFINSX rd, rs1, rs2 is opcode=0xf & rd & rs1 & rs2 & op2=0x3
+{
+ local origin:2 = rs2 & 0xf;
+ local width:2 = (rs2 >> 4) & 0xf;
+ local mask:2 = (0xffff >> (16-(width + 1))) << origin;
+ local result:2 = (~(rs1 ^ rd) & mask);
+
+ rd = (rd & ~mask) | result;
+
+ default_flags(rd);
+}
+
+# Branch if Greater than or Equal to Zero
+:BGE rel9 is opcode=0x6 & op9_10=0x2 & rel9
+{
+ if (($(XN) ^ $(XV)) == 0) goto rel9;
+}
+
+# Branch if Greater than Zero
+:BGT rel9 is opcode=0x7 & op9_10=0x0 & rel9
+{
+ if (($(XZ) | ($(XN) ^ $(XV))) == 0) goto rel9;
+}
+
+# Branch if Higher
+:BHI rel9 is opcode=0x6 & op9_10=0x0 & rel9
+{
+ if (($(XC) | $(XZ)) == 0) goto rel9;
+}
+
+#:BHS rel9 is opcode=0x4 & op9_10=0x0 & rel9 see BCC
+
+# Bit Test immediate 8-bit constant (high byte)
+:BITH rd, ximm8 is opcode=0x13 & rd & ximm8 & rd_hi
+{
+ local val = rd_hi & ximm8;
+
+ default_flags(val);
+}
+
+# Bit Test immediate 8-bit constant (low byte)
+:BITL reg8, ximm8 is opcode=0x12 & reg8 & ximm8 & rd_lo
+{
+ local val = rd_lo & ximm8;
+
+ default_flags(val);
+}
+
+# Branch if Less or Equal to Zero
+:BLE rel9 is opcode=0x7 & op9_10=0x1 & rel9
+{
+ if ($(XZ) | ($(XN) ^ $(XV))) goto rel9;
+}
+
+#:BLO rel9 is opcode=0x4 & op9_10=0x1 & rel9 See BCS
+
+# Branch if Lower or Same
+:BLS rel9 is opcode=0x6 & op9_10=0x1 & rel9
+{
+ if (($(XC) | $(XZ)) == 1) goto rel9;
+}
+
+# Branch of Lower than Zero
+:BLT rel9 is opcode=0x6 & op9_10=0x3 & rel9
+{
+ if (($(XN) ^ $(XV)) == 1) goto rel9;
+}
+
+# Branch if Minus
+:BMI rel9 is opcode=0x5 & op9_10=0x1 & rel9
+{
+ if ($(XN) == 1) goto rel9;
+}
+
+# Branch if Not Equal
+:BNE rel9 is opcode=0x4 & op9_10=0x2 & rel9
+{
+ if ($(XZ) == 0) goto rel9;
+}
+
+# Branch if Plus
+:BPL rel9 is opcode=0x5 & op9_10=0x0 & rel9
+{
+ if ($(XN) == 0) goto rel9;
+}
+
+# Branch Always
+:BRA rel10 is opcode=0x7 & bit_10=0x1 & rel10
+{
+ goto rel10;
+}
+# Break
+:BRK is xop16=0x0
+{
+ # put xgate into debug mode and set breakpoint
+ goto inst_next;
+}
+
+# Branch if Overflow Cleared
+:BVC rel9 is opcode=0x5 & op9_10=0x2 & rel9
+{
+ if ($(XV) == 0) goto rel9;
+}
+
+# Branch if Overflow Set
+:BVS rel9 is opcode=0x5 & op9_10=0x3 & rel9
+{
+ if ($(XV) == 2) goto rel9;
+}
+
+# Compare
+# synonym for SUB R0, RS1, RS2
+:CMP rs1, rs2 is opcode=0x3 & reg8=0x0 & rs1 & rs2 & op2=0x0
+{
+ tmp:2 = rs1 - rs2;
+ subtraction_flags(rs1, rs2, tmp);
+}
+
+# Compare Immediate 8-bit constant (low byte)
+:CMPL rd, ximm8 is opcode=0x1a & rd & ximm8
+{
+ local val:1 = rd:1;
+ local tmp:1 = val - ximm8;
+ local xtmp:1 = ximm8;
+ subtraction_flagsB(val, xtmp, tmp);
+}
+
+# One's Complement
+:COM rd, rs2 is opcode=0x2 & rd & reg5=0x0 & rs2 & op2=0x3
+{
+ local val:2 = ~rs2;
+ rd = val;
+
+ default_flags(rd);
+}
+
+:COM rd is opcode=0x2 & rd & reg5=0x0 & rs2 & reg8=reg2 & op2=0x3
+{
+ local val:2 = ~rs2;
+ rd = val;
+
+ default_flags(rd);
+}
+
+# Compare with Carry
+:CPC rs1, rs2 is opcode=0x3 & reg8=0x0 & rs1 & rs2 & op2=0x1
+{
+ local tmp:2 = rs1 - rs2 - zext($(XC));
+ subtraction_flags(rs1, rs2, tmp);
+}
+
+# Compare Immediate 8-bit constant with carry (high byte)
+:CPCH rd, ximm8 is opcode=0x1b & rd & ximm8
+{
+ local val:2 = rd >> 8;
+ local tmp:1 = val(1) - ximm8 - $(XC);
+ local xtmp:1 = ximm8;
+ subtraction_flagsB(val(1), xtmp, tmp);
+}
+
+# Clear Semaphore
+:CSEM rd is opcode=0x0 & rd & xop8=0xf0
+{
+ # treat as NOP
+ clearSemaphore(rd);
+}
+
+:CSEM imm3 is opcode=0x0 & imm3 & xop8=0xf1
+{
+ local sem:1 = imm3;
+ clearSemaphore(sem);
+}
+
+
+# Logical Shift Left with Carry
+:CSL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xa
+{
+ local Ctmp:2 = zext($(XC));
+ local shift:2 = ((ximm4-1)%16+1);
+ local oldRd:2 = rd >> 15;
+ getbit($(XC), rd, 16-shift);
+ leftShiftCarry(rd,Ctmp,shift,rd);
+ shiftFlags(rd,oldRd);
+}
+
+:CSL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x12
+{
+ local Ctmp:2 = zext($(XC));
+ #if rs1 > 16, then rs1 = 16
+ local rsgt:2 = zext(rs1>16);
+ local rslt:2 = zext(rs1<16);
+ local shift:2 = rs1*rsgt + 16*rslt;
+ local oldRd:2 = rd >> 15;
+ getbit($(XC), rd, 16-shift);
+ leftShiftCarry(rd,Ctmp,shift,rd);
+ shiftFlags(rd,oldRd);
+}
+
+# Logical Shift Right with Carry
+:CSR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xb
+{
+ local Ctmp:2 = zext($(XC));
+ local shift:2 = ((ximm4-1)%16+1);
+ local oldRd:2 = rd >> 15;
+ getbit($(XC), rd, shift-1);
+ rightShiftCarry(rd,Ctmp,shift,rd);
+ shiftFlags(rd,oldRd);
+}
+
+:CSR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x13
+{
+ local Ctmp:2 = zext($(XC));
+ #if rs1 > 16, then rs1 = 16
+ local rsgt:2 = zext(rs1>16);
+ local rslt:2 = zext(rs1<16);
+ local shift:2 = rs1*rsgt + 16*rslt;
+ local oldRd:2 = rd >> 15;
+ getbit($(XC), rd, shift-1);
+ rightShiftCarry(rd,Ctmp,shift,rd);
+ shiftFlags(rd,oldRd);
+}
+
+:CSR rd, rs1 is opcode=0x1 & rd & rs1 & reg5=0 & op4=0x13
+{
+ $(XN) = (rd s< 0);
+ $(XZ) = (rd == 0);
+ $(XV) = 0;
+ # $(XC) is unaffected
+}
+
+# Jump and Link
+:JAL rd is opcode=0x0 & rd & xop8=0xf6
+{
+ local dest:2 = rd;
+ rd = inst_next;
+ call [dest];
+}
+
+# Load byte from memory (low byte)
+:LDB rd, (rs1, offs5) is opcode=0x8 & rd & rs1 & offs5
+{
+ local addr = rs1 + offs5;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = *:1 (dst);
+ rd = (rd & 0xff00) | zext(val);
+}
+
+:LDB rd, (rs1, rs2) is opcode=0xc & rd & rs1 & rs2 & op2=0x0
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = *:1 (dst);
+ rd = (rd & 0xff00) | zext(val);
+}
+
+:LDB rd, (rs1, rs2+) is opcode=0xc & rd & rs1 & rs2 & op2=0x1
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = *:1 (dst);
+ rd = (rd & 0xff00) | zext(val);
+ rs1 = rs1 + 1;
+}
+
+:LDB rd, (rs1, -rs2) is opcode=0xc & rd & rs1 & rs2 & op2=0x2
+{
+ rs2 = rs2 - 1;
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = *:1 (dst);
+ rd = (rd & 0xff00) | zext(val);
+}
+
+
+# Load Immediate 8-bit constant (high byte)
+:LDH rd, ximm8 is opcode=0x1f & rd & ximm8 & rd_hi
+{
+ rd_hi = ximm8 << 8;
+}
+
+
+# Load Immediate 8-bit constant (low byte)
+:LDL rd, ximm8 is opcode=0x1e & rd & ximm8
+{
+ rd = ximm8;
+}
+
+# Load Word from Memory
+:LDW rd, (rs1, offs5) is opcode=0x9 & rd & rs1 & offs5
+{
+ local addr = rs1 + offs5;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = *:2 (dst);
+ rd = val;
+}
+
+:LDW rd, (rs1, rs2) is opcode=0xd & rd & rs1 & rs2 & op2=0x0
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = *:2 (dst);
+ rd = val;
+}
+
+:LDW rd, (rs1, rs2+) is opcode=0xd & rd & rs1 & rs2 & op2=0x1
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = *:2 (dst);
+ rd = val;
+ rs1 = rs1 + 2;
+}
+:LDW rd, (rs1, -rs2) is opcode=0xd & rd & rs1 & rs2 & op2=0x2
+{
+ rs2 = rs2 - 2;
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = *:2 (dst);
+ rd = val;
+}
+
+# Logical Shift Left
+:LSL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xc
+{
+ local shift:2 = ((ximm4-1)%16+1);
+ getbit($(XC), rd, 16-shift);
+ local oldRd:2 = rd >> 15;
+ rd = rd << shift;
+ shiftFlags(rd,oldRd);
+}
+
+:LSL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x14
+{
+ getbit($(XC), rd, 16-rs1);
+ local oldRd:2 = rd >> 15;
+ rd = rd << rs1;
+ shiftFlags(rd,oldRd);
+}
+
+# Logical Shift Right
+:LSR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xd
+{
+ getbit($(XC), rd, ximm4-1);
+ local oldRd:2 = rd >> 15;
+ rd = rd >> ximm4;
+ shiftFlags(rd,oldRd);
+}
+
+:LSR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x15
+{
+ getbit($(XC), rd, rs1-1);
+ local oldRd:2 = (rd >> 15);
+ rd = rd >> rs1;
+ shiftFlags(rd,oldRd);
+}
+
+# Move Register Content
+# Synonym for OR RD, R0, RS
+:MOV rd, rs2 is opcode=0x2 & rd & reg5=0 & rs2 & op2=0x2
+{
+ rd = rs2;
+
+ default_flags(rd);
+}
+
+# Two's Complement
+:NEG rd, rs2 is opcode=0x3 & rd & reg5=0x0 & rs2 & op2=0x0
+{
+ local tmp:2 = -rs2;
+ rd = tmp;
+ $(XN) = (rd s< 0);
+ $(XZ) = (rd == 0);
+ $(XV) = (((rs2 & rd) & 0x8000) != 0);
+ $(XC) = (((rs2 | rd) & 0x8000) != 0);
+}
+
+:NEG rd is opcode=0x3 & rd & reg5=0x0 & rs2 & reg2=reg8 & op2=0x0
+{
+ local tmp:2 = -rs2;
+ rd = tmp;
+ $(XN) = (rd s< 0);
+ $(XZ) = (rd == 0);
+ $(XV) = (((rs2 & rd) & 0x8000) != 0);
+ $(XC) = (((rs2 | rd) & 0x8000) != 0);
+}
+
+# No Op
+:NOP is xop16=0x100 {}
+
+# Logical OR
+:OR rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x2
+{
+ local result:2 = rs1 | rs2;
+ rd = result;
+
+ default_flags(result);
+}
+
+# Logical OR Immediate 8-bit Constant (high byte)
+:ORH rd, ximm8 is opcode=0x15 & rd & ximm8 & rd_hi
+{
+ rd_hi = rd_hi | ximm8;
+
+ default_flags(rd_hi);
+}
+
+# Logical OR Immediate 8-bit Constant (low byte)
+:ORL rd, ximm8 is opcode=0x14 & rd & ximm8 & rd_lo
+{
+ rd_lo = rd_lo | ximm8;
+
+ default_flags(rd_lo);
+}
+
+# Calculate Parity
+:PAR rd is opcode=0x0 & rd & xop8=0xf5
+{
+ parity(rd, $(XC));
+
+ default_flags(rd);
+}
+
+# Rotate Left
+:ROL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xe
+{
+ local cnt:2 = ximm4;
+ rd = (rd << cnt) | (rd >> (16 - cnt));
+
+ default_flags(rd);
+}
+
+:ROL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x16
+{
+ local cnt:2 = rs1 & 0xf;
+ rd = (rd << cnt) | (rd >> (16 - cnt));
+
+ default_flags(rd);
+}
+
+# Rotate Right
+:ROR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xf
+{
+ local cnt:2 = ximm4;
+ rd = (rd >> cnt) | (rd << (16 - rd));
+
+ default_flags(rd);
+}
+
+:ROR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x17
+{
+ local cnt:2 = rs1 & 0xf;
+ rd = (rd >> cnt) | (rd << (16 - rd));
+
+ default_flags(rd);
+}
+# Return to Scheduler
+# Implement as NOP for now
+:RTS is xop16=0x0200 {
+ XPC = TerminateThread();
+ return [XPC];
+}
+
+# Subtract with Carry
+:SBC rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x1
+{
+ local result:2 = rs1 - rs2 - zext($(XC));
+ rd = result;
+ subtraction_flagsC(rs1, rs2, result);
+}
+
+# Sign Extent Byte to Word
+:SEX rd is opcode=0x0 & rd & xop8=0xf4
+{
+ local result:1 = rd:1 & 0xff;
+ rd = sext(result);
+
+ default_flags(rd);
+}
+# Set Interrupt Flag
+# TODO: implement interrupt flags
+:SIF is xop16=0x0300
+{
+ setInterruptFlag();
+}
+
+:SIF rd is opcode=0x0 & rd & xop8=0xf7
+{
+ setInterruptFlag();
+}
+
+# Set Semaphore
+# TODO: implement semaphores
+:SSEM imm3 is opcode=0x0 & imm3 & xop8=0xf2
+{
+ local sem:1 = imm3;
+ setSemaphore(sem);
+}
+
+:SSEM rd is opcode=0x0 & rd & xop8=0xf3
+{
+ setSemaphore(rd);
+}
+
+# Store Byte to Memory (low byte)
+:STB rd, (rs1, offs5) is opcode=0xa & rd & rs1 & offs5
+{
+ local addr = rs1 + offs5;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = rd:1;
+ *dst = val;
+}
+
+:STB rd, (rs1, rs2) is opcode=0xe & rd & rs1 & rs2 & op2=0x0
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = rd:1;
+ *dst = val;
+}
+
+:STB rd, (rs1, rs2+) is opcode=0xe & rd & rs1 & rs2 & op2=0x1
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = rd:1;
+ *dst = val;
+ rs2 = rs2 + 1;
+}
+
+:STB rd, (rs1, -rs2) is opcode=0xe & rd & rs1 & rs2 & op2=0x2
+{
+ rs2 = rs2 - 1;
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:1 = rd:1;
+ *dst = val;
+}
+
+# Store Word to Memory
+:STW rd, (rs1, offs5) is opcode=0xb & rd & rs1 & offs5
+{
+ local addr = rs1 + offs5;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = rd;
+ *dst = val;
+}
+
+:STW rd, (rs1, rs2) is opcode=0xf & rd & rs1 & rs2 & op2=0x0
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = rd;
+ *dst = val;
+ rs2 = rs2 + 1;
+}
+
+:STW rd, (rs1, rs2+) is opcode=0xf & rd & rs1 & rs2 & op2=0x1
+{
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = rd;
+ *dst = val;
+ rs2 = rs2 + 2;
+}
+
+:STW rd, (rs1, -rs2) is opcode=0xf & rd & rs1 & rs2 & op2=0x2
+{
+ rs2 = rs2 - 2;
+ local addr = rs1 + rs2;
+ computePage(addr);
+ local dst:3 = segment(PPAGE,addr);
+ local val:2 = rd;
+ *dst = val;
+}
+
+# Subtract without Carry
+:SUB rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x0
+{
+ local result:2 = rs1 - rs2;
+ rd = result;
+
+ subtraction_flags(rs1, rs2, result);
+}
+
+
+# Subtract Immediate 8-bit constant (high byte)
+:SUBH rd, ximm8 is opcode=0x19 & rd & ximm8
+{
+ local val:2 = ximm8 << 8;
+ local result:2 = rd - val;
+
+ subtraction_flags(rd, val, result);
+
+ rd = result;
+}
+
+# Subtract Immediate 8-bit constant (low byte)
+:SUBL rd, ximm8 is opcode=0x18 & rd & ximm8
+{
+ local val:2 = ximm8;
+ local result:2 = rd - val;
+
+ $(XN) = (result s< 0);
+ $(XZ) = ((result == 0) & ($(XZ)==1));
+ $(XV) = ((~rd & result) & 0x8000) != 0;
+ $(XC) = ((rd & ~result) & 0x8000) != 0;
+ rd = result;
+}
+
+# Transfer from and to Special Registers
+:TFR rd, XCCR is opcode=0x0 & rd & xop8=0xf8 & XCCR
+{
+ local val:1 = ((($(XN) << 1) | $(XZ) << 1) | $(XV) << 1) | $(XC);
+ rd = zext(val);
+}
+
+:TFR XCCR, rd is opcode=0x0 & rd & xop8=0xf9 & XCCR
+{
+ XCCR = rd & 0xf;
+ $(XN) = rd[3,1];
+ $(XZ) = rd[2,1];
+ $(XV) = rd[1,1];
+ $(XC) = rd[0,1];
+}
+
+:TFR rd, XPC is opcode=0x0 & rd & xop8=0xfa & XPC
+{
+ rd = inst_next + 2;
+}
+
+# Test Register
+# Synonym for SUB R0, RS, R0
+:TST rs1 is opcode=0x3 & reg8=0x0 & rs1 & reg2=0x0 & op2=0x0
+{
+ local result:2 = rs1;
+
+ subtraction_flags(rs1,0,result);
+}
+
+# Logical Exclusive NOR
+:XNOR rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x3
+{
+ local result:2 = ~(rs1 ^ rs2);
+ rd = result;
+
+ default_flags(result);
+}
+
+# Logical Exclusive NOR Immediate 8-bit constant (high byte)
+:XNORH rd, ximm8 is opcode=0x17 & rd & ximm8 & rd_hi
+{
+ rd_hi = ~(rd_hi ^ ximm8);
+
+ default_flags(rd_hi);
+}
+
+# Logical Exclusive NOR Immediate 8-bit constant (low byte)
+:XNORL rd, ximm8 is opcode=0x16 & rd & ximm8 & rd_lo
+{
+ rd_lo= ~(rd_lo^ ximm8);
+
+ default_flags(rd_lo);
+}
+
+}
\ No newline at end of file
diff --git a/Ghidra/Processors/HCS12/data/manuals/HCS12.idx b/Ghidra/Processors/HCS12/data/manuals/HCS12.idx
new file mode 100644
index 0000000000..9e07ad6fc7
--- /dev/null
+++ b/Ghidra/Processors/HCS12/data/manuals/HCS12.idx
@@ -0,0 +1,356 @@
+@S12XCPUV2.pdf[ CPU12/CPU12X Reference Manual, Rev. v01.04 21 Apr. 2016, nxp.com ]
+ABA, 84
+ABX, 85
+ABY, 86
+ADCA, 87
+ADCB, 88
+ADDA, 89
+ADDB, 90
+ADDD, 91
+ADDX, 92
+ADDY, 93
+ADED, 94
+ADEX, 95
+ADEY, 96
+ANDA, 97
+ANDB, 98
+ANDCC, 99
+ANDX, 100
+ANDY, 101
+ASL, 102
+ASLA, 103
+ASLB, 104
+ASLD, 105
+ASLW, 106
+ASLX, 107
+ASLY, 108
+ASR, 109
+ASRA, 110
+ASRB, 111
+ASRW, 112
+ASRX, 113
+ASRY, 114
+BCC, 115
+BCLR, 116
+BCS, 117
+BEQ, 118
+BGE, 119
+BGND, 120
+BGT, 121
+BHI, 122
+BHS, 123
+BITA, 124
+BITB, 125
+BITX, 126
+BITY, 127
+BLE, 128
+BLO, 129
+BLS, 130
+BLT, 131
+BMI, 132
+BNE, 133
+BPL, 134
+BRA, 135
+BRCLR, 136
+BRN, 137
+BRSET, 138
+BSET, 139
+BSR, 140
+BTAS, 141
+BVC, 142
+BVS, 143
+CALL, 144
+CBA, 145
+CLC, 146
+CLI, 147
+CLR, 148
+CLRA, 149
+CLRB, 150
+CLRW, 151
+CLRX, 152
+CLRY, 153
+CLV, 154
+CMPA, 155
+CMPB, 156
+COM, 157
+COMA, 158
+COMB, 159
+COMW, 160
+COMX, 161
+COMY, 162
+CPD, 163
+CPED, 164
+CPES, 165
+CPEX, 166
+CPEY, 167
+CPS, 168
+CPX, 169
+CPY, 170
+DAA, 171
+DBEQ, 172
+DBNE, 173
+DEC, 174
+DECA, 175
+DECB, 176
+DECW, 177
+DECX, 178
+DECY, 179
+DES, 180
+DEX, 181
+DEY, 182
+EDIV, 183
+EDIVS, 184
+EMACS, 185
+EMAXD, 186
+EMAXM, 187
+EMIND, 188
+EMINM, 189
+EMUL, 190
+EMULS, 191
+EORA, 192
+EORB, 193
+EORX, 194
+EORY, 195
+ETBL, 196
+EXG, 197
+FDIV, 199
+GLDAA, 200
+GLDAB, 201
+GLDD, 202
+GLDS, 203
+GLDX, 204
+GLDY, 205
+GSTAA, 206
+GSTAB, 207
+GSTD, 208
+GSTS, 209
+GSTX, 210
+GSTY, 211
+IBEQ, 212
+IBNE, 213
+IDIV, 214
+IDIVS, 215
+INC, 216
+INCA, 217
+INCB, 218
+INCW, 219
+INCX, 220
+INCY, 221
+INS, 222
+INX, 223
+INY, 224
+JMP, 225
+JSR, 226
+LBCC, 227
+LBCS, 228
+LBEQ, 229
+LBGE, 230
+LBGT, 231
+LBHI, 232
+LBHS, 233
+LBLE, 234
+LBLO, 235
+LBLS, 236
+LBLT, 237
+LBMI, 238
+LBNE, 239
+LBPL, 240
+LBRA, 241
+LBRN, 242
+LBVC, 243
+LBVS, 244
+LDAA, 245
+LDAB, 246
+LDD, 247
+LDS, 248
+LDX, 249
+LDY, 250
+LEAS, 251
+LEAX, 252
+LEAY, 253
+LSL, 254
+LSLA, 255
+LSLB, 256
+LSLD, 257
+LSLW, 258
+LSLX, 259
+LSLY, 260
+LSR, 261
+LSRA, 262
+LSRB, 263
+LSRD, 264
+LSRW, 265
+LSRX, 266
+LSRY, 267
+MAXA, 268
+MAXM, 269
+MEM, 270
+MINA, 271
+MINM, 272
+MOVB, 273
+MOVW, 280
+MUL, 287
+NEG, 288
+NEGA, 289
+NEGB, 290
+NEGW, 291
+NEGX, 292
+NEGY, 293
+NOP, 294
+ORAA, 295
+ORAB, 296
+ORCC, 297
+ORX, 298
+ORY, 299
+PSHA, 300
+PSHB, 301
+PSHC, 302
+PSHCW, 303
+PSHD, 304
+PSHX, 305
+PSHY, 306
+PULA, 307
+PULB, 308
+PULC, 309
+PULCW, 310
+PULD, 311
+PULX, 312
+PULY, 313
+REV, 314
+REVW, 316
+ROL, 318
+ROLA, 319
+ROLB, 320
+ROLW, 321
+ROLX, 322
+ROLY, 323
+ROR, 324
+RORA, 325
+RORB, 326
+RORW, 327
+RORX, 328
+RORY, 329
+RTC, 330
+RTI, 331
+RTS, 332
+SBA, 333
+SBCA, 334
+SBCB, 335
+SBED, 336
+SBEX, 337
+SBEY, 338
+SEC, 339
+SEI, 340
+SEV, 341
+SEX, 342
+STAA, 343
+STAB, 344
+STD, 345
+STOP, 346
+STS, 348
+STX, 349
+STY, 350
+SUBA, 351
+SUBB, 352
+SUBD, 353
+SUBX, 354
+SUBY, 355
+SWI, 356
+SYS, 357
+TAB, 358
+TAP, 359
+TBA, 360
+TBEQ, 361
+TBL, 362
+TBNE, 363
+TFR, 364
+TPA, 366
+TRAP, 367
+TST, 368
+TSTA, 369
+TSTB, 370
+TSTW, 371
+TSTX, 372
+TSTY, 373
+TSX, 374
+TSY, 375
+TXS, 376
+TYS, 377
+WAI, 378
+WAV, 379
+XGDX, 380
+XGDY, 381
+
+@MC9S12XEP100RMV1.pdf[ MC9S12XEP100 Reference Manual, Rev. 1.25 02/2013, nxp.com ]
+ADC, 389
+ADD, 390
+ADDH, 391
+ADDL, 392
+AND, 393
+ANDH, 394
+ANDL, 395
+ASR, 396
+BCC, 397
+BCS, 398
+BEQ, 399
+BFEXT, 400
+BFFO, 401
+BFINS, 402
+BFINSI, 403
+BFINSX, 404
+BGE, 405
+BGT, 406
+BHI, 407
+BHS, 408
+BITH, 409
+BITL, 410
+BLE, 411
+BLO, 412
+BLS, 413
+BLT, 414
+BMI, 415
+BNE, 416
+BPL, 417
+BRA, 418
+BRK, 419
+BVC, 420
+BVS, 421
+CMP, 422
+CMPL, 423
+COM, 424
+CPC, 425
+CPCH, 426
+CSEM, 427
+CSL, 428
+CSR, 429
+JAL, 430
+LDB, 431
+LDH, 432
+LDL, 433
+LDW, 434
+LSL, 435
+LSR, 436
+MOV, 437
+NEG, 438
+NOP, 439
+OR, 440
+ORH, 441
+ORL, 442
+PAR, 443
+ROL, 444
+ROR, 445
+RTS, 446
+SBC, 447
+SEX, 448
+SIF, 449
+SSEM, 450
+STB, 451
+STW, 452
+SUB, 453
+SUBH, 454
+SUBL, 455
+TFR, 456
+TST, 457
+XNOR, 458
+XNORH, 459
+XNORL, 460
diff --git a/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConstantAnalyzer.java b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConstantAnalyzer.java
new file mode 100644
index 0000000000..f3220f56bd
--- /dev/null
+++ b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConstantAnalyzer.java
@@ -0,0 +1,165 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.plugin.core.analysis;
+
+import ghidra.program.model.address.Address;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.lang.Processor;
+import ghidra.program.model.listing.Instruction;
+import ghidra.program.model.listing.Program;
+import ghidra.program.model.pcode.PcodeOp;
+import ghidra.program.model.symbol.RefType;
+import ghidra.program.model.symbol.SourceType;
+import ghidra.program.util.ContextEvaluator;
+import ghidra.program.util.SymbolicPropogator;
+import ghidra.program.util.VarnodeContext;
+import ghidra.util.exception.CancelledException;
+import ghidra.util.task.TaskMonitor;
+
+public class HCS12ConstantAnalyzer extends ConstantPropagationAnalyzer {
+
+ private final static String PROCESSOR_NAME = "HCS12";
+
+ public HCS12ConstantAnalyzer() {
+ super(PROCESSOR_NAME);
+ }
+
+ @Override
+ public boolean canAnalyze(Program program) {
+ boolean canAnalyze = program.getLanguage().getProcessor()
+ .equals(Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME));
+
+ if (!canAnalyze) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private long hcs12TranslatePagedAddress(long addrWordOffset) {
+
+ long page = (addrWordOffset >> 16) & 0xff;
+
+ long addr = addrWordOffset & 0xffff;
+
+ // Register address
+ if ( (addr & 0xfC00) == 0x0) {
+ return addr;
+ }
+
+ // EPage address
+ if ((addr & 0xfc00) ==0x800) {
+ return 0x100000 | ((page << 10) | (addr & 0x3ff));
+ }
+
+ // EPage FF fixed address
+ if ((addr & 0xfc00) ==0xC00) {
+ return (0x4FF << 10) | (addr & 0x3ff);
+ }
+
+ // RPage address
+ if ((addr & 0xf000) ==0x1000) {
+ return (page << 12) | (addr & 0xfff);
+ }
+
+ // RPage FE fixed address
+ if ((addr & 0xf000) ==0x2000) {
+ return (0xFE << 12) | (addr & 0xfff);
+ }
+
+ // RPage FF fixed address
+ if ((addr & 0xf000) ==0x3000) {
+ return (0xFF << 12) | (addr & 0xfff);
+ }
+
+ // PPage FD fixed address
+ if ((addr & 0xc000) ==0x4000) {
+ return 0x400000 | (0xFD << 14) | (addr & 0x3fff);
+ }
+
+ // PPage address
+ if ((addr & 0xc000) ==0x8000) {
+ return 0x400000 | (page << 14) | (addr & 0x3fff);
+ }
+
+ // PPage FF fixed address
+ if ((addr & 0xc000) ==0xC000) {
+ return 0x400000 | (0xFF << 14) | (addr & 0x3fff);
+ }
+
+ return addr;
+ }
+
+ @Override
+ public AddressSetView flowConstants(final Program program, Address flowStart, AddressSetView flowSet,
+ final SymbolicPropogator symEval, final TaskMonitor monitor) throws CancelledException {
+
+ // follow all flows building up context
+ // use context to fill out addresses on certain instructions
+ ContextEvaluator eval = new ConstantPropagationContextEvaluator(trustWriteMemOption) {
+
+ @Override
+ public boolean evaluateReference(VarnodeContext context, Instruction instr, int pcodeop,
+ Address address, int size, RefType refType) {
+
+ if ((refType.isRead() || refType.isWrite()) &&
+ adjustPagedAddress(instr, address, refType)) {
+ return false;
+ }
+ return super.evaluateReference(context, instr, pcodeop, address, size, refType);
+ }
+
+ @Override
+ public Address evaluateConstant(VarnodeContext context, Instruction instr, int pcodeop, Address constant,
+ int size, RefType refType) {
+ // TODO Auto-generated method stub
+ return super.evaluateConstant(context, instr, pcodeop, constant, size, refType);
+ }
+
+ private boolean adjustPagedAddress(Instruction instr, Address address, RefType refType) {
+ PcodeOp[] pcode = instr.getPcode();
+ for (PcodeOp op : pcode) {
+ int numin = op.getNumInputs();
+ if (numin < 1) {
+ continue;
+ }
+ if (op.getOpcode() != PcodeOp.CALLOTHER) {
+ continue;
+ }
+ String opName = instr.getProgram().getLanguage().getUserDefinedOpName(
+ (int) op.getInput(0).getOffset());
+ if (opName != null && opName.equals("segment") && numin > 2) {
+ // assume this is a poorly created segment op addr
+ long high = address.getOffset() >> 16;
+ long low = address.getOffset() & 0xffff;
+ address = address.getNewAddress((high << 14) | (low & 0x3fff));
+ makeReference(instr, address, refType);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // handle the reference on the correct read or write operand
+ private void makeReference(Instruction instr, Address address, RefType refType) {
+ int index = (refType.isRead() ? 1 : 0);
+ instr.addOperandReference(index, address, refType, SourceType.ANALYSIS);
+ }
+ };
+
+ return symEval.flowConstants(flowStart, flowSet, eval, true, monitor);
+ }
+}
diff --git a/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConventionAnalyzer.java b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConventionAnalyzer.java
new file mode 100644
index 0000000000..b2c0f2f61a
--- /dev/null
+++ b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/plugin/core/analysis/HCS12ConventionAnalyzer.java
@@ -0,0 +1,133 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.plugin.core.analysis;
+
+import java.math.BigInteger;
+
+import ghidra.app.services.AbstractAnalyzer;
+import ghidra.app.services.AnalysisPriority;
+import ghidra.app.services.AnalyzerType;
+import ghidra.app.util.importer.MessageLog;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.lang.Processor;
+import ghidra.program.model.lang.Register;
+import ghidra.program.model.lang.RegisterValue;
+import ghidra.program.model.listing.Function;
+import ghidra.program.model.listing.FunctionIterator;
+import ghidra.program.model.listing.Instruction;
+import ghidra.program.model.listing.InstructionIterator;
+import ghidra.program.model.listing.Program;
+import ghidra.program.model.symbol.SourceType;
+import ghidra.util.Msg;
+import ghidra.util.exception.CancelledException;
+import ghidra.util.exception.InvalidInputException;
+import ghidra.util.task.TaskMonitor;
+
+public class HCS12ConventionAnalyzer extends AbstractAnalyzer {
+
+ private static final String NAME = "HCS12 Calling Convention";
+ private static final String DESCRIPTION = "Analyzes HCS12 programs with paged memory access to identify a calling convention for each function. This analyzer looks at the type of return used for the function to identify the calling convention.";
+
+ Register xgate = null;
+
+ public HCS12ConventionAnalyzer() {
+ super(NAME, DESCRIPTION, AnalyzerType.FUNCTION_ANALYZER);
+ setPriority(AnalysisPriority.FUNCTION_ANALYSIS);
+ setDefaultEnablement(true);
+ }
+
+ @Override
+ public boolean canAnalyze(Program program) {
+ // Only analyze HCS12 Programs
+ Processor processor = program.getLanguage().getProcessor();
+
+ boolean canDo = processor.equals(Processor.findOrPossiblyCreateProcessor("HCS12"));
+ if (canDo) {
+ xgate = program.getRegister("XGATE");
+ }
+
+ return canDo;
+ }
+
+ void checkReturn(Program program, Instruction instr) {
+ String mnemonic = instr.getMnemonicString().toLowerCase();
+
+ if (instr == null || !instr.getFlowType().isTerminal()) {
+ return;
+ }
+
+ // if XGATE set on instruction is XGATE
+ RegisterValue xgateValue = program.getProgramContext().getRegisterValue(xgate, instr.getMinAddress());
+ if (xgateValue != null && xgateValue.hasValue() && xgateValue.getUnsignedValue().equals(BigInteger.ONE)) {
+ setPrototypeModel(program, instr, "__asm_xgate");
+ return;
+ }
+
+ // set the correct convention
+ if (mnemonic.equals("rtc")) {
+ setPrototypeModel(program, instr, "__asmA_longcall");
+ return;
+ }
+
+ if (mnemonic.equals("rts")) {
+ setPrototypeModel(program, instr, "__asmA");
+ return;
+ }
+
+ }
+
+ private void setPrototypeModel(Program program, Instruction instr, String convention) {
+ if (convention == null) {
+ return;
+ }
+
+ Function func = program.getFunctionManager().getFunctionContaining(instr.getMinAddress());
+ if (func == null) {
+ return;
+ }
+
+ if (func.getSignatureSource() != SourceType.DEFAULT) {
+ return;
+ }
+
+ try {
+ func.setCallingConvention(convention);
+ } catch (InvalidInputException e) {
+ Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
+ throws CancelledException {
+
+ // get all functions within the set
+ FunctionIterator functions = program.getFunctionManager().getFunctions(set, true);
+ for (Function function : functions) {
+
+ // for each function body, search instructions
+ AddressSetView body = function.getBody();
+ InstructionIterator instructions = program.getListing().getInstructions(body, true);
+ for (Instruction instr : instructions) {
+ if (instr.getFlowType().isTerminal()) {
+ checkReturn(program, instr);
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/Ghidra/Processors/HCS12/src/main/java/ghidra/app/util/bin/format/elf/extend/HCS12X_ElfExtension.java b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/util/bin/format/elf/extend/HCS12X_ElfExtension.java
new file mode 100644
index 0000000000..c87952dcc0
--- /dev/null
+++ b/Ghidra/Processors/HCS12/src/main/java/ghidra/app/util/bin/format/elf/extend/HCS12X_ElfExtension.java
@@ -0,0 +1,178 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.util.bin.format.elf.extend;
+
+import ghidra.app.util.bin.format.elf.ElfConstants;
+import ghidra.app.util.bin.format.elf.ElfHeader;
+import ghidra.app.util.bin.format.elf.ElfLoadHelper;
+import ghidra.app.util.bin.format.elf.ElfProgramHeader;
+import ghidra.app.util.bin.format.elf.ElfProgramHeaderType;
+import ghidra.app.util.bin.format.elf.ElfSectionHeader;
+import ghidra.app.util.bin.format.elf.ElfSectionHeaderType;
+import ghidra.app.util.bin.format.elf.ElfSymbol;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.address.AddressSpace;
+import ghidra.program.model.lang.Language;
+import ghidra.program.model.listing.Program;
+
+public class HCS12X_ElfExtension extends ElfExtension {
+
+ // Elf Program Header Extensions
+ public static final ElfProgramHeaderType PT_HCS12_ARCHEXT =
+ new ElfProgramHeaderType(0x70000000, "PT_HCS12X_ARCHEXT", "HCS12X extension");
+
+ // Elf Section Header Extensions
+ public static final ElfSectionHeaderType SHT_HCS12_ATTRIBUTES =
+ new ElfSectionHeaderType(0x70000003, "SHT_AHCS12_ATTRIBUTES", "Attribute section");
+
+ @Override
+ public boolean canHandle(ElfHeader elf) {
+ return elf.e_machine() == ElfConstants.EM_68HC12;
+ }
+
+ @Override
+ public boolean canHandle(ElfLoadHelper elfLoadHelper) {
+ Language language = elfLoadHelper.getProgram().getLanguage();
+ return canHandle(elfLoadHelper.getElfHeader()) &&
+ "HCS12".equals(language.getProcessor().toString());
+ }
+
+ @Override
+ public String getDataTypeSuffix() {
+ return "_HCS12";
+ }
+
+ @Override
+ public Address getPreferredSegmentAddress(ElfLoadHelper elfLoadHelper, ElfProgramHeader elfProgramHeader) {
+
+ AddressSpace space =
+ getPreferredSegmentAddressSpace(elfLoadHelper, elfProgramHeader);
+
+ if (space.equals(AddressSpace.OTHER_SPACE)) {
+ return space.getAddress(elfProgramHeader.getVirtualAddress());
+ }
+
+ Program program = elfLoadHelper.getProgram();
+
+ long addrWordOffset = elfProgramHeader.getVirtualAddress();
+
+ if (space == program.getAddressFactory().getDefaultAddressSpace()) {
+ addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
+ }
+
+ addrWordOffset = hcs12TranslatePagedAddress(addrWordOffset);
+
+ return space.getTruncatedAddress(addrWordOffset, true);
+ }
+
+ @Override
+ public Address getPreferredSectionAddress(ElfLoadHelper elfLoadHelper,
+ ElfSectionHeader elfSectionHeader) {
+
+ // don't translate non-allocated sections
+ if (!elfSectionHeader.isAlloc()) {
+ return super.getPreferredSectionAddress(elfLoadHelper, elfSectionHeader);
+ }
+
+ Program program = elfLoadHelper.getProgram();
+
+ AddressSpace space = getPreferredSectionAddressSpace(elfLoadHelper, elfSectionHeader);
+
+ long addrWordOffset = elfSectionHeader.getAddress();
+
+ if (space == program.getAddressFactory().getDefaultAddressSpace()) {
+ addrWordOffset += elfLoadHelper.getImageBaseWordAdjustmentOffset();
+ }
+
+ addrWordOffset = hcs12TranslatePagedAddress(addrWordOffset);
+
+ return space.getTruncatedAddress(addrWordOffset, true);
+ }
+
+ private long hcs12TranslatePagedAddress(long addrWordOffset) {
+
+ long page = (addrWordOffset >> 16) & 0xff;
+
+ long addr = addrWordOffset & 0xffff;
+
+ // Register address
+ if ( (addr & 0xfC00) == 0x0) {
+ return addr;
+ }
+
+ // EPage address
+ if ((addr & 0xfc00) ==0x800) {
+ return 0x100000 | ((page << 10) | (addr & 0x3ff));
+ }
+
+ // EPage FF fixed address
+ if ((addr & 0xfc00) ==0xC00) {
+ return (0x4FF << 10) | (addr & 0x3ff);
+ }
+
+ // RPage address
+ if ((addr & 0xf000) ==0x1000) {
+ return (page << 12) | (addr & 0xfff);
+ }
+
+ // RPage FE fixed address
+ if ((addr & 0xf000) ==0x2000) {
+ return (0xFE << 12) | (addr & 0xfff);
+ }
+
+ // RPage FF fixed address
+ if ((addr & 0xf000) ==0x3000) {
+ return (0xFF << 12) | (addr & 0xfff);
+ }
+
+ // PPage FD fixed address
+ if ((addr & 0xc000) ==0x4000) {
+ return 0x400000 | (0xFD << 14) | (addr & 0x3fff);
+ }
+
+ // PPage address
+ if ((addr & 0xc000) ==0x8000) {
+ return 0x400000 | (page << 14) | (addr & 0x3fff);
+ }
+
+ // PPage FF fixed address
+ if ((addr & 0xc000) ==0xC000) {
+ return 0x400000 | (0xFF << 14) | (addr & 0x3fff);
+ }
+
+ return addr;
+ }
+
+ @Override
+ public Address evaluateElfSymbol(ElfLoadHelper elfLoadHelper, ElfSymbol elfSymbol,
+ Address address, boolean isExternal) {
+
+ if (isExternal) {
+ return address;
+ }
+
+ String symName = elfSymbol.getNameAsString();
+
+ long laddr = address.getOffset();
+
+ laddr = hcs12TranslatePagedAddress(laddr);
+
+ Address mappedAddr = address.getNewAddress(laddr);
+
+ return mappedAddr;
+ }
+
+}