]> localhost Git - WindEmu.git/commitdiff
formatting: add .clang-format, and run clang-format on all source files
authorGeorge Wright <gw@gwright.org.uk>
Thu, 25 Jun 2026 00:49:59 +0000 (17:49 -0700)
committerGeorge Wright <gw@gwright.org.uk>
Fri, 26 Jun 2026 00:54:24 +0000 (17:54 -0700)
29 files changed:
.clang-format [new file with mode: 0644]
WindCore/arm710.cpp
WindCore/arm710.h
WindCore/clps7111.cpp
WindCore/clps7111.h
WindCore/clps7111_defs.h
WindCore/clps7600.cpp
WindCore/clps7600.h
WindCore/common.h
WindCore/decoder-arm.c
WindCore/decoder-inlines.h
WindCore/decoder.c
WindCore/decoder.h
WindCore/emitter-arm.h
WindCore/emitter-inlines.h
WindCore/emubase.h
WindCore/etna.cpp
WindCore/etna.h
WindCore/hardware.h
WindCore/isa-inlines.h
WindCore/wind_defs.h
WindCore/windermere.cpp
WindCore/windermere.h
WindQt/main.cpp
WindQt/mainwindow.cpp
WindQt/mainwindow.h
WindQt/pdascreenwindow.cpp
WindQt/pdascreenwindow.h
WindWasm/main.cpp

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..f145697
--- /dev/null
@@ -0,0 +1,321 @@
+---
+Language:        Cpp
+AlignAfterOpenBracket: true
+AccessModifierOffset: -2
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    true
+AlignConsecutiveBitFields:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveDeclarations:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: true
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveMacros:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveShortCaseStatements:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCaseArrows: false
+  AlignCaseColons: false
+AlignConsecutiveTableGenBreakingDAGArgColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveTableGenCondOperatorColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveTableGenDefinitionColons:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionDeclarations: false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignEscapedNewlines: Right
+AlignOperands:   Align
+AlignTrailingComments:
+  AlignPPAndNotPP: true
+  Kind:            Always
+  OverEmptyLines:  0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowBreakBeforeNoexceptSpecifier: Never
+AllowBreakBeforeQtProperty: false
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseExpressionOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortCompoundRequirementOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: false
+AllowShortNamespacesOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AttributeMacros:
+  - __capability
+BinPackArguments: true
+BinPackLongBracedList: true
+BinPackParameters: BinPack
+BitFieldColonSpacing: Both
+BracedInitializerIndentWidth: -1
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterExternBlock: false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakAdjacentStringLiterals: true
+BreakAfterAttributes: Leave
+BreakAfterJavaFieldAnnotations: false
+BreakAfterOpenBracketBracedList: false
+BreakAfterOpenBracketFunction: false
+BreakAfterOpenBracketIf: false
+BreakAfterOpenBracketLoop: false
+BreakAfterOpenBracketSwitch: false
+BreakAfterReturnType: None
+BreakArrays:     true
+BreakBeforeBinaryOperators: None
+BreakBeforeCloseBracketBracedList: false
+BreakBeforeCloseBracketFunction: false
+BreakBeforeCloseBracketIf: false
+BreakBeforeCloseBracketLoop: false
+BreakBeforeCloseBracketSwitch: false
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Attach
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTemplateCloser: false
+BreakBeforeTernaryOperators: true
+BreakBinaryOperations: Never
+BreakConstructorInitializers: BeforeColon
+BreakFunctionDefinitionParameters: false
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+BreakTemplateDeclarations: MultiLine
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: AlignFirstComment
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+EnumTrailingComma: Leave
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: false
+IndentCaseLabels: false
+IndentExportBlock: true
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequiresClause: true
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+InsertBraces:    false
+InsertNewlineAtEOF: false
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+  Binary:          0
+  BinaryMinDigitsInsert: 0
+  BinaryMaxDigitsRemove: 0
+  Decimal:         0
+  DecimalMinDigitsInsert: 0
+  DecimalMaxDigitsRemove: 0
+  Hex:             0
+  HexMinDigitsInsert: 0
+  HexMaxDigitsRemove: 0
+  BinaryMinDigits: 0
+  DecimalMinDigits: 0
+  HexMinDigits:    0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLines:
+  AtEndOfFile:     false
+  AtStartOfBlock:  true
+  AtStartOfFile:   true
+KeepFormFeed:    false
+LambdaBodyIndentation: Signature
+LineEnding:      DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MainIncludeChar: Quote
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+NumericLiteralCase:
+  ExponentLetter:  Leave
+  HexDigit:        Leave
+  Prefix:          Leave
+  Suffix:          Leave
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+OneLineFormatOffRegex: ''
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakBeforeMemberAccess: 150
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakScopeResolution: 500
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+PPIndentWidth:   -1
+QualifierAlignment: Leave
+ReferenceAlignment: Pointer
+ReflowComments:  Always
+RemoveBracesLLVM: false
+RemoveEmptyLinesInUnwrappedLines: false
+RemoveParentheses: Leave
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SkipMacroDefinitionBody: false
+SortIncludes:
+  Enabled:         true
+  IgnoreCase:      false
+  IgnoreExtension: false
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterOperatorKeyword: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeJsonColon: false
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterForeachMacros: true
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   true
+  AfterNot:        false
+  AfterOverloadedOperator: false
+  AfterPlacementOperator: true
+  AfterRequiresInClause: false
+  AfterRequiresInExpression: false
+  BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBraces: Never
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInContainerLiterals: true
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParens:  Never
+SpacesInParensOptions:
+  ExceptDoubleParentheses: false
+  InCStyleCasts:   false
+  InConditionalStatements: false
+  InEmptyParentheses: false
+  Other:           false
+SpacesInSquareBrackets: false
+Standard:        Latest
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TableGenBreakInsideDAGArg: DontBreak
+TabWidth:        8
+UseTab:          Never
+VerilogBreakBetweenInstancePorts: true
+WhitespaceSensitiveMacros:
+  - BOOST_PP_STRINGIZE
+  - CF_SWIFT_NAME
+  - NS_SWIFT_NAME
+  - PP_STRINGIZE
+  - STRINGIZE
+WrapNamespaceBodyWithEmptyLines: Leave
+...
+
index 1496186e5c088a00411c8e40112b965e9e01e63f..4cbe1e1ee0278b2c18623d9bc0f42cb9f8603112 100644 (file)
 #include "common.h"
 
 // this will need changing if this code ever compiles on big-endian procs
-inline uint32_t read32LE(uint8_t *p) {
-       return *((uint32_t *)p);
-}
-inline void write32LE(uint8_t *p, uint32_t v) {
-       *((uint32_t *)p) = v;
-}
-
+inline uint32_t read32LE(uint8_t* p) { return *((uint32_t*)p); }
+inline void write32LE(uint8_t* p, uint32_t v) { *((uint32_t*)p) = v; }
 
 void ARM710::switchBank(BankIndex newBank) {
-       if (newBank != bank) {
-               // R13 and R14 need saving/loading for all banks
-               allModesBankedRegisters[bank][0] = GPRs[13];
-               allModesBankedRegisters[bank][1] = GPRs[14];
-               GPRs[13] = allModesBankedRegisters[newBank][0];
-               GPRs[14] = allModesBankedRegisters[newBank][1];
-
-               // R8 to R12 are only banked in FIQ mode
-               auto oldBankR8to12 = (bank == FiqBank) ? 1 : 0;
-               auto newBankR8to12 = (newBank == FiqBank) ? 1 : 0;
-               if (oldBankR8to12 != newBankR8to12) {
-                       // swap these sets around
-                       for (int i = 0; i < 5; i++)
-                               fiqBankedRegisters[oldBankR8to12][i] = GPRs[8 + i];
-                       for (int i = 0; i < 5; i++)
-                               GPRs[8 + i] = fiqBankedRegisters[newBankR8to12][i];
-               }
-
-               bank = newBank;
-       }
+  if (newBank != bank) {
+    // R13 and R14 need saving/loading for all banks
+    allModesBankedRegisters[bank][0] = GPRs[13];
+    allModesBankedRegisters[bank][1] = GPRs[14];
+    GPRs[13] = allModesBankedRegisters[newBank][0];
+    GPRs[14] = allModesBankedRegisters[newBank][1];
+
+    // R8 to R12 are only banked in FIQ mode
+    auto oldBankR8to12 = (bank == FiqBank) ? 1 : 0;
+    auto newBankR8to12 = (newBank == FiqBank) ? 1 : 0;
+    if (oldBankR8to12 != newBankR8to12) {
+      // swap these sets around
+      for (int i = 0; i < 5; i++)
+        fiqBankedRegisters[oldBankR8to12][i] = GPRs[8 + i];
+      for (int i = 0; i < 5; i++)
+        GPRs[8 + i] = fiqBankedRegisters[newBankR8to12][i];
+    }
+
+    bank = newBank;
+  }
 }
 
-
 void ARM710::switchMode(Mode newMode) {
-       auto oldMode = currentMode();
-       if (newMode != oldMode) {
-//             log("Switching mode! %x", newMode);
-               switchBank(modeToBank[newMode & 0xF]);
-
-               CPSR &= ~CPSR_ModeMask;
-               CPSR |= newMode;
-       }
+  auto oldMode = currentMode();
+  if (newMode != oldMode) {
+    //         log("Switching mode! %x", newMode);
+    switchBank(modeToBank[newMode & 0xF]);
+
+    CPSR &= ~CPSR_ModeMask;
+    CPSR |= newMode;
+  }
 }
 
 void ARM710::raiseException(Mode mode, uint32_t savedPC, uint32_t newPC) {
-       auto bankIndex = modeToBank[mode & 0xF];
-//     log("Raising exception mode %x, saving PC %08x, CPSR %08x", mode, savedPC, CPSR);
-       SPSRs[bankIndex] = CPSR;
+  auto bankIndex = modeToBank[mode & 0xF];
+  //   log("Raising exception mode %x, saving PC %08x, CPSR %08x", mode,
+  // savedPC, CPSR);
+  SPSRs[bankIndex] = CPSR;
 
-       switchMode(mode);
+  switchMode(mode);
 
-       prefetchCount = 0;
-       GPRs[14] = savedPC;
-       GPRs[15] = newPC;
+  prefetchCount = 0;
+  GPRs[14] = savedPC;
+  GPRs[15] = newPC;
 }
 
 void ARM710::requestFIQ() {
-       raiseException(FIQ32, getRealPC() + 4, 0x1C);
-       CPSR |= CPSR_FIQDisable;
-       CPSR |= CPSR_IRQDisable;
+  raiseException(FIQ32, getRealPC() + 4, 0x1C);
+  CPSR |= CPSR_FIQDisable;
+  CPSR |= CPSR_IRQDisable;
 }
 
 void ARM710::requestIRQ() {
-//     log("Requesting IRQ: Last exec = %08x, setting LR = %08x", lastPcExecuted(), getRealPC() + 4);
-       raiseException(IRQ32, getRealPC() + 4, 0x18);
-       CPSR |= CPSR_IRQDisable;
+  //   log("Requesting IRQ: Last exec = %08x, setting LR = %08x",
+  // lastPcExecuted(), getRealPC() + 4);
+  raiseException(IRQ32, getRealPC() + 4, 0x18);
+  CPSR |= CPSR_IRQDisable;
 }
 
 void ARM710::reset() {
 #ifdef ARM710T_CACHE
-       clearCache();
+  clearCache();
 #endif
-       raiseException(Supervisor32, 0, 0);
+  raiseException(Supervisor32, 0, 0);
 }
 
-
-
 uint32_t ARM710::tick() {
-       // pop an instruction off the end of the pipeline
-       bool haveInsn = false;
-       uint32_t insn;
-       MMUFault insnFault;
-       if (prefetchCount == 2) {
-               haveInsn = true;
-               insn = prefetch[1];
-               insnFault = prefetchFaults[1];
-       }
-
-       // move the instruction we fetched last tick once along
-       if (prefetchCount >= 1) {
-               prefetch[1] = prefetch[0];
-               prefetchFaults[1] = prefetchFaults[0];
-       }
-
-       // fetch a new instruction
-       auto newInsn = readVirtual(GPRs[15], V32);
-       GPRs[15] += 4;
-       prefetch[0] = newInsn.first.value_or(0);
-       prefetchFaults[0] = newInsn.second;
-       if (prefetchCount < 2)
-               prefetchCount++;
-
-       // now deal with the one we popped
-       uint32_t clocks = 1;
-       if (haveInsn) {
-               pcHistory[pcHistoryIndex] = {GPRs[15] - 0xC, insn};
-               pcHistoryIndex = (pcHistoryIndex + 1) % PcHistoryCount;
-               if (insnFault != NoFault) {
-                       // Raise a prefetch error
-                       // These do not set FSR or FAR
-                       log("prefetch error! %08x", insnFault >> MMUFaultAddressShift);
-                       logPcHistory();
-                       raiseException(Abort32, GPRs[15] - 8, 0xC);
-               } else {
-                       clocks += executeInstruction(insn);
-               }
-       }
-
-       if (faultTriggeredThisCycle) {
-               // data abort time!
-               faultTriggeredThisCycle = false;
-               raiseException(Abort32, GPRs[15] - 4, 0x10);
-       }
-
-       return clocks;
+  // pop an instruction off the end of the pipeline
+  bool haveInsn = false;
+  uint32_t insn;
+  MMUFault insnFault;
+  if (prefetchCount == 2) {
+    haveInsn = true;
+    insn = prefetch[1];
+    insnFault = prefetchFaults[1];
+  }
+
+  // move the instruction we fetched last tick once along
+  if (prefetchCount >= 1) {
+    prefetch[1] = prefetch[0];
+    prefetchFaults[1] = prefetchFaults[0];
+  }
+
+  // fetch a new instruction
+  auto newInsn = readVirtual(GPRs[15], V32);
+  GPRs[15] += 4;
+  prefetch[0] = newInsn.first.value_or(0);
+  prefetchFaults[0] = newInsn.second;
+  if (prefetchCount < 2)
+    prefetchCount++;
+
+  // now deal with the one we popped
+  uint32_t clocks = 1;
+  if (haveInsn) {
+    pcHistory[pcHistoryIndex] = {GPRs[15] - 0xC, insn};
+    pcHistoryIndex = (pcHistoryIndex + 1) % PcHistoryCount;
+    if (insnFault != NoFault) {
+      // Raise a prefetch error
+      // These do not set FSR or FAR
+      log("prefetch error! %08x", insnFault >> MMUFaultAddressShift);
+      logPcHistory();
+      raiseException(Abort32, GPRs[15] - 8, 0xC);
+    } else {
+      clocks += executeInstruction(insn);
+    }
+  }
+
+  if (faultTriggeredThisCycle) {
+    // data abort time!
+    faultTriggeredThisCycle = false;
+    raiseException(Abort32, GPRs[15] - 4, 0x10);
+  }
+
+  return clocks;
 }
 
-
 static inline uint32_t extract(uint32_t value, uint32_t hiBit, uint32_t loBit) {
-       return (value >> loBit) & ((1 << (hiBit - loBit + 1)) - 1);
-//     return (value >> (32 - offset - length)) & ((1 << length) - 1);
+  return (value >> loBit) & ((1 << (hiBit - loBit + 1)) - 1);
+  //   return (value >> (32 - offset - length)) & ((1 << length) - 1);
 }
 static inline bool extract1(uint32_t value, uint32_t bit) {
-       return (value >> bit) & 1;
+  return (value >> bit) & 1;
 }
 
-
 uint32_t ARM710::executeInstruction(uint32_t i) {
-       uint32_t cycles = 1;
-//     log("executing insn %08x @ %08x", i, GPRs[15] - 0xC);
-
-       // a big old dispatch thing here
-       // but first, conditions!
-       if (!checkCondition(extract(i, 31, 28)))
-               return cycles;
-
-       if ((i & 0x0F000000) == 0x0F000000)
-               raiseException(Supervisor32, GPRs[15] - 8, 0x08);
-       else if ((i & 0x0F000F10) == 0x0E000F10)
-               cycles += execCP15RegisterTransfer(extract(i,23,21), extract1(i,20), extract(i,19,16), extract(i,15,12), extract(i,7,5), extract(i,3,0));
-       else if ((i & 0x0E000000) == 0x0A000000)
-               cycles += execBranch(extract1(i,24), extract(i,23,0));
-       else if ((i & 0x0E000000) == 0x08000000)
-               cycles += execBlockDataTransfer(extract(i,24,20), extract(i,19,16), extract(i,15,0));
-       else if ((i & 0x0C000000) == 0x04000000)
-               cycles += execSingleDataTransfer(extract(i,25,20), extract(i,19,16), extract(i,15,12), extract(i,11,0));
-       else if ((i & 0x0FB00FF0) == 0x01000090)
-               cycles += execSingleDataSwap(extract1(i,22), extract(i,19,16), extract(i,15,12), extract(i,3,0));
-       else if ((i & 0x0F8000F0) == 0x00000090)
-               cycles += execMultiply(extract(i,21,20), extract(i,19,16), extract(i,15,12), extract(i,11,8), extract(i,3,0));
-       else if ((i & 0x0F8000F0) == 0x00800090 && isTVersion)
-               cycles += execMultiplyLong(extract(i,22,20), extract(i,19,16), extract(i,15,12), extract(i,11,8), extract(i,3,0));
-       else if ((i & 0x0E000090) == 0x00000090) {
-               cycles += execSingleHalfWordDataTransfer(extract(i, 24, 20), extract(i, 19, 16), extract(i, 15, 12), extract(i, 11, 8), extract(i, 6, 5), extract(i, 3, 0));
-       } else if ((i & 0x0C000000) == 0x00000000)
-               cycles += execDataProcessing(extract1(i,25), extract(i,24,21), extract1(i,20), extract(i,19,16), extract(i,15,12), extract(i,11,0));
-       else
-               raiseException(Undefined32, GPRs[15] - 8, 0x04);
-
-       return cycles;
+  uint32_t cycles = 1;
+  //   log("executing insn %08x @ %08x", i, GPRs[15] - 0xC);
+
+  // a big old dispatch thing here
+  // but first, conditions!
+  if (!checkCondition(extract(i, 31, 28)))
+    return cycles;
+
+  if ((i & 0x0F000000) == 0x0F000000)
+    raiseException(Supervisor32, GPRs[15] - 8, 0x08);
+  else if ((i & 0x0F000F10) == 0x0E000F10)
+    cycles += execCP15RegisterTransfer(extract(i, 23, 21), extract1(i, 20),
+                                       extract(i, 19, 16), extract(i, 15, 12),
+                                       extract(i, 7, 5), extract(i, 3, 0));
+  else if ((i & 0x0E000000) == 0x0A000000)
+    cycles += execBranch(extract1(i, 24), extract(i, 23, 0));
+  else if ((i & 0x0E000000) == 0x08000000)
+    cycles += execBlockDataTransfer(extract(i, 24, 20), extract(i, 19, 16),
+                                    extract(i, 15, 0));
+  else if ((i & 0x0C000000) == 0x04000000)
+    cycles += execSingleDataTransfer(extract(i, 25, 20), extract(i, 19, 16),
+                                     extract(i, 15, 12), extract(i, 11, 0));
+  else if ((i & 0x0FB00FF0) == 0x01000090)
+    cycles += execSingleDataSwap(extract1(i, 22), extract(i, 19, 16),
+                                 extract(i, 15, 12), extract(i, 3, 0));
+  else if ((i & 0x0F8000F0) == 0x00000090)
+    cycles +=
+        execMultiply(extract(i, 21, 20), extract(i, 19, 16), extract(i, 15, 12),
+                     extract(i, 11, 8), extract(i, 3, 0));
+  else if ((i & 0x0F8000F0) == 0x00800090 && isTVersion)
+    cycles += execMultiplyLong(extract(i, 22, 20), extract(i, 19, 16),
+                               extract(i, 15, 12), extract(i, 11, 8),
+                               extract(i, 3, 0));
+  else if ((i & 0x0E000090) == 0x00000090) {
+    cycles += execSingleHalfWordDataTransfer(
+        extract(i, 24, 20), extract(i, 19, 16), extract(i, 15, 12),
+        extract(i, 11, 8), extract(i, 6, 5), extract(i, 3, 0));
+  } else if ((i & 0x0C000000) == 0x00000000)
+    cycles += execDataProcessing(extract1(i, 25), extract(i, 24, 21),
+                                 extract1(i, 20), extract(i, 19, 16),
+                                 extract(i, 15, 12), extract(i, 11, 0));
+  else
+    raiseException(Undefined32, GPRs[15] - 8, 0x04);
+
+  return cycles;
 }
 
-uint32_t ARM710::execDataProcessing(bool I, uint32_t Opcode, bool S, uint32_t Rn, uint32_t Rd, uint32_t Operand2)
-{
-       uint32_t cycles = 0; // TODO increment me semi-accurately
-       bool shifterCarryOutput;
-
-       // compute our Op1 (may be unnecessary but that's ok)
-       uint32_t op1 = GPRs[Rn];
-
-       // compute our Op2
-       uint32_t op2;
-       if (!I) {
-               // REGISTER
-               uint32_t Rm = extract(Operand2, 3, 0);
-               op2 = GPRs[Rm];
-
-               uint8_t shiftBy;
-
-               // this is the real painful one, honestly
-               if (extract(Operand2, 4, 4)) {
-                       // Shift by Register
-                       uint32_t Rs = extract(Operand2, 11, 8);
-                       shiftBy = GPRs[Rs] & 0xFF;
-               } else {
-                       // Shift by Immediate
-                       shiftBy = extract(Operand2, 11, 7);
-
-                       if (Rn == 15) // if PC is fetched...
-                               op1 -= 4; // compensate for prefetching
-                       if (Rm == 15)
-                               op2 -= 4;
-               }
-
-               if (extract(Operand2, 4, 4) && (shiftBy == 0)) {
-                       // register shift by 0 never does anything
-                       shifterCarryOutput = flagC();
-               } else {
-                       switch (extract(Operand2, 6, 5)) {
-                       case 0: // Logical Left (LSL)
-                               if (shiftBy == 0) {
-                                       shifterCarryOutput = flagC();
-                                       // no change to op2!
-                               } else if (shiftBy <= 31) {
-                                       shifterCarryOutput = extract1(op2, 31 - shiftBy);
-                                       op2 <<= shiftBy;
-                               } else if (shiftBy == 32) {
-                                       shifterCarryOutput = extract1(op2, 0);
-                                       op2 = 0;
-                               } else /*if (shiftBy >= 33)*/ {
-                                       shifterCarryOutput = false;
-                                       op2 = 0;
-                               }
-                               break;
-                       case 1: // Logical Right (LSR)
-                               if (shiftBy == 0 || shiftBy == 32) {
-                                       shifterCarryOutput = extract1(op2, 31);
-                                       op2 = 0;
-                               } else if (shiftBy <= 31) {
-                                       shifterCarryOutput = extract1(op2, shiftBy - 1);
-                                       op2 >>= shiftBy;
-                               } else /*if (shiftBy >= 33)*/ {
-                                       shifterCarryOutput = false;
-                                       op2 = 0;
-                               }
-                               break;
-                       case 2: // Arithmetic Right (ASR)
-                               if (shiftBy == 0 || shiftBy >= 32) {
-                                       shifterCarryOutput = extract1(op2, 31);
-                                       op2 = (int32_t)op2 >> 31;
-                               } else /*if (shiftBy <= 31)*/ {
-                                       shifterCarryOutput = extract1(op2, shiftBy - 1);
-                                       op2 = (int32_t)op2 >> shiftBy;
-                               }
-                               break;
-                       case 3: // Rotate Right (ROR)
-                               if (shiftBy == 0) { // treated as RRX
-                                       shifterCarryOutput = op2 & 1;
-                                       op2 >>= 1;
-                                       op2 |= flagC() ? 0x80000000 : 0;
-                               } else {
-                                       shiftBy %= 32;
-                                       if (shiftBy == 0) { // like 32
-                                               shifterCarryOutput = extract1(op2, 31);
-                                               // no change to op2
-                                       } else {
-                                               shifterCarryOutput = extract1(op2, shiftBy - 1);
-                                               op2 = ROR(op2, shiftBy);
-                                       }
-                               }
-                               break;
-                       }
-               }
-       } else {
-               // IMMEDIATE
-               if (Rn == 15) // if PC is fetched...
-                       op1 -= 4; // compensate for prefetching
-
-               uint32_t Rotate = extract(Operand2, 11, 8);
-               uint32_t Imm = extract(Operand2, 7, 0);
-               op2 = ROR(Imm, Rotate * 2);
-               shifterCarryOutput = flagC(); // correct? unsure...
-       }
-
-       // we have our operands, what next
-       uint64_t result = 0;
-       uint32_t flags = 0;
-
-#define LOGICAL_OP(v) \
-       result = v; \
-       flags |= (result & 0xFFFFFFFF) ? 0 : CPSR_Z; \
-       flags |= (result & 0x80000000) ? CPSR_N : 0; \
-       flags |= shifterCarryOutput ? CPSR_C : 0; \
-       flags |= (CPSR & CPSR_V);
-
-#define ADD_OP(a, b, c) \
-       result = (uint64_t)(a) + (uint64_t)(b) + (uint64_t)(c); \
-       flags |= (result & 0xFFFFFFFF) ? 0 : CPSR_Z; \
-       flags |= (result & 0x80000000) ? CPSR_N : 0; \
-       flags |= (result & 0x100000000) ? CPSR_C : 0; \
-       flags |= ((((a) & 0x80000000) == ((b) & 0x80000000)) && (((a) & 0x80000000) != (result & 0x80000000))) ? CPSR_V : 0;
+uint32_t ARM710::execDataProcessing(bool I, uint32_t Opcode, bool S,
+                                    uint32_t Rn, uint32_t Rd,
+                                    uint32_t Operand2) {
+  uint32_t cycles = 0; // TODO increment me semi-accurately
+  bool shifterCarryOutput;
+
+  // compute our Op1 (may be unnecessary but that's ok)
+  uint32_t op1 = GPRs[Rn];
+
+  // compute our Op2
+  uint32_t op2;
+  if (!I) {
+    // REGISTER
+    uint32_t Rm = extract(Operand2, 3, 0);
+    op2 = GPRs[Rm];
+
+    uint8_t shiftBy;
+
+    // this is the real painful one, honestly
+    if (extract(Operand2, 4, 4)) {
+      // Shift by Register
+      uint32_t Rs = extract(Operand2, 11, 8);
+      shiftBy = GPRs[Rs] & 0xFF;
+    } else {
+      // Shift by Immediate
+      shiftBy = extract(Operand2, 11, 7);
+
+      if (Rn == 15) // if PC is fetched...
+        op1 -= 4;   // compensate for prefetching
+      if (Rm == 15)
+        op2 -= 4;
+    }
+
+    if (extract(Operand2, 4, 4) && (shiftBy == 0)) {
+      // register shift by 0 never does anything
+      shifterCarryOutput = flagC();
+    } else {
+      switch (extract(Operand2, 6, 5)) {
+      case 0: // Logical Left (LSL)
+        if (shiftBy == 0) {
+          shifterCarryOutput = flagC();
+          // no change to op2!
+        } else if (shiftBy <= 31) {
+          shifterCarryOutput = extract1(op2, 31 - shiftBy);
+          op2 <<= shiftBy;
+        } else if (shiftBy == 32) {
+          shifterCarryOutput = extract1(op2, 0);
+          op2 = 0;
+        } else /*if (shiftBy >= 33)*/ {
+          shifterCarryOutput = false;
+          op2 = 0;
+        }
+        break;
+      case 1: // Logical Right (LSR)
+        if (shiftBy == 0 || shiftBy == 32) {
+          shifterCarryOutput = extract1(op2, 31);
+          op2 = 0;
+        } else if (shiftBy <= 31) {
+          shifterCarryOutput = extract1(op2, shiftBy - 1);
+          op2 >>= shiftBy;
+        } else /*if (shiftBy >= 33)*/ {
+          shifterCarryOutput = false;
+          op2 = 0;
+        }
+        break;
+      case 2: // Arithmetic Right (ASR)
+        if (shiftBy == 0 || shiftBy >= 32) {
+          shifterCarryOutput = extract1(op2, 31);
+          op2 = (int32_t)op2 >> 31;
+        } else /*if (shiftBy <= 31)*/ {
+          shifterCarryOutput = extract1(op2, shiftBy - 1);
+          op2 = (int32_t)op2 >> shiftBy;
+        }
+        break;
+      case 3:               // Rotate Right (ROR)
+        if (shiftBy == 0) { // treated as RRX
+          shifterCarryOutput = op2 & 1;
+          op2 >>= 1;
+          op2 |= flagC() ? 0x80000000 : 0;
+        } else {
+          shiftBy %= 32;
+          if (shiftBy == 0) { // like 32
+            shifterCarryOutput = extract1(op2, 31);
+            // no change to op2
+          } else {
+            shifterCarryOutput = extract1(op2, shiftBy - 1);
+            op2 = ROR(op2, shiftBy);
+          }
+        }
+        break;
+      }
+    }
+  } else {
+    // IMMEDIATE
+    if (Rn == 15) // if PC is fetched...
+      op1 -= 4;   // compensate for prefetching
+
+    uint32_t Rotate = extract(Operand2, 11, 8);
+    uint32_t Imm = extract(Operand2, 7, 0);
+    op2 = ROR(Imm, Rotate * 2);
+    shifterCarryOutput = flagC(); // correct? unsure...
+  }
+
+  // we have our operands, what next
+  uint64_t result = 0;
+  uint32_t flags = 0;
+
+#define LOGICAL_OP(v)                                                          \
+  result = v;                                                                  \
+  flags |= (result & 0xFFFFFFFF) ? 0 : CPSR_Z;                                 \
+  flags |= (result & 0x80000000) ? CPSR_N : 0;                                 \
+  flags |= shifterCarryOutput ? CPSR_C : 0;                                    \
+  flags |= (CPSR & CPSR_V);
+
+#define ADD_OP(a, b, c)                                                        \
+  result = (uint64_t)(a) + (uint64_t)(b) + (uint64_t)(c);                      \
+  flags |= (result & 0xFFFFFFFF) ? 0 : CPSR_Z;                                 \
+  flags |= (result & 0x80000000) ? CPSR_N : 0;                                 \
+  flags |= (result & 0x100000000) ? CPSR_C : 0;                                \
+  flags |= ((((a) & 0x80000000) == ((b) & 0x80000000)) &&                      \
+            (((a) & 0x80000000) != (result & 0x80000000)))                     \
+               ? CPSR_V                                                        \
+               : 0;
 
 #define SUB_OP(a, b, c) ADD_OP(a, ~b, c)
 
-
-       switch (Opcode) {
-       case 0:   LOGICAL_OP(op1 & op2);     break; // AND
-       case 1:   LOGICAL_OP(op1 ^ op2);     break; // EOR
-       case 2:   SUB_OP(op1, op2, 1);       break; // SUB
-       case 3:   SUB_OP(op2, op1, 1);       break; // RSB
-       case 4:   ADD_OP(op1, op2, 0);       break; // ADD
-       case 5:   ADD_OP(op1, op2, flagC()); break; // ADC
-       case 6:   SUB_OP(op1, op2, flagC()); break; // SBC
-       case 7:   SUB_OP(op2, op1, flagC()); break; // RSC
-       case 8:   LOGICAL_OP(op1 & op2);     break; // TST
-       case 9:   LOGICAL_OP(op1 ^ op2);     break; // TEQ
-       case 0xA: SUB_OP(op1, op2, 1);       break; // CMP
-       case 0xB: ADD_OP(op1, op2, 0);       break; // CMN
-       case 0xC: LOGICAL_OP(op1 | op2);     break; // ORR
-       case 0xD: LOGICAL_OP(op2);           break; // MOV
-       case 0xE: LOGICAL_OP(op1 & ~op2);    break; // BIC
-       case 0xF: LOGICAL_OP(~op2);          break; // MVN
-       }
-
-       if (Opcode >= 8 && Opcode <= 0xB) {
-               // Output-less opcodes: special behaviour
-               if (S) {
-                       CPSR = (CPSR & ~CPSR_FlagMask) | flags;
-//                     log("CPSR setflags=%08x results in CPSR=%08x", flags, CPSR);
-               } else if (Opcode == 8) {
-                       // MRS, CPSR -> Reg
-                       GPRs[Rd] = CPSR;
-//                     log("r%d <- CPSR(%08x)", Rd, GPRs[Rd]);
-               } else if (Opcode == 9) {
-                       // MSR, Reg -> CPSR
-                       bool canChangeMode = extract1(Rn, 0);
-                       if (canChangeMode && isPrivileged()) {
-                               auto newCPSR = GPRs[extract(Operand2, 3, 0)];
-                               switchMode(modeFromCPSR(newCPSR));
-                               CPSR = newCPSR;
-//                             log("CPSR change privileged: %08x", CPSR);
-                       } else {
-                               // for the flag-only version, immediates are allowed
-                               // so we just re-use what was calculated earlier...
-                               auto newFlag = I ? op2 : GPRs[extract(Operand2, 3, 0)];
-                               CPSR &= ~CPSR_FlagMask;
-                               CPSR |= (newFlag & CPSR_FlagMask);
-//                             log("CPSR change unprivileged: new=%08x result=%08x", newFlag, CPSR);
-                       }
-               } else if (Opcode == 0xA) {
-                       // MRS, SPSR -> Reg
-                       if (isPrivileged()) {
-                               GPRs[Rd] = SPSRs[currentBank()];
-//                             log("r%d <- SPSR(%08x)", Rd, GPRs[Rd]);
-                       }
-               } else /*if (Opcode == 0xB)*/ {
-                       bool canChangeMode = extract1(Rn, 0);
-                       if (isPrivileged()) {
-                               if (canChangeMode) {
-                                       SPSRs[currentBank()] = GPRs[extract(Operand2, 3, 0)];
-//                                     log("SPSR change privileged: %08x", SPSRs[currentBank()]);
-                               } else {
-                                       // same hat
-                                       auto newFlag = I ? op2 : GPRs[extract(Operand2, 3, 0)];
-                                       SPSRs[currentBank()] &= ~CPSR_FlagMask;
-                                       SPSRs[currentBank()] |= (newFlag & CPSR_FlagMask);
-//                                     log("SPSR change unprivileged: new=%08x result=%08x", newFlag, SPSRs[currentBank()]);
-                               }
-                       }
-               }
-       } else {
-               GPRs[Rd] = result & 0xFFFFFFFF;
-
-               if (Rd == 15) {
-                       // Writing to PC
-                       // Special things occur here!
-                       GPRs[Rd] &= ~3; // TODO is this really necessary??
-                       prefetchCount = 0;
-                       if (S && isPrivileged()) {
-                               // We SHOULD be privileged
-                               // (Raise an error otherwise...?)
-                               auto saved = SPSRs[currentBank()];
-                               switchMode(modeFromCPSR(saved));
-                               CPSR = saved;
-//                             log("dataproc restore CPSR: %08x", saved);
-                       }
-               } else if (S) {
-                       CPSR = (CPSR & ~CPSR_FlagMask) | flags;
-//                     log("dataproc flag change: flags=%08x CPSR=%08x", flags, CPSR);
-               }
-       }
-
-       return cycles;
+  switch (Opcode) {
+  case 0:
+    LOGICAL_OP(op1 & op2);
+    break; // AND
+  case 1:
+    LOGICAL_OP(op1 ^ op2);
+    break; // EOR
+  case 2:
+    SUB_OP(op1, op2, 1);
+    break; // SUB
+  case 3:
+    SUB_OP(op2, op1, 1);
+    break; // RSB
+  case 4:
+    ADD_OP(op1, op2, 0);
+    break; // ADD
+  case 5:
+    ADD_OP(op1, op2, flagC());
+    break; // ADC
+  case 6:
+    SUB_OP(op1, op2, flagC());
+    break; // SBC
+  case 7:
+    SUB_OP(op2, op1, flagC());
+    break; // RSC
+  case 8:
+    LOGICAL_OP(op1 & op2);
+    break; // TST
+  case 9:
+    LOGICAL_OP(op1 ^ op2);
+    break; // TEQ
+  case 0xA:
+    SUB_OP(op1, op2, 1);
+    break; // CMP
+  case 0xB:
+    ADD_OP(op1, op2, 0);
+    break; // CMN
+  case 0xC:
+    LOGICAL_OP(op1 | op2);
+    break; // ORR
+  case 0xD:
+    LOGICAL_OP(op2);
+    break; // MOV
+  case 0xE:
+    LOGICAL_OP(op1 & ~op2);
+    break; // BIC
+  case 0xF:
+    LOGICAL_OP(~op2);
+    break; // MVN
+  }
+
+  if (Opcode >= 8 && Opcode <= 0xB) {
+    // Output-less opcodes: special behaviour
+    if (S) {
+      CPSR = (CPSR & ~CPSR_FlagMask) | flags;
+      //                       log("CPSR setflags=%08x results in CPSR=%08x",
+      // flags, CPSR);
+    } else if (Opcode == 8) {
+      // MRS, CPSR -> Reg
+      GPRs[Rd] = CPSR;
+      //                       log("r%d <- CPSR(%08x)", Rd, GPRs[Rd]);
+    } else if (Opcode == 9) {
+      // MSR, Reg -> CPSR
+      bool canChangeMode = extract1(Rn, 0);
+      if (canChangeMode && isPrivileged()) {
+        auto newCPSR = GPRs[extract(Operand2, 3, 0)];
+        switchMode(modeFromCPSR(newCPSR));
+        CPSR = newCPSR;
+        //                             log("CPSR change privileged: %08x",
+        // CPSR);
+      } else {
+        // for the flag-only version, immediates are allowed
+        // so we just re-use what was calculated earlier...
+        auto newFlag = I ? op2 : GPRs[extract(Operand2, 3, 0)];
+        CPSR &= ~CPSR_FlagMask;
+        CPSR |= (newFlag & CPSR_FlagMask);
+        //                             log("CPSR change unprivileged: new=%08x
+        // result=%08x", newFlag, CPSR);
+      }
+    } else if (Opcode == 0xA) {
+      // MRS, SPSR -> Reg
+      if (isPrivileged()) {
+        GPRs[Rd] = SPSRs[currentBank()];
+        //                             log("r%d <- SPSR(%08x)", Rd, GPRs[Rd]);
+      }
+    } else /*if (Opcode == 0xB)*/ {
+      bool canChangeMode = extract1(Rn, 0);
+      if (isPrivileged()) {
+        if (canChangeMode) {
+          SPSRs[currentBank()] = GPRs[extract(Operand2, 3, 0)];
+          //                                   log("SPSR change privileged:
+          //%08x", SPSRs[currentBank()]);
+        } else {
+          // same hat
+          auto newFlag = I ? op2 : GPRs[extract(Operand2, 3, 0)];
+          SPSRs[currentBank()] &= ~CPSR_FlagMask;
+          SPSRs[currentBank()] |= (newFlag & CPSR_FlagMask);
+          //                                   log("SPSR change unprivileged:
+          // new=%08x result=%08x", newFlag, SPSRs[currentBank()]);
+        }
+      }
+    }
+  } else {
+    GPRs[Rd] = result & 0xFFFFFFFF;
+
+    if (Rd == 15) {
+      // Writing to PC
+      // Special things occur here!
+      GPRs[Rd] &= ~3; // TODO is this really necessary??
+      prefetchCount = 0;
+      if (S && isPrivileged()) {
+        // We SHOULD be privileged
+        // (Raise an error otherwise...?)
+        auto saved = SPSRs[currentBank()];
+        switchMode(modeFromCPSR(saved));
+        CPSR = saved;
+        //                             log("dataproc restore CPSR: %08x",
+        // saved);
+      }
+    } else if (S) {
+      CPSR = (CPSR & ~CPSR_FlagMask) | flags;
+      //                       log("dataproc flag change: flags=%08x
+      // CPSR=%08x", flags, CPSR);
+    }
+  }
+
+  return cycles;
 }
 
-uint32_t ARM710::execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn, uint32_t Rs, uint32_t Rm)
-{
-       // no need for R15 fuckery
-       // datasheet says it's not allowed here
-       if (AS & 2)
-               GPRs[Rd] = GPRs[Rm] * GPRs[Rs] + GPRs[Rn];
-       else
-               GPRs[Rd] = GPRs[Rm] * GPRs[Rs];
-
-       if (AS & 1) {
-               CPSR &= ~(CPSR_N | CPSR_Z);
-               CPSR |= GPRs[Rd] ? 0 : CPSR_Z;
-               CPSR |= (GPRs[Rd] & 0x80000000) ? CPSR_N : 0;
-       }
-
-       return 0;
+uint32_t ARM710::execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn,
+                              uint32_t Rs, uint32_t Rm) {
+  // no need for R15 fuckery
+  // datasheet says it's not allowed here
+  if (AS & 2)
+    GPRs[Rd] = GPRs[Rm] * GPRs[Rs] + GPRs[Rn];
+  else
+    GPRs[Rd] = GPRs[Rm] * GPRs[Rs];
+
+  if (AS & 1) {
+    CPSR &= ~(CPSR_N | CPSR_Z);
+    CPSR |= GPRs[Rd] ? 0 : CPSR_Z;
+    CPSR |= (GPRs[Rd] & 0x80000000) ? CPSR_N : 0;
+  }
+
+  return 0;
 }
 
 // ARM710T only!
-uint32_t ARM710::execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo, uint32_t Rs, uint32_t Rm)
-{
-       // no need for R15 fuckery
-       // datasheet says it's not allowed here
-       uint64_t result;
-       if (UAS & 4) // unsigned
-               result = (uint64_t)GPRs[Rm] * (uint64_t)GPRs[Rs];
-       else // signed
-               result = (uint64_t)((int64_t)GPRs[Rm] * (int64_t)GPRs[Rs]);
-
-       if (UAS & 2) {
-               // accumulate
-               uint64_t addend = (uint64_t)GPRs[RdLo] | ((uint64_t)GPRs[RdHi] << 32);
-               result += addend;
-       }
-
-       if (UAS & 1) {
-               CPSR &= ~(CPSR_N | CPSR_Z);
-               CPSR |= result ? 0 : CPSR_Z;
-               CPSR |= (result & 0x8000000000000000) ? CPSR_N : 0;
-       }
-
-       GPRs[RdLo] = result & 0xFFFFFFFF;
-       GPRs[RdHi] = result >> 32;
-
-       return 0;
+uint32_t ARM710::execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo,
+                                  uint32_t Rs, uint32_t Rm) {
+  // no need for R15 fuckery
+  // datasheet says it's not allowed here
+  uint64_t result;
+  if (UAS & 4) // unsigned
+    result = (uint64_t)GPRs[Rm] * (uint64_t)GPRs[Rs];
+  else // signed
+    result = (uint64_t)((int64_t)GPRs[Rm] * (int64_t)GPRs[Rs]);
+
+  if (UAS & 2) {
+    // accumulate
+    uint64_t addend = (uint64_t)GPRs[RdLo] | ((uint64_t)GPRs[RdHi] << 32);
+    result += addend;
+  }
+
+  if (UAS & 1) {
+    CPSR &= ~(CPSR_N | CPSR_Z);
+    CPSR |= result ? 0 : CPSR_Z;
+    CPSR |= (result & 0x8000000000000000) ? CPSR_N : 0;
+  }
+
+  GPRs[RdLo] = result & 0xFFFFFFFF;
+  GPRs[RdHi] = result >> 32;
+
+  return 0;
 }
 
-uint32_t ARM710::execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd, uint32_t Rm)
-{
-       auto valueSize = B ? V8 : V32;
-       auto readResult = readVirtual(GPRs[Rn], valueSize);
-       auto fault = readResult.second;
+uint32_t ARM710::execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd,
+                                    uint32_t Rm) {
+  auto valueSize = B ? V8 : V32;
+  auto readResult = readVirtual(GPRs[Rn], valueSize);
+  auto fault = readResult.second;
 
-       if (fault == NoFault) {
-               fault = writeVirtual(GPRs[Rm], GPRs[Rn], valueSize);
-               if (fault == NoFault)
-                       GPRs[Rd] = readResult.first.value();
-       }
+  if (fault == NoFault) {
+    fault = writeVirtual(GPRs[Rm], GPRs[Rn], valueSize);
+    if (fault == NoFault)
+      GPRs[Rd] = readResult.first.value();
+  }
 
-       if (fault != NoFault)
-               reportFault(fault);
+  if (fault != NoFault)
+    reportFault(fault);
 
-       return 1;
+  return 1;
 }
 
-uint32_t ARM710::execSingleDataTransfer(uint32_t IPUBWL, uint32_t Rn, uint32_t Rd, uint32_t offset)
-{
-       bool load = extract1(IPUBWL, 0);
-       bool writeback = extract1(IPUBWL, 1);
-       auto valueSize = extract1(IPUBWL, 2) ? V8 : V32;
-       bool up = extract1(IPUBWL, 3);
-       bool preIndex = extract1(IPUBWL, 4);
-       bool immediate = !extract1(IPUBWL, 5);
-
-       // calculate the offset
-       uint32_t calcOffset;
-       if (!immediate) {
-               // REGISTER
-               uint32_t Rm = extract(offset, 3, 0);
-               calcOffset = GPRs[Rm];
-
-               uint8_t shiftBy = extract(offset, 11, 7);
-
-               switch (extract(offset, 6, 5)) {
-               case 0: // Logical Left (LSL)
-                       if (shiftBy > 0)
-                               calcOffset <<= shiftBy;
-                       break;
-               case 1: // Logical Right (LSR)
-                       if (shiftBy == 0)
-                               calcOffset = 0;
-                       else
-                               calcOffset >>= shiftBy;
-                       break;
-               case 2: // Arithmetic Right (ASR)
-                       if (shiftBy == 0)
-                               calcOffset = (int32_t)calcOffset >> 31;
-                       else
-                               calcOffset = (int32_t)calcOffset >> shiftBy;
-                       break;
-               case 3: // Rotate Right (ROR)
-                       if (shiftBy == 0) { // treated as RRX
-                               calcOffset >>= 1;
-                               calcOffset |= flagC() ? 0x80000000 : 0;
-                       } else
-                               calcOffset = ROR(calcOffset, shiftBy);
-                       break;
-               }
-       } else {
-               // IMMEDIATE
-               // No rotation or anything here
-               calcOffset = offset;
-       }
-
-       uint32_t base = GPRs[Rn];
-       if (Rn == 15) base -= 4; // prefetch adjustment
-       uint32_t modifiedBase = up ? (base + calcOffset) : (base - calcOffset);
-       uint32_t transferAddr = preIndex ? modifiedBase : base;
-
-       bool changeModes = !preIndex && writeback && isPrivileged();
-       auto saveMode = currentMode();
-
-       MMUFault fault;
-
-       if (load) {
-               if (changeModes) switchMode(User32);
-               auto readResult = readVirtual(transferAddr, valueSize);
-               if (changeModes) switchMode(saveMode);
-               if (readResult.first.has_value()) {
-                       GPRs[Rd] = readResult.first.value();
-                       if (Rd == 15) prefetchCount = 0;
-               }
-               fault = readResult.second;
-       } else {
-               uint32_t value = GPRs[Rd];
-               if (changeModes) switchMode(User32);
-               fault = writeVirtual(value, transferAddr, valueSize);
-               if (changeModes) switchMode(saveMode);
-       }
-
-       if ((preIndex && writeback) || !preIndex)
-               GPRs[Rn] = modifiedBase;
-
-       if (fault != NoFault)
-               reportFault(fault);
-
-       return 2;
+uint32_t ARM710::execSingleDataTransfer(uint32_t IPUBWL, uint32_t Rn,
+                                        uint32_t Rd, uint32_t offset) {
+  bool load = extract1(IPUBWL, 0);
+  bool writeback = extract1(IPUBWL, 1);
+  auto valueSize = extract1(IPUBWL, 2) ? V8 : V32;
+  bool up = extract1(IPUBWL, 3);
+  bool preIndex = extract1(IPUBWL, 4);
+  bool immediate = !extract1(IPUBWL, 5);
+
+  // calculate the offset
+  uint32_t calcOffset;
+  if (!immediate) {
+    // REGISTER
+    uint32_t Rm = extract(offset, 3, 0);
+    calcOffset = GPRs[Rm];
+
+    uint8_t shiftBy = extract(offset, 11, 7);
+
+    switch (extract(offset, 6, 5)) {
+    case 0: // Logical Left (LSL)
+      if (shiftBy > 0)
+        calcOffset <<= shiftBy;
+      break;
+    case 1: // Logical Right (LSR)
+      if (shiftBy == 0)
+        calcOffset = 0;
+      else
+        calcOffset >>= shiftBy;
+      break;
+    case 2: // Arithmetic Right (ASR)
+      if (shiftBy == 0)
+        calcOffset = (int32_t)calcOffset >> 31;
+      else
+        calcOffset = (int32_t)calcOffset >> shiftBy;
+      break;
+    case 3:               // Rotate Right (ROR)
+      if (shiftBy == 0) { // treated as RRX
+        calcOffset >>= 1;
+        calcOffset |= flagC() ? 0x80000000 : 0;
+      } else
+        calcOffset = ROR(calcOffset, shiftBy);
+      break;
+    }
+  } else {
+    // IMMEDIATE
+    // No rotation or anything here
+    calcOffset = offset;
+  }
+
+  uint32_t base = GPRs[Rn];
+  if (Rn == 15)
+    base -= 4; // prefetch adjustment
+  uint32_t modifiedBase = up ? (base + calcOffset) : (base - calcOffset);
+  uint32_t transferAddr = preIndex ? modifiedBase : base;
+
+  bool changeModes = !preIndex && writeback && isPrivileged();
+  auto saveMode = currentMode();
+
+  MMUFault fault;
+
+  if (load) {
+    if (changeModes)
+      switchMode(User32);
+    auto readResult = readVirtual(transferAddr, valueSize);
+    if (changeModes)
+      switchMode(saveMode);
+    if (readResult.first.has_value()) {
+      GPRs[Rd] = readResult.first.value();
+      if (Rd == 15)
+        prefetchCount = 0;
+    }
+    fault = readResult.second;
+  } else {
+    uint32_t value = GPRs[Rd];
+    if (changeModes)
+      switchMode(User32);
+    fault = writeVirtual(value, transferAddr, valueSize);
+    if (changeModes)
+      switchMode(saveMode);
+  }
+
+  if ((preIndex && writeback) || !preIndex)
+    GPRs[Rn] = modifiedBase;
+
+  if (fault != NoFault)
+    reportFault(fault);
+
+  return 2;
 }
 
-uint32_t ARM710::execSingleHalfWordDataTransfer(uint32_t PUIWL, uint32_t Rn, uint32_t Rd, uint32_t addrMode1, uint32_t SH, uint32_t addrMode2)
-{
-       bool load = extract1(PUIWL, 0);
-       bool writeback = extract1(PUIWL, 1);
-       bool immediate = extract1(PUIWL, 2);
-       bool up = extract1(PUIWL, 3);
-       bool preIndex = extract1(PUIWL, 4);
-
-       uint32_t LSH = ((PUIWL << 2) | SH) & 0x7;
-       ValueSize valueSize;
-       bool isSigned;
-
-       switch (LSH) {
-       case 0x1:
-               valueSize = V16;
-               isSigned = false;
-               break;
-       case 0x5:
-               valueSize = V16;
-               isSigned = false;
-               break;
-       case 0x6:
-               valueSize = V8;
-               isSigned = true;
-               break;
-       case 0x7:
-               valueSize = V16;
-               isSigned = true;
-               break;
-       default:
-               // Invalid instruction on ARMv4 as it doesn't support double word ldr/str
-               return 2;
-       }
-
-       // calculate the offset
-       uint32_t calcOffset;
-       if (!immediate) {
-               // addrMode1 should be zero (SBZ)
-               // addrMode2 is Rm
-               calcOffset = GPRs[addrMode2];
-       } else {
-               // IMMEDIATE
-               // No rotation or anything here
-               // addrMode1 is the high 4 bits
-               // addrMode2 is the low 4 bits
-               calcOffset = (addrMode1 << 4) | addrMode2;
-       }
-
-       uint32_t base = GPRs[Rn];
-       if (Rn == 15) base -= 4; // prefetch adjustment
-       uint32_t modifiedBase = up ? (base + calcOffset) : (base - calcOffset);
-       uint32_t transferAddr = preIndex ? modifiedBase : base;
-
-       bool changeModes = !preIndex && writeback && isPrivileged();
-       auto saveMode = currentMode();
-
-       MMUFault fault;
-
-       if (load) {
-               if (changeModes) switchMode(User32);
-               auto readResult = readVirtual(transferAddr, valueSize);
-               if (changeModes) switchMode(saveMode);
-               if (readResult.first.has_value()) {
-                               GPRs[Rd] = readResult.first.value();
-                               if (Rd == 15) prefetchCount = 0;
-               }
-               fault = readResult.second;
-       } else {
-               uint32_t value = GPRs[Rd];
-               if (changeModes) switchMode(User32);
-               fault = writeVirtual(value, transferAddr, valueSize);
-               if (changeModes) switchMode(saveMode);
-       }
-
-       if ((preIndex && writeback) || !preIndex)
-               GPRs[Rn] = modifiedBase;
-
-       if (fault != NoFault)
-               reportFault(fault);
-
-       return 2;
+uint32_t ARM710::execSingleHalfWordDataTransfer(uint32_t PUIWL, uint32_t Rn,
+                                                uint32_t Rd, uint32_t addrMode1,
+                                                uint32_t SH,
+                                                uint32_t addrMode2) {
+  bool load = extract1(PUIWL, 0);
+  bool writeback = extract1(PUIWL, 1);
+  bool immediate = extract1(PUIWL, 2);
+  bool up = extract1(PUIWL, 3);
+  bool preIndex = extract1(PUIWL, 4);
+
+  uint32_t LSH = ((PUIWL << 2) | SH) & 0x7;
+  ValueSize valueSize;
+  bool isSigned;
+
+  switch (LSH) {
+  case 0x1:
+    valueSize = V16;
+    isSigned = false;
+    break;
+  case 0x5:
+    valueSize = V16;
+    isSigned = false;
+    break;
+  case 0x6:
+    valueSize = V8;
+    isSigned = true;
+    break;
+  case 0x7:
+    valueSize = V16;
+    isSigned = true;
+    break;
+  default:
+    // Invalid instruction on ARMv4 as it doesn't support double word ldr/str
+    return 2;
+  }
+
+  // calculate the offset
+  uint32_t calcOffset;
+  if (!immediate) {
+    // addrMode1 should be zero (SBZ)
+    // addrMode2 is Rm
+    calcOffset = GPRs[addrMode2];
+  } else {
+    // IMMEDIATE
+    // No rotation or anything here
+    // addrMode1 is the high 4 bits
+    // addrMode2 is the low 4 bits
+    calcOffset = (addrMode1 << 4) | addrMode2;
+  }
+
+  uint32_t base = GPRs[Rn];
+  if (Rn == 15)
+    base -= 4; // prefetch adjustment
+  uint32_t modifiedBase = up ? (base + calcOffset) : (base - calcOffset);
+  uint32_t transferAddr = preIndex ? modifiedBase : base;
+
+  bool changeModes = !preIndex && writeback && isPrivileged();
+  auto saveMode = currentMode();
+
+  MMUFault fault;
+
+  if (load) {
+    if (changeModes)
+      switchMode(User32);
+    auto readResult = readVirtual(transferAddr, valueSize);
+    if (changeModes)
+      switchMode(saveMode);
+    if (readResult.first.has_value()) {
+      GPRs[Rd] = readResult.first.value();
+      if (Rd == 15)
+        prefetchCount = 0;
+    }
+    fault = readResult.second;
+  } else {
+    uint32_t value = GPRs[Rd];
+    if (changeModes)
+      switchMode(User32);
+    fault = writeVirtual(value, transferAddr, valueSize);
+    if (changeModes)
+      switchMode(saveMode);
+  }
+
+  if ((preIndex && writeback) || !preIndex)
+    GPRs[Rn] = modifiedBase;
+
+  if (fault != NoFault)
+    reportFault(fault);
+
+  return 2;
 }
 
-uint32_t ARM710::execBlockDataTransfer(uint32_t PUSWL, uint32_t Rn, uint32_t registerList)
-{
-       bool load = extract1(PUSWL, 0);
-       bool store = !load;
-       bool writeback = extract1(PUSWL, 1);
-       bool psrForceUser = extract1(PUSWL, 2);
-       bool up = extract1(PUSWL, 3);
-       bool preIndex = extract1(PUSWL, 4);
-
-       MMUFault fault = NoFault;
-       uint32_t base = GPRs[Rn] & ~3;
-       uint32_t blockSize = popcount32(registerList) * 4;
-
-       uint32_t lowAddr, updatedBase;
-       if (up) {
-               updatedBase = base + blockSize;
-               lowAddr = base + (preIndex ? 4 : 0);
-       } else {
-               updatedBase = base - blockSize;
-               lowAddr = updatedBase + (preIndex ? 0 : 4);
-       }
-
-       auto saveBank = bank;
-       if (psrForceUser && (store || !(registerList & 0x8000)))
-               switchBank(MainBank);
-
-       bool doneWriteback = false;
-       if (load && writeback) {
-               doneWriteback = true;
-               GPRs[Rn] = updatedBase;
-       }
-
-       uint32_t addr = lowAddr;
-       for (int i = 0; i < 16; i++) {
-               if (registerList & (1 << i)) {
-                       // work on this one
-                       if (load) {
-                               // handling for LDM faults may be kinda iffy...
-                               // wording on datasheet is a bit unclear
-                               auto readResult = readVirtual(addr, V32);
-                               if (readResult.first.has_value())
-                                       GPRs[i] = readResult.first.value();
-                               if (readResult.second != NoFault) {
-                                       fault = readResult.second;
-                                       break;
-                               }
-                       } else {
-                               auto newFault = writeVirtual(GPRs[i], addr, V32);
-                               if (newFault != NoFault)
-                                       fault = newFault;
-                       }
-
-                       addr += 4;
-
-                       if (writeback && !doneWriteback) {
-                               doneWriteback = true;
-                               GPRs[Rn] = updatedBase;
-                       }
-               }
-       }
-
-       // datasheet specifies that base register must be
-       // restored if an error occurs during LDM
-       if (load && fault != NoFault)
-               GPRs[Rn] = writeback ? updatedBase : base;
-
-       if (psrForceUser && (store || !(registerList & 0x8000)))
-               switchBank(saveBank);
-
-       if (load && (registerList & 0x8000)) {
-               prefetchCount = 0;
-               if (psrForceUser && isPrivileged() && fault == NoFault) {
-                       auto saved = SPSRs[currentBank()];
-                       switchMode(modeFromCPSR(saved));
-                       CPSR = saved;
-//                     log("reloading saved SPSR: %08x", saved);
-               }
-       }
-
-       if (fault != NoFault)
-               reportFault(fault);
-
-       return 0; // fixme
+uint32_t ARM710::execBlockDataTransfer(uint32_t PUSWL, uint32_t Rn,
+                                       uint32_t registerList) {
+  bool load = extract1(PUSWL, 0);
+  bool store = !load;
+  bool writeback = extract1(PUSWL, 1);
+  bool psrForceUser = extract1(PUSWL, 2);
+  bool up = extract1(PUSWL, 3);
+  bool preIndex = extract1(PUSWL, 4);
+
+  MMUFault fault = NoFault;
+  uint32_t base = GPRs[Rn] & ~3;
+  uint32_t blockSize = popcount32(registerList) * 4;
+
+  uint32_t lowAddr, updatedBase;
+  if (up) {
+    updatedBase = base + blockSize;
+    lowAddr = base + (preIndex ? 4 : 0);
+  } else {
+    updatedBase = base - blockSize;
+    lowAddr = updatedBase + (preIndex ? 0 : 4);
+  }
+
+  auto saveBank = bank;
+  if (psrForceUser && (store || !(registerList & 0x8000)))
+    switchBank(MainBank);
+
+  bool doneWriteback = false;
+  if (load && writeback) {
+    doneWriteback = true;
+    GPRs[Rn] = updatedBase;
+  }
+
+  uint32_t addr = lowAddr;
+  for (int i = 0; i < 16; i++) {
+    if (registerList & (1 << i)) {
+      // work on this one
+      if (load) {
+        // handling for LDM faults may be kinda iffy...
+        // wording on datasheet is a bit unclear
+        auto readResult = readVirtual(addr, V32);
+        if (readResult.first.has_value())
+          GPRs[i] = readResult.first.value();
+        if (readResult.second != NoFault) {
+          fault = readResult.second;
+          break;
+        }
+      } else {
+        auto newFault = writeVirtual(GPRs[i], addr, V32);
+        if (newFault != NoFault)
+          fault = newFault;
+      }
+
+      addr += 4;
+
+      if (writeback && !doneWriteback) {
+        doneWriteback = true;
+        GPRs[Rn] = updatedBase;
+      }
+    }
+  }
+
+  // datasheet specifies that base register must be
+  // restored if an error occurs during LDM
+  if (load && fault != NoFault)
+    GPRs[Rn] = writeback ? updatedBase : base;
+
+  if (psrForceUser && (store || !(registerList & 0x8000)))
+    switchBank(saveBank);
+
+  if (load && (registerList & 0x8000)) {
+    prefetchCount = 0;
+    if (psrForceUser && isPrivileged() && fault == NoFault) {
+      auto saved = SPSRs[currentBank()];
+      switchMode(modeFromCPSR(saved));
+      CPSR = saved;
+      //                       log("reloading saved SPSR: %08x", saved);
+    }
+  }
+
+  if (fault != NoFault)
+    reportFault(fault);
+
+  return 0; // fixme
 }
 
-uint32_t ARM710::execBranch(bool L, uint32_t offset)
-{
-       if (L)
-               GPRs[14] = GPRs[15] - 8;
+uint32_t ARM710::execBranch(bool L, uint32_t offset) {
+  if (L)
+    GPRs[14] = GPRs[15] - 8;
 
-       // start with 24 bits, shift left 2, sign extend to 32
-       int32_t sextOffset = (int32_t)(offset << 8) >> 6;
+  // start with 24 bits, shift left 2, sign extend to 32
+  int32_t sextOffset = (int32_t)(offset << 8) >> 6;
 
-       prefetchCount = 0;
-       GPRs[15] -= 4; // account for our prefetch being +4 too much
-       GPRs[15] += sextOffset;
-       return 0;
+  prefetchCount = 0;
+  GPRs[15] -= 4; // account for our prefetch being +4 too much
+  GPRs[15] += sextOffset;
+  return 0;
 }
 
-uint32_t ARM710::execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn, uint32_t Rd, uint32_t CP, uint32_t CRm)
-{
-       (void)CP;
-       (void)CRm;
-
-       if (!isPrivileged())
-               return 0;
-
-       if (L) {
-               // read a value
-               uint32_t what = 0;
-
-               switch (CRn) {
-               case 0: what = cp15_id; break;
-               case 3: what = cp15_domainAccessControl; break;
-               case 5: what = cp15_faultStatus; break;
-               case 6: what = cp15_faultAddress; break;
-               }
-
-               if (Rd == 15)
-                       CPSR = (CPSR & ~CPSR_FlagMask) | (what & CPSR_FlagMask);
-               else
-                       GPRs[Rd] = what;
-       } else {
-               // store a value
-               uint32_t what = GPRs[Rd];
-
-               switch (CRn) {
-               case 1: cp15_control = what; log("setting cp15_control to %08x", what); break;
-               case 2: cp15_translationTableBase = what; break;
-               case 3: cp15_domainAccessControl = what; break;
-               case 5:
-                       if (isTVersion)
-                               cp15_faultStatus = what;
+uint32_t ARM710::execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn,
+                                          uint32_t Rd, uint32_t CP,
+                                          uint32_t CRm) {
+  (void)CP;
+  (void)CRm;
+
+  if (!isPrivileged())
+    return 0;
+
+  if (L) {
+    // read a value
+    uint32_t what = 0;
+
+    switch (CRn) {
+    case 0:
+      what = cp15_id;
+      break;
+    case 3:
+      what = cp15_domainAccessControl;
+      break;
+    case 5:
+      what = cp15_faultStatus;
+      break;
+    case 6:
+      what = cp15_faultAddress;
+      break;
+    }
+
+    if (Rd == 15)
+      CPSR = (CPSR & ~CPSR_FlagMask) | (what & CPSR_FlagMask);
+    else
+      GPRs[Rd] = what;
+  } else {
+    // store a value
+    uint32_t what = GPRs[Rd];
+
+    switch (CRn) {
+    case 1:
+      cp15_control = what;
+      log("setting cp15_control to %08x", what);
+      break;
+    case 2:
+      cp15_translationTableBase = what;
+      break;
+    case 3:
+      cp15_domainAccessControl = what;
+      break;
+    case 5:
+      if (isTVersion)
+        cp15_faultStatus = what;
 #ifdef ARM710T_TLB
-                       else
-                               flushTlb();
+      else
+        flushTlb();
 #endif
-                       break;
-               case 6:
-                       if (isTVersion)
-                               cp15_faultAddress = what;
+      break;
+    case 6:
+      if (isTVersion)
+        cp15_faultAddress = what;
 #ifdef ARM710T_TLB
-                       else
-                               flushTlb(what);
-                       break;
+      else
+        flushTlb(what);
+      break;
 #endif
-               case 7:
+    case 7:
 #ifdef ARM710T_CACHE
-                       clearCache();
-                       log("cache cleared");
+      clearCache();
+      log("cache cleared");
 #endif
-                       break;
-               case 8: {
+      break;
+    case 8: {
 #ifdef ARM710T_TLB
-                       if (isTVersion) {
-                               if (CPOpc == 1)
-                                       flushTlb(what);
-                               else
-                                       flushTlb();
-                       }
+      if (isTVersion) {
+        if (CPOpc == 1)
+          flushTlb(what);
+        else
+          flushTlb();
+      }
 #endif
-                       break;
-               }
-               }
-       }
+      break;
+    }
+    }
+  }
 
-       return 0;
+  return 0;
 }
 
-
-
 #ifdef ARM710T_CACHE
 void ARM710T::clearCache() {
-       for (uint32_t i = 0; i < CacheSets; i++) {
-               for (uint32_t j = 0; j < CacheBlocksPerSet; j++) {
-                       cacheBlockTags[i][j] = 0;
-               }
-       }
+  for (uint32_t i = 0; i < CacheSets; i++) {
+    for (uint32_t j = 0; j < CacheBlocksPerSet; j++) {
+      cacheBlockTags[i][j] = 0;
+    }
+  }
 }
 
-uint8_t *ARM710T::findCacheLine(uint32_t virtAddr) {
-       uint32_t set = virtAddr & CacheAddressSetMask;
-       uint32_t tag = virtAddr & CacheAddressTagMask;
-       set >>= CacheAddressSetShift;
+uint8_tARM710T::findCacheLine(uint32_t virtAddr) {
+  uint32_t set = virtAddr & CacheAddressSetMask;
+  uint32_t tag = virtAddr & CacheAddressTagMask;
+  set >>= CacheAddressSetShift;
 
-       for (uint32_t i = 0; i < CacheBlocksPerSet; i++) {
-               if (cacheBlockTags[set][i] & CacheBlockEnabled) {
-                       if ((cacheBlockTags[set][i] & ~CacheBlockEnabled) == tag)
-                               return &cacheBlocks[set][i][0];
-               }
-       }
+  for (uint32_t i = 0; i < CacheBlocksPerSet; i++) {
+    if (cacheBlockTags[set][i] & CacheBlockEnabled) {
+      if ((cacheBlockTags[set][i] & ~CacheBlockEnabled) == tag)
+        return &cacheBlocks[set][i][0];
+    }
+  }
 
-       return nullptr;
+  return nullptr;
 }
 
-pair<MaybeU32, ARM710T::MMUFault> ARM710T::addCacheLineAndRead(uint32_t physAddr, uint32_t virtAddr, ValueSize valueSize, int domain, bool isPage) {
-       uint32_t set = virtAddr & CacheAddressSetMask;
-       uint32_t tag = virtAddr & CacheAddressTagMask;
-       set >>= CacheAddressSetShift;
-
-       // "it will be randomly placed in a cache bank"
-       //    - the ARM710a data sheet, 6-2 (p90)
-       uint32_t i = rand() % CacheBlocksPerSet;
-       uint8_t *block = &cacheBlocks[set][i][0];
-       MaybeU32 result;
-       MMUFault fault = NoFault;
-
-       for (uint32_t j = 0; j < CacheBlockSize; j += 4) {
-               auto word = readPhysical((physAddr & ~CacheAddressLineMask) + j, V32);
-               if (word.has_value()) {
-                       write32LE(&block[j], word.value());
-                       if (valueSize == V8 && j == (virtAddr & CacheAddressLineMask & ~3))
-                               result = (word.value() >> ((virtAddr & 3) * 8)) & 0xFF;
-                       else if (valueSize == V32 && j == (virtAddr & CacheAddressLineMask))
-                               result = word.value();
-               } else {
-                       // read error, great
-                       // TODO: should probably prioritise specific kinds of faults over others
-                       fault = encodeFaultSorP(SorPLinefetchError, isPage, domain, virtAddr & ~CacheAddressLineMask);
-                       break;
-               }
-       }
-
-       // the cache block is only stored if it's complete
-       if (fault == NoFault)
-               cacheBlockTags[set][i] = tag | CacheBlockEnabled;
-
-       return make_pair(result, fault);
+pair<MaybeU32, ARM710T::MMUFault>
+ARM710T::addCacheLineAndRead(uint32_t physAddr, uint32_t virtAddr,
+                             ValueSize valueSize, int domain, bool isPage) {
+  uint32_t set = virtAddr & CacheAddressSetMask;
+  uint32_t tag = virtAddr & CacheAddressTagMask;
+  set >>= CacheAddressSetShift;
+
+  // "it will be randomly placed in a cache bank"
+  //    - the ARM710a data sheet, 6-2 (p90)
+  uint32_t i = rand() % CacheBlocksPerSet;
+  uint8_t* block = &cacheBlocks[set][i][0];
+  MaybeU32 result;
+  MMUFault fault = NoFault;
+
+  for (uint32_t j = 0; j < CacheBlockSize; j += 4) {
+    auto word = readPhysical((physAddr & ~CacheAddressLineMask) + j, V32);
+    if (word.has_value()) {
+      write32LE(&block[j], word.value());
+      if (valueSize == V8 && j == (virtAddr & CacheAddressLineMask & ~3))
+        result = (word.value() >> ((virtAddr & 3) * 8)) & 0xFF;
+      else if (valueSize == V32 && j == (virtAddr & CacheAddressLineMask))
+        result = word.value();
+    } else {
+      // read error, great
+      // TODO: should probably prioritise specific kinds of faults over others
+      fault = encodeFaultSorP(SorPLinefetchError, isPage, domain,
+                              virtAddr & ~CacheAddressLineMask);
+      break;
+    }
+  }
+
+  // the cache block is only stored if it's complete
+  if (fault == NoFault)
+    cacheBlockTags[set][i] = tag | CacheBlockEnabled;
+
+  return make_pair(result, fault);
 }
 
 MaybeU32 ARM710T::readCached(uint32_t virtAddr, ValueSize valueSize) {
-       uint8_t *line = findCacheLine(virtAddr);
-       if (line) {
-               if (valueSize == V8)
-                       return line[virtAddr & CacheAddressLineMask];
-               else /*if (valueSize == V32)*/
-                       return read32LE(&line[virtAddr & CacheAddressLineMask]);
-       }
-       return {};
+  uint8_t* line = findCacheLine(virtAddr);
+  if (line) {
+    if (valueSize == V8)
+      return line[virtAddr & CacheAddressLineMask];
+    else /*if (valueSize == V32)*/
+      return read32LE(&line[virtAddr & CacheAddressLineMask]);
+  }
+  return {};
 }
 
-
-bool ARM710T::writeCached(uint32_t value, uint32_t virtAddr, ValueSize valueSize) {
-       uint8_t *line = findCacheLine(virtAddr);
-       if (line) {
-               if (valueSize == V8)
-                       line[virtAddr & CacheAddressLineMask] = value & 0xFF;
-               else /*if (valueSize == V32)*/
-                       write32LE(&line[virtAddr & CacheAddressLineMask], value);
-               return true;
-       }
-       return false;
+bool ARM710T::writeCached(uint32_t value, uint32_t virtAddr,
+                          ValueSize valueSize) {
+  uint8_t* line = findCacheLine(virtAddr);
+  if (line) {
+    if (valueSize == V8)
+      line[virtAddr & CacheAddressLineMask] = value & 0xFF;
+    else /*if (valueSize == V32)*/
+      write32LE(&line[virtAddr & CacheAddressLineMask], value);
+    return true;
+  }
+  return false;
 }
 #endif
 
-
-uint32_t ARM710::physAddrFromTlbEntry(TlbEntry *tlbEntry, uint32_t virtAddr) {
-       if ((tlbEntry->lv2Entry & 3) == 2) {
-               // Smøl page
-               return (tlbEntry->lv2Entry & 0xFFFFF000) | (virtAddr & 0xFFF);
-       } else if ((tlbEntry->lv2Entry & 3) == 1) {
-               // Lørge page
-               return (tlbEntry->lv2Entry & 0xFFFF0000) | (virtAddr & 0xFFFF);
-       } else {
-               // Section
-               return (tlbEntry->lv1Entry & 0xFFF00000) | (virtAddr & 0xFFFFF);
-       }
+uint32_t ARM710::physAddrFromTlbEntry(TlbEntry* tlbEntry, uint32_t virtAddr) {
+  if ((tlbEntry->lv2Entry & 3) == 2) {
+    // Smøl page
+    return (tlbEntry->lv2Entry & 0xFFFFF000) | (virtAddr & 0xFFF);
+  } else if ((tlbEntry->lv2Entry & 3) == 1) {
+    // Lørge page
+    return (tlbEntry->lv2Entry & 0xFFFF0000) | (virtAddr & 0xFFFF);
+  } else {
+    // Section
+    return (tlbEntry->lv1Entry & 0xFFF00000) | (virtAddr & 0xFFFFF);
+  }
 }
 
-
 MaybeU32 ARM710::virtToPhys(uint32_t virtAddr) {
-       if (!isMMUEnabled())
-               return virtAddr;
-
-       TlbEntry tempEntry;
-       auto translated = translateAddressUsingTlb(virtAddr, &tempEntry);
-       if (holds_alternative<TlbEntry *>(translated)) {
-               auto tlbEntry = get<TlbEntry *>(translated);
-               return physAddrFromTlbEntry(tlbEntry, virtAddr);
-       } else {
-               return MaybeU32();
-       }
+  if (!isMMUEnabled())
+    return virtAddr;
+
+  TlbEntry tempEntry;
+  auto translated = translateAddressUsingTlb(virtAddr, &tempEntry);
+  if (holds_alternative<TlbEntry*>(translated)) {
+    auto tlbEntry = get<TlbEntry*>(translated);
+    return physAddrFromTlbEntry(tlbEntry, virtAddr);
+  } else {
+    return MaybeU32();
+  }
 }
 
-
 MaybeU32 ARM710::readVirtualDebug(uint32_t virtAddr, ValueSize valueSize) {
-       if (auto v = virtToPhys(virtAddr); v.has_value())
-               return readPhysical(v.value(), valueSize);
-       else
-               return {};
+  if (auto v = virtToPhys(virtAddr); v.has_value())
+    return readPhysical(v.value(), valueSize);
+  else
+    return {};
 }
 
+pair<MaybeU32, ARM710::MMUFault> ARM710::readVirtual(uint32_t virtAddr,
+                                                     ValueSize valueSize) {
+  if (isAlignmentFaultEnabled() && valueSize == V32 && virtAddr & 3)
+    return make_pair(MaybeU32(), encodeFault(AlignmentFault, 0, virtAddr));
 
-pair<MaybeU32, ARM710::MMUFault> ARM710::readVirtual(uint32_t virtAddr, ValueSize valueSize) {
-       if (isAlignmentFaultEnabled() && valueSize == V32 && virtAddr & 3)
-               return make_pair(MaybeU32(), encodeFault(AlignmentFault, 0, virtAddr));
-
-       // fast path: cache
+  // fast path: cache
 #ifdef ARM710T_CACHE
-       if (auto v = readCached(virtAddr, valueSize); v.has_value())
-               return make_pair(v.value(), NoFault);
+  if (auto v = readCached(virtAddr, valueSize); v.has_value())
+    return make_pair(v.value(), NoFault);
 #endif
 
-       if (!isMMUEnabled()) {
-               // things are very simple without a MMU
-               if (auto v = readPhysical(virtAddr, valueSize); v.has_value())
-                       return make_pair(v.value(), NoFault);
-               else
-                       return make_pair(MaybeU32(), encodeFault(NonMMUError, 0, virtAddr));
-       }
+  if (!isMMUEnabled()) {
+    // things are very simple without a MMU
+    if (auto v = readPhysical(virtAddr, valueSize); v.has_value())
+      return make_pair(v.value(), NoFault);
+    else
+      return make_pair(MaybeU32(), encodeFault(NonMMUError, 0, virtAddr));
+  }
 
-       auto translated = translateAddressUsingTlb(virtAddr);
-       if (holds_alternative<MMUFault>(translated))
-               return make_pair(MaybeU32(), get<MMUFault>(translated));
+  auto translated = translateAddressUsingTlb(virtAddr);
+  if (holds_alternative<MMUFault>(translated))
+    return make_pair(MaybeU32(), get<MMUFault>(translated));
 
-       // resolve this boy
-       auto tlbEntry = get<TlbEntry *>(translated);
+  // resolve this boy
+  auto tlbEntry = get<TlbEntry*>(translated);
 
-       if (auto f = checkAccessPermissions(tlbEntry, virtAddr, false); f != NoFault)
-               return make_pair(MaybeU32(), f);
+  if (auto f = checkAccessPermissions(tlbEntry, virtAddr, false); f != NoFault)
+    return make_pair(MaybeU32(), f);
 
-       int domain = (tlbEntry->lv1Entry >> 5) & 0xF;
-       bool isPage = (tlbEntry->lv2Entry != 0);
+  int domain = (tlbEntry->lv1Entry >> 5) & 0xF;
+  bool isPage = (tlbEntry->lv2Entry != 0);
 
-       uint32_t physAddr = physAddrFromTlbEntry(tlbEntry, virtAddr);
+  uint32_t physAddr = physAddrFromTlbEntry(tlbEntry, virtAddr);
 
 #ifdef ARM710T_CACHE
-       bool cacheable = tlbEntry->lv2Entry ? (tlbEntry->lv2Entry & 8) : (tlbEntry->lv1Entry & 8);
-       if (cacheable && isCacheEnabled())
-               return addCacheLineAndRead(physAddr, virtAddr, valueSize, domain, isPage);
-       else
+  bool cacheable =
+      tlbEntry->lv2Entry ? (tlbEntry->lv2Entry & 8) : (tlbEntry->lv1Entry & 8);
+  if (cacheable && isCacheEnabled())
+    return addCacheLineAndRead(physAddr, virtAddr, valueSize, domain, isPage);
+  else
 #endif
-       if (auto result = readPhysical(physAddr, valueSize); result.has_value())
-               return make_pair(result, NoFault);
-       else
-               return make_pair(result, encodeFaultSorP(SorPOtherBusError, isPage, domain, virtAddr));
+      if (auto result = readPhysical(physAddr, valueSize); result.has_value())
+    return make_pair(result, NoFault);
+  else
+    return make_pair(
+        result, encodeFaultSorP(SorPOtherBusError, isPage, domain, virtAddr));
 }
 
-ARM710::MMUFault ARM710::writeVirtual(uint32_t value, uint32_t virtAddr, ValueSize valueSize) {
-       if (isAlignmentFaultEnabled() && valueSize == V32 && virtAddr & 3)
-               return encodeFault(AlignmentFault, 0, virtAddr);
+ARM710::MMUFault ARM710::writeVirtual(uint32_t value, uint32_t virtAddr,
+                                      ValueSize valueSize) {
+  if (isAlignmentFaultEnabled() && valueSize == V32 && virtAddr & 3)
+    return encodeFault(AlignmentFault, 0, virtAddr);
 
-       if (!isMMUEnabled()) {
-               // direct virtual -> physical mapping, sans MMU
-               if (!writePhysical(value, virtAddr, valueSize))
-                       return encodeFault(NonMMUError, 0, virtAddr);
-       } else {
-               auto translated = translateAddressUsingTlb(virtAddr);
-               if (holds_alternative<MMUFault>(translated))
-                       return get<MMUFault>(translated);
+  if (!isMMUEnabled()) {
+    // direct virtual -> physical mapping, sans MMU
+    if (!writePhysical(value, virtAddr, valueSize))
+      return encodeFault(NonMMUError, 0, virtAddr);
+  } else {
+    auto translated = translateAddressUsingTlb(virtAddr);
+    if (holds_alternative<MMUFault>(translated))
+      return get<MMUFault>(translated);
 
-               // resolve this boy
-               auto tlbEntry = get<TlbEntry *>(translated);
+    // resolve this boy
+    auto tlbEntry = get<TlbEntry*>(translated);
 
-               if (auto f = checkAccessPermissions(tlbEntry, virtAddr, true); f != NoFault)
-                       return f;
+    if (auto f = checkAccessPermissions(tlbEntry, virtAddr, true); f != NoFault)
+      return f;
 
-               uint32_t physAddr = physAddrFromTlbEntry(tlbEntry, virtAddr);
-               int domain = (tlbEntry->lv1Entry >> 5) & 0xF;
-               bool isPage = (tlbEntry->lv2Entry != 0);
+    uint32_t physAddr = physAddrFromTlbEntry(tlbEntry, virtAddr);
+    int domain = (tlbEntry->lv1Entry >> 5) & 0xF;
+    bool isPage = (tlbEntry->lv2Entry != 0);
 
-               if (!writePhysical(value, physAddr, valueSize))
-                       return encodeFaultSorP(SorPOtherBusError, isPage, domain, virtAddr);
-       }
+    if (!writePhysical(value, physAddr, valueSize))
+      return encodeFaultSorP(SorPOtherBusError, isPage, domain, virtAddr);
+  }
 
-       // commit to cache if all was good
+  // commit to cache if all was good
 #ifdef ARM710T_CACHE
-       writeCached(value, virtAddr, valueSize);
+  writeCached(value, virtAddr, valueSize);
 #endif
-       return NoFault;
+  return NoFault;
 }
 
-
-
 // TLB
 #ifdef ARM710T_TLB
 void ARM710::flushTlb() {
-       for (TlbEntry &e : tlb)
-               e = {0, 0, 0, 0};
+  for (TlbEntry& e : tlb)
+    e = {0, 0, 0, 0};
 }
 void ARM710::flushTlb(uint32_t virtAddr) {
-       for (TlbEntry &e : tlb) {
-               if (e.addrMask && (virtAddr & e.addrMask) == e.addr) {
-                       e = {0, 0, 0, 0};
-                       break;
-               }
-       }
+  for (TlbEntry& e : tlb) {
+    if (e.addrMask && (virtAddr & e.addrMask) == e.addr) {
+      e = {0, 0, 0, 0};
+      break;
+    }
+  }
 }
 #endif
 
-ARM710::TlbEntry *ARM710::_allocateTlbEntry(uint32_t addrMask, uint32_t addr) {
+ARM710::TlbEntryARM710::_allocateTlbEntry(uint32_t addrMask, uint32_t addr) {
 #ifdef ARM710T_TLB
-       TlbEntry *entry = &tlb[nextTlbIndex];
-       nextTlbIndex = (nextTlbIndex + 1) % TlbSize;
+  TlbEntry* entry = &tlb[nextTlbIndex];
+  nextTlbIndex = (nextTlbIndex + 1) % TlbSize;
 #else
-       TlbEntry *entry = &singleTlbEntry;
+  TlbEntry* entry = &singleTlbEntry;
 #endif
-       entry->addrMask = addrMask;
-       entry->addr = addr & addrMask;
-       return entry;
+  entry->addrMask = addrMask;
+  entry->addr = addr & addrMask;
+  return entry;
 }
 
-variant<ARM710::TlbEntry *, ARM710::MMUFault> ARM710::translateAddressUsingTlb(uint32_t virtAddr, TlbEntry *useMe) {
+variant<ARM710::TlbEntry*, ARM710::MMUFault>
+ARM710::translateAddressUsingTlb(uint32_t virtAddr, TlbEntry* useMe) {
 #ifdef ARM710T_TLB
-       // first things first, do we have a matching entry in the TLB?
-       for (TlbEntry &e : tlb) {
-               if (e.addrMask && (virtAddr & e.addrMask) == e.addr)
-                       return &e;
-       }
+  // first things first, do we have a matching entry in the TLB?
+  for (TlbEntry& e : tlb) {
+    if (e.addrMask && (virtAddr & e.addrMask) == e.addr)
+      return &e;
+  }
 #endif
 
-       // no, so do a page table walk
-       TlbEntry *entry;
-       uint32_t tableIndex = virtAddr >> 20;
-
-       // fetch the Level 1 entry
-       auto lv1EntryOpt = readPhysical(cp15_translationTableBase | (tableIndex << 2), V32);
-       if (!lv1EntryOpt.has_value())
-               return Lv1TranslationError;
-       auto lv1Entry = lv1EntryOpt.value();
-       int domain = (lv1Entry >> 5) & 0xF;
-
-       switch (lv1Entry & 3) {
-       case 0:
-       case 3:
-               // invalid!
-               return encodeFault(SectionTranslationFault, domain, virtAddr);
-       case 2:
-               // a Section entry is straightforward
-               // we just throw that immediately into the TLB
-               entry = useMe ? useMe : _allocateTlbEntry(0xFFF00000, virtAddr);
-               entry->lv1Entry = lv1Entry;
-               entry->lv2Entry = 0;
-               return entry;
-       case 1:
-               // a Page requires a Level 2 read
-               uint32_t pageTableAddr = lv1Entry & 0xFFFFFC00;
-               uint32_t lv2TableIndex = (virtAddr >> 12) & 0xFF;
-
-               auto lv2EntryOpt = readPhysical(pageTableAddr | (lv2TableIndex << 2), V32);
-               if (!lv2EntryOpt.has_value())
-                       return encodeFault(Lv2TranslationError, domain, virtAddr);
-               auto lv2Entry = lv2EntryOpt.value();
-
-               switch (lv2Entry & 3) {
-               case 0:
-               case 3:
-                       // invalid!
-                       return encodeFault(PageTranslationFault, domain, virtAddr);
-               case 1:
-                       // Large 64kb page
-                       entry = useMe ? useMe : _allocateTlbEntry(0xFFFF0000, virtAddr);
-                       entry->lv1Entry = lv1Entry;
-                       entry->lv2Entry = lv2Entry;
-                       return entry;
-               case 2:
-                       // Small 4kb page
-                       entry = useMe ? useMe : _allocateTlbEntry(0xFFFFF000, virtAddr);
-                       entry->lv1Entry = lv1Entry;
-                       entry->lv2Entry = lv2Entry;
-                       return entry;
-               }
-       }
-
-       // we should never get here as the switch covers 0, 1, 2, 3
-       // but this satisfies a compiler warning
-       return SectionTranslationFault;
+  // no, so do a page table walk
+  TlbEntry* entry;
+  uint32_t tableIndex = virtAddr >> 20;
+
+  // fetch the Level 1 entry
+  auto lv1EntryOpt =
+      readPhysical(cp15_translationTableBase | (tableIndex << 2), V32);
+  if (!lv1EntryOpt.has_value())
+    return Lv1TranslationError;
+  auto lv1Entry = lv1EntryOpt.value();
+  int domain = (lv1Entry >> 5) & 0xF;
+
+  switch (lv1Entry & 3) {
+  case 0:
+  case 3:
+    // invalid!
+    return encodeFault(SectionTranslationFault, domain, virtAddr);
+  case 2:
+    // a Section entry is straightforward
+    // we just throw that immediately into the TLB
+    entry = useMe ? useMe : _allocateTlbEntry(0xFFF00000, virtAddr);
+    entry->lv1Entry = lv1Entry;
+    entry->lv2Entry = 0;
+    return entry;
+  case 1:
+    // a Page requires a Level 2 read
+    uint32_t pageTableAddr = lv1Entry & 0xFFFFFC00;
+    uint32_t lv2TableIndex = (virtAddr >> 12) & 0xFF;
+
+    auto lv2EntryOpt = readPhysical(pageTableAddr | (lv2TableIndex << 2), V32);
+    if (!lv2EntryOpt.has_value())
+      return encodeFault(Lv2TranslationError, domain, virtAddr);
+    auto lv2Entry = lv2EntryOpt.value();
+
+    switch (lv2Entry & 3) {
+    case 0:
+    case 3:
+      // invalid!
+      return encodeFault(PageTranslationFault, domain, virtAddr);
+    case 1:
+      // Large 64kb page
+      entry = useMe ? useMe : _allocateTlbEntry(0xFFFF0000, virtAddr);
+      entry->lv1Entry = lv1Entry;
+      entry->lv2Entry = lv2Entry;
+      return entry;
+    case 2:
+      // Small 4kb page
+      entry = useMe ? useMe : _allocateTlbEntry(0xFFFFF000, virtAddr);
+      entry->lv1Entry = lv1Entry;
+      entry->lv2Entry = lv2Entry;
+      return entry;
+    }
+  }
+
+  // we should never get here as the switch covers 0, 1, 2, 3
+  // but this satisfies a compiler warning
+  return SectionTranslationFault;
 }
 
-
-
-ARM710::MMUFault ARM710::checkAccessPermissions(ARM710::TlbEntry *entry, uint32_t virtAddr, bool isWrite) const {
-       int domain;
-       int accessPerms;
-       bool isPage;
-
-       // extract info from the entries
-       domain = (entry->lv1Entry >> 5) & 0xF;
-       if (entry->lv2Entry) {
-               // Page
-               accessPerms = (entry->lv2Entry >> 4) & 0xFF;
-
-               int permIndex;
-               if ((entry->lv2Entry & 3) == 1) // Large 64kb
-                       permIndex = (virtAddr >> 14) & 3;
-               else                            // Small 4kb
-                       permIndex = (virtAddr >> 10) & 3;
-
-               accessPerms >>= (permIndex * 2);
-               accessPerms &= 3;
-               isPage = true;
-       } else {
-               // Section
-               accessPerms = (entry->lv1Entry >> 10) & 3;
-               isPage = false;
-       }
-
-       // now, do our checks
-       int primaryAccessControls = (cp15_domainAccessControl >> (domain * 2)) & 3;
-
-       // Manager: always allowed
-       if (primaryAccessControls == 3)
-               return NoFault;
-
-       // Client: enforce checks!
-       if (primaryAccessControls == 1) {
-#define OK_IF_TRUE(b) return ((b) ? NoFault : encodeFaultSorP(SorPPermissionFault, isPage, domain, virtAddr))
-               bool System = cp15_control & 0x100;
-               bool ROM = cp15_control & 0x200;
-
-               if (accessPerms == 0) {
-                       if (!System && !ROM) {
-                               // 00/0/0: Any access generates a permission fault
-                               OK_IF_TRUE(false);
-                       } else if (System && !ROM) {
-                               // 00/1/0: Supervisor read only permitted
-                               OK_IF_TRUE(!isWrite && isPrivileged());
-                       } else if (!System && ROM) {
-                               // 00/0/1: Any write generates a permission fault
-                               OK_IF_TRUE(!isWrite);
-                       } else /*if (System && ROM)*/ {
-                               // Reserved
-                               OK_IF_TRUE(false);
-                       }
-               } else if (accessPerms == 1) {
-                       // 01/x/x: Access allowed only in Supervisor mode
-                       OK_IF_TRUE(isPrivileged());
-               } else if (accessPerms == 2) {
-                       // 10/x/x: Writes in User mode cause permission fault
-                       OK_IF_TRUE(!isWrite || isPrivileged());
-               } else /*if (accessPerms == 3)*/ {
-                       // 11/x/x: All access types permitted in both modes
-                       OK_IF_TRUE(true);
-               }
+ARM710::MMUFault ARM710::checkAccessPermissions(ARM710::TlbEntry* entry,
+                                                uint32_t virtAddr,
+                                                bool isWrite) const {
+  int domain;
+  int accessPerms;
+  bool isPage;
+
+  // extract info from the entries
+  domain = (entry->lv1Entry >> 5) & 0xF;
+  if (entry->lv2Entry) {
+    // Page
+    accessPerms = (entry->lv2Entry >> 4) & 0xFF;
+
+    int permIndex;
+    if ((entry->lv2Entry & 3) == 1) // Large 64kb
+      permIndex = (virtAddr >> 14) & 3;
+    else // Small 4kb
+      permIndex = (virtAddr >> 10) & 3;
+
+    accessPerms >>= (permIndex * 2);
+    accessPerms &= 3;
+    isPage = true;
+  } else {
+    // Section
+    accessPerms = (entry->lv1Entry >> 10) & 3;
+    isPage = false;
+  }
+
+  // now, do our checks
+  int primaryAccessControls = (cp15_domainAccessControl >> (domain * 2)) & 3;
+
+  // Manager: always allowed
+  if (primaryAccessControls == 3)
+    return NoFault;
+
+  // Client: enforce checks!
+  if (primaryAccessControls == 1) {
+#define OK_IF_TRUE(b)                                                          \
+  return (                                                                     \
+      (b) ? NoFault                                                            \
+          : encodeFaultSorP(SorPPermissionFault, isPage, domain, virtAddr))
+    bool System = cp15_control & 0x100;
+    bool ROM = cp15_control & 0x200;
+
+    if (accessPerms == 0) {
+      if (!System && !ROM) {
+        // 00/0/0: Any access generates a permission fault
+        OK_IF_TRUE(false);
+      } else if (System && !ROM) {
+        // 00/1/0: Supervisor read only permitted
+        OK_IF_TRUE(!isWrite && isPrivileged());
+      } else if (!System && ROM) {
+        // 00/0/1: Any write generates a permission fault
+        OK_IF_TRUE(!isWrite);
+      } else /*if (System && ROM)*/ {
+        // Reserved
+        OK_IF_TRUE(false);
+      }
+    } else if (accessPerms == 1) {
+      // 01/x/x: Access allowed only in Supervisor mode
+      OK_IF_TRUE(isPrivileged());
+    } else if (accessPerms == 2) {
+      // 10/x/x: Writes in User mode cause permission fault
+      OK_IF_TRUE(!isWrite || isPrivileged());
+    } else /*if (accessPerms == 3)*/ {
+      // 11/x/x: All access types permitted in both modes
+      OK_IF_TRUE(true);
+    }
 #undef OK_IF_TRUE
-       }
+  }
 
-       // No Access or Reserved: never allowed (Domain Fault)
-       return encodeFaultSorP(SorPDomainFault, isPage, domain, virtAddr);
+  // No Access or Reserved: never allowed (Domain Fault)
+  return encodeFaultSorP(SorPDomainFault, isPage, domain, virtAddr);
 }
 
-
 void ARM710::reportFault(MMUFault fault) {
-       if (fault != NoFault) {
-               if ((fault & 0xF) != NonMMUError) {
-                       cp15_faultStatus = fault & (MMUFaultTypeMask | MMUFaultDomainMask);
-                       cp15_faultAddress = fault >> MMUFaultAddressShift;
-               }
-
-               static const char *faultTypes[] = {
-                       "NoFault",
-                       "AlignmentFault",
-                       "???",
-                       "NonMMUError",
-                       "SectionLinefetchError",
-                       "SectionTranslationFault",
-                       "PageLinefetchError",
-                       "PageTranslationFault",
-                       "SectionOtherBusError",
-                       "SectionDomainFault",
-                       "PageOtherBusError",
-                       "PageDomainFault",
-                       "Lv1TranslationError",
-                       "SectionPermissionFault",
-                       "Lv2TranslationError",
-                       "PagePermissionFault"
-               };
-               log("⚠️ Fault type=%s domain=%d address=%08x pc=%08x lr=%08x",
-                       faultTypes[fault & MMUFaultTypeMask],
-                       (fault & MMUFaultDomainMask) >> MMUFaultDomainShift,
-                       fault >> MMUFaultAddressShift,
-                       GPRs[15], GPRs[14]);
-
-               // this signals a branch to DataAbort after the
-               // instruction is done executing
-               faultTriggeredThisCycle = true;
-       }
+  if (fault != NoFault) {
+    if ((fault & 0xF) != NonMMUError) {
+      cp15_faultStatus = fault & (MMUFaultTypeMask | MMUFaultDomainMask);
+      cp15_faultAddress = fault >> MMUFaultAddressShift;
+    }
+
+    static const char* faultTypes[] = {"NoFault",
+                                       "AlignmentFault",
+                                       "???",
+                                       "NonMMUError",
+                                       "SectionLinefetchError",
+                                       "SectionTranslationFault",
+                                       "PageLinefetchError",
+                                       "PageTranslationFault",
+                                       "SectionOtherBusError",
+                                       "SectionDomainFault",
+                                       "PageOtherBusError",
+                                       "PageDomainFault",
+                                       "Lv1TranslationError",
+                                       "SectionPermissionFault",
+                                       "Lv2TranslationError",
+                                       "PagePermissionFault"};
+    log("⚠️ Fault type=%s domain=%d address=%08x pc=%08x lr=%08x",
+        faultTypes[fault & MMUFaultTypeMask],
+        (fault & MMUFaultDomainMask) >> MMUFaultDomainShift,
+        fault >> MMUFaultAddressShift, GPRs[15], GPRs[14]);
+
+    // this signals a branch to DataAbort after the
+    // instruction is done executing
+    faultTriggeredThisCycle = true;
+  }
 }
 
+void ARM710::log(const char* format, ...) {
+  if (logger) {
+    char buffer[1024];
 
-void ARM710::log(const char *format, ...) {
-       if (logger) {
-               char buffer[1024];
-
-               va_list vaList;
-               va_start(vaList, format);
-               vsnprintf(buffer, sizeof(buffer), format, vaList);
-               va_end(vaList);
+    va_list vaList;
+    va_start(vaList, format);
+    vsnprintf(buffer, sizeof(buffer), format, vaList);
+    va_end(vaList);
 
-               logger(buffer);
-       }
+    logger(buffer);
+  }
 }
 
 void ARM710::logPcHistory() {
-       for (int i = 0; i < PcHistoryCount; i++) {
-               pcHistoryIndex = (pcHistoryIndex + 1) % PcHistoryCount;
-               log("%03d: %08x %08x", i, pcHistory[pcHistoryIndex].addr, pcHistory[pcHistoryIndex].insn);
-       }
+  for (int i = 0; i < PcHistoryCount; i++) {
+    pcHistoryIndex = (pcHistoryIndex + 1) % PcHistoryCount;
+    log("%03d: %08x %08x", i, pcHistory[pcHistoryIndex].addr,
+        pcHistory[pcHistoryIndex].insn);
+  }
 }
index f0fa139a3fb14dd56f37e66f46d84e0458eb40e3..6430e1c12309e8b3f225ef3ad6a68f20a243b65f 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 #include <functional>
-#include <stdint.h>
 #include <optional>
+#include <stdint.h>
 #include <variant>
 
 using namespace std;
@@ -18,288 +18,326 @@ using namespace std;
 // TLB is 64 entries
 
 // Speedhacks:
-//#define ARM710T_CACHE
-//#define ARM710T_TLB
+// #define ARM710T_CACHE
+// #define ARM710T_TLB
 
 typedef optional<uint32_t> MaybeU32;
 
-class ARM710
-{
+class ARM710 {
 public:
-       enum ValueSize { V8 = 0, V16 = 1, V32 = 2 };
-
-       enum MMUFault : uint64_t {
-               // ref: datasheet 9-13 (p111)
-               NoFault                 = 0,
-               AlignmentFault          = 1,
-               // the ARM gods say there is to be no fault 2 or 3
-               SectionLinefetchError   = 4,
-               SectionTranslationFault = 5,
-               PageLinefetchError      = 6,
-               PageTranslationFault    = 7,
-               SectionOtherBusError    = 8,
-               SectionDomainFault      = 9,
-               PageOtherBusError       = 0xA,
-               PageDomainFault         = 0xB,
-               Lv1TranslationError     = 0xC,
-               SectionPermissionFault  = 0xD,
-               Lv2TranslationError     = 0xE,
-               PagePermissionFault     = 0xF,
-
-               // not actually in the ARM datasheet
-               // so we are reusing it for nefarious purposes
-               NonMMUError             = 3,
-
-               MMUFaultTypeMask        = 0xF,
-               MMUFaultDomainMask      = 0xF0,
-               MMUFaultDomainShift     = 4,
-               MMUFaultAddressMask     = 0xFFFFFFFF00000000,
-               MMUFaultAddressShift    = 32
-       };
-
-
-
-       ARM710(bool _isTVersion) {
-               isTVersion = _isTVersion;
-               cp15_id = _isTVersion ? 0x41807100 : 0x41047100;
-               clearAllValues();
-       }
-       virtual ~ARM710() { }
-
-       void clearAllValues() {
-               bank = MainBank;
-               CPSR = 0;
-               for (int i = 0; i < 16; i++) GPRs[i] = 0;
-               for (int i = 0; i < 5; i++) {
-                       fiqBankedRegisters[0][i] = 0;
-                       fiqBankedRegisters[1][i] = 0;
-                       SPSRs[i] = 0;
-               }
-               for (int i = 0; i < 6; i++) {
-                       allModesBankedRegisters[i][0] = 0;
-                       allModesBankedRegisters[i][1] = 0;
-               }
-
-               cp15_control = 0;
-               cp15_translationTableBase = 0;
-               cp15_domainAccessControl = 0;
-               cp15_faultStatus = 0;
-               cp15_faultAddress = 0;
-               prefetchCount = 0;
+  enum ValueSize { V8 = 0, V16 = 1, V32 = 2 };
+
+  enum MMUFault : uint64_t {
+    // ref: datasheet 9-13 (p111)
+    NoFault = 0,
+    AlignmentFault = 1,
+    // the ARM gods say there is to be no fault 2 or 3
+    SectionLinefetchError = 4,
+    SectionTranslationFault = 5,
+    PageLinefetchError = 6,
+    PageTranslationFault = 7,
+    SectionOtherBusError = 8,
+    SectionDomainFault = 9,
+    PageOtherBusError = 0xA,
+    PageDomainFault = 0xB,
+    Lv1TranslationError = 0xC,
+    SectionPermissionFault = 0xD,
+    Lv2TranslationError = 0xE,
+    PagePermissionFault = 0xF,
+
+    // not actually in the ARM datasheet
+    // so we are reusing it for nefarious purposes
+    NonMMUError = 3,
+
+    MMUFaultTypeMask = 0xF,
+    MMUFaultDomainMask = 0xF0,
+    MMUFaultDomainShift = 4,
+    MMUFaultAddressMask = 0xFFFFFFFF00000000,
+    MMUFaultAddressShift = 32
+  };
+
+  ARM710(bool _isTVersion) {
+    isTVersion = _isTVersion;
+    cp15_id = _isTVersion ? 0x41807100 : 0x41047100;
+    clearAllValues();
+  }
+  virtual ~ARM710() {}
+
+  void clearAllValues() {
+    bank = MainBank;
+    CPSR = 0;
+    for (int i = 0; i < 16; i++)
+      GPRs[i] = 0;
+    for (int i = 0; i < 5; i++) {
+      fiqBankedRegisters[0][i] = 0;
+      fiqBankedRegisters[1][i] = 0;
+      SPSRs[i] = 0;
+    }
+    for (int i = 0; i < 6; i++) {
+      allModesBankedRegisters[i][0] = 0;
+      allModesBankedRegisters[i][1] = 0;
+    }
+
+    cp15_control = 0;
+    cp15_translationTableBase = 0;
+    cp15_domainAccessControl = 0;
+    cp15_faultStatus = 0;
+    cp15_faultAddress = 0;
+    prefetchCount = 0;
 #ifdef ARM710T_CACHE
-               clearCache();
+    clearCache();
 #endif
 #ifdef ARM710T_TLB
-               flushTlb();
+    flushTlb();
 #endif
-       }
-
-       void setProcessorID(uint32_t v) { cp15_id = v; }
-       bool canAcceptFIQ() const { return !(CPSR & CPSR_FIQDisable); }
-       bool canAcceptIRQ() const { return !(CPSR & CPSR_IRQDisable); }
-       void requestFIQ(); // pull nFIQ low
-       void requestIRQ(); // pull nIRQ low
-       void reset();      // pull nRESET low
-
-       bool instructionReady() const { return (prefetchCount == 2); }
-       uint32_t tick();   // run the chip for at least 1 clock cycle
-
-       MaybeU32 readVirtualDebug(uint32_t virtAddr, ValueSize valueSize);
-       MaybeU32 virtToPhys(uint32_t virtAddr);
-
-       pair<MaybeU32, MMUFault> readVirtual(uint32_t virtAddr, ValueSize valueSize);
-       virtual MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) = 0;
-       MMUFault writeVirtual(uint32_t value, uint32_t virtAddr, ARM710::ValueSize valueSize);
-       virtual bool writePhysical(uint32_t value, uint32_t physAddr, ARM710::ValueSize valueSize) = 0;
-
-       uint32_t getGPR(int index) const { return GPRs[index]; }
-       uint32_t getCPSR() const { return CPSR; }
-       uint32_t getRealPC() const {
-               return GPRs[15] - (4 * prefetchCount);
-       }
-
-       void setLogger(std::function<void(const char *)> newLogger) { logger = newLogger; }
-       uint32_t lastPcExecuted() const { return pcHistory[(pcHistoryIndex - 1) % PcHistoryCount].addr; }
+  }
+
+  void setProcessorID(uint32_t v) { cp15_id = v; }
+  bool canAcceptFIQ() const { return !(CPSR & CPSR_FIQDisable); }
+  bool canAcceptIRQ() const { return !(CPSR & CPSR_IRQDisable); }
+  void requestFIQ(); // pull nFIQ low
+  void requestIRQ(); // pull nIRQ low
+  void reset();      // pull nRESET low
+
+  bool instructionReady() const { return (prefetchCount == 2); }
+  uint32_t tick(); // run the chip for at least 1 clock cycle
+
+  MaybeU32 readVirtualDebug(uint32_t virtAddr, ValueSize valueSize);
+  MaybeU32 virtToPhys(uint32_t virtAddr);
+
+  pair<MaybeU32, MMUFault> readVirtual(uint32_t virtAddr, ValueSize valueSize);
+  virtual MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) = 0;
+  MMUFault writeVirtual(uint32_t value, uint32_t virtAddr,
+                        ARM710::ValueSize valueSize);
+  virtual bool writePhysical(uint32_t value, uint32_t physAddr,
+                             ARM710::ValueSize valueSize) = 0;
+
+  uint32_t getGPR(int index) const { return GPRs[index]; }
+  uint32_t getCPSR() const { return CPSR; }
+  uint32_t getRealPC() const { return GPRs[15] - (4 * prefetchCount); }
+
+  void setLogger(std::function<void(const char*)> newLogger) {
+    logger = newLogger;
+  }
+  uint32_t lastPcExecuted() const {
+    return pcHistory[(pcHistoryIndex - 1) % PcHistoryCount].addr;
+  }
+
 public:
-       void log(const char *format, ...);
-       void logPcHistory();
+  void log(const char* format, ...);
+  void logPcHistory();
+
 private:
-       std::function<void(const char *)> logger;
-
-       enum { PcHistoryCount = 10 };
-       struct { uint32_t addr, insn; } pcHistory[PcHistoryCount];
-       uint32_t pcHistoryIndex = 0;
-
-       enum { Nop = 0xE1A00000 };
-
-       enum Mode : uint8_t {
-               User32       = 0x10,
-               FIQ32        = 0x11,
-               IRQ32        = 0x12,
-               Supervisor32 = 0x13,
-               Abort32      = 0x17,
-               Undefined32  = 0x1B
-       };
-
-       enum BankIndex : uint8_t {
-               FiqBank,
-               IrqBank,
-               SvcBank,
-               AbtBank,
-               UndBank,
-               MainBank
-       };
-
-       constexpr static const BankIndex modeToBank[16] = {
-               MainBank, FiqBank,  IrqBank,  SvcBank,
-               MainBank, MainBank, MainBank, AbtBank,
-               MainBank, MainBank, MainBank, UndBank,
-               MainBank, MainBank, MainBank, MainBank
-       };
-
-       enum : uint32_t {
-               CPSR_ModeMask   = 0x0000001F,
-               CPSR_FIQDisable = 0x00000040,
-               CPSR_IRQDisable = 0x00000080,
-               CPSR_V          = 0x10000000,
-               CPSR_C          = 0x20000000,
-               CPSR_Z          = 0x40000000,
-               CPSR_N          = 0x80000000,
-               CPSR_FlagMask   = 0xF0000000
-       };
-
-       // active state
-       BankIndex bank;
-       uint32_t CPSR;
-       uint32_t GPRs[16];
-
-       // saved state
-       uint32_t fiqBankedRegisters[2][5];      // R8..R12 inclusive
-       uint32_t allModesBankedRegisters[6][2]; // R13, R14
-       uint32_t SPSRs[5];
-
-       // coprocessor 15
-       uint32_t cp15_id;                   // 0: read-only
-       uint32_t cp15_control;              // 1: write-only
-       uint32_t cp15_translationTableBase; // 2: write-only
-       uint32_t cp15_domainAccessControl;  // 3: write-only
-       uint8_t  cp15_faultStatus;          // 5: read-only (writing has unrelated effects)
-       uint32_t cp15_faultAddress;         // 6: read-only (writing has unrelated effects)
-
-       bool isTVersion;
-
-       bool flagV() const { return CPSR & CPSR_V; }
-       bool flagC() const { return CPSR & CPSR_C; }
-       bool flagZ() const { return CPSR & CPSR_Z; }
-       bool flagN() const { return CPSR & CPSR_N; }
-       bool checkCondition(int cond) const {
-               switch (cond) {
-               /*EQ*/ case 0:   return flagZ();
-               /*NE*/ case 1:   return !flagZ();
-               /*CS*/ case 2:   return flagC();
-               /*CC*/ case 3:   return !flagC();
-               /*MI*/ case 4:   return flagN();
-               /*PL*/ case 5:   return !flagN();
-               /*VS*/ case 6:   return flagV();
-               /*VC*/ case 7:   return !flagV();
-               /*HI*/ case 8:   return flagC() && !flagZ();
-               /*LS*/ case 9:   return !flagC() || flagZ();
-               /*GE*/ case 0xA: return flagN() == flagV();
-               /*LT*/ case 0xB: return flagN() != flagV();
-               /*GT*/ case 0xC: return !flagZ() && (flagN() == flagV());
-               /*LE*/ case 0xD: return flagZ() || (flagN() != flagV());
-               /*AL*/ case 0xE: return true;
-               /*NV*/ /*case 0xF:*/
-               default:  return false;
-               }
-       }
-
-       static Mode modeFromCPSR(uint32_t v) { return (Mode)(v & CPSR_ModeMask); }
-       Mode currentMode()             const { return modeFromCPSR(CPSR); }
-       BankIndex currentBank()        const { return modeToBank[(Mode)(CPSR & 0xF)]; }
-       bool isPrivileged()            const { return (CPSR & 0x1F) > User32; }
-       bool isMMUEnabled()            const { return (cp15_control & 1); }
-       bool isAlignmentFaultEnabled() const { return (cp15_control & 2); }
-       bool isCacheEnabled()          const { return (cp15_control & 4); }
-       bool isWriteBufferEnabled()    const { return (cp15_control & 8); }
-
-       void switchMode(Mode mode);
-       void switchBank(BankIndex bank);
-       void raiseException(Mode mode, uint32_t savedPC, uint32_t newPC);
-
-       // MMU/TLB
-       enum MMUFaultSorP : uint64_t {
-               SorPLinefetchError      = 4,
-               SorPTranslationFault    = 5,
-               SorPOtherBusError       = 8,
-               SorPDomainFault         = 9,
-               SorPPermissionFault     = 0xD,
-       };
-
-       MMUFault encodeFault(MMUFault fault, int domain, uint32_t virtAddr) const {
-               return (MMUFault)(fault | (domain << 4) | ((uint64_t)virtAddr << 32));
-       }
-       MMUFault encodeFaultSorP(MMUFaultSorP baseFault, bool isPage, int domain, uint32_t virtAddr) const {
-               return (MMUFault)(baseFault | (isPage ? 2 : 0) | (domain << 4) | ((uint64_t)virtAddr << 32));
-       }
-
-       struct TlbEntry { uint32_t addrMask, addr, lv1Entry, lv2Entry; };
+  std::function<void(const char*)> logger;
+
+  enum { PcHistoryCount = 10 };
+  struct {
+    uint32_t addr, insn;
+  } pcHistory[PcHistoryCount];
+  uint32_t pcHistoryIndex = 0;
+
+  enum { Nop = 0xE1A00000 };
+
+  enum Mode : uint8_t {
+    User32 = 0x10,
+    FIQ32 = 0x11,
+    IRQ32 = 0x12,
+    Supervisor32 = 0x13,
+    Abort32 = 0x17,
+    Undefined32 = 0x1B
+  };
+
+  enum BankIndex : uint8_t {
+    FiqBank,
+    IrqBank,
+    SvcBank,
+    AbtBank,
+    UndBank,
+    MainBank
+  };
+
+  constexpr static const BankIndex modeToBank[16] = {
+      MainBank, FiqBank,  IrqBank,  SvcBank,  MainBank, MainBank,
+      MainBank, AbtBank,  MainBank, MainBank, MainBank, UndBank,
+      MainBank, MainBank, MainBank, MainBank};
+
+  enum : uint32_t {
+    CPSR_ModeMask = 0x0000001F,
+    CPSR_FIQDisable = 0x00000040,
+    CPSR_IRQDisable = 0x00000080,
+    CPSR_V = 0x10000000,
+    CPSR_C = 0x20000000,
+    CPSR_Z = 0x40000000,
+    CPSR_N = 0x80000000,
+    CPSR_FlagMask = 0xF0000000
+  };
+
+  // active state
+  BankIndex bank;
+  uint32_t CPSR;
+  uint32_t GPRs[16];
+
+  // saved state
+  uint32_t fiqBankedRegisters[2][5];      // R8..R12 inclusive
+  uint32_t allModesBankedRegisters[6][2]; // R13, R14
+  uint32_t SPSRs[5];
+
+  // coprocessor 15
+  uint32_t cp15_id;                   // 0: read-only
+  uint32_t cp15_control;              // 1: write-only
+  uint32_t cp15_translationTableBase; // 2: write-only
+  uint32_t cp15_domainAccessControl;  // 3: write-only
+  uint8_t cp15_faultStatus;   // 5: read-only (writing has unrelated effects)
+  uint32_t cp15_faultAddress; // 6: read-only (writing has unrelated effects)
+
+  bool isTVersion;
+
+  bool flagV() const { return CPSR & CPSR_V; }
+  bool flagC() const { return CPSR & CPSR_C; }
+  bool flagZ() const { return CPSR & CPSR_Z; }
+  bool flagN() const { return CPSR & CPSR_N; }
+  bool checkCondition(int cond) const {
+    switch (cond) {
+    /*EQ*/ case 0:
+      return flagZ();
+    /*NE*/ case 1:
+      return !flagZ();
+    /*CS*/ case 2:
+      return flagC();
+    /*CC*/ case 3:
+      return !flagC();
+    /*MI*/ case 4:
+      return flagN();
+    /*PL*/ case 5:
+      return !flagN();
+    /*VS*/ case 6:
+      return flagV();
+    /*VC*/ case 7:
+      return !flagV();
+    /*HI*/ case 8:
+      return flagC() && !flagZ();
+    /*LS*/ case 9:
+      return !flagC() || flagZ();
+    /*GE*/ case 0xA:
+      return flagN() == flagV();
+    /*LT*/ case 0xB:
+      return flagN() != flagV();
+    /*GT*/ case 0xC:
+      return !flagZ() && (flagN() == flagV());
+    /*LE*/ case 0xD:
+      return flagZ() || (flagN() != flagV());
+    /*AL*/ case 0xE:
+      return true;
+    /*NV*/ /*case 0xF:*/
+    default:
+      return false;
+    }
+  }
+
+  static Mode modeFromCPSR(uint32_t v) { return (Mode)(v & CPSR_ModeMask); }
+  Mode currentMode() const { return modeFromCPSR(CPSR); }
+  BankIndex currentBank() const { return modeToBank[(Mode)(CPSR & 0xF)]; }
+  bool isPrivileged() const { return (CPSR & 0x1F) > User32; }
+  bool isMMUEnabled() const { return (cp15_control & 1); }
+  bool isAlignmentFaultEnabled() const { return (cp15_control & 2); }
+  bool isCacheEnabled() const { return (cp15_control & 4); }
+  bool isWriteBufferEnabled() const { return (cp15_control & 8); }
+
+  void switchMode(Mode mode);
+  void switchBank(BankIndex bank);
+  void raiseException(Mode mode, uint32_t savedPC, uint32_t newPC);
+
+  // MMU/TLB
+  enum MMUFaultSorP : uint64_t {
+    SorPLinefetchError = 4,
+    SorPTranslationFault = 5,
+    SorPOtherBusError = 8,
+    SorPDomainFault = 9,
+    SorPPermissionFault = 0xD,
+  };
+
+  MMUFault encodeFault(MMUFault fault, int domain, uint32_t virtAddr) const {
+    return (MMUFault)(fault | (domain << 4) | ((uint64_t)virtAddr << 32));
+  }
+  MMUFault encodeFaultSorP(MMUFaultSorP baseFault, bool isPage, int domain,
+                           uint32_t virtAddr) const {
+    return (MMUFault)(baseFault | (isPage ? 2 : 0) | (domain << 4) |
+                      ((uint64_t)virtAddr << 32));
+  }
+
+  struct TlbEntry {
+    uint32_t addrMask, addr, lv1Entry, lv2Entry;
+  };
 #ifdef ARM710T_TLB
-       enum { TlbSize = 64 };
-       TlbEntry tlb[TlbSize];
-       int nextTlbIndex = 0;
+  enum { TlbSize = 64 };
+  TlbEntry tlb[TlbSize];
+  int nextTlbIndex = 0;
 
-       void flushTlb();
-       void flushTlb(uint32_t virtAddr);
+  void flushTlb();
+  void flushTlb(uint32_t virtAddr);
 #else
-       TlbEntry singleTlbEntry;
-#endif 
+  TlbEntry singleTlbEntry;
+#endif
 
-       TlbEntry *_allocateTlbEntry(uint32_t addrMask, uint32_t addr);
-       variant<TlbEntry *, MMUFault> translateAddressUsingTlb(uint32_t virtAddr, TlbEntry *useMe=nullptr);
-       static uint32_t physAddrFromTlbEntry(TlbEntry *tlbEntry, uint32_t virtAddr);
-       MMUFault checkAccessPermissions(TlbEntry *entry, uint32_t virtAddr, bool isWrite) const;
+  TlbEntry* _allocateTlbEntry(uint32_t addrMask, uint32_t addr);
+  variant<TlbEntry*, MMUFault>
+  translateAddressUsingTlb(uint32_t virtAddr, TlbEntry* useMe = nullptr);
+  static uint32_t physAddrFromTlbEntry(TlbEntry* tlbEntry, uint32_t virtAddr);
+  MMUFault checkAccessPermissions(TlbEntry* entry, uint32_t virtAddr,
+                                  bool isWrite) const;
 
-       bool faultTriggeredThisCycle = false;
-       void reportFault(MMUFault fault);
+  bool faultTriggeredThisCycle = false;
+  void reportFault(MMUFault fault);
 
-       // Instruction/Data Cache
+  // Instruction/Data Cache
 #ifdef ARM710T_CACHE
-       enum {
-               CacheSets = 4,
-               CacheBlocksPerSet = 128,
-               CacheBlockSize = 0x10,
-
-               CacheAddressLineMask = 0x0000000F,
-               CacheAddressSetMask  = 0x00000030, CacheAddressSetShift = 4,
-               CacheAddressTagMask  = 0xFFFFFFC0,
-
-               CacheBlockEnabled = 1
-       };
-       uint32_t cacheBlockTags[CacheSets][CacheBlocksPerSet];
-       uint8_t cacheBlocks[CacheSets][CacheBlocksPerSet][CacheBlockSize];
-
-       void clearCache();
-       uint8_t *findCacheLine(uint32_t virtAddr);
-       pair<MaybeU32, MMUFault> addCacheLineAndRead(uint32_t physAddr, uint32_t virtAddr, ValueSize valueSize, int domain, bool isPage);
-       MaybeU32 readCached(uint32_t virtAddr, ValueSize valueSize);
-       bool writeCached(uint32_t value, uint32_t virtAddr, ValueSize valueSize);
+  enum {
+    CacheSets = 4,
+    CacheBlocksPerSet = 128,
+    CacheBlockSize = 0x10,
+
+    CacheAddressLineMask = 0x0000000F,
+    CacheAddressSetMask = 0x00000030,
+    CacheAddressSetShift = 4,
+    CacheAddressTagMask = 0xFFFFFFC0,
+
+    CacheBlockEnabled = 1
+  };
+  uint32_t cacheBlockTags[CacheSets][CacheBlocksPerSet];
+  uint8_t cacheBlocks[CacheSets][CacheBlocksPerSet][CacheBlockSize];
+
+  void clearCache();
+  uint8_t* findCacheLine(uint32_t virtAddr);
+  pair<MaybeU32, MMUFault> addCacheLineAndRead(uint32_t physAddr,
+                                               uint32_t virtAddr,
+                                               ValueSize valueSize, int domain,
+                                               bool isPage);
+  MaybeU32 readCached(uint32_t virtAddr, ValueSize valueSize);
+  bool writeCached(uint32_t value, uint32_t virtAddr, ValueSize valueSize);
 #endif
 
-       // Instruction Loop
-       int prefetchCount;
-       uint32_t prefetch[2];
-       MMUFault prefetchFaults[2];
-
-       uint32_t executeInstruction(uint32_t insn);
-
-       uint32_t execDataProcessing(bool I, uint32_t Opcode, bool S, uint32_t Rn, uint32_t Rd, uint32_t Operand2);
-       uint32_t execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn, uint32_t Rs, uint32_t Rm);
-       uint32_t execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo, uint32_t Rs, uint32_t Rm);
-       uint32_t execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd, uint32_t Rm);
-       uint32_t execSingleDataTransfer(uint32_t IPUBWL, uint32_t Rn, uint32_t Rd, uint32_t offset);
-       uint32_t execSingleHalfWordDataTransfer(uint32_t PUIWL, uint32_t Rn, uint32_t Rd, uint32_t addrMode1, uint32_t SH, uint32_t addrMode2);
-       uint32_t execBlockDataTransfer(uint32_t PUSWL, uint32_t Rn, uint32_t registerList);
-       uint32_t execBranch(bool L, uint32_t offset);
-       uint32_t execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn, uint32_t Rd, uint32_t CP, uint32_t CRm);
+  // Instruction Loop
+  int prefetchCount;
+  uint32_t prefetch[2];
+  MMUFault prefetchFaults[2];
+
+  uint32_t executeInstruction(uint32_t insn);
+
+  uint32_t execDataProcessing(bool I, uint32_t Opcode, bool S, uint32_t Rn,
+                              uint32_t Rd, uint32_t Operand2);
+  uint32_t execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn, uint32_t Rs,
+                        uint32_t Rm);
+  uint32_t execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo,
+                            uint32_t Rs, uint32_t Rm);
+  uint32_t execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd, uint32_t Rm);
+  uint32_t execSingleDataTransfer(uint32_t IPUBWL, uint32_t Rn, uint32_t Rd,
+                                  uint32_t offset);
+  uint32_t execSingleHalfWordDataTransfer(uint32_t PUIWL, uint32_t Rn,
+                                          uint32_t Rd, uint32_t addrMode1,
+                                          uint32_t SH, uint32_t addrMode2);
+  uint32_t execBlockDataTransfer(uint32_t PUSWL, uint32_t Rn,
+                                 uint32_t registerList);
+  uint32_t execBranch(bool L, uint32_t offset);
+  uint32_t execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn,
+                                    uint32_t Rd, uint32_t CP, uint32_t CRm);
 };
index 618e54606aeece8657a4ab0d0b6c39030f0cedb7..0f5087a292f1da7c2475ed2a1facde30688542e8 100644 (file)
 #include "clps7111.h"
 #include "clps7111_defs.h"
+#include "common.h"
 #include "hardware.h"
 #include <time.h>
-#include "common.h"
-
 
 namespace CLPS7111 {
-Emulator::Emulator() : EmuBase(false), pcCardController(this) {
-}
-
-
-uint32_t Emulator::getRTC() {
-       return time(nullptr) - 946684800;
-}
-
+Emulator::Emulator() : EmuBase(false), pcCardController(this) {}
 
+uint32_t Emulator::getRTC() { return time(nullptr) - 946684800; }
 
 uint32_t Emulator::readReg8(uint32_t reg) {
-       if (reg == PADR) {
-               return ((portValues >> 24) & 0x80) | (readKeyboard() & 0x7F);
-       } else if (reg == PBDR) {
-               return ((portValues >> 16) & 0x0F) | ((keyboardExtra ^ 0xF) << 4);
-       } else if (reg == PDDR) {
-               return (portValues >> 8) & 0xFF;
-       } else if (reg == PEDR) {
-               return portValues & 0xFF;
-       } else if (reg == PADDR) {
-               return (portDirections >> 24) & 0xFF;
-       } else if (reg == PBDDR) {
-               return (portDirections >> 16) & 0xFF;
-       } else if (reg == PDDDR) {
-               return (portDirections >> 8) & 0xFF;
-       } else if (reg == PEDDR) {
-               return portDirections & 0xFF;
-       } else {
-               log("RegRead8 unknown:: pc=%08x lr=%08x reg=%03x", getRealPC(), getGPR(14), reg);
-               return 0xFF;
-       }
+  if (reg == PADR) {
+    return ((portValues >> 24) & 0x80) | (readKeyboard() & 0x7F);
+  } else if (reg == PBDR) {
+    return ((portValues >> 16) & 0x0F) | ((keyboardExtra ^ 0xF) << 4);
+  } else if (reg == PDDR) {
+    return (portValues >> 8) & 0xFF;
+  } else if (reg == PEDR) {
+    return portValues & 0xFF;
+  } else if (reg == PADDR) {
+    return (portDirections >> 24) & 0xFF;
+  } else if (reg == PBDDR) {
+    return (portDirections >> 16) & 0xFF;
+  } else if (reg == PDDDR) {
+    return (portDirections >> 8) & 0xFF;
+  } else if (reg == PEDDR) {
+    return portDirections & 0xFF;
+  } else {
+    log("RegRead8 unknown:: pc=%08x lr=%08x reg=%03x", getRealPC(), getGPR(14),
+        reg);
+    return 0xFF;
+  }
 }
 uint32_t Emulator::readReg32(uint32_t reg) {
-       if (reg == SYSCON1) {
-               uint32_t flg = 0;
-               if (tc1.config & Timer::PERIODIC) flg |= 0x10;
-               if (tc1.config & Timer::MODE_512KHZ) flg |= 0x20;
-               if (tc2.config & Timer::PERIODIC) flg |= 0x40;
-               if (tc2.config & Timer::MODE_512KHZ) flg |= 0x80;
-               flg |= (kScan & 0xF);
-               return flg;
-       } else if (reg == SYSFLG1) {
-               uint32_t flg = sysFlg1;
-               flg |= 2; // external power present
-               flg |= (rtcDiv << 16);
-               // maybe set more stuff?
-               return flg;
-       } else if (reg == INTSR1) {
-               return pendingInterrupts & 0xFFFF;
-       } else if (reg == INTMR1) {
-               return interruptMask & 0xFFFF;
-       } else if (reg == LCDCON) {
-               return lcdControl;
-       } else if (reg == TC1D) {
-               return tc1.value;
-       } else if (reg == TC2D) {
-               return tc2.value;
-       } else if (reg == RTCDR) {
-               return rtc;
-       } else if (reg == SYNCIO) {
-               switch (lastSyncioRequest & 0xFF) {
-               case 0xC1: // DigitiserX
-                       return (touchX * 8) + 305;
-               case 0x81: // DigitiserY
-                       return (touchY * 13.53) + 680;
-               case 0x91: // MainBattery
-                       return 3000;
-               case 0xD1: // BackupBattery
-                       return 3100;
-               case 0xA1: // Reference
-                       return 1000;
-               }
-               log("SYNCIO read unknown:: req=%08x", lastSyncioRequest);
-               return 0xFFFFFFFF;
-       } else if (reg == PALLSW) {
-               return lcdPalette & 0xFFFFFFFF;
-       } else if (reg == PALMSW) {
-               return lcdPalette >> 32;
-       } else if (reg == SYSCON2) {
-               return 0;
-       } else if (reg == SYSFLG2) {
-               return 0;
-       } else if (reg == INTSR2) {
-               return pendingInterrupts >> 16;
-       } else if (reg == INTMR2) {
-               return interruptMask >> 16;
-       } else {
-               log("RegRead32 unknown:: pc=%08x lr=%08x reg=%03x", getRealPC(), getGPR(14), reg);
-               return 0xFFFFFFFF;
-       }
+  if (reg == SYSCON1) {
+    uint32_t flg = 0;
+    if (tc1.config & Timer::PERIODIC)
+      flg |= 0x10;
+    if (tc1.config & Timer::MODE_512KHZ)
+      flg |= 0x20;
+    if (tc2.config & Timer::PERIODIC)
+      flg |= 0x40;
+    if (tc2.config & Timer::MODE_512KHZ)
+      flg |= 0x80;
+    flg |= (kScan & 0xF);
+    return flg;
+  } else if (reg == SYSFLG1) {
+    uint32_t flg = sysFlg1;
+    flg |= 2; // external power present
+    flg |= (rtcDiv << 16);
+    // maybe set more stuff?
+    return flg;
+  } else if (reg == INTSR1) {
+    return pendingInterrupts & 0xFFFF;
+  } else if (reg == INTMR1) {
+    return interruptMask & 0xFFFF;
+  } else if (reg == LCDCON) {
+    return lcdControl;
+  } else if (reg == TC1D) {
+    return tc1.value;
+  } else if (reg == TC2D) {
+    return tc2.value;
+  } else if (reg == RTCDR) {
+    return rtc;
+  } else if (reg == SYNCIO) {
+    switch (lastSyncioRequest & 0xFF) {
+    case 0xC1: // DigitiserX
+      return (touchX * 8) + 305;
+    case 0x81: // DigitiserY
+      return (touchY * 13.53) + 680;
+    case 0x91: // MainBattery
+      return 3000;
+    case 0xD1: // BackupBattery
+      return 3100;
+    case 0xA1: // Reference
+      return 1000;
+    }
+    log("SYNCIO read unknown:: req=%08x", lastSyncioRequest);
+    return 0xFFFFFFFF;
+  } else if (reg == PALLSW) {
+    return lcdPalette & 0xFFFFFFFF;
+  } else if (reg == PALMSW) {
+    return lcdPalette >> 32;
+  } else if (reg == SYSCON2) {
+    return 0;
+  } else if (reg == SYSFLG2) {
+    return 0;
+  } else if (reg == INTSR2) {
+    return pendingInterrupts >> 16;
+  } else if (reg == INTMR2) {
+    return interruptMask >> 16;
+  } else {
+    log("RegRead32 unknown:: pc=%08x lr=%08x reg=%03x", getRealPC(), getGPR(14),
+        reg);
+    return 0xFFFFFFFF;
+  }
 }
 
 void Emulator::writeReg8(uint32_t reg, uint8_t value) {
-       if (reg == PADR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0x00FFFFFF;
-               portValues |= (uint32_t)value << 24;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PBDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFF00FFFF;
-               portValues |= (uint32_t)value << 16;
-//             if ((portValues & 0x10000) && !(oldPorts & 0x10000))
-//                     etna.setPromBit0High();
-//             else if (!(portValues & 0x10000) && (oldPorts & 0x10000))
-//                     etna.setPromBit0Low();
-//             if ((portValues & 0x20000) && !(oldPorts & 0x20000))
-//                     etna.setPromBit1High();
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PDDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFFFF00FF;
-               portValues |= (uint32_t)value << 8;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PEDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFFFFFF00;
-               portValues |= (uint32_t)value;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PADDR) {
-               portDirections &= 0x00FFFFFF;
-               portDirections |= (uint32_t)value << 24;
-       } else if (reg == PBDDR) {
-               portDirections &= 0xFF00FFFF;
-               portDirections |= (uint32_t)value << 16;
-       } else if (reg == PDDDR) {
-               portDirections &= 0xFFFF00FF;
-               portDirections |= (uint32_t)value << 8;
-       } else if (reg == PEDDR) {
-               portDirections &= 0xFFFFFF00;
-               portDirections |= (uint32_t)value;
-       } else if (reg == FRBADDR) {
-               log("LCD: address write %08x", value << 28);
-               lcdAddress = value << 28;
-       } else {
-               log("RegWrite8 unknown:: pc=%08x reg=%03x value=%02x", getRealPC(), reg, value);
-       }
+  if (reg == PADR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0x00FFFFFF;
+    portValues |= (uint32_t)value << 24;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PBDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFF00FFFF;
+    portValues |= (uint32_t)value << 16;
+    //         if ((portValues & 0x10000) && !(oldPorts & 0x10000))
+    //                 etna.setPromBit0High();
+    //         else if (!(portValues & 0x10000) && (oldPorts & 0x10000))
+    //                 etna.setPromBit0Low();
+    //         if ((portValues & 0x20000) && !(oldPorts & 0x20000))
+    //                 etna.setPromBit1High();
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PDDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFFFF00FF;
+    portValues |= (uint32_t)value << 8;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PEDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFFFFFF00;
+    portValues |= (uint32_t)value;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PADDR) {
+    portDirections &= 0x00FFFFFF;
+    portDirections |= (uint32_t)value << 24;
+  } else if (reg == PBDDR) {
+    portDirections &= 0xFF00FFFF;
+    portDirections |= (uint32_t)value << 16;
+  } else if (reg == PDDDR) {
+    portDirections &= 0xFFFF00FF;
+    portDirections |= (uint32_t)value << 8;
+  } else if (reg == PEDDR) {
+    portDirections &= 0xFFFFFF00;
+    portDirections |= (uint32_t)value;
+  } else if (reg == FRBADDR) {
+    log("LCD: address write %08x", value << 28);
+    lcdAddress = value << 28;
+  } else {
+    log("RegWrite8 unknown:: pc=%08x reg=%03x value=%02x", getRealPC(), reg,
+        value);
+  }
 }
 void Emulator::writeReg32(uint32_t reg, uint32_t value) {
-       if (reg == SYSCON1) {
-               kScan = value & 0xF;
-               uint8_t tc1cfg = Timer::ENABLED; // always on with PS-7111!
-               if (value & 0x10) tc1cfg |= Timer::PERIODIC;
-               if (value & 0x20) tc1cfg |= Timer::MODE_512KHZ;
-               uint8_t tc2cfg = Timer::ENABLED;
-               if (value & 0x40) tc2cfg |= Timer::PERIODIC;
-               if (value & 0x80) tc2cfg |= Timer::MODE_512KHZ;
-               tc1.setConfig(tc1cfg);
-               tc2.setConfig(tc2cfg);
-       } else if (reg == INTMR1) {
-               interruptMask &= 0xFFFF0000;;
-               interruptMask |= (value & 0xFFFF);
-       } else if (reg == LCDCON) {
-               log("LCD: ctl write %08x", value);
-               lcdControl = value;
-       } else if (reg == TC1D) {
-               tc1.load(value);
-       } else if (reg == TC2D) {
-               tc2.load(value);
-       } else if (reg == RTCDR) {
-               rtc = value;
-       } else if (reg == SYNCIO) {
-               lastSyncioRequest = value & 0xFFFF;
-       } else if (reg == PALLSW) {
-               lcdPalette &= 0xFFFFFFFF00000000;
-               lcdPalette |= value;
-       } else if (reg == PALMSW) {
-               lcdPalette &= 0x00000000FFFFFFFF;
-               lcdPalette |= (uint64_t)value << 32;
-       } else if (reg == HALT) {
-               halted = true;
-       // BLEOI = 0x410,
-       // MCEOI = 0x414,
-       } else if (reg == TEOI) {
-               pendingInterrupts &= ~(1 << TINT);
-       // TEOI = 0x418,
-       // STFCLR = 0x41C,
-       // E2EOI = 0x420,
-       } else if (reg == TC1EOI) {
-               pendingInterrupts &= ~(1 << TC1OI);
-       } else if (reg == TC2EOI) {
-               pendingInterrupts &= ~(1 << TC2OI);
-       } else if (reg == SYSCON2) {
-               log("SysCon2 write: %08x", value);
-       } else if (reg == INTMR2) {
-               interruptMask &= 0xFFFF;
-               interruptMask |= (value << 16);
-       } else if (reg == KBDEOI) {
-               pendingInterrupts &= ~(1 << KBDINT);
-       } else {
-               log("RegWrite32 unknown:: pc=%08x reg=%03x value=%08x", getRealPC(), reg, value);
-       }
+  if (reg == SYSCON1) {
+    kScan = value & 0xF;
+    uint8_t tc1cfg = Timer::ENABLED; // always on with PS-7111!
+    if (value & 0x10)
+      tc1cfg |= Timer::PERIODIC;
+    if (value & 0x20)
+      tc1cfg |= Timer::MODE_512KHZ;
+    uint8_t tc2cfg = Timer::ENABLED;
+    if (value & 0x40)
+      tc2cfg |= Timer::PERIODIC;
+    if (value & 0x80)
+      tc2cfg |= Timer::MODE_512KHZ;
+    tc1.setConfig(tc1cfg);
+    tc2.setConfig(tc2cfg);
+  } else if (reg == INTMR1) {
+    interruptMask &= 0xFFFF0000;
+    ;
+    interruptMask |= (value & 0xFFFF);
+  } else if (reg == LCDCON) {
+    log("LCD: ctl write %08x", value);
+    lcdControl = value;
+  } else if (reg == TC1D) {
+    tc1.load(value);
+  } else if (reg == TC2D) {
+    tc2.load(value);
+  } else if (reg == RTCDR) {
+    rtc = value;
+  } else if (reg == SYNCIO) {
+    lastSyncioRequest = value & 0xFFFF;
+  } else if (reg == PALLSW) {
+    lcdPalette &= 0xFFFFFFFF00000000;
+    lcdPalette |= value;
+  } else if (reg == PALMSW) {
+    lcdPalette &= 0x00000000FFFFFFFF;
+    lcdPalette |= (uint64_t)value << 32;
+  } else if (reg == HALT) {
+    halted = true;
+    // BLEOI = 0x410,
+    // MCEOI = 0x414,
+  } else if (reg == TEOI) {
+    pendingInterrupts &= ~(1 << TINT);
+    // TEOI = 0x418,
+    // STFCLR = 0x41C,
+    // E2EOI = 0x420,
+  } else if (reg == TC1EOI) {
+    pendingInterrupts &= ~(1 << TC1OI);
+  } else if (reg == TC2EOI) {
+    pendingInterrupts &= ~(1 << TC2OI);
+  } else if (reg == SYSCON2) {
+    log("SysCon2 write: %08x", value);
+  } else if (reg == INTMR2) {
+    interruptMask &= 0xFFFF;
+    interruptMask |= (value << 16);
+  } else if (reg == KBDEOI) {
+    pendingInterrupts &= ~(1 << KBDINT);
+  } else {
+    log("RegWrite32 unknown:: pc=%08x reg=%03x value=%08x", getRealPC(), reg,
+        value);
+  }
 }
 
 MaybeU32 Emulator::readPhysical(uint32_t physAddr, ValueSize valueSize) {
-       uint8_t region = (physAddr >> 28);
-       if (valueSize == V8) {
-               if (region == 0)
-                       return ROM[physAddr & 0xFFFFFF];
-               else if (region == 1)
-                       return ROM2[physAddr & 0x3FFFF];
-               else if (region == 4)
-                       return pcCardController.read(physAddr & 0xFFFFFFF, V8);
-               else if (region == 8 && physAddr <= 0x80001FFF)
-                       return readReg8(physAddr & 0x1FFF);
-               else if (region == 0xC)
-                       return MemoryBlockC0[physAddr & MemoryBlockMask];
-               else if (region > 0xC)
-                       return 0xFF; // just throw accesses to unmapped RAM away
-       } else {
-               uint32_t result;
-               if (region == 0)
-                       LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
-               else if (region == 1)
-                       LOAD_32LE(result, physAddr & 0x3FFFF, ROM2);
-               else if (region == 4)
-                       result = pcCardController.read(physAddr & 0xFFFFFFF, V32);
-               else if (region == 8 && physAddr <= 0x80001FFF)
-                       result = readReg32(physAddr & 0x1FFF);
-               else if (region == 0xC)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region > 0xC)
-                       return 0xFFFFFFFF; // just throw accesses to unmapped RAM away
-               else
-                       return {};
-               return result;
-       }
-
-       return {};
+  uint8_t region = (physAddr >> 28);
+  if (valueSize == V8) {
+    if (region == 0)
+      return ROM[physAddr & 0xFFFFFF];
+    else if (region == 1)
+      return ROM2[physAddr & 0x3FFFF];
+    else if (region == 4)
+      return pcCardController.read(physAddr & 0xFFFFFFF, V8);
+    else if (region == 8 && physAddr <= 0x80001FFF)
+      return readReg8(physAddr & 0x1FFF);
+    else if (region == 0xC)
+      return MemoryBlockC0[physAddr & MemoryBlockMask];
+    else if (region > 0xC)
+      return 0xFF; // just throw accesses to unmapped RAM away
+  } else {
+    uint32_t result;
+    if (region == 0)
+      LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
+    else if (region == 1)
+      LOAD_32LE(result, physAddr & 0x3FFFF, ROM2);
+    else if (region == 4)
+      result = pcCardController.read(physAddr & 0xFFFFFFF, V32);
+    else if (region == 8 && physAddr <= 0x80001FFF)
+      result = readReg32(physAddr & 0x1FFF);
+    else if (region == 0xC)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region > 0xC)
+      return 0xFFFFFFFF; // just throw accesses to unmapped RAM away
+    else
+      return {};
+    return result;
+  }
+
+  return {};
 }
 
-bool Emulator::writePhysical(uint32_t value, uint32_t physAddr, ValueSize valueSize) {
-       uint8_t region = (physAddr >> 28);
-       if (valueSize == V8) {
-               if (region == 0xC)
-                       MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
-               else if (region > 0xC)
-                       return true; // just throw accesses to unmapped RAM away
-               else if (region == 4)
-                       pcCardController.write(value, physAddr & 0xFFFFFFF, V8);
-               else if (region == 8 && physAddr <= 0x80001FFF)
-                       writeReg8(physAddr & 0x1FFF, value);
-               else
-                       return false;
-       } else {
-               if (region == 0xC)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region > 0xC)
-                       return true; // just throw accesses to unmapped RAM away
-               else if (region == 4)
-                       pcCardController.write(value, physAddr & 0xFFFFFFF, V32);
-               else if (region == 8 && physAddr <= 0x80001FFF)
-                       writeReg32(physAddr & 0x1FFF, value);
-               else
-                       return false;
-       }
-       return true;
+bool Emulator::writePhysical(uint32_t value, uint32_t physAddr,
+                             ValueSize valueSize) {
+  uint8_t region = (physAddr >> 28);
+  if (valueSize == V8) {
+    if (region == 0xC)
+      MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    else if (region > 0xC)
+      return true; // just throw accesses to unmapped RAM away
+    else if (region == 4)
+      pcCardController.write(value, physAddr & 0xFFFFFFF, V8);
+    else if (region == 8 && physAddr <= 0x80001FFF)
+      writeReg8(physAddr & 0x1FFF, value);
+    else
+      return false;
+  } else {
+    if (region == 0xC)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region > 0xC)
+      return true; // just throw accesses to unmapped RAM away
+    else if (region == 4)
+      pcCardController.write(value, physAddr & 0xFFFFFFF, V32);
+    else if (region == 8 && physAddr <= 0x80001FFF)
+      writeReg32(physAddr & 0x1FFF, value);
+    else
+      return false;
+  }
+  return true;
 }
 
-
-
 void Emulator::configure() {
-       if (configured) return;
-       configured = true;
+  if (configured)
+    return;
+  configured = true;
 
-       srand(1000);
+  srand(1000);
 
-       memset(&tc1, 0, sizeof(tc1));
-       memset(&tc2, 0, sizeof(tc1));
-       tc1.clockSpeed = CLOCK_SPEED;
-       tc2.clockSpeed = CLOCK_SPEED;
+  memset(&tc1, 0, sizeof(tc1));
+  memset(&tc2, 0, sizeof(tc1));
+  tc1.clockSpeed = CLOCK_SPEED;
+  tc2.clockSpeed = CLOCK_SPEED;
 
-       nextTickAt = TICK_INTERVAL;
-       tc1.nextTickAt = tc1.tickInterval();
-       tc2.nextTickAt = tc2.tickInterval();
-       rtc = getRTC();
+  nextTickAt = TICK_INTERVAL;
+  tc1.nextTickAt = tc1.tickInterval();
+  tc2.nextTickAt = tc2.tickInterval();
+  rtc = getRTC();
 
-       reset();
+  reset();
 }
 
-uint8_t *Emulator::getROMBuffer() {
-       return ROM;
-}
-size_t Emulator::getROMSize() {
-       return sizeof(ROM);
-}
-void Emulator::loadROM(uint8_t *buffer, size_t size) {
-       memcpy(ROM, buffer, min(size, sizeof(ROM)));
+uint8_t* Emulator::getROMBuffer() { return ROM; }
+size_t Emulator::getROMSize() { return sizeof(ROM); }
+void Emulator::loadROM(uint8_t* buffer, size_t size) {
+  memcpy(ROM, buffer, min(size, sizeof(ROM)));
 }
 
 void Emulator::executeUntil(int64_t cycles) {
-       if (!configured)
-               configure();
-
-       while (!asleep && passedCycles < cycles) {
-               if (passedCycles >= nextTickAt) {
-                       // increment RTCDIV
-                       if (rtcDiv == 0x3F) {
-                               rtc++;
-                               rtcDiv = 0;
-                       } else {
-                               rtcDiv++;
-                       }
-
-                       nextTickAt += TICK_INTERVAL;
-                       pendingInterrupts |= (1<<TINT);
-               }
-               if (tc1.tick(passedCycles))
-                       pendingInterrupts |= (1<<TC1OI);
-               if (tc2.tick(passedCycles))
-                       pendingInterrupts |= (1<<TC2OI);
-
-               if ((pendingInterrupts & interruptMask & FIQ_INTERRUPTS) != 0 && canAcceptFIQ()) {
-                       requestFIQ();
-                       halted = false;
-               }
-               if ((pendingInterrupts & interruptMask & IRQ_INTERRUPTS) != 0 && canAcceptIRQ()) {
-                       requestIRQ();
-                       halted = false;
-               }
-
-               // what's running?
-               if (halted) {
-                       // keep the clock moving
-                       passedCycles++;
-               } else {
-                       if (auto v = virtToPhys(getGPR(15) - 0xC); v.has_value() && instructionReady())
-                               debugPC(v.value());
-                       passedCycles += tick();
-
-                       uint32_t new_pc = getGPR(15) - 0xC;
-                       if (_breakpoints.find(new_pc) != _breakpoints.end()) {
-                               log("⚠️ Breakpoint triggered at %08x!", new_pc);
-                               return;
-                       }
-                       if (new_pc >= 0x80000000 && new_pc <= 0x90000000) {
-                               log("BAD PC %08x!!", new_pc);
-                               logPcHistory();
-                               return;
-                       }
-               }
-       }
+  if (!configured)
+    configure();
+
+  while (!asleep && passedCycles < cycles) {
+    if (passedCycles >= nextTickAt) {
+      // increment RTCDIV
+      if (rtcDiv == 0x3F) {
+        rtc++;
+        rtcDiv = 0;
+      } else {
+        rtcDiv++;
+      }
+
+      nextTickAt += TICK_INTERVAL;
+      pendingInterrupts |= (1 << TINT);
+    }
+    if (tc1.tick(passedCycles))
+      pendingInterrupts |= (1 << TC1OI);
+    if (tc2.tick(passedCycles))
+      pendingInterrupts |= (1 << TC2OI);
+
+    if ((pendingInterrupts & interruptMask & FIQ_INTERRUPTS) != 0 &&
+        canAcceptFIQ()) {
+      requestFIQ();
+      halted = false;
+    }
+    if ((pendingInterrupts & interruptMask & IRQ_INTERRUPTS) != 0 &&
+        canAcceptIRQ()) {
+      requestIRQ();
+      halted = false;
+    }
+
+    // what's running?
+    if (halted) {
+      // keep the clock moving
+      passedCycles++;
+    } else {
+      if (auto v = virtToPhys(getGPR(15) - 0xC);
+          v.has_value() && instructionReady())
+        debugPC(v.value());
+      passedCycles += tick();
+
+      uint32_t new_pc = getGPR(15) - 0xC;
+      if (_breakpoints.find(new_pc) != _breakpoints.end()) {
+        log("⚠️ Breakpoint triggered at %08x!", new_pc);
+        return;
+      }
+      if (new_pc >= 0x80000000 && new_pc <= 0x90000000) {
+        log("BAD PC %08x!!", new_pc);
+        logPcHistory();
+        return;
+      }
+    }
+  }
 }
 
-
-const char *Emulator::identifyObjectCon(uint32_t ptr) {
-       if (ptr == readVirtualDebug(0x80000880, V32).value()) return "process";
-       if (ptr == readVirtualDebug(0x80000884, V32).value()) return "thread";
-       if (ptr == readVirtualDebug(0x80000888, V32).value()) return "chunk";
-//     if (ptr == readVirtualDebug(0x8000088C, V32).value()) return "semaphore";
-//     if (ptr == readVirtualDebug(0x80000890, V32).value()) return "mutex";
-       if (ptr == readVirtualDebug(0x80000894, V32).value()) return "logicaldevice";
-       if (ptr == readVirtualDebug(0x80000898, V32).value()) return "physicaldevice";
-       if (ptr == readVirtualDebug(0x8000089C, V32).value()) return "channel";
-       if (ptr == readVirtualDebug(0x800008A0, V32).value()) return "server";
-//     if (ptr == readVirtualDebug(0x800008A4, V32).value()) return "unk8A4"; // name always null
-       if (ptr == readVirtualDebug(0x800008AC, V32).value()) return "library";
-//     if (ptr == readVirtualDebug(0x800008B0, V32).value()) return "unk8B0"; // name always null
-//     if (ptr == readVirtualDebug(0x800008B4, V32).value()) return "unk8B4"; // name always null
-       return nullptr;
+const char* Emulator::identifyObjectCon(uint32_t ptr) {
+  if (ptr == readVirtualDebug(0x80000880, V32).value())
+    return "process";
+  if (ptr == readVirtualDebug(0x80000884, V32).value())
+    return "thread";
+  if (ptr == readVirtualDebug(0x80000888, V32).value())
+    return "chunk";
+  //   if (ptr == readVirtualDebug(0x8000088C, V32).value()) return
+  //"semaphore";       if (ptr == readVirtualDebug(0x80000890, V32).value())
+  //return "mutex";
+  if (ptr == readVirtualDebug(0x80000894, V32).value())
+    return "logicaldevice";
+  if (ptr == readVirtualDebug(0x80000898, V32).value())
+    return "physicaldevice";
+  if (ptr == readVirtualDebug(0x8000089C, V32).value())
+    return "channel";
+  if (ptr == readVirtualDebug(0x800008A0, V32).value())
+    return "server";
+  //   if (ptr == readVirtualDebug(0x800008A4, V32).value()) return "unk8A4";
+  //// name always null
+  if (ptr == readVirtualDebug(0x800008AC, V32).value())
+    return "library";
+  //   if (ptr == readVirtualDebug(0x800008B0, V32).value()) return "unk8B0";
+  //// name always null        if (ptr == readVirtualDebug(0x800008B4,
+  ///V32).value())
+  // return "unk8B4"; // name always null
+  return nullptr;
 }
 
-void Emulator::fetchStr(uint32_t str, char *buf) {
-       if (str == 0) {
-               strcpy(buf, "<NULL>");
-               return;
-       }
-       int size = readVirtualDebug(str, V32).value();
-       for (int i = 0; i < size; i++) {
-               buf[i] = readVirtualDebug(str + 4 + i, V8).value();
-       }
-       buf[size] = 0;
+void Emulator::fetchStr(uint32_t str, charbuf) {
+  if (str == 0) {
+    strcpy(buf, "<NULL>");
+    return;
+  }
+  int size = readVirtualDebug(str, V32).value();
+  for (int i = 0; i < size; i++) {
+    buf[i] = readVirtualDebug(str + 4 + i, V8).value();
+  }
+  buf[size] = 0;
 }
 
-void Emulator::fetchName(uint32_t obj, char *buf) {
-       fetchStr(readVirtualDebug(obj + 0x10, V32).value(), buf);
+void Emulator::fetchName(uint32_t obj, charbuf) {
+  fetchStr(readVirtualDebug(obj + 0x10, V32).value(), buf);
 }
 
-void Emulator::fetchProcessFilename(uint32_t obj, char *buf) {
-       fetchStr(readVirtualDebug(obj + 0x3C, V32).value(), buf);
+void Emulator::fetchProcessFilename(uint32_t obj, charbuf) {
+  fetchStr(readVirtualDebug(obj + 0x3C, V32).value(), buf);
 }
 
 void Emulator::debugPC(uint32_t pc) {
-       char objName[1000];
-       if (pc == 0x32304) {
-               // CObjectCon::AddL()
-               uint32_t container = getGPR(0);
-               uint32_t obj = getGPR(1);
-               const char *wut = identifyObjectCon(container);
-               if (wut) {
-                       fetchName(obj, objName);
-                       if (strcmp(wut, "process") == 0) {
-                               char procName[1000];
-                               fetchProcessFilename(obj, procName);
-                               log("OBJS: added %s at %08x <%s> <%s>", wut, obj, objName, procName);
-                       } else {
-                               log("OBJS: added %s at %08x <%s>", wut, obj, objName);
-                       }
-               }
-       }
-
-       if (pc == 0x634) {
-               uint32_t virtAddr = getGPR(0);
-               uint32_t physAddr = getGPR(1);
-               uint32_t btIndex = getGPR(2);
-               uint32_t regionSize = getGPR(3);
-               log("KERNEL MMU SECTION: v:%08x p:%08x size:%08x idx:%02x",
-                       virtAddr, physAddr, regionSize, btIndex);
-       }
-       if (pc == 0x66C) {
-               uint32_t virtAddr = getGPR(0);
-               uint32_t physAddr = getGPR(1);
-               uint32_t btIndex = getGPR(2);
-               uint32_t regionSize = getGPR(3);
-               uint32_t pageTableA = getGPR(4);
-               uint32_t pageTableB = getGPR(5);
-               log("KERNEL MMU PAGES: v:%08x p:%08x size:%08x idx:%02x tableA:%08x tableB:%08x",
-                       virtAddr, physAddr, regionSize, btIndex, pageTableA, pageTableB);
-       }
-       if (pc == 0x15070) {
-               uint32_t virtAddr = getGPR(0);
-               uint32_t physAddr = getGPR(1);
-               uint32_t regionSize = getGPR(2);
-               uint32_t a = getGPR(3);
-               log("DPlatChunkHw MAPPING: v:%08x p:%08x size:%08x arg:%08x",
-                       virtAddr, physAddr, regionSize, a);
-       }
-
-       if (pc == 0x16198) {
-               uint32_t rawEvent = getGPR(0);
-               uint32_t evtType = readVirtualDebug(rawEvent, V32).value_or(0);
-               uint32_t evtTick = readVirtualDebug(rawEvent + 4, V32).value_or(0);
-               uint32_t evtParamA = readVirtualDebug(rawEvent + 8, V32).value_or(0);
-               uint32_t evtParamB = readVirtualDebug(rawEvent + 0xC, V32).value_or(0);
-               const char *n = "???";
-               switch (evtType) {
-               case 0: n = "ENone"; break;
-               case 1: n = "EPointerMove"; break;
-               case 2: n = "EPointerSwitchOn"; break;
-               case 3: n = "EKeyDown"; break;
-               case 4: n = "EKeyUp"; break;
-               case 5: n = "ERedraw"; break;
-               case 6: n = "ESwitchOn"; break;
-               case 7: n = "EActive"; break;
-               case 8: n = "EInactive"; break;
-               case 9: n = "EUpdateModifiers"; break;
-               case 10: n = "EButton1Down"; break;
-               case 11: n = "EButton1Up"; break;
-               case 12: n = "EButton2Down"; break;
-               case 13: n = "EButton2Up"; break;
-               case 14: n = "EButton3Down"; break;
-               case 15: n = "EButton3Up"; break;
-               case 16: n = "ESwitchOff"; break;
-               }
-               log("EVENT %s: tick=%d params=%08x,%08x", n, evtTick, evtParamA, evtParamB);
-       }
+  char objName[1000];
+  if (pc == 0x32304) {
+    // CObjectCon::AddL()
+    uint32_t container = getGPR(0);
+    uint32_t obj = getGPR(1);
+    const char* wut = identifyObjectCon(container);
+    if (wut) {
+      fetchName(obj, objName);
+      if (strcmp(wut, "process") == 0) {
+        char procName[1000];
+        fetchProcessFilename(obj, procName);
+        log("OBJS: added %s at %08x <%s> <%s>", wut, obj, objName, procName);
+      } else {
+        log("OBJS: added %s at %08x <%s>", wut, obj, objName);
+      }
+    }
+  }
+
+  if (pc == 0x634) {
+    uint32_t virtAddr = getGPR(0);
+    uint32_t physAddr = getGPR(1);
+    uint32_t btIndex = getGPR(2);
+    uint32_t regionSize = getGPR(3);
+    log("KERNEL MMU SECTION: v:%08x p:%08x size:%08x idx:%02x", virtAddr,
+        physAddr, regionSize, btIndex);
+  }
+  if (pc == 0x66C) {
+    uint32_t virtAddr = getGPR(0);
+    uint32_t physAddr = getGPR(1);
+    uint32_t btIndex = getGPR(2);
+    uint32_t regionSize = getGPR(3);
+    uint32_t pageTableA = getGPR(4);
+    uint32_t pageTableB = getGPR(5);
+    log("KERNEL MMU PAGES: v:%08x p:%08x size:%08x idx:%02x tableA:%08x "
+        "tableB:%08x",
+        virtAddr, physAddr, regionSize, btIndex, pageTableA, pageTableB);
+  }
+  if (pc == 0x15070) {
+    uint32_t virtAddr = getGPR(0);
+    uint32_t physAddr = getGPR(1);
+    uint32_t regionSize = getGPR(2);
+    uint32_t a = getGPR(3);
+    log("DPlatChunkHw MAPPING: v:%08x p:%08x size:%08x arg:%08x", virtAddr,
+        physAddr, regionSize, a);
+  }
+
+  if (pc == 0x16198) {
+    uint32_t rawEvent = getGPR(0);
+    uint32_t evtType = readVirtualDebug(rawEvent, V32).value_or(0);
+    uint32_t evtTick = readVirtualDebug(rawEvent + 4, V32).value_or(0);
+    uint32_t evtParamA = readVirtualDebug(rawEvent + 8, V32).value_or(0);
+    uint32_t evtParamB = readVirtualDebug(rawEvent + 0xC, V32).value_or(0);
+    const char* n = "???";
+    switch (evtType) {
+    case 0:
+      n = "ENone";
+      break;
+    case 1:
+      n = "EPointerMove";
+      break;
+    case 2:
+      n = "EPointerSwitchOn";
+      break;
+    case 3:
+      n = "EKeyDown";
+      break;
+    case 4:
+      n = "EKeyUp";
+      break;
+    case 5:
+      n = "ERedraw";
+      break;
+    case 6:
+      n = "ESwitchOn";
+      break;
+    case 7:
+      n = "EActive";
+      break;
+    case 8:
+      n = "EInactive";
+      break;
+    case 9:
+      n = "EUpdateModifiers";
+      break;
+    case 10:
+      n = "EButton1Down";
+      break;
+    case 11:
+      n = "EButton1Up";
+      break;
+    case 12:
+      n = "EButton2Down";
+      break;
+    case 13:
+      n = "EButton2Up";
+      break;
+    case 14:
+      n = "EButton3Down";
+      break;
+    case 15:
+      n = "EButton3Up";
+      break;
+    case 16:
+      n = "ESwitchOff";
+      break;
+    }
+    log("EVENT %s: tick=%d params=%08x,%08x", n, evtTick, evtParamA, evtParamB);
+  }
 }
 
-
-const char *Emulator::getDeviceName() const { return "Osaris"; }
-int Emulator::getDigitiserWidth()  const { return 440; }
+const char* Emulator::getDeviceName() const { return "Osaris"; }
+int Emulator::getDigitiserWidth() const { return 440; }
 int Emulator::getDigitiserHeight() const { return 200; }
-int Emulator::getLCDOffsetX()      const { return 60; }
-int Emulator::getLCDOffsetY()      const { return 0; }
-int Emulator::getLCDWidth()        const { return 320; }
-int Emulator::getLCDHeight()       const { return 200; }
-
-void Emulator::readLCDIntoBuffer(uint8_t **lines, bool is32BitOutput) const {
-       if (lcdAddress == 0xC0000000) {
-               int width = 320, height = 200;
-               int bpp = 1;
-               if (lcdControl & 0x40000000) bpp = 2;
-               if (lcdControl & 0x80000000) bpp = 4;
-               int ppb = 8 / bpp;
-
-               // build our image out
-               int lineWidth = (width * bpp) / 8;
-               for (int y = 0; y < height; y++) {
-                       int lineOffs = lineWidth * y;
-                       for (int x = 0; x < width; x++) {
-                               uint8_t byte = MemoryBlockC0[lineOffs + (x / ppb)];
-                               int shift = (x & (ppb - 1)) * bpp;
-                               int mask = (1 << bpp) - 1;
-                               int palIdx = (byte >> shift) & mask;
-                               int palValue;
-                               if (bpp == 1)
-                                       palValue = palIdx * 255;
-                               else
-                                       palValue = (lcdPalette >> (palIdx * 4)) & 0xF;
-
-                               palValue |= (palValue << 4);
-                               if (is32BitOutput) {
-                                       lines[y][x*4] = palValue ^ 0xFF;
-                                       lines[y][x*4+1] = palValue ^ 0xFF;
-                                       lines[y][x*4+2] = palValue ^ 0xFF;
-                               } else {
-                                       lines[y][x] = palValue ^ 0xFF;
-                               }
-                       }
-               }
-       }
+int Emulator::getLCDOffsetX() const { return 60; }
+int Emulator::getLCDOffsetY() const { return 0; }
+int Emulator::getLCDWidth() const { return 320; }
+int Emulator::getLCDHeight() const { return 200; }
+
+void Emulator::readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const {
+  if (lcdAddress == 0xC0000000) {
+    int width = 320, height = 200;
+    int bpp = 1;
+    if (lcdControl & 0x40000000)
+      bpp = 2;
+    if (lcdControl & 0x80000000)
+      bpp = 4;
+    int ppb = 8 / bpp;
+
+    // build our image out
+    int lineWidth = (width * bpp) / 8;
+    for (int y = 0; y < height; y++) {
+      int lineOffs = lineWidth * y;
+      for (int x = 0; x < width; x++) {
+        uint8_t byte = MemoryBlockC0[lineOffs + (x / ppb)];
+        int shift = (x & (ppb - 1)) * bpp;
+        int mask = (1 << bpp) - 1;
+        int palIdx = (byte >> shift) & mask;
+        int palValue;
+        if (bpp == 1)
+          palValue = palIdx * 255;
+        else
+          palValue = (lcdPalette >> (palIdx * 4)) & 0xF;
+
+        palValue |= (palValue << 4);
+        if (is32BitOutput) {
+          lines[y][x * 4] = palValue ^ 0xFF;
+          lines[y][x * 4 + 1] = palValue ^ 0xFF;
+          lines[y][x * 4 + 2] = palValue ^ 0xFF;
+        } else {
+          lines[y][x] = palValue ^ 0xFF;
+        }
+      }
+    }
+  }
 }
 
-
-
 void Emulator::diffPorts(uint32_t oldval, uint32_t newval) {
-       uint32_t changes = oldval ^ newval;
-       if (changes & 1) log("PRT E0: %d", newval&1);
-       if (changes & 2) log("PRT E1: %d", newval&2);
-       if (changes & 4) log("PRT E2: %d", newval&4);
-       if (changes & 0x100) log("PRT D0: %d", newval&0x100);
-       if (changes & 0x200) log("PRT D1: %d", newval&0x200);
-       if (changes & 0x400) log("PRT D2: %d", newval&0x400);
-       if (changes & 0x800) log("PRT D3: %d", newval&0x800);
-       if (changes & 0x1000) log("PRT D4: %d", newval&0x1000);
-       if (changes & 0x2000) log("PRT D5: %d", newval&0x2000);
-       if (changes & 0x4000) log("PRT D6: %d", newval&0x4000);
-       if (changes & 0x8000) log("PRT D7: %d", newval&0x8000);
-       if (changes & 0x10000) log("PRT B0: %d", newval&0x10000);
-       if (changes & 0x20000) log("PRT B1: %d", newval&0x20000);
-       if (changes & 0x40000) log("PRT B2: %d", newval&0x40000);
-       if (changes & 0x80000) log("PRT B3: %d", newval&0x80000);
-       if (changes & 0x100000) log("PRT B4: %d", newval&0x100000);
-       if (changes & 0x200000) log("PRT B5: %d", newval&0x200000);
-       if (changes & 0x400000) log("PRT B6: %d", newval&0x400000);
-       if (changes & 0x800000) log("PRT B7: %d", newval&0x800000);
+  uint32_t changes = oldval ^ newval;
+  if (changes & 1)
+    log("PRT E0: %d", newval & 1);
+  if (changes & 2)
+    log("PRT E1: %d", newval & 2);
+  if (changes & 4)
+    log("PRT E2: %d", newval & 4);
+  if (changes & 0x100)
+    log("PRT D0: %d", newval & 0x100);
+  if (changes & 0x200)
+    log("PRT D1: %d", newval & 0x200);
+  if (changes & 0x400)
+    log("PRT D2: %d", newval & 0x400);
+  if (changes & 0x800)
+    log("PRT D3: %d", newval & 0x800);
+  if (changes & 0x1000)
+    log("PRT D4: %d", newval & 0x1000);
+  if (changes & 0x2000)
+    log("PRT D5: %d", newval & 0x2000);
+  if (changes & 0x4000)
+    log("PRT D6: %d", newval & 0x4000);
+  if (changes & 0x8000)
+    log("PRT D7: %d", newval & 0x8000);
+  if (changes & 0x10000)
+    log("PRT B0: %d", newval & 0x10000);
+  if (changes & 0x20000)
+    log("PRT B1: %d", newval & 0x20000);
+  if (changes & 0x40000)
+    log("PRT B2: %d", newval & 0x40000);
+  if (changes & 0x80000)
+    log("PRT B3: %d", newval & 0x80000);
+  if (changes & 0x100000)
+    log("PRT B4: %d", newval & 0x100000);
+  if (changes & 0x200000)
+    log("PRT B5: %d", newval & 0x200000);
+  if (changes & 0x400000)
+    log("PRT B6: %d", newval & 0x400000);
+  if (changes & 0x800000)
+    log("PRT B7: %d", newval & 0x800000);
 }
 
-
 uint32_t Emulator::readKeyboard() const {
-       if (kScan & 8) {
-               // Select one keyboard
-               if ((kScan & 7) < 7)
-                       return keyboardColumns[kScan & 7];
-               else
-                       return 0;
-       } else if (kScan == 0) {
-               // Report all columns combined
-               uint8_t val = 0;
-               for (int i = 0; i < 7; i++)
-                       val |= keyboardColumns[i];
-               return val;
-       } else {
-               return 0;
-       }
+  if (kScan & 8) {
+    // Select one keyboard
+    if ((kScan & 7) < 7)
+      return keyboardColumns[kScan & 7];
+    else
+      return 0;
+  } else if (kScan == 0) {
+    // Report all columns combined
+    uint8_t val = 0;
+    for (int i = 0; i < 7; i++)
+      val |= keyboardColumns[i];
+    return val;
+  } else {
+    return 0;
+  }
 }
 
 void Emulator::setKeyboardKey(EpocKey key, bool value) {
-       int idx = -1;
-#define KEY(column, bit) idx = (column << 8) | (1 << bit); break
-
-       switch ((int)key) {
-       case '1':                KEY(0, 0);
-       case '2':                KEY(1, 0);
-       case '3':                KEY(2, 0);
-       case '4':                KEY(3, 0);
-       case '5':                KEY(4, 0);
-       case '6':                KEY(5, 0);
-       case '7':                KEY(6, 0);
-
-       case '8':                KEY(0, 1);
-       case '9':                KEY(1, 1);
-       case '0':                KEY(2, 1);
-       case 'P':                KEY(3, 1);
-       case EStdKeySingleQuote: KEY(4, 1);
-       case EStdKeyEnter:       KEY(5, 1);
-       case EStdKeyBackspace:   KEY(6, 1);
-
-       case EStdKeyEscape:      KEY(0, 2);
-       case 'Q':                KEY(1, 2);
-       case 'W':                KEY(2, 2);
-       case 'E':                KEY(3, 2);
-       case 'R':                KEY(4, 2);
-       case 'T':                KEY(5, 2);
-       case 'Y':                KEY(6, 2);
-
-       case 'U':                KEY(0, 3);
-       case 'J':                KEY(1, 3);
-       case 'I':                KEY(2, 3);
-       case 'K':                KEY(3, 3);
-       case 'O':                KEY(4, 3);
-       case 'L':                KEY(5, 3);
-       case EStdKeyUpArrow:     KEY(6, 3);
-
-       case EStdKeyTab:         KEY(0, 4);
-       case 'A':                KEY(1, 4);
-       case 'S':                KEY(2, 4);
-       case 'D':                KEY(3, 4);
-       case 'F':                KEY(4, 4);
-       case 'G':                KEY(5, 4);
-       case 'H':                KEY(6, 4);
-
-       case EStdKeySpace:       KEY(0, 5);
-       case EStdKeyComma:       KEY(1, 5);
-       case 'M':                KEY(2, 5);
-       case EStdKeyFullStop:    KEY(3, 5);
-       case EStdKeyLeftArrow:   KEY(4, 5);
-       case EStdKeyDownArrow:   KEY(5, 5);
-       case EStdKeyRightArrow:  KEY(6, 5);
-
-       case 'Z':                KEY(0, 6);
-       case 'X':                KEY(1, 6);
-       case EStdKeyMenu:        KEY(2, 6);
-       case 'C':                KEY(3, 6);
-       case 'V':                KEY(4, 6);
-       case 'B':                KEY(5, 6);
-       case 'N':                KEY(6, 6);
-
-       case EStdKeyLeftShift:   KEY(8, 0);
-       case EStdKeyRightShift:  KEY(8, 1);
-       case EStdKeyLeftCtrl:    KEY(8, 2);
-       case EStdKeyLeftFunc:    KEY(8, 3);
-       }
-
-       if (idx >= 0x800) {
-               if (value)
-                       keyboardExtra |= (idx & 0xFF);
-               else
-                       keyboardExtra &= ~(idx & 0xFF);
-       } else if (idx >= 0) {
-               if (value)
-                       keyboardColumns[idx >> 8] |= (idx & 0xFF);
-               else
-                       keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
-       }
+  int idx = -1;
+#define KEY(column, bit)                                                       \
+  idx = (column << 8) | (1 << bit);                                            \
+  break
+
+  switch ((int)key) {
+  case '1':
+    KEY(0, 0);
+  case '2':
+    KEY(1, 0);
+  case '3':
+    KEY(2, 0);
+  case '4':
+    KEY(3, 0);
+  case '5':
+    KEY(4, 0);
+  case '6':
+    KEY(5, 0);
+  case '7':
+    KEY(6, 0);
+
+  case '8':
+    KEY(0, 1);
+  case '9':
+    KEY(1, 1);
+  case '0':
+    KEY(2, 1);
+  case 'P':
+    KEY(3, 1);
+  case EStdKeySingleQuote:
+    KEY(4, 1);
+  case EStdKeyEnter:
+    KEY(5, 1);
+  case EStdKeyBackspace:
+    KEY(6, 1);
+
+  case EStdKeyEscape:
+    KEY(0, 2);
+  case 'Q':
+    KEY(1, 2);
+  case 'W':
+    KEY(2, 2);
+  case 'E':
+    KEY(3, 2);
+  case 'R':
+    KEY(4, 2);
+  case 'T':
+    KEY(5, 2);
+  case 'Y':
+    KEY(6, 2);
+
+  case 'U':
+    KEY(0, 3);
+  case 'J':
+    KEY(1, 3);
+  case 'I':
+    KEY(2, 3);
+  case 'K':
+    KEY(3, 3);
+  case 'O':
+    KEY(4, 3);
+  case 'L':
+    KEY(5, 3);
+  case EStdKeyUpArrow:
+    KEY(6, 3);
+
+  case EStdKeyTab:
+    KEY(0, 4);
+  case 'A':
+    KEY(1, 4);
+  case 'S':
+    KEY(2, 4);
+  case 'D':
+    KEY(3, 4);
+  case 'F':
+    KEY(4, 4);
+  case 'G':
+    KEY(5, 4);
+  case 'H':
+    KEY(6, 4);
+
+  case EStdKeySpace:
+    KEY(0, 5);
+  case EStdKeyComma:
+    KEY(1, 5);
+  case 'M':
+    KEY(2, 5);
+  case EStdKeyFullStop:
+    KEY(3, 5);
+  case EStdKeyLeftArrow:
+    KEY(4, 5);
+  case EStdKeyDownArrow:
+    KEY(5, 5);
+  case EStdKeyRightArrow:
+    KEY(6, 5);
+
+  case 'Z':
+    KEY(0, 6);
+  case 'X':
+    KEY(1, 6);
+  case EStdKeyMenu:
+    KEY(2, 6);
+  case 'C':
+    KEY(3, 6);
+  case 'V':
+    KEY(4, 6);
+  case 'B':
+    KEY(5, 6);
+  case 'N':
+    KEY(6, 6);
+
+  case EStdKeyLeftShift:
+    KEY(8, 0);
+  case EStdKeyRightShift:
+    KEY(8, 1);
+  case EStdKeyLeftCtrl:
+    KEY(8, 2);
+  case EStdKeyLeftFunc:
+    KEY(8, 3);
+  }
+
+  if (idx >= 0x800) {
+    if (value)
+      keyboardExtra |= (idx & 0xFF);
+    else
+      keyboardExtra &= ~(idx & 0xFF);
+  } else if (idx >= 0) {
+    if (value)
+      keyboardColumns[idx >> 8] |= (idx & 0xFF);
+    else
+      keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
+  }
 }
 
-
 void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {
-       pendingInterrupts &= ~(1 << EINT2);
-       if (down)
-               pendingInterrupts |= (1 << EINT2);
-       log("Touch: x=%d y=%d down=%s", x, y, down ? "yes" : "no");
-       touchX = x;
-       touchY = y;
+  pendingInterrupts &= ~(1 << EINT2);
+  if (down)
+    pendingInterrupts |= (1 << EINT2);
+  log("Touch: x=%d y=%d down=%s", x, y, down ? "yes" : "no");
+  touchX = x;
+  touchY = y;
 }
 
-}
+} // namespace CLPS7111
index 47dae14ef53d1c389395fb998b5a09fe5764fbd2..ccb5b5101d83cee2ce55f86f8931a1b5d6b7f68b 100644 (file)
@@ -1,80 +1,80 @@
 #pragma once
-#include "emubase.h"
 #include "clps7111_defs.h"
 #include "clps7600.h"
-#include "hardware.h"
+#include "emubase.h"
 #include "etna.h"
+#include "hardware.h"
 
 namespace CLPS7111 {
 class Emulator : public EmuBase {
 public:
-       uint8_t ROM[0x800000];
-       uint8_t ROM2[0x40000];
-       uint8_t MemoryBlockC0[0x400000];
-       enum { MemoryBlockMask = 0x3FFFFF };
+  uint8_t ROM[0x800000];
+  uint8_t ROM2[0x40000];
+  uint8_t MemoryBlockC0[0x400000];
+  enum { MemoryBlockMask = 0x3FFFFF };
 
 private:
-       uint16_t pendingInterrupts = 0;
-       uint16_t interruptMask = 0;
-       uint32_t portValues = 0;
-       uint32_t portDirections = 0;
-       uint32_t sysFlg1 = 0x20008000; // constant CL-PS7111 flag and cold start flag
-       uint32_t lcdControl = 0;
-       uint32_t lcdAddress = 0xC0000000;
-       uint32_t rtc = 0;
-       uint32_t rtcDiv = 0;
-       uint64_t lcdPalette = 0;
-       uint16_t lastSyncioRequest = 0;
-
-       uint32_t kScan = 0;
-       uint8_t keyboardColumns[7] = {0,0,0,0,0,0,0};
-       uint8_t keyboardExtra = 0;
-       int32_t touchX = 0, touchY = 0;
+  uint16_t pendingInterrupts = 0;
+  uint16_t interruptMask = 0;
+  uint32_t portValues = 0;
+  uint32_t portDirections = 0;
+  uint32_t sysFlg1 = 0x20008000; // constant CL-PS7111 flag and cold start flag
+  uint32_t lcdControl = 0;
+  uint32_t lcdAddress = 0xC0000000;
+  uint32_t rtc = 0;
+  uint32_t rtcDiv = 0;
+  uint64_t lcdPalette = 0;
+  uint16_t lastSyncioRequest = 0;
 
-       Timer tc1, tc2;
-       CLPS7600 pcCardController;
-       bool halted = false, asleep = false;
+  uint32_t kScan = 0;
+  uint8_t keyboardColumns[7] = {0, 0, 0, 0, 0, 0, 0};
+  uint8_t keyboardExtra = 0;
+  int32_t touchX = 0, touchY = 0;
 
+  Timer tc1, tc2;
+  CLPS7600 pcCardController;
+  bool halted = false, asleep = false;
 
-       uint32_t getRTC();
+  uint32_t getRTC();
 
-       uint32_t readReg8(uint32_t reg);
-       uint32_t readReg32(uint32_t reg);
-       void writeReg8(uint32_t reg, uint8_t value);
-       void writeReg32(uint32_t reg, uint32_t value);
+  uint32_t readReg8(uint32_t reg);
+  uint32_t readReg32(uint32_t reg);
+  void writeReg8(uint32_t reg, uint8_t value);
+  void writeReg32(uint32_t reg, uint32_t value);
 
 public:
-       MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) override;
-       bool writePhysical(uint32_t value, uint32_t physAddr, ValueSize valueSize) override;
+  MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) override;
+  bool writePhysical(uint32_t value, uint32_t physAddr,
+                     ValueSize valueSize) override;
 
 private:
-       bool configured = false;
-       void configure();
+  bool configured = false;
+  void configure();
 
-       const char *identifyObjectCon(uint32_t ptr);
-       void fetchStr(uint32_t str, char *buf);
-       void fetchName(uint32_t obj, char *buf);
-       void fetchProcessFilename(uint32_t obj, char *buf);
-       void debugPC(uint32_t pc);
-       void diffPorts(uint32_t oldval, uint32_t newval);
-       uint32_t readKeyboard() const;
+  const char* identifyObjectCon(uint32_t ptr);
+  void fetchStr(uint32_t str, char* buf);
+  void fetchName(uint32_t obj, char* buf);
+  void fetchProcessFilename(uint32_t obj, char* buf);
+  void debugPC(uint32_t pc);
+  void diffPorts(uint32_t oldval, uint32_t newval);
+  uint32_t readKeyboard() const;
 
 public:
-       Emulator();
-       uint8_t *getROMBuffer() override;
-       size_t getROMSize() override;
-       void loadROM(uint8_t *buffer, size_t size) override;
-       void executeUntil(int64_t cycles) override;
-       int32_t getClockSpeed() const override { return CLOCK_SPEED; }
-       const char *getDeviceName() const override;
-       int getDigitiserWidth() const override;
-       int getDigitiserHeight() const override;
-       int getLCDOffsetX() const override;
-       int getLCDOffsetY() const override;
-       int getLCDWidth() const override;
-       int getLCDHeight() const override;
-       void readLCDIntoBuffer(uint8_t **lines, bool is32BitOutput) const override;
-       void setKeyboardKey(EpocKey key, bool value) override;
-       void updateTouchInput(int32_t x, int32_t y, bool down) override;
+  Emulator();
+  uint8_t* getROMBuffer() override;
+  size_t getROMSize() override;
+  void loadROM(uint8_t* buffer, size_t size) override;
+  void executeUntil(int64_t cycles) override;
+  int32_t getClockSpeed() const override { return CLOCK_SPEED; }
+  const char* getDeviceName() const override;
+  int getDigitiserWidth() const override;
+  int getDigitiserHeight() const override;
+  int getLCDOffsetX() const override;
+  int getLCDOffsetY() const override;
+  int getLCDWidth() const override;
+  int getLCDHeight() const override;
+  void readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const override;
+  void setKeyboardKey(EpocKey key, bool value) override;
+  void updateTouchInput(int32_t x, int32_t y, bool down) override;
 };
-}
+} // namespace CLPS7111
index af02b6573ab25210c8351c28098864ef5f4ae355..a49d74faf9bed422d2fc4f1cd2053a6813a7e702 100644 (file)
@@ -2,82 +2,78 @@
 #include <stdint.h>
 
 namespace CLPS7111 {
-enum {
-       CLOCK_SPEED = 0x4800*1000,
-       TICK_INTERVAL = CLOCK_SPEED / 64
-};
+enum { CLOCK_SPEED = 0x4800 * 1000, TICK_INTERVAL = CLOCK_SPEED / 64 };
 
 enum Interrupt {
-       EXTFIQ = 0,   // FiqExternal
-       BLINT = 1,    // FiqBatLow
-       WEINT = 2,    // FiqWatchDog
-       MCINT = 3,    // FiqMediaChg
-       CSINT = 4,    // IrqCodec
-       EINT1 = 5,    // IrqExt1
-       EINT2 = 6,    // IrqExt2
-       EINT3 = 7,    // IrqExt3
-       TC1OI = 8,    // IrqTimer1
-       TC2OI = 9,    // IrqTimer2
-       RTCMI = 10,   // IrqRtcMatch
-       TINT = 11,    // IrqTick
-       UTXINT = 12,  // IrqUartTx?
-       URXINT1 = 13, // IrqUartRx?
-       UMSINT = 14,  // IrqUartModem?
-       SSEOTI = 15,  // IrqSpi
-       KBDINT = 16,  // IrqKeyPress?
-       UTXINT2 = 28, // IrqSpi2Tx?
-       URXINT2 = 29, // IrqSpi2Rx?
-       FIQ_INTERRUPTS = 0x000F,
-       IRQ_INTERRUPTS = 0xFFF0
+  EXTFIQ = 0,   // FiqExternal
+  BLINT = 1,    // FiqBatLow
+  WEINT = 2,    // FiqWatchDog
+  MCINT = 3,    // FiqMediaChg
+  CSINT = 4,    // IrqCodec
+  EINT1 = 5,    // IrqExt1
+  EINT2 = 6,    // IrqExt2
+  EINT3 = 7,    // IrqExt3
+  TC1OI = 8,    // IrqTimer1
+  TC2OI = 9,    // IrqTimer2
+  RTCMI = 10,   // IrqRtcMatch
+  TINT = 11,    // IrqTick
+  UTXINT = 12,  // IrqUartTx?
+  URXINT1 = 13, // IrqUartRx?
+  UMSINT = 14,  // IrqUartModem?
+  SSEOTI = 15,  // IrqSpi
+  KBDINT = 16,  // IrqKeyPress?
+  UTXINT2 = 28, // IrqSpi2Tx?
+  URXINT2 = 29, // IrqSpi2Rx?
+  FIQ_INTERRUPTS = 0x000F,
+  IRQ_INTERRUPTS = 0xFFF0
 };
 
 enum Register {
-       PADR = 0,
-       PBDR = 1,
-       PDDR = 3,
-       PADDR = 0x40,
-       PBDDR = 0x41,
-       PDDDR = 0x43,
-       PEDR = 0x80,
-       PEDDR = 0xC0,
-       SYSCON1 = 0x100,
-       SYSFLG1 = 0x140,
-       MEMCFG1 = 0x180,
-       MEMCFG2 = 0x1C0,
-       DRFPR = 0x200,
-       INTSR1 = 0x240,
-       INTMR1 = 0x280,
-       LCDCON = 0x2C0,
-       TC1D = 0x300,
-       TC2D = 0x340,
-       RTCDR = 0x380,
-       RTCMR = 0x3C0,
-       PMPCON = 0x400,
-       CODR = 0x440,
-       UARTDR1 = 0x480,
-       UBRLCR1 = 0x4C0,
-       SYNCIO = 0x500,
-       PALLSW = 0x540,
-       PALMSW = 0x580,
-       STFCLR = 0x5C0,
-       BLEOI = 0x600,
-       MCEOI = 0x640,
-       TEOI = 0x680,
-       TC1EOI = 0x6C0,
-       TC2EOI = 0x700,
-       RTCEOI = 0x740,
-       UMSEOI = 0x780,
-       COEOI = 0x7C0,
-       HALT = 0x800,
-       STDBY = 0x840,
-       FRBADDR = 0x1000,
-       SYSCON2 = 0x1100,
-       SYSFLG2 = 0x1140,
-       INTSR2 = 0x1240,
-       INTMR2 = 0x1280,
-       UARTDR2 = 0x1480,
-       UBRLCR2 = 0x14C0,
-       KBDEOI = 0x1700
+  PADR = 0,
+  PBDR = 1,
+  PDDR = 3,
+  PADDR = 0x40,
+  PBDDR = 0x41,
+  PDDDR = 0x43,
+  PEDR = 0x80,
+  PEDDR = 0xC0,
+  SYSCON1 = 0x100,
+  SYSFLG1 = 0x140,
+  MEMCFG1 = 0x180,
+  MEMCFG2 = 0x1C0,
+  DRFPR = 0x200,
+  INTSR1 = 0x240,
+  INTMR1 = 0x280,
+  LCDCON = 0x2C0,
+  TC1D = 0x300,
+  TC2D = 0x340,
+  RTCDR = 0x380,
+  RTCMR = 0x3C0,
+  PMPCON = 0x400,
+  CODR = 0x440,
+  UARTDR1 = 0x480,
+  UBRLCR1 = 0x4C0,
+  SYNCIO = 0x500,
+  PALLSW = 0x540,
+  PALMSW = 0x580,
+  STFCLR = 0x5C0,
+  BLEOI = 0x600,
+  MCEOI = 0x640,
+  TEOI = 0x680,
+  TC1EOI = 0x6C0,
+  TC2EOI = 0x700,
+  RTCEOI = 0x740,
+  UMSEOI = 0x780,
+  COEOI = 0x7C0,
+  HALT = 0x800,
+  STDBY = 0x840,
+  FRBADDR = 0x1000,
+  SYSCON2 = 0x1100,
+  SYSFLG2 = 0x1140,
+  INTSR2 = 0x1240,
+  INTMR2 = 0x1280,
+  UARTDR2 = 0x1480,
+  UBRLCR2 = 0x14C0,
+  KBDEOI = 0x1700
 };
-}
-
+} // namespace CLPS7111
index 3b2d36a81dc25c3f78328c472c1b0b368ecccf70..98b7d98e9308645e0db8cdfecf8f3adc246b1579 100644 (file)
 #include "clps7600.h"
 #include "arm710.h"
 
-CLPS7600::CLPS7600(ARM710 *_cpu)
-{
-       cpu = _cpu;
-}
+CLPS7600::CLPS7600(ARM710* _cpu) { cpu = _cpu; }
 
 enum {
-       PCM_BVD1 = 1,
-       PCM_BVD2 = 2,
-       PCM_CD1 = 4,
-       PCM_CD2 = 8,
-       PCM_VS1 = 0x10,
-       PCM_VS2 = 0x20,
-       PDREQ_L = 0x40,
-       PCTL = 0x100,
-       PCM_WP = 0x200,
-       PCM_RDY = 0x400,
-       FIFOTHLD = 0x800,
-       IDLE = 0x1000,
-       WR_FAIL = 0x2000,
-       RD_FAIL = 0x4000,
-       RESERVED = 0x8000
+  PCM_BVD1 = 1,
+  PCM_BVD2 = 2,
+  PCM_CD1 = 4,
+  PCM_CD2 = 8,
+  PCM_VS1 = 0x10,
+  PCM_VS2 = 0x20,
+  PDREQ_L = 0x40,
+  PCTL = 0x100,
+  PCM_WP = 0x200,
+  PCM_RDY = 0x400,
+  FIFOTHLD = 0x800,
+  IDLE = 0x1000,
+  WR_FAIL = 0x2000,
+  RD_FAIL = 0x4000,
+  RESERVED = 0x8000
 };
 
 uint32_t CLPS7600::getInputLevel() const {
-       uint32_t v = 0;
+  uint32_t v = 0;
 
-       if (isMemoryMode())
-               v |= PCM_RDY; // we are ALWAYS ready
+  if (isMemoryMode())
+    v |= PCM_RDY; // we are ALWAYS ready
 
-       return v;
+  return v;
 }
 
-uint32_t CLPS7600::read(uint32_t addr, ARM710::ValueSize valueSize)
-{
-       cpu->log("CLPS7600 read: addr=%07x size=%d pc=%08x lr=%08x", addr, (valueSize == ARM710::V32) ? 32 : 8, cpu->getRealPC(), cpu->getGPR(14));
-       if (valueSize == ARM710::V32) {
-               switch (addr) {
-               case 0xC000000: // Interrupt Status
-                       return interruptStatus;
-               case 0xC000400: // Interrupt Mask
-                       return interruptMask;
-               case 0xC001C00: // Interrupt Input Level
-                       return getInputLevel();
-               case 0xC002000: // System Interface Configuration
-                       return systemInterfaceConfig;
-               case 0xC002400: // Card Interface Configuration
-                       return cardInterfaceConfig;
-               case 0xC002800: // Power Management
-                       return powerManagement;
-               case 0xC002C00: // Card Power Control
-                       return cardPowerControl;
-               case 0xC003000: // Card Interface Timing 0A
-                       return cardInterfaceTiming0A;
-               case 0xC003400: // Card Interface Timing 0B
-                       return cardInterfaceTiming0B;
-               case 0xC003800: // Card Interface Timing 1A
-                       return cardInterfaceTiming1A;
-               case 0xC003C00: // Card Interface Timing 1B
-                       return cardInterfaceTiming1B;
-               case 0xC004000: // DMA Control
-                       return dmaControl;
-               case 0xC004400: // Device Information
-                       return deviceInformation;
-               default:
-                       cpu->log("CLPS7600 unknown register read: addr=%07x pc=%08x lr=%08x", addr, cpu->getRealPC(), cpu->getGPR(14));
-                       return 0xFFFFFFFF;
-               }
-       }
-       cpu->log("unknown!!");
-       return 0xFF;
+uint32_t CLPS7600::read(uint32_t addr, ARM710::ValueSize valueSize) {
+  cpu->log("CLPS7600 read: addr=%07x size=%d pc=%08x lr=%08x", addr,
+           (valueSize == ARM710::V32) ? 32 : 8, cpu->getRealPC(),
+           cpu->getGPR(14));
+  if (valueSize == ARM710::V32) {
+    switch (addr) {
+    case 0xC000000: // Interrupt Status
+      return interruptStatus;
+    case 0xC000400: // Interrupt Mask
+      return interruptMask;
+    case 0xC001C00: // Interrupt Input Level
+      return getInputLevel();
+    case 0xC002000: // System Interface Configuration
+      return systemInterfaceConfig;
+    case 0xC002400: // Card Interface Configuration
+      return cardInterfaceConfig;
+    case 0xC002800: // Power Management
+      return powerManagement;
+    case 0xC002C00: // Card Power Control
+      return cardPowerControl;
+    case 0xC003000: // Card Interface Timing 0A
+      return cardInterfaceTiming0A;
+    case 0xC003400: // Card Interface Timing 0B
+      return cardInterfaceTiming0B;
+    case 0xC003800: // Card Interface Timing 1A
+      return cardInterfaceTiming1A;
+    case 0xC003C00: // Card Interface Timing 1B
+      return cardInterfaceTiming1B;
+    case 0xC004000: // DMA Control
+      return dmaControl;
+    case 0xC004400: // Device Information
+      return deviceInformation;
+    default:
+      cpu->log("CLPS7600 unknown register read: addr=%07x pc=%08x lr=%08x",
+               addr, cpu->getRealPC(), cpu->getGPR(14));
+      return 0xFFFFFFFF;
+    }
+  }
+  cpu->log("unknown!!");
+  return 0xFF;
 }
 
-void CLPS7600::write(uint32_t value, uint32_t addr, ARM710::ValueSize valueSize)
-{
-       cpu->log("CLPS7600 write: addr=%07x size=%d value=%08x pc=%08x lr=%08x", addr, (valueSize == ARM710::V32) ? 32 : 8, value, cpu->getRealPC(), cpu->getGPR(14));
-       if (valueSize == ARM710::V32) {
-               switch (addr) {
-               case 0xC000400: // Interrupt Mask
-                       interruptMask = value;
-                       break;
-               case 0xC000800: // Interrupt Clear
-                       break;
-               case 0xC000C00: // Interrupt Output Select
-                       break;
-               case 0xC001000: // Interrupt Reserved Register 1
-                       break;
-               case 0xC001400: // Interrupt Reserved Register 2
-                       break;
-               case 0xC001800: // Interrupt Reserved Register 3
-                       break;
-               case 0xC002000: // System Interface Configuration
-                       systemInterfaceConfig = value;
-                       break;
-               case 0xC002400: // Card Interface Configuration
-                       cardInterfaceConfig = value;
-                       cpu->log("PC card enabled: %s", (value & 0x400) ? "yes" : "no");
-                       cpu->log("PC card write protect: %s", (value & 0x200) ? "yes" : "no");
-                       cpu->log("PC card mode: %s", (value & 0x100) ? "i/o" : "memory");
-                       break;
-               case 0xC002800: // Power Management
-                       powerManagement = value;
-                       break;
-               case 0xC002C00: // Card Power Control
-                       cardPowerControl = value;
-                       break;
-               case 0xC003000: // Card Interface Timing 0A
-                       cardInterfaceTiming0A = value;
-                       break;
-               case 0xC003400: // Card Interface Timing 0B
-                       cardInterfaceTiming0B = value;
-                       break;
-               case 0xC003800: // Card Interface Timing 1A
-                       cardInterfaceTiming1A = value;
-                       break;
-               case 0xC003C00: // Card Interface Timing 1B
-                       cardInterfaceTiming1B = value;
-                       break;
-               case 0xC004000: // DMA Control
-                       dmaControl = value;
-                       break;
-               case 0xC004400: // Device Information
-                       deviceInformation = value;
-                       break;
-               default:
-                       cpu->log("CLPS7600 unknown register write: addr=%07x value=%08x pc=%08x lr=%08x", addr, value, cpu->getRealPC(), cpu->getGPR(14));
-               }
-       } else {
-               cpu->log("unknown write!!");
-       }
+void CLPS7600::write(uint32_t value, uint32_t addr,
+                     ARM710::ValueSize valueSize) {
+  cpu->log("CLPS7600 write: addr=%07x size=%d value=%08x pc=%08x lr=%08x", addr,
+           (valueSize == ARM710::V32) ? 32 : 8, value, cpu->getRealPC(),
+           cpu->getGPR(14));
+  if (valueSize == ARM710::V32) {
+    switch (addr) {
+    case 0xC000400: // Interrupt Mask
+      interruptMask = value;
+      break;
+    case 0xC000800: // Interrupt Clear
+      break;
+    case 0xC000C00: // Interrupt Output Select
+      break;
+    case 0xC001000: // Interrupt Reserved Register 1
+      break;
+    case 0xC001400: // Interrupt Reserved Register 2
+      break;
+    case 0xC001800: // Interrupt Reserved Register 3
+      break;
+    case 0xC002000: // System Interface Configuration
+      systemInterfaceConfig = value;
+      break;
+    case 0xC002400: // Card Interface Configuration
+      cardInterfaceConfig = value;
+      cpu->log("PC card enabled: %s", (value & 0x400) ? "yes" : "no");
+      cpu->log("PC card write protect: %s", (value & 0x200) ? "yes" : "no");
+      cpu->log("PC card mode: %s", (value & 0x100) ? "i/o" : "memory");
+      break;
+    case 0xC002800: // Power Management
+      powerManagement = value;
+      break;
+    case 0xC002C00: // Card Power Control
+      cardPowerControl = value;
+      break;
+    case 0xC003000: // Card Interface Timing 0A
+      cardInterfaceTiming0A = value;
+      break;
+    case 0xC003400: // Card Interface Timing 0B
+      cardInterfaceTiming0B = value;
+      break;
+    case 0xC003800: // Card Interface Timing 1A
+      cardInterfaceTiming1A = value;
+      break;
+    case 0xC003C00: // Card Interface Timing 1B
+      cardInterfaceTiming1B = value;
+      break;
+    case 0xC004000: // DMA Control
+      dmaControl = value;
+      break;
+    case 0xC004400: // Device Information
+      deviceInformation = value;
+      break;
+    default:
+      cpu->log("CLPS7600 unknown register write: addr=%07x value=%08x pc=%08x "
+               "lr=%08x",
+               addr, value, cpu->getRealPC(), cpu->getGPR(14));
+    }
+  } else {
+    cpu->log("unknown write!!");
+  }
 }
index e9fe2a9adf70776cb3985c426c394d7eabd87644..6e766a8fd856021711a345fcd3bb52898d47356b 100644 (file)
@@ -1,33 +1,31 @@
 #pragma once
-#include <stdint.h>
 #include "arm710.h"
+#include <stdint.h>
 
-class CLPS7600
-{
+class CLPS7600 {
 private:
-       ARM710 *cpu;
+  ARM710* cpu;
 
-       uint32_t interruptStatus = 0;
-       uint32_t interruptMask = 0;
-       uint32_t systemInterfaceConfig = 0x1F8;
-       uint32_t cardInterfaceConfig = 0;
-       uint32_t powerManagement = 0;
-       uint32_t cardPowerControl = 0;
-       uint32_t cardInterfaceTiming0A = 0x1F00;
-       uint32_t cardInterfaceTiming0B = 0;
-       uint32_t cardInterfaceTiming1A = 0x1F00;
-       uint32_t cardInterfaceTiming1B = 0;
-       uint32_t dmaControl = 0;
-       uint32_t deviceInformation = 0x40;
+  uint32_t interruptStatus = 0;
+  uint32_t interruptMask = 0;
+  uint32_t systemInterfaceConfig = 0x1F8;
+  uint32_t cardInterfaceConfig = 0;
+  uint32_t powerManagement = 0;
+  uint32_t cardPowerControl = 0;
+  uint32_t cardInterfaceTiming0A = 0x1F00;
+  uint32_t cardInterfaceTiming0B = 0;
+  uint32_t cardInterfaceTiming1A = 0x1F00;
+  uint32_t cardInterfaceTiming1B = 0;
+  uint32_t dmaControl = 0;
+  uint32_t deviceInformation = 0x40;
 
-       bool isIOMode() const { return (cardInterfaceConfig & 0x100); }
-       bool isMemoryMode() const { return !(cardInterfaceConfig & 0x100); }
-       uint32_t getInputLevel() const;
+  bool isIOMode() const { return (cardInterfaceConfig & 0x100); }
+  bool isMemoryMode() const { return !(cardInterfaceConfig & 0x100); }
+  uint32_t getInputLevel() const;
 
 public:
-       CLPS7600(ARM710 *_cpu);
+  CLPS7600(ARM710* _cpu);
 
-       uint32_t read(uint32_t addr, ARM710::ValueSize valueSize);
-       void write(uint32_t value, uint32_t addr, ARM710::ValueSize valueSize);
+  uint32_t read(uint32_t addr, ARM710::ValueSize valueSize);
+  void write(uint32_t value, uint32_t addr, ARM710::ValueSize valueSize);
 };
-
index 0b0e6d93449fece4fdd60cb241fea2acd2c91373..90cb63b1eb223e88f8ce68ee2ef864daad579174 100644 (file)
@@ -50,14 +50,14 @@ typedef intptr_t ssize_t;
 #define snprintf _snprintf
 #define strdup _strdup
 #define lseek _lseek
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
 #elif defined(__wii__)
 #include <sys/time.h>
 typedef intptr_t ssize_t;
 #else
 #include <strings.h>
-#include <unistd.h>
 #include <sys/time.h>
+#include <unistd.h>
 #endif
 
 #ifdef PSP2
@@ -66,7 +66,7 @@ typedef intptr_t ssize_t;
 #endif
 
 #ifndef SSIZE_MAX
-#define SSIZE_MAX ((ssize_t) (SIZE_MAX >> 1))
+#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
 #endif
 
 #ifndef UNUSED
@@ -77,14 +77,17 @@ typedef intptr_t ssize_t;
 #define M_PI 3.141592654f
 #endif
 
-#if !defined(_MSC_VER) && (defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#if !defined(_MSC_VER) && (defined(__llvm__) || (__GNUC__ > 4) ||              \
+                           (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
 #define ATOMIC_STORE(DST, SRC) __atomic_store_n(&DST, SRC, __ATOMIC_RELEASE)
 #define ATOMIC_LOAD(DST, SRC) DST = __atomic_load_n(&SRC, __ATOMIC_ACQUIRE)
 #define ATOMIC_ADD(DST, OP) __atomic_add_fetch(&DST, OP, __ATOMIC_RELEASE)
 #define ATOMIC_SUB(DST, OP) __atomic_sub_fetch(&DST, OP, __ATOMIC_RELEASE)
 #define ATOMIC_OR(DST, OP) __atomic_or_fetch(&DST, OP, __ATOMIC_RELEASE)
 #define ATOMIC_AND(DST, OP) __atomic_and_fetch(&DST, OP, __ATOMIC_RELEASE)
-#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true,__ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)
+#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC)                                     \
+  __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true, __ATOMIC_ACQ_REL,    \
+                              __ATOMIC_ACQUIRE)
 #define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC)
 #define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC)
 #elif defined _MSC_VER
@@ -94,9 +97,11 @@ typedef intptr_t ssize_t;
 #define ATOMIC_SUB(DST, OP) InterlockedAddRelease(&DST, -OP)
 #define ATOMIC_OR(DST, OP) InterlockedOrRelease(&DST, OP)
 #define ATOMIC_AND(DST, OP) InterlockedAndRelease(&DST, OP)
-#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED)
+#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC)                                     \
+  (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED)
 #define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(&DST, SRC)
-#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(&SRC, 0, 0)
+#define ATOMIC_LOAD_PTR(DST, SRC)                                              \
+  DST = InterlockedCompareExchangePointer(&SRC, 0, 0)
 #else
 // TODO
 #define ATOMIC_STORE(DST, SRC) DST = SRC
@@ -105,7 +110,8 @@ typedef intptr_t ssize_t;
 #define ATOMIC_SUB(DST, OP) DST -= OP
 #define ATOMIC_OR(DST, OP) DST |= OP
 #define ATOMIC_AND(DST, OP) DST &= OP
-#define ATOMIC_CMPXCHG(DST, EXPECTED, OP) ((DST == EXPECTED) ? ((DST = OP), true) : false)
+#define ATOMIC_CMPXCHG(DST, EXPECTED, OP)                                      \
+  ((DST == EXPECTED) ? ((DST = OP), true) : false)
 #define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC)
 #define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC)
 #endif
@@ -122,107 +128,140 @@ typedef intptr_t ssize_t;
 #endif
 
 #if defined __BIG_ENDIAN__
-#define LOAD_32BE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
+#define LOAD_32BE(DEST, ADDR, ARR)                                             \
+  DEST = *(uint32_t*)((uintptr_t)(ARR) + (size_t)(ADDR))
 #if defined(__PPC__) || defined(__POWERPC__)
-#define LOAD_32LE(DEST, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       const void* _ptr = (ARR); \
-       __asm__("lwbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \
-}
+#define LOAD_32LE(DEST, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    const void* _ptr = (ARR);                                                  \
+    __asm__("lwbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr));          \
+  }
 
-#define LOAD_16LE(DEST, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       const void* _ptr = (ARR); \
-       __asm__("lhbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \
-}
+#define LOAD_16LE(DEST, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    const void* _ptr = (ARR);                                                  \
+    __asm__("lhbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr));          \
+  }
 
-#define STORE_32LE(SRC, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       void* _ptr = (ARR); \
-       __asm__("stwbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \
-}
+#define STORE_32LE(SRC, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    void* _ptr = (ARR);                                                        \
+    __asm__("stwbrx %0, %1, %2"                                                \
+            :                                                                  \
+            : "r"(SRC), "b"(_ptr), "r"(_addr)                                  \
+            : "memory");                                                       \
+  }
 
-#define STORE_16LE(SRC, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       void* _ptr = (ARR); \
-       __asm__("sthbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \
-}
+#define STORE_16LE(SRC, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    void* _ptr = (ARR);                                                        \
+    __asm__("sthbrx %0, %1, %2"                                                \
+            :                                                                  \
+            : "r"(SRC), "b"(_ptr), "r"(_addr)                                  \
+            : "memory");                                                       \
+  }
 
-#define LOAD_64LE(DEST, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       union { \
-               struct { \
-                       uint32_t hi; \
-                       uint32_t lo; \
-               }; \
-               uint64_t b64; \
-       } bswap; \
-       const void* _ptr = (ARR); \
-       __asm__( \
-               "lwbrx %0, %2, %3 \n" \
-               "lwbrx %1, %2, %4 \n" \
-               : "=&r"(bswap.lo), "=&r"(bswap.hi) : "b"(_ptr), "r"(_addr), "r"(_addr + 4)) ; \
-       DEST = bswap.b64; \
-}
+#define LOAD_64LE(DEST, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    union {                                                                    \
+      struct {                                                                 \
+        uint32_t hi;                                                           \
+        uint32_t lo;                                                           \
+      };                                                                       \
+      uint64_t b64;                                                            \
+    } bswap;                                                                   \
+    const void* _ptr = (ARR);                                                  \
+    __asm__("lwbrx %0, %2, %3 \n"                                              \
+            "lwbrx %1, %2, %4 \n"                                              \
+            : "=&r"(bswap.lo), "=&r"(bswap.hi)                                 \
+            : "b"(_ptr), "r"(_addr), "r"(_addr + 4));                          \
+    DEST = bswap.b64;                                                          \
+  }
 
-#define STORE_64LE(SRC, ADDR, ARR) { \
-       uint32_t _addr = (ADDR); \
-       union { \
-               struct { \
-                       uint32_t hi; \
-                       uint32_t lo; \
-               }; \
-               uint64_t b64; \
-       } bswap = { .b64 = SRC }; \
-       const void* _ptr = (ARR); \
-       __asm__( \
-               "stwbrx %0, %2, %3 \n" \
-               "stwbrx %1, %2, %4 \n" \
-               : : "r"(bswap.hi), "r"(bswap.lo), "b"(_ptr), "r"(_addr), "r"(_addr + 4) : "memory"); \
-}
+#define STORE_64LE(SRC, ADDR, ARR)                                             \
+  {                                                                            \
+    uint32_t _addr = (ADDR);                                                   \
+    union {                                                                    \
+      struct {                                                                 \
+        uint32_t hi;                                                           \
+        uint32_t lo;                                                           \
+      };                                                                       \
+      uint64_t b64;                                                            \
+    } bswap = {.b64 = SRC};                                                    \
+    const void* _ptr = (ARR);                                                  \
+    __asm__("stwbrx %0, %2, %3 \n"                                             \
+            "stwbrx %1, %2, %4 \n"                                             \
+            :                                                                  \
+            : "r"(bswap.hi), "r"(bswap.lo), "b"(_ptr), "r"(_addr),             \
+              "r"(_addr + 4)                                                   \
+            : "memory");                                                       \
+  }
 
-#elif defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
-#define LOAD_64LE(DEST, ADDR, ARR) DEST = __builtin_bswap64(((uint64_t*) ARR)[(ADDR) >> 3])
-#define LOAD_32LE(DEST, ADDR, ARR) DEST = __builtin_bswap32(((uint32_t*) ARR)[(ADDR) >> 2])
-#define LOAD_16LE(DEST, ADDR, ARR) DEST = __builtin_bswap16(((uint16_t*) ARR)[(ADDR) >> 1])
-#define STORE_64LE(SRC, ADDR, ARR) ((uint64_t*) ARR)[(ADDR) >> 3] = __builtin_bswap64(SRC)
-#define STORE_32LE(SRC, ADDR, ARR) ((uint32_t*) ARR)[(ADDR) >> 2] = __builtin_bswap32(SRC)
-#define STORE_16LE(SRC, ADDR, ARR) ((uint16_t*) ARR)[(ADDR) >> 1] = __builtin_bswap16(SRC)
+#elif defined(__llvm__) || (__GNUC__ > 4) ||                                   \
+    (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+#define LOAD_64LE(DEST, ADDR, ARR)                                             \
+  DEST = __builtin_bswap64(((uint64_t*)ARR)[(ADDR) >> 3])
+#define LOAD_32LE(DEST, ADDR, ARR)                                             \
+  DEST = __builtin_bswap32(((uint32_t*)ARR)[(ADDR) >> 2])
+#define LOAD_16LE(DEST, ADDR, ARR)                                             \
+  DEST = __builtin_bswap16(((uint16_t*)ARR)[(ADDR) >> 1])
+#define STORE_64LE(SRC, ADDR, ARR)                                             \
+  ((uint64_t*)ARR)[(ADDR) >> 3] = __builtin_bswap64(SRC)
+#define STORE_32LE(SRC, ADDR, ARR)                                             \
+  ((uint32_t*)ARR)[(ADDR) >> 2] = __builtin_bswap32(SRC)
+#define STORE_16LE(SRC, ADDR, ARR)                                             \
+  ((uint16_t*)ARR)[(ADDR) >> 1] = __builtin_bswap16(SRC)
 #else
 #error Big endian build not supported on this platform.
 #endif
 #else
-#define LOAD_64LE(DEST, ADDR, ARR) DEST = *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
-#define LOAD_32LE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
-#define LOAD_16LE(DEST, ADDR, ARR) DEST = *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
-#define STORE_64LE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
-#define STORE_32LE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
-#define STORE_16LE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
+#define LOAD_64LE(DEST, ADDR, ARR)                                             \
+  DEST = *(uint64_t*)((uintptr_t)(ARR) + (size_t)(ADDR))
+#define LOAD_32LE(DEST, ADDR, ARR)                                             \
+  DEST = *(uint32_t*)((uintptr_t)(ARR) + (size_t)(ADDR))
+#define LOAD_16LE(DEST, ADDR, ARR)                                             \
+  DEST = *(uint16_t*)((uintptr_t)(ARR) + (size_t)(ADDR))
+#define STORE_64LE(SRC, ADDR, ARR)                                             \
+  *(uint64_t*)((uintptr_t)(ARR) + (size_t)(ADDR)) = SRC
+#define STORE_32LE(SRC, ADDR, ARR)                                             \
+  *(uint32_t*)((uintptr_t)(ARR) + (size_t)(ADDR)) = SRC
+#define STORE_16LE(SRC, ADDR, ARR)                                             \
+  *(uint16_t*)((uintptr_t)(ARR) + (size_t)(ADDR)) = SRC
 #ifdef _MSC_VER
-#define LOAD_32BE(DEST, ADDR, ARR) DEST = _byteswap_ulong(((uint32_t*) ARR)[(ADDR) >> 2])
+#define LOAD_32BE(DEST, ADDR, ARR)                                             \
+  DEST = _byteswap_ulong(((uint32_t*)ARR)[(ADDR) >> 2])
 #else
-#define LOAD_32BE(DEST, ADDR, ARR) DEST = __builtin_bswap32(((uint32_t*) ARR)[(ADDR) >> 2])
+#define LOAD_32BE(DEST, ADDR, ARR)                                             \
+  DEST = __builtin_bswap32(((uint32_t*)ARR)[(ADDR) >> 2])
 #endif
 #endif
 
 #define MAKE_MASK(START, END) (((1 << ((END) - (START))) - 1) << (START))
 #define CHECK_BITS(SRC, START, END) ((SRC) & MAKE_MASK(START, END))
-#define EXT_BITS(SRC, START, END) (((SRC) >> (START)) & ((1 << ((END) - (START))) - 1))
-#define INS_BITS(SRC, START, END, BITS) (CLEAR_BITS(SRC, START, END) | (((BITS) << (START)) & MAKE_MASK(START, END)))
+#define EXT_BITS(SRC, START, END)                                              \
+  (((SRC) >> (START)) & ((1 << ((END) - (START))) - 1))
+#define INS_BITS(SRC, START, END, BITS)                                        \
+  (CLEAR_BITS(SRC, START, END) | (((BITS) << (START)) & MAKE_MASK(START, END)))
 #define CLEAR_BITS(SRC, START, END) ((SRC) & ~MAKE_MASK(START, END))
 #define FILL_BITS(SRC, START, END) ((SRC) | MAKE_MASK(START, END))
-#define TEST_FILL_BITS(SRC, START, END, TEST) ((TEST) ? (FILL_BITS(SRC, START, END)) : (CLEAR_BITS(SRC, START, END)))
+#define TEST_FILL_BITS(SRC, START, END, TEST)                                  \
+  ((TEST) ? (FILL_BITS(SRC, START, END)) : (CLEAR_BITS(SRC, START, END)))
 
 #ifdef _MSC_VER
-#pragma section(".CRT$XCU",read)
+#pragma section(".CRT$XCU", read)
 #define ATTRIBUTE_UNUSED
 #define ATTRIBUTE_FORMAT(X, Y, Z)
 #define ATTRIBUTE_NOINLINE
 // Adapted from https://stackoverflow.com/a/2390626
-#define _CONSTRUCTOR(FN, PRE) \
-    static void FN(void); \
-    __declspec(allocate(".CRT$XCU")) void (*_CONSTRUCTOR_ ## FN)(void) = FN; \
-    static void FN(void)
+#define _CONSTRUCTOR(FN, PRE)                                                  \
+  static void FN(void);                                                        \
+  __declspec(allocate(".CRT$XCU")) void (*_CONSTRUCTOR_##FN)(void) = FN;       \
+  static void FN(void)
 #ifdef _WIN64
 #define CONSTRUCTOR(FN) _CONSTRUCTOR(FN, "")
 #else
@@ -237,25 +276,26 @@ typedef intptr_t ssize_t;
 
 #define DECL_BITFIELD(NAME, TYPE) typedef TYPE NAME
 
-#define DECL_BITS(TYPE, FIELD, START, SIZE) \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## Is ## FIELD (TYPE src) { \
-               return CHECK_BITS(src, (START), (START) + (SIZE)); \
-       } \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## Get ## FIELD (TYPE src) { \
-               return EXT_BITS(src, (START), (START) + (SIZE)); \
-       } \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## Clear ## FIELD (TYPE src) { \
-               return CLEAR_BITS(src, (START), (START) + (SIZE)); \
-       } \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## Fill ## FIELD (TYPE src) { \
-               return FILL_BITS(src, (START), (START) + (SIZE)); \
-       } \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## Set ## FIELD (TYPE src, TYPE bits) { \
-               return INS_BITS(src, (START), (START) + (SIZE), bits); \
-       } \
-       ATTRIBUTE_UNUSED static inline TYPE TYPE ## TestFill ## FIELD (TYPE src, bool test) { \
-               return TEST_FILL_BITS(src, (START), (START) + (SIZE), test); \
-       }
+#define DECL_BITS(TYPE, FIELD, START, SIZE)                                    \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##Is##FIELD(TYPE src) {              \
+    return CHECK_BITS(src, (START), (START) + (SIZE));                         \
+  }                                                                            \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##Get##FIELD(TYPE src) {             \
+    return EXT_BITS(src, (START), (START) + (SIZE));                           \
+  }                                                                            \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##Clear##FIELD(TYPE src) {           \
+    return CLEAR_BITS(src, (START), (START) + (SIZE));                         \
+  }                                                                            \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##Fill##FIELD(TYPE src) {            \
+    return FILL_BITS(src, (START), (START) + (SIZE));                          \
+  }                                                                            \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##Set##FIELD(TYPE src, TYPE bits) {  \
+    return INS_BITS(src, (START), (START) + (SIZE), bits);                     \
+  }                                                                            \
+  ATTRIBUTE_UNUSED static inline TYPE TYPE##TestFill##FIELD(TYPE src,          \
+                                                            bool test) {       \
+    return TEST_FILL_BITS(src, (START), (START) + (SIZE), test);               \
+  }
 
 #define DECL_BIT(TYPE, FIELD, BIT) DECL_BITS(TYPE, FIELD, BIT, 1)
 
@@ -267,12 +307,13 @@ typedef intptr_t ssize_t;
 #define UNLIKELY(X) (!!(X))
 #endif
 
-#define ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31)))
+#define ROR(I, ROTATE)                                                         \
+  ((((uint32_t)(I)) >> ROTATE) | ((uint32_t)(I) << ((-ROTATE) & 31)))
 
 static inline uint32_t popcount32(unsigned bits) {
-       bits = bits - ((bits >> 1) & 0x55555555);
-       bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
-       return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+  bits = bits - ((bits >> 1) & 0x55555555);
+  bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
+  return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
 }
 
 CXX_GUARD_END
index afbb03d8d2649a38c2832b752646ee6eefd15b66..6df4e737f64cde3df73fb2695d72eff4105974ce 100644 (file)
 #include "emitter-arm.h"
 #include "isa-inlines.h"
 
-#define ADDR_MODE_1_SHIFT(OP) \
-       info->op3.reg = opcode & 0x0000000F; \
-       info->op3.shifterOp = ARM_SHIFT_ ## OP; \
-       info->operandFormat |= ARM_OPERAND_REGISTER_3; \
-       if (opcode & 0x00000010) { \
-               info->op3.shifterReg = (opcode >> 8) & 0xF; \
-               ++info->iCycles; \
-               info->operandFormat |= ARM_OPERAND_SHIFT_REGISTER_3; \
-       } else { \
-               info->op3.shifterImm = (opcode >> 7) & 0x1F; \
-               info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3; \
-       }
-
-#define ADDR_MODE_1_LSL \
-       ADDR_MODE_1_SHIFT(LSL) \
-       if (!info->op3.shifterImm) { \
-               info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3; \
-               info->op3.shifterOp = ARM_SHIFT_NONE; \
-       }
+#define ADDR_MODE_1_SHIFT(OP)                                                  \
+  info->op3.reg = opcode & 0x0000000F;                                         \
+  info->op3.shifterOp = ARM_SHIFT_##OP;                                        \
+  info->operandFormat |= ARM_OPERAND_REGISTER_3;                               \
+  if (opcode & 0x00000010) {                                                   \
+    info->op3.shifterReg = (opcode >> 8) & 0xF;                                \
+    ++info->iCycles;                                                           \
+    info->operandFormat |= ARM_OPERAND_SHIFT_REGISTER_3;                       \
+  } else {                                                                     \
+    info->op3.shifterImm = (opcode >> 7) & 0x1F;                               \
+    info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3;                      \
+  }
+
+#define ADDR_MODE_1_LSL                                                        \
+  ADDR_MODE_1_SHIFT(LSL)                                                       \
+  if (!info->op3.shifterImm) {                                                 \
+    info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3;                     \
+    info->op3.shifterOp = ARM_SHIFT_NONE;                                      \
+  }
 
 #define ADDR_MODE_1_LSR ADDR_MODE_1_SHIFT(LSR)
 #define ADDR_MODE_1_ASR ADDR_MODE_1_SHIFT(ASR)
-#define ADDR_MODE_1_ROR \
-       ADDR_MODE_1_SHIFT(ROR) \
-       if (!info->op3.shifterImm) { \
-               info->op3.shifterOp = ARM_SHIFT_RRX; \
-       }
-
-#define ADDR_MODE_1_IMM \
-       int rotate = (opcode & 0x00000F00) >> 7; \
-       int immediate = opcode & 0x000000FF; \
-       info->op3.immediate = ROR(immediate, rotate); \
-       info->operandFormat |= ARM_OPERAND_IMMEDIATE_3;
-
-#define ADDR_MODE_2_SHIFT(OP) \
-       info->memory.format |= ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_SHIFTED_OFFSET; \
-       info->memory.offset.shifterOp = ARM_SHIFT_ ## OP; \
-       info->memory.offset.shifterImm = (opcode >> 7) & 0x1F; \
-       info->memory.offset.reg = opcode & 0x0000000F;
-
-#define ADDR_MODE_2_LSL \
-       ADDR_MODE_2_SHIFT(LSL) \
-       if (!info->memory.offset.shifterImm) { \
-               info->memory.format &= ~ARM_MEMORY_SHIFTED_OFFSET; \
-               info->memory.offset.shifterOp = ARM_SHIFT_NONE; \
-       }
-
-#define ADDR_MODE_2_LSR ADDR_MODE_2_SHIFT(LSR) \
-       if (!info->memory.offset.shifterImm) { \
-               info->memory.offset.shifterImm = 32; \
-       }
-
-#define ADDR_MODE_2_ASR ADDR_MODE_2_SHIFT(ASR) \
-       if (!info->memory.offset.shifterImm) { \
-               info->memory.offset.shifterImm = 32; \
-       }
-
-#define ADDR_MODE_2_ROR \
-       ADDR_MODE_2_SHIFT(ROR) \
-       if (!info->memory.offset.shifterImm) { \
-               info->memory.offset.shifterOp = ARM_SHIFT_RRX; \
-       }
-
-#define ADDR_MODE_2_IMM \
-       info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET; \
-       info->memory.offset.immediate = opcode & 0x00000FFF;
-
-#define ADDR_MODE_3_REG \
-       info->memory.format |= ARM_MEMORY_REGISTER_OFFSET; \
-       info->memory.offset.reg = opcode & 0x0000000F;
-
-#define ADDR_MODE_3_IMM \
-       info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET; \
-       info->memory.offset.immediate = (opcode & 0x0000000F) | ((opcode & 0x00000F00) >> 4);
-
-#define DEFINE_DECODER_ARM(NAME, MNEMONIC, BODY) \
-       static void _ARMDecode ## NAME (uint32_t opcode, struct ARMInstructionInfo* info) { \
-               UNUSED(opcode); \
-               info->mnemonic = ARM_MN_ ## MNEMONIC; \
-               BODY; \
-       }
-
-#define DEFINE_ALU_DECODER_EX_ARM(NAME, MNEMONIC, S, SHIFTER, OTHER_AFFECTED, SKIPPED) \
-       DEFINE_DECODER_ARM(NAME, MNEMONIC, \
-               info->op1.reg = (opcode >> 12) & 0xF; \
-               info->op2.reg = (opcode >> 16) & 0xF; \
-               info->operandFormat = ARM_OPERAND_REGISTER_1 | \
-                       OTHER_AFFECTED | \
-                       ARM_OPERAND_REGISTER_2; \
-               info->affectsCPSR = S; \
-               SHIFTER; \
-               if (SKIPPED == 1) { \
-                       info->op1 = info->op2; \
-                       info->op2 = info->op3; \
-                       info->operandFormat >>= 8; \
-               } else if (SKIPPED == 2) { \
-                       info->op2 = info->op3; \
-                       info->operandFormat |= info->operandFormat >> 8; \
-                       info->operandFormat &= ~ARM_OPERAND_3; \
-               } \
-               if (info->op1.reg == ARM_PC) { \
-                       info->branchType = ARM_BRANCH_INDIRECT; \
-               })
-
-#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 0, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 0, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 0, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 0, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 0, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## SI, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED)
-
-#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_NONE, 1) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_NONE, 1) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_NONE, 1) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_NONE, 1) \
-       DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_NONE, 1)
-
-#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \
-       DEFINE_DECODER_ARM(NAME, MNEMONIC, \
-               info->op1.reg = (opcode >> 16) & 0xF; \
-               info->op2.reg = opcode & 0xF; \
-               info->op3.reg = (opcode >> 8) & 0xF; \
-               info->op4.reg = (opcode >> 12) & 0xF; \
-               info->operandFormat = ARM_OPERAND_REGISTER_1 | \
-                       ARM_OPERAND_AFFECTED_1 | \
-                       ARM_OPERAND_REGISTER_2 | \
-                       ARM_OPERAND_REGISTER_3 | \
-                       OTHER_AFFECTED; \
-               info->affectsCPSR = S; \
-               if (info->op1.reg == ARM_PC) { \
-                       info->branchType = ARM_BRANCH_INDIRECT; \
-               })
-
-#define DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S) \
-       DEFINE_DECODER_ARM(NAME, MNEMONIC, \
-               info->op1.reg = (opcode >> 12) & 0xF; \
-               info->op2.reg = (opcode >> 16) & 0xF; \
-               info->op3.reg = opcode & 0xF; \
-               info->op4.reg = (opcode >> 8) & 0xF; \
-               info->operandFormat = ARM_OPERAND_REGISTER_1 | \
-                       ARM_OPERAND_AFFECTED_1 | \
-                       ARM_OPERAND_REGISTER_2 | \
-                       ARM_OPERAND_AFFECTED_2 | \
-                       ARM_OPERAND_REGISTER_3 | \
-                       ARM_OPERAND_REGISTER_4; \
-               info->affectsCPSR = S; \
-               if (info->op1.reg == ARM_PC) { \
-                       info->branchType = ARM_BRANCH_INDIRECT; \
-               })
-
-#define DEFINE_MULTIPLY_DECODER_ARM(NAME, OTHER_AFFECTED) \
-       DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0, OTHER_AFFECTED) \
-       DEFINE_MULTIPLY_DECODER_EX_ARM(NAME ## S, NAME, 1, OTHER_AFFECTED)
-
-#define DEFINE_LONG_MULTIPLY_DECODER_ARM(NAME) \
-       DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0) \
-       DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME ## S, NAME, 1)
-
-#define DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, ADDRESSING_MODE, ADDRESSING_DECODING, CYCLES, TYPE) \
-       DEFINE_DECODER_ARM(NAME, MNEMONIC, \
-               info->op1.reg = (opcode >> 12) & 0xF; \
-               info->memory.baseReg = (opcode >> 16) & 0xF; \
-               info->memory.width = TYPE; \
-               info->operandFormat = ARM_OPERAND_REGISTER_1 | \
-                       ARM_OPERAND_AFFECTED_1 | /* TODO: Remove this for STR */ \
-                       ARM_OPERAND_MEMORY_2; \
-               info->memory.format = ARM_MEMORY_REGISTER_BASE | ADDRESSING_MODE; \
-               ADDRESSING_DECODING; \
-               CYCLES;)
-
-#define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
-               ARM_MEMORY_POST_INCREMENT | \
-               ARM_MEMORY_WRITEBACK | \
-               ARM_MEMORY_OFFSET_SUBTRACT, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
-               ARM_MEMORY_POST_INCREMENT | \
-               ARM_MEMORY_WRITEBACK, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## P, MNEMONIC, \
-               ARM_MEMORY_OFFSET_SUBTRACT, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PW, MNEMONIC, \
-               ARM_MEMORY_PRE_INCREMENT | \
-               ARM_MEMORY_WRITEBACK | \
-               ARM_MEMORY_OFFSET_SUBTRACT, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PU, MNEMONIC, \
-               0, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PUW, MNEMONIC, \
-               ARM_MEMORY_WRITEBACK, \
-               ADDRESSING_MODE, CYCLES, TYPE)
-
-#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE)
-
-#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, CYCLES, TYPE)
-
-#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
-               ARM_MEMORY_POST_INCREMENT | \
-               ARM_MEMORY_WRITEBACK | \
-               ARM_MEMORY_OFFSET_SUBTRACT, \
-               ADDRESSING_MODE, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
-               ARM_MEMORY_POST_INCREMENT | \
-               ARM_MEMORY_WRITEBACK, \
-               ADDRESSING_MODE, CYCLES, TYPE)
-
-#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE) \
-       DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE)
-
-#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \
-       DEFINE_DECODER_ARM(NAME, MNEMONIC, \
-               info->memory.baseReg = (opcode >> 16) & 0xF; \
-               info->op1.immediate = opcode & 0x0000FFFF; \
-               if (info->op1.immediate & (1 << ARM_PC)) { \
-                       info->branchType = ARM_BRANCH_INDIRECT; \
-               } \
-               info->operandFormat = ARM_OPERAND_MEMORY_1; \
-               info->memory.format = ARM_MEMORY_REGISTER_BASE | \
-                       WRITEBACK | \
-                       ARM_MEMORY_ ## DIRECTION;)
-
-
-#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DA,   NAME, DECREMENT_AFTER, 0) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DAW,  NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DB,   NAME, DECREMENT_BEFORE, 0) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DBW,  NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IA,   NAME, INCREMENT_AFTER, 0) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IAW,  NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IB,   NAME, INCREMENT_BEFORE, 0) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IBW,  NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA,  NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB,  NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA,  NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB,  NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
-       DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
-
-#define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
-       DEFINE_DECODER_ARM(NAME, SWP, \
-               info->memory.baseReg = (opcode >> 16) & 0xF; \
-               info->op1.reg = (opcode >> 12) & 0xF; \
-               info->op2.reg = opcode & 0xF; \
-               info->operandFormat = ARM_OPERAND_REGISTER_1 | \
-                       ARM_OPERAND_AFFECTED_1 | \
-                       ARM_OPERAND_REGISTER_2 | \
-                       ARM_OPERAND_MEMORY_3; \
-               info->memory.format = ARM_MEMORY_REGISTER_BASE; \
-               info->memory.width = TYPE;)
+#define ADDR_MODE_1_ROR                                                        \
+  ADDR_MODE_1_SHIFT(ROR)                                                       \
+  if (!info->op3.shifterImm) {                                                 \
+    info->op3.shifterOp = ARM_SHIFT_RRX;                                       \
+  }
+
+#define ADDR_MODE_1_IMM                                                        \
+  int rotate = (opcode & 0x00000F00) >> 7;                                     \
+  int immediate = opcode & 0x000000FF;                                         \
+  info->op3.immediate = ROR(immediate, rotate);                                \
+  info->operandFormat |= ARM_OPERAND_IMMEDIATE_3;
+
+#define ADDR_MODE_2_SHIFT(OP)                                                  \
+  info->memory.format |=                                                       \
+      ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_SHIFTED_OFFSET;                  \
+  info->memory.offset.shifterOp = ARM_SHIFT_##OP;                              \
+  info->memory.offset.shifterImm = (opcode >> 7) & 0x1F;                       \
+  info->memory.offset.reg = opcode & 0x0000000F;
+
+#define ADDR_MODE_2_LSL                                                        \
+  ADDR_MODE_2_SHIFT(LSL)                                                       \
+  if (!info->memory.offset.shifterImm) {                                       \
+    info->memory.format &= ~ARM_MEMORY_SHIFTED_OFFSET;                         \
+    info->memory.offset.shifterOp = ARM_SHIFT_NONE;                            \
+  }
+
+#define ADDR_MODE_2_LSR                                                        \
+  ADDR_MODE_2_SHIFT(LSR)                                                       \
+  if (!info->memory.offset.shifterImm) {                                       \
+    info->memory.offset.shifterImm = 32;                                       \
+  }
+
+#define ADDR_MODE_2_ASR                                                        \
+  ADDR_MODE_2_SHIFT(ASR)                                                       \
+  if (!info->memory.offset.shifterImm) {                                       \
+    info->memory.offset.shifterImm = 32;                                       \
+  }
+
+#define ADDR_MODE_2_ROR                                                        \
+  ADDR_MODE_2_SHIFT(ROR)                                                       \
+  if (!info->memory.offset.shifterImm) {                                       \
+    info->memory.offset.shifterOp = ARM_SHIFT_RRX;                             \
+  }
+
+#define ADDR_MODE_2_IMM                                                        \
+  info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET;                          \
+  info->memory.offset.immediate = opcode & 0x00000FFF;
+
+#define ADDR_MODE_3_REG                                                        \
+  info->memory.format |= ARM_MEMORY_REGISTER_OFFSET;                           \
+  info->memory.offset.reg = opcode & 0x0000000F;
+
+#define ADDR_MODE_3_IMM                                                        \
+  info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET;                          \
+  info->memory.offset.immediate =                                              \
+      (opcode & 0x0000000F) | ((opcode & 0x00000F00) >> 4);
+
+#define DEFINE_DECODER_ARM(NAME, MNEMONIC, BODY)                               \
+  static void _ARMDecode##NAME(uint32_t opcode,                                \
+                               struct ARMInstructionInfo* info) {              \
+    UNUSED(opcode);                                                            \
+    info->mnemonic = ARM_MN_##MNEMONIC;                                        \
+    BODY;                                                                      \
+  }
+
+#define DEFINE_ALU_DECODER_EX_ARM(NAME, MNEMONIC, S, SHIFTER, OTHER_AFFECTED,  \
+                                  SKIPPED)                                     \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, MNEMONIC, info->op1.reg = (opcode >> 12) & 0xF;                    \
+      info->op2.reg = (opcode >> 16) & 0xF;                                    \
+      info->operandFormat =                                                    \
+          ARM_OPERAND_REGISTER_1 | OTHER_AFFECTED | ARM_OPERAND_REGISTER_2;    \
+      info->affectsCPSR = S; SHIFTER; if (SKIPPED == 1) {                      \
+        info->op1 = info->op2;                                                 \
+        info->op2 = info->op3;                                                 \
+        info->operandFormat >>= 8;                                             \
+      } else if (SKIPPED == 2) {                                               \
+        info->op2 = info->op3;                                                 \
+        info->operandFormat |= info->operandFormat >> 8;                       \
+        info->operandFormat &= ~ARM_OPERAND_3;                                 \
+      } if (info->op1.reg == ARM_PC) {                                         \
+        info->branchType = ARM_BRANCH_INDIRECT;                                \
+      })
+
+#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED)                                  \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_LSL, NAME, 0, ADDR_MODE_1_LSL,              \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##S_LSL, NAME, 1, ADDR_MODE_1_LSL,             \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_LSR, NAME, 0, ADDR_MODE_1_LSR,              \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##S_LSR, NAME, 1, ADDR_MODE_1_LSR,             \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_ASR, NAME, 0, ADDR_MODE_1_ASR,              \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##S_ASR, NAME, 1, ADDR_MODE_1_ASR,             \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_ROR, NAME, 0, ADDR_MODE_1_ROR,              \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##S_ROR, NAME, 1, ADDR_MODE_1_ROR,             \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##I, NAME, 0, ADDR_MODE_1_IMM,                 \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)                   \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##SI, NAME, 1, ADDR_MODE_1_IMM,                \
+                            ARM_OPERAND_AFFECTED_1, SKIPPED)
+
+#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME)                                    \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_LSL, NAME, 1, ADDR_MODE_1_LSL,              \
+                            ARM_OPERAND_NONE, 1)                               \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_LSR, NAME, 1, ADDR_MODE_1_LSR,              \
+                            ARM_OPERAND_NONE, 1)                               \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_ASR, NAME, 1, ADDR_MODE_1_ASR,              \
+                            ARM_OPERAND_NONE, 1)                               \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##_ROR, NAME, 1, ADDR_MODE_1_ROR,              \
+                            ARM_OPERAND_NONE, 1)                               \
+  DEFINE_ALU_DECODER_EX_ARM(NAME##I, NAME, 1, ADDR_MODE_1_IMM,                 \
+                            ARM_OPERAND_NONE, 1)
+
+#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED)      \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, MNEMONIC, info->op1.reg = (opcode >> 16) & 0xF;                    \
+      info->op2.reg = opcode & 0xF; info->op3.reg = (opcode >> 8) & 0xF;       \
+      info->op4.reg = (opcode >> 12) & 0xF;                                    \
+      info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |  \
+                            ARM_OPERAND_REGISTER_2 | ARM_OPERAND_REGISTER_3 |  \
+                            OTHER_AFFECTED;                                    \
+      info->affectsCPSR = S; if (info->op1.reg == ARM_PC) {                    \
+        info->branchType = ARM_BRANCH_INDIRECT;                                \
+      })
+
+#define DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S)                 \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, MNEMONIC, info->op1.reg = (opcode >> 12) & 0xF;                    \
+      info->op2.reg = (opcode >> 16) & 0xF; info->op3.reg = opcode & 0xF;      \
+      info->op4.reg = (opcode >> 8) & 0xF;                                     \
+      info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |  \
+                            ARM_OPERAND_REGISTER_2 | ARM_OPERAND_AFFECTED_2 |  \
+                            ARM_OPERAND_REGISTER_3 | ARM_OPERAND_REGISTER_4;   \
+      info->affectsCPSR = S; if (info->op1.reg == ARM_PC) {                    \
+        info->branchType = ARM_BRANCH_INDIRECT;                                \
+      })
+
+#define DEFINE_MULTIPLY_DECODER_ARM(NAME, OTHER_AFFECTED)                      \
+  DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0, OTHER_AFFECTED)                \
+  DEFINE_MULTIPLY_DECODER_EX_ARM(NAME##S, NAME, 1, OTHER_AFFECTED)
+
+#define DEFINE_LONG_MULTIPLY_DECODER_ARM(NAME)                                 \
+  DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0)                           \
+  DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME##S, NAME, 1)
+
+#define DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, ADDRESSING_MODE,      \
+                                         ADDRESSING_DECODING, CYCLES, TYPE)    \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, MNEMONIC, info->op1.reg = (opcode >> 12) & 0xF;                    \
+      info->memory.baseReg = (opcode >> 16) & 0xF; info->memory.width = TYPE;  \
+      info->operandFormat =                                                    \
+          ARM_OPERAND_REGISTER_1 |                                             \
+          ARM_OPERAND_AFFECTED_1 | /* TODO: Remove this for STR */             \
+          ARM_OPERAND_MEMORY_2;                                                \
+      info->memory.format = ARM_MEMORY_REGISTER_BASE | ADDRESSING_MODE;        \
+      ADDRESSING_DECODING; CYCLES;)
+
+#define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE,     \
+                                          CYCLES, TYPE)                        \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC,                             \
+                                   ARM_MEMORY_POST_INCREMENT |                 \
+                                       ARM_MEMORY_WRITEBACK |                  \
+                                       ARM_MEMORY_OFFSET_SUBTRACT,             \
+                                   ADDRESSING_MODE, CYCLES, TYPE)              \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(                                            \
+      NAME##U, MNEMONIC, ARM_MEMORY_POST_INCREMENT | ARM_MEMORY_WRITEBACK,     \
+      ADDRESSING_MODE, CYCLES, TYPE)                                           \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME##P, MNEMONIC,                          \
+                                   ARM_MEMORY_OFFSET_SUBTRACT,                 \
+                                   ADDRESSING_MODE, CYCLES, TYPE)              \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME##PW, MNEMONIC,                         \
+                                   ARM_MEMORY_PRE_INCREMENT |                  \
+                                       ARM_MEMORY_WRITEBACK |                  \
+                                       ARM_MEMORY_OFFSET_SUBTRACT,             \
+                                   ADDRESSING_MODE, CYCLES, TYPE)              \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME##PU, MNEMONIC, 0, ADDRESSING_MODE,     \
+                                   CYCLES, TYPE)                               \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME##PUW, MNEMONIC, ARM_MEMORY_WRITEBACK,  \
+                                   ADDRESSING_MODE, CYCLES, TYPE)
+
+#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE)     \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##_LSL_, MNEMONIC, ADDR_MODE_2_LSL,    \
+                                    CYCLES, TYPE)                              \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##_LSR_, MNEMONIC, ADDR_MODE_2_LSR,    \
+                                    CYCLES, TYPE)                              \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##_ASR_, MNEMONIC, ADDR_MODE_2_ASR,    \
+                                    CYCLES, TYPE)                              \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##_ROR_, MNEMONIC, ADDR_MODE_2_ROR,    \
+                                    CYCLES, TYPE)                              \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##I, MNEMONIC, ADDR_MODE_2_IMM,        \
+                                    CYCLES, TYPE)
+
+#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE)     \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES,   \
+                                    TYPE)                                      \
+  DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME##I, MNEMONIC, ADDR_MODE_3_IMM,        \
+                                    CYCLES, TYPE)
+
+#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE,   \
+                                            CYCLES, TYPE)                      \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC,                             \
+                                   ARM_MEMORY_POST_INCREMENT |                 \
+                                       ARM_MEMORY_WRITEBACK |                  \
+                                       ARM_MEMORY_OFFSET_SUBTRACT,             \
+                                   ADDRESSING_MODE, CYCLES, TYPE)              \
+  DEFINE_LOAD_STORE_DECODER_EX_ARM(                                            \
+      NAME##U, MNEMONIC, ARM_MEMORY_POST_INCREMENT | ARM_MEMORY_WRITEBACK,     \
+      ADDRESSING_MODE, CYCLES, TYPE)
+
+#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE)          \
+  DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME##_LSL_, MNEMONIC, ADDR_MODE_2_LSL,  \
+                                      CYCLES, TYPE)                            \
+  DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME##_LSR_, MNEMONIC, ADDR_MODE_2_LSR,  \
+                                      CYCLES, TYPE)                            \
+  DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME##_ASR_, MNEMONIC, ADDR_MODE_2_ASR,  \
+                                      CYCLES, TYPE)                            \
+  DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME##_ROR_, MNEMONIC, ADDR_MODE_2_ROR,  \
+                                      CYCLES, TYPE)                            \
+  DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME##I, MNEMONIC, ADDR_MODE_2_IMM,      \
+                                      CYCLES, TYPE)
+
+#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION,   \
+                                                  WRITEBACK)                   \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, MNEMONIC, info->memory.baseReg = (opcode >> 16) & 0xF;             \
+      info->op1.immediate = opcode & 0x0000FFFF;                               \
+      if (info->op1.immediate & (1 << ARM_PC)) {                               \
+        info->branchType = ARM_BRANCH_INDIRECT;                                \
+      } info->operandFormat = ARM_OPERAND_MEMORY_1;                            \
+      info->memory.format =                                                    \
+          ARM_MEMORY_REGISTER_BASE | WRITEBACK | ARM_MEMORY_##DIRECTION;)
+
+#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME)                           \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##DA, NAME, DECREMENT_AFTER,   \
+                                            0)                                 \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##DAW, NAME, DECREMENT_AFTER,  \
+                                            ARM_MEMORY_WRITEBACK)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##DB, NAME, DECREMENT_BEFORE,  \
+                                            0)                                 \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##DBW, NAME, DECREMENT_BEFORE, \
+                                            ARM_MEMORY_WRITEBACK)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##IA, NAME, INCREMENT_AFTER,   \
+                                            0)                                 \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##IAW, NAME, INCREMENT_AFTER,  \
+                                            ARM_MEMORY_WRITEBACK)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##IB, NAME, INCREMENT_BEFORE,  \
+                                            0)                                 \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##IBW, NAME, INCREMENT_BEFORE, \
+                                            ARM_MEMORY_WRITEBACK)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SDA, NAME, DECREMENT_AFTER,  \
+                                            ARM_MEMORY_SPSR_SWAP)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SDAW, NAME, DECREMENT_AFTER, \
+                                            ARM_MEMORY_WRITEBACK |             \
+                                                ARM_MEMORY_SPSR_SWAP)          \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SDB, NAME, DECREMENT_BEFORE, \
+                                            ARM_MEMORY_SPSR_SWAP)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(                                   \
+      NAME##SDBW, NAME, DECREMENT_BEFORE,                                      \
+      ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)                             \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SIA, NAME, INCREMENT_AFTER,  \
+                                            ARM_MEMORY_SPSR_SWAP)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SIAW, NAME, INCREMENT_AFTER, \
+                                            ARM_MEMORY_WRITEBACK |             \
+                                                ARM_MEMORY_SPSR_SWAP)          \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME##SIB, NAME, INCREMENT_BEFORE, \
+                                            ARM_MEMORY_SPSR_SWAP)              \
+  DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(                                   \
+      NAME##SIBW, NAME, INCREMENT_BEFORE,                                      \
+      ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
+
+#define DEFINE_SWP_DECODER_ARM(NAME, TYPE)                                     \
+  DEFINE_DECODER_ARM(                                                          \
+      NAME, SWP, info->memory.baseReg = (opcode >> 16) & 0xF;                  \
+      info->op1.reg = (opcode >> 12) & 0xF; info->op2.reg = opcode & 0xF;      \
+      info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |  \
+                            ARM_OPERAND_REGISTER_2 | ARM_OPERAND_MEMORY_3;     \
+      info->memory.format = ARM_MEMORY_REGISTER_BASE;                          \
+      info->memory.width = TYPE;)
 
 DEFINE_ALU_DECODER_ARM(ADD, 0)
 DEFINE_ALU_DECODER_ARM(ADC, 0)
@@ -312,17 +345,25 @@ DEFINE_LONG_MULTIPLY_DECODER_ARM(UMULL)
 
 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE)
-DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD)
-DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE)
-DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD)
+DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES,
+                                     ARM_ACCESS_HALFWORD)
+DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES,
+                                     ARM_ACCESS_SIGNED_BYTE)
+DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES,
+                                     ARM_ACCESS_SIGNED_HALFWORD)
 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE_CYCLES, ARM_ACCESS_WORD)
 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE_CYCLES, ARM_ACCESS_BYTE)
-DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD)
-
-DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_BYTE)
-DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_WORD)
-DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE)
-DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD)
+DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES,
+                                     ARM_ACCESS_HALFWORD)
+
+DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES,
+                                ARM_ACCESS_TRANSLATED_BYTE)
+DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES,
+                                ARM_ACCESS_TRANSLATED_WORD)
+DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES,
+                                ARM_ACCESS_TRANSLATED_BYTE)
+DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES,
+                                ARM_ACCESS_TRANSLATED_WORD)
 
 DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM)
 DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM)
@@ -334,22 +375,19 @@ DEFINE_SWP_DECODER_ARM(SWPB, ARM_ACCESS_BYTE)
 
 // Begin branch definitions
 
-DEFINE_DECODER_ARM(B, B,
-       int32_t offset = opcode << 8;
-       info->op1.immediate = offset >> 6;
-       info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
-       info->branchType = ARM_BRANCH;)
+DEFINE_DECODER_ARM(B, B, int32_t offset = opcode << 8;
+                   info->op1.immediate = offset >> 6;
+                   info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
+                   info->branchType = ARM_BRANCH;)
 
-DEFINE_DECODER_ARM(BL, BL,
-       int32_t offset = opcode << 8;
-       info->op1.immediate = offset >> 6;
-       info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
-       info->branchType = ARM_BRANCH_LINKED;)
+DEFINE_DECODER_ARM(BL, BL, int32_t offset = opcode << 8;
+                   info->op1.immediate = offset >> 6;
+                   info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
+                   info->branchType = ARM_BRANCH_LINKED;)
 
-DEFINE_DECODER_ARM(BX, BX,
-       info->op1.reg = opcode & 0x0000000F;
-       info->operandFormat = ARM_OPERAND_REGISTER_1;
-       info->branchType = ARM_BRANCH_INDIRECT;)
+DEFINE_DECODER_ARM(BX, BX, info->op1.reg = opcode & 0x0000000F;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1;
+                   info->branchType = ARM_BRANCH_INDIRECT;)
 
 // End branch definitions
 
@@ -363,85 +401,75 @@ DEFINE_DECODER_ARM(MRC, ILL, info->operandFormat = ARM_OPERAND_NONE;)
 
 // Begin miscellaneous definitions
 
-DEFINE_DECODER_ARM(BKPT, BKPT,
-       info->operandFormat = ARM_OPERAND_NONE;
-       info->traps = 1;) // Not strictly in ARMv4T, but here for convenience
+DEFINE_DECODER_ARM(
+    BKPT, BKPT,
+    info->operandFormat = ARM_OPERAND_NONE;
+    info->traps = 1;) // Not strictly in ARMv4T, but here for convenience
 DEFINE_DECODER_ARM(ILL, ILL,
-       info->operandFormat = ARM_OPERAND_NONE;
-       info->traps = 1;) // Illegal opcode
-
-DEFINE_DECODER_ARM(MSR, MSR,
-       info->affectsCPSR = 1;
-       info->op1.reg = ARM_CPSR;
-       info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
-       info->op2.reg = opcode & 0x0000000F;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_REGISTER_2;)
-
-DEFINE_DECODER_ARM(MSRR, MSR,
-       info->op1.reg = ARM_SPSR;
-       info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
-       info->op2.reg = opcode & 0x0000000F;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_REGISTER_2;)
-
-DEFINE_DECODER_ARM(MRS, MRS,
-       info->affectsCPSR = 1;
-       info->op1.reg = (opcode >> 12) & 0xF;
-       info->op2.reg = ARM_CPSR;
-       info->op2.psrBits = 0;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_REGISTER_2;)
-
-DEFINE_DECODER_ARM(MRSR, MRS,
-       info->op1.reg = (opcode >> 12) & 0xF;
-       info->op2.reg = ARM_SPSR;
-       info->op2.psrBits = 0;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_REGISTER_2;)
-
-DEFINE_DECODER_ARM(MSRI, MSR,
-       int rotate = (opcode & 0x00000F00) >> 7;
-       int32_t operand = ROR(opcode & 0x000000FF, rotate);
-       info->affectsCPSR = 1;
-       info->op1.reg = ARM_CPSR;
-       info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
-       info->op2.immediate = operand;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_IMMEDIATE_2;)
-
-DEFINE_DECODER_ARM(MSRRI, MSR,
-       int rotate = (opcode & 0x00000F00) >> 7;
-       int32_t operand = ROR(opcode & 0x000000FF, rotate);
-       info->op1.reg = ARM_SPSR;
-       info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
-       info->op2.immediate = operand;
-       info->operandFormat = ARM_OPERAND_REGISTER_1 |
-               ARM_OPERAND_AFFECTED_1 |
-               ARM_OPERAND_IMMEDIATE_2;)
-
-DEFINE_DECODER_ARM(SWI, SWI,
-       info->op1.immediate = opcode & 0xFFFFFF;
-       info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
-       info->traps = 1;)
+                   info->operandFormat = ARM_OPERAND_NONE;
+                   info->traps = 1;) // Illegal opcode
+
+DEFINE_DECODER_ARM(MSR, MSR, info->affectsCPSR = 1; info->op1.reg = ARM_CPSR;
+                   info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
+                   info->op2.reg = opcode & 0x0000000F;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_REGISTER_2;)
+
+DEFINE_DECODER_ARM(MSRR, MSR, info->op1.reg = ARM_SPSR;
+                   info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
+                   info->op2.reg = opcode & 0x0000000F;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_REGISTER_2;)
+
+DEFINE_DECODER_ARM(MRS, MRS, info->affectsCPSR = 1;
+                   info->op1.reg = (opcode >> 12) & 0xF;
+                   info->op2.reg = ARM_CPSR; info->op2.psrBits = 0;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_REGISTER_2;)
+
+DEFINE_DECODER_ARM(MRSR, MRS, info->op1.reg = (opcode >> 12) & 0xF;
+                   info->op2.reg = ARM_SPSR; info->op2.psrBits = 0;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_REGISTER_2;)
+
+DEFINE_DECODER_ARM(MSRI, MSR, int rotate = (opcode & 0x00000F00) >> 7;
+                   int32_t operand = ROR(opcode & 0x000000FF, rotate);
+                   info->affectsCPSR = 1; info->op1.reg = ARM_CPSR;
+                   info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
+                   info->op2.immediate = operand;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_IMMEDIATE_2;)
+
+DEFINE_DECODER_ARM(MSRRI, MSR, int rotate = (opcode & 0x00000F00) >> 7;
+                   int32_t operand = ROR(opcode & 0x000000FF, rotate);
+                   info->op1.reg = ARM_SPSR;
+                   info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
+                   info->op2.immediate = operand;
+                   info->operandFormat = ARM_OPERAND_REGISTER_1 |
+                                         ARM_OPERAND_AFFECTED_1 |
+                                         ARM_OPERAND_IMMEDIATE_2;)
+
+DEFINE_DECODER_ARM(SWI, SWI, info->op1.immediate = opcode & 0xFFFFFF;
+                   info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
+                   info->traps = 1;)
 
 typedef void (*ARMDecoder)(uint32_t opcode, struct ARMInstructionInfo* info);
 
 static const ARMDecoder _armDecoderTable[0x1000] = {
-       DECLARE_ARM_EMITTER_BLOCK(_ARMDecode)
-};
+    DECLARE_ARM_EMITTER_BLOCK(_ARMDecode)};
 
 void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info) {
-       memset(info, 0, sizeof(*info));
-       info->opcode = opcode;
-       info->branchType = ARM_BRANCH_NONE;
-       info->condition = opcode >> 28;
-       info->sInstructionCycles = 1;
-       ARMDecoder decoder = _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
-       decoder(opcode, info);
+  memset(info, 0, sizeof(*info));
+  info->opcode = opcode;
+  info->branchType = ARM_BRANCH_NONE;
+  info->condition = opcode >> 28;
+  info->sInstructionCycles = 1;
+  ARMDecoder decoder =
+      _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
+  decoder(opcode, info);
 }
index 4dd80a08b8569eb41a575983871c478d22279c03..31092e21a874f327f0fb3fd6c607f7004b266ed7 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
-#define LOAD_CYCLES    \
-       info->iCycles = 1; \
-       info->nDataCycles = 1;
+#define LOAD_CYCLES                                                            \
+  info->iCycles = 1;                                                           \
+  info->nDataCycles = 1;
 
-#define STORE_CYCLES              \
-       info->sInstructionCycles = 0; \
-       info->nInstructionCycles = 1; \
-       info->nDataCycles = 1;
+#define STORE_CYCLES                                                           \
+  info->sInstructionCycles = 0;                                                \
+  info->nInstructionCycles = 1;                                                \
+  info->nDataCycles = 1;
 
 #endif
index 9e8545c106028f30307d9d4ebeef131998f8c6ff..2feb1c1dbb9906a5d9a6ea21dc746dd14f7f841f 100644 (file)
 
 #include "decoder-inlines.h"
 
-#define ADVANCE(AMOUNT) \
-       if (AMOUNT >= blen) { \
-               buffer[blen - 1] = '\0'; \
-               return total; \
-       } \
-       total += AMOUNT; \
-       buffer += AMOUNT; \
-       blen -= AMOUNT;
+#define ADVANCE(AMOUNT)                                                        \
+  if (AMOUNT >= blen) {                                                        \
+    buffer[blen - 1] = '\0';                                                   \
+    return total;                                                              \
+  }                                                                            \
+  total += AMOUNT;                                                             \
+  buffer += AMOUNT;                                                            \
+  blen -= AMOUNT;
 
 static int _decodeRegister(int reg, char* buffer, int blen);
 static int _decodeRegisterList(int list, char* buffer, int blen);
 static int _decodePSR(int bits, char* buffer, int blen);
-static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen);
-static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen);
-static int _decodeShift(union ARMOperand operand, bool reg, char* buffer, int blen);
+static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer,
+                             int blen);
+static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer,
+                         int blen);
+static int _decodeShift(union ARMOperand operand, bool reg, char* buffer,
+                        int blen);
 
-static const char* _armConditions[] = {
-       "eq",
-       "ne",
-       "cs",
-       "cc",
-       "mi",
-       "pl",
-       "vs",
-       "vc",
-       "hi",
-       "ls",
-       "ge",
-       "lt",
-       "gt",
-       "le",
-       "al",
-       "nv"
-};
+static const char* _armConditions[] = {"eq", "ne", "cs", "cc", "mi", "pl",
+                                       "vs", "vc", "hi", "ls", "ge", "lt",
+                                       "gt", "le", "al", "nv"};
 
 static int _decodeRegister(int reg, char* buffer, int blen) {
-       switch (reg) {
-       case ARM_SP:
-               strncpy(buffer, "sp", blen - 1);
-               return 2;
-       case ARM_LR:
-               strncpy(buffer, "lr", blen - 1);
-               return 2;
-       case ARM_PC:
-               strncpy(buffer, "pc", blen - 1);
-               return 2;
-       case ARM_CPSR:
-               strncpy(buffer, "cpsr", blen - 1);
-               return 4;
-       case ARM_SPSR:
-               strncpy(buffer, "spsr", blen - 1);
-               return 4;
-       default:
-               return snprintf(buffer, blen - 1, "r%i", reg);
-       }
+  switch (reg) {
+  case ARM_SP:
+    strncpy(buffer, "sp", blen - 1);
+    return 2;
+  case ARM_LR:
+    strncpy(buffer, "lr", blen - 1);
+    return 2;
+  case ARM_PC:
+    strncpy(buffer, "pc", blen - 1);
+    return 2;
+  case ARM_CPSR:
+    strncpy(buffer, "cpsr", blen - 1);
+    return 4;
+  case ARM_SPSR:
+    strncpy(buffer, "spsr", blen - 1);
+    return 4;
+  default:
+    return snprintf(buffer, blen - 1, "r%i", reg);
+  }
 }
 
 static int _decodeRegisterList(int list, char* buffer, int blen) {
-       if (blen <= 0) {
-               return 0;
-       }
-       int total = 0;
-       strncpy(buffer, "{", blen - 1);
-       ADVANCE(1);
-       int i;
-       int start = -1;
-       int end = -1;
-       int written;
-       for (i = 0; i <= ARM_PC; ++i) {
-               if (list & 1) {
-                       if (start < 0) {
-                               start = i;
-                               end = i;
-                       } else if (end + 1 == i) {
-                               end = i;
-                       } else {
-                               if (end > start) {
-                                       written = _decodeRegister(start, buffer, blen);
-                                       ADVANCE(written);
-                                       strncpy(buffer, "-", blen - 1);
-                                       ADVANCE(1);
-                               }
-                               written = _decodeRegister(end, buffer, blen);
-                               ADVANCE(written);
-                               strncpy(buffer, ",", blen - 1);
-                               ADVANCE(1);
-                               start = i;
-                               end = i;
-                       }
-               }
-               list >>= 1;
-       }
-       if (start >= 0) {
-               if (end > start) {
-                       written = _decodeRegister(start, buffer, blen);
-                       ADVANCE(written);
-                       strncpy(buffer, "-", blen - 1);
-                       ADVANCE(1);
-               }
-               written = _decodeRegister(end, buffer, blen);
-               ADVANCE(written);
-       }
-       strncpy(buffer, "}", blen - 1);
-       ADVANCE(1);
-       return total;
+  if (blen <= 0) {
+    return 0;
+  }
+  int total = 0;
+  strncpy(buffer, "{", blen - 1);
+  ADVANCE(1);
+  int i;
+  int start = -1;
+  int end = -1;
+  int written;
+  for (i = 0; i <= ARM_PC; ++i) {
+    if (list & 1) {
+      if (start < 0) {
+        start = i;
+        end = i;
+      } else if (end + 1 == i) {
+        end = i;
+      } else {
+        if (end > start) {
+          written = _decodeRegister(start, buffer, blen);
+          ADVANCE(written);
+          strncpy(buffer, "-", blen - 1);
+          ADVANCE(1);
+        }
+        written = _decodeRegister(end, buffer, blen);
+        ADVANCE(written);
+        strncpy(buffer, ",", blen - 1);
+        ADVANCE(1);
+        start = i;
+        end = i;
+      }
+    }
+    list >>= 1;
+  }
+  if (start >= 0) {
+    if (end > start) {
+      written = _decodeRegister(start, buffer, blen);
+      ADVANCE(written);
+      strncpy(buffer, "-", blen - 1);
+      ADVANCE(1);
+    }
+    written = _decodeRegister(end, buffer, blen);
+    ADVANCE(written);
+  }
+  strncpy(buffer, "}", blen - 1);
+  ADVANCE(1);
+  return total;
 }
 
 static int _decodePSR(int psrBits, char* buffer, int blen) {
-       if (!psrBits) {
-               return 0;
-       }
-       int total = 0;
-       strncpy(buffer, "_", blen - 1);
-       ADVANCE(1);
-       if (psrBits & ARM_PSR_C) {
-               strncpy(buffer, "c", blen - 1);
-               ADVANCE(1);
-       }
-       if (psrBits & ARM_PSR_X) {
-               strncpy(buffer, "x", blen - 1);
-               ADVANCE(1);
-       }
-       if (psrBits & ARM_PSR_S) {
-               strncpy(buffer, "s", blen - 1);
-               ADVANCE(1);
-       }
-       if (psrBits & ARM_PSR_F) {
-               strncpy(buffer, "f", blen - 1);
-               ADVANCE(1);
-       }
-       return total;
+  if (!psrBits) {
+    return 0;
+  }
+  int total = 0;
+  strncpy(buffer, "_", blen - 1);
+  ADVANCE(1);
+  if (psrBits & ARM_PSR_C) {
+    strncpy(buffer, "c", blen - 1);
+    ADVANCE(1);
+  }
+  if (psrBits & ARM_PSR_X) {
+    strncpy(buffer, "x", blen - 1);
+    ADVANCE(1);
+  }
+  if (psrBits & ARM_PSR_S) {
+    strncpy(buffer, "s", blen - 1);
+    ADVANCE(1);
+  }
+  if (psrBits & ARM_PSR_F) {
+    strncpy(buffer, "f", blen - 1);
+    ADVANCE(1);
+  }
+  return total;
 }
 
-static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen) {
-       return snprintf(buffer, blen - 1, "$%08X", address + pc);
+static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer,
+                             int blen) {
+  return snprintf(buffer, blen - 1, "$%08X", address + pc);
 }
 
-static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen) {
-       if (blen <= 1) {
-               return 0;
-       }
-       int total = 0;
-       strncpy(buffer, "[", blen - 1);
-       ADVANCE(1);
-       int written;
-       if (memory.format & ARM_MEMORY_REGISTER_BASE) {
-               if (memory.baseReg == ARM_PC && memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
-                       written = _decodePCRelative(memory.format & ARM_MEMORY_OFFSET_SUBTRACT ? -memory.offset.immediate : memory.offset.immediate, pc & 0xFFFFFFFC, buffer, blen);
-                       ADVANCE(written);
-               } else {
-                       written = _decodeRegister(memory.baseReg, buffer, blen);
-                       ADVANCE(written);
-                       if (memory.format & (ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_IMMEDIATE_OFFSET) && !(memory.format & ARM_MEMORY_POST_INCREMENT)) {
-                               strncpy(buffer, ", ", blen - 1);
-                               ADVANCE(2);
-                       }
-               }
-       }
-       if (memory.format & ARM_MEMORY_POST_INCREMENT) {
-               strncpy(buffer, "], ", blen - 1);
-               ADVANCE(3);
-       }
-       if (memory.format & ARM_MEMORY_IMMEDIATE_OFFSET && memory.baseReg != ARM_PC) {
-               if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
-                       written = snprintf(buffer, blen - 1, "#-%i", memory.offset.immediate);
-                       ADVANCE(written);
-               } else {
-                       written = snprintf(buffer, blen - 1, "#%i", memory.offset.immediate);
-                       ADVANCE(written);
-               }
-       } else if (memory.format & ARM_MEMORY_REGISTER_OFFSET) {
-               if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
-                       strncpy(buffer, "-", blen - 1);
-                       ADVANCE(1);
-               }
-               written = _decodeRegister(memory.offset.reg, buffer, blen);
-               ADVANCE(written);
-       }
-       if (memory.format & ARM_MEMORY_SHIFTED_OFFSET) {
-               written = _decodeShift(memory.offset, false, buffer, blen);
-               ADVANCE(written);
-       }
+static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer,
+                         int blen) {
+  if (blen <= 1) {
+    return 0;
+  }
+  int total = 0;
+  strncpy(buffer, "[", blen - 1);
+  ADVANCE(1);
+  int written;
+  if (memory.format & ARM_MEMORY_REGISTER_BASE) {
+    if (memory.baseReg == ARM_PC &&
+        memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
+      written = _decodePCRelative(memory.format & ARM_MEMORY_OFFSET_SUBTRACT
+                                      ? -memory.offset.immediate
+                                      : memory.offset.immediate,
+                                  pc & 0xFFFFFFFC, buffer, blen);
+      ADVANCE(written);
+    } else {
+      written = _decodeRegister(memory.baseReg, buffer, blen);
+      ADVANCE(written);
+      if (memory.format &
+              (ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_IMMEDIATE_OFFSET) &&
+          !(memory.format & ARM_MEMORY_POST_INCREMENT)) {
+        strncpy(buffer, ", ", blen - 1);
+        ADVANCE(2);
+      }
+    }
+  }
+  if (memory.format & ARM_MEMORY_POST_INCREMENT) {
+    strncpy(buffer, "], ", blen - 1);
+    ADVANCE(3);
+  }
+  if (memory.format & ARM_MEMORY_IMMEDIATE_OFFSET && memory.baseReg != ARM_PC) {
+    if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
+      written = snprintf(buffer, blen - 1, "#-%i", memory.offset.immediate);
+      ADVANCE(written);
+    } else {
+      written = snprintf(buffer, blen - 1, "#%i", memory.offset.immediate);
+      ADVANCE(written);
+    }
+  } else if (memory.format & ARM_MEMORY_REGISTER_OFFSET) {
+    if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
+      strncpy(buffer, "-", blen - 1);
+      ADVANCE(1);
+    }
+    written = _decodeRegister(memory.offset.reg, buffer, blen);
+    ADVANCE(written);
+  }
+  if (memory.format & ARM_MEMORY_SHIFTED_OFFSET) {
+    written = _decodeShift(memory.offset, false, buffer, blen);
+    ADVANCE(written);
+  }
 
-       if (!(memory.format & ARM_MEMORY_POST_INCREMENT)) {
-               strncpy(buffer, "]", blen - 1);
-               ADVANCE(1);
-       }
-       if ((memory.format & (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) == (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) {
-               strncpy(buffer, "!", blen - 1);
-               ADVANCE(1);
-       }
-       return total;
+  if (!(memory.format & ARM_MEMORY_POST_INCREMENT)) {
+    strncpy(buffer, "]", blen - 1);
+    ADVANCE(1);
+  }
+  if ((memory.format & (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) ==
+      (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) {
+    strncpy(buffer, "!", blen - 1);
+    ADVANCE(1);
+  }
+  return total;
 }
 
 static int _decodeShift(union ARMOperand op, bool reg, char* buffer, int blen) {
-       if (blen <= 1) {
-               return 0;
-       }
-       int total = 0;
-       strncpy(buffer, ", ", blen - 1);
-       ADVANCE(2);
-       int written;
-       switch (op.shifterOp) {
-       case ARM_SHIFT_LSL:
-               strncpy(buffer, "lsl ", blen - 1);
-               ADVANCE(4);
-               break;
-       case ARM_SHIFT_LSR:
-               strncpy(buffer, "lsr ", blen - 1);
-               ADVANCE(4);
-               break;
-       case ARM_SHIFT_ASR:
-               strncpy(buffer, "asr ", blen - 1);
-               ADVANCE(4);
-               break;
-       case ARM_SHIFT_ROR:
-               strncpy(buffer, "ror ", blen - 1);
-               ADVANCE(4);
-               break;
-       case ARM_SHIFT_RRX:
-               strncpy(buffer, "rrx", blen - 1);
-               ADVANCE(3);
-               return total;
-       }
-       if (!reg) {
-               written = snprintf(buffer, blen - 1, "#%i", op.shifterImm);
-       } else {
-               written = _decodeRegister(op.shifterReg, buffer, blen);
-       }
-       ADVANCE(written);
-       return total;
+  if (blen <= 1) {
+    return 0;
+  }
+  int total = 0;
+  strncpy(buffer, ", ", blen - 1);
+  ADVANCE(2);
+  int written;
+  switch (op.shifterOp) {
+  case ARM_SHIFT_LSL:
+    strncpy(buffer, "lsl ", blen - 1);
+    ADVANCE(4);
+    break;
+  case ARM_SHIFT_LSR:
+    strncpy(buffer, "lsr ", blen - 1);
+    ADVANCE(4);
+    break;
+  case ARM_SHIFT_ASR:
+    strncpy(buffer, "asr ", blen - 1);
+    ADVANCE(4);
+    break;
+  case ARM_SHIFT_ROR:
+    strncpy(buffer, "ror ", blen - 1);
+    ADVANCE(4);
+    break;
+  case ARM_SHIFT_RRX:
+    strncpy(buffer, "rrx", blen - 1);
+    ADVANCE(3);
+    return total;
+  }
+  if (!reg) {
+    written = snprintf(buffer, blen - 1, "#%i", op.shifterImm);
+  } else {
+    written = _decodeRegister(op.shifterReg, buffer, blen);
+  }
+  ADVANCE(written);
+  return total;
 }
 
 static const char* _armMnemonicStrings[] = {
-       "ill",
-       "adc",
-       "add",
-       "and",
-       "asr",
-       "b",
-       "bic",
-       "bkpt",
-       "bl",
-       "bx",
-       "cmn",
-       "cmp",
-       "eor",
-       "ldm",
-       "ldr",
-       "lsl",
-       "lsr",
-       "mla",
-       "mov",
-       "mrs",
-       "msr",
-       "mul",
-       "mvn",
-       "neg",
-       "orr",
-       "ror",
-       "rsb",
-       "rsc",
-       "sbc",
-       "smlal",
-       "smull",
-       "stm",
-       "str",
-       "sub",
-       "swi",
-       "swp",
-       "teq",
-       "tst",
-       "umlal",
-       "umull",
+    "ill",   "adc", "add", "and", "asr", "b",   "bic", "bkpt", "bl",    "bx",
+    "cmn",   "cmp", "eor", "ldm", "ldr", "lsl", "lsr", "mla",  "mov",   "mrs",
+    "msr",   "mul", "mvn", "neg", "orr", "ror", "rsb", "rsc",  "sbc",   "smlal",
+    "smull", "stm", "str", "sub", "swi", "swp", "teq", "tst",  "umlal", "umull",
 
-       "ill"
-};
+    "ill"};
 
-static const char* _armDirectionStrings[] = {
-       "da",
-       "ia",
-       "db",
-       "ib"
-};
+static const char* _armDirectionStrings[] = {"da", "ia", "db", "ib"};
 
 static const char* _armAccessTypeStrings[] = {
-       "",
-       "b",
-       "h",
-       "",
-       "",
-       "",
-       "",
-       "",
+    "", "b",  "h",  "", "",  "", "", "",
 
-       "",
-       "sb",
-       "sh",
-       "",
-       "",
-       "",
-       "",
-       "",
+    "", "sb", "sh", "", "",  "", "", "",
 
-       "",
-       "bt",
-       "",
-       "",
-       "t",
-       "",
-       "",
-       ""
-};
+    "", "bt", "",   "", "t", "", "", ""};
 
-int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, int blen) {
-       const char* mnemonic = _armMnemonicStrings[info->mnemonic];
-       int written;
-       int total = 0;
-       const char* cond = "";
-       if (info->condition != ARM_CONDITION_AL && info->condition < ARM_CONDITION_NV) {
-               cond = _armConditions[info->condition];
-       }
-       const char* flags = "";
-       switch (info->mnemonic) {
-       case ARM_MN_LDM:
-       case ARM_MN_STM:
-               flags = _armDirectionStrings[MEMORY_FORMAT_TO_DIRECTION(info->memory.format)];
-               break;
-       case ARM_MN_LDR:
-       case ARM_MN_STR:
-       case ARM_MN_SWP:
-               flags = _armAccessTypeStrings[info->memory.width];
-               break;
-       case ARM_MN_ADD:
-       case ARM_MN_ADC:
-       case ARM_MN_AND:
-       case ARM_MN_BIC:
-       case ARM_MN_EOR:
-       case ARM_MN_MOV:
-       case ARM_MN_MVN:
-       case ARM_MN_ORR:
-       case ARM_MN_RSB:
-       case ARM_MN_RSC:
-       case ARM_MN_SBC:
-       case ARM_MN_SUB:
-               if (info->affectsCPSR) {
-                       flags = "s";
-               }
-               break;
-       default:
-               break;
-       }
-       written = snprintf(buffer, blen - 1, "%s%s%s ", mnemonic, cond, flags);
-       ADVANCE(written);
+int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer,
+                   int blen) {
+  const char* mnemonic = _armMnemonicStrings[info->mnemonic];
+  int written;
+  int total = 0;
+  const char* cond = "";
+  if (info->condition != ARM_CONDITION_AL &&
+      info->condition < ARM_CONDITION_NV) {
+    cond = _armConditions[info->condition];
+  }
+  const char* flags = "";
+  switch (info->mnemonic) {
+  case ARM_MN_LDM:
+  case ARM_MN_STM:
+    flags =
+        _armDirectionStrings[MEMORY_FORMAT_TO_DIRECTION(info->memory.format)];
+    break;
+  case ARM_MN_LDR:
+  case ARM_MN_STR:
+  case ARM_MN_SWP:
+    flags = _armAccessTypeStrings[info->memory.width];
+    break;
+  case ARM_MN_ADD:
+  case ARM_MN_ADC:
+  case ARM_MN_AND:
+  case ARM_MN_BIC:
+  case ARM_MN_EOR:
+  case ARM_MN_MOV:
+  case ARM_MN_MVN:
+  case ARM_MN_ORR:
+  case ARM_MN_RSB:
+  case ARM_MN_RSC:
+  case ARM_MN_SBC:
+  case ARM_MN_SUB:
+    if (info->affectsCPSR) {
+      flags = "s";
+    }
+    break;
+  default:
+    break;
+  }
+  written = snprintf(buffer, blen - 1, "%s%s%s ", mnemonic, cond, flags);
+  ADVANCE(written);
 
-       switch (info->mnemonic) {
-       case ARM_MN_LDM:
-       case ARM_MN_STM:
-               written = _decodeRegister(info->memory.baseReg, buffer, blen);
-               ADVANCE(written);
-               if (info->memory.format & ARM_MEMORY_WRITEBACK) {
-                       strncpy(buffer, "!", blen - 1);
-                       ADVANCE(1);
-               }
-               strncpy(buffer, ", ", blen - 1);
-               ADVANCE(2);
-               written = _decodeRegisterList(info->op1.immediate, buffer, blen);
-               ADVANCE(written);
-               if (info->memory.format & ARM_MEMORY_SPSR_SWAP) {
-                       strncpy(buffer, "^", blen - 1);
-                       ADVANCE(1);
-               }
-               break;
-       case ARM_MN_B:
-       case ARM_MN_BL:
-               if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
-                       written = _decodePCRelative(info->op1.immediate, pc, buffer, blen);
-                       ADVANCE(written);
-               }
-               break;
-       default:
-               if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
-                       written = snprintf(buffer, blen - 1, "#%i", info->op1.immediate);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_MEMORY_1) {
-                       written = _decodeMemory(info->memory, pc, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_REGISTER_1) {
-                       written = _decodeRegister(info->op1.reg, buffer, blen);
-                       ADVANCE(written);
-                       if (info->op1.reg > ARM_PC) {
-                               written = _decodePSR(info->op1.psrBits, buffer, blen);
-                               ADVANCE(written);
-                       }
-               }
-               if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_1) {
-                       written = _decodeShift(info->op1, true, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_1) {
-                       written = _decodeShift(info->op1, false, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_2) {
-                       strncpy(buffer, ", ", blen);
-                       ADVANCE(2);
-               }
-               if (info->operandFormat & ARM_OPERAND_IMMEDIATE_2) {
-                       written = snprintf(buffer, blen - 1, "#%i", info->op2.immediate);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_MEMORY_2) {
-                       written = _decodeMemory(info->memory, pc, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_REGISTER_2) {
-                       written = _decodeRegister(info->op2.reg, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_2) {
-                       written = _decodeShift(info->op2, true, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_2) {
-                       written = _decodeShift(info->op2, false, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_3) {
-                       strncpy(buffer, ", ", blen - 1);
-                       ADVANCE(2);
-               }
-               if (info->operandFormat & ARM_OPERAND_IMMEDIATE_3) {
-                       written = snprintf(buffer, blen - 1, "#%i", info->op3.immediate);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_MEMORY_3) {
-                       written = _decodeMemory(info->memory, pc, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_REGISTER_3) {
-                       written = _decodeRegister(info->op3.reg, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_3) {
-                       written = _decodeShift(info->op3, true, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_3) {
-                       written = _decodeShift(info->op3, false, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_4) {
-                       strncpy(buffer, ", ", blen - 1);
-                       ADVANCE(2);
-               }
-               if (info->operandFormat & ARM_OPERAND_IMMEDIATE_4) {
-                       written = snprintf(buffer, blen - 1, "#%i", info->op4.immediate);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_MEMORY_4) {
-                       written = _decodeMemory(info->memory, pc, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_REGISTER_4) {
-                       written = _decodeRegister(info->op4.reg, buffer, blen);
-                       ADVANCE(written);
-               }
-               if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_4) {
-                       written = _decodeShift(info->op4, true, buffer, blen);
-                       ADVANCE(written);
-               } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_4) {
-                       written = _decodeShift(info->op4, false, buffer, blen);
-                       ADVANCE(written);
-               }
-               break;
-       }
-       buffer[blen - 1] = '\0';
-       return total;
+  switch (info->mnemonic) {
+  case ARM_MN_LDM:
+  case ARM_MN_STM:
+    written = _decodeRegister(info->memory.baseReg, buffer, blen);
+    ADVANCE(written);
+    if (info->memory.format & ARM_MEMORY_WRITEBACK) {
+      strncpy(buffer, "!", blen - 1);
+      ADVANCE(1);
+    }
+    strncpy(buffer, ", ", blen - 1);
+    ADVANCE(2);
+    written = _decodeRegisterList(info->op1.immediate, buffer, blen);
+    ADVANCE(written);
+    if (info->memory.format & ARM_MEMORY_SPSR_SWAP) {
+      strncpy(buffer, "^", blen - 1);
+      ADVANCE(1);
+    }
+    break;
+  case ARM_MN_B:
+  case ARM_MN_BL:
+    if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
+      written = _decodePCRelative(info->op1.immediate, pc, buffer, blen);
+      ADVANCE(written);
+    }
+    break;
+  default:
+    if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
+      written = snprintf(buffer, blen - 1, "#%i", info->op1.immediate);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_MEMORY_1) {
+      written = _decodeMemory(info->memory, pc, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_REGISTER_1) {
+      written = _decodeRegister(info->op1.reg, buffer, blen);
+      ADVANCE(written);
+      if (info->op1.reg > ARM_PC) {
+        written = _decodePSR(info->op1.psrBits, buffer, blen);
+        ADVANCE(written);
+      }
+    }
+    if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_1) {
+      written = _decodeShift(info->op1, true, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_1) {
+      written = _decodeShift(info->op1, false, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_2) {
+      strncpy(buffer, ", ", blen);
+      ADVANCE(2);
+    }
+    if (info->operandFormat & ARM_OPERAND_IMMEDIATE_2) {
+      written = snprintf(buffer, blen - 1, "#%i", info->op2.immediate);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_MEMORY_2) {
+      written = _decodeMemory(info->memory, pc, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_REGISTER_2) {
+      written = _decodeRegister(info->op2.reg, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_2) {
+      written = _decodeShift(info->op2, true, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_2) {
+      written = _decodeShift(info->op2, false, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_3) {
+      strncpy(buffer, ", ", blen - 1);
+      ADVANCE(2);
+    }
+    if (info->operandFormat & ARM_OPERAND_IMMEDIATE_3) {
+      written = snprintf(buffer, blen - 1, "#%i", info->op3.immediate);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_MEMORY_3) {
+      written = _decodeMemory(info->memory, pc, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_REGISTER_3) {
+      written = _decodeRegister(info->op3.reg, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_3) {
+      written = _decodeShift(info->op3, true, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_3) {
+      written = _decodeShift(info->op3, false, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_4) {
+      strncpy(buffer, ", ", blen - 1);
+      ADVANCE(2);
+    }
+    if (info->operandFormat & ARM_OPERAND_IMMEDIATE_4) {
+      written = snprintf(buffer, blen - 1, "#%i", info->op4.immediate);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_MEMORY_4) {
+      written = _decodeMemory(info->memory, pc, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_REGISTER_4) {
+      written = _decodeRegister(info->op4.reg, buffer, blen);
+      ADVANCE(written);
+    }
+    if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_4) {
+      written = _decodeShift(info->op4, true, buffer, blen);
+      ADVANCE(written);
+    } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_4) {
+      written = _decodeShift(info->op4, false, buffer, blen);
+      ADVANCE(written);
+    }
+    break;
+  }
+  buffer[blen - 1] = '\0';
+  return total;
 }
index 31515e1efe114ae633edae9102521419f1e0a37d..38c19745d3e0b7ba03e38b59b0440803cd292819 100644 (file)
@@ -16,54 +16,56 @@ CXX_GUARD_START
 // Bit 3: the destination of this operand is affected by this opcode
 // Bit 4: this operand is shifted by a register
 // Bit 5: this operand is shifted by an immediate
-#define ARM_OPERAND_NONE                0x00000000
-#define ARM_OPERAND_REGISTER_1          0x00000001
-#define ARM_OPERAND_IMMEDIATE_1         0x00000002
-#define ARM_OPERAND_MEMORY_1            0x00000004
-#define ARM_OPERAND_AFFECTED_1          0x00000008
-#define ARM_OPERAND_SHIFT_REGISTER_1    0x00000010
-#define ARM_OPERAND_SHIFT_IMMEDIATE_1   0x00000020
-#define ARM_OPERAND_1                   0x000000FF
-
-#define ARM_OPERAND_REGISTER_2          0x00000100
-#define ARM_OPERAND_IMMEDIATE_2         0x00000200
-#define ARM_OPERAND_MEMORY_2            0x00000400
-#define ARM_OPERAND_AFFECTED_2          0x00000800
-#define ARM_OPERAND_SHIFT_REGISTER_2    0x00001000
-#define ARM_OPERAND_SHIFT_IMMEDIATE_2   0x00002000
-#define ARM_OPERAND_2                   0x0000FF00
-
-#define ARM_OPERAND_REGISTER_3          0x00010000
-#define ARM_OPERAND_IMMEDIATE_3         0x00020000
-#define ARM_OPERAND_MEMORY_3            0x00040000
-#define ARM_OPERAND_AFFECTED_3          0x00080000
-#define ARM_OPERAND_SHIFT_REGISTER_3    0x00100000
-#define ARM_OPERAND_SHIFT_IMMEDIATE_3   0x00200000
-#define ARM_OPERAND_3                   0x00FF0000
-
-#define ARM_OPERAND_REGISTER_4          0x01000000
-#define ARM_OPERAND_IMMEDIATE_4         0x02000000
-#define ARM_OPERAND_MEMORY_4            0x04000000
-#define ARM_OPERAND_AFFECTED_4          0x08000000
-#define ARM_OPERAND_SHIFT_REGISTER_4    0x10000000
-#define ARM_OPERAND_SHIFT_IMMEDIATE_4   0x20000000
-#define ARM_OPERAND_4                   0xFF000000
-
-#define ARM_OPERAND_MEMORY (ARM_OPERAND_MEMORY_1 | ARM_OPERAND_MEMORY_2 | ARM_OPERAND_MEMORY_3 | ARM_OPERAND_MEMORY_4)
-
-#define ARM_MEMORY_REGISTER_BASE     0x0001
-#define ARM_MEMORY_IMMEDIATE_OFFSET  0x0002
-#define ARM_MEMORY_REGISTER_OFFSET   0x0004
-#define ARM_MEMORY_SHIFTED_OFFSET    0x0008
-#define ARM_MEMORY_PRE_INCREMENT     0x0010
-#define ARM_MEMORY_POST_INCREMENT    0x0020
-#define ARM_MEMORY_OFFSET_SUBTRACT   0x0040
-#define ARM_MEMORY_WRITEBACK         0x0080
-#define ARM_MEMORY_DECREMENT_AFTER   0x0000
-#define ARM_MEMORY_INCREMENT_AFTER   0x0100
-#define ARM_MEMORY_DECREMENT_BEFORE  0x0200
-#define ARM_MEMORY_INCREMENT_BEFORE  0x0300
-#define ARM_MEMORY_SPSR_SWAP         0x0400
+#define ARM_OPERAND_NONE 0x00000000
+#define ARM_OPERAND_REGISTER_1 0x00000001
+#define ARM_OPERAND_IMMEDIATE_1 0x00000002
+#define ARM_OPERAND_MEMORY_1 0x00000004
+#define ARM_OPERAND_AFFECTED_1 0x00000008
+#define ARM_OPERAND_SHIFT_REGISTER_1 0x00000010
+#define ARM_OPERAND_SHIFT_IMMEDIATE_1 0x00000020
+#define ARM_OPERAND_1 0x000000FF
+
+#define ARM_OPERAND_REGISTER_2 0x00000100
+#define ARM_OPERAND_IMMEDIATE_2 0x00000200
+#define ARM_OPERAND_MEMORY_2 0x00000400
+#define ARM_OPERAND_AFFECTED_2 0x00000800
+#define ARM_OPERAND_SHIFT_REGISTER_2 0x00001000
+#define ARM_OPERAND_SHIFT_IMMEDIATE_2 0x00002000
+#define ARM_OPERAND_2 0x0000FF00
+
+#define ARM_OPERAND_REGISTER_3 0x00010000
+#define ARM_OPERAND_IMMEDIATE_3 0x00020000
+#define ARM_OPERAND_MEMORY_3 0x00040000
+#define ARM_OPERAND_AFFECTED_3 0x00080000
+#define ARM_OPERAND_SHIFT_REGISTER_3 0x00100000
+#define ARM_OPERAND_SHIFT_IMMEDIATE_3 0x00200000
+#define ARM_OPERAND_3 0x00FF0000
+
+#define ARM_OPERAND_REGISTER_4 0x01000000
+#define ARM_OPERAND_IMMEDIATE_4 0x02000000
+#define ARM_OPERAND_MEMORY_4 0x04000000
+#define ARM_OPERAND_AFFECTED_4 0x08000000
+#define ARM_OPERAND_SHIFT_REGISTER_4 0x10000000
+#define ARM_OPERAND_SHIFT_IMMEDIATE_4 0x20000000
+#define ARM_OPERAND_4 0xFF000000
+
+#define ARM_OPERAND_MEMORY                                                     \
+  (ARM_OPERAND_MEMORY_1 | ARM_OPERAND_MEMORY_2 | ARM_OPERAND_MEMORY_3 |        \
+   ARM_OPERAND_MEMORY_4)
+
+#define ARM_MEMORY_REGISTER_BASE 0x0001
+#define ARM_MEMORY_IMMEDIATE_OFFSET 0x0002
+#define ARM_MEMORY_REGISTER_OFFSET 0x0004
+#define ARM_MEMORY_SHIFTED_OFFSET 0x0008
+#define ARM_MEMORY_PRE_INCREMENT 0x0010
+#define ARM_MEMORY_POST_INCREMENT 0x0020
+#define ARM_MEMORY_OFFSET_SUBTRACT 0x0040
+#define ARM_MEMORY_WRITEBACK 0x0080
+#define ARM_MEMORY_DECREMENT_AFTER 0x0000
+#define ARM_MEMORY_INCREMENT_AFTER 0x0100
+#define ARM_MEMORY_DECREMENT_BEFORE 0x0200
+#define ARM_MEMORY_INCREMENT_BEFORE 0x0300
+#define ARM_MEMORY_SPSR_SWAP 0x0400
 
 #define ARM_PSR_C 1
 #define ARM_PSR_X 2
@@ -74,146 +76,141 @@ CXX_GUARD_START
 #define MEMORY_FORMAT_TO_DIRECTION(F) (((F) >> 8) & 0x3)
 
 enum ARMCondition {
-       ARM_CONDITION_EQ = 0x0,
-       ARM_CONDITION_NE = 0x1,
-       ARM_CONDITION_CS = 0x2,
-       ARM_CONDITION_CC = 0x3,
-       ARM_CONDITION_MI = 0x4,
-       ARM_CONDITION_PL = 0x5,
-       ARM_CONDITION_VS = 0x6,
-       ARM_CONDITION_VC = 0x7,
-       ARM_CONDITION_HI = 0x8,
-       ARM_CONDITION_LS = 0x9,
-       ARM_CONDITION_GE = 0xA,
-       ARM_CONDITION_LT = 0xB,
-       ARM_CONDITION_GT = 0xC,
-       ARM_CONDITION_LE = 0xD,
-       ARM_CONDITION_AL = 0xE,
-       ARM_CONDITION_NV = 0xF
+  ARM_CONDITION_EQ = 0x0,
+  ARM_CONDITION_NE = 0x1,
+  ARM_CONDITION_CS = 0x2,
+  ARM_CONDITION_CC = 0x3,
+  ARM_CONDITION_MI = 0x4,
+  ARM_CONDITION_PL = 0x5,
+  ARM_CONDITION_VS = 0x6,
+  ARM_CONDITION_VC = 0x7,
+  ARM_CONDITION_HI = 0x8,
+  ARM_CONDITION_LS = 0x9,
+  ARM_CONDITION_GE = 0xA,
+  ARM_CONDITION_LT = 0xB,
+  ARM_CONDITION_GT = 0xC,
+  ARM_CONDITION_LE = 0xD,
+  ARM_CONDITION_AL = 0xE,
+  ARM_CONDITION_NV = 0xF
 };
 
 enum ARMShifterOperation {
-       ARM_SHIFT_NONE = 0,
-       ARM_SHIFT_LSL,
-       ARM_SHIFT_LSR,
-       ARM_SHIFT_ASR,
-       ARM_SHIFT_ROR,
-       ARM_SHIFT_RRX
+  ARM_SHIFT_NONE = 0,
+  ARM_SHIFT_LSL,
+  ARM_SHIFT_LSR,
+  ARM_SHIFT_ASR,
+  ARM_SHIFT_ROR,
+  ARM_SHIFT_RRX
 };
 
 union ARMOperand {
-       struct {
-               uint8_t reg;
-               uint8_t shifterOp;
-               union {
-                       uint8_t shifterReg;
-                       uint8_t shifterImm;
-                       uint8_t psrBits;
-               };
-       };
-       int32_t immediate;
+  struct {
+    uint8_t reg;
+    uint8_t shifterOp;
+    union {
+      uint8_t shifterReg;
+      uint8_t shifterImm;
+      uint8_t psrBits;
+    };
+  };
+  int32_t immediate;
 };
 
 enum ARMMemoryAccessType {
-       ARM_ACCESS_WORD = 4,
-       ARM_ACCESS_HALFWORD = 2,
-       ARM_ACCESS_SIGNED_HALFWORD = 10,
-       ARM_ACCESS_BYTE = 1,
-       ARM_ACCESS_SIGNED_BYTE = 9,
-       ARM_ACCESS_TRANSLATED_WORD = 20,
-       ARM_ACCESS_TRANSLATED_BYTE = 17
+  ARM_ACCESS_WORD = 4,
+  ARM_ACCESS_HALFWORD = 2,
+  ARM_ACCESS_SIGNED_HALFWORD = 10,
+  ARM_ACCESS_BYTE = 1,
+  ARM_ACCESS_SIGNED_BYTE = 9,
+  ARM_ACCESS_TRANSLATED_WORD = 20,
+  ARM_ACCESS_TRANSLATED_BYTE = 17
 };
 
 enum ARMBranchType {
-       ARM_BRANCH_NONE = 0,
-       ARM_BRANCH = 1,
-       ARM_BRANCH_INDIRECT = 2,
-       ARM_BRANCH_LINKED = 4
+  ARM_BRANCH_NONE = 0,
+  ARM_BRANCH = 1,
+  ARM_BRANCH_INDIRECT = 2,
+  ARM_BRANCH_LINKED = 4
 };
 
 struct ARMMemoryAccess {
-       uint8_t baseReg;
-       uint8_t width;
-       uint16_t format;
-       union ARMOperand offset;
+  uint8_t baseReg;
+  uint8_t width;
+  uint16_t format;
+  union ARMOperand offset;
 };
 
 enum ARMMnemonic {
-       ARM_MN_ILL = 0,
-       ARM_MN_ADC,
-       ARM_MN_ADD,
-       ARM_MN_AND,
-       ARM_MN_ASR,
-       ARM_MN_B,
-       ARM_MN_BIC,
-       ARM_MN_BKPT,
-       ARM_MN_BL,
-       ARM_MN_BX,
-       ARM_MN_CMN,
-       ARM_MN_CMP,
-       ARM_MN_EOR,
-       ARM_MN_LDM,
-       ARM_MN_LDR,
-       ARM_MN_LSL,
-       ARM_MN_LSR,
-       ARM_MN_MLA,
-       ARM_MN_MOV,
-       ARM_MN_MRS,
-       ARM_MN_MSR,
-       ARM_MN_MUL,
-       ARM_MN_MVN,
-       ARM_MN_NEG,
-       ARM_MN_ORR,
-       ARM_MN_ROR,
-       ARM_MN_RSB,
-       ARM_MN_RSC,
-       ARM_MN_SBC,
-       ARM_MN_SMLAL,
-       ARM_MN_SMULL,
-       ARM_MN_STM,
-       ARM_MN_STR,
-       ARM_MN_SUB,
-       ARM_MN_SWI,
-       ARM_MN_SWP,
-       ARM_MN_TEQ,
-       ARM_MN_TST,
-       ARM_MN_UMLAL,
-       ARM_MN_UMULL,
-
-       ARM_MN_MAX
+  ARM_MN_ILL = 0,
+  ARM_MN_ADC,
+  ARM_MN_ADD,
+  ARM_MN_AND,
+  ARM_MN_ASR,
+  ARM_MN_B,
+  ARM_MN_BIC,
+  ARM_MN_BKPT,
+  ARM_MN_BL,
+  ARM_MN_BX,
+  ARM_MN_CMN,
+  ARM_MN_CMP,
+  ARM_MN_EOR,
+  ARM_MN_LDM,
+  ARM_MN_LDR,
+  ARM_MN_LSL,
+  ARM_MN_LSR,
+  ARM_MN_MLA,
+  ARM_MN_MOV,
+  ARM_MN_MRS,
+  ARM_MN_MSR,
+  ARM_MN_MUL,
+  ARM_MN_MVN,
+  ARM_MN_NEG,
+  ARM_MN_ORR,
+  ARM_MN_ROR,
+  ARM_MN_RSB,
+  ARM_MN_RSC,
+  ARM_MN_SBC,
+  ARM_MN_SMLAL,
+  ARM_MN_SMULL,
+  ARM_MN_STM,
+  ARM_MN_STR,
+  ARM_MN_SUB,
+  ARM_MN_SWI,
+  ARM_MN_SWP,
+  ARM_MN_TEQ,
+  ARM_MN_TST,
+  ARM_MN_UMLAL,
+  ARM_MN_UMULL,
+
+  ARM_MN_MAX
 };
 
-enum {
-       ARM_SP = 13,
-       ARM_LR = 14,
-       ARM_PC = 15,
-       ARM_CPSR = 16,
-       ARM_SPSR = 17
-};
+enum { ARM_SP = 13, ARM_LR = 14, ARM_PC = 15, ARM_CPSR = 16, ARM_SPSR = 17 };
 
 struct ARMInstructionInfo {
-       uint32_t opcode;
-       union ARMOperand op1;
-       union ARMOperand op2;
-       union ARMOperand op3;
-       union ARMOperand op4;
-       struct ARMMemoryAccess memory;
-       int operandFormat;
-       bool traps : 1;
-       bool affectsCPSR : 1;
-       unsigned branchType : 3;
-       unsigned condition : 4;
-       unsigned mnemonic : 6;
-       unsigned iCycles : 3;
-       unsigned cCycles : 4;
-       unsigned sInstructionCycles : 4;
-       unsigned nInstructionCycles : 4;
-       unsigned sDataCycles : 10;
-       unsigned nDataCycles : 10;
+  uint32_t opcode;
+  union ARMOperand op1;
+  union ARMOperand op2;
+  union ARMOperand op3;
+  union ARMOperand op4;
+  struct ARMMemoryAccess memory;
+  int operandFormat;
+  bool traps : 1;
+  bool affectsCPSR : 1;
+  unsigned branchType : 3;
+  unsigned condition : 4;
+  unsigned mnemonic : 6;
+  unsigned iCycles : 3;
+  unsigned cCycles : 4;
+  unsigned sInstructionCycles : 4;
+  unsigned nInstructionCycles : 4;
+  unsigned sDataCycles : 10;
+  unsigned nDataCycles : 10;
 };
 
 void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info);
-int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, int blen);
+int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer,
+                   int blen);
 
 CXX_GUARD_END
 
index e99a1b7eed9de8aa7b2321b7d77b47bef9fd443b..e979228d9bd576f1afebcd3bdde439078b31f79d 100644 (file)
 
 #include "emitter-inlines.h"
 
-#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \
-       EMITTER ## NAME
+#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) EMITTER##NAME
 
-#define DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ALU) \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I)), \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))
+#define DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ALU)                          \
+  DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU##I)),                              \
+      DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU##I))
 
-#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, EX2), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, EX3), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, EX4)
+#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4)                \
+  DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSL),                                 \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSL),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ASR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ASR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ROR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ROR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSL),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, EX1),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_LSR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, EX2),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ASR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, EX3),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ALU##_ROR),                             \
+      DECLARE_INSTRUCTION_ARM(EMITTER, EX4)
 
-#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W)), \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W))
+#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W)         \
+  DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME##I##P##U##W)),                    \
+      DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME##I##P##U##W))
 
-#define DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, NAME, P, U, W) \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL)
+#define DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, NAME, P, U, W)                   \
+  DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_LSL_##P##U##W),                      \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_LSR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_ASR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_ROR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_LSL_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_LSR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_ASR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, NAME##_ROR_##P##U##W),                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL)
 
-#define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W) \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W)), \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W))
+#define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W)          \
+  DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME##MODE##W)),                       \
+      DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME##MODE##W))
 
-#define DECLARE_ARM_BRANCH_BLOCK(EMITTER, NAME) \
-       DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
+#define DECLARE_ARM_BRANCH_BLOCK(EMITTER, NAME)                                \
+  DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
 
 // TODO: Support coprocessors
-#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, N, W) \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \
-       DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
+#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, N, W)    \
+  DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)),                                \
+      DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
 
-#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \
-       DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))))
+#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2)                   \
+  DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1),              \
+                         DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))))
 
-#define DECLARE_ARM_SWI_BLOCK(EMITTER) \
-       DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))
+#define DECLARE_ARM_SWI_BLOCK(EMITTER)                                         \
+  DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))
 
-#define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, BX), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \
-       DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \
-       DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \
-       DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \
-       DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \
-       DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
-       DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
-       DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
-       DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \
-       DECLARE_ARM_SWI_BLOCK(EMITTER)
+#define DECLARE_ARM_EMITTER_BLOCK(EMITTER)                                     \
+  DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL),                    \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH),          \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL),                \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH),          \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL),               \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI),        \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL),               \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI),        \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL),             \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU),     \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL),             \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU),     \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL),            \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU),  \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL),            \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU),  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, MRS),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, SWP),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, STRHP),                                 \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP),         \
+      DECLARE_INSTRUCTION_ARM(EMITTER, MSR),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, BX),                                    \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, BKPT),                                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW),                                \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW),      \
+      DECLARE_INSTRUCTION_ARM(EMITTER, MRSR),                                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, SWPB),                                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP),                                \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP),      \
+      DECLARE_INSTRUCTION_ARM(EMITTER, MSRR),                                  \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW),                               \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_INSTRUCTION_ARM(EMITTER, ILL),                                   \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW),   \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL),            \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU),  \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL),           \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW,          \
+                            LDRSHPUW),                                         \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL),           \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU,          \
+                            LDRSHIPU),                                         \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL),          \
+      DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW,        \
+                            LDRSHIPUW),                                        \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS),                          \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN),                           \
+      DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS),                          \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ),              \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ),              \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ),             \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ),            \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ),           \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W),          \
+      DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W),          \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ),                        \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ),                        \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ),                       \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ),                      \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ),                     \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W),                    \
+      DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W),                    \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ),               \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ),              \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W),             \
+      DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W),             \
+      DECLARE_ARM_BRANCH_BLOCK(EMITTER, B),                                    \
+      DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL),                                   \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ),          \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ),          \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ),         \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W),      \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W),      \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ),        \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ),       \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W),      \
+      DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W),      \
+      DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR),                        \
+      DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC),                        \
+      DECLARE_ARM_SWI_BLOCK(EMITTER)
 
 #endif
index 38bab70bddf08f6160461ab73a1649a2bdbd256f..74faa98c2d6809d04acc860a33666bcfe81fb619 100644 (file)
@@ -6,27 +6,14 @@
 #ifndef EMITTER_INLINES_H
 #define EMITTER_INLINES_H
 
-#define DO_4(DIRECTIVE) \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE
+#define DO_4(DIRECTIVE) DIRECTIVE, DIRECTIVE, DIRECTIVE, DIRECTIVE
 
-#define DO_8(DIRECTIVE) \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE, \
-       DIRECTIVE
+#define DO_8(DIRECTIVE)                                                        \
+  DIRECTIVE, DIRECTIVE, DIRECTIVE, DIRECTIVE, DIRECTIVE, DIRECTIVE, DIRECTIVE, \
+      DIRECTIVE
 
-#define DO_256(DIRECTIVE) \
-       DO_4(DO_8(DO_8(DIRECTIVE)))
+#define DO_256(DIRECTIVE) DO_4(DO_8(DO_8(DIRECTIVE)))
 
-#define DO_INTERLACE(LEFT, RIGHT) \
-       LEFT, \
-       RIGHT
+#define DO_INTERLACE(LEFT, RIGHT) LEFT, RIGHT
 
 #endif
index ae35d9d8434642a142d2f9c6ca6ad6bbed9ddee7..ceb001817c975139a7a93bb5368fe24cebf7c8b8 100644 (file)
 #include <unordered_set>
 
 enum EpocKey {
-       EStdKeyDial = 161,
-       EStdKeyOff = 160,
-       EStdKeyHelp = 159,
-       EStdKeyDictaphoneRecord = 158,
-       EStdKeyDictaphoneStop = 157,
-       EStdKeyDictaphonePlay = 156,
-       EStdKeySliderUp = 155,
-       EStdKeySliderDown = 154,
-       EStdKeyDecContrast = 153,
-       EStdKeyIncContrast = 152,
-       EStdKeyBacklightToggle = 151,
-       EStdKeyBacklightOff = 150,
-       EStdKeyBacklightOn = 149,
-       EStdKeyMenu = 148,
-       EStdKeyNkpFullStop = 147,
-       EStdKeyNkp0 = 146,
-       EStdKeyNkp9 = 145,
-       EStdKeyNkp8 = 144,
-       EStdKeyNkp7 = 143,
-       EStdKeyNkp6 = 142,
-       EStdKeyNkp5 = 141,
-       EStdKeyNkp4 = 140,
-       EStdKeyNkp3 = 139,
-       EStdKeyNkp2 = 138,
-       EStdKeyNkp1 = 137,
-       EStdKeyNkpEnter = 136,
-       EStdKeyNkpPlus = 135,
-       EStdKeyNkpMinus = 134,
-       EStdKeyNkpAsterisk = 133,
-       EStdKeyNkpForwardSlash = 132,
-       EStdKeyEquals = 131,
-       EStdKeyMinus = 130,
-       EStdKeySquareBracketRight = 129,
-       EStdKeySquareBracketLeft = 128,
-       EStdKeyHash = 127,
-       EStdKeySingleQuote = 126,
-       EStdKeySemiColon = 125,
-       EStdKeyBackSlash = 124,
-       EStdKeyForwardSlash = 123,
-       EStdKeyFullStop = 122,
-       EStdKeyComma = 121,
-       EStdKeyXXX = 120,
-       EStdKeyF24 = 119,
-       EStdKeyF23 = 118,
-       EStdKeyF22 = 117,
-       EStdKeyF21 = 116,
-       EStdKeyF20 = 115,
-       EStdKeyF19 = 114,
-       EStdKeyF18 = 113,
-       EStdKeyF17 = 112,
-       EStdKeyF16 = 111,
-       EStdKeyF15 = 110,
-       EStdKeyF14 = 109,
-       EStdKeyF13 = 108,
-       EStdKeyF12 = 107,
-       EStdKeyF11 = 106,
-       EStdKeyF10 = 105,
-       EStdKeyF9 = 104,
-       EStdKeyF8 = 103,
-       EStdKeyF7 = 102,
-       EStdKeyF6 = 101,
-       EStdKeyF5 = 100,
-       EStdKeyF4 = 99,
-       EStdKeyF3 = 98,
-       EStdKeyF2 = 97,
-       EStdKeyF1 = 96,
-       EStdKeyScrollLock = 28,
-       EStdKeyNumLock = 27,
-       EStdKeyCapsLock = 26,
-       EStdKeyRightFunc = 25,
-       EStdKeyLeftFunc = 24,
-       EStdKeyRightCtrl = 23,
-       EStdKeyLeftCtrl = 22,
-       EStdKeyRightAlt = 21,
-       EStdKeyLeftAlt = 20,
-       EStdKeyRightShift = 19,
-       EStdKeyLeftShift = 18,
-       EStdKeyDownArrow = 17,
-       EStdKeyUpArrow = 16,
-       EStdKeyRightArrow = 15,
-       EStdKeyLeftArrow = 14,
-       EStdKeyDelete = 13,
-       EStdKeyInsert = 12,
-       EStdKeyPageDown = 11,
-       EStdKeyPageUp = 10,
-       EStdKeyEnd = 9,
-       EStdKeyHome = 8,
-       EStdKeyPause = 7,
-       EStdKeyPrintScreen = 6,
-       EStdKeySpace = 5,
-       EStdKeyEscape = 4,
-       EStdKeyEnter = 3,
-       EStdKeyTab = 2,
-       EStdKeyBackspace = 1,
-       EStdKeyNull = 0
+  EStdKeyDial = 161,
+  EStdKeyOff = 160,
+  EStdKeyHelp = 159,
+  EStdKeyDictaphoneRecord = 158,
+  EStdKeyDictaphoneStop = 157,
+  EStdKeyDictaphonePlay = 156,
+  EStdKeySliderUp = 155,
+  EStdKeySliderDown = 154,
+  EStdKeyDecContrast = 153,
+  EStdKeyIncContrast = 152,
+  EStdKeyBacklightToggle = 151,
+  EStdKeyBacklightOff = 150,
+  EStdKeyBacklightOn = 149,
+  EStdKeyMenu = 148,
+  EStdKeyNkpFullStop = 147,
+  EStdKeyNkp0 = 146,
+  EStdKeyNkp9 = 145,
+  EStdKeyNkp8 = 144,
+  EStdKeyNkp7 = 143,
+  EStdKeyNkp6 = 142,
+  EStdKeyNkp5 = 141,
+  EStdKeyNkp4 = 140,
+  EStdKeyNkp3 = 139,
+  EStdKeyNkp2 = 138,
+  EStdKeyNkp1 = 137,
+  EStdKeyNkpEnter = 136,
+  EStdKeyNkpPlus = 135,
+  EStdKeyNkpMinus = 134,
+  EStdKeyNkpAsterisk = 133,
+  EStdKeyNkpForwardSlash = 132,
+  EStdKeyEquals = 131,
+  EStdKeyMinus = 130,
+  EStdKeySquareBracketRight = 129,
+  EStdKeySquareBracketLeft = 128,
+  EStdKeyHash = 127,
+  EStdKeySingleQuote = 126,
+  EStdKeySemiColon = 125,
+  EStdKeyBackSlash = 124,
+  EStdKeyForwardSlash = 123,
+  EStdKeyFullStop = 122,
+  EStdKeyComma = 121,
+  EStdKeyXXX = 120,
+  EStdKeyF24 = 119,
+  EStdKeyF23 = 118,
+  EStdKeyF22 = 117,
+  EStdKeyF21 = 116,
+  EStdKeyF20 = 115,
+  EStdKeyF19 = 114,
+  EStdKeyF18 = 113,
+  EStdKeyF17 = 112,
+  EStdKeyF16 = 111,
+  EStdKeyF15 = 110,
+  EStdKeyF14 = 109,
+  EStdKeyF13 = 108,
+  EStdKeyF12 = 107,
+  EStdKeyF11 = 106,
+  EStdKeyF10 = 105,
+  EStdKeyF9 = 104,
+  EStdKeyF8 = 103,
+  EStdKeyF7 = 102,
+  EStdKeyF6 = 101,
+  EStdKeyF5 = 100,
+  EStdKeyF4 = 99,
+  EStdKeyF3 = 98,
+  EStdKeyF2 = 97,
+  EStdKeyF1 = 96,
+  EStdKeyScrollLock = 28,
+  EStdKeyNumLock = 27,
+  EStdKeyCapsLock = 26,
+  EStdKeyRightFunc = 25,
+  EStdKeyLeftFunc = 24,
+  EStdKeyRightCtrl = 23,
+  EStdKeyLeftCtrl = 22,
+  EStdKeyRightAlt = 21,
+  EStdKeyLeftAlt = 20,
+  EStdKeyRightShift = 19,
+  EStdKeyLeftShift = 18,
+  EStdKeyDownArrow = 17,
+  EStdKeyUpArrow = 16,
+  EStdKeyRightArrow = 15,
+  EStdKeyLeftArrow = 14,
+  EStdKeyDelete = 13,
+  EStdKeyInsert = 12,
+  EStdKeyPageDown = 11,
+  EStdKeyPageUp = 10,
+  EStdKeyEnd = 9,
+  EStdKeyHome = 8,
+  EStdKeyPause = 7,
+  EStdKeyPrintScreen = 6,
+  EStdKeySpace = 5,
+  EStdKeyEscape = 4,
+  EStdKeyEnter = 3,
+  EStdKeyTab = 2,
+  EStdKeyBackspace = 1,
+  EStdKeyNull = 0
 };
 
-class EmuBase : public ARM710
-{
+class EmuBase : public ARM710 {
 protected:
 #ifndef __EMSCRIPTEN__
-       std::unordered_set<uint32_t> _breakpoints;
+  std::unordered_set<uint32_t> _breakpoints;
 #endif
-       int64_t passedCycles = 0;
-       int64_t nextTickAt = 0;
-       uint8_t readKeyboard(int kScan);
+  int64_t passedCycles = 0;
+  int64_t nextTickAt = 0;
+  uint8_t readKeyboard(int kScan);
 
 public:
-       EmuBase(bool isTVersion) : ARM710(isTVersion) { }
+  EmuBase(bool isTVersion) : ARM710(isTVersion) {}
 
-       virtual uint8_t *getROMBuffer() = 0;
-       virtual size_t getROMSize() = 0;
-       virtual void loadROM(uint8_t *buffer, size_t size) = 0;
-       virtual void executeUntil(int64_t cycles) = 0;
-       virtual int32_t getClockSpeed() const = 0;
-       virtual const char *getDeviceName() const = 0;
-       virtual int getDigitiserWidth() const = 0;
-       virtual int getDigitiserHeight() const = 0;
-       virtual int getLCDOffsetX() const = 0;
-       virtual int getLCDOffsetY() const = 0;
-       virtual int getLCDWidth() const = 0;
-       virtual int getLCDHeight() const = 0;
-       virtual void readLCDIntoBuffer(uint8_t **lines, bool is32BitOutput) const = 0;
-       virtual void setKeyboardKey(EpocKey key, bool value) = 0;
-       virtual void updateTouchInput(int32_t x, int32_t y, bool down) = 0;
+  virtual uint8_t* getROMBuffer() = 0;
+  virtual size_t getROMSize() = 0;
+  virtual void loadROM(uint8_t* buffer, size_t size) = 0;
+  virtual void executeUntil(int64_t cycles) = 0;
+  virtual int32_t getClockSpeed() const = 0;
+  virtual const char* getDeviceName() const = 0;
+  virtual int getDigitiserWidth() const = 0;
+  virtual int getDigitiserHeight() const = 0;
+  virtual int getLCDOffsetX() const = 0;
+  virtual int getLCDOffsetY() const = 0;
+  virtual int getLCDWidth() const = 0;
+  virtual int getLCDHeight() const = 0;
+  virtual void readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const = 0;
+  virtual void setKeyboardKey(EpocKey key, bool value) = 0;
+  virtual void updateTouchInput(int32_t x, int32_t y, bool down) = 0;
 
 #ifndef __EMSCRIPTEN__
-       std::unordered_set<uint32_t> &breakpoints() { return _breakpoints; }
+  std::unordered_set<uint32_t>& breakpoints() { return _breakpoints; }
 #endif
-       uint64_t currentCycles() const { return passedCycles; }
+  uint64_t currentCycles() const { return passedCycles; }
 };
-
index 1e7c75be4749c437858fecdc6acd95e2262c0f62..94c7ae70894f82921c8595c6c596e819de023454 100644 (file)
 #include <string.h>
 
 enum EtnaReg {
-    regUnk0 = 0,
-    regUnk1 = 1,
-    regUartIntStatus = 2,
-    regUartIntMask = 3,
-    regUartBaudRateLo8 = 4,
-    regUartBaudRateHi4 = 5,
-    regPcCdIntStatus = 6,
-    regPcCdIntMask = 7,
-    regIntClear = 8,
-    regSktVarA0 = 9,
-    regSktVarA1 = 0xA,
-    regSktCtrl = 0xB,
-    regWake1 = 0xC,
-    regSktVarB0 = 0xD,
-    regSktVarB1 = 0xE,
-    regWake2 = 0xF
+  regUnk0 = 0,
+  regUnk1 = 1,
+  regUartIntStatus = 2,
+  regUartIntMask = 3,
+  regUartBaudRateLo8 = 4,
+  regUartBaudRateHi4 = 5,
+  regPcCdIntStatus = 6,
+  regPcCdIntMask = 7,
+  regIntClear = 8,
+  regSktVarA0 = 9,
+  regSktVarA1 = 0xA,
+  regSktCtrl = 0xB,
+  regWake1 = 0xC,
+  regSktVarB0 = 0xD,
+  regSktVarB1 = 0xE,
+  regWake2 = 0xF
 };
 
-static const char *nameReg(uint32_t reg) {
-    switch (reg) {
-    case regUnk0: return "unk0";
-    case regUnk1: return "unk1";
-    case regUartIntStatus: return "UartIntStatus";
-    case regUartIntMask: return "UartIntMask";
-    case regUartBaudRateLo8: return "UartBaudRateLo8";
-    case regUartBaudRateHi4: return "UartBaudRateHi4";
-    case regPcCdIntStatus: return "PcCdIntStatus";
-    case regPcCdIntMask: return "PcCdIntMask";
-    case regIntClear: return "IntClear";
-    case regSktVarA0: return "SktVarA0";
-    case regSktVarA1: return "SktVarA1";
-    case regSktCtrl: return "SktCtrl";
-    case regWake1: return "wake1";
-    case regSktVarB0: return "SktVarB0";
-    case regSktVarB1: return "SktVarB1";
-    case regWake2: return "wake2";
-    }
-    return nullptr;
+static const char* nameReg(uint32_t reg) {
+  switch (reg) {
+  case regUnk0:
+    return "unk0";
+  case regUnk1:
+    return "unk1";
+  case regUartIntStatus:
+    return "UartIntStatus";
+  case regUartIntMask:
+    return "UartIntMask";
+  case regUartBaudRateLo8:
+    return "UartBaudRateLo8";
+  case regUartBaudRateHi4:
+    return "UartBaudRateHi4";
+  case regPcCdIntStatus:
+    return "PcCdIntStatus";
+  case regPcCdIntMask:
+    return "PcCdIntMask";
+  case regIntClear:
+    return "IntClear";
+  case regSktVarA0:
+    return "SktVarA0";
+  case regSktVarA1:
+    return "SktVarA1";
+  case regSktCtrl:
+    return "SktCtrl";
+  case regWake1:
+    return "wake1";
+  case regSktVarB0:
+    return "SktVarB0";
+  case regSktVarB1:
+    return "SktVarB1";
+  case regWake2:
+    return "wake2";
+  }
+  return nullptr;
 }
 
-
-Etna::Etna(ARM710 *owner) {
-    this->owner = owner;
-
-    for (int i = 0; i < 0x80; i++)
-        prom[i] = 0;
-
-       // defaults expected by the touchscreen code
-       prom[0xA] = 20;
-       prom[0xB] = 20;
-       prom[0xC] = 20;
-       prom[0xD] = 30;
-
-    // some basic stuff to begin with
-    // set up the Psion's unique ID
-    prom[0x1B] = 0xDE;
-    prom[0x1A] = 0xAD;
-    prom[0x19] = 0xBE;
-    prom[0x18] = 0xEF;
-
-    // give ourselves a neat custom device name
-    const char *key = "PSIONPSIONPSION";
-    const char *name = "WindEmu!";
-    prom[0x28] = strlen(name);
-    if (prom[0x28] > 15)
-        prom[0x28] = 15;
-    for (int i = 0; i < prom[0x28]; i++)
-        prom[0x29 + i] = name[i] ^ key[i];
-
-    // calculate the checksum
-    uint8_t chk = 0;
-    for (int i = 0; i < 0x7F; i++)
-        chk ^= prom[i];
-
-    // EPOC is expecting 66
-       prom[0x7F] = chk ^ 66;
+Etna::Etna(ARM710* owner) {
+  this->owner = owner;
+
+  for (int i = 0; i < 0x80; i++)
+    prom[i] = 0;
+
+  // defaults expected by the touchscreen code
+  prom[0xA] = 20;
+  prom[0xB] = 20;
+  prom[0xC] = 20;
+  prom[0xD] = 30;
+
+  // some basic stuff to begin with
+  // set up the Psion's unique ID
+  prom[0x1B] = 0xDE;
+  prom[0x1A] = 0xAD;
+  prom[0x19] = 0xBE;
+  prom[0x18] = 0xEF;
+
+  // give ourselves a neat custom device name
+  const char* key = "PSIONPSIONPSION";
+  const char* name = "WindEmu!";
+  prom[0x28] = strlen(name);
+  if (prom[0x28] > 15)
+    prom[0x28] = 15;
+  for (int i = 0; i < prom[0x28]; i++)
+    prom[0x29 + i] = name[i] ^ key[i];
+
+  // calculate the checksum
+  uint8_t chk = 0;
+  for (int i = 0; i < 0x7F; i++)
+    chk ^= prom[i];
+
+  // EPOC is expecting 66
+  prom[0x7F] = chk ^ 66;
 }
 
-
-uint32_t Etna::readReg8(uint32_t reg)
-{
-//    if (!promReadActive)
-//             owner->log("ETNA readReg8: reg=%s @ pc=%08x,lr=%08x", nameReg(reg), owner->getGPR(15) - 4, owner->getGPR(14));
-    switch (reg) {
-    case regIntClear: return 0;
-    case regSktVarA0: return 1; // will store some status flags
-    case regSktVarA1: return 0; // will store some more status flags
-    case regWake1: return wake1;
-    case regWake2: return wake2;
-    }
-    return 0xFF;
+uint32_t Etna::readReg8(uint32_t reg) {
+  //    if (!promReadActive)
+  //           owner->log("ETNA readReg8: reg=%s @ pc=%08x,lr=%08x",
+  // nameReg(reg), owner->getGPR(15) - 4, owner->getGPR(14));
+  switch (reg) {
+  case regIntClear:
+    return 0;
+  case regSktVarA0:
+    return 1; // will store some status flags
+  case regSktVarA1:
+    return 0; // will store some more status flags
+  case regWake1:
+    return wake1;
+  case regWake2:
+    return wake2;
+  }
+  return 0xFF;
 }
 
-uint32_t Etna::readReg32(uint32_t reg)
-{
-    // may be able to remove this, p. sure Etna is byte addressing only
-       owner->log("ETNA readReg32: reg=%x", reg);
-    return 0xFFFFFFFF;
-}
-
-void Etna::writeReg8(uint32_t reg, uint8_t value)
-{
-    if (!promReadActive)
-               owner->log("ETNA writeReg8: reg=%s value=%02x @ pc=%08x,lr=%08x", nameReg(reg), value, owner->getGPR(15) - 4, owner->getGPR(14));
-    switch (reg) {
-    case regIntClear: pendingInterrupts &= ~value; break;
-    case regWake1: wake1 = value; break;
-    case regWake2: wake2 = value; break;
-    }
+uint32_t Etna::readReg32(uint32_t reg) {
+  // may be able to remove this, p. sure Etna is byte addressing only
+  owner->log("ETNA readReg32: reg=%x", reg);
+  return 0xFFFFFFFF;
 }
 
-void Etna::writeReg32(uint32_t reg, uint32_t value)
-{
-    // may be able to remove this, p. sure Etna is byte addressing only
-       owner->log("ETNA writeReg32: reg=%x value=%08x", reg, value);
+void Etna::writeReg8(uint32_t reg, uint8_t value) {
+  if (!promReadActive)
+    owner->log("ETNA writeReg8: reg=%s value=%02x @ pc=%08x,lr=%08x",
+               nameReg(reg), value, owner->getGPR(15) - 4, owner->getGPR(14));
+  switch (reg) {
+  case regIntClear:
+    pendingInterrupts &= ~value;
+    break;
+  case regWake1:
+    wake1 = value;
+    break;
+  case regWake2:
+    wake2 = value;
+    break;
+  }
 }
 
-void Etna::setPromBit0High()
-{
-    // begin reading a word
-    promReadAddress = 0;
-    promReadValue = 0;
-    promAddressBitsReceived = 0;
-    promReadActive = true;
+void Etna::writeReg32(uint32_t reg, uint32_t value) {
+  // may be able to remove this, p. sure Etna is byte addressing only
+  owner->log("ETNA writeReg32: reg=%x value=%08x", reg, value);
 }
 
-void Etna::setPromBit0Low()
-{
-    promReadActive = false;
+void Etna::setPromBit0High() {
+  // begin reading a word
+  promReadAddress = 0;
+  promReadValue = 0;
+  promAddressBitsReceived = 0;
+  promReadActive = true;
 }
 
-void Etna::setPromBit1High()
-{
-    if (promAddressBitsReceived < 10) {
-        // we're still receiving the address
-        promReadAddress <<= 1;
-        promReadAddress |= ((wake1 & 4) >> 2);
-        if (++promAddressBitsReceived == 10) {
-            // we can fetch the value now
-            int addressInBytes = promReadAddress * 2;
-            addressInBytes %= sizeof(prom);
-            promReadValue = prom[addressInBytes] | (prom[addressInBytes + 1] << 8);
-        }
-    } else {
-        wake1 &= ~8;
-        if (promReadValue & 0x8000)
-            wake1 |= 8;
-        promReadValue <<= 1;
+void Etna::setPromBit0Low() { promReadActive = false; }
+
+void Etna::setPromBit1High() {
+  if (promAddressBitsReceived < 10) {
+    // we're still receiving the address
+    promReadAddress <<= 1;
+    promReadAddress |= ((wake1 & 4) >> 2);
+    if (++promAddressBitsReceived == 10) {
+      // we can fetch the value now
+      int addressInBytes = promReadAddress * 2;
+      addressInBytes %= sizeof(prom);
+      promReadValue = prom[addressInBytes] | (prom[addressInBytes + 1] << 8);
     }
+  } else {
+    wake1 &= ~8;
+    if (promReadValue & 0x8000)
+      wake1 |= 8;
+    promReadValue <<= 1;
+  }
 }
index ef42e89d30d903ab314b0489bd36d83681454689..f929fda82c68d4b04407bb265cdce68541c9cb91 100644 (file)
@@ -4,26 +4,26 @@
 class ARM710;
 
 class Etna {
-    uint8_t prom[0x80] = {};
-    uint16_t promReadAddress = 0, promReadValue = 0;
-    bool promReadActive = false;
-    int promAddressBitsReceived = 0;
+  uint8_t prom[0x80] = {};
+  uint16_t promReadAddress = 0, promReadValue = 0;
+  bool promReadActive = false;
+  int promAddressBitsReceived = 0;
 
-    uint8_t pendingInterrupts = 0, interruptMask = 0;
-    uint8_t wake1 = 0, wake2 = 0;
+  uint8_t pendingInterrupts = 0, interruptMask = 0;
+  uint8_t wake1 = 0, wake2 = 0;
 
-       ARM710 *owner;
+  ARM710* owner;
 
 public:
-       Etna(ARM710 *owner);
+  Etna(ARM710* owner);
 
-    uint32_t readReg8(uint32_t reg);
-    uint32_t readReg32(uint32_t reg);
-    void writeReg8(uint32_t reg, uint8_t value);
-    void writeReg32(uint32_t reg, uint32_t value);
+  uint32_t readReg8(uint32_t reg);
+  uint32_t readReg32(uint32_t reg);
+  void writeReg8(uint32_t reg, uint8_t value);
+  void writeReg32(uint32_t reg, uint32_t value);
 
-    // PROM
-    void setPromBit0High(); // port B, bit 0
-    void setPromBit0Low(); // port B, bit 0
-    void setPromBit1High(); // port B, bit 1
+  // PROM
+  void setPromBit0High(); // port B, bit 0
+  void setPromBit0Low();  // port B, bit 0
+  void setPromBit1High(); // port B, bit 1
 };
index 02ac9485ed9eb1974803cb9eb6ac3deaab3ca4e2..2f1ab0d8de1b1512bc330ed00d30235300b07892 100644 (file)
 #include <stdio.h>
 
 struct Timer {
-       ARM710 *cpu;
+  ARM710* cpu;
 
-       enum {
-               MODE_512KHZ = 1<<3,
-               PERIODIC = 1<<6,
-               ENABLED = 1<<7
-       };
-    int64_t nextTickAt;
-       uint8_t config;
-       uint32_t interval;
-       int32_t value;
-       int clockSpeed;
+  enum { MODE_512KHZ = 1 << 3, PERIODIC = 1 << 6, ENABLED = 1 << 7 };
+  int64_t nextTickAt;
+  uint8_t config;
+  uint32_t interval;
+  int32_t value;
+  int clockSpeed;
 
-       int tickInterval() const {
-               return (config & MODE_512KHZ) ? (clockSpeed / 512000) : (clockSpeed / 2000);
-       }
-       void load(uint32_t lval) {
-               interval = lval;
-               value = lval;
-       }
-       void setConfig(uint8_t cval) {
-               nextTickAt -= tickInterval();
-               config = cval;
-               nextTickAt += tickInterval();
-       }
-    bool tick(int64_t cycles) {
-               if (cycles >= nextTickAt) {
-                       nextTickAt += tickInterval();
+  int tickInterval() const {
+    return (config & MODE_512KHZ) ? (clockSpeed / 512000) : (clockSpeed / 2000);
+  }
+  void load(uint32_t lval) {
+    interval = lval;
+    value = lval;
+  }
+  void setConfig(uint8_t cval) {
+    nextTickAt -= tickInterval();
+    config = cval;
+    nextTickAt += tickInterval();
+  }
+  bool tick(int64_t cycles) {
+    if (cycles >= nextTickAt) {
+      nextTickAt += tickInterval();
 
-                       if (config & ENABLED) {
-                               --value;
-                               if (value == 0) {
-                                       if (config & PERIODIC)
-                                               value = interval;
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-       void dump() {
-               printf("enabled=%s periodic=%s interval=%d value=%d\n",
-                       (config & ENABLED) ? "true" : "false",
-                       (config & PERIODIC) ? "true" : "false",
-                       interval, value
-               );
-       }
+      if (config & ENABLED) {
+        --value;
+        if (value == 0) {
+          if (config & PERIODIC)
+            value = interval;
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  void dump() {
+    printf("enabled=%s periodic=%s interval=%d value=%d\n",
+           (config & ENABLED) ? "true" : "false",
+           (config & PERIODIC) ? "true" : "false", interval, value);
+  }
 };
 
 enum UartRegs {
-       UART0DATA = 0x600,
-       UART0FCR = 0x604,
-       UART0LCR = 0x608,
-       UART0CON = 0x60C,
-       UART0FLG = 0x610,
-       UART0INT = 0x614,
-       UART0INTM = 0x618,
-       UART0INTR = 0x61C,
-       UART0TEST1 = 0x620,
-       UART0TEST2 = 0x624,
-       UART0TEST3 = 0x628,
-       UART1DATA = 0x700,
-       UART1FCR = 0x704,
-       UART1LCR = 0x708,
-       UART1CON = 0x70C,
-       UART1FLG = 0x710,
-       UART1INT = 0x714,
-       UART1INTM = 0x718,
-       UART1INTR = 0x71C,
-       UART1TEST1 = 0x720,
-       UART1TEST2 = 0x724,
-       UART1TEST3 = 0x728,
+  UART0DATA = 0x600,
+  UART0FCR = 0x604,
+  UART0LCR = 0x608,
+  UART0CON = 0x60C,
+  UART0FLG = 0x610,
+  UART0INT = 0x614,
+  UART0INTM = 0x618,
+  UART0INTR = 0x61C,
+  UART0TEST1 = 0x620,
+  UART0TEST2 = 0x624,
+  UART0TEST3 = 0x628,
+  UART1DATA = 0x700,
+  UART1FCR = 0x704,
+  UART1LCR = 0x708,
+  UART1CON = 0x70C,
+  UART1FLG = 0x710,
+  UART1INT = 0x714,
+  UART1INTM = 0x718,
+  UART1INTR = 0x71C,
+  UART1TEST1 = 0x720,
+  UART1TEST2 = 0x724,
+  UART1TEST3 = 0x728,
 };
 
 struct UART {
-       ARM710 *cpu;
+  ARM710* cpu;
 
-       enum {
-               IntRx = 1,
-               IntTx = 2,
-               IntModemStatus = 4,
-               PortCtrlEnable = 1,
-               PortCtrlSirEnable = 2,
-               PortCtrlIrdaTx = 4,
-               FrameCtrlBreak = 1,
-               FrameCtrlParityEnable = 2,
-               FrameCtrlEvenParity = 4,
-               FrameCtrlExtraStopBit = 8,
-               FrameCtrlUFifoEn = 0x10,
-               FrameCtrlWrdLenMask = 0x60,
-               FrameCtrlWlen5 = 0,
-               FrameCtrlWlen6 = 0x20,
-               FrameCtrlWlen7 = 0x40,
-               FrameCtrlWlen8 = 0x60,
-               RecvFrameError = 0x100,
-               RecvParityError = 0x200,
-               RecvOverrunError = 0x400,
-               FlagClearToSend = 1,
-               FlagDataSetReady = 2,
-               FlagDataCarrierDetect = 4,
-               FlagBusy = 8,
-               FlagReceiveFifoEmpty = 0x10,
-               FlagTransmitFifoFull = 0x20
-       };
-       uint8_t portControl = 0;
-       uint8_t frameControl = 0;
-       uint8_t interrupts = 0, interruptMask = 0;
+  enum {
+    IntRx = 1,
+    IntTx = 2,
+    IntModemStatus = 4,
+    PortCtrlEnable = 1,
+    PortCtrlSirEnable = 2,
+    PortCtrlIrdaTx = 4,
+    FrameCtrlBreak = 1,
+    FrameCtrlParityEnable = 2,
+    FrameCtrlEvenParity = 4,
+    FrameCtrlExtraStopBit = 8,
+    FrameCtrlUFifoEn = 0x10,
+    FrameCtrlWrdLenMask = 0x60,
+    FrameCtrlWlen5 = 0,
+    FrameCtrlWlen6 = 0x20,
+    FrameCtrlWlen7 = 0x40,
+    FrameCtrlWlen8 = 0x60,
+    RecvFrameError = 0x100,
+    RecvParityError = 0x200,
+    RecvOverrunError = 0x400,
+    FlagClearToSend = 1,
+    FlagDataSetReady = 2,
+    FlagDataCarrierDetect = 4,
+    FlagBusy = 8,
+    FlagReceiveFifoEmpty = 0x10,
+    FlagTransmitFifoFull = 0x20
+  };
+  uint8_t portControl = 0;
+  uint8_t frameControl = 0;
+  uint8_t interrupts = 0, interruptMask = 0;
 
-       // UART0DATA = 0x600, byte write, long read
-       // UART0FCR = 0x604, long
-       // UART0LCR = 0x608, long
-       // UART0CON = 0x60C, byte
-       // UART0FLG = 0x610, byte
-       // UART0INT = 0x614, long write, byte read
-       // UART0INTM = 0x618, byte
-       // UART0INTR = 0x61C, byte
-       // UART0TEST1 = 0x620,
-       // UART0TEST2 = 0x624,
-       // UART0TEST3 = 0x628,
-       uint32_t readReg8(uint32_t reg) {
-               // UART0DATA
-               if (reg == (UART0CON & 0xFF)) {
-                       return portControl;
-               } else if (reg == (UART0FLG & 0xFF)) {
-                       // we pretend we are never busy, never have full fifo
-                       return FlagReceiveFifoEmpty;
-               // UART0INT?
-               // UART0INTM?
-               // UART0INTR?
-               } else {
-                       printf("unhandled 8bit uart read %x at pc=%08x lr=%08x\n", reg, cpu->getGPR(15), cpu->getGPR(14));
-                       return 0xFF;
-               }
-       }
-       uint32_t readReg32(uint32_t reg) {
-               // UART0DATA
-               if (reg == (UART0FCR & 0xFF)) {
-                       return frameControl;
-               // UART0LCR
-               } else if (reg == (UART0FLG & 0xFF)) {
-                       // we pretend we are never busy, never have full fifo
-                       return FlagReceiveFifoEmpty;
-               } else {
-                       printf("unhandled 32bit uart read %x at pc=%08x lr=%08x\n", reg, cpu->getGPR(15), cpu->getGPR(14));
-                       return 0xFFFFFFFF;
-               }
-       }
-       void writeReg8(uint32_t reg, uint8_t value) {
-               // UART0DATA
-               if (reg == (UART0CON & 0xFF)) {
-                       portControl = value;
-                       printf("portcon updated: enable=%d sirenable=%d irdatx=%d\n", value&1, value&2, value&4);
-               } else if (reg == (UART0INTM & 0xFF)) {
-                       interruptMask = value;
-                       printf("uart interruptmask updated: %d\n", value);
-               // UART0INTR?
-               } else {
-                       printf("unhandled 8bit uart write %x value %02x at pc=%08x lr=%08x\n", reg, value, cpu->getGPR(15), cpu->getGPR(14));
-               }
-       }
-       void writeReg32(uint32_t reg, uint32_t value) {
-               if (reg == (UART0FCR & 0xFF)) {
-                       frameControl = value;
-                       printf("frameControl updated: break=%d parityEn=%d evenParity=%d extraStop=%d ufifoEn=%d wrdLen=%d\n",
-                               value&1,
-                               value&2,
-                               value&4,
-                               value&8,
-                               value&0x10,
-                               ((value&0x60)>>5)+5);
-               } else if (reg == (UART0LCR & 0xFF)) {
-                       printf("** uart writing lcr %x **\n", value);
-               } else if (reg == (UART0INT & 0xFF)) {
-                       printf("uart interrupts %x -> %x\n", interrupts, value);
-                       interrupts = value;
-               } else {
-                       printf("unhandled 32bit uart write %x value %08x at pc=%08x lr=%08x\n", reg, value, cpu->getGPR(15), cpu->getGPR(14));
-               }
-       }
+  // UART0DATA = 0x600, byte write, long read
+  // UART0FCR = 0x604, long
+  // UART0LCR = 0x608, long
+  // UART0CON = 0x60C, byte
+  // UART0FLG = 0x610, byte
+  // UART0INT = 0x614, long write, byte read
+  // UART0INTM = 0x618, byte
+  // UART0INTR = 0x61C, byte
+  // UART0TEST1 = 0x620,
+  // UART0TEST2 = 0x624,
+  // UART0TEST3 = 0x628,
+  uint32_t readReg8(uint32_t reg) {
+    // UART0DATA
+    if (reg == (UART0CON & 0xFF)) {
+      return portControl;
+    } else if (reg == (UART0FLG & 0xFF)) {
+      // we pretend we are never busy, never have full fifo
+      return FlagReceiveFifoEmpty;
+      // UART0INT?
+      // UART0INTM?
+      // UART0INTR?
+    } else {
+      printf("unhandled 8bit uart read %x at pc=%08x lr=%08x\n", reg,
+             cpu->getGPR(15), cpu->getGPR(14));
+      return 0xFF;
+    }
+  }
+  uint32_t readReg32(uint32_t reg) {
+    // UART0DATA
+    if (reg == (UART0FCR & 0xFF)) {
+      return frameControl;
+      // UART0LCR
+    } else if (reg == (UART0FLG & 0xFF)) {
+      // we pretend we are never busy, never have full fifo
+      return FlagReceiveFifoEmpty;
+    } else {
+      printf("unhandled 32bit uart read %x at pc=%08x lr=%08x\n", reg,
+             cpu->getGPR(15), cpu->getGPR(14));
+      return 0xFFFFFFFF;
+    }
+  }
+  void writeReg8(uint32_t reg, uint8_t value) {
+    // UART0DATA
+    if (reg == (UART0CON & 0xFF)) {
+      portControl = value;
+      printf("portcon updated: enable=%d sirenable=%d irdatx=%d\n", value & 1,
+             value & 2, value & 4);
+    } else if (reg == (UART0INTM & 0xFF)) {
+      interruptMask = value;
+      printf("uart interruptmask updated: %d\n", value);
+      // UART0INTR?
+    } else {
+      printf("unhandled 8bit uart write %x value %02x at pc=%08x lr=%08x\n",
+             reg, value, cpu->getGPR(15), cpu->getGPR(14));
+    }
+  }
+  void writeReg32(uint32_t reg, uint32_t value) {
+    if (reg == (UART0FCR & 0xFF)) {
+      frameControl = value;
+      printf("frameControl updated: break=%d parityEn=%d evenParity=%d "
+             "extraStop=%d ufifoEn=%d wrdLen=%d\n",
+             value & 1, value & 2, value & 4, value & 8, value & 0x10,
+             ((value & 0x60) >> 5) + 5);
+    } else if (reg == (UART0LCR & 0xFF)) {
+      printf("** uart writing lcr %x **\n", value);
+    } else if (reg == (UART0INT & 0xFF)) {
+      printf("uart interrupts %x -> %x\n", interrupts, value);
+      interrupts = value;
+    } else {
+      printf("unhandled 32bit uart write %x value %08x at pc=%08x lr=%08x\n",
+             reg, value, cpu->getGPR(15), cpu->getGPR(14));
+    }
+  }
 };
index d13aabe3b20f9de0c9a32da615d69d02c2c8d3d6..b87896d4dbbcde77482ce3b451e9c671b7805360 100644 (file)
@@ -9,14 +9,18 @@
 #include "macros.h"
 
 #define ARM_SIGN(I) ((I) >> 31)
-#define ARM_SXT_8(I) (((int8_t) (I) << 24) >> 24)
-#define ARM_SXT_16(I) (((int16_t) (I) << 16) >> 16)
-#define ARM_UXT_64(I) (uint64_t)(uint32_t) (I)
+#define ARM_SXT_8(I) (((int8_t)(I) << 24) >> 24)
+#define ARM_SXT_16(I) (((int16_t)(I) << 16) >> 16)
+#define ARM_UXT_64(I) (uint64_t)(uint32_t)(I)
 
-#define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31))
-#define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N)))
-#define ARM_BORROW_FROM_CARRY(M, N, D, C) (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t) (C))
-#define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
-#define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
+#define ARM_CARRY_FROM(M, N, D)                                                \
+  (((uint32_t)(M) >> 31) + ((uint32_t)(N) >> 31) > ((uint32_t)(D) >> 31))
+#define ARM_BORROW_FROM(M, N, D) (((uint32_t)(M)) >= ((uint32_t)(N)))
+#define ARM_BORROW_FROM_CARRY(M, N, D, C)                                      \
+  (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t)(C))
+#define ARM_V_ADDITION(M, N, D)                                                \
+  (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
+#define ARM_V_SUBTRACTION(M, N, D)                                             \
+  ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
 
 #endif
index 9d74b8d114144a97d94a41328fda8949f05467b7..571500a9f8156fb7697a78ead3f184249574db56 100644 (file)
@@ -2,92 +2,89 @@
 #include <stdint.h>
 
 namespace Windermere {
-enum {
-       CLOCK_SPEED = 0x9000*1000,
-       TICK_INTERVAL = CLOCK_SPEED / 64
-};
+enum { CLOCK_SPEED = 0x9000 * 1000, TICK_INTERVAL = CLOCK_SPEED / 64 };
 
 enum Interrupt {
-       EXTFIQ = 0,  // FiqExternal
-       BLINT = 1,   // FiqBatLow
-       WEINT = 2,   // FiqWatchDog
-       MCINT = 3,   // FiqMediaChg
-       CSINT = 4,   // IrqCodec
-       EINT1 = 5,   // IrqExt1
-       EINT2 = 6,   // IrqExt2
-       EINT3 = 7,   // IrqExt3
-       TC1OI = 8,   // IrqTimer1
-       TC2OI = 9,   // IrqTimer2
-       RTCMI = 10,  // IrqRtcMatch
-       TINT = 11,   // IrqTick
-       UART1 = 12,  // IrqUart1
-       UART2 = 13,  // IrqUart1
-       LCDINT = 14, // IrqLcd
-       SSEOTI = 15,  // IrqSpi
-       FIQ_INTERRUPTS = 0x000F,
-       IRQ_INTERRUPTS = 0xFFF0
+  EXTFIQ = 0,  // FiqExternal
+  BLINT = 1,   // FiqBatLow
+  WEINT = 2,   // FiqWatchDog
+  MCINT = 3,   // FiqMediaChg
+  CSINT = 4,   // IrqCodec
+  EINT1 = 5,   // IrqExt1
+  EINT2 = 6,   // IrqExt2
+  EINT3 = 7,   // IrqExt3
+  TC1OI = 8,   // IrqTimer1
+  TC2OI = 9,   // IrqTimer2
+  RTCMI = 10,  // IrqRtcMatch
+  TINT = 11,   // IrqTick
+  UART1 = 12,  // IrqUart1
+  UART2 = 13,  // IrqUart1
+  LCDINT = 14, // IrqLcd
+  SSEOTI = 15, // IrqSpi
+  FIQ_INTERRUPTS = 0x000F,
+  IRQ_INTERRUPTS = 0xFFF0
 };
 
 enum Register {
-       MEMCFG1 = 0,
-       MEMCFG2 = 4,
-       DRAM_CFG = 0x100,
-       LCDCTL = 0x200,
-       LCDST = 0x204,
-       LCD_DBAR1 = 0x210,
-       LCDT0 = 0x220,
-       LCDT1 = 0x224,
-       LCDT2 = 0x228,
-       PWRSR = 0x400,
-       PWRCNT = 0x404,
-       HALT = 0x408,
-       STBY = 0x40C,
-       BLEOI = 0x410,
-       MCEOI = 0x414,
-       TEOI = 0x418,
-       STFCLR = 0x41C,
-       E2EOI = 0x420,
-       INTSR = 0x500,
-       INTRSR = 0x504,
-       INTENS = 0x508,
-       INTENC = 0x50C,
-       INTTEST1 = 0x514,
-       INTTEST2 = 0x518,
-       PUMPCON = 0x900,
-       CODR = 0xA00,
-       CONFG = 0xA04,
-       COLFG = 0xA08,
-       COEOI = 0xA0C,
-       COTEST = 0xA10,
-       SSCR0 = 0xB00,
-       SSCR1 = 0xB04,
-       SSDR = 0xB0C,
-       SSSR = 0xB14,
-       TC1LOAD = 0xC00,
-       TC1VAL = 0xC04,
-       TC1CTRL = 0xC08,
-       TC1EOI = 0xC0C,
-       TC2LOAD = 0xC20,
-       TC2VAL = 0xC24,
-       TC2CTRL = 0xC28,
-       TC2EOI = 0xC2C,
-       BZCONT = 0xC40,
-       RTCDRL = 0xD00,
-       RTCDRU = 0xD04,
-       RTCMRL = 0xD08,
-       RTCMRU = 0xD0C,
-       RTCEOI = 0xD10,
-       PADR = 0xE00,
-       PBDR = 0xE04,
-       PCDR = 0xE08,
-       PDDR = 0xE0C,
-       PADDR = 0xE10,
-       PBDDR = 0xE14,
-       PCDDR = 0xE18,
-       PDDDR = 0xE1C,
-       PEDR = 0xE20,
-       PEDDR = 0xE24,
-       KSCAN = 0xE28,
-       LCDMUX = 0xE2C
+  MEMCFG1 = 0,
+  MEMCFG2 = 4,
+  DRAM_CFG = 0x100,
+  LCDCTL = 0x200,
+  LCDST = 0x204,
+  LCD_DBAR1 = 0x210,
+  LCDT0 = 0x220,
+  LCDT1 = 0x224,
+  LCDT2 = 0x228,
+  PWRSR = 0x400,
+  PWRCNT = 0x404,
+  HALT = 0x408,
+  STBY = 0x40C,
+  BLEOI = 0x410,
+  MCEOI = 0x414,
+  TEOI = 0x418,
+  STFCLR = 0x41C,
+  E2EOI = 0x420,
+  INTSR = 0x500,
+  INTRSR = 0x504,
+  INTENS = 0x508,
+  INTENC = 0x50C,
+  INTTEST1 = 0x514,
+  INTTEST2 = 0x518,
+  PUMPCON = 0x900,
+  CODR = 0xA00,
+  CONFG = 0xA04,
+  COLFG = 0xA08,
+  COEOI = 0xA0C,
+  COTEST = 0xA10,
+  SSCR0 = 0xB00,
+  SSCR1 = 0xB04,
+  SSDR = 0xB0C,
+  SSSR = 0xB14,
+  TC1LOAD = 0xC00,
+  TC1VAL = 0xC04,
+  TC1CTRL = 0xC08,
+  TC1EOI = 0xC0C,
+  TC2LOAD = 0xC20,
+  TC2VAL = 0xC24,
+  TC2CTRL = 0xC28,
+  TC2EOI = 0xC2C,
+  BZCONT = 0xC40,
+  RTCDRL = 0xD00,
+  RTCDRU = 0xD04,
+  RTCMRL = 0xD08,
+  RTCMRU = 0xD0C,
+  RTCEOI = 0xD10,
+  PADR = 0xE00,
+  PBDR = 0xE04,
+  PCDR = 0xE08,
+  PDDR = 0xE0C,
+  PADDR = 0xE10,
+  PBDDR = 0xE14,
+  PCDDR = 0xE18,
+  PDDDR = 0xE1C,
+  PEDR = 0xE20,
+  PEDDR = 0xE24,
+  KSCAN = 0xE28,
+  LCDMUX = 0xE2C
 };
-}
+} // namespace Windermere
index 41bbe708a04151ed6844f5946707a5df43d1cd2d..e8a28a0357baf631d7b0385249f80de288b824ae 100644 (file)
 #include "windermere.h"
-#include "wind_defs.h"
+#include "common.h"
 #include "hardware.h"
+#include "wind_defs.h"
 #include <time.h>
-#include "common.h"
-
 
-//#define INCLUDE_D
-//#define INCLUDE_BANK1
+// #define INCLUDE_D
+// #define INCLUDE_BANK1
 
 namespace Windermere {
-Emulator::Emulator() : EmuBase(true), etna(this) {
-}
-
-
-uint32_t Emulator::getRTC() {
-    return time(nullptr) - 946684800;
-}
+Emulator::Emulator() : EmuBase(true), etna(this) {}
 
+uint32_t Emulator::getRTC() { return time(nullptr) - 946684800; }
 
 uint32_t Emulator::readReg8(uint32_t reg) {
-       if ((reg & 0xF00) == 0x600) {
-               return uart1.readReg8(reg & 0xFF);
-       } else if ((reg & 0xF00) == 0x700) {
-               return uart2.readReg8(reg & 0xFF);
-       } else if (reg == TC1CTRL) {
-               return tc1.config;
-       } else if (reg == TC2CTRL) {
-               return tc2.config;
-       } else if (reg == PADR) {
-               return readKeyboard();
-       } else if (reg == PBDR) {
-               return (portValues >> 16) & 0xFF;
-       } else if (reg == PCDR) {
-               return (portValues >> 8) & 0xFF;
-       } else if (reg == PDDR) {
-               return portValues & 0xFF;
-       } else if (reg == PADDR) {
-               return (portDirections >> 24) & 0xFF;
-       } else if (reg == PBDDR) {
-               return (portDirections >> 16) & 0xFF;
-       } else if (reg == PCDDR) {
-               return (portDirections >> 8) & 0xFF;
-       } else if (reg == PDDDR) {
-               return portDirections & 0xFF;
-       } else {
-//             printf("RegRead8 unknown:: pc=%08x lr=%08x reg=%03x\n", getGPR(15)-4, getGPR(14), reg);
-               return 0xFF;
-       }
+  if ((reg & 0xF00) == 0x600) {
+    return uart1.readReg8(reg & 0xFF);
+  } else if ((reg & 0xF00) == 0x700) {
+    return uart2.readReg8(reg & 0xFF);
+  } else if (reg == TC1CTRL) {
+    return tc1.config;
+  } else if (reg == TC2CTRL) {
+    return tc2.config;
+  } else if (reg == PADR) {
+    return readKeyboard();
+  } else if (reg == PBDR) {
+    return (portValues >> 16) & 0xFF;
+  } else if (reg == PCDR) {
+    return (portValues >> 8) & 0xFF;
+  } else if (reg == PDDR) {
+    return portValues & 0xFF;
+  } else if (reg == PADDR) {
+    return (portDirections >> 24) & 0xFF;
+  } else if (reg == PBDDR) {
+    return (portDirections >> 16) & 0xFF;
+  } else if (reg == PCDDR) {
+    return (portDirections >> 8) & 0xFF;
+  } else if (reg == PDDDR) {
+    return portDirections & 0xFF;
+  } else {
+    //         printf("RegRead8 unknown:: pc=%08x lr=%08x reg=%03x\n",
+    // getGPR(15)-4, getGPR(14), reg);
+    return 0xFF;
+  }
 }
 uint32_t Emulator::readReg32(uint32_t reg) {
-       if (reg == LCDCTL) {
-               printf("LCD control read pc=%08x lr=%08x !!!\n", getGPR(15), getGPR(14));
-               return lcdControl;
-       } else if (reg == LCDST) {
-               printf("LCD state read pc=%08x lr=%08x !!!\n", getGPR(15), getGPR(14));
-               return 0xFFFFFFFF;
-       } else if (reg == PWRSR) {
-//             printf("!!! PWRSR read pc=%08x lr=%08x !!!\n", getGPR(15), getGPR(14));
-               return pwrsr;
-       } else if (reg == INTSR) {
-               return pendingInterrupts & interruptMask;
-       } else if (reg == INTRSR) {
-               return pendingInterrupts;
-       } else if (reg == INTENS) {
-               return interruptMask;
-       } else if ((reg & 0xF00) == 0x600) {
-               return uart1.readReg32(reg & 0xFF);
-       } else if ((reg & 0xF00) == 0x700) {
-               return uart2.readReg32(reg & 0xFF);
-       } else if (reg == TC1VAL) {
-               return tc1.value;
-       } else if (reg == TC2VAL) {
-               return tc2.value;
-       } else if (reg == SSDR) {
-               // as per 5000A7B0 in 5mx rom
-               uint16_t ssiValue = 0;
-               switch (lastSSIRequest) {
-               case 0xD0D3: ssiValue = (uint16_t)(50 + (touchX * 5.7)); break;
-               case 0x9093: ssiValue = (uint16_t)(3834 - (touchY * 13.225)); break;
-               case 0xA4A4: ssiValue = 3100; break; // MainBattery
-               case 0xE4E4: ssiValue = 3100; break; // BackupBattery
-               }
-
-               uint32_t ret = 0;
-               if (ssiReadCounter == 4) ret = (ssiValue >> 5) & 0x7F;
-               if (ssiReadCounter == 5) ret = (ssiValue << 3) & 0xF8;
-               ssiReadCounter++;
-               if (ssiReadCounter == 6) ssiReadCounter = 0;
-
-               // by hardware we should be clearing SSEOTI here, i think
-               // but we just leave it on to simplify things
-               return ret;
-       } else if (reg == SSSR) {
-               return 0;
-    } else if (reg == RTCDRL) {
-        uint16_t v = rtc & 0xFFFF;
-//             log("RTCDRL: %04x", v);
-        return v;
-    } else if (reg == RTCDRU) {
-        uint16_t v = rtc >> 16;
-//             log("RTCDRU: %04x", v);
-        return v;
-    } else if (reg == KSCAN) {
-        return kScan;
-    } else {
-//             printf("RegRead32 unknown:: pc=%08x lr=%08x reg=%03x\n", getGPR(15)-4, getGPR(14), reg);
-               return 0xFFFFFFFF;
-       }
+  if (reg == LCDCTL) {
+    printf("LCD control read pc=%08x lr=%08x !!!\n", getGPR(15), getGPR(14));
+    return lcdControl;
+  } else if (reg == LCDST) {
+    printf("LCD state read pc=%08x lr=%08x !!!\n", getGPR(15), getGPR(14));
+    return 0xFFFFFFFF;
+  } else if (reg == PWRSR) {
+    //         printf("!!! PWRSR read pc=%08x lr=%08x !!!\n", getGPR(15),
+    // getGPR(14));
+    return pwrsr;
+  } else if (reg == INTSR) {
+    return pendingInterrupts & interruptMask;
+  } else if (reg == INTRSR) {
+    return pendingInterrupts;
+  } else if (reg == INTENS) {
+    return interruptMask;
+  } else if ((reg & 0xF00) == 0x600) {
+    return uart1.readReg32(reg & 0xFF);
+  } else if ((reg & 0xF00) == 0x700) {
+    return uart2.readReg32(reg & 0xFF);
+  } else if (reg == TC1VAL) {
+    return tc1.value;
+  } else if (reg == TC2VAL) {
+    return tc2.value;
+  } else if (reg == SSDR) {
+    // as per 5000A7B0 in 5mx rom
+    uint16_t ssiValue = 0;
+    switch (lastSSIRequest) {
+    case 0xD0D3:
+      ssiValue = (uint16_t)(50 + (touchX * 5.7));
+      break;
+    case 0x9093:
+      ssiValue = (uint16_t)(3834 - (touchY * 13.225));
+      break;
+    case 0xA4A4:
+      ssiValue = 3100;
+      break; // MainBattery
+    case 0xE4E4:
+      ssiValue = 3100;
+      break; // BackupBattery
+    }
+
+    uint32_t ret = 0;
+    if (ssiReadCounter == 4)
+      ret = (ssiValue >> 5) & 0x7F;
+    if (ssiReadCounter == 5)
+      ret = (ssiValue << 3) & 0xF8;
+    ssiReadCounter++;
+    if (ssiReadCounter == 6)
+      ssiReadCounter = 0;
+
+    // by hardware we should be clearing SSEOTI here, i think
+    // but we just leave it on to simplify things
+    return ret;
+  } else if (reg == SSSR) {
+    return 0;
+  } else if (reg == RTCDRL) {
+    uint16_t v = rtc & 0xFFFF;
+    //         log("RTCDRL: %04x", v);
+    return v;
+  } else if (reg == RTCDRU) {
+    uint16_t v = rtc >> 16;
+    //         log("RTCDRU: %04x", v);
+    return v;
+  } else if (reg == KSCAN) {
+    return kScan;
+  } else {
+    //         printf("RegRead32 unknown:: pc=%08x lr=%08x reg=%03x\n",
+    // getGPR(15)-4, getGPR(14), reg);
+    return 0xFFFFFFFF;
+  }
 }
 
 void Emulator::writeReg8(uint32_t reg, uint8_t value) {
-       if ((reg & 0xF00) == 0x600) {
-               uart1.writeReg8(reg & 0xFF, value);
-       } else if ((reg & 0xF00) == 0x700) {
-               uart2.writeReg8(reg & 0xFF, value);
-       } else if (reg == TC1CTRL) {
-               tc1.setConfig(value);
-       } else if (reg == TC2CTRL) {
-               tc2.setConfig(value);
-       } else if (reg == PADR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0x00FFFFFF;
-               portValues |= (uint32_t)value << 24;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PBDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFF00FFFF;
-               portValues |= (uint32_t)value << 16;
-               if ((portValues & 0x10000) && !(oldPorts & 0x10000))
-                       etna.setPromBit0High();
-               else if (!(portValues & 0x10000) && (oldPorts & 0x10000))
-                       etna.setPromBit0Low();
-               if ((portValues & 0x20000) && !(oldPorts & 0x20000))
-                       etna.setPromBit1High();
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PCDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFFFF00FF;
-               portValues |= (uint32_t)value << 8;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PDDR) {
-               uint32_t oldPorts = portValues;
-               portValues &= 0xFFFFFF00;
-               portValues |= (uint32_t)value;
-               diffPorts(oldPorts, portValues);
-       } else if (reg == PADDR) {
-               portDirections &= 0x00FFFFFF;
-               portDirections |= (uint32_t)value << 24;
-       } else if (reg == PBDDR) {
-               portDirections &= 0xFF00FFFF;
-               portDirections |= (uint32_t)value << 16;
-       } else if (reg == PCDDR) {
-               portDirections &= 0xFFFF00FF;
-               portDirections |= (uint32_t)value << 8;
-       } else if (reg == PDDDR) {
-               portDirections &= 0xFFFFFF00;
-               portDirections |= (uint32_t)value;
-    } else if (reg == KSCAN) {
-        kScan = value;
-    } else {
-//             printf("RegWrite8 unknown:: pc=%08x reg=%03x value=%02x\n", getGPR(15)-4, reg, value);
-       }
+  if ((reg & 0xF00) == 0x600) {
+    uart1.writeReg8(reg & 0xFF, value);
+  } else if ((reg & 0xF00) == 0x700) {
+    uart2.writeReg8(reg & 0xFF, value);
+  } else if (reg == TC1CTRL) {
+    tc1.setConfig(value);
+  } else if (reg == TC2CTRL) {
+    tc2.setConfig(value);
+  } else if (reg == PADR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0x00FFFFFF;
+    portValues |= (uint32_t)value << 24;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PBDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFF00FFFF;
+    portValues |= (uint32_t)value << 16;
+    if ((portValues & 0x10000) && !(oldPorts & 0x10000))
+      etna.setPromBit0High();
+    else if (!(portValues & 0x10000) && (oldPorts & 0x10000))
+      etna.setPromBit0Low();
+    if ((portValues & 0x20000) && !(oldPorts & 0x20000))
+      etna.setPromBit1High();
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PCDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFFFF00FF;
+    portValues |= (uint32_t)value << 8;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PDDR) {
+    uint32_t oldPorts = portValues;
+    portValues &= 0xFFFFFF00;
+    portValues |= (uint32_t)value;
+    diffPorts(oldPorts, portValues);
+  } else if (reg == PADDR) {
+    portDirections &= 0x00FFFFFF;
+    portDirections |= (uint32_t)value << 24;
+  } else if (reg == PBDDR) {
+    portDirections &= 0xFF00FFFF;
+    portDirections |= (uint32_t)value << 16;
+  } else if (reg == PCDDR) {
+    portDirections &= 0xFFFF00FF;
+    portDirections |= (uint32_t)value << 8;
+  } else if (reg == PDDDR) {
+    portDirections &= 0xFFFFFF00;
+    portDirections |= (uint32_t)value;
+  } else if (reg == KSCAN) {
+    kScan = value;
+  } else {
+    //         printf("RegWrite8 unknown:: pc=%08x reg=%03x value=%02x\n",
+    // getGPR(15)-4, reg, value);
+  }
 }
 void Emulator::writeReg32(uint32_t reg, uint32_t value) {
-       if (reg == LCDCTL) {
-               printf("LCD: ctl write %08x\n", value);
-               lcdControl = value;
-       } else if (reg == LCD_DBAR1) {
-               printf("LCD: address write %08x\n", value);
-        lcdAddress = value;
-       } else if (reg == LCDT0) {
-               printf("LCD: horz timing write %08x\n", value);
-       } else if (reg == LCDT1) {
-               printf("LCD: vert timing write %08x\n", value);
-       } else if (reg == LCDT2) {
-               printf("LCD: clocks write %08x\n", value);
-       } else if (reg == INTENS) {
-//             diffInterrupts(interruptMask, interruptMask | value);
-               interruptMask |= value;
-       } else if (reg == INTENC) {
-//             diffInterrupts(interruptMask, interruptMask &~ value);
-               interruptMask &= ~value;
-       } else if (reg == HALT) {
-               halted = true;
-       // BLEOI = 0x410,
-       // MCEOI = 0x414,
-       } else if (reg == TEOI) {
-               pendingInterrupts &= ~(1 << TINT);
-       // TEOI = 0x418,
-       // STFCLR = 0x41C,
-       // E2EOI = 0x420,
-       } else if ((reg & 0xF00) == 0x600) {
-               uart1.writeReg32(reg & 0xFF, value);
-       } else if ((reg & 0xF00) == 0x700) {
-               uart2.writeReg32(reg & 0xFF, value);
-       } else if (reg == SSDR) {
-               if (value != 0)
-                       lastSSIRequest = (lastSSIRequest >> 8) | (value & 0xFF00);
-       } else if (reg == TC1LOAD) {
-               tc1.load(value);
-       } else if (reg == TC1EOI) {
-               pendingInterrupts &= ~(1 << TC1OI);
-       } else if (reg == TC2LOAD) {
-               tc2.load(value);
-       } else if (reg == TC2EOI) {
-               pendingInterrupts &= ~(1 << TC2OI);
-       } else if (reg == RTCDRL) {
-               rtc &= 0xFFFF0000;
-               rtc |= (value & 0xFFFF);
-               log("RTC write lower: %04x", value);
-       } else if (reg == RTCDRU) {
-               rtc &= 0x0000FFFF;
-               rtc |= (value & 0xFFFF) << 16;
-               log("RTC write upper: %04x", value);
-       } else {
-//             printf("RegWrite32 unknown:: pc=%08x reg=%03x value=%08x\n", getGPR(15)-4, reg, value);
-       }
+  if (reg == LCDCTL) {
+    printf("LCD: ctl write %08x\n", value);
+    lcdControl = value;
+  } else if (reg == LCD_DBAR1) {
+    printf("LCD: address write %08x\n", value);
+    lcdAddress = value;
+  } else if (reg == LCDT0) {
+    printf("LCD: horz timing write %08x\n", value);
+  } else if (reg == LCDT1) {
+    printf("LCD: vert timing write %08x\n", value);
+  } else if (reg == LCDT2) {
+    printf("LCD: clocks write %08x\n", value);
+  } else if (reg == INTENS) {
+    //         diffInterrupts(interruptMask, interruptMask | value);
+    interruptMask |= value;
+  } else if (reg == INTENC) {
+    //         diffInterrupts(interruptMask, interruptMask &~ value);
+    interruptMask &= ~value;
+  } else if (reg == HALT) {
+    halted = true;
+    // BLEOI = 0x410,
+    // MCEOI = 0x414,
+  } else if (reg == TEOI) {
+    pendingInterrupts &= ~(1 << TINT);
+    // TEOI = 0x418,
+    // STFCLR = 0x41C,
+    // E2EOI = 0x420,
+  } else if ((reg & 0xF00) == 0x600) {
+    uart1.writeReg32(reg & 0xFF, value);
+  } else if ((reg & 0xF00) == 0x700) {
+    uart2.writeReg32(reg & 0xFF, value);
+  } else if (reg == SSDR) {
+    if (value != 0)
+      lastSSIRequest = (lastSSIRequest >> 8) | (value & 0xFF00);
+  } else if (reg == TC1LOAD) {
+    tc1.load(value);
+  } else if (reg == TC1EOI) {
+    pendingInterrupts &= ~(1 << TC1OI);
+  } else if (reg == TC2LOAD) {
+    tc2.load(value);
+  } else if (reg == TC2EOI) {
+    pendingInterrupts &= ~(1 << TC2OI);
+  } else if (reg == RTCDRL) {
+    rtc &= 0xFFFF0000;
+    rtc |= (value & 0xFFFF);
+    log("RTC write lower: %04x", value);
+  } else if (reg == RTCDRU) {
+    rtc &= 0x0000FFFF;
+    rtc |= (value & 0xFFFF) << 16;
+    log("RTC write upper: %04x", value);
+  } else {
+    //         printf("RegWrite32 unknown:: pc=%08x reg=%03x value=%08x\n",
+    // getGPR(15)-4, reg, value);
+  }
 }
 
 MaybeU32 Emulator::readPhysical(uint32_t physAddr, ValueSize valueSize) {
-       uint8_t region = (physAddr >> 24) & 0xF1;
-       if (valueSize == V8) {
-               if (region == 0)
-                       return ROM[physAddr & 0xFFFFFF];
-               else if (region == 0x10)
-                       return ROM2[physAddr & 0x3FFFF];
-               else if (region == 0x20 && physAddr <= 0x20000FFF)
-                       return etna.readReg8(physAddr & 0xFFF);
-               else if (region == 0x80 && physAddr <= 0x80000FFF)
-                       return readReg8(physAddr & 0xFFF);
+  uint8_t region = (physAddr >> 24) & 0xF1;
+  if (valueSize == V8) {
+    if (region == 0)
+      return ROM[physAddr & 0xFFFFFF];
+    else if (region == 0x10)
+      return ROM2[physAddr & 0x3FFFF];
+    else if (region == 0x20 && physAddr <= 0x20000FFF)
+      return etna.readReg8(physAddr & 0xFFF);
+    else if (region == 0x80 && physAddr <= 0x80000FFF)
+      return readReg8(physAddr & 0xFFF);
 #if defined(INCLUDE_BANK1)
-               else if (region == 0xC0)
-                       return MemoryBlockC0[physAddr & MemoryBlockMask];
-               else if (region == 0xC1)
-                       return MemoryBlockC1[physAddr & MemoryBlockMask];
-               else if (region == 0xD0)
-                       return MemoryBlockD0[physAddr & MemoryBlockMask];
-               else if (region == 0xD1)
-                       return MemoryBlockD1[physAddr & MemoryBlockMask];
+    else if (region == 0xC0)
+      return MemoryBlockC0[physAddr & MemoryBlockMask];
+    else if (region == 0xC1)
+      return MemoryBlockC1[physAddr & MemoryBlockMask];
+    else if (region == 0xD0)
+      return MemoryBlockD0[physAddr & MemoryBlockMask];
+    else if (region == 0xD1)
+      return MemoryBlockD1[physAddr & MemoryBlockMask];
 #elif defined(INCLUDE_D)
-               else if (region == 0xC0 || region == 0xC1)
-                       return MemoryBlockC0[physAddr & MemoryBlockMask];
-               else if (region == 0xD0 || region == 0xD1)
-                       return MemoryBlockD0[physAddr & MemoryBlockMask];
+    else if (region == 0xC0 || region == 0xC1)
+      return MemoryBlockC0[physAddr & MemoryBlockMask];
+    else if (region == 0xD0 || region == 0xD1)
+      return MemoryBlockD0[physAddr & MemoryBlockMask];
 #else
-               else if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0xD1)
-                       return MemoryBlockC0[physAddr & MemoryBlockMask];
+    else if (region == 0xC0 || region == 0xC1 || region == 0xD0 ||
+             region == 0xD1)
+      return MemoryBlockC0[physAddr & MemoryBlockMask];
 #endif
-               else if (region >= 0xC0)
-                       return 0xFF; // just throw accesses to unmapped RAM away
-       } else {
-               uint32_t result;
-               if (region == 0)
-                       LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
-               else if (region == 0x10)
-                       LOAD_32LE(result, physAddr & 0x3FFFF, ROM2);
-               else if (region == 0x20 && physAddr <= 0x20000FFF)
-                       result = etna.readReg32(physAddr & 0xFFF);
-               else if (region == 0x80 && physAddr <= 0x80000FFF)
-                       result = readReg32(physAddr & 0xFFF);
+    else if (region >= 0xC0)
+      return 0xFF; // just throw accesses to unmapped RAM away
+  } else {
+    uint32_t result;
+    if (region == 0)
+      LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
+    else if (region == 0x10)
+      LOAD_32LE(result, physAddr & 0x3FFFF, ROM2);
+    else if (region == 0x20 && physAddr <= 0x20000FFF)
+      result = etna.readReg32(physAddr & 0xFFF);
+    else if (region == 0x80 && physAddr <= 0x80000FFF)
+      result = readReg32(physAddr & 0xFFF);
 #if defined(INCLUDE_BANK1)
-               else if (region == 0xC0)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region == 0xC1)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC1);
-               else if (region == 0xD0)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD0);
-               else if (region == 0xD1)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD1);
+    else if (region == 0xC0)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region == 0xC1)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC1);
+    else if (region == 0xD0)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD0);
+    else if (region == 0xD1)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD1);
 #elif defined(INCLUDE_D)
-               else if (region == 0xC0 || region == 0xC1)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region == 0xD0 || region == 0xD1)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD0);
+    else if (region == 0xC0 || region == 0xC1)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region == 0xD0 || region == 0xD1)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockD0);
 #else
-               else if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0xD1)
-                       LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region == 0xC0 || region == 0xC1 || region == 0xD0 ||
+             region == 0xD1)
+      LOAD_32LE(result, physAddr & MemoryBlockMask, MemoryBlockC0);
 #endif
-               else if (region >= 0xC0)
-                       return 0xFFFFFFFF; // just throw accesses to unmapped RAM away
-               else
-                       return {};
-               return result;
-       }
-
-       return {};
+    else if (region >= 0xC0)
+      return 0xFFFFFFFF; // just throw accesses to unmapped RAM away
+    else
+      return {};
+    return result;
+  }
+
+  return {};
 }
 
-bool Emulator::writePhysical(uint32_t value, uint32_t physAddr, ValueSize valueSize) {
-       uint8_t region = (physAddr >> 24) & 0xF1;
-       if (valueSize == V8) {
+bool Emulator::writePhysical(uint32_t value, uint32_t physAddr,
+                             ValueSize valueSize) {
+  uint8_t region = (physAddr >> 24) & 0xF1;
+  if (valueSize == V8) {
 #if defined(INCLUDE_BANK1)
-               if (region == 0xC0)
-                       MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
-               else if (region == 0xC1)
-                       MemoryBlockC1[physAddr & MemoryBlockMask] = (uint8_t)value;
-               else if (region == 0xD0)
-                       MemoryBlockD0[physAddr & MemoryBlockMask] = (uint8_t)value;
-               else if (region == 0xD1)
-                       MemoryBlockD1[physAddr & MemoryBlockMask] = (uint8_t)value;
+    if (region == 0xC0)
+      MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    else if (region == 0xC1)
+      MemoryBlockC1[physAddr & MemoryBlockMask] = (uint8_t)value;
+    else if (region == 0xD0)
+      MemoryBlockD0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    else if (region == 0xD1)
+      MemoryBlockD1[physAddr & MemoryBlockMask] = (uint8_t)value;
 #elif defined(INCLUDE_D)
-               if (region == 0xC0 || region == 0xC1)
-                       MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
-               else if (region == 0xD0 || region == 0xD1)
-                       MemoryBlockD0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    if (region == 0xC0 || region == 0xC1)
+      MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    else if (region == 0xD0 || region == 0xD1)
+      MemoryBlockD0[physAddr & MemoryBlockMask] = (uint8_t)value;
 #else
-               if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0xD1)
-                       MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
+    if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0xD1)
+      MemoryBlockC0[physAddr & MemoryBlockMask] = (uint8_t)value;
 #endif
-               else if (region >= 0xC0)
-                       return true; // just throw accesses to unmapped RAM away
-               else if (region == 0x20 && physAddr <= 0x20000FFF)
-                       etna.writeReg8(physAddr & 0xFFF, value);
-               else if (region == 0x80 && physAddr <= 0x80000FFF)
-                       writeReg8(physAddr & 0xFFF, value);
-               else
-                       return false;
-       } else {
-               uint8_t region = (physAddr >> 24) & 0xF1;
+    else if (region >= 0xC0)
+      return true; // just throw accesses to unmapped RAM away
+    else if (region == 0x20 && physAddr <= 0x20000FFF)
+      etna.writeReg8(physAddr & 0xFFF, value);
+    else if (region == 0x80 && physAddr <= 0x80000FFF)
+      writeReg8(physAddr & 0xFFF, value);
+    else
+      return false;
+  } else {
+    uint8_t region = (physAddr >> 24) & 0xF1;
 #if defined(INCLUDE_BANK1)
-               if (region == 0xC0)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region == 0xC1)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC1);
-               else if (region == 0xD0)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD0);
-               else if (region == 0xD1)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD1);
+    if (region == 0xC0)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region == 0xC1)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC1);
+    else if (region == 0xD0)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD0);
+    else if (region == 0xD1)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD1);
 #elif defined(INCLUDE_D)
-               if (region == 0xC0 || region == 0xC1)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
-               else if (region == 0xD0 || region == 0xD1)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD0);
+    if (region == 0xC0 || region == 0xC1)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
+    else if (region == 0xD0 || region == 0xD1)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockD0);
 #else
-               if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0x01)
-                       STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
+    if (region == 0xC0 || region == 0xC1 || region == 0xD0 || region == 0x01)
+      STORE_32LE(value, physAddr & MemoryBlockMask, MemoryBlockC0);
 #endif
-               else if (region >= 0xC0)
-                       return true; // just throw accesses to unmapped RAM away
-               else if (region == 0x20 && physAddr <= 0x20000FFF)
-                       etna.writeReg32(physAddr & 0xFFF, value);
-               else if (region == 0x80 && physAddr <= 0x80000FFF)
-                       writeReg32(physAddr & 0xFFF, value);
-               else
-                       return false;
-       }
-       return true;
+    else if (region >= 0xC0)
+      return true; // just throw accesses to unmapped RAM away
+    else if (region == 0x20 && physAddr <= 0x20000FFF)
+      etna.writeReg32(physAddr & 0xFFF, value);
+    else if (region == 0x80 && physAddr <= 0x80000FFF)
+      writeReg32(physAddr & 0xFFF, value);
+    else
+      return false;
+  }
+  return true;
 }
 
-
-
 void Emulator::configure() {
-       if (configured) return;
-       configured = true;
+  if (configured)
+    return;
+  configured = true;
 
-       srand(1000);
+  srand(1000);
 
-       uart1.cpu = this;
-       uart2.cpu = this;
-       memset(&tc1, 0, sizeof(tc1));
-       memset(&tc2, 0, sizeof(tc1));
-       tc1.clockSpeed = CLOCK_SPEED;
-       tc2.clockSpeed = CLOCK_SPEED;
+  uart1.cpu = this;
+  uart2.cpu = this;
+  memset(&tc1, 0, sizeof(tc1));
+  memset(&tc2, 0, sizeof(tc1));
+  tc1.clockSpeed = CLOCK_SPEED;
+  tc2.clockSpeed = CLOCK_SPEED;
 
-       nextTickAt = TICK_INTERVAL;
-       tc1.nextTickAt = tc1.tickInterval();
-       tc2.nextTickAt = tc2.tickInterval();
-       rtc = getRTC();
+  nextTickAt = TICK_INTERVAL;
+  tc1.nextTickAt = tc1.tickInterval();
+  tc2.nextTickAt = tc2.tickInterval();
+  rtc = getRTC();
 
-       reset();
+  reset();
 }
 
-uint8_t *Emulator::getROMBuffer() {
-       return ROM;
-}
-size_t Emulator::getROMSize() {
-       return sizeof(ROM);
-}
-void Emulator::loadROM(uint8_t *buffer, size_t size) {
-       memcpy(ROM, buffer, min(size, sizeof(ROM)));
+uint8_t* Emulator::getROMBuffer() { return ROM; }
+size_t Emulator::getROMSize() { return sizeof(ROM); }
+void Emulator::loadROM(uint8_t* buffer, size_t size) {
+  memcpy(ROM, buffer, min(size, sizeof(ROM)));
 }
 
 void Emulator::executeUntil(int64_t cycles) {
-       if (!configured)
-               configure();
-
-       while (!asleep && passedCycles < cycles) {
-               if (passedCycles >= nextTickAt) {
-                       // increment RTCDIV
-                       if ((pwrsr & 0x3F) == 0x3F) {
-                               rtc++;
-                               pwrsr &= ~0x3F;
-                       } else {
-                               pwrsr++;
-                       }
-
-                       nextTickAt += TICK_INTERVAL;
-                       pendingInterrupts |= (1<<TINT);
-               }
-               if (tc1.tick(passedCycles))
-                       pendingInterrupts |= (1<<TC1OI);
-               if (tc2.tick(passedCycles))
-                       pendingInterrupts |= (1<<TC2OI);
-
-               if ((pendingInterrupts & interruptMask & FIQ_INTERRUPTS) != 0 && canAcceptFIQ()) {
-                       requestFIQ();
-                       halted = false;
-               }
-               if ((pendingInterrupts & interruptMask & IRQ_INTERRUPTS) != 0 && canAcceptIRQ()) {
-                       requestIRQ();
-                       halted = false;
-               }
-
-               // what's running?
-               if (halted) {
-                       // keep the clock moving
-                       // when does the next earliest thing happen?
-                       // this stops us from spinning needlessly
-                       int64_t nextEvent = nextTickAt;
-                       if (tc1.nextTickAt < nextEvent) nextEvent = tc1.nextTickAt;
-                       if (tc2.nextTickAt < nextEvent) nextEvent = tc2.nextTickAt;
-                       if (cycles < nextEvent) nextEvent = cycles;
-                       passedCycles = nextEvent;
-               } else {
-                       if (auto v = virtToPhys(getGPR(15) - 0xC); v.has_value() && instructionReady())
-                               debugPC(v.value());
-                       passedCycles += tick();
+  if (!configured)
+    configure();
+
+  while (!asleep && passedCycles < cycles) {
+    if (passedCycles >= nextTickAt) {
+      // increment RTCDIV
+      if ((pwrsr & 0x3F) == 0x3F) {
+        rtc++;
+        pwrsr &= ~0x3F;
+      } else {
+        pwrsr++;
+      }
+
+      nextTickAt += TICK_INTERVAL;
+      pendingInterrupts |= (1 << TINT);
+    }
+    if (tc1.tick(passedCycles))
+      pendingInterrupts |= (1 << TC1OI);
+    if (tc2.tick(passedCycles))
+      pendingInterrupts |= (1 << TC2OI);
+
+    if ((pendingInterrupts & interruptMask & FIQ_INTERRUPTS) != 0 &&
+        canAcceptFIQ()) {
+      requestFIQ();
+      halted = false;
+    }
+    if ((pendingInterrupts & interruptMask & IRQ_INTERRUPTS) != 0 &&
+        canAcceptIRQ()) {
+      requestIRQ();
+      halted = false;
+    }
+
+    // what's running?
+    if (halted) {
+      // keep the clock moving
+      // when does the next earliest thing happen?
+      // this stops us from spinning needlessly
+      int64_t nextEvent = nextTickAt;
+      if (tc1.nextTickAt < nextEvent)
+        nextEvent = tc1.nextTickAt;
+      if (tc2.nextTickAt < nextEvent)
+        nextEvent = tc2.nextTickAt;
+      if (cycles < nextEvent)
+        nextEvent = cycles;
+      passedCycles = nextEvent;
+    } else {
+      if (auto v = virtToPhys(getGPR(15) - 0xC);
+          v.has_value() && instructionReady())
+        debugPC(v.value());
+      passedCycles += tick();
 
 #ifndef __EMSCRIPTEN__
-                       uint32_t new_pc = getGPR(15) - 0xC;
-                       if (_breakpoints.find(new_pc) != _breakpoints.end()) {
-                               log("⚠️ Breakpoint triggered at %08x!", new_pc);
-                               return;
-                       }
+      uint32_t new_pc = getGPR(15) - 0xC;
+      if (_breakpoints.find(new_pc) != _breakpoints.end()) {
+        log("⚠️ Breakpoint triggered at %08x!", new_pc);
+        return;
+      }
 #endif
-               }
-       }
+    }
+  }
 }
 
-
-const char *Emulator::identifyObjectCon(uint32_t ptr) {
-       if (ptr == readVirtualDebug(0x80000980, V32).value()) return "process";
-       if (ptr == readVirtualDebug(0x80000984, V32).value()) return "thread";
-       if (ptr == readVirtualDebug(0x80000988, V32).value()) return "chunk";
-//     if (ptr == readVirtualDebug(0x8000098C, V32).value()) return "semaphore";
-//     if (ptr == readVirtualDebug(0x80000990, V32).value()) return "mutex";
-       if (ptr == readVirtualDebug(0x80000994, V32).value()) return "logicaldevice";
-       if (ptr == readVirtualDebug(0x80000998, V32).value()) return "physicaldevice";
-       if (ptr == readVirtualDebug(0x8000099C, V32).value()) return "channel";
-       if (ptr == readVirtualDebug(0x800009A0, V32).value()) return "server";
-//     if (ptr == readVirtualDebug(0x800009A4, V32).value()) return "unk9A4"; // name always null
-       if (ptr == readVirtualDebug(0x800009AC, V32).value()) return "library";
-//     if (ptr == readVirtualDebug(0x800009B0, V32).value()) return "unk9B0"; // name always null
-//     if (ptr == readVirtualDebug(0x800009B4, V32).value()) return "unk9B4"; // name always null
-       return NULL;
+const char* Emulator::identifyObjectCon(uint32_t ptr) {
+  if (ptr == readVirtualDebug(0x80000980, V32).value())
+    return "process";
+  if (ptr == readVirtualDebug(0x80000984, V32).value())
+    return "thread";
+  if (ptr == readVirtualDebug(0x80000988, V32).value())
+    return "chunk";
+  //   if (ptr == readVirtualDebug(0x8000098C, V32).value()) return
+  //"semaphore";       if (ptr == readVirtualDebug(0x80000990, V32).value())
+  //return "mutex";
+  if (ptr == readVirtualDebug(0x80000994, V32).value())
+    return "logicaldevice";
+  if (ptr == readVirtualDebug(0x80000998, V32).value())
+    return "physicaldevice";
+  if (ptr == readVirtualDebug(0x8000099C, V32).value())
+    return "channel";
+  if (ptr == readVirtualDebug(0x800009A0, V32).value())
+    return "server";
+  //   if (ptr == readVirtualDebug(0x800009A4, V32).value()) return "unk9A4";
+  //// name always null
+  if (ptr == readVirtualDebug(0x800009AC, V32).value())
+    return "library";
+  //   if (ptr == readVirtualDebug(0x800009B0, V32).value()) return "unk9B0";
+  //// name always null        if (ptr == readVirtualDebug(0x800009B4,
+  ///V32).value())
+  // return "unk9B4"; // name always null
+  return NULL;
 }
 
-void Emulator::fetchStr(uint32_t str, char *buf) {
-       if (str == 0) {
-               strcpy(buf, "<NULL>");
-               return;
-       }
-       int size = readVirtualDebug(str, V32).value();
-       for (int i = 0; i < size; i++) {
-               buf[i] = readVirtualDebug(str + 4 + i, V8).value();
-       }
-       buf[size] = 0;
+void Emulator::fetchStr(uint32_t str, charbuf) {
+  if (str == 0) {
+    strcpy(buf, "<NULL>");
+    return;
+  }
+  int size = readVirtualDebug(str, V32).value();
+  for (int i = 0; i < size; i++) {
+    buf[i] = readVirtualDebug(str + 4 + i, V8).value();
+  }
+  buf[size] = 0;
 }
 
-void Emulator::fetchName(uint32_t obj, char *buf) {
-       fetchStr(readVirtualDebug(obj + 0x10, V32).value(), buf);
+void Emulator::fetchName(uint32_t obj, charbuf) {
+  fetchStr(readVirtualDebug(obj + 0x10, V32).value(), buf);
 }
 
-void Emulator::fetchProcessFilename(uint32_t obj, char *buf) {
-       fetchStr(readVirtualDebug(obj + 0x3C, V32).value(), buf);
+void Emulator::fetchProcessFilename(uint32_t obj, charbuf) {
+  fetchStr(readVirtualDebug(obj + 0x3C, V32).value(), buf);
 }
 
 void Emulator::debugPC(uint32_t pc) {
-       char objName[1000];
-       if (pc == 0x2CBC4) {
-               // CObjectCon::AddL()
-               uint32_t container = getGPR(0);
-               uint32_t obj = getGPR(1);
-               const char *wut = identifyObjectCon(container);
-               if (wut) {
-                       fetchName(obj, objName);
-                       if (strcmp(wut, "process") == 0) {
-                               char procName[1000];
-                               fetchProcessFilename(obj, procName);
-                               log("OBJS: added %s at %08x <%s> <%s>", wut, obj, objName, procName);
-                       } else {
-                               log("OBJS: added %s at %08x <%s>", wut, obj, objName);
-                       }
-               }
-       }
-
-       if (pc == 0x6D8) {
-               uint32_t virtAddr = getGPR(0);
-               uint32_t physAddr = getGPR(1);
-               uint32_t btIndex = getGPR(2);
-               uint32_t regionSize = getGPR(3);
-               log("KERNEL MMU SECTION: v:%08x p:%08x size:%08x idx:%02x",
-                       virtAddr, physAddr, regionSize, btIndex);
-       }
-       if (pc == 0x710) {
-               uint32_t virtAddr = getGPR(0);
-               uint32_t physAddr = getGPR(1);
-               uint32_t btIndex = getGPR(2);
-               uint32_t regionSize = getGPR(3);
-               uint32_t pageTableA = getGPR(4);
-               uint32_t pageTableB = getGPR(5);
-               log("KERNEL MMU PAGES: v:%08x p:%08x size:%08x idx:%02x tableA:%08x tableB:%08x",
-                       virtAddr, physAddr, regionSize, btIndex, pageTableA, pageTableB);
-       }
-
-       if (pc == 0x1576C) {
-               uint32_t rawEvent = getGPR(0);
-               uint32_t evtType = readVirtualDebug(rawEvent, V32).value_or(0);
-               uint32_t evtTick = readVirtualDebug(rawEvent + 4, V32).value_or(0);
-               uint32_t evtParamA = readVirtualDebug(rawEvent + 8, V32).value_or(0);
-               uint32_t evtParamB = readVirtualDebug(rawEvent + 0xC, V32).value_or(0);
-               const char *n = "???";
-               switch (evtType) {
-               case 0: n = "ENone"; break;
-               case 1: n = "EPointerMove"; break;
-               case 2: n = "EPointerSwitchOn"; break;
-               case 3: n = "EKeyDown"; break;
-               case 4: n = "EKeyUp"; break;
-               case 5: n = "ERedraw"; break;
-               case 6: n = "ESwitchOn"; break;
-               case 7: n = "EActive"; break;
-               case 8: n = "EInactive"; break;
-               case 9: n = "EUpdateModifiers"; break;
-               case 10: n = "EButton1Down"; break;
-               case 11: n = "EButton1Up"; break;
-               case 12: n = "EButton2Down"; break;
-               case 13: n = "EButton2Up"; break;
-               case 14: n = "EButton3Down"; break;
-               case 15: n = "EButton3Up"; break;
-               case 16: n = "ESwitchOff"; break;
-               }
-               log("EVENT %s: tick=%d params=%d,%d", n, evtTick, evtParamA, evtParamB);
-       }
+  char objName[1000];
+  if (pc == 0x2CBC4) {
+    // CObjectCon::AddL()
+    uint32_t container = getGPR(0);
+    uint32_t obj = getGPR(1);
+    const char* wut = identifyObjectCon(container);
+    if (wut) {
+      fetchName(obj, objName);
+      if (strcmp(wut, "process") == 0) {
+        char procName[1000];
+        fetchProcessFilename(obj, procName);
+        log("OBJS: added %s at %08x <%s> <%s>", wut, obj, objName, procName);
+      } else {
+        log("OBJS: added %s at %08x <%s>", wut, obj, objName);
+      }
+    }
+  }
+
+  if (pc == 0x6D8) {
+    uint32_t virtAddr = getGPR(0);
+    uint32_t physAddr = getGPR(1);
+    uint32_t btIndex = getGPR(2);
+    uint32_t regionSize = getGPR(3);
+    log("KERNEL MMU SECTION: v:%08x p:%08x size:%08x idx:%02x", virtAddr,
+        physAddr, regionSize, btIndex);
+  }
+  if (pc == 0x710) {
+    uint32_t virtAddr = getGPR(0);
+    uint32_t physAddr = getGPR(1);
+    uint32_t btIndex = getGPR(2);
+    uint32_t regionSize = getGPR(3);
+    uint32_t pageTableA = getGPR(4);
+    uint32_t pageTableB = getGPR(5);
+    log("KERNEL MMU PAGES: v:%08x p:%08x size:%08x idx:%02x tableA:%08x "
+        "tableB:%08x",
+        virtAddr, physAddr, regionSize, btIndex, pageTableA, pageTableB);
+  }
+
+  if (pc == 0x1576C) {
+    uint32_t rawEvent = getGPR(0);
+    uint32_t evtType = readVirtualDebug(rawEvent, V32).value_or(0);
+    uint32_t evtTick = readVirtualDebug(rawEvent + 4, V32).value_or(0);
+    uint32_t evtParamA = readVirtualDebug(rawEvent + 8, V32).value_or(0);
+    uint32_t evtParamB = readVirtualDebug(rawEvent + 0xC, V32).value_or(0);
+    const char* n = "???";
+    switch (evtType) {
+    case 0:
+      n = "ENone";
+      break;
+    case 1:
+      n = "EPointerMove";
+      break;
+    case 2:
+      n = "EPointerSwitchOn";
+      break;
+    case 3:
+      n = "EKeyDown";
+      break;
+    case 4:
+      n = "EKeyUp";
+      break;
+    case 5:
+      n = "ERedraw";
+      break;
+    case 6:
+      n = "ESwitchOn";
+      break;
+    case 7:
+      n = "EActive";
+      break;
+    case 8:
+      n = "EInactive";
+      break;
+    case 9:
+      n = "EUpdateModifiers";
+      break;
+    case 10:
+      n = "EButton1Down";
+      break;
+    case 11:
+      n = "EButton1Up";
+      break;
+    case 12:
+      n = "EButton2Down";
+      break;
+    case 13:
+      n = "EButton2Up";
+      break;
+    case 14:
+      n = "EButton3Down";
+      break;
+    case 15:
+      n = "EButton3Up";
+      break;
+    case 16:
+      n = "ESwitchOff";
+      break;
+    }
+    log("EVENT %s: tick=%d params=%d,%d", n, evtTick, evtParamA, evtParamB);
+  }
 }
 
-
-const char *Emulator::getDeviceName() const { return "Series 5mx"; }
-int Emulator::getDigitiserWidth()  const { return 695; }
+const char* Emulator::getDeviceName() const { return "Series 5mx"; }
+int Emulator::getDigitiserWidth() const { return 695; }
 int Emulator::getDigitiserHeight() const { return 280; }
-int Emulator::getLCDOffsetX()      const { return 45; }
-int Emulator::getLCDOffsetY()      const { return 5; }
-int Emulator::getLCDWidth()        const { return 640; }
-int Emulator::getLCDHeight()       const { return 240; }
+int Emulator::getLCDOffsetX() const { return 45; }
+int Emulator::getLCDOffsetY() const { return 5; }
+int Emulator::getLCDWidth() const { return 640; }
+int Emulator::getLCDHeight() const { return 240; }
 
 // TODO move this elsewhere
 static bool initRgbValues = false;
 static uint32_t rgbValues[16];
 
-void Emulator::readLCDIntoBuffer(uint8_t **lines, bool is32BitOutput) const {
-       if (!initRgbValues) {
-               initRgbValues = true;
-               for (int i = 0; i < 16; i++) {
-                       int r = (0x99 * i) / 15;
-                       int g = (0xAA * i) / 15;
-                       int b = (0x88 * i) / 15;
-                       rgbValues[15 - i] = r | (g << 8) | (b << 16) | 0xFF000000;
-               }
-       }
-
-       if ((lcdAddress >> 24) == 0xC0) {
-               const uint8_t *lcdBuf = &MemoryBlockC0[lcdAddress & MemoryBlockMask];
-               int width = 640, height = 240;
-
-               // fetch palette
-               int bpp = 1 << (lcdBuf[1] >> 4);
-               int ppb = 8 / bpp;
-               uint16_t palette[16];
-               for (int i = 0; i < 16; i++)
-                       palette[i] = lcdBuf[i*2] | ((lcdBuf[i*2+1] << 8) & 0xF00);
-
-               // build our image out
-               int lineWidth = (width * bpp) / 8;
-               for (int y = 0; y < height; y++) {
-                       int lineOffs = 0x20 + (lineWidth * y);
-                       for (int x = 0; x < width; x++) {
-                               uint8_t byte = lcdBuf[lineOffs + (x / ppb)];
-                               int shift = (x & (ppb - 1)) * bpp;
-                               int mask = (1 << bpp) - 1;
-                               int palIdx = (byte >> shift) & mask;
-                               int palValue = palette[palIdx];
-
-                               if (is32BitOutput) {
-                                       auto line = (uint32_t *)lines[y];
-                                       line[x] = rgbValues[palValue];
-                               } else {
-                                       palValue |= (palValue << 4);
-                                       lines[y][x] = palValue ^ 0xFF;
-                               }
-                       }
-               }
-       }
+void Emulator::readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const {
+  if (!initRgbValues) {
+    initRgbValues = true;
+    for (int i = 0; i < 16; i++) {
+      int r = (0x99 * i) / 15;
+      int g = (0xAA * i) / 15;
+      int b = (0x88 * i) / 15;
+      rgbValues[15 - i] = r | (g << 8) | (b << 16) | 0xFF000000;
+    }
+  }
+
+  if ((lcdAddress >> 24) == 0xC0) {
+    const uint8_t* lcdBuf = &MemoryBlockC0[lcdAddress & MemoryBlockMask];
+    int width = 640, height = 240;
+
+    // fetch palette
+    int bpp = 1 << (lcdBuf[1] >> 4);
+    int ppb = 8 / bpp;
+    uint16_t palette[16];
+    for (int i = 0; i < 16; i++)
+      palette[i] = lcdBuf[i * 2] | ((lcdBuf[i * 2 + 1] << 8) & 0xF00);
+
+    // build our image out
+    int lineWidth = (width * bpp) / 8;
+    for (int y = 0; y < height; y++) {
+      int lineOffs = 0x20 + (lineWidth * y);
+      for (int x = 0; x < width; x++) {
+        uint8_t byte = lcdBuf[lineOffs + (x / ppb)];
+        int shift = (x & (ppb - 1)) * bpp;
+        int mask = (1 << bpp) - 1;
+        int palIdx = (byte >> shift) & mask;
+        int palValue = palette[palIdx];
+
+        if (is32BitOutput) {
+          auto line = (uint32_t*)lines[y];
+          line[x] = rgbValues[palValue];
+        } else {
+          palValue |= (palValue << 4);
+          lines[y][x] = palValue ^ 0xFF;
+        }
+      }
+    }
+  }
 }
 
-
 void Emulator::diffPorts(uint32_t oldval, uint32_t newval) {
-       uint32_t changes = oldval ^ newval;
-       if (changes & 1) log("PRT codec enable: %d", newval&1);
-       if (changes & 2) log("PRT audio amp enable: %d", newval&2);
-       if (changes & 4) log("PRT lcd power: %d", newval&4);
-       if (changes & 8) log("PRT etna door: %d", newval&8);
-       if (changes & 0x10) log("PRT sled: %d", newval&0x10);
-       if (changes & 0x20) log("PRT pump pwr2: %d", newval&0x20);
-       if (changes & 0x40) log("PRT pump pwr1: %d", newval&0x40);
-       if (changes & 0x80) log("PRT etna err: %d", newval&0x80);
-       if (changes & 0x100) log("PRT rs-232 rts: %d", newval&0x100);
-       if (changes & 0x200) log("PRT rs-232 dtr toggle: %d", newval&0x200);
-       if (changes & 0x400) log("PRT disable power led: %d", newval&0x400);
-       if (changes & 0x800) log("PRT enable uart1: %d", newval&0x800);
-       if (changes & 0x1000) log("PRT lcd backlight: %d", newval&0x1000);
-       if (changes & 0x2000) log("PRT enable uart0: %d", newval&0x2000);
-       if (changes & 0x4000) log("PRT dictaphone: %d", newval&0x4000);
-// PROM read process makes this super spammy in stdout
-//     if (changes & 0x10000) log("PRT EECS: %d", newval&0x10000);
-//     if (changes & 0x20000) log("PRT EECLK: %d", newval&0x20000);
-       if (changes & 0x40000) log("PRT contrast0: %d", newval&0x40000);
-       if (changes & 0x80000) log("PRT contrast1: %d", newval&0x80000);
-       if (changes & 0x100000) log("PRT contrast2: %d", newval&0x100000);
-       if (changes & 0x200000) log("PRT contrast3: %d", newval&0x200000);
-       if (changes & 0x400000) log("PRT case open: %d", newval&0x400000);
-       if (changes & 0x800000) log("PRT etna cf power: %d", newval&0x800000);
+  uint32_t changes = oldval ^ newval;
+  if (changes & 1)
+    log("PRT codec enable: %d", newval & 1);
+  if (changes & 2)
+    log("PRT audio amp enable: %d", newval & 2);
+  if (changes & 4)
+    log("PRT lcd power: %d", newval & 4);
+  if (changes & 8)
+    log("PRT etna door: %d", newval & 8);
+  if (changes & 0x10)
+    log("PRT sled: %d", newval & 0x10);
+  if (changes & 0x20)
+    log("PRT pump pwr2: %d", newval & 0x20);
+  if (changes & 0x40)
+    log("PRT pump pwr1: %d", newval & 0x40);
+  if (changes & 0x80)
+    log("PRT etna err: %d", newval & 0x80);
+  if (changes & 0x100)
+    log("PRT rs-232 rts: %d", newval & 0x100);
+  if (changes & 0x200)
+    log("PRT rs-232 dtr toggle: %d", newval & 0x200);
+  if (changes & 0x400)
+    log("PRT disable power led: %d", newval & 0x400);
+  if (changes & 0x800)
+    log("PRT enable uart1: %d", newval & 0x800);
+  if (changes & 0x1000)
+    log("PRT lcd backlight: %d", newval & 0x1000);
+  if (changes & 0x2000)
+    log("PRT enable uart0: %d", newval & 0x2000);
+  if (changes & 0x4000)
+    log("PRT dictaphone: %d", newval & 0x4000);
+  // PROM read process makes this super spammy in stdout
+  //   if (changes & 0x10000) log("PRT EECS: %d", newval&0x10000);
+  //   if (changes & 0x20000) log("PRT EECLK: %d", newval&0x20000);
+  if (changes & 0x40000)
+    log("PRT contrast0: %d", newval & 0x40000);
+  if (changes & 0x80000)
+    log("PRT contrast1: %d", newval & 0x80000);
+  if (changes & 0x100000)
+    log("PRT contrast2: %d", newval & 0x100000);
+  if (changes & 0x200000)
+    log("PRT contrast3: %d", newval & 0x200000);
+  if (changes & 0x400000)
+    log("PRT case open: %d", newval & 0x400000);
+  if (changes & 0x800000)
+    log("PRT etna cf power: %d", newval & 0x800000);
 }
 
 void Emulator::diffInterrupts(uint16_t oldval, uint16_t newval) {
-       uint16_t changes = oldval ^ newval;
-       if (changes & 1) log("INTCHG external=%d", newval & 1);
-       if (changes & 2) log("INTCHG lowbat=%d", newval & 2);
-       if (changes & 4) log("INTCHG watchdog=%d", newval & 4);
-       if (changes & 8) log("INTCHG mediachg=%d", newval & 8);
-       if (changes & 0x10) log("INTCHG codec=%d", newval & 0x10);
-       if (changes & 0x20) log("INTCHG ext1=%d", newval & 0x20);
-       if (changes & 0x40) log("INTCHG ext2=%d", newval & 0x40);
-       if (changes & 0x80) log("INTCHG ext3=%d", newval & 0x80);
-       if (changes & 0x100) log("INTCHG timer1=%d", newval & 0x100);
-       if (changes & 0x200) log("INTCHG timer2=%d", newval & 0x200);
-       if (changes & 0x400) log("INTCHG rtcmatch=%d", newval & 0x400);
-       if (changes & 0x800) log("INTCHG tick=%d", newval & 0x800);
-       if (changes & 0x1000) log("INTCHG uart1=%d", newval & 0x1000);
-       if (changes & 0x2000) log("INTCHG uart2=%d", newval & 0x2000);
-       if (changes & 0x4000) log("INTCHG lcd=%d", newval & 0x4000);
-       if (changes & 0x8000) log("INTCHG spi=%d", newval & 0x8000);
+  uint16_t changes = oldval ^ newval;
+  if (changes & 1)
+    log("INTCHG external=%d", newval & 1);
+  if (changes & 2)
+    log("INTCHG lowbat=%d", newval & 2);
+  if (changes & 4)
+    log("INTCHG watchdog=%d", newval & 4);
+  if (changes & 8)
+    log("INTCHG mediachg=%d", newval & 8);
+  if (changes & 0x10)
+    log("INTCHG codec=%d", newval & 0x10);
+  if (changes & 0x20)
+    log("INTCHG ext1=%d", newval & 0x20);
+  if (changes & 0x40)
+    log("INTCHG ext2=%d", newval & 0x40);
+  if (changes & 0x80)
+    log("INTCHG ext3=%d", newval & 0x80);
+  if (changes & 0x100)
+    log("INTCHG timer1=%d", newval & 0x100);
+  if (changes & 0x200)
+    log("INTCHG timer2=%d", newval & 0x200);
+  if (changes & 0x400)
+    log("INTCHG rtcmatch=%d", newval & 0x400);
+  if (changes & 0x800)
+    log("INTCHG tick=%d", newval & 0x800);
+  if (changes & 0x1000)
+    log("INTCHG uart1=%d", newval & 0x1000);
+  if (changes & 0x2000)
+    log("INTCHG uart2=%d", newval & 0x2000);
+  if (changes & 0x4000)
+    log("INTCHG lcd=%d", newval & 0x4000);
+  if (changes & 0x8000)
+    log("INTCHG spi=%d", newval & 0x8000);
 }
 
-
 uint32_t Emulator::readKeyboard() {
-       if (kScan & 8) {
-               // Select one keyboard
-               return keyboardColumns[kScan & 7];
-       } else if (kScan == 0) {
-               // Report all columns combined
-               uint8_t val = 0;
-               for (int i = 0; i < 8; i++)
-                       val |= keyboardColumns[i];
-               return val;
-       } else {
-               return 0;
-       }
+  if (kScan & 8) {
+    // Select one keyboard
+    return keyboardColumns[kScan & 7];
+  } else if (kScan == 0) {
+    // Report all columns combined
+    uint8_t val = 0;
+    for (int i = 0; i < 8; i++)
+      val |= keyboardColumns[i];
+    return val;
+  } else {
+    return 0;
+  }
 }
 
 void Emulator::setKeyboardKey(EpocKey key, bool value) {
-       int idx = -1;
-#define KEY(column, bit) idx = (column << 8) | (1 << bit); break
-
-       switch ((int)key) {
-       case EStdKeyDictaphoneRecord: KEY(0, 6);
-       case '1':                     KEY(0, 5);
-       case '2':                     KEY(0, 4);
-       case '3':                     KEY(0, 3);
-       case '4':                     KEY(0, 2);
-       case '5':                     KEY(0, 1);
-       case '6':                     KEY(0, 0);
-
-       case EStdKeyDictaphonePlay:   KEY(1, 6);
-       case '7':                     KEY(1, 5);
-       case '8':                     KEY(1, 4);
-       case '9':                     KEY(1, 3);
-       case '0':                     KEY(1, 2);
-       case EStdKeyBackspace:        KEY(1, 1);
-       case EStdKeySingleQuote:      KEY(1, 0);
-
-       case EStdKeyEscape:           KEY(2, 6);
-       case 'Q':                     KEY(2, 5);
-       case 'W':                     KEY(2, 4);
-       case 'E':                     KEY(2, 3);
-       case 'R':                     KEY(2, 2);
-       case 'T':                     KEY(2, 1);
-       case 'Y':                     KEY(2, 0);
-
-       case EStdKeyMenu:             KEY(3, 6);
-       case 'U':                     KEY(3, 5);
-       case 'I':                     KEY(3, 4);
-       case 'O':                     KEY(3, 3);
-       case 'P':                     KEY(3, 2);
-       case 'L':                     KEY(3, 1);
-       case EStdKeyEnter:            KEY(3, 0);
-
-       case EStdKeyLeftCtrl:         KEY(4, 6);
-       case EStdKeyTab:              KEY(4, 5);
-       case 'A':                     KEY(4, 4);
-       case 'S':                     KEY(4, 3);
-       case 'D':                     KEY(4, 2);
-       case 'F':                     KEY(4, 1);
-       case 'G':                     KEY(4, 0);
-
-       case EStdKeyLeftFunc:         KEY(5, 6);
-       case 'H':                     KEY(5, 5);
-       case 'J':                     KEY(5, 4);
-       case 'K':                     KEY(5, 3);
-       case 'M':                     KEY(5, 2);
-       case EStdKeyFullStop:         KEY(5, 1);
-       case EStdKeyDownArrow:        KEY(5, 0);
-
-       case EStdKeyRightShift:       KEY(6, 6);
-       case 'Z':                     KEY(6, 5);
-       case 'X':                     KEY(6, 4);
-       case 'C':                     KEY(6, 3);
-       case 'V':                     KEY(6, 2);
-       case 'B':                     KEY(6, 1);
-       case 'N':                     KEY(6, 0);
-
-       case EStdKeyLeftShift:        KEY(7, 6);
-       case EStdKeyDictaphoneStop:   KEY(7, 5);
-       case EStdKeySpace:            KEY(7, 4);
-       case EStdKeyUpArrow:          KEY(7, 3);
-       case EStdKeyComma:            KEY(7, 2);
-       case EStdKeyLeftArrow:        KEY(7, 1);
-       case EStdKeyRightArrow:       KEY(7, 0);
-       }
-
-       if (idx >= 0) {
-               if (value)
-                       keyboardColumns[idx >> 8] |= (idx & 0xFF);
-               else
-                       keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
-       }
+  int idx = -1;
+#define KEY(column, bit)                                                       \
+  idx = (column << 8) | (1 << bit);                                            \
+  break
+
+  switch ((int)key) {
+  case EStdKeyDictaphoneRecord:
+    KEY(0, 6);
+  case '1':
+    KEY(0, 5);
+  case '2':
+    KEY(0, 4);
+  case '3':
+    KEY(0, 3);
+  case '4':
+    KEY(0, 2);
+  case '5':
+    KEY(0, 1);
+  case '6':
+    KEY(0, 0);
+
+  case EStdKeyDictaphonePlay:
+    KEY(1, 6);
+  case '7':
+    KEY(1, 5);
+  case '8':
+    KEY(1, 4);
+  case '9':
+    KEY(1, 3);
+  case '0':
+    KEY(1, 2);
+  case EStdKeyBackspace:
+    KEY(1, 1);
+  case EStdKeySingleQuote:
+    KEY(1, 0);
+
+  case EStdKeyEscape:
+    KEY(2, 6);
+  case 'Q':
+    KEY(2, 5);
+  case 'W':
+    KEY(2, 4);
+  case 'E':
+    KEY(2, 3);
+  case 'R':
+    KEY(2, 2);
+  case 'T':
+    KEY(2, 1);
+  case 'Y':
+    KEY(2, 0);
+
+  case EStdKeyMenu:
+    KEY(3, 6);
+  case 'U':
+    KEY(3, 5);
+  case 'I':
+    KEY(3, 4);
+  case 'O':
+    KEY(3, 3);
+  case 'P':
+    KEY(3, 2);
+  case 'L':
+    KEY(3, 1);
+  case EStdKeyEnter:
+    KEY(3, 0);
+
+  case EStdKeyLeftCtrl:
+    KEY(4, 6);
+  case EStdKeyTab:
+    KEY(4, 5);
+  case 'A':
+    KEY(4, 4);
+  case 'S':
+    KEY(4, 3);
+  case 'D':
+    KEY(4, 2);
+  case 'F':
+    KEY(4, 1);
+  case 'G':
+    KEY(4, 0);
+
+  case EStdKeyLeftFunc:
+    KEY(5, 6);
+  case 'H':
+    KEY(5, 5);
+  case 'J':
+    KEY(5, 4);
+  case 'K':
+    KEY(5, 3);
+  case 'M':
+    KEY(5, 2);
+  case EStdKeyFullStop:
+    KEY(5, 1);
+  case EStdKeyDownArrow:
+    KEY(5, 0);
+
+  case EStdKeyRightShift:
+    KEY(6, 6);
+  case 'Z':
+    KEY(6, 5);
+  case 'X':
+    KEY(6, 4);
+  case 'C':
+    KEY(6, 3);
+  case 'V':
+    KEY(6, 2);
+  case 'B':
+    KEY(6, 1);
+  case 'N':
+    KEY(6, 0);
+
+  case EStdKeyLeftShift:
+    KEY(7, 6);
+  case EStdKeyDictaphoneStop:
+    KEY(7, 5);
+  case EStdKeySpace:
+    KEY(7, 4);
+  case EStdKeyUpArrow:
+    KEY(7, 3);
+  case EStdKeyComma:
+    KEY(7, 2);
+  case EStdKeyLeftArrow:
+    KEY(7, 1);
+  case EStdKeyRightArrow:
+    KEY(7, 0);
+  }
+
+  if (idx >= 0) {
+    if (value)
+      keyboardColumns[idx >> 8] |= (idx & 0xFF);
+    else
+      keyboardColumns[idx >> 8] &= ~(idx & 0xFF);
+  }
 }
 
 void Emulator::updateTouchInput(int32_t x, int32_t y, bool down) {
-       pendingInterrupts &= ~(1 << EINT3);
-       if (down)
-               pendingInterrupts |= (1 << EINT3);
-       touchX = x;
-       touchY = y;
+  pendingInterrupts &= ~(1 << EINT3);
+  if (down)
+    pendingInterrupts |= (1 << EINT3);
+  touchX = x;
+  touchY = y;
 }
 
-}
+} // namespace Windermere
index defe545ce5d270f8c3e44cc192cafb448d22c9c6..9878258d7fe343426c84e92c679824b4e1558ab1 100644 (file)
@@ -1,81 +1,82 @@
 #pragma once
 #include "emubase.h"
-#include "wind_defs.h"
-#include "hardware.h"
 #include "etna.h"
+#include "hardware.h"
+#include "wind_defs.h"
 
 namespace Windermere {
 class Emulator : public EmuBase {
 public:
-    uint8_t ROM[0x1000000];
-       uint8_t ROM2[0x40000];
-    uint8_t MemoryBlockC0[0x800000];
-    uint8_t MemoryBlockC1[0x800000];
-    uint8_t MemoryBlockD0[0x800000];
-    uint8_t MemoryBlockD1[0x800000];
-    enum { MemoryBlockMask = 0x7FFFFF };
+  uint8_t ROM[0x1000000];
+  uint8_t ROM2[0x40000];
+  uint8_t MemoryBlockC0[0x800000];
+  uint8_t MemoryBlockC1[0x800000];
+  uint8_t MemoryBlockD0[0x800000];
+  uint8_t MemoryBlockD1[0x800000];
+  enum { MemoryBlockMask = 0x7FFFFF };
 
 private:
-    uint16_t pendingInterrupts = 0;
-    uint16_t interruptMask = 0;
-    uint32_t portValues = 0;
-    uint32_t portDirections = 0;
-    uint32_t pwrsr = 0x00002000; // cold start flag
-    uint32_t lcdControl = 0;
-    uint32_t lcdAddress = 0;
-    uint32_t rtc = 0;
-       uint16_t lastSSIRequest = 0;
-       int ssiReadCounter = 0;
+  uint16_t pendingInterrupts = 0;
+  uint16_t interruptMask = 0;
+  uint32_t portValues = 0;
+  uint32_t portDirections = 0;
+  uint32_t pwrsr = 0x00002000; // cold start flag
+  uint32_t lcdControl = 0;
+  uint32_t lcdAddress = 0;
+  uint32_t rtc = 0;
+  uint16_t lastSSIRequest = 0;
+  int ssiReadCounter = 0;
 
-       uint32_t kScan = 0;
-       uint8_t keyboardColumns[8] = {0,0,0,0,0,0,0};
-       int32_t touchX = 0, touchY = 0;
+  uint32_t kScan = 0;
+  uint8_t keyboardColumns[8] = {0, 0, 0, 0, 0, 0, 0};
+  int32_t touchX = 0, touchY = 0;
 
-    Timer tc1, tc2;
-    UART uart1, uart2;
-       Etna etna;
-       bool halted = false, asleep = false;
+  Timer tc1, tc2;
+  UART uart1, uart2;
+  Etna etna;
+  bool halted = false, asleep = false;
 
-    uint32_t getRTC();
+  uint32_t getRTC();
 
-    uint32_t readReg8(uint32_t reg);
-    uint32_t readReg32(uint32_t reg);
-    void writeReg8(uint32_t reg, uint8_t value);
-    void writeReg32(uint32_t reg, uint32_t value);
+  uint32_t readReg8(uint32_t reg);
+  uint32_t readReg32(uint32_t reg);
+  void writeReg8(uint32_t reg, uint8_t value);
+  void writeReg32(uint32_t reg, uint32_t value);
 
 public:
-       MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) override;
-       bool writePhysical(uint32_t value, uint32_t physAddr, ValueSize valueSize) override;
+  MaybeU32 readPhysical(uint32_t physAddr, ValueSize valueSize) override;
+  bool writePhysical(uint32_t value, uint32_t physAddr,
+                     ValueSize valueSize) override;
 
 private:
-    bool configured = false;
-    void configure();
+  bool configured = false;
+  void configure();
 
-    const char *identifyObjectCon(uint32_t ptr);
-    void fetchStr(uint32_t str, char *buf);
-    void fetchName(uint32_t obj, char *buf);
-    void fetchProcessFilename(uint32_t obj, char *buf);
-    void debugPC(uint32_t pc);
-       void diffPorts(uint32_t oldval, uint32_t newval);
-       void diffInterrupts(uint16_t oldval, uint16_t newval);
-       uint32_t readKeyboard();
+  const char* identifyObjectCon(uint32_t ptr);
+  void fetchStr(uint32_t str, char* buf);
+  void fetchName(uint32_t obj, char* buf);
+  void fetchProcessFilename(uint32_t obj, char* buf);
+  void debugPC(uint32_t pc);
+  void diffPorts(uint32_t oldval, uint32_t newval);
+  void diffInterrupts(uint16_t oldval, uint16_t newval);
+  uint32_t readKeyboard();
 
 public:
-       Emulator();
-       uint8_t *getROMBuffer() override;
-       size_t getROMSize() override;
-       void loadROM(uint8_t *buffer, size_t size) override;
-       void executeUntil(int64_t cycles) override;
-       int32_t getClockSpeed() const override { return CLOCK_SPEED; }
-       const char *getDeviceName() const override;
-       int getDigitiserWidth() const override;
-       int getDigitiserHeight() const override;
-       int getLCDOffsetX() const override;
-       int getLCDOffsetY() const override;
-       int getLCDWidth() const override;
-       int getLCDHeight() const override;
-       void readLCDIntoBuffer(uint8_t **lines, bool is32BitOutput) const override;
-       void setKeyboardKey(EpocKey key, bool value) override;
-       void updateTouchInput(int32_t x, int32_t y, bool down) override;
+  Emulator();
+  uint8_t* getROMBuffer() override;
+  size_t getROMSize() override;
+  void loadROM(uint8_t* buffer, size_t size) override;
+  void executeUntil(int64_t cycles) override;
+  int32_t getClockSpeed() const override { return CLOCK_SPEED; }
+  const char* getDeviceName() const override;
+  int getDigitiserWidth() const override;
+  int getDigitiserHeight() const override;
+  int getLCDOffsetX() const override;
+  int getLCDOffsetY() const override;
+  int getLCDWidth() const override;
+  int getLCDHeight() const override;
+  void readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const override;
+  void setKeyboardKey(EpocKey key, bool value) override;
+  void updateTouchInput(int32_t x, int32_t y, bool down) override;
 };
-}
+} // namespace Windermere
index 3d9b87d27f74e44791c1fa4092f0fe25c25bb394..d26184cdb2a9a17dcc29e30257d89c34dafa3912 100644 (file)
@@ -1,59 +1,59 @@
+#include "../WindCore/clps7111.h"
+#include "../WindCore/windermere.h"
 #include "mainwindow.h"
 #include <QApplication>
 #include <QFileDialog>
 #include <QMessageBox>
-#include "../WindCore/clps7111.h"
-#include "../WindCore/windermere.h"
 
-int main(int argc, char *argv[])
-{
-    QApplication a(argc, argv);
-       auto args = a.arguments();
-
-       QString romFile;
-       if (args.length() > 1)
-               romFile = args.last();
-       else
-               romFile = QFileDialog::getOpenFileName(nullptr, "Select a ROM");
-       if (romFile.isNull()) return 0;
-
-       // what do we have?
-       QFile f(romFile);
-       f.open(QFile::ReadOnly);
-       auto buffer = f.readAll();
-       f.close();
-
-       if (buffer.size() < 0x400000) {
-               QMessageBox::critical(nullptr, "WindEmu", "Invalid ROM file!");
-               return 0;
-       }
-
-       EmuBase *emu = nullptr;
-       uint8_t *romData = (uint8_t *)buffer.data();
-
-       // parse this ROM to learn what hardware it's for
-       int variantFile = *((uint32_t *)&romData[0x80 + 0x4C]) & 0xFFFFFFF;
-       if (variantFile < (buffer.size() - 8)) {
-               int variantImg = *((uint32_t *)&romData[variantFile + 4]) & 0xFFFFFFF;
-               if (variantImg < (buffer.size() - 0x70)) {
-                       int variant = *((uint32_t *)&romData[variantImg + 0x60]);
-
-                       if (variant == 0x7060001) {
-                               // 5mx ROM
-                               emu = new Windermere::Emulator;
-                       } else if (variant == 0x5040001) {
-                               // Osaris ROM
-                               emu = new CLPS7111::Emulator;
-                       } else {
-                               QMessageBox::critical(nullptr, "WindEmu", "Unrecognised ROM file!");
-                               return 0;
-                       }
-               }
-       }
-
-       emu->loadROM(romData, buffer.size());
-       MainWindow w(emu);
-    w.show();
-
-    return a.exec();
+int main(int argc, char* argv[]) {
+  QApplication a(argc, argv);
+  auto args = a.arguments();
+
+  QString romFile;
+  if (args.length() > 1)
+    romFile = args.last();
+  else
+    romFile = QFileDialog::getOpenFileName(nullptr, "Select a ROM");
+  if (romFile.isNull())
+    return 0;
+
+  // what do we have?
+  QFile f(romFile);
+  f.open(QFile::ReadOnly);
+  auto buffer = f.readAll();
+  f.close();
+
+  if (buffer.size() < 0x400000) {
+    QMessageBox::critical(nullptr, "WindEmu", "Invalid ROM file!");
+    return 0;
+  }
+
+  EmuBase* emu = nullptr;
+  uint8_t* romData = (uint8_t*)buffer.data();
+
+  // parse this ROM to learn what hardware it's for
+  int variantFile = *((uint32_t*)&romData[0x80 + 0x4C]) & 0xFFFFFFF;
+  if (variantFile < (buffer.size() - 8)) {
+    int variantImg = *((uint32_t*)&romData[variantFile + 4]) & 0xFFFFFFF;
+    if (variantImg < (buffer.size() - 0x70)) {
+      int variant = *((uint32_t*)&romData[variantImg + 0x60]);
+
+      if (variant == 0x7060001) {
+        // 5mx ROM
+        emu = new Windermere::Emulator;
+      } else if (variant == 0x5040001) {
+        // Osaris ROM
+        emu = new CLPS7111::Emulator;
+      } else {
+        QMessageBox::critical(nullptr, "WindEmu", "Unrecognised ROM file!");
+        return 0;
+      }
+    }
+  }
+
+  emu->loadROM(romData, buffer.size());
+  MainWindow w(emu);
+  w.show();
+
+  return a.exec();
 }
index fafdfd9b2dd598bb35160ebca532be2c1b1cfd4b..33709f62e8ccf22cf9999c5555eabe82c7c5116f 100644 (file)
 #include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include <QTimer>
 #include "../WindCore/decoder.h"
 #include "clps7111.h"
+#include "ui_mainwindow.h"
+#include <QTimer>
 
-MainWindow::MainWindow(EmuBase *emu, QWidget *parent) :
-    QMainWindow(parent),
-       ui(new Ui::MainWindow),
-       pdaScreen(emu),
-       emu(emu)
-{
-    ui->setupUi(this);
-       ui->logView->setMaximumBlockCount(1000);
-
-       elapsedTimer.start();
-       emu->setLogger([&](const char *str) {
-               QString fullStr = QStringLiteral("[%1] %2").arg(elapsedTimer.elapsed()).arg(str);
-               ui->logView->appendPlainText(fullStr);
-       });
-
-    timer = new QTimer(this);
-    timer->setInterval(1000/64);
-    connect(timer, SIGNAL(timeout()), SLOT(execTimer()));
-
-       pdaScreen.show();
-
-       updateScreen();
-}
-
-MainWindow::~MainWindow()
-{
-    delete ui;
-}
-
-void MainWindow::updateScreen()
-{
-    ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles()));
-
-       updateMemory();
-
-       char flagDisplay[] = {
-               (emu->getCPSR() & 0x80000000) ? 'N' : '-',
-               (emu->getCPSR() & 0x40000000) ? 'Z' : '-',
-               (emu->getCPSR() & 0x20000000) ? 'C' : '-',
-               (emu->getCPSR() & 0x10000000) ? 'V' : '-',
-               0
-       };
-       const char *modeName = "???";
-       switch (emu->getCPSR() & 0x1F) {
-       case 0x10: modeName = "User"; break;
-       case 0x11: modeName = "FIQ"; break;
-       case 0x12: modeName = "IRQ"; break;
-       case 0x13: modeName = "Supervisor"; break;
-       case 0x17: modeName = "Abort"; break;
-       case 0x1B: modeName = "Undefined"; break;
-       }
-
-    ui->regsLabel->setText(
-                               QString("R0: %1 / R1: %2 / R2: %3 / R3: %4 / R4: %5 / R5: %6 / R6: %7 / R7: %8\nR8: %9 / R9: %10 / R10:%11 / R11:%12 / R12:%13 / SP: %14 / LR: %15 / PC: %16\n%17 / Mode: %18")
-                .arg(emu->getGPR(0), 8, 16)
-                .arg(emu->getGPR(1), 8, 16)
-                .arg(emu->getGPR(2), 8, 16)
-                .arg(emu->getGPR(3), 8, 16)
-                .arg(emu->getGPR(4), 8, 16)
-                .arg(emu->getGPR(5), 8, 16)
-                .arg(emu->getGPR(6), 8, 16)
-                .arg(emu->getGPR(7), 8, 16)
-                .arg(emu->getGPR(8), 8, 16)
-                .arg(emu->getGPR(9), 8, 16)
-                .arg(emu->getGPR(10), 8, 16)
-                .arg(emu->getGPR(11), 8, 16)
-                .arg(emu->getGPR(12), 8, 16)
-                .arg(emu->getGPR(13), 8, 16)
-                .arg(emu->getGPR(14), 8, 16)
-                .arg(emu->getGPR(15), 8, 16)
-                               .arg(flagDisplay)
-                               .arg(modeName)
-                );
-
-    // show a crude disassembly
-    const int context = 8 * 4;
-       uint32_t pc = emu->getGPR(15) - 8;
-    uint32_t minCode = pc - context;
-       if (minCode >= (UINT32_MAX - context))
-        minCode = 0;
-    uint32_t maxCode = pc + context;
-       if (maxCode < context)
-        maxCode = UINT32_MAX;
-
-       QStringList codeLines;
-       for (uint32_t addr = minCode; addr >= minCode && addr <= maxCode; addr += 4) {
-               const char *prefix = (addr == pc) ? (emu->instructionReady() ? "==>" : "...") : "   ";
-        struct ARMInstructionInfo info;
-        char buffer[512];
-
-               auto result = emu->readVirtual(addr, ARM710::V32);
-               if (result.first.has_value()) {
-                       uint32_t opcode = result.first.value();
-                       ARMDecodeARM(opcode, &info);
-                       ARMDisassemble(&info, addr, buffer, sizeof(buffer));
-                       codeLines.append(QString("%1 %2 | %3 | %4").arg(prefix).arg(addr, 8, 16).arg(opcode, 8, 16).arg(buffer));
-               }
+MainWindow::MainWindow(EmuBase* emu, QWidget* parent)
+    : QMainWindow(parent), ui(new Ui::MainWindow), pdaScreen(emu), emu(emu) {
+  ui->setupUi(this);
+  ui->logView->setMaximumBlockCount(1000);
+
+  elapsedTimer.start();
+  emu->setLogger([&](const char* str) {
+    QString fullStr =
+        QStringLiteral("[%1] %2").arg(elapsedTimer.elapsed()).arg(str);
+    ui->logView->appendPlainText(fullStr);
+  });
+
+  timer = new QTimer(this);
+  timer->setInterval(1000 / 64);
+  connect(timer, SIGNAL(timeout()), SLOT(execTimer()));
+
+  pdaScreen.show();
+
+  updateScreen();
+}
+
+MainWindow::~MainWindow() { delete ui; }
+
+void MainWindow::updateScreen() {
+  ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles()));
+
+  updateMemory();
+
+  char flagDisplay[] = {(emu->getCPSR() & 0x80000000) ? 'N' : '-',
+                        (emu->getCPSR() & 0x40000000) ? 'Z' : '-',
+                        (emu->getCPSR() & 0x20000000) ? 'C' : '-',
+                        (emu->getCPSR() & 0x10000000) ? 'V' : '-', 0};
+  const char* modeName = "???";
+  switch (emu->getCPSR() & 0x1F) {
+  case 0x10:
+    modeName = "User";
+    break;
+  case 0x11:
+    modeName = "FIQ";
+    break;
+  case 0x12:
+    modeName = "IRQ";
+    break;
+  case 0x13:
+    modeName = "Supervisor";
+    break;
+  case 0x17:
+    modeName = "Abort";
+    break;
+  case 0x1B:
+    modeName = "Undefined";
+    break;
+  }
+
+  ui->regsLabel->setText(
+      QString("R0: %1 / R1: %2 / R2: %3 / R3: %4 / R4: %5 / R5: %6 / R6: %7 / "
+              "R7: %8\nR8: %9 / R9: %10 / R10:%11 / R11:%12 / R12:%13 / SP: "
+              "%14 / LR: %15 / PC: %16\n%17 / Mode: %18")
+          .arg(emu->getGPR(0), 8, 16)
+          .arg(emu->getGPR(1), 8, 16)
+          .arg(emu->getGPR(2), 8, 16)
+          .arg(emu->getGPR(3), 8, 16)
+          .arg(emu->getGPR(4), 8, 16)
+          .arg(emu->getGPR(5), 8, 16)
+          .arg(emu->getGPR(6), 8, 16)
+          .arg(emu->getGPR(7), 8, 16)
+          .arg(emu->getGPR(8), 8, 16)
+          .arg(emu->getGPR(9), 8, 16)
+          .arg(emu->getGPR(10), 8, 16)
+          .arg(emu->getGPR(11), 8, 16)
+          .arg(emu->getGPR(12), 8, 16)
+          .arg(emu->getGPR(13), 8, 16)
+          .arg(emu->getGPR(14), 8, 16)
+          .arg(emu->getGPR(15), 8, 16)
+          .arg(flagDisplay)
+          .arg(modeName));
+
+  // show a crude disassembly
+  const int context = 8 * 4;
+  uint32_t pc = emu->getGPR(15) - 8;
+  uint32_t minCode = pc - context;
+  if (minCode >= (UINT32_MAX - context))
+    minCode = 0;
+  uint32_t maxCode = pc + context;
+  if (maxCode < context)
+    maxCode = UINT32_MAX;
+
+  QStringList codeLines;
+  for (uint32_t addr = minCode; addr >= minCode && addr <= maxCode; addr += 4) {
+    const char* prefix =
+        (addr == pc) ? (emu->instructionReady() ? "==>" : "...") : "   ";
+    struct ARMInstructionInfo info;
+    char buffer[512];
+
+    auto result = emu->readVirtual(addr, ARM710::V32);
+    if (result.first.has_value()) {
+      uint32_t opcode = result.first.value();
+      ARMDecodeARM(opcode, &info);
+      ARMDisassemble(&info, addr, buffer, sizeof(buffer));
+      codeLines.append(QString("%1 %2 | %3 | %4")
+                           .arg(prefix)
+                           .arg(addr, 8, 16)
+                           .arg(opcode, 8, 16)
+                           .arg(buffer));
     }
-       ui->codeLabel->setText(codeLines.join('\n'));
+  }
+  ui->codeLabel->setText(codeLines.join('\n'));
 
-    // now, the actual screen
-       pdaScreen.updateScreen();
+  // now, the actual screen
+  pdaScreen.updateScreen();
 }
 
+void MainWindow::on_startButton_clicked() {
+  timer->start();
+  ui->startButton->setEnabled(false);
+  ui->stopButton->setEnabled(true);
+  ui->stepInsnButton->setEnabled(false);
+  ui->stepTickButton->setEnabled(false);
+}
 
-
-void MainWindow::on_startButton_clicked()
-{
-    timer->start();
-    ui->startButton->setEnabled(false);
-    ui->stopButton->setEnabled(true);
-    ui->stepInsnButton->setEnabled(false);
-    ui->stepTickButton->setEnabled(false);
+void MainWindow::on_stopButton_clicked() {
+  timer->stop();
+  ui->startButton->setEnabled(true);
+  ui->stopButton->setEnabled(false);
+  ui->stepInsnButton->setEnabled(true);
+  ui->stepTickButton->setEnabled(true);
 }
 
-void MainWindow::on_stopButton_clicked()
-{
-    timer->stop();
-    ui->startButton->setEnabled(true);
-    ui->stopButton->setEnabled(false);
-    ui->stepInsnButton->setEnabled(true);
-    ui->stepTickButton->setEnabled(true);
+void MainWindow::on_stepTickButton_clicked() {
+  //    emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED * 2));
+  emu->executeUntil(emu->currentCycles() + 25000000);
+  updateScreen();
 }
 
-void MainWindow::on_stepTickButton_clicked()
-{
-//    emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED * 2));
-       emu->executeUntil(emu->currentCycles() + 25000000);
-       updateScreen();
+void MainWindow::on_stepInsnButton_clicked() {
+  emu->executeUntil(emu->currentCycles() + 1);
+  updateScreen();
 }
 
-void MainWindow::on_stepInsnButton_clicked()
-{
-    emu->executeUntil(emu->currentCycles() + 1);
+void MainWindow::execTimer() {
+  if (emu) {
+    emu->executeUntil(emu->currentCycles() + (emu->getClockSpeed() / 64));
     updateScreen();
+  }
 }
 
-void MainWindow::execTimer()
-{
-       if (emu) {
-               emu->executeUntil(emu->currentCycles() + (emu->getClockSpeed() / 64));
-               updateScreen();
-       }
+void MainWindow::on_addBreakButton_clicked() {
+  uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16);
+  emu->breakpoints().insert(addr);
+  updateBreakpointsList();
 }
 
-void MainWindow::on_addBreakButton_clicked()
-{
-       uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16);
-       emu->breakpoints().insert(addr);
-       updateBreakpointsList();
+void MainWindow::on_removeBreakButton_clicked() {
+  uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16);
+  emu->breakpoints().erase(addr);
+  updateBreakpointsList();
 }
 
-void MainWindow::on_removeBreakButton_clicked()
-{
-       uint32_t addr = ui->breakpointAddress->text().toUInt(nullptr, 16);
-       emu->breakpoints().erase(addr);
-       updateBreakpointsList();
+void MainWindow::updateBreakpointsList() {
+  ui->breakpointsList->clear();
+  for (uint32_t addr : emu->breakpoints()) {
+    ui->breakpointsList->addItem(QString::number(addr, 16));
+  }
 }
 
-void MainWindow::updateBreakpointsList()
-{
-       ui->breakpointsList->clear();
-       for (uint32_t addr : emu->breakpoints()) {
-               ui->breakpointsList->addItem(QString::number(addr, 16));
-       }
+void MainWindow::on_memoryViewAddress_textEdited(const QString&) {
+  updateMemory();
 }
 
-void MainWindow::on_memoryViewAddress_textEdited(const QString &)
-{
-       updateMemory();
-}
+void MainWindow::updateMemory() {
+  uint32_t virtBase = ui->memoryViewAddress->text().toUInt(nullptr, 16) & ~0xFF;
+  auto physBaseOpt = emu->virtToPhys(virtBase);
+  auto physBase = physBaseOpt.value_or(0xFFFFFFFF);
+  bool ok = physBaseOpt.has_value();
+  if (ok && (virtBase != physBase))
+    ui->physicalAddressLabel->setText(
+        QStringLiteral("Physical: %1").arg(physBase, 8, 16, QLatin1Char('0')));
+
+  uint8_t block[0x100];
+  if (ok) {
+    for (int i = 0; i < 0x100; i++) {
+      block[i] = emu->readPhysical(physBase + i, ARM710::V8).value();
+    }
+  }
+
+  QStringList output;
+  for (int row = 0; row < 16; row++) {
+    QString outLine;
+    outLine.reserve(8 + 2 + (2 * 16) + 3 + 16);
+    outLine.append(QStringLiteral("%1 |").arg(virtBase + (row * 16), 8, 16));
+    for (int col = 0; col < 16; col++) {
+      if (ok)
+        outLine.append(QStringLiteral(" %1").arg(block[row * 16 + col], 2, 16,
+                                                 QLatin1Char('0')));
+      else
+        outLine.append(QStringLiteral(" ??"));
+    }
+    outLine.append(QStringLiteral(" | "));
+    for (int col = 0; col < 16; col++) {
+      uint8_t byte = block[row * 16 + col];
+      if (!ok)
+        outLine.append('?');
+      else if (byte >= 0x20 && byte <= 0x7E)
+        outLine.append((QChar)byte);
+      else
+        outLine.append('.');
+    }
+    output.append(outLine);
+  }
 
-void MainWindow::updateMemory()
-{
-       uint32_t virtBase = ui->memoryViewAddress->text().toUInt(nullptr, 16) & ~0xFF;
-       auto physBaseOpt = emu->virtToPhys(virtBase);
-       auto physBase = physBaseOpt.value_or(0xFFFFFFFF);
-       bool ok = physBaseOpt.has_value();
-       if (ok && (virtBase != physBase))
-               ui->physicalAddressLabel->setText(QStringLiteral("Physical: %1").arg(physBase, 8, 16, QLatin1Char('0')));
-
-       uint8_t block[0x100];
-       if (ok) {
-               for (int i = 0; i < 0x100; i++) {
-                       block[i] = emu->readPhysical(physBase + i, ARM710::V8).value();
-               }
-       }
-
-       QStringList output;
-       for (int row = 0; row < 16; row++) {
-               QString outLine;
-               outLine.reserve(8 + 2 + (2 * 16) + 3 + 16);
-               outLine.append(QStringLiteral("%1 |").arg(virtBase + (row * 16), 8, 16));
-               for (int col = 0; col < 16; col++) {
-                       if (ok)
-                               outLine.append(QStringLiteral(" %1").arg(block[row*16+col], 2, 16, QLatin1Char('0')));
-                       else
-                               outLine.append(QStringLiteral(" ??"));
-               }
-               outLine.append(QStringLiteral(" | "));
-               for (int col = 0; col < 16; col++) {
-                       uint8_t byte = block[row*16+col];
-                       if (!ok)
-                               outLine.append('?');
-                       else if (byte >= 0x20 && byte <= 0x7E)
-                               outLine.append((QChar)byte);
-                       else
-                               outLine.append('.');
-               }
-               output.append(outLine);
-       }
-
-       ui->memoryViewLabel->setText(output.join('\n'));
+  ui->memoryViewLabel->setText(output.join('\n'));
 }
 
 void MainWindow::on_memoryAdd1_clicked() { adjustMemoryAddress(1); }
@@ -229,24 +227,23 @@ void MainWindow::on_memorySub10_clicked() { adjustMemoryAddress(-0x10); }
 void MainWindow::on_memorySub100_clicked() { adjustMemoryAddress(-0x100); }
 
 void MainWindow::adjustMemoryAddress(int offset) {
-       uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
-       address += offset;
-       ui->memoryViewAddress->setText(QString("%1").arg(address, 8, 16, QLatin1Char('0')));
-       updateMemory();
+  uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
+  address += offset;
+  ui->memoryViewAddress->setText(
+      QString("%1").arg(address, 8, 16, QLatin1Char('0')));
+  updateMemory();
 }
 
-void MainWindow::on_writeByteButton_clicked()
-{
-       uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
-       uint8_t value = (uint8_t)ui->memoryWriteValue->text().toUInt(nullptr, 16);
-       emu->writeVirtual(value, address, ARM710::V8);
-       updateMemory();
+void MainWindow::on_writeByteButton_clicked() {
+  uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
+  uint8_t value = (uint8_t)ui->memoryWriteValue->text().toUInt(nullptr, 16);
+  emu->writeVirtual(value, address, ARM710::V8);
+  updateMemory();
 }
 
-void MainWindow::on_writeDwordButton_clicked()
-{
-       uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
-       uint32_t value = ui->memoryWriteValue->text().toUInt(nullptr, 16);
-       emu->writeVirtual(value, address, ARM710::V32);
-       updateMemory();
+void MainWindow::on_writeDwordButton_clicked() {
+  uint32_t address = ui->memoryViewAddress->text().toUInt(nullptr, 16);
+  uint32_t value = ui->memoryWriteValue->text().toUInt(nullptr, 16);
+  emu->writeVirtual(value, address, ARM710::V32);
+  updateMemory();
 }
index 636374abf88a9361886924e9d8e2582cfb416283..efd848a891e30de3f1971ffe3972eabf30c05438 100644 (file)
@@ -1,59 +1,58 @@
 #ifndef MAINWINDOW_H
 #define MAINWINDOW_H
 
-#include <QMainWindow>
-#include <QElapsedTimer>
 #include "../WindCore/emubase.h"
 #include "pdascreenwindow.h"
+#include <QElapsedTimer>
+#include <QMainWindow>
 
 namespace Ui {
 class MainWindow;
 }
 
-class MainWindow : public QMainWindow
-{
-    Q_OBJECT
+class MainWindow : public QMainWindow {
+  Q_OBJECT
 
 public:
-       explicit MainWindow(EmuBase *emu, QWidget *parent = nullptr);
-    ~MainWindow() override;
+  explicit MainWindow(EmuBase* emu, QWidget* parent = nullptr);
+  ~MainWindow() override;
 
 private slots:
-    void execTimer();
+  void execTimer();
 
-    void on_startButton_clicked();
-    void on_stopButton_clicked();
-    void on_stepInsnButton_clicked();
-    void on_stepTickButton_clicked();
+  void on_startButton_clicked();
+  void on_stopButton_clicked();
+  void on_stepInsnButton_clicked();
+  void on_stepTickButton_clicked();
 
-    void on_addBreakButton_clicked();
+  void on_addBreakButton_clicked();
 
-    void on_removeBreakButton_clicked();
+  void on_removeBreakButton_clicked();
 
-    void on_memoryViewAddress_textEdited(const QString &arg1);
-    void on_memoryAdd1_clicked();
-    void on_memoryAdd4_clicked();
-    void on_memoryAdd10_clicked();
-    void on_memoryAdd100_clicked();
-    void on_memorySub1_clicked();
-    void on_memorySub4_clicked();
-    void on_memorySub10_clicked();
-    void on_memorySub100_clicked();
+  void on_memoryViewAddress_textEdited(const QString& arg1);
+  void on_memoryAdd1_clicked();
+  void on_memoryAdd4_clicked();
+  void on_memoryAdd10_clicked();
+  void on_memoryAdd100_clicked();
+  void on_memorySub1_clicked();
+  void on_memorySub4_clicked();
+  void on_memorySub10_clicked();
+  void on_memorySub100_clicked();
 
-    void on_writeByteButton_clicked();
+  void on_writeByteButton_clicked();
 
-    void on_writeDwordButton_clicked();
+  void on_writeDwordButton_clicked();
 
 private:
-       QElapsedTimer elapsedTimer;
-    Ui::MainWindow *ui;
-       PDAScreenWindow pdaScreen;
-       EmuBase *emu;
-    QTimer *timer;
-    void updateScreen();
-    void updateBreakpointsList();
-    void updateMemory();
-    void adjustMemoryAddress(int offset);
+  QElapsedTimer elapsedTimer;
+  Ui::MainWindow* ui;
+  PDAScreenWindow pdaScreen;
+  EmuBase* emu;
+  QTimer* timer;
+  void updateScreen();
+  void updateBreakpointsList();
+  void updateMemory();
+  void adjustMemoryAddress(int offset);
 };
 
 #endif // MAINWINDOW_H
index 4531c5ba352e9357210289057d7ad499f50a2209..0eae0ae284cb6abbedbbe92408e9c3401d38a2de 100644 (file)
 #include "pdascreenwindow.h"
 #include <QKeyEvent>
 
-PDAScreenWindow::PDAScreenWindow(EmuBase *emu, QWidget *parent) :
-       QWidget(parent),
-       emu(emu),
-       lcd(new QLabel(this))
-{
-       setWindowTitle("WindEmu");
-       setFixedSize(emu->getDigitiserWidth(), emu->getDigitiserHeight());
-       lcd->setGeometry(emu->getLCDOffsetX(), emu->getLCDOffsetY(), emu->getLCDWidth(), emu->getLCDHeight());
-
-       const char *who = emu->getDeviceName();
-       if (strcmp(who, "Osaris") == 0) {
-               // some cheap and cheerful placeholders
-               int bitW = (emu->getDigitiserWidth() - emu->getLCDWidth()) / 2;
-               int bitH = emu->getDigitiserHeight() / 5;
-               int leftX = 0;
-               int rightX = bitW + emu->getLCDWidth();
-               (new QLabel("Word",       this))->setGeometry(leftX, bitH * 0, bitW, bitH);
-               (new QLabel("Sheet",      this))->setGeometry(leftX, bitH * 1, bitW, bitH);
-               (new QLabel("Data",       this))->setGeometry(leftX, bitH * 2, bitW, bitH);
-               (new QLabel("Agenda",     this))->setGeometry(leftX, bitH * 3, bitW, bitH);
-               (new QLabel("Extras",     this))->setGeometry(leftX, bitH * 4, bitW, bitH);
-               (new QLabel("EPOC",       this))->setGeometry(rightX, bitH * 0, bitW, bitH);
-               (new QLabel("Menu",       this))->setGeometry(rightX, bitH * 1, bitW, bitH);
-               (new QLabel("Copy/Paste", this))->setGeometry(rightX, bitH * 2, bitW, bitH);
-               (new QLabel("Zoom In",    this))->setGeometry(rightX, bitH * 3, bitW, bitH);
-               (new QLabel("Zoom Out",   this))->setGeometry(rightX, bitH * 4, bitW, bitH);
-       } else if (strcmp(who, "Series 5mx") == 0) {
-               int leftW = emu->getLCDOffsetX();
-               int leftH = emu->getLCDHeight() / 5;
-               (new QLabel("➡️",       this))->setGeometry(0, leftH * 0, leftW, leftH);
-               (new QLabel("📄",       this))->setGeometry(0, leftH * 1, leftW, leftH);
-               (new QLabel("📡",       this))->setGeometry(0, leftH * 2, leftW, leftH);
-               (new QLabel("+",       this))->setGeometry(0, leftH * 3, leftW, leftH);
-               (new QLabel("-",       this))->setGeometry(0, leftH * 4, leftW, leftH);
-
-               int barX = 50;
-               int barY = leftH * 5;
-               int barW = (emu->getDigitiserWidth() - barX) / 8;
-               int barH = emu->getDigitiserHeight() - emu->getLCDHeight();
-               (new QLabel("System",   this))->setGeometry(0, barY, barX, barH);
-               (new QLabel("Word",     this))->setGeometry(barX + barW * 0, barY, barW, barH);
-               (new QLabel("Sheet",    this))->setGeometry(barX + barW * 1, barY, barW, barH);
-               (new QLabel("Contacts", this))->setGeometry(barX + barW * 2, barY, barW, barH);
-               (new QLabel("Agenda",   this))->setGeometry(barX + barW * 3, barY, barW, barH);
-               (new QLabel("Email",    this))->setGeometry(barX + barW * 4, barY, barW, barH);
-               (new QLabel("Calc",     this))->setGeometry(barX + barW * 5, barY, barW, barH);
-               (new QLabel("Jotter",   this))->setGeometry(barX + barW * 6, barY, barW, barH);
-               (new QLabel("Extras",   this))->setGeometry(barX + barW * 7, barY, barW, barH);
-       }
+PDAScreenWindow::PDAScreenWindow(EmuBase* emu, QWidget* parent)
+    : QWidget(parent), emu(emu), lcd(new QLabel(this)) {
+  setWindowTitle("WindEmu");
+  setFixedSize(emu->getDigitiserWidth(), emu->getDigitiserHeight());
+  lcd->setGeometry(emu->getLCDOffsetX(), emu->getLCDOffsetY(),
+                   emu->getLCDWidth(), emu->getLCDHeight());
+
+  const char* who = emu->getDeviceName();
+  if (strcmp(who, "Osaris") == 0) {
+    // some cheap and cheerful placeholders
+    int bitW = (emu->getDigitiserWidth() - emu->getLCDWidth()) / 2;
+    int bitH = emu->getDigitiserHeight() / 5;
+    int leftX = 0;
+    int rightX = bitW + emu->getLCDWidth();
+    (new QLabel("Word", this))->setGeometry(leftX, bitH * 0, bitW, bitH);
+    (new QLabel("Sheet", this))->setGeometry(leftX, bitH * 1, bitW, bitH);
+    (new QLabel("Data", this))->setGeometry(leftX, bitH * 2, bitW, bitH);
+    (new QLabel("Agenda", this))->setGeometry(leftX, bitH * 3, bitW, bitH);
+    (new QLabel("Extras", this))->setGeometry(leftX, bitH * 4, bitW, bitH);
+    (new QLabel("EPOC", this))->setGeometry(rightX, bitH * 0, bitW, bitH);
+    (new QLabel("Menu", this))->setGeometry(rightX, bitH * 1, bitW, bitH);
+    (new QLabel("Copy/Paste", this))->setGeometry(rightX, bitH * 2, bitW, bitH);
+    (new QLabel("Zoom In", this))->setGeometry(rightX, bitH * 3, bitW, bitH);
+    (new QLabel("Zoom Out", this))->setGeometry(rightX, bitH * 4, bitW, bitH);
+  } else if (strcmp(who, "Series 5mx") == 0) {
+    int leftW = emu->getLCDOffsetX();
+    int leftH = emu->getLCDHeight() / 5;
+    (new QLabel("➡️", this))->setGeometry(0, leftH * 0, leftW, leftH);
+    (new QLabel("📄", this))->setGeometry(0, leftH * 1, leftW, leftH);
+    (new QLabel("📡", this))->setGeometry(0, leftH * 2, leftW, leftH);
+    (new QLabel("+", this))->setGeometry(0, leftH * 3, leftW, leftH);
+    (new QLabel("-", this))->setGeometry(0, leftH * 4, leftW, leftH);
+
+    int barX = 50;
+    int barY = leftH * 5;
+    int barW = (emu->getDigitiserWidth() - barX) / 8;
+    int barH = emu->getDigitiserHeight() - emu->getLCDHeight();
+    (new QLabel("System", this))->setGeometry(0, barY, barX, barH);
+    (new QLabel("Word", this))->setGeometry(barX + barW * 0, barY, barW, barH);
+    (new QLabel("Sheet", this))->setGeometry(barX + barW * 1, barY, barW, barH);
+    (new QLabel("Contacts", this))
+        ->setGeometry(barX + barW * 2, barY, barW, barH);
+    (new QLabel("Agenda", this))
+        ->setGeometry(barX + barW * 3, barY, barW, barH);
+    (new QLabel("Email", this))->setGeometry(barX + barW * 4, barY, barW, barH);
+    (new QLabel("Calc", this))->setGeometry(barX + barW * 5, barY, barW, barH);
+    (new QLabel("Jotter", this))
+        ->setGeometry(barX + barW * 6, barY, barW, barH);
+    (new QLabel("Extras", this))
+        ->setGeometry(barX + barW * 7, barY, barW, barH);
+  }
 }
 
 void PDAScreenWindow::updateScreen() {
-       uint8_t *lines[1024];
-       QImage img(emu->getLCDWidth(), emu->getLCDHeight(), QImage::Format_Grayscale8);
-       for (int y = 0; y < img.height(); y++)
-               lines[y] = img.scanLine(y);
-       emu->readLCDIntoBuffer(lines, false);
+  uint8_t* lines[1024];
+  QImage img(emu->getLCDWidth(), emu->getLCDHeight(),
+             QImage::Format_Grayscale8);
+  for (int y = 0; y < img.height(); y++)
+    lines[y] = img.scanLine(y);
+  emu->readLCDIntoBuffer(lines, false);
 
-       lcd->setPixmap(QPixmap::fromImage(std::move(img)));
+  lcd->setPixmap(QPixmap::fromImage(std::move(img)));
 }
 
 #ifdef Q_OS_MAC
 static EpocKey resolveKey(int key, int vk) {
-       // Although Cocoa/Carbon's virtual keycodes include
-       // modifiers, Qt doesn't expose them through QKeyEvent...
-       switch (key) {
-       case Qt::Key_Control: return EStdKeyLeftFunc;
-       case Qt::Key_Shift: return EStdKeyLeftShift;
-       case Qt::Key_Alt: return EStdKeyMenu;
-       case Qt::Key_Meta: return EStdKeyLeftCtrl;
-       }
-
-       // https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.6.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h#L182
-       switch (vk) {
-       case 0x00: return (EpocKey)'A';
-       case 0x01: return (EpocKey)'S';
-       case 0x02: return (EpocKey)'D';
-       case 0x03: return (EpocKey)'F';
-       case 0x04: return (EpocKey)'H';
-       case 0x05: return (EpocKey)'G';
-       case 0x06: return (EpocKey)'Z';
-       case 0x07: return (EpocKey)'X';
-       case 0x08: return (EpocKey)'C';
-       case 0x09: return (EpocKey)'V';
-       case 0x0B: return (EpocKey)'B';
-       case 0x0C: return (EpocKey)'Q';
-       case 0x0D: return (EpocKey)'W';
-       case 0x0E: return (EpocKey)'E';
-       case 0x0F: return (EpocKey)'R';
-
-       case 0x10: return (EpocKey)'Y';
-       case 0x11: return (EpocKey)'T';
-       case 0x12: return (EpocKey)'1';
-       case 0x13: return (EpocKey)'2';
-       case 0x14: return (EpocKey)'3';
-       case 0x15: return (EpocKey)'4';
-       case 0x16: return (EpocKey)'6';
-       case 0x17: return (EpocKey)'5';
-       case 0x19: return (EpocKey)'9';
-       case 0x1A: return (EpocKey)'7';
-       case 0x1C: return (EpocKey)'8';
-       case 0x1D: return (EpocKey)'0';
-       case 0x1F: return (EpocKey)'O';
-
-       case 0x20: return (EpocKey)'U';
-       case 0x22: return (EpocKey)'I';
-       case 0x23: return (EpocKey)'P';
-       case 0x24: return EStdKeyEnter;
-       case 0x25: return (EpocKey)'L';
-       case 0x26: return (EpocKey)'J';
-       case 0x27: return EStdKeySingleQuote;
-       case 0x28: return (EpocKey)'K';
-       case 0x2B: return EStdKeyComma;
-       case 0x2D: return (EpocKey)'N';
-       case 0x2E: return (EpocKey)'M';
-       case 0x2F: return EStdKeyFullStop;
-
-       case 0x30: return EStdKeyTab;
-       case 0x31: return EStdKeySpace;
-       case 0x33: return EStdKeyBackspace;
-       case 0x35: return EStdKeyEscape;
-
-       case 0x7B: return EStdKeyLeftArrow;
-       case 0x7C: return EStdKeyRightArrow;
-       case 0x7D: return EStdKeyDownArrow;
-       case 0x7E: return EStdKeyUpArrow;
-       }
-
-       return EStdKeyNull;
+  // Although Cocoa/Carbon's virtual keycodes include
+  // modifiers, Qt doesn't expose them through QKeyEvent...
+  switch (key) {
+  case Qt::Key_Control:
+    return EStdKeyLeftFunc;
+  case Qt::Key_Shift:
+    return EStdKeyLeftShift;
+  case Qt::Key_Alt:
+    return EStdKeyMenu;
+  case Qt::Key_Meta:
+    return EStdKeyLeftCtrl;
+  }
+
+  // https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.6.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h#L182
+  switch (vk) {
+  case 0x00:
+    return (EpocKey)'A';
+  case 0x01:
+    return (EpocKey)'S';
+  case 0x02:
+    return (EpocKey)'D';
+  case 0x03:
+    return (EpocKey)'F';
+  case 0x04:
+    return (EpocKey)'H';
+  case 0x05:
+    return (EpocKey)'G';
+  case 0x06:
+    return (EpocKey)'Z';
+  case 0x07:
+    return (EpocKey)'X';
+  case 0x08:
+    return (EpocKey)'C';
+  case 0x09:
+    return (EpocKey)'V';
+  case 0x0B:
+    return (EpocKey)'B';
+  case 0x0C:
+    return (EpocKey)'Q';
+  case 0x0D:
+    return (EpocKey)'W';
+  case 0x0E:
+    return (EpocKey)'E';
+  case 0x0F:
+    return (EpocKey)'R';
+
+  case 0x10:
+    return (EpocKey)'Y';
+  case 0x11:
+    return (EpocKey)'T';
+  case 0x12:
+    return (EpocKey)'1';
+  case 0x13:
+    return (EpocKey)'2';
+  case 0x14:
+    return (EpocKey)'3';
+  case 0x15:
+    return (EpocKey)'4';
+  case 0x16:
+    return (EpocKey)'6';
+  case 0x17:
+    return (EpocKey)'5';
+  case 0x19:
+    return (EpocKey)'9';
+  case 0x1A:
+    return (EpocKey)'7';
+  case 0x1C:
+    return (EpocKey)'8';
+  case 0x1D:
+    return (EpocKey)'0';
+  case 0x1F:
+    return (EpocKey)'O';
+
+  case 0x20:
+    return (EpocKey)'U';
+  case 0x22:
+    return (EpocKey)'I';
+  case 0x23:
+    return (EpocKey)'P';
+  case 0x24:
+    return EStdKeyEnter;
+  case 0x25:
+    return (EpocKey)'L';
+  case 0x26:
+    return (EpocKey)'J';
+  case 0x27:
+    return EStdKeySingleQuote;
+  case 0x28:
+    return (EpocKey)'K';
+  case 0x2B:
+    return EStdKeyComma;
+  case 0x2D:
+    return (EpocKey)'N';
+  case 0x2E:
+    return (EpocKey)'M';
+  case 0x2F:
+    return EStdKeyFullStop;
+
+  case 0x30:
+    return EStdKeyTab;
+  case 0x31:
+    return EStdKeySpace;
+  case 0x33:
+    return EStdKeyBackspace;
+  case 0x35:
+    return EStdKeyEscape;
+
+  case 0x7B:
+    return EStdKeyLeftArrow;
+  case 0x7C:
+    return EStdKeyRightArrow;
+  case 0x7D:
+    return EStdKeyDownArrow;
+  case 0x7E:
+    return EStdKeyUpArrow;
+  }
+
+  return EStdKeyNull;
 }
 #else
 #error "Unsupported platform (for now! fix me in pdascreenwindow.cpp)"
 static EpocKey resolveKey(int key) {
-       // Placeholder, doesn't work for all keys
-       switch (key) {
-       case Qt::Key_Apostrophe: return EStdKeySingleQuote;
-       case Qt::Key_Backspace: return EStdKeyBackspace;
-       case Qt::Key_Escape: return EStdKeyEscape;
-       case Qt::Key_Enter: return EStdKeyEnter;
-       case Qt::Key_Return: return EStdKeyEnter;
-       case Qt::Key_Alt: return EStdKeyMenu;
-       case Qt::Key_Tab: return EStdKeyTab;
+  // Placeholder, doesn't work for all keys
+  switch (key) {
+  case Qt::Key_Apostrophe:
+    return EStdKeySingleQuote;
+  case Qt::Key_Backspace:
+    return EStdKeyBackspace;
+  case Qt::Key_Escape:
+    return EStdKeyEscape;
+  case Qt::Key_Enter:
+    return EStdKeyEnter;
+  case Qt::Key_Return:
+    return EStdKeyEnter;
+  case Qt::Key_Alt:
+    return EStdKeyMenu;
+  case Qt::Key_Tab:
+    return EStdKeyTab;
 #ifdef Q_OS_MAC
-       case Qt::Key_Meta: return EStdKeyLeftCtrl;
+  case Qt::Key_Meta:
+    return EStdKeyLeftCtrl;
 #else
-       case Qt::Key_Control: return EStdKeyLeftCtrl;
+  case Qt::Key_Control:
+    return EStdKeyLeftCtrl;
 #endif
-       case Qt::Key_Down: return EStdKeyDownArrow;
-       case Qt::Key_Period: return EStdKeyFullStop;
+  case Qt::Key_Down:
+    return EStdKeyDownArrow;
+  case Qt::Key_Period:
+    return EStdKeyFullStop;
 #ifdef Q_OS_MAC
-       case Qt::Key_Control: return EStdKeyLeftFunc;
+  case Qt::Key_Control:
+    return EStdKeyLeftFunc;
 #else
-       case Qt::Key_Meta: return EStdKeyLeftFunc;
+  case Qt::Key_Meta:
+    return EStdKeyLeftFunc;
 #endif
-       case Qt::Key_Shift: return EStdKeyLeftShift;
-       case Qt::Key_Right: return EStdKeyRightArrow;
-       case Qt::Key_Left: return EStdKeyLeftArrow;
-       case Qt::Key_Comma: return EStdKeyComma;
-       case Qt::Key_Up: return EStdKeyUpArrow;
-       case Qt::Key_Space: return EStdKeySpace;
-       }
-
-       if (key >= '0' && key <= '9') return (EpocKey)key;
-       if (key >= 'A' && key <= 'Z') return (EpocKey)key;
-       return EStdKeyNull;
+  case Qt::Key_Shift:
+    return EStdKeyLeftShift;
+  case Qt::Key_Right:
+    return EStdKeyRightArrow;
+  case Qt::Key_Left:
+    return EStdKeyLeftArrow;
+  case Qt::Key_Comma:
+    return EStdKeyComma;
+  case Qt::Key_Up:
+    return EStdKeyUpArrow;
+  case Qt::Key_Space:
+    return EStdKeySpace;
+  }
+
+  if (key >= '0' && key <= '9')
+    return (EpocKey)key;
+  if (key >= 'A' && key <= 'Z')
+    return (EpocKey)key;
+  return EStdKeyNull;
 }
 #endif
 
-
-void PDAScreenWindow::keyPressEvent(QKeyEvent *event)
-{
-       emu->log("KeyPress: QtKey=%d nativeVirtualKey=%x nativeModifiers=%x", event->key(), event->nativeVirtualKey(), event->nativeModifiers());
-       EpocKey k = resolveKey(event->key(), event->nativeVirtualKey());
-       if (k != EStdKeyNull)
-               emu->setKeyboardKey(k, true);
+void PDAScreenWindow::keyPressEvent(QKeyEvent* event) {
+  emu->log("KeyPress: QtKey=%d nativeVirtualKey=%x nativeModifiers=%x",
+           event->key(), event->nativeVirtualKey(), event->nativeModifiers());
+  EpocKey k = resolveKey(event->key(), event->nativeVirtualKey());
+  if (k != EStdKeyNull)
+    emu->setKeyboardKey(k, true);
 }
 
-void PDAScreenWindow::keyReleaseEvent(QKeyEvent *event)
-{
-       EpocKey k = resolveKey(event->key(), event->nativeVirtualKey());
-       if (k != EStdKeyNull)
-               emu->setKeyboardKey(k, false);
+void PDAScreenWindow::keyReleaseEvent(QKeyEvent* event) {
+  EpocKey k = resolveKey(event->key(), event->nativeVirtualKey());
+  if (k != EStdKeyNull)
+    emu->setKeyboardKey(k, false);
 }
 
-
-void PDAScreenWindow::mousePressEvent(QMouseEvent *event)
-{
-       emu->updateTouchInput(event->x(), event->y(), true);
+void PDAScreenWindow::mousePressEvent(QMouseEvent* event) {
+  emu->updateTouchInput(event->x(), event->y(), true);
 }
 
-void PDAScreenWindow::mouseReleaseEvent(QMouseEvent *event)
-{
-       emu->updateTouchInput(event->x(), event->y(), false);
+void PDAScreenWindow::mouseReleaseEvent(QMouseEvent* event) {
+  emu->updateTouchInput(event->x(), event->y(), false);
 }
 
-void PDAScreenWindow::mouseMoveEvent(QMouseEvent *event)
-{
-       if (event->buttons() & Qt::LeftButton)
-               emu->updateTouchInput(event->x(), event->y(), true);
+void PDAScreenWindow::mouseMoveEvent(QMouseEvent* event) {
+  if (event->buttons() & Qt::LeftButton)
+    emu->updateTouchInput(event->x(), event->y(), true);
 }
index e18ca78d45817daf14b8b4c268716c172722a8cc..74a6db6759d4bd9c95424fb5ecdd5833640ac75a 100644 (file)
@@ -1,29 +1,28 @@
 #ifndef PDASCREENWINDOW_H
 #define PDASCREENWINDOW_H
 
-#include <QWidget>
-#include <QLabel>
 #include "emubase.h"
+#include <QLabel>
+#include <QWidget>
 
-class PDAScreenWindow : public QWidget
-{
-       Q_OBJECT
+class PDAScreenWindow : public QWidget {
+  Q_OBJECT
 private:
-       EmuBase *emu;
-       QLabel *lcd;
+  EmuBase* emu;
+  QLabel* lcd;
 
 public:
-       explicit PDAScreenWindow(EmuBase *emu, QWidget *parent = nullptr);
+  explicit PDAScreenWindow(EmuBase* emu, QWidget* parent = nullptr);
 
 public slots:
-       void updateScreen();
+  void updateScreen();
 
 protected:
-       void keyPressEvent(QKeyEvent *event) override;
-       void keyReleaseEvent(QKeyEvent *event) override;
-       void mousePressEvent(QMouseEvent *event) override;
-       void mouseReleaseEvent(QMouseEvent *event) override;
-       void mouseMoveEvent(QMouseEvent *event) override;
+  void keyPressEvent(QKeyEvent* event) override;
+  void keyReleaseEvent(QKeyEvent* event) override;
+  void mousePressEvent(QMouseEvent* event) override;
+  void mouseReleaseEvent(QMouseEvent* event) override;
+  void mouseMoveEvent(QMouseEvent* event) override;
 };
 
 #endif // PDASCREENWINDOW_H
index c05ba6774586a06496b10af0205a4c25625a27cf..ad1955062d0c493f6bbea77ab52dfc53f6ec1ab3 100644 (file)
 #include "../WindCore/emubase.h"
 #include "../WindCore/windermere.h"
-#include <stdio.h>
-#include <emscripten.h>
 #include <SDL.h>
+#include <emscripten.h>
+#include <stdio.h>
 
-EmuBase *emu;
+EmuBaseemu;
 // SDL_Window *window;
-SDL_Surface *surface;
+SDL_Surfacesurface;
 
 static EpocKey resolveKey(SDLKey sym) {
-       switch (sym) {
-               case SDLK_BACKSPACE: return EStdKeyBackspace;
-               case SDLK_TAB:       return EStdKeyTab;
-               case SDLK_RETURN:    return EStdKeyEnter;
-               case SDLK_ESCAPE:    return EStdKeyEscape;
-               case SDLK_SPACE:     return EStdKeySpace;
-               case SDLK_QUOTE:     return EStdKeySingleQuote;
-               case SDLK_COMMA:     return EStdKeyComma;
-               case SDLK_PERIOD:    return EStdKeyFullStop;
-               case SDLK_0:         return (EpocKey)'0';
-               case SDLK_1:         return (EpocKey)'1';
-               case SDLK_2:         return (EpocKey)'2';
-               case SDLK_3:         return (EpocKey)'3';
-               case SDLK_4:         return (EpocKey)'4';
-               case SDLK_5:         return (EpocKey)'5';
-               case SDLK_6:         return (EpocKey)'6';
-               case SDLK_7:         return (EpocKey)'7';
-               case SDLK_8:         return (EpocKey)'8';
-               case SDLK_9:         return (EpocKey)'9';
-               case SDLK_a:         return (EpocKey)'A';
-               case SDLK_b:         return (EpocKey)'B';
-               case SDLK_c:         return (EpocKey)'C';
-               case SDLK_d:         return (EpocKey)'D';
-               case SDLK_e:         return (EpocKey)'E';
-               case SDLK_f:         return (EpocKey)'F';
-               case SDLK_g:         return (EpocKey)'G';
-               case SDLK_h:         return (EpocKey)'H';
-               case SDLK_i:         return (EpocKey)'I';
-               case SDLK_j:         return (EpocKey)'J';
-               case SDLK_k:         return (EpocKey)'K';
-               case SDLK_l:         return (EpocKey)'L';
-               case SDLK_m:         return (EpocKey)'M';
-               case SDLK_n:         return (EpocKey)'N';
-               case SDLK_o:         return (EpocKey)'O';
-               case SDLK_p:         return (EpocKey)'P';
-               case SDLK_q:         return (EpocKey)'Q';
-               case SDLK_r:         return (EpocKey)'R';
-               case SDLK_s:         return (EpocKey)'S';
-               case SDLK_t:         return (EpocKey)'T';
-               case SDLK_u:         return (EpocKey)'U';
-               case SDLK_v:         return (EpocKey)'V';
-               case SDLK_w:         return (EpocKey)'W';
-               case SDLK_x:         return (EpocKey)'X';
-               case SDLK_y:         return (EpocKey)'Y';
-               case SDLK_z:         return (EpocKey)'Z';
-               case SDLK_UP:        return EStdKeyUpArrow;
-               case SDLK_DOWN:      return EStdKeyDownArrow;
-               case SDLK_RIGHT:     return EStdKeyRightArrow;
-               case SDLK_LEFT:      return EStdKeyLeftArrow;
-               case SDLK_RSHIFT:    return EStdKeyRightShift;
-               case SDLK_LSHIFT:    return EStdKeyLeftShift;
-               case SDLK_RCTRL:     return EStdKeyRightCtrl;
-               case SDLK_LCTRL:     return EStdKeyLeftCtrl;
-               case SDLK_RALT:      return EStdKeyMenu;
-               case SDLK_LALT:      return EStdKeyMenu;
-               case SDLK_LSUPER:    return EStdKeyLeftFunc;
-               case SDLK_RSUPER:    return EStdKeyRightFunc;
-       }
-       return EStdKeyNull;
+  switch (sym) {
+  case SDLK_BACKSPACE:
+    return EStdKeyBackspace;
+  case SDLK_TAB:
+    return EStdKeyTab;
+  case SDLK_RETURN:
+    return EStdKeyEnter;
+  case SDLK_ESCAPE:
+    return EStdKeyEscape;
+  case SDLK_SPACE:
+    return EStdKeySpace;
+  case SDLK_QUOTE:
+    return EStdKeySingleQuote;
+  case SDLK_COMMA:
+    return EStdKeyComma;
+  case SDLK_PERIOD:
+    return EStdKeyFullStop;
+  case SDLK_0:
+    return (EpocKey)'0';
+  case SDLK_1:
+    return (EpocKey)'1';
+  case SDLK_2:
+    return (EpocKey)'2';
+  case SDLK_3:
+    return (EpocKey)'3';
+  case SDLK_4:
+    return (EpocKey)'4';
+  case SDLK_5:
+    return (EpocKey)'5';
+  case SDLK_6:
+    return (EpocKey)'6';
+  case SDLK_7:
+    return (EpocKey)'7';
+  case SDLK_8:
+    return (EpocKey)'8';
+  case SDLK_9:
+    return (EpocKey)'9';
+  case SDLK_a:
+    return (EpocKey)'A';
+  case SDLK_b:
+    return (EpocKey)'B';
+  case SDLK_c:
+    return (EpocKey)'C';
+  case SDLK_d:
+    return (EpocKey)'D';
+  case SDLK_e:
+    return (EpocKey)'E';
+  case SDLK_f:
+    return (EpocKey)'F';
+  case SDLK_g:
+    return (EpocKey)'G';
+  case SDLK_h:
+    return (EpocKey)'H';
+  case SDLK_i:
+    return (EpocKey)'I';
+  case SDLK_j:
+    return (EpocKey)'J';
+  case SDLK_k:
+    return (EpocKey)'K';
+  case SDLK_l:
+    return (EpocKey)'L';
+  case SDLK_m:
+    return (EpocKey)'M';
+  case SDLK_n:
+    return (EpocKey)'N';
+  case SDLK_o:
+    return (EpocKey)'O';
+  case SDLK_p:
+    return (EpocKey)'P';
+  case SDLK_q:
+    return (EpocKey)'Q';
+  case SDLK_r:
+    return (EpocKey)'R';
+  case SDLK_s:
+    return (EpocKey)'S';
+  case SDLK_t:
+    return (EpocKey)'T';
+  case SDLK_u:
+    return (EpocKey)'U';
+  case SDLK_v:
+    return (EpocKey)'V';
+  case SDLK_w:
+    return (EpocKey)'W';
+  case SDLK_x:
+    return (EpocKey)'X';
+  case SDLK_y:
+    return (EpocKey)'Y';
+  case SDLK_z:
+    return (EpocKey)'Z';
+  case SDLK_UP:
+    return EStdKeyUpArrow;
+  case SDLK_DOWN:
+    return EStdKeyDownArrow;
+  case SDLK_RIGHT:
+    return EStdKeyRightArrow;
+  case SDLK_LEFT:
+    return EStdKeyLeftArrow;
+  case SDLK_RSHIFT:
+    return EStdKeyRightShift;
+  case SDLK_LSHIFT:
+    return EStdKeyLeftShift;
+  case SDLK_RCTRL:
+    return EStdKeyRightCtrl;
+  case SDLK_LCTRL:
+    return EStdKeyLeftCtrl;
+  case SDLK_RALT:
+    return EStdKeyMenu;
+  case SDLK_LALT:
+    return EStdKeyMenu;
+  case SDLK_LSUPER:
+    return EStdKeyLeftFunc;
+  case SDLK_RSUPER:
+    return EStdKeyRightFunc;
+  }
+  return EStdKeyNull;
 }
 
 void emuEventLoop() {
-       // printf("Doing it\n");
-       emu->executeUntil(emu->currentCycles() + (emu->getClockSpeed() / 64));
+  // printf("Doing it\n");
+  emu->executeUntil(emu->currentCycles() + (emu->getClockSpeed() / 64));
 
-       uint8_t *lines[480];
+  uint8_t* lines[480];
 
-       SDL_LockSurface(surface);
-       int baseX = emu->getLCDOffsetX();
-       int baseY = emu->getLCDOffsetY();
-       int height = emu->getLCDHeight();
-       for (int y = 0; y < height; y++) {
-               lines[y] = (uint8_t *)surface->pixels + (surface->pitch * (y + baseY)) + (baseX * 4);
-       }
-       emu->readLCDIntoBuffer(lines, true);
-       SDL_UnlockSurface(surface);
-       SDL_Flip(surface);
+  SDL_LockSurface(surface);
+  int baseX = emu->getLCDOffsetX();
+  int baseY = emu->getLCDOffsetY();
+  int height = emu->getLCDHeight();
+  for (int y = 0; y < height; y++) {
+    lines[y] = (uint8_t*)surface->pixels + (surface->pitch * (y + baseY)) +
+               (baseX * 4);
+  }
+  emu->readLCDIntoBuffer(lines, true);
+  SDL_UnlockSurface(surface);
+  SDL_Flip(surface);
 
-       SDL_Event event;
-       while (SDL_PollEvent(&event)) {
-               if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
-                       EpocKey k = resolveKey(event.key.keysym.sym);
-                       if (k != EStdKeyNull)
-                               emu->setKeyboardKey(k, (event.key.state == SDL_PRESSED));
-               } else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
-                       if (event.button.button == SDL_BUTTON_LEFT)
-                               emu->updateTouchInput(event.button.x, event.button.y, (event.button.state == SDL_PRESSED));
-               } else if (event.type == SDL_MOUSEMOTION) {
-                       emu->updateTouchInput(event.motion.x, event.motion.y, (event.motion.state & SDL_BUTTON(1)));
-               }
-       }
+  SDL_Event event;
+  while (SDL_PollEvent(&event)) {
+    if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
+      EpocKey k = resolveKey(event.key.keysym.sym);
+      if (k != EStdKeyNull)
+        emu->setKeyboardKey(k, (event.key.state == SDL_PRESSED));
+    } else if (event.type == SDL_MOUSEBUTTONDOWN ||
+               event.type == SDL_MOUSEBUTTONUP) {
+      if (event.button.button == SDL_BUTTON_LEFT)
+        emu->updateTouchInput(event.button.x, event.button.y,
+                              (event.button.state == SDL_PRESSED));
+    } else if (event.type == SDL_MOUSEMOTION) {
+      emu->updateTouchInput(event.motion.x, event.motion.y,
+                            (event.motion.state & SDL_BUTTON(1)));
+    }
+  }
 }
 
-int main(int argc, char **argv) {
-       emu = new Windermere::Emulator;
-       emu->setLogger([](const char *str) {
-               printf("%s\n", str);
-       });
-       FILE *f = fopen("rom/5mx.bin", "rb");
-       fread(emu->getROMBuffer(), 1, 10485760, f);
-       fclose(f);
+int main(int argc, char** argv) {
+  emu = new Windermere::Emulator;
+  emu->setLogger([](const char* str) { printf("%s\n", str); });
+  FILE* f = fopen("rom/5mx.bin", "rb");
+  fread(emu->getROMBuffer(), 1, 10485760, f);
+  fclose(f);
 
-       if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) != 0) {
-               printf("SDL_Init failed: %s\n", SDL_GetError());
-               return 1;
-       }
-       surface = SDL_SetVideoMode(emu->getDigitiserWidth(), emu->getDigitiserHeight(), 32, SDL_SWSURFACE);
-       if (surface == NULL) {
-               printf("SDL_SetVideoMode failed: %s\n", SDL_GetError());
-               return 1;
-       }
+  if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) != 0) {
+    printf("SDL_Init failed: %s\n", SDL_GetError());
+    return 1;
+  }
+  surface = SDL_SetVideoMode(emu->getDigitiserWidth(),
+                             emu->getDigitiserHeight(), 32, SDL_SWSURFACE);
+  if (surface == NULL) {
+    printf("SDL_SetVideoMode failed: %s\n", SDL_GetError());
+    return 1;
+  }
 
-       EM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; SDL.defaults.opaqueFrontBuffer = false;");
+  EM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; "
+         "SDL.defaults.opaqueFrontBuffer = false;");
 
-       emscripten_set_main_loop(&emuEventLoop, 64, 1);
+  emscripten_set_main_loop(&emuEventLoop, 64, 1);
 
-       return 0;
+  return 0;
 }