commit 764710ea1250312de0469d6f81b666d260eb9953 Author: Irmen de Jong Date: Wed Sep 11 02:17:59 2019 +0200 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dc16de9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build/ + +.idea/workspace.xml +.idea/misc.xml +.idea/discord.xml diff --git a/.idea/$PRODUCT_WORKSPACE_FILE$ b/.idea/$PRODUCT_WORKSPACE_FILE$ new file mode 100644 index 0000000..6eadb35 --- /dev/null +++ b/.idea/$PRODUCT_WORKSPACE_FILE$ @@ -0,0 +1,19 @@ + + + + + + + Python 3.7 (py3) + + + + + + + + \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..6437983 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Project exclude paths +/. \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..455250f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..6b01531 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..d60ac23 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,60 @@ +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + // Apply the Kotlin JVM plugin to add support for Kotlin on the JVM. + id("org.jetbrains.kotlin.jvm").version("1.3.50") + id("com.gradle.build-scan").version("2.4.2") + id("org.jetbrains.dokka").version("0.9.18") +} + +repositories { + // Use jcenter for resolving dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() +} + +dependencies { + // Use the Kotlin JDK 8 standard library. + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + + // Use the Kotlin test library. + testImplementation("org.jetbrains.kotlin:kotlin-test") + + // Use the Kotlin JUnit5 integration. + testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.1.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.1.0") +} + +//buildScan { +// termsOfServiceUrl = "https://gradle.com/terms-of-service" +// termsOfServiceAgree="yes" +// publishOnFailure() +//} + +tasks.named("test") { + // Enable JUnit 5 (Gradle 4.6+). + useJUnitPlatform() + // Always run tests, even when nothing changed. + dependsOn("cleanTest") + // Show test results. + testLogging.events("failed") + + // parallel tests. + systemProperties["junit.jupiter.execution.parallel.enabled"] = true + systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent" + maxParallelForks = Runtime.getRuntime().availableProcessors() / 2 +} + +tasks.withType().all { + kotlinOptions { + jvmTarget = "1.8" + } +} + +tasks.named("dokka") { + outputFormat = "html" + outputDirectory = "$buildDir/kdoc" + skipEmptyPackages = true +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..f7814e6 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,7 @@ +kotlin.code.style=official +kotlinVersion=1.3.50 +org.gradle.caching=true +org.gradle.console=rich +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx2500M +org.gradle.daemon=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..5c2d1cf Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..029981b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https://services.gradle.org/distributions-snapshots/gradle-5.5.1-20190713230057+0000-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..8e25e6c --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..7437cb4 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/5.5.1-20190724234647+0000/userguide/multi_project_builds.html + */ + +rootProject.name = "ksim65" diff --git a/src/main/kotlin/net/razorvine/ksim65/Petscii.kt b/src/main/kotlin/net/razorvine/ksim65/Petscii.kt new file mode 100644 index 0000000..9173e3d --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/Petscii.kt @@ -0,0 +1,1121 @@ +package net.razorvine.ksim65 + +import java.io.CharConversionException + +object Petscii { + + // decoding: from Petscii/Screencodes (0-255) to unicode + // character tables used from https://github.com/dj51d/cbmcodecs + + private val decodingPetsciiLowercase = arrayOf( + '\u0000', // 0x00 -> \u0000 + '\ufffe', // 0x01 -> UNDEFINED + '\ufffe', // 0x02 -> UNDEFINED + '\ufffe', // 0x03 -> UNDEFINED + '\ufffe', // 0x04 -> UNDEFINED + '\uf100', // 0x05 -> WHITE COLOR SWITCH (CUS) + '\ufffe', // 0x06 -> UNDEFINED + '\ufffe', // 0x07 -> UNDEFINED + '\uf118', // 0x08 -> DISABLE CHARACTER SET SWITCHING (CUS) + '\uf119', // 0x09 -> ENABLE CHARACTER SET SWITCHING (CUS) + '\ufffe', // 0x0A -> UNDEFINED + '\ufffe', // 0x0B -> UNDEFINED + '\ufffe', // 0x0C -> UNDEFINED + '\r' , // 0x0D -> CARRIAGE RETURN + '\u000e', // 0x0E -> SHIFT OUT + '\ufffe', // 0x0F -> UNDEFINED + '\ufffe', // 0x10 -> UNDEFINED + '\uf11c', // 0x11 -> CURSOR DOWN (CUS) + '\uf11a', // 0x12 -> REVERSE VIDEO ON (CUS) + '\uf120', // 0x13 -> HOME (CUS) + '\u007f', // 0x14 -> DELETE + '\ufffe', // 0x15 -> UNDEFINED + '\ufffe', // 0x16 -> UNDEFINED + '\ufffe', // 0x17 -> UNDEFINED + '\ufffe', // 0x18 -> UNDEFINED + '\ufffe', // 0x19 -> UNDEFINED + '\ufffe', // 0x1A -> UNDEFINED + '\ufffe', // 0x1B -> UNDEFINED + '\uf101', // 0x1C -> RED COLOR SWITCH (CUS) + '\uf11d', // 0x1D -> CURSOR RIGHT (CUS) + '\uf102', // 0x1E -> GREEN COLOR SWITCH (CUS) + '\uf103', // 0x1F -> BLUE COLOR SWITCH (CUS) + ' ' , // 0x20 -> SPACE + '!' , // ! 0x21 -> EXCLAMATION MARK + '"' , // " 0x22 -> QUOTATION MARK + '#' , // # 0x23 -> NUMBER SIGN + '$' , // $ 0x24 -> DOLLAR SIGN + '%' , // % 0x25 -> PERCENT SIGN + '&' , // & 0x26 -> AMPERSAND + '\'' , // ' 0x27 -> APOSTROPHE + '(' , // ( 0x28 -> LEFT PARENTHESIS + ')' , // ) 0x29 -> RIGHT PARENTHESIS + '*' , // * 0x2A -> ASTERISK + '+' , // + 0x2B -> PLUS SIGN + ',' , // , 0x2C -> COMMA + '-' , // - 0x2D -> HYPHEN-MINUS + '.' , // . 0x2E -> FULL STOP + '/' , // / 0x2F -> SOLIDUS + '0' , // 0 0x30 -> DIGIT ZERO + '1' , // 1 0x31 -> DIGIT ONE + '2' , // 2 0x32 -> DIGIT TWO + '3' , // 3 0x33 -> DIGIT THREE + '4' , // 4 0x34 -> DIGIT FOUR + '5' , // 5 0x35 -> DIGIT FIVE + '6' , // 6 0x36 -> DIGIT SIX + '7' , // 7 0x37 -> DIGIT SEVEN + '8' , // 8 0x38 -> DIGIT EIGHT + '9' , // 9 0x39 -> DIGIT NINE + ':' , // : 0x3A -> COLON + ';' , // ; 0x3B -> SEMICOLON + '<' , // < 0x3C -> LESS-THAN SIGN + '=' , // = 0x3D -> EQUALS SIGN + '>' , // > 0x3E -> GREATER-THAN SIGN + '?' , // ? 0x3F -> QUESTION MARK + '@' , // @ 0x40 -> COMMERCIAL AT + 'a' , // a 0x41 -> LATIN SMALL LETTER A + 'b' , // b 0x42 -> LATIN SMALL LETTER B + 'c' , // c 0x43 -> LATIN SMALL LETTER C + 'd' , // d 0x44 -> LATIN SMALL LETTER D + 'e' , // e 0x45 -> LATIN SMALL LETTER E + 'f' , // f 0x46 -> LATIN SMALL LETTER F + 'g' , // g 0x47 -> LATIN SMALL LETTER G + 'h' , // h 0x48 -> LATIN SMALL LETTER H + 'i' , // i 0x49 -> LATIN SMALL LETTER I + 'j' , // j 0x4A -> LATIN SMALL LETTER J + 'k' , // k 0x4B -> LATIN SMALL LETTER K + 'l' , // l 0x4C -> LATIN SMALL LETTER L + 'm' , // m 0x4D -> LATIN SMALL LETTER M + 'n' , // n 0x4E -> LATIN SMALL LETTER N + 'o' , // o 0x4F -> LATIN SMALL LETTER O + 'p' , // p 0x50 -> LATIN SMALL LETTER P + 'q' , // q 0x51 -> LATIN SMALL LETTER Q + 'r' , // r 0x52 -> LATIN SMALL LETTER R + 's' , // s 0x53 -> LATIN SMALL LETTER S + 't' , // t 0x54 -> LATIN SMALL LETTER T + 'u' , // u 0x55 -> LATIN SMALL LETTER U + 'v' , // v 0x56 -> LATIN SMALL LETTER V + 'w' , // w 0x57 -> LATIN SMALL LETTER W + 'x' , // x 0x58 -> LATIN SMALL LETTER X + 'y' , // y 0x59 -> LATIN SMALL LETTER Y + 'z' , // z 0x5A -> LATIN SMALL LETTER Z + '[' , // [ 0x5B -> LEFT SQUARE BRACKET + '\u00a3', // £ 0x5C -> POUND SIGN + ']' , // ] 0x5D -> RIGHT SQUARE BRACKET + '\u2191', // ↑ 0x5E -> UPWARDS ARROW + '\u2190', // ← 0x5F -> LEFTWARDS ARROW + '\u2500', // ─ 0x60 -> BOX DRAWINGS LIGHT HORIZONTAL + 'A' , // A 0x61 -> LATIN CAPITAL LETTER A + 'B' , // B 0x62 -> LATIN CAPITAL LETTER B + 'C' , // C 0x63 -> LATIN CAPITAL LETTER C + 'D' , // D 0x64 -> LATIN CAPITAL LETTER D + 'E' , // E 0x65 -> LATIN CAPITAL LETTER E + 'F' , // F 0x66 -> LATIN CAPITAL LETTER F + 'G' , // G 0x67 -> LATIN CAPITAL LETTER G + 'H' , // H 0x68 -> LATIN CAPITAL LETTER H + 'I' , // I 0x69 -> LATIN CAPITAL LETTER I + 'J' , // J 0x6A -> LATIN CAPITAL LETTER J + 'K' , // K 0x6B -> LATIN CAPITAL LETTER K + 'L' , // L 0x6C -> LATIN CAPITAL LETTER L + 'M' , // M 0x6D -> LATIN CAPITAL LETTER M + 'N' , // N 0x6E -> LATIN CAPITAL LETTER N + 'O' , // O 0x6F -> LATIN CAPITAL LETTER O + 'P' , // P 0x70 -> LATIN CAPITAL LETTER P + 'Q' , // Q 0x71 -> LATIN CAPITAL LETTER Q + 'R' , // R 0x72 -> LATIN CAPITAL LETTER R + 'S' , // S 0x73 -> LATIN CAPITAL LETTER S + 'T' , // T 0x74 -> LATIN CAPITAL LETTER T + 'U' , // U 0x75 -> LATIN CAPITAL LETTER U + 'V' , // V 0x76 -> LATIN CAPITAL LETTER V + 'W' , // W 0x77 -> LATIN CAPITAL LETTER W + 'X' , // X 0x78 -> LATIN CAPITAL LETTER X + 'Y' , // Y 0x79 -> LATIN CAPITAL LETTER Y + 'Z' , // Z 0x7A -> LATIN CAPITAL LETTER Z + '\u253c', // ┼ 0x7B -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0x7C -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0x7D -> BOX DRAWINGS LIGHT VERTICAL + '\u2592', // ▒ 0x7E -> MEDIUM SHADE + '\uf139', //  0x7F -> MEDIUM SHADE SLASHED LEFT (CUS) + '\ufffe', // 0x80 -> UNDEFINED + '\uf104', // 0x81 -> ORANGE COLOR SWITCH (CUS) + '\ufffe', // 0x82 -> UNDEFINED + '\ufffe', // 0x83 -> UNDEFINED + '\ufffe', // 0x84 -> UNDEFINED + '\uf110', //  0x85 -> FUNCTION KEY 1 (CUS) + '\uf112', //  0x86 -> FUNCTION KEY 3 (CUS) + '\uf114', //  0x87 -> FUNCTION KEY 5 (CUS) + '\uf116', //  0x88 -> FUNCTION KEY 7 (CUS) + '\uf111', //  0x89 -> FUNCTION KEY 2 (CUS) + '\uf113', //  0x8A -> FUNCTION KEY 4 (CUS) + '\uf115', //  0x8B -> FUNCTION KEY 6 (CUS) + '\uf117', //  0x8C -> FUNCTION KEY 8 (CUS) + '\n' , // 0x8D -> LINE FEED + '\u000f', //  0x8E -> SHIFT IN + '\ufffe', // 0x8F -> UNDEFINED + '\uf105', // 0x90 -> BLACK COLOR SWITCH (CUS) + '\uf11e', //  0x91 -> CURSOR UP (CUS) + '\uf11b', //  0x92 -> REVERSE VIDEO OFF (CUS) + '\u000c', // 0x93 -> FORM FEED + '\uf121', //  0x94 -> INSERT (CUS) + '\uf106', // 0x95 -> BROWN COLOR SWITCH (CUS) + '\uf107', // 0x96 -> LIGHT RED COLOR SWITCH (CUS) + '\uf108', // 0x97 -> GRAY 1 COLOR SWITCH (CUS) + '\uf109', //  0x98 -> GRAY 2 COLOR SWITCH (CUS) + '\uf10a', //  0x99 -> LIGHT GREEN COLOR SWITCH (CUS) + '\uf10b', //  0x9A -> LIGHT BLUE COLOR SWITCH (CUS) + '\uf10c', //  0x9B -> GRAY 3 COLOR SWITCH (CUS) + '\uf10d', //  0x9C -> PURPLE COLOR SWITCH (CUS) + '\uf11d', //  0x9D -> CURSOR LEFT (CUS) + '\uf10e', //  0x9E -> YELLOW COLOR SWITCH (CUS) + '\uf10f', //  0x9F -> CYAN COLOR SWITCH (CUS) + '\u00a0', // 0xA0 -> NO-BREAK SPACE + '\u258c', // ▌ 0xA1 -> LEFT HALF BLOCK + '\u2584', // ▄ 0xA2 -> LOWER HALF BLOCK + '\u2594', // ▔ 0xA3 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0xA4 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0xA5 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0xA6 -> MEDIUM SHADE + '\u2595', // ▕ 0xA7 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0xA8 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\uf13a', //  0xA9 -> MEDIUM SHADE SLASHED RIGHT (CUS) + '\uf130', //  0xAA -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0xAB -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0xAC -> QUADRANT LOWER RIGHT + '\u2514', // └ 0xAD -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0xAE -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0xAF -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0xB0 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0xB1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0xB2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0xB3 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0xB4 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0xB5 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0xB6 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0xB7 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0xB8 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0xB9 -> LOWER THREE EIGHTHS BLOCK + '\u2713', // ✓ 0xBA -> CHECK MARK + '\u2596', // ▖ 0xBB -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0xBC -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0xBD -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0xBE -> QUADRANT UPPER LEFT + '\u259a', // ▚ 0xBF -> QUADRANT UPPER LEFT AND LOWER RIGHT + '\u2500', // ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL + 'A' , // A 0xC1 -> LATIN CAPITAL LETTER A + 'B' , // B 0xC2 -> LATIN CAPITAL LETTER B + 'C' , // C 0xC3 -> LATIN CAPITAL LETTER C + 'D' , // D 0xC4 -> LATIN CAPITAL LETTER D + 'E' , // E 0xC5 -> LATIN CAPITAL LETTER E + 'F' , // F 0xC6 -> LATIN CAPITAL LETTER F + 'G' , // G 0xC7 -> LATIN CAPITAL LETTER G + 'H' , // H 0xC8 -> LATIN CAPITAL LETTER H + 'I' , // I 0xC9 -> LATIN CAPITAL LETTER I + 'J' , // J 0xCA -> LATIN CAPITAL LETTER J + 'K' , // K 0xCB -> LATIN CAPITAL LETTER K + 'L' , // L 0xCC -> LATIN CAPITAL LETTER L + 'M' , // M 0xCD -> LATIN CAPITAL LETTER M + 'N' , // N 0xCE -> LATIN CAPITAL LETTER N + 'O' , // O 0xCF -> LATIN CAPITAL LETTER O + 'P' , // P 0xD0 -> LATIN CAPITAL LETTER P + 'Q' , // Q 0xD1 -> LATIN CAPITAL LETTER Q + 'R' , // R 0xD2 -> LATIN CAPITAL LETTER R + 'S' , // S 0xD3 -> LATIN CAPITAL LETTER S + 'T' , // T 0xD4 -> LATIN CAPITAL LETTER T + 'U' , // U 0xD5 -> LATIN CAPITAL LETTER U + 'V' , // V 0xD6 -> LATIN CAPITAL LETTER V + 'W' , // W 0xD7 -> LATIN CAPITAL LETTER W + 'X' , // X 0xD8 -> LATIN CAPITAL LETTER X + 'Y' , // Y 0xD9 -> LATIN CAPITAL LETTER Y + 'Z' , // Z 0xDA -> LATIN CAPITAL LETTER Z + '\u253c', // ┼ 0xDB -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0xDC -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0xDD -> BOX DRAWINGS LIGHT VERTICAL + '\u2592', // ▒ 0xDE -> MEDIUM SHADE + '\uf139', //  0xDF -> MEDIUM SHADE SLASHED LEFT (CUS) + '\u00a0', // 0xE0 -> NO-BREAK SPACE + '\u258c', // ▌ 0xE1 -> LEFT HALF BLOCK + '\u2584', // ▄ 0xE2 -> LOWER HALF BLOCK + '\u2594', // ▔ 0xE3 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0xE4 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0xE5 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0xE6 -> MEDIUM SHADE + '\u2595', // ▕ 0xE7 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0xE8 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\uf13a', //  0xE9 -> MEDIUM SHADE SLASHED RIGHT (CUS) + '\uf130', //  0xEA -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0xEB -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0xEC -> QUADRANT LOWER RIGHT + '\u2514', // └ 0xED -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0xEE -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0xEF -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0xF0 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0xF1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0xF2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0xF3 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0xF4 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0xF5 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0xF6 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0xF7 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0xF8 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0xF9 -> LOWER THREE EIGHTHS BLOCK + '\u2713', // ✓ 0xFA -> CHECK MARK + '\u2596', // ▖ 0xFB -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0xFC -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0xFD -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0xFE -> QUADRANT UPPER LEFT + '\u2592' // ▒ 0xFF -> MEDIUM SHADE + ) + + private val decodingPetsciiUppercase = arrayOf( + '\u0000', // 0x00 -> \u0000 + '\ufffe', // 0x01 -> UNDEFINED + '\ufffe', // 0x02 -> UNDEFINED + '\ufffe', // 0x03 -> UNDEFINED + '\ufffe', // 0x04 -> UNDEFINED + '\uf100', // 0x05 -> WHITE COLOR SWITCH (CUS) + '\ufffe', // 0x06 -> UNDEFINED + '\ufffe', // 0x07 -> UNDEFINED + '\uf118', // 0x08 -> DISABLE CHARACTER SET SWITCHING (CUS) + '\uf119', // 0x09 -> ENABLE CHARACTER SET SWITCHING (CUS) + '\ufffe', // 0x0A -> UNDEFINED + '\ufffe', // 0x0B -> UNDEFINED + '\ufffe', // 0x0C -> UNDEFINED + '\r' , // 0x0D -> CARRIAGE RETURN + '\u000e', // 0x0E -> SHIFT OUT + '\ufffe', // 0x0F -> UNDEFINED + '\ufffe', // 0x10 -> UNDEFINED + '\uf11c', // 0x11 -> CURSOR DOWN (CUS) + '\uf11a', // 0x12 -> REVERSE VIDEO ON (CUS) + '\uf120', // 0x13 -> HOME (CUS) + '\u007f', // 0x14 -> DELETE + '\ufffe', // 0x15 -> UNDEFINED + '\ufffe', // 0x16 -> UNDEFINED + '\ufffe', // 0x17 -> UNDEFINED + '\ufffe', // 0x18 -> UNDEFINED + '\ufffe', // 0x19 -> UNDEFINED + '\ufffe', // 0x1A -> UNDEFINED + '\ufffe', // 0x1B -> UNDEFINED + '\uf101', // 0x1C -> RED COLOR SWITCH (CUS) + '\uf11d', // 0x1D -> CURSOR RIGHT (CUS) + '\uf102', // 0x1E -> GREEN COLOR SWITCH (CUS) + '\uf103', // 0x1F -> BLUE COLOR SWITCH (CUS) + ' ' , // 0x20 -> SPACE + '!' , // ! 0x21 -> EXCLAMATION MARK + '"' , // " 0x22 -> QUOTATION MARK + '#' , // # 0x23 -> NUMBER SIGN + '$' , // $ 0x24 -> DOLLAR SIGN + '%' , // % 0x25 -> PERCENT SIGN + '&' , // & 0x26 -> AMPERSAND + '\'' , // ' 0x27 -> APOSTROPHE + '(' , // ( 0x28 -> LEFT PARENTHESIS + ')' , // ) 0x29 -> RIGHT PARENTHESIS + '*' , // * 0x2A -> ASTERISK + '+' , // + 0x2B -> PLUS SIGN + ',' , // , 0x2C -> COMMA + '-' , // - 0x2D -> HYPHEN-MINUS + '.' , // . 0x2E -> FULL STOP + '/' , // / 0x2F -> SOLIDUS + '0' , // 0 0x30 -> DIGIT ZERO + '1' , // 1 0x31 -> DIGIT ONE + '2' , // 2 0x32 -> DIGIT TWO + '3' , // 3 0x33 -> DIGIT THREE + '4' , // 4 0x34 -> DIGIT FOUR + '5' , // 5 0x35 -> DIGIT FIVE + '6' , // 6 0x36 -> DIGIT SIX + '7' , // 7 0x37 -> DIGIT SEVEN + '8' , // 8 0x38 -> DIGIT EIGHT + '9' , // 9 0x39 -> DIGIT NINE + ':' , // : 0x3A -> COLON + ';' , // ; 0x3B -> SEMICOLON + '<' , // < 0x3C -> LESS-THAN SIGN + '=' , // = 0x3D -> EQUALS SIGN + '>' , // > 0x3E -> GREATER-THAN SIGN + '?' , // ? 0x3F -> QUESTION MARK + '@' , // @ 0x40 -> COMMERCIAL AT + 'A' , // A 0x41 -> LATIN CAPITAL LETTER A + 'B' , // B 0x42 -> LATIN CAPITAL LETTER B + 'C' , // C 0x43 -> LATIN CAPITAL LETTER C + 'D' , // D 0x44 -> LATIN CAPITAL LETTER D + 'E' , // E 0x45 -> LATIN CAPITAL LETTER E + 'F' , // F 0x46 -> LATIN CAPITAL LETTER F + 'G' , // G 0x47 -> LATIN CAPITAL LETTER G + 'H' , // H 0x48 -> LATIN CAPITAL LETTER H + 'I' , // I 0x49 -> LATIN CAPITAL LETTER I + 'J' , // J 0x4A -> LATIN CAPITAL LETTER J + 'K' , // K 0x4B -> LATIN CAPITAL LETTER K + 'L' , // L 0x4C -> LATIN CAPITAL LETTER L + 'M' , // M 0x4D -> LATIN CAPITAL LETTER M + 'N' , // N 0x4E -> LATIN CAPITAL LETTER N + 'O' , // O 0x4F -> LATIN CAPITAL LETTER O + 'P' , // P 0x50 -> LATIN CAPITAL LETTER P + 'Q' , // Q 0x51 -> LATIN CAPITAL LETTER Q + 'R' , // R 0x52 -> LATIN CAPITAL LETTER R + 'S' , // S 0x53 -> LATIN CAPITAL LETTER S + 'T' , // T 0x54 -> LATIN CAPITAL LETTER T + 'U' , // U 0x55 -> LATIN CAPITAL LETTER U + 'V' , // V 0x56 -> LATIN CAPITAL LETTER V + 'W' , // W 0x57 -> LATIN CAPITAL LETTER W + 'X' , // X 0x58 -> LATIN CAPITAL LETTER X + 'Y' , // Y 0x59 -> LATIN CAPITAL LETTER Y + 'Z' , // Z 0x5A -> LATIN CAPITAL LETTER Z + '[' , // [ 0x5B -> LEFT SQUARE BRACKET + '\u00a3', // £ 0x5C -> POUND SIGN + ']' , // ] 0x5D -> RIGHT SQUARE BRACKET + '\u2191', // ↑ 0x5E -> UPWARDS ARROW + '\u2190', // ← 0x5F -> LEFTWARDS ARROW + '\u2500', // ─ 0x60 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2660', // ♠ 0x61 -> BLACK SPADE SUIT + '\u2502', // │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL + '\u2500', // ─ 0x63 -> BOX DRAWINGS LIGHT HORIZONTAL + '\uf122', //  0x64 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER UP (CUS) + '\uf123', //  0x65 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS UP (CUS) + '\uf124', //  0x66 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER DOWN (CUS) + '\uf126', //  0x67 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER LEFT (CUS) + '\uf128', //  0x68 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER RIGHT (CUS) + '\u256e', // ╮ 0x69 -> BOX DRAWINGS LIGHT ARC DOWN AND LEFT + '\u2570', // ╰ 0x6A -> BOX DRAWINGS LIGHT ARC UP AND RIGHT + '\u256f', // ╯ 0x6B -> BOX DRAWINGS LIGHT ARC UP AND LEFT + '\uf12a', //  0x6C -> ONE EIGHTH BLOCK UP AND RIGHT (CUS) + '\u2572', // ╲ 0x6D -> BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + '\u2571', // ╱ 0x6E -> BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + '\uf12b', //  0x6F -> ONE EIGHTH BLOCK DOWN AND RIGHT (CUS) + '\uf12c', //  0x70 -> ONE EIGHTH BLOCK DOWN AND LEFT (CUS) + '\u25cf', // ● 0x71 -> BLACK CIRCLE + '\uf125', //  0x72 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS DOWN (CUS) + '\u2665', // ♥ 0x73 -> BLACK HEART SUIT + '\uf127', //  0x74 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS LEFT (CUS) + '\u256d', // ╭ 0x75 -> BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + '\u2573', // ╳ 0x76 -> BOX DRAWINGS LIGHT DIAGONAL CROSS + '\u25cb', // ○ 0x77 -> WHITE CIRCLE + '\u2663', // ♣ 0x78 -> BLACK CLUB SUIT + '\uf129', //  0x79 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS RIGHT (CUS) + '\u2666', // ♦ 0x7A -> BLACK DIAMOND SUIT + '\u253c', // ┼ 0x7B -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0x7C -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0x7D -> BOX DRAWINGS LIGHT VERTICAL + '\u03c0', // π 0x7E -> GREEK SMALL LETTER PI + '\u25e5', // ◥ 0x7F -> BLACK UPPER RIGHT TRIANGLE + '\ufffe', // 0x80 -> UNDEFINED + '\uf104', //  0x81 -> ORANGE COLOR SWITCH (CUS) + '\ufffe', // 0x82 -> UNDEFINED + '\ufffe', // 0x83 -> UNDEFINED + '\ufffe', // 0x84 -> UNDEFINED + '\uf110', // 0x85 -> FUNCTION KEY 1 (CUS) + '\uf112', // 0x86 -> FUNCTION KEY 3 (CUS) + '\uf114', // 0x87 -> FUNCTION KEY 5 (CUS) + '\uf116', // 0x88 -> FUNCTION KEY 7 (CUS) + '\uf111', // 0x89 -> FUNCTION KEY 2 (CUS) + '\uf113', // 0x8A -> FUNCTION KEY 4 (CUS) + '\uf115', // 0x8B -> FUNCTION KEY 6 (CUS) + '\uf117', // 0x8C -> FUNCTION KEY 8 (CUS) + '\n' , // 0x8D -> LINE FEED + '\u000f', // 0x8E -> SHIFT IN + '\ufffe', // 0x8F -> UNDEFINED + '\uf105', // 0x90 -> BLACK COLOR SWITCH (CUS) + '\uf11e', // 0x91 -> CURSOR UP (CUS) + '\uf11b', // 0x92 -> REVERSE VIDEO OFF (CUS) + '\u000c', // 0x93 -> FORM FEED + '\uf121', // 0x94 -> INSERT (CUS) + '\uf106', // 0x95 -> BROWN COLOR SWITCH (CUS) + '\uf107', // 0x96 -> LIGHT RED COLOR SWITCH (CUS) + '\uf108', // 0x97 -> GRAY 1 COLOR SWITCH (CUS) + '\uf109', // 0x98 -> GRAY 2 COLOR SWITCH (CUS) + '\uf10a', // 0x99 -> LIGHT GREEN COLOR SWITCH (CUS) + '\uf10b', // 0x9A -> LIGHT BLUE COLOR SWITCH (CUS) + '\uf10c', // 0x9B -> GRAY 3 COLOR SWITCH (CUS) + '\uf10d', // 0x9C -> PURPLE COLOR SWITCH (CUS) + '\uf11d', // 0x9D -> CURSOR LEFT (CUS) + '\uf10e', // 0x9E -> YELLOW COLOR SWITCH (CUS) + '\uf10f', // 0x9F -> CYAN COLOR SWITCH (CUS) + '\u00a0', // 0xA0 -> NO-BREAK SPACE + '\u258c', // ▌ 0xA1 -> LEFT HALF BLOCK + '\u2584', // ▄ 0xA2 -> LOWER HALF BLOCK + '\u2594', // ▔ 0xA3 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0xA4 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0xA5 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0xA6 -> MEDIUM SHADE + '\u2595', // ▕ 0xA7 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0xA8 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\u25e4', // ◤ 0xA9 -> BLACK UPPER LEFT TRIANGLE + '\uf130', //  0xAA -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0xAB -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0xAC -> QUADRANT LOWER RIGHT + '\u2514', // └ 0xAD -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0xAE -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0xAF -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0xB0 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0xB1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0xB2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0xB3 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0xB4 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0xB5 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0xB6 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0xB7 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0xB8 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0xB9 -> LOWER THREE EIGHTHS BLOCK + '\uf12d', //  0xBA -> ONE EIGHTH BLOCK UP AND LEFT (CUS) + '\u2596', // ▖ 0xBB -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0xBC -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0xBD -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0xBE -> QUADRANT UPPER LEFT + '\u259a', // ▚ 0xBF -> QUADRANT UPPER LEFT AND LOWER RIGHT + '\u2500', // ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2660', // ♠ 0xC1 -> BLACK SPADE SUIT + '\u2502', // │ 0xC2 -> BOX DRAWINGS LIGHT VERTICAL + '\u2500', // ─ 0xC3 -> BOX DRAWINGS LIGHT HORIZONTAL + '\uf122', //  0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER UP (CUS) + '\uf123', //  0xC5 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS UP (CUS) + '\uf124', //  0xC6 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER DOWN (CUS) + '\uf126', //  0xC7 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER LEFT (CUS) + '\uf128', //  0xC8 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER RIGHT (CUS) + '\u256e', // ╮ 0xC9 -> BOX DRAWINGS LIGHT ARC DOWN AND LEFT + '\u2570', // ╰ 0xCA -> BOX DRAWINGS LIGHT ARC UP AND RIGHT + '\u256f', // ╯ 0xCB -> BOX DRAWINGS LIGHT ARC UP AND LEFT + '\uf12a', //  0xCC -> ONE EIGHTH BLOCK UP AND RIGHT (CUS) + '\u2572', // ╲ 0xCD -> BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + '\u2571', // ╱ 0xCE -> BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + '\uf12b', //  0xCF -> ONE EIGHTH BLOCK DOWN AND RIGHT (CUS) + '\uf12c', //  0xD0 -> ONE EIGHTH BLOCK DOWN AND LEFT (CUS) + '\u25cf', // ● 0xD1 -> BLACK CIRCLE + '\uf125', //  0xD2 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS DOWN (CUS) + '\u2665', // ♥ 0xD3 -> BLACK HEART SUIT + '\uf127', //  0xD4 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS LEFT (CUS) + '\u256d', // ╭ 0xD5 -> BOX DRAWINGS LIGHT ARC DOWN AND LEFT + '\u2573', // ╳ 0xD6 -> BOX DRAWINGS LIGHT DIAGONAL CROSS + '\u25cb', // ○ 0xD7 -> WHITE CIRCLE + '\u2663', // ♣ 0xD8 -> BLACK CLUB SUIT + '\uf129', //  0xD9 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS RIGHT (CUS) + '\u2666', // ♦ 0xDA -> BLACK DIAMOND SUIT + '\u253c', // ┼ 0xDB -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0xDC -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0xDD -> BOX DRAWINGS LIGHT VERTICAL + '\u03c0', // π 0xDE -> GREEK SMALL LETTER PI + '\u25e5', // ◥ 0xDF -> BLACK UPPER RIGHT TRIANGLE + '\u00a0', // 0xE0 -> NO-BREAK SPACE + '\u258c', // ▌ 0xE1 -> LEFT HALF BLOCK + '\u2584', // ▄ 0xE2 -> LOWER HALF BLOCK + '\u2594', // ▔ 0xE3 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0xE4 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0xE5 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0xE6 -> MEDIUM SHADE + '\u2595', // ▕ 0xE7 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0xE8 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\u25e4', // ◤ 0xE9 -> BLACK UPPER LEFT TRIANGLE + '\uf130', //  0xEA -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0xEB -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0xEC -> QUADRANT LOWER RIGHT + '\u2514', // └ 0xED -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0xEE -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0xEF -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0xF0 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0xF1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0xF2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0xF3 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0xF4 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0xF5 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0xF6 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0xF7 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0xF8 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0xF9 -> LOWER THREE EIGHTHS BLOCK + '\uf12d', //  0xFA -> ONE EIGHTH BLOCK UP AND LEFT (CUS) + '\u2596', // ▖ 0xFB -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0xFC -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0xFD -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0xFE -> QUADRANT UPPER LEFT + '\u03c0' // π 0xFF -> GREEK SMALL LETTER PI + ) + + private val decodingScreencodeLowercase = arrayOf( + '@' , // @ 0x00 -> COMMERCIAL AT + 'a' , // a 0x01 -> LATIN SMALL LETTER A + 'b' , // b 0x02 -> LATIN SMALL LETTER B + 'c' , // c 0x03 -> LATIN SMALL LETTER C + 'd' , // d 0x04 -> LATIN SMALL LETTER D + 'e' , // e 0x05 -> LATIN SMALL LETTER E + 'f' , // f 0x06 -> LATIN SMALL LETTER F + 'g' , // g 0x07 -> LATIN SMALL LETTER G + 'h' , // h 0x08 -> LATIN SMALL LETTER H + 'i' , // i 0x09 -> LATIN SMALL LETTER I + 'j' , // j 0x0A -> LATIN SMALL LETTER J + 'k' , // k 0x0B -> LATIN SMALL LETTER K + 'l' , // l 0x0C -> LATIN SMALL LETTER L + 'm' , // m 0x0D -> LATIN SMALL LETTER M + 'n' , // n 0x0E -> LATIN SMALL LETTER N + 'o' , // o 0x0F -> LATIN SMALL LETTER O + 'p' , // p 0x10 -> LATIN SMALL LETTER P + 'q' , // q 0x11 -> LATIN SMALL LETTER Q + 'r' , // r 0x12 -> LATIN SMALL LETTER R + 's' , // s 0x13 -> LATIN SMALL LETTER S + 't' , // t 0x14 -> LATIN SMALL LETTER T + 'u' , // u 0x15 -> LATIN SMALL LETTER U + 'v' , // v 0x16 -> LATIN SMALL LETTER V + 'w' , // w 0x17 -> LATIN SMALL LETTER W + 'x' , // x 0x18 -> LATIN SMALL LETTER X + 'y' , // y 0x19 -> LATIN SMALL LETTER Y + 'z' , // z 0x1A -> LATIN SMALL LETTER Z + '[' , // [ 0x1B -> LEFT SQUARE BRACKET + '\u00a3', // £ 0x1C -> POUND SIGN + ']' , // ] 0x1D -> RIGHT SQUARE BRACKET + '\u2191', // ↑ 0x1E -> UPWARDS ARROW + '\u2190', // ← 0x1F -> LEFTWARDS ARROW + ' ' , // 0x20 -> SPACE + '!' , // ! 0x21 -> EXCLAMATION MARK + '"' , // " 0x22 -> QUOTATION MARK + '#' , // # 0x23 -> NUMBER SIGN + '$' , // $ 0x24 -> DOLLAR SIGN + '%' , // % 0x25 -> PERCENT SIGN + '&' , // & 0x26 -> AMPERSAND + '\'' , // ' 0x27 -> APOSTROPHE + '(' , // ( 0x28 -> LEFT PARENTHESIS + ')' , // ) 0x29 -> RIGHT PARENTHESIS + '*' , // * 0x2A -> ASTERISK + '+' , // + 0x2B -> PLUS SIGN + ',' , // , 0x2C -> COMMA + '-' , // - 0x2D -> HYPHEN-MINUS + '.' , // . 0x2E -> FULL STOP + '/' , // / 0x2F -> SOLIDUS + '0' , // 0 0x30 -> DIGIT ZERO + '1' , // 1 0x31 -> DIGIT ONE + '2' , // 2 0x32 -> DIGIT TWO + '3' , // 3 0x33 -> DIGIT THREE + '4' , // 4 0x34 -> DIGIT FOUR + '5' , // 5 0x35 -> DIGIT FIVE + '6' , // 6 0x36 -> DIGIT SIX + '7' , // 7 0x37 -> DIGIT SEVEN + '8' , // 8 0x38 -> DIGIT EIGHT + '9' , // 9 0x39 -> DIGIT NINE + ':' , // : 0x3A -> COLON + ';' , // ; 0x3B -> SEMICOLON + '<' , // < 0x3C -> LESS-THAN SIGN + '=' , // = 0x3D -> EQUALS SIGN + '>' , // > 0x3E -> GREATER-THAN SIGN + '?' , // ? 0x3F -> QUESTION MARK + '\u2500', // ─ 0x40 -> BOX DRAWINGS LIGHT HORIZONTAL + 'A' , // A 0x41 -> LATIN CAPITAL LETTER A + 'B' , // B 0x42 -> LATIN CAPITAL LETTER B + 'C' , // C 0x43 -> LATIN CAPITAL LETTER C + 'D' , // D 0x44 -> LATIN CAPITAL LETTER D + 'E' , // E 0x45 -> LATIN CAPITAL LETTER E + 'F' , // F 0x46 -> LATIN CAPITAL LETTER F + 'G' , // G 0x47 -> LATIN CAPITAL LETTER G + 'H' , // H 0x48 -> LATIN CAPITAL LETTER H + 'I' , // I 0x49 -> LATIN CAPITAL LETTER I + 'J' , // J 0x4A -> LATIN CAPITAL LETTER J + 'K' , // K 0x4B -> LATIN CAPITAL LETTER K + 'L' , // L 0x4C -> LATIN CAPITAL LETTER L + 'M' , // M 0x4D -> LATIN CAPITAL LETTER M + 'N' , // N 0x4E -> LATIN CAPITAL LETTER N + 'O' , // O 0x4F -> LATIN CAPITAL LETTER O + 'P' , // P 0x50 -> LATIN CAPITAL LETTER P + 'Q' , // Q 0x51 -> LATIN CAPITAL LETTER Q + 'R' , // R 0x52 -> LATIN CAPITAL LETTER R + 'S' , // S 0x53 -> LATIN CAPITAL LETTER S + 'T' , // T 0x54 -> LATIN CAPITAL LETTER T + 'U' , // U 0x55 -> LATIN CAPITAL LETTER U + 'V' , // V 0x56 -> LATIN CAPITAL LETTER V + 'W' , // W 0x57 -> LATIN CAPITAL LETTER W + 'X' , // X 0x58 -> LATIN CAPITAL LETTER X + 'Y' , // Y 0x59 -> LATIN CAPITAL LETTER Y + 'Z' , // Z 0x5A -> LATIN CAPITAL LETTER Z + '\u253c', // ┼ 0x5B -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0x5C -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0x5D -> BOX DRAWINGS LIGHT VERTICAL + '\u2592', // ▒ 0x5E -> MEDIUM SHADE + '\uf139', //  0x5F -> MEDIUM SHADE SLASHED LEFT (CUS) + '\u00a0', // 0x60 -> NO-BREAK SPACE + '\u258c', // ▌ 0x61 -> LEFT HALF BLOCK + '\u2584', // ▄ 0x62 -> LOWER HALF BLOCK + '\u2594', // ▔ 0x63 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0x64 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0x65 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0x66 -> MEDIUM SHADE + '\u2595', // ▕ 0x67 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0x68 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\uf13a', //  0x69 -> MEDIUM SHADE SLASHED RIGHT (CUS) + '\uf130', //  0x6A -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0x6B -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0x6C -> QUADRANT LOWER RIGHT + '\u2514', // └ 0x6D -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0x6E -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0x6F -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0x70 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0x71 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0x72 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0x73 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0x74 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0x75 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0x76 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0x77 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0x78 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0x79 -> LOWER THREE EIGHTHS BLOCK + '\u2713', // ✓ 0x7A -> CHECK MARK + '\u2596', // ▖ 0x7B -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0x7C -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0x7D -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0x7E -> QUADRANT UPPER LEFT + '\u259a', // ▚ 0x7F -> QUADRANT UPPER LEFT AND LOWER RIGHT + '\ufffe', // 0x80 -> UNDEFINED + '\ufffe', // 0x81 -> UNDEFINED + '\ufffe', // 0x82 -> UNDEFINED + '\ufffe', // 0x83 -> UNDEFINED + '\ufffe', // 0x84 -> UNDEFINED + '\ufffe', // 0x85 -> UNDEFINED + '\ufffe', // 0x86 -> UNDEFINED + '\ufffe', // 0x87 -> UNDEFINED + '\ufffe', // 0x88 -> UNDEFINED + '\ufffe', // 0x89 -> UNDEFINED + '\ufffe', // 0x8A -> UNDEFINED + '\ufffe', // 0x8B -> UNDEFINED + '\ufffe', // 0x8C -> UNDEFINED + '\ufffe', // 0x8D -> UNDEFINED + '\ufffe', // 0x8E -> UNDEFINED + '\ufffe', // 0x8F -> UNDEFINED + '\ufffe', // 0x90 -> UNDEFINED + '\ufffe', // 0x91 -> UNDEFINED + '\ufffe', // 0x92 -> UNDEFINED + '\ufffe', // 0x93 -> UNDEFINED + '\ufffe', // 0x94 -> UNDEFINED + '\ufffe', // 0x95 -> UNDEFINED + '\ufffe', // 0x96 -> UNDEFINED + '\ufffe', // 0x97 -> UNDEFINED + '\ufffe', // 0x98 -> UNDEFINED + '\ufffe', // 0x99 -> UNDEFINED + '\ufffe', // 0x9A -> UNDEFINED + '\ufffe', // 0x9B -> UNDEFINED + '\ufffe', // 0x9C -> UNDEFINED + '\ufffe', // 0x9D -> UNDEFINED + '\ufffe', // 0x9E -> UNDEFINED + '\ufffe', // 0x9F -> UNDEFINED + '\ufffe', // 0xA0 -> UNDEFINED + '\ufffe', // 0xA1 -> UNDEFINED + '\ufffe', // 0xA2 -> UNDEFINED + '\ufffe', // 0xA3 -> UNDEFINED + '\ufffe', // 0xA4 -> UNDEFINED + '\ufffe', // 0xA5 -> UNDEFINED + '\ufffe', // 0xA6 -> UNDEFINED + '\ufffe', // 0xA7 -> UNDEFINED + '\ufffe', // 0xA8 -> UNDEFINED + '\ufffe', // 0xA9 -> UNDEFINED + '\ufffe', // 0xAA -> UNDEFINED + '\ufffe', // 0xAB -> UNDEFINED + '\ufffe', // 0xAC -> UNDEFINED + '\ufffe', // 0xAD -> UNDEFINED + '\ufffe', // 0xAE -> UNDEFINED + '\ufffe', // 0xAF -> UNDEFINED + '\ufffe', // 0xB0 -> UNDEFINED + '\ufffe', // 0xB1 -> UNDEFINED + '\ufffe', // 0xB2 -> UNDEFINED + '\ufffe', // 0xB3 -> UNDEFINED + '\ufffe', // 0xB4 -> UNDEFINED + '\ufffe', // 0xB5 -> UNDEFINED + '\ufffe', // 0xB6 -> UNDEFINED + '\ufffe', // 0xB7 -> UNDEFINED + '\ufffe', // 0xB8 -> UNDEFINED + '\ufffe', // 0xB9 -> UNDEFINED + '\ufffe', // 0xBA -> UNDEFINED + '\ufffe', // 0xBB -> UNDEFINED + '\ufffe', // 0xBC -> UNDEFINED + '\ufffe', // 0xBD -> UNDEFINED + '\ufffe', // 0xBE -> UNDEFINED + '\ufffe', // 0xBF -> UNDEFINED + '\ufffe', // 0xC0 -> UNDEFINED + '\ufffe', // 0xC1 -> UNDEFINED + '\ufffe', // 0xC2 -> UNDEFINED + '\ufffe', // 0xC3 -> UNDEFINED + '\ufffe', // 0xC4 -> UNDEFINED + '\ufffe', // 0xC5 -> UNDEFINED + '\ufffe', // 0xC6 -> UNDEFINED + '\ufffe', // 0xC7 -> UNDEFINED + '\ufffe', // 0xC8 -> UNDEFINED + '\ufffe', // 0xC9 -> UNDEFINED + '\ufffe', // 0xCA -> UNDEFINED + '\ufffe', // 0xCB -> UNDEFINED + '\ufffe', // 0xCC -> UNDEFINED + '\ufffe', // 0xCD -> UNDEFINED + '\ufffe', // 0xCE -> UNDEFINED + '\ufffe', // 0xCF -> UNDEFINED + '\ufffe', // 0xD0 -> UNDEFINED + '\ufffe', // 0xD1 -> UNDEFINED + '\ufffe', // 0xD2 -> UNDEFINED + '\ufffe', // 0xD3 -> UNDEFINED + '\ufffe', // 0xD4 -> UNDEFINED + '\ufffe', // 0xD5 -> UNDEFINED + '\ufffe', // 0xD6 -> UNDEFINED + '\ufffe', // 0xD7 -> UNDEFINED + '\ufffe', // 0xD8 -> UNDEFINED + '\ufffe', // 0xD9 -> UNDEFINED + '\ufffe', // 0xDA -> UNDEFINED + '\ufffe', // 0xDB -> UNDEFINED + '\ufffe', // 0xDC -> UNDEFINED + '\ufffe', // 0xDD -> UNDEFINED + '\ufffe', // 0xDE -> UNDEFINED + '\ufffe', // 0xDF -> UNDEFINED + '\ufffe', // 0xE0 -> UNDEFINED + '\ufffe', // 0xE1 -> UNDEFINED + '\ufffe', // 0xE2 -> UNDEFINED + '\ufffe', // 0xE3 -> UNDEFINED + '\ufffe', // 0xE4 -> UNDEFINED + '\ufffe', // 0xE5 -> UNDEFINED + '\ufffe', // 0xE6 -> UNDEFINED + '\ufffe', // 0xE7 -> UNDEFINED + '\ufffe', // 0xE8 -> UNDEFINED + '\ufffe', // 0xE9 -> UNDEFINED + '\ufffe', // 0xEA -> UNDEFINED + '\ufffe', // 0xEB -> UNDEFINED + '\ufffe', // 0xEC -> UNDEFINED + '\ufffe', // 0xED -> UNDEFINED + '\ufffe', // 0xEE -> UNDEFINED + '\ufffe', // 0xEF -> UNDEFINED + '\ufffe', // 0xF0 -> UNDEFINED + '\ufffe', // 0xF1 -> UNDEFINED + '\ufffe', // 0xF2 -> UNDEFINED + '\ufffe', // 0xF3 -> UNDEFINED + '\ufffe', // 0xF4 -> UNDEFINED + '\ufffe', // 0xF5 -> UNDEFINED + '\ufffe', // 0xF6 -> UNDEFINED + '\ufffe', // 0xF7 -> UNDEFINED + '\ufffe', // 0xF8 -> UNDEFINED + '\ufffe', // 0xF9 -> UNDEFINED + '\ufffe', // 0xFA -> UNDEFINED + '\ufffe', // 0xFB -> UNDEFINED + '\ufffe', // 0xFC -> UNDEFINED + '\ufffe', // 0xFD -> UNDEFINED + '\ufffe', // 0xFE -> UNDEFINED + '\ufffe' // 0xFF -> UNDEFINED + ) + + private val decodingScreencodeUppercase = arrayOf( + '@' , // @ 0x00 -> COMMERCIAL AT + 'A' , // A 0x01 -> LATIN CAPITAL LETTER A + 'B' , // B 0x02 -> LATIN CAPITAL LETTER B + 'C' , // C 0x03 -> LATIN CAPITAL LETTER C + 'D' , // D 0x04 -> LATIN CAPITAL LETTER D + 'E' , // E 0x05 -> LATIN CAPITAL LETTER E + 'F' , // F 0x06 -> LATIN CAPITAL LETTER F + 'G' , // G 0x07 -> LATIN CAPITAL LETTER G + 'H' , // H 0x08 -> LATIN CAPITAL LETTER H + 'I' , // I 0x09 -> LATIN CAPITAL LETTER I + 'J' , // J 0x0A -> LATIN CAPITAL LETTER J + 'K' , // K 0x0B -> LATIN CAPITAL LETTER K + 'L' , // L 0x0C -> LATIN CAPITAL LETTER L + 'M' , // M 0x0D -> LATIN CAPITAL LETTER M + 'N' , // N 0x0E -> LATIN CAPITAL LETTER N + 'O' , // O 0x0F -> LATIN CAPITAL LETTER O + 'P' , // P 0x10 -> LATIN CAPITAL LETTER P + 'Q' , // Q 0x11 -> LATIN CAPITAL LETTER Q + 'R' , // R 0x12 -> LATIN CAPITAL LETTER R + 'S' , // S 0x13 -> LATIN CAPITAL LETTER S + 'T' , // T 0x14 -> LATIN CAPITAL LETTER T + 'U' , // U 0x15 -> LATIN CAPITAL LETTER U + 'V' , // V 0x16 -> LATIN CAPITAL LETTER V + 'W' , // W 0x17 -> LATIN CAPITAL LETTER W + 'X' , // X 0x18 -> LATIN CAPITAL LETTER X + 'Y' , // Y 0x19 -> LATIN CAPITAL LETTER Y + 'Z' , // Z 0x1A -> LATIN CAPITAL LETTER Z + '[' , // [ 0x1B -> LEFT SQUARE BRACKET + '\u00a3', // £ 0x1C -> POUND SIGN + ']' , // ] 0x1D -> RIGHT SQUARE BRACKET + '\u2191', // ↑ 0x1E -> UPWARDS ARROW + '\u2190', // ← 0x1F -> LEFTWARDS ARROW + ' ' , // 0x20 -> SPACE + '!' , // ! 0x21 -> EXCLAMATION MARK + '"' , // " 0x22 -> QUOTATION MARK + '#' , // # 0x23 -> NUMBER SIGN + '$' , // $ 0x24 -> DOLLAR SIGN + '%' , // % 0x25 -> PERCENT SIGN + '&' , // & 0x26 -> AMPERSAND + '\'' , // ' 0x27 -> APOSTROPHE + '(' , // ( 0x28 -> LEFT PARENTHESIS + ')' , // ) 0x29 -> RIGHT PARENTHESIS + '*' , // * 0x2A -> ASTERISK + '+' , // + 0x2B -> PLUS SIGN + ',' , // , 0x2C -> COMMA + '-' , // - 0x2D -> HYPHEN-MINUS + '.' , // . 0x2E -> FULL STOP + '/' , // / 0x2F -> SOLIDUS + '0' , // 0 0x30 -> DIGIT ZERO + '1' , // 1 0x31 -> DIGIT ONE + '2' , // 2 0x32 -> DIGIT TWO + '3' , // 3 0x33 -> DIGIT THREE + '4' , // 4 0x34 -> DIGIT FOUR + '5' , // 5 0x35 -> DIGIT FIVE + '6' , // 6 0x36 -> DIGIT SIX + '7' , // 7 0x37 -> DIGIT SEVEN + '8' , // 8 0x38 -> DIGIT EIGHT + '9' , // 9 0x39 -> DIGIT NINE + ':' , // : 0x3A -> COLON + ';' , // ; 0x3B -> SEMICOLON + '<' , // < 0x3C -> LESS-THAN SIGN + '=' , // = 0x3D -> EQUALS SIGN + '>' , // > 0x3E -> GREATER-THAN SIGN + '?' , // ? 0x3F -> QUESTION MARK + '\u2500', // ─ 0x40 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2660', // ♠ 0x41 -> BLACK SPADE SUIT + '\u2502', // │ 0x42 -> BOX DRAWINGS LIGHT VERTICAL + '\u2500', // ─ 0x43 -> BOX DRAWINGS LIGHT HORIZONTAL + '\uf122', //  0x44 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER UP (CUS) + '\uf123', //  0x45 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS UP (CUS) + '\uf124', //  0x46 -> BOX DRAWINGS LIGHT HORIZONTAL ONE QUARTER DOWN (CUS) + '\uf126', //  0x47 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER LEFT (CUS) + '\uf128', //  0x48 -> BOX DRAWINGS LIGHT VERTICAL ONE QUARTER RIGHT (CUS) + '\u256e', // ╮ 0x49 -> BOX DRAWINGS LIGHT ARC DOWN AND LEFT + '\u2570', // ╰ 0x4A -> BOX DRAWINGS LIGHT ARC UP AND RIGHT + '\u256f', // ╯ 0x4B -> BOX DRAWINGS LIGHT ARC UP AND LEFT + '\uf12a', //  0x4C -> ONE EIGHTH BLOCK UP AND RIGHT (CUS) + '\u2572', // ╲ 0x4D -> BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + '\u2571', // ╱ 0x4E -> BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + '\uf12b', //  0x4F -> ONE EIGHTH BLOCK DOWN AND RIGHT (CUS) + '\uf12c', //  0x50 -> ONE EIGHTH BLOCK DOWN AND LEFT (CUS) + '\u25cf', // ● 0x51 -> BLACK CIRCLE + '\uf125', //  0x52 -> BOX DRAWINGS LIGHT HORIZONTAL TWO QUARTERS DOWN (CUS) + '\u2665', // ♥ 0x53 -> BLACK HEART SUIT + '\uf127', //  0x54 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS LEFT (CUS) + '\u256d', // ╭ 0x55 -> BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + '\u2573', // ╳ 0x56 -> BOX DRAWINGS LIGHT DIAGONAL CROSS + '\u25cb', // ○ 0x57 -> WHITE CIRCLE + '\u2663', // ♣ 0x58 -> BLACK CLUB SUIT + '\uf129', //  0x59 -> BOX DRAWINGS LIGHT VERTICAL TWO QUARTERS RIGHT (CUS) + '\u2666', // ♦ 0x5A -> BLACK DIAMOND SUIT + '\u253c', // ┼ 0x5B -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\uf12e', //  0x5C -> LEFT HALF BLOCK MEDIUM SHADE (CUS) + '\u2502', // │ 0x5D -> BOX DRAWINGS LIGHT VERTICAL + '\u03c0', // π 0x5E -> GREEK SMALL LETTER PI + '\u25e5', // ◥ 0x5F -> BLACK UPPER RIGHT TRIANGLE + '\u00a0', // 0x60 -> NO-BREAK SPACE + '\u258c', // ▌ 0x61 -> LEFT HALF BLOCK + '\u2584', // ▄ 0x62 -> LOWER HALF BLOCK + '\u2594', // ▔ 0x63 -> UPPER ONE EIGHTH BLOCK + '\u2581', // ▁ 0x64 -> LOWER ONE EIGHTH BLOCK + '\u258f', // ▏ 0x65 -> LEFT ONE EIGHTH BLOCK + '\u2592', // ▒ 0x66 -> MEDIUM SHADE + '\u2595', // ▕ 0x67 -> RIGHT ONE EIGHTH BLOCK + '\uf12f', //  0x68 -> LOWER HALF BLOCK MEDIUM SHADE (CUS) + '\u25e4', // ◤ 0x69 -> BLACK UPPER LEFT TRIANGLE + '\uf130', //  0x6A -> RIGHT ONE QUARTER BLOCK (CUS) + '\u251c', // ├ 0x6B -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2597', // ▗ 0x6C -> QUADRANT LOWER RIGHT + '\u2514', // └ 0x6D -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2510', // ┐ 0x6E -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2582', // ▂ 0x6F -> LOWER ONE QUARTER BLOCK + '\u250c', // ┌ 0x70 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2534', // ┴ 0x71 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c', // ┬ 0x72 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2524', // ┤ 0x73 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u258e', // ▎ 0x74 -> LEFT ONE QUARTER BLOCK + '\u258d', // ▍ 0x75 -> LEFT THREE EIGTHS BLOCK + '\uf131', //  0x76 -> RIGHT THREE EIGHTHS BLOCK (CUS) + '\uf132', //  0x77 -> UPPER ONE QUARTER BLOCK (CUS) + '\uf133', //  0x78 -> UPPER THREE EIGHTS BLOCK (CUS) + '\u2583', // ▃ 0x79 -> LOWER THREE EIGHTHS BLOCK + '\uf12d', //  0x7A -> ONE EIGHTH BLOCK UP AND LEFT (CUS) + '\u2596', // ▖ 0x7B -> QUADRANT LOWER LEFT + '\u259d', // ▝ 0x7C -> QUADRANT UPPER RIGHT + '\u2518', // ┘ 0x7D -> BOX DRAWINGS LIGHT UP AND LEFT + '\u2598', // ▘ 0x7E -> QUADRANT UPPER LEFT + '\u259a', // ▚ 0x7F -> QUADRANT UPPER LEFT AND LOWER RIGHT + '\ufffe', // 0x80 -> UNDEFINED + '\ufffe', // 0x81 -> UNDEFINED + '\ufffe', // 0x82 -> UNDEFINED + '\ufffe', // 0x83 -> UNDEFINED + '\ufffe', // 0x84 -> UNDEFINED + '\ufffe', // 0x85 -> UNDEFINED + '\ufffe', // 0x86 -> UNDEFINED + '\ufffe', // 0x87 -> UNDEFINED + '\ufffe', // 0x88 -> UNDEFINED + '\ufffe', // 0x89 -> UNDEFINED + '\ufffe', // 0x8A -> UNDEFINED + '\ufffe', // 0x8B -> UNDEFINED + '\ufffe', // 0x8C -> UNDEFINED + '\ufffe', // 0x8D -> UNDEFINED + '\ufffe', // 0x8E -> UNDEFINED + '\ufffe', // 0x8F -> UNDEFINED + '\ufffe', // 0x90 -> UNDEFINED + '\ufffe', // 0x91 -> UNDEFINED + '\ufffe', // 0x92 -> UNDEFINED + '\ufffe', // 0x93 -> UNDEFINED + '\ufffe', // 0x94 -> UNDEFINED + '\ufffe', // 0x95 -> UNDEFINED + '\ufffe', // 0x96 -> UNDEFINED + '\ufffe', // 0x97 -> UNDEFINED + '\ufffe', // 0x98 -> UNDEFINED + '\ufffe', // 0x99 -> UNDEFINED + '\ufffe', // 0x9A -> UNDEFINED + '\ufffe', // 0x9B -> UNDEFINED + '\ufffe', // 0x9C -> UNDEFINED + '\ufffe', // 0x9D -> UNDEFINED + '\ufffe', // 0x9E -> UNDEFINED + '\ufffe', // 0x9F -> UNDEFINED + '\ufffe', // 0xA0 -> UNDEFINED + '\ufffe', // 0xA1 -> UNDEFINED + '\ufffe', // 0xA2 -> UNDEFINED + '\ufffe', // 0xA3 -> UNDEFINED + '\ufffe', // 0xA4 -> UNDEFINED + '\ufffe', // 0xA5 -> UNDEFINED + '\ufffe', // 0xA6 -> UNDEFINED + '\ufffe', // 0xA7 -> UNDEFINED + '\ufffe', // 0xA8 -> UNDEFINED + '\ufffe', // 0xA9 -> UNDEFINED + '\ufffe', // 0xAA -> UNDEFINED + '\ufffe', // 0xAB -> UNDEFINED + '\ufffe', // 0xAC -> UNDEFINED + '\ufffe', // 0xAD -> UNDEFINED + '\ufffe', // 0xAE -> UNDEFINED + '\ufffe', // 0xAF -> UNDEFINED + '\ufffe', // 0xB0 -> UNDEFINED + '\ufffe', // 0xB1 -> UNDEFINED + '\ufffe', // 0xB2 -> UNDEFINED + '\ufffe', // 0xB3 -> UNDEFINED + '\ufffe', // 0xB4 -> UNDEFINED + '\ufffe', // 0xB5 -> UNDEFINED + '\ufffe', // 0xB6 -> UNDEFINED + '\ufffe', // 0xB7 -> UNDEFINED + '\ufffe', // 0xB8 -> UNDEFINED + '\ufffe', // 0xB9 -> UNDEFINED + '\ufffe', // 0xBA -> UNDEFINED + '\ufffe', // 0xBB -> UNDEFINED + '\ufffe', // 0xBC -> UNDEFINED + '\ufffe', // 0xBD -> UNDEFINED + '\ufffe', // 0xBE -> UNDEFINED + '\ufffe', // 0xBF -> UNDEFINED + '\ufffe', // 0xC0 -> UNDEFINED + '\ufffe', // 0xC1 -> UNDEFINED + '\ufffe', // 0xC2 -> UNDEFINED + '\ufffe', // 0xC3 -> UNDEFINED + '\ufffe', // 0xC4 -> UNDEFINED + '\ufffe', // 0xC5 -> UNDEFINED + '\ufffe', // 0xC6 -> UNDEFINED + '\ufffe', // 0xC7 -> UNDEFINED + '\ufffe', // 0xC8 -> UNDEFINED + '\ufffe', // 0xC9 -> UNDEFINED + '\ufffe', // 0xCA -> UNDEFINED + '\ufffe', // 0xCB -> UNDEFINED + '\ufffe', // 0xCC -> UNDEFINED + '\ufffe', // 0xCD -> UNDEFINED + '\ufffe', // 0xCE -> UNDEFINED + '\ufffe', // 0xCF -> UNDEFINED + '\ufffe', // 0xD0 -> UNDEFINED + '\ufffe', // 0xD1 -> UNDEFINED + '\ufffe', // 0xD2 -> UNDEFINED + '\ufffe', // 0xD3 -> UNDEFINED + '\ufffe', // 0xD4 -> UNDEFINED + '\ufffe', // 0xD5 -> UNDEFINED + '\ufffe', // 0xD6 -> UNDEFINED + '\ufffe', // 0xD7 -> UNDEFINED + '\ufffe', // 0xD8 -> UNDEFINED + '\ufffe', // 0xD9 -> UNDEFINED + '\ufffe', // 0xDA -> UNDEFINED + '\ufffe', // 0xDB -> UNDEFINED + '\ufffe', // 0xDC -> UNDEFINED + '\ufffe', // 0xDD -> UNDEFINED + '\ufffe', // 0xDE -> UNDEFINED + '\ufffe', // 0xDF -> UNDEFINED + '\ufffe', // 0xE0 -> UNDEFINED + '\ufffe', // 0xE1 -> UNDEFINED + '\ufffe', // 0xE2 -> UNDEFINED + '\ufffe', // 0xE3 -> UNDEFINED + '\ufffe', // 0xE4 -> UNDEFINED + '\ufffe', // 0xE5 -> UNDEFINED + '\ufffe', // 0xE6 -> UNDEFINED + '\ufffe', // 0xE7 -> UNDEFINED + '\ufffe', // 0xE8 -> UNDEFINED + '\ufffe', // 0xE9 -> UNDEFINED + '\ufffe', // 0xEA -> UNDEFINED + '\ufffe', // 0xEB -> UNDEFINED + '\ufffe', // 0xEC -> UNDEFINED + '\ufffe', // 0xED -> UNDEFINED + '\ufffe', // 0xEE -> UNDEFINED + '\ufffe', // 0xEF -> UNDEFINED + '\ufffe', // 0xF0 -> UNDEFINED + '\ufffe', // 0xF1 -> UNDEFINED + '\ufffe', // 0xF2 -> UNDEFINED + '\ufffe', // 0xF3 -> UNDEFINED + '\ufffe', // 0xF4 -> UNDEFINED + '\ufffe', // 0xF5 -> UNDEFINED + '\ufffe', // 0xF6 -> UNDEFINED + '\ufffe', // 0xF7 -> UNDEFINED + '\ufffe', // 0xF8 -> UNDEFINED + '\ufffe', // 0xF9 -> UNDEFINED + '\ufffe', // 0xFA -> UNDEFINED + '\ufffe', // 0xFB -> UNDEFINED + '\ufffe', // 0xFC -> UNDEFINED + '\ufffe', // 0xFD -> UNDEFINED + '\ufffe', // 0xFE -> UNDEFINED + '\ufffe' // 0xFF -> UNDEFINED + ) + + // encoding: from unicode to Petscii/Screencodes (0-255) + private val encodingPetsciiLowercase = decodingPetsciiLowercase.withIndex().associate{it.value to it.index} + private val encodingPetsciiUppercase = decodingPetsciiUppercase.withIndex().associate{it.value to it.index} + private val encodingScreencodeLowercase = decodingScreencodeLowercase.withIndex().associate{it.value to it.index} + private val encodingScreencodeUppercase = decodingScreencodeUppercase.withIndex().associate{it.value to it.index} + + + fun encodePetscii(text: String, lowercase: Boolean = false): List { + val lookup = if(lowercase) encodingPetsciiLowercase else encodingPetsciiUppercase + return text.map { + val petscii = lookup[it] + petscii?.toShort() ?: if(it=='\u0000') + 0.toShort() + else { + val case = if (lowercase) "lower" else "upper" + throw CharConversionException("no ${case}case Petscii character for '$it'") + } + } + } + + fun decodePetscii(petscii: Iterable, lowercase: Boolean = false): String { + val decodeTable = if(lowercase) decodingPetsciiLowercase else decodingPetsciiUppercase + return petscii.map { decodeTable[it.toInt()] }.joinToString("") + } + + fun encodeScreencode(text: String, lowercase: Boolean = false): List { + val lookup = if(lowercase) encodingScreencodeLowercase else encodingScreencodeUppercase + return text.map{ + val screencode = lookup[it] + screencode?.toShort() ?: if(it=='\u0000') + 0.toShort() + else { + val case = if (lowercase) "lower" else "upper" + throw CharConversionException("no ${case}Screencode character for '$it'") + } + } + } + + fun decodeScreencode(screencode: Iterable, lowercase: Boolean = false): String { + val decodeTable = if(lowercase) decodingScreencodeLowercase else decodingScreencodeUppercase + return screencode.map { decodeTable[it.toInt()] }.joinToString("") + } + + fun petscii2scr(petscii_code: Short, inverseVideo: Boolean): Short { + val code = when { + petscii_code <= 0x1f -> petscii_code + 128 + petscii_code <= 0x3f -> petscii_code.toInt() + petscii_code <= 0x5f -> petscii_code - 64 + petscii_code <= 0x7f -> petscii_code - 32 + petscii_code <= 0x9f -> petscii_code + 64 + petscii_code <= 0xbf -> petscii_code - 64 + petscii_code <= 0xfe -> petscii_code - 128 + petscii_code == 255.toShort() -> 95 + else -> throw CharConversionException("petscii code out of range") + } + if(inverseVideo) + return (code or 0x80).toShort() + return code.toShort() + } + + fun scr2petscii(screencode: Short): Short { + val petscii = when { + screencode <= 0x1f -> screencode + 64 + screencode <= 0x3f -> screencode.toInt() + screencode <= 0x5d -> screencode +123 + screencode == 0x5e.toShort() -> 255 + screencode == 0x5f.toShort() -> 223 + screencode <= 0x7f -> screencode + 64 + screencode <= 0xbf -> screencode - 128 + screencode <= 0xfe -> screencode - 64 + screencode == 255.toShort() -> 191 + else -> throw CharConversionException("screencode out of range") + } + return petscii.toShort() + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/Sim65Main.kt b/src/main/kotlin/net/razorvine/ksim65/Sim65Main.kt new file mode 100644 index 0000000..8962c83 --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/Sim65Main.kt @@ -0,0 +1,81 @@ +package net.razorvine.ksim65 + +import net.razorvine.ksim65.components.* +import net.razorvine.ksim65.components.Cpu6502.Companion.IRQ_vector +import net.razorvine.ksim65.components.Cpu6502.Companion.NMI_vector +import net.razorvine.ksim65.components.Cpu6502.Companion.RESET_vector + + +fun main(args: Array) { + printSoftwareHeader() + startSimulator(args) +} + +internal fun printSoftwareHeader() { + val buildVersion = object {}.javaClass.getResource("/version.txt").readText().trim() + println("\nSim65 6502 cpu simulator v$buildVersion by Irmen de Jong (irmen@razorvine.net)") + println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n") +} + + +private fun startSimulator(args: Array) { + + // create a computer system. + // note that the order in which components are added to the bus, is important: + // it determines the priority of reads and writes. + val cpu = Cpu6502(true) + val ram = Ram(0, 0xffff) + ram[RESET_vector] = 0x00 + ram[RESET_vector + 1] = 0x10 + ram[IRQ_vector] = 0x00 + ram[IRQ_vector + 1] = 0x20 + ram[NMI_vector] = 0x00 + ram[NMI_vector + 1] = 0x30 + +// // read the RTC and write the date+time to $2000 +// for(b in listOf(0xa0, 0x00, 0xb9, 0x00, 0xd1, 0x99, 0x00, 0x20, 0xc8, 0xc0, 0x09, 0xd0, 0xf5, 0x00).withIndex()) { +// ram[0x1000+b.index] = b.value.toShort() +// } + + // set the timer to $22aa00 and enable it on regular irq + for(b in listOf(0xa9, 0x00, 0x8d, 0x00, 0xd2, 0xa9, 0x00, 0x8d, 0x01, 0xd2, 0xa9, 0xaa, 0x8d, 0x02, + 0xd2, 0xa9, 0x22, 0x8d, 0x03, 0xd2, 0xa9, 0x01, 0x8d, 0x00, 0xd2, 0x4c, 0x19, 0x10).withIndex()) { + ram[0x1000+b.index] = b.value.toShort() + } + + + // load the irq routine that prints 'irq!' to the parallel port + for(b in listOf(0x48, 0xa9, 0x09, 0x8d, 0x00, 0xd0, 0xee, 0x01, 0xd0, 0xa9, 0x12, 0x8d, 0x00, 0xd0, + 0xee, 0x01, 0xd0, 0xa9, 0x11, 0x8d, 0x00, 0xd0, 0xee, 0x01, 0xd0, 0xa9, 0x21, 0x8d, 0x00, 0xd0, + 0xee, 0x01, 0xd0, 0x68, 0x40).withIndex()) { + ram[0x2000+b.index] = b.value.toShort() + } + + val parallel = ParallelPort(0xd000, 0xd001) + val clock = RealTimeClock(0xd100, 0xd108) + val timer = Timer(0xd200, 0xd203, cpu) + + val bus = Bus() + bus.add(cpu) + bus.add(parallel) + bus.add(clock) + bus.add(timer) + bus.add(ram) + bus.reset() + + cpu.Status.I = false // enable interrupts + + try { + while (true) { + bus.clock() + } + } catch (ix: Cpu6502.InstructionError) { + println("HMMM $ix") + // ignore + } + + ram.hexDump(0x1000, 0x1020) + val dis = cpu.disassemble(ram, 0x1000, 0x1020) + println(dis.joinToString("\n")) + ram.hexDump(0x2000, 0x2008) +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Bus.kt b/src/main/kotlin/net/razorvine/ksim65/components/Bus.kt new file mode 100644 index 0000000..c6e2cf6 --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Bus.kt @@ -0,0 +1,42 @@ +package net.razorvine.ksim65.components + +class Bus { + + private val components = mutableListOf() + private val memComponents = mutableListOf() + + fun reset() { + components.forEach { it.reset() } + memComponents.forEach { it.reset() } + } + + fun clock() { + components.forEach { it.clock() } + memComponents.forEach { it.clock() } + } + + fun add(component: BusComponent) { + components.add(component) + component.bus = this + } + + fun add(component: MemMappedComponent) { + memComponents.add(component) + component.bus = this + } + + fun read(address: Address): UByte { + memComponents.forEach { + if(address>=it.startAddress && address<=it.endAddress) + return it[address] + } + return 0xff + } + + fun write(address: Address, data: UByte) { + memComponents.forEach { + if(address>=it.startAddress && address<=it.endAddress) + it[address] = data + } + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Component.kt b/src/main/kotlin/net/razorvine/ksim65/components/Component.kt new file mode 100644 index 0000000..11f6335 --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Component.kt @@ -0,0 +1,41 @@ +package net.razorvine.ksim65.components + +import net.razorvine.ksim65.Petscii + +typealias UByte = Short +typealias Address = Int + + +abstract class BusComponent { + lateinit var bus: Bus + + abstract fun clock() + abstract fun reset() +} + +abstract class MemMappedComponent(val startAddress: Address, val endAddress: Address): BusComponent() { + abstract operator fun get(address: Address): UByte + abstract operator fun set(address: Address, data: UByte) + + init { + require(endAddress>=startAddress) + require(startAddress>=0 && endAddress <= 0xffff) { "can only have 16-bit address space" } + } + + fun hexDump(from: Address, to: Address) { + (from .. to).chunked(16).forEach { + print("\$${it.first().toString(16).padStart(4, '0')} ") + val bytes = it.map { address -> get(address) } + bytes.forEach { byte -> + print(byte.toString(16).padStart(2, '0') + " ") + } + print(" ") + print(Petscii.decodeScreencode(bytes, false).replace('\ufffe', '.')) + println() + } + } +} + +abstract class MemoryComponent(startAddress: Address, endAddress: Address): MemMappedComponent(startAddress, endAddress) { + abstract fun cloneContents(): Array +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Cpu6502.kt b/src/main/kotlin/net/razorvine/ksim65/components/Cpu6502.kt new file mode 100644 index 0000000..0779fcd --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Cpu6502.kt @@ -0,0 +1,1223 @@ +package net.razorvine.ksim65.components + +// TODO: implement the illegal opcodes, see http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes +// TODO: add the optional additional cycles to certain instructions and addressing modes + + +open class Cpu6502(private val stopOnBrk: Boolean) : BusComponent() { + var tracing: Boolean = false + var totalCycles: Long = 0 + private set + + class InstructionError(msg: String) : RuntimeException(msg) + + companion object { + const val NMI_vector = 0xfffa + const val RESET_vector = 0xfffc + const val IRQ_vector = 0xfffe + const val resetCycles = 8 + + fun hexW(number: Address, allowSingleByte: Boolean = false): String { + val msb = number ushr 8 + val lsb = number and 0xff + return if (msb == 0 && allowSingleByte) + hexB(lsb) + else + hexB(msb) + hexB( + lsb + ) + } + + private const val hexdigits = "0123456789abcdef" + + fun hexB(number: Short): String = hexB(number.toInt()) + + fun hexB(number: Int): String { + val loNibble = number and 15 + val hiNibble = number ushr 4 + return hexdigits[hiNibble].toString() + hexdigits[loNibble] + } + } + + enum class AddrMode { + Imp, + Acc, + Imm, + Zp, + ZpX, + ZpY, + Rel, + Abs, + AbsX, + AbsY, + Ind, + IzX, + IzY + } + + class Instruction(val opcode: UByte, val mnemonic: String, val mode: AddrMode, val cycles: Int, val execute: () -> Unit) { + override fun toString(): String { + return "[${hexB(opcode)}: $mnemonic $mode]" + } + } + + class StatusRegister( + var C: Boolean = false, + var Z: Boolean = false, + var I: Boolean = false, + var D: Boolean = false, + var B: Boolean = false, + var V: Boolean = false, + var N: Boolean = false + ) { + fun asByte(): UByte { + return (0b00100000 or + (if (N) 0b10000000 else 0) or + (if (V) 0b01000000 else 0) or + (if (B) 0b00010000 else 0) or + (if (D) 0b00001000 else 0) or + (if (I) 0b00000100 else 0) or + (if (Z) 0b00000010 else 0) or + (if (C) 0b00000001 else 0) + ).toShort() + } + + fun fromByte(byte: Int) { + N = (byte and 0b10000000) != 0 + V = (byte and 0b01000000) != 0 + B = (byte and 0b00010000) != 0 + D = (byte and 0b00001000) != 0 + I = (byte and 0b00000100) != 0 + Z = (byte and 0b00000010) != 0 + C = (byte and 0b00000001) != 0 + } + + override fun toString(): String { + return asByte().toString(2).padStart(8, '0') + } + + override fun hashCode(): Int = asByte().toInt() + + override fun equals(other: Any?): Boolean { + if (other !is StatusRegister) + return false + return asByte() == other.asByte() + } + } + + + var instrCycles: Int = 0 + var A: Int = 0 + var X: Int = 0 + var Y: Int = 0 + var SP: Int = 0 + var PC: Address = 0 + val Status = StatusRegister() + var currentOpcode: Int = 0 + private lateinit var currentInstruction: Instruction + + // has an interrupt been requested? + private var pendingInterrupt: Pair? = null + + // data byte from the instruction (only set when addr.mode is Accumulator, Immediate or Implied) + private var fetchedData: Int = 0 + + // all other addressing modes yield a fetched memory address + private var fetchedAddress: Address = 0 + + private val addressingModes = mapOf Unit>( + AddrMode.Imp to ::amImp, + AddrMode.Acc to ::amAcc, + AddrMode.Imm to ::amImm, + AddrMode.Zp to ::amZp, + AddrMode.ZpX to ::amZpx, + AddrMode.ZpY to ::amZpy, + AddrMode.Rel to ::amRel, + AddrMode.Abs to ::amAbs, + AddrMode.AbsX to ::amAbsx, + AddrMode.AbsY to ::amAbsy, + AddrMode.Ind to ::amInd, + AddrMode.IzX to ::amIzx, + AddrMode.IzY to ::amIzy + ) + + private val breakpoints = mutableMapOf Unit>() + + fun breakpoint(address: Address, action: (cpu: Cpu6502, pc: Address) -> Unit) { + breakpoints[address] = action + } + + fun disassemble(component: MemoryComponent, from: Address, to: Address) = + disassemble(component.cloneContents(), component.startAddress, from, to) + + fun disassemble(memory: Array, baseAddress: Address, from: Address, to: Address): List { + var address = from - baseAddress + val spacing1 = " " + val spacing2 = " " + val spacing3 = " " + val result = mutableListOf() + + while (address <= (to - baseAddress)) { + val byte = memory[address] + var line = "\$${hexW(address)} ${hexB( + byte + )} " + address++ + val opcode = opcodes[byte.toInt()] + when (opcode.mode) { + AddrMode.Acc -> { + line += "$spacing1 ${opcode.mnemonic} a" + } + AddrMode.Imp -> { + line += "$spacing1 ${opcode.mnemonic}" + } + AddrMode.Imm -> { + val value = memory[address++] + line += "${hexB(value)} $spacing2 ${opcode.mnemonic} #\$${hexB( + value + )}" + } + AddrMode.Zp -> { + val zpAddr = memory[address++] + line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB( + zpAddr + )}" + } + AddrMode.ZpX -> { + val zpAddr = memory[address++] + line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB( + zpAddr + )},x" + } + AddrMode.ZpY -> { + val zpAddr = memory[address++] + line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} \$${hexB( + zpAddr + )},y" + } + AddrMode.Rel -> { + val rel = memory[address++] + val target = + if (rel <= 0x7f) + address + rel + else + address - (256 - rel) + line += "${hexB(rel)} $spacing2 ${opcode.mnemonic} \$${hexW( + target, + true + )}" + } + AddrMode.Abs -> { + val lo = memory[address++] + val hi = memory[address++] + val absAddr = lo.toInt() or (hi.toInt() shl 8) + line += "${hexB(lo)} ${hexB( + hi + )} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)}" + } + AddrMode.AbsX -> { + val lo = memory[address++] + val hi = memory[address++] + val absAddr = lo.toInt() or (hi.toInt() shl 8) + line += "${hexB(lo)} ${hexB( + hi + )} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},x" + } + AddrMode.AbsY -> { + val lo = memory[address++] + val hi = memory[address++] + val absAddr = lo.toInt() or (hi.toInt() shl 8) + line += "${hexB(lo)} ${hexB( + hi + )} $spacing3 ${opcode.mnemonic} \$${hexW(absAddr)},y" + } + AddrMode.Ind -> { + val lo = memory[address++] + val hi = memory[address++] + val indirectAddr = lo.toInt() or (hi.toInt() shl 8) + line += "${hexB(lo)} ${hexB( + hi + )} $spacing3 ${opcode.mnemonic} (\$${hexW( + indirectAddr + )})" + } + AddrMode.IzX -> { + val zpAddr = memory[address++] + line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB( + zpAddr + )},x)" + } + AddrMode.IzY -> { + val zpAddr = memory[address++] + line += "${hexB(zpAddr)} $spacing2 ${opcode.mnemonic} (\$${hexB( + zpAddr + )}),y" + } + } + result.add(line) + } + + return result + } + + override fun reset() { + SP = 0xfd + PC = readWord(RESET_vector) + A = 0 + X = 0 + Y = 0 + Status.C = false + Status.Z = false + Status.I = true + Status.D = false + Status.B = false + Status.V = false + Status.N = false + instrCycles = resetCycles // a reset takes time as well + currentOpcode = 0 + currentInstruction = opcodes[0] + } + + override fun clock() { + if (instrCycles == 0) { + if (pendingInterrupt != null) { + // NMI or IRQ interrupt. + // handled by the BRK instruction logic. + currentOpcode = 0 + currentInstruction = opcodes[0] + } else { + // no interrupt, continue with next instruction + currentOpcode = read(PC) + currentInstruction = opcodes[currentOpcode] + + if (tracing) printState() + + breakpoints[PC]?.let { + val oldPC = PC + val oldOpcode = currentOpcode + it(this, PC) + if (PC != oldPC) + return clock() + if (oldOpcode != currentOpcode) + currentInstruction = opcodes[currentOpcode] + } + + if (currentOpcode == 0 && stopOnBrk) { + throw InstructionError( + "stopped on BRK instruction at ${hexW( + PC + )}" + ) + } + } + + PC++ + instrCycles = currentInstruction.cycles + addressingModes.getValue(currentInstruction.mode)() + currentInstruction.execute() + } + + instrCycles-- + totalCycles++ + } + + fun step() { + // step a whole instruction + while (instrCycles > 0) clock() // remaining instruction subcycles from the previous instruction + clock() // the actual instruction execution cycle + while (instrCycles > 0) clock() // instruction subcycles + } + + fun nmi(source: BusComponent) { + pendingInterrupt = Pair(true, source) + } + + fun irq(source: BusComponent) { + if (!Status.I) + pendingInterrupt = Pair(false, source) + } + + fun printState() { + println("cycle:$totalCycles - pc=${hexW(PC)} " + + "A=${hexB(A)} " + + "X=${hexB(X)} " + + "Y=${hexB(Y)} " + + "SP=${hexB(SP)} " + + " n=" + (if (Status.N) "1" else "0") + + " v=" + (if (Status.V) "1" else "0") + + " b=" + (if (Status.B) "1" else "0") + + " d=" + (if (Status.D) "1" else "0") + + " i=" + (if (Status.I) "1" else "0") + + " z=" + (if (Status.Z) "1" else "0") + + " c=" + (if (Status.C) "1" else "0") + + " icycles=$instrCycles instr=${hexB(currentOpcode)}:${currentInstruction.mnemonic}" + ) + } + + private fun amImp() { + fetchedData = A + } + + private fun amAcc() { + fetchedData = A + } + + private fun amImm() { + fetchedData = readPc() + } + + private fun amZp() { + fetchedAddress = readPc() + } + + private fun amZpx() { + // note: zeropage index will not leave Zp when page boundary is crossed + fetchedAddress = (readPc() + X) and 0xff + } + + private fun amZpy() { + // note: zeropage index will not leave Zp when page boundary is crossed + fetchedAddress = (readPc() + Y) and 0xff + } + + private fun amRel() { + val relative = readPc() + fetchedAddress = if (relative >= 0x80) { + PC - (256 - relative) and 0xffff + } else + PC + relative and 0xffff + } + + private fun amAbs() { + val lo = readPc() + val hi = readPc() + fetchedAddress = lo or (hi shl 8) + } + + private fun amAbsx() { + val lo = readPc() + val hi = readPc() + fetchedAddress = X + (lo or (hi shl 8)) and 0xffff + } + + private fun amAbsy() { + val lo = readPc() + val hi = readPc() + fetchedAddress = Y + (lo or (hi shl 8)) and 0xffff + } + + private fun amInd() { + // not able to fetch an adress which crosses the page boundary (6502, fixed in 65C02) + var lo = readPc() + var hi = readPc() + fetchedAddress = lo or (hi shl 8) + if (lo == 0xff) { + // emulate bug + lo = read(fetchedAddress) + hi = read(fetchedAddress and 0xff00) + } else { + // normal behavior + lo = read(fetchedAddress) + hi = read(fetchedAddress + 1) + } + fetchedAddress = lo or (hi shl 8) + } + + private fun amIzx() { + // note: not able to fetch an adress which crosses the page boundary + fetchedAddress = readPc() + val lo = read((fetchedAddress + X) and 0xff) + val hi = read((fetchedAddress + X + 1) and 0xff) + fetchedAddress = lo or (hi shl 8) + } + + private fun amIzy() { + // note: not able to fetch an adress which crosses the page boundary + fetchedAddress = readPc() + val lo = read(fetchedAddress) + val hi = read((fetchedAddress + 1) and 0xff) + fetchedAddress = Y + (lo or (hi shl 8)) and 0xffff + } + + private fun getFetched() = + if (currentInstruction.mode == AddrMode.Imm || + currentInstruction.mode == AddrMode.Acc || + currentInstruction.mode == AddrMode.Imp + ) + fetchedData + else + read(fetchedAddress) + + private fun readPc(): Int = bus.read(PC++).toInt() + + private fun pushStackAddr(address: Address) { + val lo = address and 0xff + val hi = (address ushr 8) + pushStack(hi) + pushStack(lo) + } + + private fun pushStack(status: StatusRegister) { + pushStack(status.asByte().toInt()) + } + + private fun pushStack(data: Int) { + write(SP or 0x0100, data) + SP = (SP - 1) and 0xff + } + + private fun popStack(): Int { + SP = (SP + 1) and 0xff + return read(SP or 0x0100) + } + + private fun popStackAddr(): Address { + val lo = popStack() + val hi = popStack() + return lo or (hi shl 8) + } + + private fun read(address: Address): Int = bus.read(address).toInt() + private fun readWord(address: Address): Int = bus.read(address).toInt() or (bus.read(address + 1).toInt() shl 8) + private fun write(address: Address, data: Int) = bus.write(address, data.toShort()) + + // opcodes table from http://www.oxyron.de/html/opcodes02.html + private val opcodes = listOf( + Instruction(0x00, "brk", AddrMode.Imp, 7, ::iBrk), + Instruction(0x01, "ora", AddrMode.IzX, 6, ::iOra), + Instruction(0x02, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x03, "slo", AddrMode.IzX, 8, ::iSlo), + Instruction(0x04, "nop", AddrMode.Zp, 3, ::iNop), + Instruction(0x05, "ora", AddrMode.Zp, 3, ::iOra), + Instruction(0x06, "asl", AddrMode.Zp, 5, ::iAsl), + Instruction(0x07, "slo", AddrMode.Zp, 5, ::iSlo), + Instruction(0x08, "php", AddrMode.Imp, 3, ::iPhp), + Instruction(0x09, "ora", AddrMode.Imm, 2, ::iOra), + Instruction(0x0a, "asl", AddrMode.Acc, 2, ::iAsl), + Instruction(0x0b, "anc", AddrMode.Imm, 2, ::iAnc), + Instruction(0x0c, "nop", AddrMode.Abs, 4, ::iNop), + Instruction(0x0d, "ora", AddrMode.Abs, 4, ::iOra), + Instruction(0x0e, "asl", AddrMode.Abs, 6, ::iAsl), + Instruction(0x0f, "slo", AddrMode.Abs, 6, ::iSlo), + Instruction(0x10, "bpl", AddrMode.Rel, 2, ::iBpl), + Instruction(0x11, "ora", AddrMode.IzY, 5, ::iOra), + Instruction(0x12, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x13, "slo", AddrMode.IzY, 6, ::iSlo), + Instruction(0x14, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0x15, "ora", AddrMode.ZpX, 4, ::iOra), + Instruction(0x16, "asl", AddrMode.ZpX, 6, ::iAsl), + Instruction(0x17, "slo", AddrMode.ZpX, 6, ::iSlo), + Instruction(0x18, "clc", AddrMode.Imp, 2, ::iClc), + Instruction(0x19, "ora", AddrMode.AbsY, 4, ::iOra), + Instruction(0x1a, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0x1b, "slo", AddrMode.AbsY, 7, ::iSlo), + Instruction(0x1c, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0x1d, "ora", AddrMode.AbsX, 4, ::iOra), + Instruction(0x1e, "asl", AddrMode.AbsX, 7, ::iAsl), + Instruction(0x1f, "slo", AddrMode.AbsX, 7, ::iSlo), + Instruction(0x20, "jsr", AddrMode.Abs, 6, ::iJsr), + Instruction(0x21, "and", AddrMode.IzX, 6, ::iAnd), + Instruction(0x22, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x23, "rla", AddrMode.IzX, 8, ::iRla), + Instruction(0x24, "bit", AddrMode.Zp, 3, ::iBit), + Instruction(0x25, "and", AddrMode.Zp, 3, ::iAnd), + Instruction(0x26, "rol", AddrMode.Zp, 5, ::iRol), + Instruction(0x27, "rla", AddrMode.Zp, 5, ::iRla), + Instruction(0x28, "plp", AddrMode.Imp, 4, ::iPlp), + Instruction(0x29, "and", AddrMode.Imm, 2, ::iAnd), + Instruction(0x2a, "rol", AddrMode.Acc, 2, ::iRol), + Instruction(0x2b, "anc", AddrMode.Imm, 2, ::iAnc), + Instruction(0x2c, "bit", AddrMode.Abs, 4, ::iBit), + Instruction(0x2d, "and", AddrMode.Abs, 4, ::iAnd), + Instruction(0x2e, "rol", AddrMode.Abs, 6, ::iRol), + Instruction(0x2f, "rla", AddrMode.Abs, 6, ::iRla), + Instruction(0x30, "bmi", AddrMode.Rel, 2, ::iBmi), + Instruction(0x31, "and", AddrMode.IzY, 5, ::iAnd), + Instruction(0x32, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x33, "rla", AddrMode.IzY, 8, ::iRla), + Instruction(0x34, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0x35, "and", AddrMode.ZpX, 4, ::iAnd), + Instruction(0x36, "rol", AddrMode.ZpX, 6, ::iRol), + Instruction(0x37, "rla", AddrMode.ZpX, 6, ::iRla), + Instruction(0x38, "sec", AddrMode.Imp, 2, ::iSec), + Instruction(0x39, "and", AddrMode.AbsY, 4, ::iAnd), + Instruction(0x3a, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0x3b, "rla", AddrMode.AbsY, 7, ::iRla), + Instruction(0x3c, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0x3d, "and", AddrMode.AbsX, 4, ::iAnd), + Instruction(0x3e, "rol", AddrMode.AbsX, 7, ::iRol), + Instruction(0x3f, "rla", AddrMode.AbsX, 7, ::iRla), + Instruction(0x40, "rti", AddrMode.Imp, 6, ::iRti), + Instruction(0x41, "eor", AddrMode.IzX, 6, ::iEor), + Instruction(0x42, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x43, "sre", AddrMode.IzX, 8, ::iSre), + Instruction(0x44, "nop", AddrMode.Zp, 3, ::iNop), + Instruction(0x45, "eor", AddrMode.Zp, 3, ::iEor), + Instruction(0x46, "lsr", AddrMode.Zp, 5, ::iLsr), + Instruction(0x47, "sre", AddrMode.Zp, 5, ::iSre), + Instruction(0x48, "pha", AddrMode.Imp, 3, ::iPha), + Instruction(0x49, "eor", AddrMode.Imm, 2, ::iEor), + Instruction(0x4a, "lsr", AddrMode.Acc, 2, ::iLsr), + Instruction(0x4b, "alr", AddrMode.Imm, 2, ::iAlr), + Instruction(0x4c, "jmp", AddrMode.Abs, 3, ::iJmp), + Instruction(0x4d, "eor", AddrMode.Abs, 4, ::iEor), + Instruction(0x4e, "lsr", AddrMode.Abs, 6, ::iLsr), + Instruction(0x4f, "sre", AddrMode.Abs, 6, ::iSre), + Instruction(0x50, "bvc", AddrMode.Rel, 2, ::iBvc), + Instruction(0x51, "eor", AddrMode.IzY, 5, ::iEor), + Instruction(0x52, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x53, "sre", AddrMode.IzY, 8, ::iSre), + Instruction(0x54, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0x55, "eor", AddrMode.ZpX, 4, ::iEor), + Instruction(0x56, "lsr", AddrMode.ZpX, 6, ::iLsr), + Instruction(0x57, "sre", AddrMode.ZpX, 6, ::iSre), + Instruction(0x58, "cli", AddrMode.Imp, 2, ::iCli), + Instruction(0x59, "eor", AddrMode.AbsY, 4, ::iEor), + Instruction(0x5a, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0x5b, "sre", AddrMode.AbsY, 7, ::iSre), + Instruction(0x5c, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0x5d, "eor", AddrMode.AbsX, 4, ::iEor), + Instruction(0x5e, "lsr", AddrMode.AbsX, 7, ::iLsr), + Instruction(0x5f, "sre", AddrMode.AbsX, 7, ::iSre), + Instruction(0x60, "rts", AddrMode.Imp, 6, ::iRts), + Instruction(0x61, "adc", AddrMode.IzX, 6, ::iAdc), + Instruction(0x62, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x63, "rra", AddrMode.IzX, 8, ::iRra), + Instruction(0x64, "nop", AddrMode.Zp, 3, ::iNop), + Instruction(0x65, "adc", AddrMode.Zp, 3, ::iAdc), + Instruction(0x66, "ror", AddrMode.Zp, 5, ::iRor), + Instruction(0x67, "rra", AddrMode.Zp, 5, ::iRra), + Instruction(0x68, "pla", AddrMode.Imp, 4, ::iPla), + Instruction(0x69, "adc", AddrMode.Imm, 2, ::iAdc), + Instruction(0x6a, "ror", AddrMode.Acc, 2, ::iRor), + Instruction(0x6b, "arr", AddrMode.Imm, 2, ::iArr), + Instruction(0x6c, "jmp", AddrMode.Ind, 5, ::iJmp), + Instruction(0x6d, "adc", AddrMode.Abs, 4, ::iAdc), + Instruction(0x6e, "ror", AddrMode.Abs, 6, ::iRor), + Instruction(0x6f, "rra", AddrMode.Abs, 6, ::iRra), + Instruction(0x70, "bvs", AddrMode.Rel, 2, ::iBvs), + Instruction(0x71, "adc", AddrMode.IzY, 5, ::iAdc), + Instruction(0x72, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x73, "rra", AddrMode.IzY, 8, ::iRra), + Instruction(0x74, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0x75, "adc", AddrMode.ZpX, 4, ::iAdc), + Instruction(0x76, "ror", AddrMode.ZpX, 6, ::iRor), + Instruction(0x77, "rra", AddrMode.ZpX, 6, ::iRra), + Instruction(0x78, "sei", AddrMode.Imp, 2, ::iSei), + Instruction(0x79, "adc", AddrMode.AbsY, 4, ::iAdc), + Instruction(0x7a, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0x7b, "rra", AddrMode.AbsY, 7, ::iRra), + Instruction(0x7c, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0x7d, "adc", AddrMode.AbsX, 4, ::iAdc), + Instruction(0x7e, "ror", AddrMode.AbsX, 7, ::iRor), + Instruction(0x7f, "rra", AddrMode.AbsX, 7, ::iRra), + Instruction(0x80, "nop", AddrMode.Imm, 2, ::iNop), + Instruction(0x81, "sta", AddrMode.IzX, 6, ::iSta), + Instruction(0x82, "nop", AddrMode.Imm, 2, ::iNop), + Instruction(0x83, "sax", AddrMode.IzX, 6, ::iSax), + Instruction(0x84, "sty", AddrMode.Zp, 3, ::iSty), + Instruction(0x85, "sta", AddrMode.Zp, 3, ::iSta), + Instruction(0x86, "stx", AddrMode.Zp, 3, ::iStx), + Instruction(0x87, "sax", AddrMode.Zp, 3, ::iSax), + Instruction(0x88, "dey", AddrMode.Imp, 2, ::iDey), + Instruction(0x89, "nop", AddrMode.Imm, 2, ::iNop), + Instruction(0x8a, "txa", AddrMode.Imp, 2, ::iTxa), + Instruction(0x8b, "xaa", AddrMode.Imm, 2, ::iXaa), + Instruction(0x8c, "sty", AddrMode.Abs, 4, ::iSty), + Instruction(0x8d, "sta", AddrMode.Abs, 4, ::iSta), + Instruction(0x8e, "stx", AddrMode.Abs, 4, ::iStx), + Instruction(0x8f, "sax", AddrMode.Abs, 4, ::iSax), + Instruction(0x90, "bcc", AddrMode.Rel, 2, ::iBcc), + Instruction(0x91, "sta", AddrMode.IzY, 6, ::iSta), + Instruction(0x92, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0x93, "ahx", AddrMode.IzY, 6, ::iAhx), + Instruction(0x94, "sty", AddrMode.ZpX, 4, ::iSty), + Instruction(0x95, "sta", AddrMode.ZpX, 4, ::iSta), + Instruction(0x96, "stx", AddrMode.ZpY, 4, ::iStx), + Instruction(0x97, "sax", AddrMode.ZpY, 4, ::iSax), + Instruction(0x98, "tya", AddrMode.Imp, 2, ::iTya), + Instruction(0x99, "sta", AddrMode.AbsY, 5, ::iSta), + Instruction(0x9a, "txs", AddrMode.Imp, 2, ::iTxs), + Instruction(0x9b, "tas", AddrMode.AbsY, 5, ::iTas), + Instruction(0x9c, "shy", AddrMode.AbsX, 5, ::iShy), + Instruction(0x9d, "sta", AddrMode.AbsX, 5, ::iSta), + Instruction(0x9e, "shx", AddrMode.AbsY, 5, ::iShx), + Instruction(0x9f, "ahx", AddrMode.AbsY, 5, ::iAhx), + Instruction(0xa0, "ldy", AddrMode.Imm, 2, ::iLdy), + Instruction(0xa1, "lda", AddrMode.IzX, 6, ::iLda), + Instruction(0xa2, "ldx", AddrMode.Imm, 2, ::iLdx), + Instruction(0xa3, "lax", AddrMode.IzX, 6, ::iLax), + Instruction(0xa4, "ldy", AddrMode.Zp, 3, ::iLdy), + Instruction(0xa5, "lda", AddrMode.Zp, 3, ::iLda), + Instruction(0xa6, "ldx", AddrMode.Zp, 3, ::iLdx), + Instruction(0xa7, "lax", AddrMode.Zp, 3, ::iLax), + Instruction(0xa8, "tay", AddrMode.Imp, 2, ::iTay), + Instruction(0xa9, "lda", AddrMode.Imm, 2, ::iLda), + Instruction(0xaa, "tax", AddrMode.Imp, 2, ::iTax), + Instruction(0xab, "lax", AddrMode.Imm, 2, ::iLax), + Instruction(0xac, "ldy", AddrMode.Abs, 4, ::iLdy), + Instruction(0xad, "lda", AddrMode.Abs, 4, ::iLda), + Instruction(0xae, "ldx", AddrMode.Abs, 4, ::iLdx), + Instruction(0xaf, "lax", AddrMode.Abs, 4, ::iLax), + Instruction(0xb0, "bcs", AddrMode.Rel, 2, ::iBcs), + Instruction(0xb1, "lda", AddrMode.IzY, 5, ::iLda), + Instruction(0xb2, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0xb3, "lax", AddrMode.IzY, 5, ::iLax), + Instruction(0xb4, "ldy", AddrMode.ZpX, 4, ::iLdy), + Instruction(0xb5, "lda", AddrMode.ZpX, 4, ::iLda), + Instruction(0xb6, "ldx", AddrMode.ZpY, 4, ::iLdx), + Instruction(0xb7, "lax", AddrMode.ZpY, 4, ::iLax), + Instruction(0xb8, "clv", AddrMode.Imp, 2, ::iClv), + Instruction(0xb9, "lda", AddrMode.AbsY, 4, ::iLda), + Instruction(0xba, "tsx", AddrMode.Imp, 2, ::iTsx), + Instruction(0xbb, "las", AddrMode.AbsY, 4, ::iLas), + Instruction(0xbc, "ldy", AddrMode.AbsX, 4, ::iLdy), + Instruction(0xbd, "lda", AddrMode.AbsX, 4, ::iLda), + Instruction(0xbe, "ldx", AddrMode.AbsY, 4, ::iLdx), + Instruction(0xbf, "lax", AddrMode.AbsY, 4, ::iLax), + Instruction(0xc0, "cpy", AddrMode.Imm, 2, ::iCpy), + Instruction(0xc1, "cmp", AddrMode.IzX, 6, ::iCmp), + Instruction(0xc2, "nop", AddrMode.Imm, 2, ::iNop), + Instruction(0xc3, "dcp", AddrMode.IzX, 8, ::iDcp), + Instruction(0xc4, "cpy", AddrMode.Zp, 3, ::iCpy), + Instruction(0xc5, "cmp", AddrMode.Zp, 3, ::iCmp), + Instruction(0xc6, "dec", AddrMode.Zp, 5, ::iDec), + Instruction(0xc7, "dcp", AddrMode.Zp, 5, ::iDcp), + Instruction(0xc8, "iny", AddrMode.Imp, 2, ::iIny), + Instruction(0xc9, "cmp", AddrMode.Imm, 2, ::iCmp), + Instruction(0xca, "dex", AddrMode.Imp, 2, ::iDex), + Instruction(0xcb, "axs", AddrMode.Imm, 2, ::iAxs), + Instruction(0xcc, "cpy", AddrMode.Abs, 4, ::iCpy), + Instruction(0xcd, "cmp", AddrMode.Abs, 4, ::iCmp), + Instruction(0xce, "dec", AddrMode.Abs, 6, ::iDec), + Instruction(0xcf, "dcp", AddrMode.Abs, 6, ::iDcp), + Instruction(0xd0, "bne", AddrMode.Rel, 2, ::iBne), + Instruction(0xd1, "cmp", AddrMode.IzY, 5, ::iCmp), + Instruction(0xd2, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0xd3, "dcp", AddrMode.IzY, 8, ::iDcp), + Instruction(0xd4, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0xd5, "cmp", AddrMode.ZpX, 4, ::iCmp), + Instruction(0xd6, "dec", AddrMode.ZpX, 6, ::iDec), + Instruction(0xd7, "dcp", AddrMode.ZpX, 6, ::iDcp), + Instruction(0xd8, "cld", AddrMode.Imp, 2, ::iCld), + Instruction(0xd9, "cmp", AddrMode.AbsY, 4, ::iCmp), + Instruction(0xda, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0xdb, "dcp", AddrMode.AbsY, 7, ::iDcp), + Instruction(0xdc, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0xdd, "cmp", AddrMode.AbsX, 4, ::iCmp), + Instruction(0xde, "dec", AddrMode.AbsX, 7, ::iDec), + Instruction(0xdf, "dcp", AddrMode.AbsX, 7, ::iDcp), + Instruction(0xe0, "cpx", AddrMode.Imm, 2, ::iCpx), + Instruction(0xe1, "sbc", AddrMode.IzX, 6, ::iSbc), + Instruction(0xe2, "nop", AddrMode.Imm, 2, ::iNop), + Instruction(0xe3, "isc", AddrMode.IzX, 8, ::iIsc), + Instruction(0xe4, "cpx", AddrMode.Zp, 3, ::iCpx), + Instruction(0xe5, "sbc", AddrMode.Zp, 3, ::iSbc), + Instruction(0xe6, "inc", AddrMode.Zp, 5, ::iInc), + Instruction(0xe7, "isc", AddrMode.Zp, 5, ::iIsc), + Instruction(0xe8, "inx", AddrMode.Imp, 2, ::iInx), + Instruction(0xe9, "sbc", AddrMode.Imm, 2, ::iSbc), + Instruction(0xea, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0xeb, "sbc", AddrMode.Imm, 2, ::iSbc), + Instruction(0xec, "cpx", AddrMode.Abs, 4, ::iCpx), + Instruction(0xed, "sbc", AddrMode.Abs, 4, ::iSbc), + Instruction(0xee, "inc", AddrMode.Abs, 6, ::iInc), + Instruction(0xef, "isc", AddrMode.Abs, 6, ::iIsc), + Instruction(0xf0, "beq", AddrMode.Rel, 2, ::iBeq), + Instruction(0xf1, "sbc", AddrMode.IzY, 5, ::iSbc), + Instruction(0xf2, "???", AddrMode.Imp, 0, ::iInvalid), + Instruction(0xf3, "isc", AddrMode.IzY, 8, ::iIsc), + Instruction(0xf4, "nop", AddrMode.ZpX, 4, ::iNop), + Instruction(0xf5, "sbc", AddrMode.ZpX, 4, ::iSbc), + Instruction(0xf6, "inc", AddrMode.ZpX, 6, ::iInc), + Instruction(0xf7, "isc", AddrMode.ZpX, 6, ::iIsc), + Instruction(0xf8, "sed", AddrMode.Imp, 2, ::iSed), + Instruction(0xf9, "sbc", AddrMode.AbsY, 4, ::iSbc), + Instruction(0xfa, "nop", AddrMode.Imp, 2, ::iNop), + Instruction(0xfb, "isc", AddrMode.AbsY, 7, ::iIsc), + Instruction(0xfc, "nop", AddrMode.AbsX, 4, ::iNop), + Instruction(0xfd, "sbc", AddrMode.AbsX, 4, ::iSbc), + Instruction(0xfe, "inc", AddrMode.AbsX, 7, ::iInc), + Instruction(0xff, "isc", AddrMode.AbsX, 7, ::iIsc ) + ).toTypedArray() + + + private fun iInvalid() { + throw InstructionError( + "invalid instruction encountered: opcode=${hexB( + currentOpcode + )} instr=${currentInstruction.mnemonic}" + ) + } + + // official instructions + + private fun iAdc() { + val operand = getFetched() + if (Status.D) { + // BCD add + // see http://www.6502.org/tutorials/decimal_mode.html + // and http://nesdev.com/6502.txt + // and https://sourceforge.net/p/vice-emu/code/HEAD/tree/trunk/vice/src/6510core.c#l598 + // (the implementation below is based on the code used by Vice) + var tmp = (A and 0xf) + (operand and 0xf) + (if (Status.C) 1 else 0) + if (tmp > 9) tmp += 6 + tmp = if (tmp <= 0x0f) { + (tmp and 0xf) + (A and 0xf0) + (operand and 0xf0) + } else { + (tmp and 0xf) + (A and 0xf0) + (operand and 0xf0) + 0x10 + } + Status.Z = A + operand + (if (Status.C) 1 else 0) and 0xff == 0 + Status.N = tmp and 0b10000000 != 0 + Status.V = (A xor tmp) and 0x80 != 0 && (A xor operand) and 0b10000000 == 0 + if (tmp and 0x1f0 > 0x90) tmp += 0x60 + Status.C = tmp > 0xf0 // original: (tmp and 0xff0) > 0xf0 + A = tmp and 0xff + } else { + // normal add + val tmp = operand + A + if (Status.C) 1 else 0 + Status.N = (tmp and 0b10000000) != 0 + Status.Z = (tmp and 0xff) == 0 + Status.V = (A xor operand).inv() and (A xor tmp) and 0b10000000 != 0 + Status.C = tmp > 0xff + A = tmp and 0xff + } + } + + private fun iAnd() { + A = A and getFetched() + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iAsl() { + if (currentInstruction.mode == AddrMode.Acc) { + Status.C = (A and 0b10000000) != 0 + A = (A shl 1) and 0xff + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } else { + val data = read(fetchedAddress) + Status.C = (data and 0b10000000) != 0 + val shifted = (data shl 1) and 0xff + write(fetchedAddress, shifted) + Status.Z = shifted == 0 + Status.N = (shifted and 0b10000000) != 0 + } + } + + private fun iBcc() { + if (!Status.C) PC = fetchedAddress + } + + private fun iBcs() { + if (Status.C) PC = fetchedAddress + } + + private fun iBeq() { + if (Status.Z) PC = fetchedAddress + } + + private fun iBit() { + val operand = getFetched() + Status.Z = (A and operand) == 0 + Status.V = (operand and 0b01000000) != 0 + Status.N = (operand and 0b10000000) != 0 + } + + private fun iBmi() { + if (Status.N) PC = fetchedAddress + } + + private fun iBne() { + if (!Status.Z) PC = fetchedAddress + } + + private fun iBpl() { + if (!Status.N) PC = fetchedAddress + } + + private fun iBrk() { + // handle BRK ('software interrupt') or a real hardware IRQ + val interrupt = pendingInterrupt + val nmi = interrupt?.first == true + if (interrupt != null) { + pushStackAddr(PC - 1) + } else { + PC++ + pushStackAddr(PC) + } + Status.B = interrupt == null + pushStack(Status) + Status.I = true // interrupts are now disabled + // NMOS 6502 doesn't clear the D flag (CMOS version does...) + PC = readWord(if (nmi) NMI_vector else IRQ_vector) + pendingInterrupt = null + } + + private fun iBvc() { + if (!Status.V) PC = fetchedAddress + } + + private fun iBvs() { + if (Status.V) PC = fetchedAddress + } + + private fun iClc() { + Status.C = false + } + + private fun iCld() { + Status.D = false + } + + private fun iCli() { + Status.I = false + } + + private fun iClv() { + Status.V = false + } + + private fun iCmp() { + val fetched = getFetched() + Status.C = A >= fetched + Status.Z = A == fetched + Status.N = ((A - fetched) and 0b10000000) != 0 + } + + private fun iCpx() { + val fetched = getFetched() + Status.C = X >= fetched + Status.Z = X == fetched + Status.N = ((X - fetched) and 0b10000000) != 0 + } + + private fun iCpy() { + val fetched = getFetched() + Status.C = Y >= fetched + Status.Z = Y == fetched + Status.N = ((Y - fetched) and 0b10000000) != 0 + } + + private fun iDec() { + val data = (read(fetchedAddress) - 1) and 0xff + write(fetchedAddress, data) + Status.Z = data == 0 + Status.N = (data and 0b10000000) != 0 + } + + private fun iDex() { + X = (X - 1) and 0xff + Status.Z = X == 0 + Status.N = (X and 0b10000000) != 0 + } + + private fun iDey() { + Y = (Y - 1) and 0xff + Status.Z = Y == 0 + Status.N = (Y and 0b10000000) != 0 + } + + private fun iEor() { + A = A xor getFetched() + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iInc() { + val data = (read(fetchedAddress) + 1) and 0xff + write(fetchedAddress, data) + Status.Z = data == 0 + Status.N = (data and 0b10000000) != 0 + } + + private fun iInx() { + X = (X + 1) and 0xff + Status.Z = X == 0 + Status.N = (X and 0b10000000) != 0 + } + + private fun iIny() { + Y = (Y + 1) and 0xff + Status.Z = Y == 0 + Status.N = (Y and 0b10000000) != 0 + } + + private fun iJmp() { + PC = fetchedAddress + } + + private fun iJsr() { + pushStackAddr(PC - 1) + PC = fetchedAddress + } + + private fun iLda() { + A = getFetched() + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iLdx() { + X = getFetched() + Status.Z = X == 0 + Status.N = (X and 0b10000000) != 0 + } + + private fun iLdy() { + Y = getFetched() + Status.Z = Y == 0 + Status.N = (Y and 0b10000000) != 0 + } + + private fun iLsr() { + if (currentInstruction.mode == AddrMode.Acc) { + Status.C = (A and 1) == 1 + A = A ushr 1 + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } else { + val data = read(fetchedAddress) + Status.C = (data and 1) == 1 + val shifted = data ushr 1 + write(fetchedAddress, shifted) + Status.Z = shifted == 0 + Status.N = (shifted and 0b10000000) != 0 + } + } + + private fun iNop() {} + + private fun iOra() { + A = A or getFetched() + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iPha() { + pushStack(A) + } + + private fun iPhp() { + val origBreakflag = Status.B + Status.B = true + pushStack(Status) + Status.B = origBreakflag + } + + private fun iPla() { + A = popStack() + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iPlp() { + Status.fromByte(popStack()) + Status.B = true // break is always 1 except when pushing on stack + } + + private fun iRol() { + val oldCarry = Status.C + if (currentInstruction.mode == AddrMode.Acc) { + Status.C = (A and 0b10000000) != 0 + A = (A shl 1 and 0xff) or (if (oldCarry) 1 else 0) + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } else { + val data = read(fetchedAddress) + Status.C = (data and 0b10000000) != 0 + val shifted = (data shl 1 and 0xff) or (if (oldCarry) 1 else 0) + write(fetchedAddress, shifted) + Status.Z = shifted == 0 + Status.N = (shifted and 0b10000000) != 0 + } + } + + private fun iRor() { + val oldCarry = Status.C + if (currentInstruction.mode == AddrMode.Acc) { + Status.C = (A and 1) == 1 + A = (A ushr 1) or (if (oldCarry) 0b10000000 else 0) + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } else { + val data = read(fetchedAddress) + Status.C = (data and 1) == 1 + val shifted = (data ushr 1) or (if (oldCarry) 0b10000000 else 0) + write(fetchedAddress, shifted) + Status.Z = shifted == 0 + Status.N = (shifted and 0b10000000) != 0 + } + } + + private fun iRti() { + Status.fromByte(popStack()) + Status.B = true // break is always 1 except when pushing on stack + PC = popStackAddr() + } + + private fun iRts() { + PC = popStackAddr() + PC = (PC + 1) and 0xffff + } + + private fun iSbc() { + val operand = getFetched() + val tmp = (A - operand - if (Status.C) 0 else 1) and 0xffff + Status.V = (A xor operand) and (A xor tmp) and 0b10000000 != 0 + if (Status.D) { + // BCD subtract + // see http://www.6502.org/tutorials/decimal_mode.html + // and http://nesdev.com/6502.txt + // and https://sourceforge.net/p/vice-emu/code/HEAD/tree/trunk/vice/src/6510core.c#l1396 + // (the implementation below is based on the code used by Vice) + var tmpA = ((A and 0xf) - (operand and 0xf) - if (Status.C) 0 else 1) and 0xffff + tmpA = if ((tmpA and 0x10) != 0) { + ((tmpA - 6) and 0xf) or (A and 0xf0) - (operand and 0xf0) - 0x10 + } else { + (tmpA and 0xf) or (A and 0xf0) - (operand and 0xf0) + } + if ((tmpA and 0x100) != 0) tmpA -= 0x60 + A = tmpA and 0xff + } else { + // normal subtract + A = tmp and 0xff + } + Status.C = tmp < 0x100 + Status.Z = (tmp and 0xff) == 0 + Status.N = (tmp and 0b10000000) != 0 + } + + private fun iSec() { + Status.C = true + } + + private fun iSed() { + Status.D = true + } + + private fun iSei() { + Status.I = true + } + + private fun iSta() { + write(fetchedAddress, A) + } + + private fun iStx() { + write(fetchedAddress, X) + } + + private fun iSty() { + write(fetchedAddress, Y) + } + + private fun iTax() { + X = A + Status.Z = X == 0 + Status.N = (X and 0b10000000) != 0 + } + + private fun iTay() { + Y = A + Status.Z = Y == 0 + Status.N = (Y and 0b10000000) != 0 + } + + private fun iTsx() { + X = SP + Status.Z = X == 0 + Status.N = (X and 0b10000000) != 0 + } + + private fun iTxa() { + A = X + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + private fun iTxs() { + SP = X + } + + private fun iTya() { + A = Y + Status.Z = A == 0 + Status.N = (A and 0b10000000) != 0 + } + + // unofficial/illegal instructions + + private fun iAhx() { + TODO("ahx - ('illegal' instruction)") + } + + private fun iAlr() { + TODO("alr=asr - ('illegal' instruction)") + } + + private fun iAnc() { + TODO("anc - ('illegal' instruction)") + } + + private fun iArr() { + TODO("arr - ('illegal' instruction)") + } + + private fun iAxs() { + TODO("axs - ('illegal' instruction)") + } + + private fun iDcp() { + TODO("dcp - ('illegal' instruction)") + } + + private fun iIsc() { + TODO("isc=isb - ('illegal' instruction)") + } + + private fun iLas() { + TODO("las=lar - ('illegal' instruction)") + } + + private fun iLax() { + TODO("lax - ('illegal' instruction)") + } + + private fun iRla() { + TODO("rla - ('illegal' instruction)") + } + + private fun iRra() { + TODO("rra - ('illegal' instruction)") + } + + private fun iSax() { + TODO("sax - ('illegal' instruction)") + } + + private fun iShx() { + TODO("shx - ('illegal' instruction)") + } + + private fun iShy() { + TODO("shy - ('illegal' instruction)") + } + + private fun iSlo() { + TODO("slo=aso - ('illegal' instruction)") + } + + private fun iSre() { + TODO("sre=lse - ('illegal' instruction)") + } + + private fun iTas() { + TODO("tas - ('illegal' instruction)") + } + + private fun iXaa() { + TODO("xaa - ('illegal' instruction)") + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Cpu65C02.kt b/src/main/kotlin/net/razorvine/ksim65/components/Cpu65C02.kt new file mode 100644 index 0000000..e625d2d --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Cpu65C02.kt @@ -0,0 +1,10 @@ +package net.razorvine.ksim65.components + +class Cpu65C02(stopOnBrk: Boolean): Cpu6502(stopOnBrk) { + + + val waiting: Boolean = false + + // TODO implement this CPU type 65C02, and re-enable the unit tests for that + +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/ParallelPort.kt b/src/main/kotlin/net/razorvine/ksim65/components/ParallelPort.kt new file mode 100644 index 0000000..0807f93 --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/ParallelPort.kt @@ -0,0 +1,37 @@ +package net.razorvine.ksim65.components + +import net.razorvine.ksim65.Petscii + +/** + * A parallel output device (basically, prints bytes as characters to the screen) + * First address = data byte (8 parallel bits) + * Second address = control byte (bit 0 high = write byte) + */ +class ParallelPort(startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) { + var dataByte: UByte = 0 + + init { + require(endAddress - startAddress + 1 == 2) { "parallel needs exactly 2 memory bytes (data + control)" } + } + + override fun clock() {} + override fun reset() {} + + override operator fun get(address: Address): UByte { + return if (address == startAddress) + dataByte + else + 0 + } + + override operator fun set(address: Address, data: UByte) { + if (address == startAddress) + dataByte = data + else if (address == endAddress) { + if ((data.toInt() and 1) == 1) { + val char = Petscii.decodeScreencode(listOf(dataByte), false).first() + println("PARALLEL WRITE: '$char'") + } + } + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Ram.kt b/src/main/kotlin/net/razorvine/ksim65/components/Ram.kt new file mode 100644 index 0000000..f714cdf --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Ram.kt @@ -0,0 +1,55 @@ +package net.razorvine.ksim65.components + +import java.io.File + +class Ram(startAddress: Address, endAddress: Address): MemoryComponent(startAddress, endAddress) { + private val memory = ShortArray(endAddress-startAddress+1) + + override operator fun get(address: Address): UByte = memory[address-startAddress] + + override operator fun set(address: Address, data: UByte) { + memory[address-startAddress] = data + } + + override fun cloneContents(): Array = memory.toTypedArray() + + override fun clock() { } + + override fun reset() { + // contents of RAM doesn't change on a reset + } + + fun fill(data: UByte) { + memory.fill(data) + } + + /** + * load a c64-style prg program at the given address, + * this file has the load address as the first two bytes. + */ + fun loadPrg(filename: String) { + val bytes = File(filename).readBytes() + val address = (bytes[0].toInt() or (bytes[1].toInt() shl 8)) and 65535 + bytes.drop(2).forEachIndexed { index, byte -> + memory[address+index] = + if(byte>=0) + byte.toShort() + else + (256+byte).toShort() + } + } + + /** + * load a binary program at the given address + */ + fun load(filename: String, address: Address) { + val bytes = File(filename).readBytes() + bytes.forEachIndexed { index, byte -> + memory[address+index] = + if(byte>=0) + byte.toShort() + else + (256+byte).toShort() + } + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/RealTimeClock.kt b/src/main/kotlin/net/razorvine/ksim65/components/RealTimeClock.kt new file mode 100644 index 0000000..fed939a --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/RealTimeClock.kt @@ -0,0 +1,64 @@ +package net.razorvine.ksim65.components + +import java.time.LocalDate +import java.time.LocalTime + + +/** + * A real-time clock (time of day clock). + * byte value + * 00 year (lsb) + * 01 year (msb) + * 02 month, 1-12 + * 03 day, 1-31 + * 04 hour, 0-23 + * 05 minute, 0-59 + * 06 second, 0-59 + * 07 millisecond, 0-999 (lsb) + * 08 millisecond, 0-999 (msb) + */ +class RealTimeClock(startAddress: Address, endAddress: Address) : MemMappedComponent(startAddress, endAddress) { + + init { + require(endAddress - startAddress + 1 == 9) { "rtc needs exactly 9 memory bytes" } + } + + override fun clock() { + /* not updated on clock pulse */ + } + + override fun reset() { + /* never reset */ + } + + override operator fun get(address: Address): UByte { + return when (address - startAddress) { + 0 -> { + val year = LocalDate.now().year + (year and 255).toShort() + } + 1 -> { + val year = LocalDate.now().year + (year ushr 8).toShort() + } + 2 -> LocalDate.now().monthValue.toShort() + 3 -> LocalDate.now().dayOfMonth.toShort() + 4 -> LocalTime.now().hour.toShort() + 5 -> LocalTime.now().minute.toShort() + 6 -> LocalTime.now().second.toShort() + 7 -> { + val ms = LocalTime.now().nano / 1000 + (ms and 255).toShort() + } + 8 -> { + val ms = LocalTime.now().nano / 1000 + (ms ushr 8).toShort() + } + else -> 0 + } + } + + override operator fun set(address: Address, data: UByte) { + /* real time clock can't be set */ + } +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Rom.kt b/src/main/kotlin/net/razorvine/ksim65/components/Rom.kt new file mode 100644 index 0000000..009e8ed --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Rom.kt @@ -0,0 +1,20 @@ +package net.razorvine.ksim65.components + +class Rom(startAddress: Address, endAddress: Address, data: Array? = null) : MemoryComponent(startAddress, endAddress) { + private val memory = + if (data == null) + ShortArray(endAddress - startAddress - 1) + else + ShortArray(data.size) { index -> data[index] } + + init { + if (data != null) + require(endAddress - startAddress + 1 == data.size) { "rom address range doesn't match size of data bytes" } + } + + override operator fun get(address: Address): UByte = memory[address - startAddress] + override operator fun set(address: Address, data: UByte) {} + override fun cloneContents(): Array = memory.toTypedArray() + override fun clock() {} + override fun reset() {} +} diff --git a/src/main/kotlin/net/razorvine/ksim65/components/Timer.kt b/src/main/kotlin/net/razorvine/ksim65/components/Timer.kt new file mode 100644 index 0000000..75e506e --- /dev/null +++ b/src/main/kotlin/net/razorvine/ksim65/components/Timer.kt @@ -0,0 +1,87 @@ +package net.razorvine.ksim65.components + +/** + * A programmable timer. Causes an IRQ or NMI at specified 24-bits intervals. + * byte value + * 00 control register bit 0=enable bit 1=nmi (instead of irq) + * 01 24 bits interval value, bits 0-7 (lo) + * 02 24 bits interval value, bits 8-15 (mid) + * 03 24 bits interval value, bits 16-23 (hi) + */ +class Timer(startAddress: Address, endAddress: Address, val cpu: Cpu6502) : MemMappedComponent(startAddress, endAddress) { + private var counter: Int = 0 + private var interval: Int = 0 + private var nmi = false + private var enabled = false + set(value) { + if(value && !field) { + // timer is set to enabled (was disabled) - reset the counter + counter = 0 + } + field = value + } + + init { + require(endAddress - startAddress + 1 == 4) { "timer needs exactly 4 memory bytes" } + } + + override fun clock() { + if (enabled && interval > 0) { + counter++ + if (counter == interval) { + if (nmi) + cpu.nmi(this) + else + cpu.irq(this) + counter = 0 + } + } + } + + override fun reset() { + counter = 0 + interval = 0 + enabled = false + nmi = false + } + + override operator fun get(address: Address): UByte { + when (address - startAddress) { + 0 -> { + var data = 0 + if (enabled) data = data or 0b00000001 + if (nmi) data = data or 0b00000010 + return data.toShort() + } + 1 -> { + return (counter and 0xff).toShort() + } + 2 -> { + return ((counter ushr 8) and 0xff).toShort() + } + 3 -> { + return ((counter ushr 16) and 0xff).toShort() + } + else -> return 0 + } + } + + override operator fun set(address: Address, data: UByte) { + when (address - startAddress) { + 0 -> { + val i = data.toInt() + enabled = (i and 0b00000001) != 0 + nmi = (i and 0b00000010) != 0 + } + 1 -> { + interval = (interval and 0x7fffff00) or data.toInt() + } + 2 -> { + interval = (interval and 0x7fff00ff) or (data.toInt() shl 8) + } + 3 -> { + interval = (interval and 0x7f00ffff) or (data.toInt() shl 16) + } + } + } +} diff --git a/src/main/resources/version.txt b/src/main/resources/version.txt new file mode 100644 index 0000000..d3827e7 --- /dev/null +++ b/src/main/resources/version.txt @@ -0,0 +1 @@ +1.0 diff --git a/src/test/kotlin/6502_functional_tests/6502_decimal_test.a65 b/src/test/kotlin/6502_functional_tests/6502_decimal_test.a65 new file mode 100644 index 0000000..7a76ad1 --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/6502_decimal_test.a65 @@ -0,0 +1,355 @@ +; Verify decimal mode behavior +; Written by Bruce Clark. This code is public domain. +; see http://www.6502.org/tutorials/decimal_mode.html +; +; Returns: +; ERROR = 0 if the test passed +; ERROR = 1 if the test failed +; modify the code at the DONE label for desired program end +; +; This routine requires 17 bytes of RAM -- 1 byte each for: +; AR, CF, DA, DNVZC, ERROR, HA, HNVZC, N1, N1H, N1L, N2, N2L, NF, VF, and ZF +; and 2 bytes for N2H +; +; Variables: +; N1 and N2 are the two numbers to be added or subtracted +; N1H, N1L, N2H, and N2L are the upper 4 bits and lower 4 bits of N1 and N2 +; DA and DNVZC are the actual accumulator and flag results in decimal mode +; HA and HNVZC are the accumulator and flag results when N1 and N2 are +; added or subtracted using binary arithmetic +; AR, NF, VF, ZF, and CF are the predicted decimal mode accumulator and +; flag results, calculated using binary arithmetic +; +; This program takes approximately 1 minute at 1 MHz (a few seconds more on +; a 65C02 than a 6502 or 65816) +; + +; Configuration: +cputype = 0 ; 0 = 6502, 1 = 65C02, 2 = 65C816 +vld_bcd = 0 ; 0 = allow invalid bcd, 1 = valid bcd only +chk_a = 1 ; check accumulator +chk_n = 0 ; check sign (negative) flag +chk_v = 0 ; check overflow flag +chk_z = 0 ; check zero flag +chk_c = 1 ; check carry flag + +end_of_test macro + db $db ;execute 65C02 stop instruction + endm + + bss + org 0 +; operands - register Y = carry in +N1 ds 1 +N2 ds 1 +; binary result +HA ds 1 +HNVZC ds 1 + ;04 +; decimal result +DA ds 1 +DNVZC ds 1 +; predicted results +AR ds 1 +NF ds 1 + ;08 +VF ds 1 +ZF ds 1 +CF ds 1 +ERROR ds 1 + ;0C +; workspace +N1L ds 1 +N1H ds 1 +N2L ds 1 +N2H ds 2 + + code + org $200 +TEST ldy #1 ; initialize Y (used to loop through carry flag values) + sty ERROR ; store 1 in ERROR until the test passes + lda #0 ; initialize N1 and N2 + sta N1 + sta N2 +LOOP1 lda N2 ; N2L = N2 & $0F + and #$0F ; [1] see text + if vld_bcd = 1 + cmp #$0a + bcs NEXT2 + endif + sta N2L + lda N2 ; N2H = N2 & $F0 + and #$F0 ; [2] see text + if vld_bcd = 1 + cmp #$a0 + bcs NEXT2 + endif + sta N2H + ora #$0F ; N2H+1 = (N2 & $F0) + $0F + sta N2H+1 +LOOP2 lda N1 ; N1L = N1 & $0F + and #$0F ; [3] see text + if vld_bcd = 1 + cmp #$0a + bcs NEXT1 + endif + sta N1L + lda N1 ; N1H = N1 & $F0 + and #$F0 ; [4] see text + if vld_bcd = 1 + cmp #$a0 + bcs NEXT1 + endif + sta N1H + jsr ADD + jsr A6502 + jsr COMPARE + bne DONE + jsr SUB + jsr S6502 + jsr COMPARE + bne DONE +NEXT1 inc N1 ; [5] see text + bne LOOP2 ; loop through all 256 values of N1 +NEXT2 inc N2 ; [6] see text + bne LOOP1 ; loop through all 256 values of N2 + dey + bpl LOOP1 ; loop through both values of the carry flag + lda #0 ; test passed, so store 0 in ERROR + sta ERROR +DONE + end_of_test + +; Calculate the actual decimal mode accumulator and flags, the accumulator +; and flag results when N1 is added to N2 using binary arithmetic, the +; predicted accumulator result, the predicted carry flag, and the predicted +; V flag +; +ADD sed ; decimal mode + cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1 + adc N2 + sta DA ; actual accumulator result in decimal mode + php + pla + sta DNVZC ; actual flags result in decimal mode + cld ; binary mode + cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1 + adc N2 + sta HA ; accumulator result of N1+N2 using binary arithmetic + + php + pla + sta HNVZC ; flags result of N1+N2 using binary arithmetic + cpy #1 + lda N1L + adc N2L + cmp #$0A + ldx #0 + bcc A1 + inx + adc #5 ; add 6 (carry is set) + and #$0F + sec +A1 ora N1H +; +; if N1L + N2L < $0A, then add N2 & $F0 +; if N1L + N2L >= $0A, then add (N2 & $F0) + $0F + 1 (carry is set) +; + adc N2H,x + php + bcs A2 + cmp #$A0 + bcc A3 +A2 adc #$5F ; add $60 (carry is set) + sec +A3 sta AR ; predicted accumulator result + php + pla + sta CF ; predicted carry result + pla +; +; note that all 8 bits of the P register are stored in VF +; + sta VF ; predicted V flags + rts + +; Calculate the actual decimal mode accumulator and flags, and the +; accumulator and flag results when N2 is subtracted from N1 using binary +; arithmetic +; +SUB sed ; decimal mode + cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1 + sbc N2 + sta DA ; actual accumulator result in decimal mode + php + pla + sta DNVZC ; actual flags result in decimal mode + cld ; binary mode + cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1 + sbc N2 + sta HA ; accumulator result of N1-N2 using binary arithmetic + + php + pla + sta HNVZC ; flags result of N1-N2 using binary arithmetic + rts + + if cputype != 1 +; Calculate the predicted SBC accumulator result for the 6502 and 65816 +; +SUB1 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1L + sbc N2L + ldx #0 + bcs S11 + inx + sbc #5 ; subtract 6 (carry is clear) + and #$0F + clc +S11 ora N1H +; +; if N1L - N2L >= 0, then subtract N2 & $F0 +; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +; + sbc N2H,x + bcs S12 + sbc #$5F ; subtract $60 (carry is clear) +S12 sta AR + rts + endif + + if cputype = 1 +; Calculate the predicted SBC accumulator result for the 6502 and 65C02 +; +SUB2 cpy #1 ; set carry if Y = 1, clear carry if Y = 0 + lda N1L + sbc N2L + ldx #0 + bcs S21 + inx + and #$0F + clc +S21 ora N1H +; +; if N1L - N2L >= 0, then subtract N2 & $F0 +; if N1L - N2L < 0, then subtract (N2 & $F0) + $0F + 1 (carry is clear) +; + sbc N2H,x + bcs S22 + sbc #$5F ; subtract $60 (carry is clear) +S22 cpx #0 + beq S23 + sbc #6 +S23 sta AR ; predicted accumulator result + rts + endif + +; Compare accumulator actual results to predicted results +; +; Return: +; Z flag = 1 (BEQ branch) if same +; Z flag = 0 (BNE branch) if different +; +COMPARE + if chk_a = 1 + lda DA + cmp AR + bne C1 + endif + if chk_n = 1 + lda DNVZC ; [7] see text + eor NF + and #$80 ; mask off N flag + bne C1 + endif + if chk_v = 1 + lda DNVZC ; [8] see text + eor VF + and #$40 ; mask off V flag + bne C1 ; [9] see text + endif + if chk_z = 1 + lda DNVZC + eor ZF ; mask off Z flag + and #2 + bne C1 ; [10] see text + endif + if chk_c = 1 + lda DNVZC + eor CF + and #1 ; mask off C flag + endif +C1 rts + +; These routines store the predicted values for ADC and SBC for the 6502, +; 65C02, and 65816 in AR, CF, NF, VF, and ZF + + if cputype = 0 + +A6502 lda VF ; 6502 +; +; since all 8 bits of the P register were stored in VF, bit 7 of VF contains +; the N flag for NF +; + sta NF + lda HNVZC + sta ZF + rts + +S6502 jsr SUB1 + lda HNVZC + sta NF + sta VF + sta ZF + sta CF + rts + + endif + if cputype = 1 + +A6502 lda AR ; 65C02 + php + pla + sta NF + sta ZF + rts + +S6502 jsr SUB2 + lda AR + php + pla + sta NF + sta ZF + lda HNVZC + sta VF + sta CF + rts + + endif + if cputype = 2 + +A6502 lda AR ; 65C816 + php + pla + sta NF + sta ZF + rts + +S6502 jsr SUB1 + lda AR + php + pla + sta NF + sta ZF + lda HNVZC + sta VF + sta CF + rts + + endif + + end TEST diff --git a/src/test/kotlin/6502_functional_tests/6502_functional_test.a65 b/src/test/kotlin/6502_functional_tests/6502_functional_test.a65 new file mode 100644 index 0000000..2c4031c --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/6502_functional_test.a65 @@ -0,0 +1,6103 @@ +; +; 6 5 0 2 F U N C T I O N A L T E S T +; +; Copyright (C) 2012-2015 Klaus Dormann +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . + + +; This program is designed to test all opcodes of a 6502 emulator using all +; addressing modes with focus on propper setting of the processor status +; register bits. +; +; version 04-dec-2017 +; contact info at http://2m5.de or email K@2m5.de +; +; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/ +; command line switches: -l -m -s2 -w -h0 +; | | | | no page headers in listing +; | | | wide listing (133 char/col) +; | | write intel hex file instead of binary +; | expand macros in listing +; generate pass2 listing +; +; No IO - should be run from a monitor with access to registers. +; To run load intel hex image with a load command, than alter PC to 400 hex +; (code_segment) and enter a go command. +; Loop on program counter determines error or successful completion of test. +; Check listing for relevant traps (jump/branch *). +; Please note that in early tests some instructions will have to be used before +; they are actually tested! +; +; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled. +; Tests documented behavior of the original NMOS 6502 only! No unofficial +; opcodes. Additional opcodes of newer versions of the CPU (65C02, 65816) will +; not be tested. Decimal ops will only be tested with valid BCD operands and +; N V Z flags will be ignored. +; +; Debugging hints: +; Most of the code is written sequentially. if you hit a trap, check the +; immediately preceeding code for the instruction to be tested. Results are +; tested first, flags are checked second by pushing them onto the stack and +; pulling them to the accumulator after the result was checked. The "real" +; flags are no longer valid for the tested instruction at this time! +; If the tested instruction was indexed, the relevant index (X or Y) must +; also be checked. Opposed to the flags, X and Y registers are still valid. +; +; versions: +; 28-jul-2012 1st version distributed for testing +; 29-jul-2012 fixed references to location 0, now #0 +; added license - GPLv3 +; 30-jul-2012 added configuration options +; 01-aug-2012 added trap macro to allow user to change error handling +; 01-dec-2012 fixed trap in branch field must be a branch +; 02-mar-2013 fixed PLA flags not tested +; 19-jul-2013 allowed ROM vectors to be loaded when load_data_direct = 0 +; added test sequence check to detect if tests jump their fence +; 23-jul-2013 added RAM integrity check option +; 16-aug-2013 added error report to standard output option +; 13-dec-2014 added binary/decimal opcode table switch test +; 14-dec-2014 improved relative address test +; 23-aug-2015 added option to disable self modifying tests +; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM +; added small branch offset pretest +; 21-oct-2015 added option to disable decimal mode ADC & SBC tests +; 04-dec-2017 fixed BRK only tested with interrupts enabled +; added option to skip the remainder of a failing test +; in report.i65 + + +; C O N F I G U R A T I O N + +;ROM_vectors writable (0=no, 1=yes) +;if ROM vectors can not be used interrupts will not be trapped +;as a consequence BRK can not be tested but will be emulated to test RTI +ROM_vectors = 1 + +;load_data_direct (0=move from code segment, 1=load directly) +;loading directly is preferred but may not be supported by your platform +;0 produces only consecutive object code, 1 is not suitable for a binary image +load_data_direct = 1 + +;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow +;change) 2 requires extra code and is not recommended. SEI & CLI can only be +;tested if you allow changing the interrupt status (I_flag = 3) +I_flag = 3 + +;configure memory - try to stay away from memory used by the system +;zero_page memory start address, $50 (80) consecutive Bytes required +; add 2 if I_flag = 2 +zero_page = $a + +;data_segment memory start address, $6A (106) consecutive Bytes required +data_segment = $200 + if (data_segment & $ff) != 0 + ERROR ERROR ERROR low byte of data_segment MUST be $00 !! + endif + +;code_segment memory start address, 13kB of consecutive space required +; add 2.5 kB if I_flag = 2 +code_segment = $400 + +;self modifying code may be disabled to allow running in ROM +;0=part of the code is self modifying and must reside in RAM +;1=tests disabled: branch range +disable_selfmod = 0 + +;report errors through I/O channel (0=use standard self trap loops, 1=include +;report.i65 as I/O channel, add 3.5 kB) +report = 0 + +;RAM integrity test option. Checks for undesired RAM writes. +;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k) +;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM +ram_top = -1 + +;disable test decimal mode ADC & SBC, 0=enable, 1=disable, +;2=disable including decimal flag in processor status +disable_decimal = 0 + + noopt ;do not take shortcuts + +;macros for error & success traps to allow user modification +;example: +;trap macro +; jsr my_error_handler +; endm +;trap_eq macro +; bne skip\? +; trap ;failed equal (zero) +;skip\? +; endm +; +; my_error_handler should pop the calling address from the stack and report it. +; putting larger portions of code (more than 3 bytes) inside the trap macro +; may lead to branch range problems for some tests. + if report = 0 +trap macro + jmp * ;failed anyway + endm +trap_eq macro + beq * ;failed equal (zero) + endm +trap_ne macro + bne * ;failed not equal (non zero) + endm +trap_cs macro + bcs * ;failed carry set + endm +trap_cc macro + bcc * ;failed carry clear + endm +trap_mi macro + bmi * ;failed minus (bit 7 set) + endm +trap_pl macro + bpl * ;failed plus (bit 7 clear) + endm +trap_vs macro + bvs * ;failed overflow set + endm +trap_vc macro + bvc * ;failed overflow clear + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jmp * ;test passed, no errors + endm + endif + if report = 1 +trap macro + jsr report_error + endm +trap_eq macro + bne skip\? + trap ;failed equal (zero) +skip\? + endm +trap_ne macro + beq skip\? + trap ;failed not equal (non zero) +skip\? + endm +trap_cs macro + bcc skip\? + trap ;failed carry set +skip\? + endm +trap_cc macro + bcs skip\? + trap ;failed carry clear +skip\? + endm +trap_mi macro + bpl skip\? + trap ;failed minus (bit 7 set) +skip\? + endm +trap_pl macro + bmi skip\? + trap ;failed plus (bit 7 clear) +skip\? + endm +trap_vs macro + bvc skip\? + trap ;failed overflow set +skip\? + endm +trap_vc macro + bvs skip\? + trap ;failed overflow clear +skip\? + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jsr report_success + endm + endif + + +carry equ %00000001 ;flag bits in status +zero equ %00000010 +intdis equ %00000100 +decmode equ %00001000 +break equ %00010000 +reserv equ %00100000 +overfl equ %01000000 +minus equ %10000000 + +fc equ carry +fz equ zero +fzc equ carry+zero +fv equ overfl +fvz equ overfl+zero +fn equ minus +fnc equ minus+carry +fnz equ minus+zero +fnzc equ minus+zero+carry +fnv equ minus+overfl + +fao equ break+reserv ;bits always on after PHP, BRK +fai equ fao+intdis ;+ forced interrupt disable +faod equ fao+decmode ;+ ignore decimal +faid equ fai+decmode ;+ ignore decimal +m8 equ $ff ;8 bit mask +m8i equ $ff&~intdis ;8 bit mask - interrupt disable + +;macros to allow masking of status bits. +;masking test of decimal bit +;masking of interrupt enable/disable on load and compare +;masking of always on bits after PHP or BRK (unused & break) on compare + if disable_decimal < 2 + if I_flag = 0 +load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm +cmp_flag macro + cmp #(\1|fao)&m8i ;I_flag is always enabled + always on bits + endm +eor_flag macro + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 +load_flag macro + lda #\1|intdis ;force disable interrupts + endm +cmp_flag macro + cmp #(\1|fai)&m8 ;I_flag is always disabled + always on bits + endm +eor_flag macro + eor #(\1|fai) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 +load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm +cmp_flag macro + eor flag_I_on ;I_flag is never changed + cmp #(\1|fao)&m8i ;expected flags + always on bits, mask I + endm +eor_flag macro + eor flag_I_on ;I_flag is never changed + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 +load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm +cmp_flag macro + cmp #(\1|fao)&m8 ;expected flags + always on bits + endm +eor_flag macro + eor #\1|fao ;invert expected flags + always on bits + endm + endif + else + if I_flag = 0 +load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm +cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8i ;I_flag is always enabled + always on bits + endm +eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #(\1&m8i|faod) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 +load_flag macro + lda #\1|intdis ;force disable interrupts + endm +cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faid)&m8 ;I_flag is always disabled + always on bits + endm +eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #(\1|faid) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 +load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm +cmp_flag macro + eor flag_I_on ;I_flag is never changed + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8i ;expected flags + always on bits, mask I + endm +eor_flag macro + eor flag_I_on ;I_flag is never changed + ora #decmode ;ignore decimal mode bit + eor #(\1&m8i|faod) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 +load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm +cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8 ;expected flags + always on bits + endm +eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #\1|faod ;invert expected flags + always on bits + endm + endif + endif + +;macros to set (register|memory|zeropage) & status +set_stat macro ;setting flags in the processor status register + load_flag \1 + pha ;use stack to load status + plp + endm + +set_a macro ;precharging accu & status + load_flag \2 + pha ;use stack to load status + lda #\1 ;precharge accu + plp + endm + +set_x macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldx #\1 ;precharge index x + plp + endm + +set_y macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldy #\1 ;precharge index y + plp + endm + +set_ax macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;precharge accu + plp + endm + +set_ay macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,y ;precharge accu + plp + endm + +set_z macro ;precharging indexed zp & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to zeropage + sta zpt + plp + endm + +set_zx macro ;precharging zp,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed zeropage + sta zpt,x + plp + endm + +set_abs macro ;precharging indexed memory & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to memory + sta abst + plp + endm + +set_absx macro ;precharging abs,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed memory + sta abst,x + plp + endm + +;macros to test (register|memory|zeropage) & status & (mask) +tst_stat macro ;testing flags in the processor status register + php ;save status + pla ;use stack to retrieve status + pha + cmp_flag \1 + trap_ne + plp ;restore status + endm + +tst_a macro ;testing result in accu & flags + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_x macro ;testing result in x index & flags + php ;save flags + cpx #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_y macro ;testing result in y index & flags + php ;save flags + cpy #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_ax macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne ; + endm + +tst_ay macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,y ;test result + trap_ne ; + pla ;load status + eor_flag \3 + cmp \2,y ;test flags + trap_ne + endm + +tst_z macro ;indexed testing result in zp & flags + php ;save flags + lda zpt + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_zx macro ;testing result in zp,x & flags + php ;save flags + lda zpt,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_abs macro ;indexed testing result in memory & flags + php ;save flags + lda abst + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_absx macro ;testing result in abs,x & flags + php ;save flags + lda abst,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +; RAM integrity test +; verifies that none of the previous tests has altered RAM outside of the +; designated write areas. +; uses zpt word as indirect pointer, zpt+2 word as checksum + if ram_top > -1 +check_ram macro + cld + lda #0 + sta zpt ;set low byte of indirect pointer + sta zpt+3 ;checksum high byte + if disable_selfmod = 0 + sta range_adr ;reset self modifying code + endif + clc + ldx #zp_bss-zero_page ;zeropage - write test area +ccs3\? adc zero_page,x + bcc ccs2\? + inc zpt+3 ;carry to high byte + clc +ccs2\? inx + bne ccs3\? + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area +ccs5\? adc (zpt),y + bcc ccs4\? + inc zpt+3 ;carry to high byte + clc +ccs4\? iny + bne ccs5\? + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne ccs5\? + sta zpt+2 ;checksum low is + cmp ram_chksm ;checksum low expected + trap_ne ;checksum mismatch + lda zpt+3 ;checksum high is + cmp ram_chksm+1 ;checksum high expected + trap_ne ;checksum mismatch + endm + else +check_ram macro + ;RAM check disabled - RAM size not set + endm + endif + +next_test macro ;make sure, tests don't jump the fence + lda test_case ;previous test + cmp #test_num + trap_ne ;test is out of sequence +test_num = test_num + 1 + lda #test_num ;*** next tests' number + sta test_case + ;check_ram ;uncomment to find altered RAM after each test + endm + + if load_data_direct = 1 + data + else + bss ;uninitialized segment, copy of data at end of code! + endif + org zero_page +;break test interrupt save +irq_a ds 1 ;a register +irq_x ds 1 ;x register + if I_flag = 2 +;masking for I bit in status +flag_I_on ds 1 ;or mask to load flags +flag_I_off ds 1 ;and mask to load flags + endif +zpt ;5 bytes store/modify test area +;add/subtract operand generation and result/flag prediction +adfc ds 1 ;carry flag before op +ad1 ds 1 ;operand 1 - accumulator +ad2 ds 1 ;operand 2 - memory / immediate +adrl ds 1 ;expected result bits 0-7 +adrh ds 1 ;expected result bit 8 (carry) +adrf ds 1 ;expected flags NV0000ZC (only binary mode) +sb2 ds 1 ;operand 2 complemented for subtract +zp_bss +zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +zp7f db $7f ;test pattern for compare +;logical zeropage operands +zpOR db 0,$1f,$71,$80 ;test pattern for OR +zpAN db $0f,$ff,$7f,$80 ;test pattern for AND +zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR +;indirect addressing pointers +ind1 dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f +inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern +indt dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 +inwt dw abst-$f8 ;indirect pointer for wrap-test store +indAN dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 +indEO dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 +indOR dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 +;add/subtract indirect pointers +adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory +sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC) +adiy2 dw ada2-$ff ;with offset for indirect indexed +sbiy2 dw sba2-$ff +zp_bss_end + + org data_segment +test_case ds 1 ;current test number +ram_chksm ds 2 ;checksum for RAM integrity test +;add/subtract operand copy - abs tests write area +abst ;5 bytes store/modify test area +ada2 ds 1 ;operand 2 +sba2 ds 1 ;operand 2 complemented for subtract + ds 3 ;fill remaining bytes +data_bss + if load_data_direct = 1 +ex_andi and #0 ;execute immediate opcodes + rts +ex_eori eor #0 ;execute immediate opcodes + rts +ex_orai ora #0 ;execute immediate opcodes + rts +ex_adci adc #0 ;execute immediate opcodes + rts +ex_sbci sbc #0 ;execute immediate opcodes + rts + else +ex_andi ds 3 +ex_eori ds 3 +ex_orai ds 3 +ex_adci ds 3 +ex_sbci ds 3 + endif +abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +abs7f db $7f ;test pattern for compare +;loads +fLDx db fn,fn,0,fz ;expected flags for load +;shifts +rASL ;expected result ASL & ROL -carry +rROL db $86,$04,$82,0 ; " +rROLc db $87,$05,$83,1 ;expected result ROL +carry +rLSR ;expected result LSR & ROR -carry +rROR db $61,$41,$20,0 ; " +rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry +fASL ;expected flags for shifts +fROL db fnc,fc,fn,fz ;no carry in +fROLc db fnc,fc,fn,0 ;carry in +fLSR +fROR db fc,0,fc,fz ;no carry in +fRORc db fnc,fn,fnc,fn ;carry in +;increments (decrements) +rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC +fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC +;logical memory operand +absOR db 0,$1f,$71,$80 ;test pattern for OR +absAN db $0f,$ff,$7f,$80 ;test pattern for AND +absEO db $ff,$0f,$8f,$8f ;test pattern for EOR +;logical accu operand +absORa db 0,$f1,$1f,0 ;test pattern for OR +absANa db $f0,$ff,$ff,$ff ;test pattern for AND +absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR +;logical results +absrlo db 0,$ff,$7f,$80 +absflo db fz,fn,0,fn +data_bss_end + + + code + org code_segment +start cld + ldx #$ff + txs + lda #0 ;*** test 0 = initialize + sta test_case +test_num = 0 + +;stop interrupts before initializing BSS + if I_flag = 1 + sei + endif + +;initialize I/O for report channel + if report = 1 + jsr report_init + endif + +;pretest small branch offset + ldx #5 + jmp psb_test +psb_bwok + ldy #5 + bne psb_forw + trap ;branch should be taken + dey ;forward landing zone + dey + dey + dey + dey +psb_forw + dey + dey + dey + dey + dey + beq psb_fwok + trap ;forward offset + + dex ;backward landing zone + dex + dex + dex + dex +psb_back + dex + dex + dex + dex + dex + beq psb_bwok + trap ;backward offset +psb_test + bne psb_back + trap ;branch should be taken +psb_fwok + +;initialize BSS segment + if load_data_direct != 1 + ldx #zp_end-zp_init-1 +ld_zp lda zp_init,x + sta zp_bss,x + dex + bpl ld_zp + ldx #data_end-data_init-1 +ld_data lda data_init,x + sta data_bss,x + dex + bpl ld_data + if ROM_vectors = 1 + ldx #5 +ld_vect lda vec_init,x + sta vec_bss,x + dex + bpl ld_vect + endif + endif + +;retain status of interrupt flag + if I_flag = 2 + php + pla + and #4 ;isolate flag + sta flag_I_on ;or mask + eor #lo(~4) ;reverse + sta flag_I_off ;and mask + endif + +;generate checksum for RAM integrity test + if ram_top > -1 + lda #0 + sta zpt ;set low byte of indirect pointer + sta ram_chksm+1 ;checksum high byte + if disable_selfmod = 0 + sta range_adr ;reset self modifying code + endif + clc + ldx #zp_bss-zero_page ;zeropage - write test area +gcs3 adc zero_page,x + bcc gcs2 + inc ram_chksm+1 ;carry to high byte + clc +gcs2 inx + bne gcs3 + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area +gcs5 adc (zpt),y + bcc gcs4 + inc ram_chksm+1 ;carry to high byte + clc +gcs4 iny + bne gcs5 + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne gcs5 + sta ram_chksm ;checksum complete + endif + next_test + + if disable_selfmod = 0 +;testing relative addressing with BEQ + ldy #$fe ;testing maximum range, not -1/-2 (invalid/self adr) +range_loop + dey ;next relative address + tya + tax ;precharge count to end of loop + bpl range_fw ;calculate relative address + clc ;avoid branch self or to relative address of branch + adc #2 + nop ;offset landing zone - tolerate +/-5 offset to branch + nop + nop + nop + nop +range_fw + nop + nop + nop + nop + nop + eor #$7f ;complement except sign + sta range_adr ;load into test target + lda #0 ;should set zero flag in status register + jmp range_op + + dex ; offset landing zone - backward branch too far + dex + dex + dex + dex + ;relative address target field with branch under test in the middle + dex ;-128 - max backward + dex + dex + dex + dex + dex + dex + dex + dex ;-120 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-110 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-100 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-90 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-80 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-70 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-60 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-50 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-40 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-30 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-20 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;-10 + dex + dex + dex + dex + dex + dex + dex ;-3 +range_op ;test target with zero flag=0, z=1 if previous dex +range_adr = *+1 ;modifiable relative address + beq *+64 ;+64 if called without modification + dex ;+0 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+10 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+20 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+30 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+40 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+50 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+60 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+70 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+80 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+90 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+100 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+110 + dex + dex + dex + dex + dex + dex + dex + dex + dex + dex ;+120 + dex + dex + dex + dex + dex + dex + nop ;offset landing zone - forward branch too far + nop + nop + nop + nop + beq range_ok ;+127 - max forward + trap ; bad range + nop ;offset landing zone - tolerate +/-5 offset to branch + nop + nop + nop + nop +range_ok + nop + nop + nop + nop + nop + cpy #0 + beq range_end + jmp range_loop +range_end ;range test successful + endif + next_test + +;partial test BNE & CMP, CPX, CPY immediate + cpy #1 ;testing BNE true + bne test_bne + trap +test_bne + lda #0 + cmp #0 ;test compare immediate + trap_ne + trap_cc + trap_mi + cmp #1 + trap_eq + trap_cs + trap_pl + tax + cpx #0 ;test compare x immediate + trap_ne + trap_cc + trap_mi + cpx #1 + trap_eq + trap_cs + trap_pl + tay + cpy #0 ;test compare y immediate + trap_ne + trap_cc + trap_mi + cpy #1 + trap_eq + trap_cs + trap_pl + next_test +;testing stack operations PHA PHP PLA PLP + + ldx #$ff ;initialize stack + txs + lda #$55 + pha + lda #$aa + pha + cmp $1fe ;on stack ? + trap_ne + tsx + txa ;overwrite accu + cmp #$fd ;sp decremented? + trap_ne + pla + cmp #$aa ;successful retreived from stack? + trap_ne + pla + cmp #$55 + trap_ne + cmp $1ff ;remains on stack? + trap_ne + tsx + cpx #$ff ;sp incremented? + trap_ne + next_test + +;testing branch decisions BPL BMI BVC BVS BCC BCS BNE BEQ + set_stat $ff ;all on + bpl nbr1 ;branches should not be taken + bvc nbr2 + bcc nbr3 + bne nbr4 + bmi br1 ;branches should be taken + trap +br1 bvs br2 + trap +br2 bcs br3 + trap +br3 beq br4 + trap +nbr1 + trap ;previous bpl taken +nbr2 + trap ;previous bvc taken +nbr3 + trap ;previous bcc taken +nbr4 + trap ;previous bne taken +br4 php + tsx + cpx #$fe ;sp after php? + trap_ne + pla + cmp_flag $ff ;returned all flags on? + trap_ne + tsx + cpx #$ff ;sp after php? + trap_ne + set_stat 0 ;all off + bmi nbr11 ;branches should not be taken + bvs nbr12 + bcs nbr13 + beq nbr14 + bpl br11 ;branches should be taken + trap +br11 bvc br12 + trap +br12 bcc br13 + trap +br13 bne br14 + trap +nbr11 + trap ;previous bmi taken +nbr12 + trap ;previous bvs taken +nbr13 + trap ;previous bcs taken +nbr14 + trap ;previous beq taken +br14 php + pla + cmp_flag 0 ;flags off except break (pushed by sw) + reserved? + trap_ne + ;crosscheck flags + set_stat zero + bne brzs1 + beq brzs2 +brzs1 + trap ;branch zero/non zero +brzs2 bcs brzs3 + bcc brzs4 +brzs3 + trap ;branch carry/no carry +brzs4 bmi brzs5 + bpl brzs6 +brzs5 + trap ;branch minus/plus +brzs6 bvs brzs7 + bvc brzs8 +brzs7 + trap ;branch overflow/no overflow +brzs8 + set_stat carry + beq brcs1 + bne brcs2 +brcs1 + trap ;branch zero/non zero +brcs2 bcc brcs3 + bcs brcs4 +brcs3 + trap ;branch carry/no carry +brcs4 bmi brcs5 + bpl brcs6 +brcs5 + trap ;branch minus/plus +brcs6 bvs brcs7 + bvc brcs8 +brcs7 + trap ;branch overflow/no overflow + +brcs8 + set_stat minus + beq brmi1 + bne brmi2 +brmi1 + trap ;branch zero/non zero +brmi2 bcs brmi3 + bcc brmi4 +brmi3 + trap ;branch carry/no carry +brmi4 bpl brmi5 + bmi brmi6 +brmi5 + trap ;branch minus/plus +brmi6 bvs brmi7 + bvc brmi8 +brmi7 + trap ;branch overflow/no overflow +brmi8 + set_stat overfl + beq brvs1 + bne brvs2 +brvs1 + trap ;branch zero/non zero +brvs2 bcs brvs3 + bcc brvs4 +brvs3 + trap ;branch carry/no carry +brvs4 bmi brvs5 + bpl brvs6 +brvs5 + trap ;branch minus/plus +brvs6 bvc brvs7 + bvs brvs8 +brvs7 + trap ;branch overflow/no overflow +brvs8 + set_stat $ff-zero + beq brzc1 + bne brzc2 +brzc1 + trap ;branch zero/non zero +brzc2 bcc brzc3 + bcs brzc4 +brzc3 + trap ;branch carry/no carry +brzc4 bpl brzc5 + bmi brzc6 +brzc5 + trap ;branch minus/plus +brzc6 bvc brzc7 + bvs brzc8 +brzc7 + trap ;branch overflow/no overflow +brzc8 + set_stat $ff-carry + bne brcc1 + beq brcc2 +brcc1 + trap ;branch zero/non zero +brcc2 bcs brcc3 + bcc brcc4 +brcc3 + trap ;branch carry/no carry +brcc4 bpl brcc5 + bmi brcc6 +brcc5 + trap ;branch minus/plus +brcc6 bvc brcc7 + bvs brcc8 +brcc7 + trap ;branch overflow/no overflow +brcc8 + set_stat $ff-minus + bne brpl1 + beq brpl2 +brpl1 + trap ;branch zero/non zero +brpl2 bcc brpl3 + bcs brpl4 +brpl3 + trap ;branch carry/no carry +brpl4 bmi brpl5 + bpl brpl6 +brpl5 + trap ;branch minus/plus +brpl6 bvc brpl7 + bvs brpl8 +brpl7 + trap ;branch overflow/no overflow +brpl8 + set_stat $ff-overfl + bne brvc1 + beq brvc2 +brvc1 + trap ;branch zero/non zero +brvc2 bcc brvc3 + bcs brvc4 +brvc3 + trap ;branch carry/no carry +brvc4 bpl brvc5 + bmi brvc6 +brvc5 + trap ;branch minus/plus +brvc6 bvs brvc7 + bvc brvc8 +brvc7 + trap ;branch overflow/no overflow +brvc8 + next_test + +; test PHA does not alter flags or accumulator but PLA does + ldx #$55 ;x & y protected + ldy #$aa + set_a 1,$ff ;push + pha + tst_a 1,$ff + set_a 0,0 + pha + tst_a 0,0 + set_a $ff,$ff + pha + tst_a $ff,$ff + set_a 1,0 + pha + tst_a 1,0 + set_a 0,$ff + pha + tst_a 0,$ff + set_a $ff,0 + pha + tst_a $ff,0 + set_a 0,$ff ;pull + pla + tst_a $ff,$ff-zero + set_a $ff,0 + pla + tst_a 0,zero + set_a $fe,$ff + pla + tst_a 1,$ff-zero-minus + set_a 0,0 + pla + tst_a $ff,minus + set_a $ff,$ff + pla + tst_a 0,$ff-minus + set_a $fe,0 + pla + tst_a 1,0 + cpx #$55 ;x & y unchanged? + trap_ne + cpy #$aa + trap_ne + next_test + +; partial pretest EOR # + set_a $3c,0 + eor #$c3 + tst_a $ff,fn + set_a $c3,0 + eor #$c3 + tst_a 0,fz + next_test + +; PC modifying instructions except branches (NOP, JMP, JSR, RTS, BRK, RTI) +; testing NOP + ldx #$24 + ldy #$42 + set_a $18,0 + nop + tst_a $18,0 + cpx #$24 + trap_ne + cpy #$42 + trap_ne + ldx #$db + ldy #$bd + set_a $e7,$ff + nop + tst_a $e7,$ff + cpx #$db + trap_ne + cpy #$bd + trap_ne + next_test + +; jump absolute + set_stat $0 + lda #'F' + ldx #'A' + ldy #'R' ;N=0, V=0, Z=0, C=0 + jmp test_far + nop + nop + trap_ne ;runover protection + inx + inx +far_ret + trap_eq ;returned flags OK? + trap_pl + trap_cc + trap_vc + cmp #('F'^$aa) ;returned registers OK? + trap_ne + cpx #('A'+1) + trap_ne + cpy #('R'-3) + trap_ne + dex + iny + iny + iny + eor #$aa ;N=0, V=1, Z=0, C=1 + jmp test_near + nop + nop + trap_ne ;runover protection + inx + inx +test_near + trap_eq ;passed flags OK? + trap_mi + trap_cc + trap_vc + cmp #'F' ;passed registers OK? + trap_ne + cpx #'A' + trap_ne + cpy #'R' + trap_ne + next_test + +; jump indirect + set_stat 0 + lda #'I' + ldx #'N' + ldy #'D' ;N=0, V=0, Z=0, C=0 + jmp (ptr_tst_ind) + nop + trap_ne ;runover protection + dey + dey +ind_ret + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_eq ;returned flags OK? + trap_pl + trap_cc + trap_vc + cmp #('I'^$aa) ;returned registers OK? + trap_ne + cpx #('N'+1) + trap_ne + cpy #('D'-6) + trap_ne + tsx ;SP check + cpx #$ff + trap_ne + next_test + +; jump subroutine & return from subroutine + set_stat 0 + lda #'J' + ldx #'S' + ldy #'R' ;N=0, V=0, Z=0, C=0 + jsr test_jsr +jsr_ret = *-1 ;last address of jsr = return address + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_eq ;returned flags OK? + trap_pl + trap_cc + trap_vc + cmp #('J'^$aa) ;returned registers OK? + trap_ne + cpx #('S'+1) + trap_ne + cpy #('R'-6) + trap_ne + tsx ;sp? + cpx #$ff + trap_ne + next_test + +; break & return from interrupt + if ROM_vectors = 1 + load_flag 0 ;with interrupts enabled if allowed! + pha + lda #'B' + ldx #'R' + ldy #'K' + plp ;N=0, V=0, Z=0, C=0 + brk + else + lda #hi brk_ret0 ;emulated break + pha + lda #lo brk_ret0 + pha + load_flag fao ;set break & unused on stack + pha + load_flag intdis ;during interrupt + pha + lda #'B' + ldx #'R' + ldy #'K' + plp ;N=0, V=0, Z=0, C=0 + jmp irq_trap + endif + dey ;should not be executed +brk_ret0 ;address of break return + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + cmp #'B'^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne + cpx #'R'+1 + trap_ne + cpy #'K'-6 + trap_ne + pla ;returned flags OK (unchanged)? + cmp_flag 0 + trap_ne + tsx ;sp? + cpx #$ff + trap_ne + if ROM_vectors = 1 + load_flag $ff ;with interrupts disabled if allowed! + pha + lda #$ff-'B' + ldx #$ff-'R' + ldy #$ff-'K' + plp ;N=1, V=1, Z=1, C=1 + brk + else + lda #hi brk_ret1 ;emulated break + pha + lda #lo brk_ret1 + pha + load_flag $ff + pha ;set break & unused on stack + pha ;actual flags + lda #$ff-'B' + ldx #$ff-'R' + ldy #$ff-'K' + plp ;N=1, V=1, Z=1, C=1 + jmp irq_trap + endif + dey ;should not be executed +brk_ret1 ;address of break return + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + cmp #($ff-'B')^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne + cpx #$ff-'R'+1 + trap_ne + cpy #$ff-'K'-6 + trap_ne + pla ;returned flags OK (unchanged)? + cmp_flag $ff + trap_ne + tsx ;sp? + cpx #$ff + trap_ne + next_test + +; test set and clear flags CLC CLI CLD CLV SEC SEI SED + set_stat $ff + clc + tst_stat $ff-carry + sec + tst_stat $ff + if I_flag = 3 + cli + tst_stat $ff-intdis + sei + tst_stat $ff + endif + cld + tst_stat $ff-decmode + sed + tst_stat $ff + clv + tst_stat $ff-overfl + set_stat 0 + tst_stat 0 + sec + tst_stat carry + clc + tst_stat 0 + if I_flag = 3 + sei + tst_stat intdis + cli + tst_stat 0 + endif + sed + tst_stat decmode + cld + tst_stat 0 + set_stat overfl + tst_stat overfl + clv + tst_stat 0 + next_test +; testing index register increment/decrement and transfer +; INX INY DEX DEY TAX TXA TAY TYA + ldx #$fe + set_stat $ff + inx ;ff + tst_x $ff,$ff-zero + inx ;00 + tst_x 0,$ff-minus + inx ;01 + tst_x 1,$ff-minus-zero + dex ;00 + tst_x 0,$ff-minus + dex ;ff + tst_x $ff,$ff-zero + dex ;fe + set_stat 0 + inx ;ff + tst_x $ff,minus + inx ;00 + tst_x 0,zero + inx ;01 + tst_x 1,0 + dex ;00 + tst_x 0,zero + dex ;ff + tst_x $ff,minus + + ldy #$fe + set_stat $ff + iny ;ff + tst_y $ff,$ff-zero + iny ;00 + tst_y 0,$ff-minus + iny ;01 + tst_y 1,$ff-minus-zero + dey ;00 + tst_y 0,$ff-minus + dey ;ff + tst_y $ff,$ff-zero + dey ;fe + set_stat 0 + iny ;ff + tst_y $ff,0+minus + iny ;00 + tst_y 0,zero + iny ;01 + tst_y 1,0 + dey ;00 + tst_y 0,zero + dey ;ff + tst_y $ff,minus + + ldx #$ff + set_stat $ff + txa + tst_a $ff,$ff-zero + php + inx ;00 + plp + txa + tst_a 0,$ff-minus + php + inx ;01 + plp + txa + tst_a 1,$ff-minus-zero + set_stat 0 + txa + tst_a 1,0 + php + dex ;00 + plp + txa + tst_a 0,zero + php + dex ;ff + plp + txa + tst_a $ff,minus + + ldy #$ff + set_stat $ff + tya + tst_a $ff,$ff-zero + php + iny ;00 + plp + tya + tst_a 0,$ff-minus + php + iny ;01 + plp + tya + tst_a 1,$ff-minus-zero + set_stat 0 + tya + tst_a 1,0 + php + dey ;00 + plp + tya + tst_a 0,zero + php + dey ;ff + plp + tya + tst_a $ff,minus + + load_flag $ff + pha + ldx #$ff ;ff + txa + plp + tay + tst_y $ff,$ff-zero + php + inx ;00 + txa + plp + tay + tst_y 0,$ff-minus + php + inx ;01 + txa + plp + tay + tst_y 1,$ff-minus-zero + load_flag 0 + pha + lda #0 + txa + plp + tay + tst_y 1,0 + php + dex ;00 + txa + plp + tay + tst_y 0,zero + php + dex ;ff + txa + plp + tay + tst_y $ff,minus + + + load_flag $ff + pha + ldy #$ff ;ff + tya + plp + tax + tst_x $ff,$ff-zero + php + iny ;00 + tya + plp + tax + tst_x 0,$ff-minus + php + iny ;01 + tya + plp + tax + tst_x 1,$ff-minus-zero + load_flag 0 + pha + lda #0 ;preset status + tya + plp + tax + tst_x 1,0 + php + dey ;00 + tya + plp + tax + tst_x 0,zero + php + dey ;ff + tya + plp + tax + tst_x $ff,minus + next_test + +;TSX sets NZ - TXS does not +; This section also tests for proper stack wrap around. + ldx #1 ;01 + set_stat $ff + txs + php + lda $101 + cmp_flag $ff + trap_ne + set_stat 0 + txs + php + lda $101 + cmp_flag 0 + trap_ne + dex ;00 + set_stat $ff + txs + php + lda $100 + cmp_flag $ff + trap_ne + set_stat 0 + txs + php + lda $100 + cmp_flag 0 + trap_ne + dex ;ff + set_stat $ff + txs + php + lda $1ff + cmp_flag $ff + trap_ne + set_stat 0 + txs + php + lda $1ff + cmp_flag 0 + + ldx #1 + txs ;sp=01 + set_stat $ff + tsx ;clears Z, N + php ;sp=00 + cpx #1 + trap_ne + lda $101 + cmp_flag $ff-minus-zero + trap_ne + set_stat $ff + tsx ;clears N, sets Z + php ;sp=ff + cpx #0 + trap_ne + lda $100 + cmp_flag $ff-minus + trap_ne + set_stat $ff + tsx ;clears N, sets Z + php ;sp=fe + cpx #$ff + trap_ne + lda $1ff + cmp_flag $ff-zero + trap_ne + + ldx #1 + txs ;sp=01 + set_stat 0 + tsx ;clears Z, N + php ;sp=00 + cpx #1 + trap_ne + lda $101 + cmp_flag 0 + trap_ne + set_stat 0 + tsx ;clears N, sets Z + php ;sp=ff + cpx #0 + trap_ne + lda $100 + cmp_flag zero + trap_ne + set_stat 0 + tsx ;clears N, sets Z + php ;sp=fe + cpx #$ff + trap_ne + lda $1ff + cmp_flag minus + trap_ne + pla ;sp=ff + next_test + +; testing index register load & store LDY LDX STY STX all addressing modes +; LDX / STX - zp,y / abs,y + ldy #3 +tldx + set_stat 0 + ldx zp1,y + php ;test stores do not alter flags + txa + eor #$c3 + plp + sta abst,y + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,y ;test flags + trap_ne + dey + bpl tldx + + ldy #3 +tldx1 + set_stat $ff + ldx zp1,y + php ;test stores do not alter flags + txa + eor #$c3 + plp + sta abst,y + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,y ;test flags + trap_ne + dey + bpl tldx1 + + ldy #3 +tldx2 + set_stat 0 + ldx abs1,y + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt,y + php ;flags after load/store sequence + eor #$c3 + cmp zp1,y ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,y ;test flags + trap_ne + dey + bpl tldx2 + + ldy #3 +tldx3 + set_stat $ff + ldx abs1,y + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt,y + php ;flags after load/store sequence + eor #$c3 + cmp zp1,y ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,y ;test flags + trap_ne + dey + bpl tldx3 + + ldy #3 ;testing store result + ldx #0 +tstx lda zpt,y + eor #$c3 + cmp zp1,y + trap_ne ;store to zp data + stx zpt,y ;clear + lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstx + next_test + +; indexed wraparound test (only zp should wrap) + ldy #3+$fa +tldx4 ldx zp1-$fa&$ff,y ;wrap on indexed zp + txa + sta abst-$fa,y ;no STX abs,y! + dey + cpy #$fa + bcs tldx4 + ldy #3+$fa +tldx5 ldx abs1-$fa,y ;no wrap on indexed abs + stx zpt-$fa&$ff,y + dey + cpy #$fa + bcs tldx5 + ldy #3 ;testing wraparound result + ldx #0 +tstx1 lda zpt,y + cmp zp1,y + trap_ne ;store to zp data + stx zpt,y ;clear + lda abst,y + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstx1 + next_test + +; LDY / STY - zp,x / abs,x + ldx #3 +tldy + set_stat 0 + ldy zp1,x + php ;test stores do not alter flags + tya + eor #$c3 + plp + sta abst,x + php ;flags after load/store sequence + eor #$c3 + cmp abs1,x ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldy + + ldx #3 +tldy1 + set_stat $ff + ldy zp1,x + php ;test stores do not alter flags + tya + eor #$c3 + plp + sta abst,x + php ;flags after load/store sequence + eor #$c3 + cmp abs1,x ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldy1 + + ldx #3 +tldy2 + set_stat 0 + ldy abs1,x + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt,x + php ;flags after load/store sequence + eor #$c3 + cmp zp1,x ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldy2 + + ldx #3 +tldy3 + set_stat $ff + ldy abs1,x + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt,x + php ;flags after load/store sequence + eor #$c3 + cmp zp1,x ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldy3 + + ldx #3 ;testing store result + ldy #0 +tsty lda zpt,x + eor #$c3 + cmp zp1,x + trap_ne ;store to zp,x data + sty zpt,x ;clear + lda abst,x + eor #$c3 + cmp abs1,x + trap_ne ;store to abs,x data + txa + sta abst,x ;clear + dex + bpl tsty + next_test + +; indexed wraparound test (only zp should wrap) + ldx #3+$fa +tldy4 ldy zp1-$fa&$ff,x ;wrap on indexed zp + tya + sta abst-$fa,x ;no STX abs,x! + dex + cpx #$fa + bcs tldy4 + ldx #3+$fa +tldy5 ldy abs1-$fa,x ;no wrap on indexed abs + sty zpt-$fa&$ff,x + dex + cpx #$fa + bcs tldy5 + ldx #3 ;testing wraparound result + ldy #0 +tsty1 lda zpt,x + cmp zp1,x + trap_ne ;store to zp,x data + sty zpt,x ;clear + lda abst,x + cmp abs1,x + trap_ne ;store to abs,x data + txa + sta abst,x ;clear + dex + bpl tsty1 + next_test + +; LDX / STX - zp / abs / # + set_stat 0 + ldx zp1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$c3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldx zp1+1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+1 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$82 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldx zp1+2 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+2 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$41 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldx zp1+3 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+3 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #0 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldx zp1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$c3 ;test result + trap_ne ; + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldx zp1+1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+1 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$82 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldx zp1+2 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+2 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #$41 ;test result + trap_ne ; + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldx zp1+3 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx abst+3 + php ;flags after load/store sequence + eor #$c3 + tax + cpx #0 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + set_stat 0 + ldx abs1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt + php ;flags after load/store sequence + eor #$c3 + cmp zp1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldx abs1+1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+1 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldx abs1+2 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+2 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldx abs1+3 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+3 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldx abs1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt + php ;flags after load/store sequence + eor #$c3 + tax + cpx zp1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldx abs1+1 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+1 + php ;flags after load/store sequence + eor #$c3 + tax + cpx zp1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldx abs1+2 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+2 + php ;flags after load/store sequence + eor #$c3 + tax + cpx zp1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldx abs1+3 + php ;test stores do not alter flags + txa + eor #$c3 + tax + plp + stx zpt+3 + php ;flags after load/store sequence + eor #$c3 + tax + cpx zp1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + set_stat 0 + ldx #$c3 + php + cpx abs1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldx #$82 + php + cpx abs1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldx #$41 + php + cpx abs1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldx #0 + php + cpx abs1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldx #$c3 + php + cpx abs1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldx #$82 + php + cpx abs1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldx #$41 + php + cpx abs1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldx #0 + php + cpx abs1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + ldx #0 + lda zpt + eor #$c3 + cmp zp1 + trap_ne ;store to zp data + stx zpt ;clear + lda abst + eor #$c3 + cmp abs1 + trap_ne ;store to abs data + stx abst ;clear + lda zpt+1 + eor #$c3 + cmp zp1+1 + trap_ne ;store to zp data + stx zpt+1 ;clear + lda abst+1 + eor #$c3 + cmp abs1+1 + trap_ne ;store to abs data + stx abst+1 ;clear + lda zpt+2 + eor #$c3 + cmp zp1+2 + trap_ne ;store to zp data + stx zpt+2 ;clear + lda abst+2 + eor #$c3 + cmp abs1+2 + trap_ne ;store to abs data + stx abst+2 ;clear + lda zpt+3 + eor #$c3 + cmp zp1+3 + trap_ne ;store to zp data + stx zpt+3 ;clear + lda abst+3 + eor #$c3 + cmp abs1+3 + trap_ne ;store to abs data + stx abst+3 ;clear + next_test + +; LDY / STY - zp / abs / # + set_stat 0 + ldy zp1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$c3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldy zp1+1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+1 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$82 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldy zp1+2 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+2 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$41 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldy zp1+3 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+3 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #0 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldy zp1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$c3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldy zp1+1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+1 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$82 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldy zp1+2 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+2 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #$41 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldy zp1+3 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty abst+3 + php ;flags after load/store sequence + eor #$c3 + tay + cpy #0 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + set_stat 0 + ldy abs1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt + php ;flags after load/store sequence + eor #$c3 + tay + cpy zp1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldy abs1+1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+1 + php ;flags after load/store sequence + eor #$c3 + tay + cpy zp1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldy abs1+2 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+2 + php ;flags after load/store sequence + eor #$c3 + tay + cpy zp1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldy abs1+3 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+3 + php ;flags after load/store sequence + eor #$c3 + tay + cpy zp1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldy abs1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt + php ;flags after load/store sequence + eor #$c3 + tay + cmp zp1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldy abs1+1 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+1 + php ;flags after load/store sequence + eor #$c3 + tay + cmp zp1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldy abs1+2 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+2 + php ;flags after load/store sequence + eor #$c3 + tay + cmp zp1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldy abs1+3 + php ;test stores do not alter flags + tya + eor #$c3 + tay + plp + sty zpt+3 + php ;flags after load/store sequence + eor #$c3 + tay + cmp zp1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + + set_stat 0 + ldy #$c3 + php + cpy abs1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + ldy #$82 + php + cpy abs1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + ldy #$41 + php + cpy abs1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + ldy #0 + php + cpy abs1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + ldy #$c3 + php + cpy abs1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + ldy #$82 + php + cpy abs1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + ldy #$41 + php + cpy abs1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + ldy #0 + php + cpy abs1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + ldy #0 + lda zpt + eor #$c3 + cmp zp1 + trap_ne ;store to zp data + sty zpt ;clear + lda abst + eor #$c3 + cmp abs1 + trap_ne ;store to abs data + sty abst ;clear + lda zpt+1 + eor #$c3 + cmp zp1+1 + trap_ne ;store to zp+1 data + sty zpt+1 ;clear + lda abst+1 + eor #$c3 + cmp abs1+1 + trap_ne ;store to abs+1 data + sty abst+1 ;clear + lda zpt+2 + eor #$c3 + cmp zp1+2 + trap_ne ;store to zp+2 data + sty zpt+2 ;clear + lda abst+2 + eor #$c3 + cmp abs1+2 + trap_ne ;store to abs+2 data + sty abst+2 ;clear + lda zpt+3 + eor #$c3 + cmp zp1+3 + trap_ne ;store to zp+3 data + sty zpt+3 ;clear + lda abst+3 + eor #$c3 + cmp abs1+3 + trap_ne ;store to abs+3 data + sty abst+3 ;clear + next_test + +; testing load / store accumulator LDA / STA all addressing modes +; LDA / STA - zp,x / abs,x + ldx #3 +tldax + set_stat 0 + lda zp1,x + php ;test stores do not alter flags + eor #$c3 + plp + sta abst,x + php ;flags after load/store sequence + eor #$c3 + cmp abs1,x ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldax + + ldx #3 +tldax1 + set_stat $ff + lda zp1,x + php ;test stores do not alter flags + eor #$c3 + plp + sta abst,x + php ;flags after load/store sequence + eor #$c3 + cmp abs1,x ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldax1 + + ldx #3 +tldax2 + set_stat 0 + lda abs1,x + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt,x + php ;flags after load/store sequence + eor #$c3 + cmp zp1,x ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldax2 + + ldx #3 +tldax3 + set_stat $ff + lda abs1,x + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt,x + php ;flags after load/store sequence + eor #$c3 + cmp zp1,x ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,x ;test flags + trap_ne + dex + bpl tldax3 + + ldx #3 ;testing store result + ldy #0 +tstax lda zpt,x + eor #$c3 + cmp zp1,x + trap_ne ;store to zp,x data + sty zpt,x ;clear + lda abst,x + eor #$c3 + cmp abs1,x + trap_ne ;store to abs,x data + txa + sta abst,x ;clear + dex + bpl tstax + next_test + +; LDA / STA - (zp),y / abs,y / (zp,x) + ldy #3 +tlday + set_stat 0 + lda (ind1),y + php ;test stores do not alter flags + eor #$c3 + plp + sta abst,y + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,y ;test flags + trap_ne + dey + bpl tlday + + ldy #3 +tlday1 + set_stat $ff + lda (ind1),y + php ;test stores do not alter flags + eor #$c3 + plp + sta abst,y + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,y ;test flags + trap_ne + dey + bpl tlday1 + + ldy #3 ;testing store result + ldx #0 +tstay lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay + + ldy #3 +tlday2 + set_stat 0 + lda abs1,y + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt),y + php ;flags after load/store sequence + eor #$c3 + cmp (ind1),y ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,y ;test flags + trap_ne + dey + bpl tlday2 + + ldy #3 +tlday3 + set_stat $ff + lda abs1,y + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt),y + php ;flags after load/store sequence + eor #$c3 + cmp (ind1),y ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,y ;test flags + trap_ne + dey + bpl tlday3 + + ldy #3 ;testing store result + ldx #0 +tstay1 lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay1 + + ldx #6 + ldy #3 +tldax4 + set_stat 0 + lda (ind1,x) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt,x) + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx,y ;test flags + trap_ne + dex + dex + dey + bpl tldax4 + + ldx #6 + ldy #3 +tldax5 + set_stat $ff + lda (ind1,x) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt,x) + php ;flags after load/store sequence + eor #$c3 + cmp abs1,y ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx,y ;test flags + trap_ne + dex + dex + dey + bpl tldax5 + + ldy #3 ;testing store result + ldx #0 +tstay2 lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay2 + next_test + +; indexed wraparound test (only zp should wrap) + ldx #3+$fa +tldax6 lda zp1-$fa&$ff,x ;wrap on indexed zp + sta abst-$fa,x ;no STX abs,x! + dex + cpx #$fa + bcs tldax6 + ldx #3+$fa +tldax7 lda abs1-$fa,x ;no wrap on indexed abs + sta zpt-$fa&$ff,x + dex + cpx #$fa + bcs tldax7 + + ldx #3 ;testing wraparound result + ldy #0 +tstax1 lda zpt,x + cmp zp1,x + trap_ne ;store to zp,x data + sty zpt,x ;clear + lda abst,x + cmp abs1,x + trap_ne ;store to abs,x data + txa + sta abst,x ;clear + dex + bpl tstax1 + + ldy #3+$f8 + ldx #6+$f8 +tlday4 lda (ind1-$f8&$ff,x) ;wrap on indexed zp indirect + sta abst-$f8,y + dex + dex + dey + cpy #$f8 + bcs tlday4 + ldy #3 ;testing wraparound result + ldx #0 +tstay4 lda abst,y + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay4 + + ldy #3+$f8 +tlday5 lda abs1-$f8,y ;no wrap on indexed abs + sta (inwt),y + dey + cpy #$f8 + bcs tlday5 + ldy #3 ;testing wraparound result + ldx #0 +tstay5 lda abst,y + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay5 + + ldy #3+$f8 + ldx #6+$f8 +tlday6 lda (inw1),y ;no wrap on zp indirect indexed + sta (indt-$f8&$ff,x) + dex + dex + dey + cpy #$f8 + bcs tlday6 + ldy #3 ;testing wraparound result + ldx #0 +tstay6 lda abst,y + cmp abs1,y + trap_ne ;store to abs data + txa + sta abst,y ;clear + dey + bpl tstay6 + next_test + +; LDA / STA - zp / abs / # + set_stat 0 + lda zp1 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst + php ;flags after load/store sequence + eor #$c3 + cmp #$c3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + lda zp1+1 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+1 + php ;flags after load/store sequence + eor #$c3 + cmp #$82 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + lda zp1+2 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+2 + php ;flags after load/store sequence + eor #$c3 + cmp #$41 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + lda zp1+3 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+3 + php ;flags after load/store sequence + eor #$c3 + cmp #0 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + set_stat $ff + lda zp1 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst + php ;flags after load/store sequence + eor #$c3 + cmp #$c3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + lda zp1+1 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+1 + php ;flags after load/store sequence + eor #$c3 + cmp #$82 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + lda zp1+2 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+2 + php ;flags after load/store sequence + eor #$c3 + cmp #$41 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + lda zp1+3 + php ;test stores do not alter flags + eor #$c3 + plp + sta abst+3 + php ;flags after load/store sequence + eor #$c3 + cmp #0 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + set_stat 0 + lda abs1 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt + php ;flags after load/store sequence + eor #$c3 + cmp zp1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + lda abs1+1 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+1 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + lda abs1+2 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+2 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + lda abs1+3 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+3 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + set_stat $ff + lda abs1 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt + php ;flags after load/store sequence + eor #$c3 + cmp zp1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + lda abs1+1 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+1 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + lda abs1+2 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+2 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + lda abs1+3 + php ;test stores do not alter flags + eor #$c3 + plp + sta zpt+3 + php ;flags after load/store sequence + eor #$c3 + cmp zp1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + set_stat 0 + lda #$c3 + php + cmp abs1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + lda #$82 + php + cmp abs1+1 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + lda #$41 + php + cmp abs1+2 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + lda #0 + php + cmp abs1+3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + + set_stat $ff + lda #$c3 + php + cmp abs1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + lda #$82 + php + cmp abs1+1 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + lda #$41 + php + cmp abs1+2 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + lda #0 + php + cmp abs1+3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + + ldx #0 + lda zpt + eor #$c3 + cmp zp1 + trap_ne ;store to zp data + stx zpt ;clear + lda abst + eor #$c3 + cmp abs1 + trap_ne ;store to abs data + stx abst ;clear + lda zpt+1 + eor #$c3 + cmp zp1+1 + trap_ne ;store to zp data + stx zpt+1 ;clear + lda abst+1 + eor #$c3 + cmp abs1+1 + trap_ne ;store to abs data + stx abst+1 ;clear + lda zpt+2 + eor #$c3 + cmp zp1+2 + trap_ne ;store to zp data + stx zpt+2 ;clear + lda abst+2 + eor #$c3 + cmp abs1+2 + trap_ne ;store to abs data + stx abst+2 ;clear + lda zpt+3 + eor #$c3 + cmp zp1+3 + trap_ne ;store to zp data + stx zpt+3 ;clear + lda abst+3 + eor #$c3 + cmp abs1+3 + trap_ne ;store to abs data + stx abst+3 ;clear + next_test + +; testing bit test & compares BIT CPX CPY CMP all addressing modes +; BIT - zp / abs + set_a $ff,0 + bit zp1+3 ;00 - should set Z / clear NV + tst_a $ff,fz + set_a 1,0 + bit zp1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,fv + set_a 1,0 + bit zp1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz + set_a 1,0 + bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv + + set_a $ff,$ff + bit zp1+3 ;00 - should set Z / clear NV + tst_a $ff,~fnv + set_a 1,$ff + bit zp1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz + set_a 1,$ff + bit zp1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv + set_a 1,$ff + bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz + + set_a $ff,0 + bit abs1+3 ;00 - should set Z / clear NV + tst_a $ff,fz + set_a 1,0 + bit abs1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,fv + set_a 1,0 + bit abs1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz + set_a 1,0 + bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv + + set_a $ff,$ff + bit abs1+3 ;00 - should set Z / clear NV + tst_a $ff,~fnv + set_a 1,$ff + bit abs1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz + set_a 1,$ff + bit abs1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv + set_a 1,$ff + bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz + next_test + +; CPX - zp / abs / # + set_x $80,0 + cpx zp7f + tst_stat fc + dex + cpx zp7f + tst_stat fzc + dex + cpx zp7f + tst_x $7e,fn + set_x $80,$ff + cpx zp7f + tst_stat ~fnz + dex + cpx zp7f + tst_stat ~fn + dex + cpx zp7f + tst_x $7e,~fzc + + set_x $80,0 + cpx abs7f + tst_stat fc + dex + cpx abs7f + tst_stat fzc + dex + cpx abs7f + tst_x $7e,fn + set_x $80,$ff + cpx abs7f + tst_stat ~fnz + dex + cpx abs7f + tst_stat ~fn + dex + cpx abs7f + tst_x $7e,~fzc + + set_x $80,0 + cpx #$7f + tst_stat fc + dex + cpx #$7f + tst_stat fzc + dex + cpx #$7f + tst_x $7e,fn + set_x $80,$ff + cpx #$7f + tst_stat ~fnz + dex + cpx #$7f + tst_stat ~fn + dex + cpx #$7f + tst_x $7e,~fzc + next_test + +; CPY - zp / abs / # + set_y $80,0 + cpy zp7f + tst_stat fc + dey + cpy zp7f + tst_stat fzc + dey + cpy zp7f + tst_y $7e,fn + set_y $80,$ff + cpy zp7f + tst_stat ~fnz + dey + cpy zp7f + tst_stat ~fn + dey + cpy zp7f + tst_y $7e,~fzc + + set_y $80,0 + cpy abs7f + tst_stat fc + dey + cpy abs7f + tst_stat fzc + dey + cpy abs7f + tst_y $7e,fn + set_y $80,$ff + cpy abs7f + tst_stat ~fnz + dey + cpy abs7f + tst_stat ~fn + dey + cpy abs7f + tst_y $7e,~fzc + + set_y $80,0 + cpy #$7f + tst_stat fc + dey + cpy #$7f + tst_stat fzc + dey + cpy #$7f + tst_y $7e,fn + set_y $80,$ff + cpy #$7f + tst_stat ~fnz + dey + cpy #$7f + tst_stat ~fn + dey + cpy #$7f + tst_y $7e,~fzc + next_test + +; CMP - zp / abs / # + set_a $80,0 + cmp zp7f + tst_a $80,fc + set_a $7f,0 + cmp zp7f + tst_a $7f,fzc + set_a $7e,0 + cmp zp7f + tst_a $7e,fn + set_a $80,$ff + cmp zp7f + tst_a $80,~fnz + set_a $7f,$ff + cmp zp7f + tst_a $7f,~fn + set_a $7e,$ff + cmp zp7f + tst_a $7e,~fzc + + set_a $80,0 + cmp abs7f + tst_a $80,fc + set_a $7f,0 + cmp abs7f + tst_a $7f,fzc + set_a $7e,0 + cmp abs7f + tst_a $7e,fn + set_a $80,$ff + cmp abs7f + tst_a $80,~fnz + set_a $7f,$ff + cmp abs7f + tst_a $7f,~fn + set_a $7e,$ff + cmp abs7f + tst_a $7e,~fzc + + set_a $80,0 + cmp #$7f + tst_a $80,fc + set_a $7f,0 + cmp #$7f + tst_a $7f,fzc + set_a $7e,0 + cmp #$7f + tst_a $7e,fn + set_a $80,$ff + cmp #$7f + tst_a $80,~fnz + set_a $7f,$ff + cmp #$7f + tst_a $7f,~fn + set_a $7e,$ff + cmp #$7f + tst_a $7e,~fzc + + ldx #4 ;with indexing by X + set_a $80,0 + cmp zp1,x + tst_a $80,fc + set_a $7f,0 + cmp zp1,x + tst_a $7f,fzc + set_a $7e,0 + cmp zp1,x + tst_a $7e,fn + set_a $80,$ff + cmp zp1,x + tst_a $80,~fnz + set_a $7f,$ff + cmp zp1,x + tst_a $7f,~fn + set_a $7e,$ff + cmp zp1,x + tst_a $7e,~fzc + + set_a $80,0 + cmp abs1,x + tst_a $80,fc + set_a $7f,0 + cmp abs1,x + tst_a $7f,fzc + set_a $7e,0 + cmp abs1,x + tst_a $7e,fn + set_a $80,$ff + cmp abs1,x + tst_a $80,~fnz + set_a $7f,$ff + cmp abs1,x + tst_a $7f,~fn + set_a $7e,$ff + cmp abs1,x + tst_a $7e,~fzc + + ldy #4 ;with indexing by Y + ldx #8 ;with indexed indirect + set_a $80,0 + cmp abs1,y + tst_a $80,fc + set_a $7f,0 + cmp abs1,y + tst_a $7f,fzc + set_a $7e,0 + cmp abs1,y + tst_a $7e,fn + set_a $80,$ff + cmp abs1,y + tst_a $80,~fnz + set_a $7f,$ff + cmp abs1,y + tst_a $7f,~fn + set_a $7e,$ff + cmp abs1,y + tst_a $7e,~fzc + + set_a $80,0 + cmp (ind1,x) + tst_a $80,fc + set_a $7f,0 + cmp (ind1,x) + tst_a $7f,fzc + set_a $7e,0 + cmp (ind1,x) + tst_a $7e,fn + set_a $80,$ff + cmp (ind1,x) + tst_a $80,~fnz + set_a $7f,$ff + cmp (ind1,x) + tst_a $7f,~fn + set_a $7e,$ff + cmp (ind1,x) + tst_a $7e,~fzc + + set_a $80,0 + cmp (ind1),y + tst_a $80,fc + set_a $7f,0 + cmp (ind1),y + tst_a $7f,fzc + set_a $7e,0 + cmp (ind1),y + tst_a $7e,fn + set_a $80,$ff + cmp (ind1),y + tst_a $80,~fnz + set_a $7f,$ff + cmp (ind1),y + tst_a $7f,~fn + set_a $7e,$ff + cmp (ind1),y + tst_a $7e,~fzc + next_test + +; testing shifts - ASL LSR ROL ROR all addressing modes +; shifts - accumulator + ldx #3 +tasl + set_ax zp1,0 + asl a + tst_ax rASL,fASL,0 + dex + bpl tasl + ldx #3 +tasl1 + set_ax zp1,$ff + asl a + tst_ax rASL,fASL,$ff-fnzc + dex + bpl tasl1 + + ldx #3 +tlsr + set_ax zp1,0 + lsr a + tst_ax rLSR,fLSR,0 + dex + bpl tlsr + ldx #3 +tlsr1 + set_ax zp1,$ff + lsr a + tst_ax rLSR,fLSR,$ff-fnzc + dex + bpl tlsr1 + + ldx #3 +trol + set_ax zp1,0 + rol a + tst_ax rROL,fROL,0 + dex + bpl trol + ldx #3 +trol1 + set_ax zp1,$ff-fc + rol a + tst_ax rROL,fROL,$ff-fnzc + dex + bpl trol1 + + ldx #3 +trolc + set_ax zp1,fc + rol a + tst_ax rROLc,fROLc,0 + dex + bpl trolc + ldx #3 +trolc1 + set_ax zp1,$ff + rol a + tst_ax rROLc,fROLc,$ff-fnzc + dex + bpl trolc1 + + ldx #3 +tror + set_ax zp1,0 + ror a + tst_ax rROR,fROR,0 + dex + bpl tror + ldx #3 +tror1 + set_ax zp1,$ff-fc + ror a + tst_ax rROR,fROR,$ff-fnzc + dex + bpl tror1 + + ldx #3 +trorc + set_ax zp1,fc + ror a + tst_ax rRORc,fRORc,0 + dex + bpl trorc + ldx #3 +trorc1 + set_ax zp1,$ff + ror a + tst_ax rRORc,fRORc,$ff-fnzc + dex + bpl trorc1 + next_test + +; shifts - zeropage + ldx #3 +tasl2 + set_z zp1,0 + asl zpt + tst_z rASL,fASL,0 + dex + bpl tasl2 + ldx #3 +tasl3 + set_z zp1,$ff + asl zpt + tst_z rASL,fASL,$ff-fnzc + dex + bpl tasl3 + + ldx #3 +tlsr2 + set_z zp1,0 + lsr zpt + tst_z rLSR,fLSR,0 + dex + bpl tlsr2 + ldx #3 +tlsr3 + set_z zp1,$ff + lsr zpt + tst_z rLSR,fLSR,$ff-fnzc + dex + bpl tlsr3 + + ldx #3 +trol2 + set_z zp1,0 + rol zpt + tst_z rROL,fROL,0 + dex + bpl trol2 + ldx #3 +trol3 + set_z zp1,$ff-fc + rol zpt + tst_z rROL,fROL,$ff-fnzc + dex + bpl trol3 + + ldx #3 +trolc2 + set_z zp1,fc + rol zpt + tst_z rROLc,fROLc,0 + dex + bpl trolc2 + ldx #3 +trolc3 + set_z zp1,$ff + rol zpt + tst_z rROLc,fROLc,$ff-fnzc + dex + bpl trolc3 + + ldx #3 +tror2 + set_z zp1,0 + ror zpt + tst_z rROR,fROR,0 + dex + bpl tror2 + ldx #3 +tror3 + set_z zp1,$ff-fc + ror zpt + tst_z rROR,fROR,$ff-fnzc + dex + bpl tror3 + + ldx #3 +trorc2 + set_z zp1,fc + ror zpt + tst_z rRORc,fRORc,0 + dex + bpl trorc2 + ldx #3 +trorc3 + set_z zp1,$ff + ror zpt + tst_z rRORc,fRORc,$ff-fnzc + dex + bpl trorc3 + next_test + +; shifts - absolute + ldx #3 +tasl4 + set_abs zp1,0 + asl abst + tst_abs rASL,fASL,0 + dex + bpl tasl4 + ldx #3 +tasl5 + set_abs zp1,$ff + asl abst + tst_abs rASL,fASL,$ff-fnzc + dex + bpl tasl5 + + ldx #3 +tlsr4 + set_abs zp1,0 + lsr abst + tst_abs rLSR,fLSR,0 + dex + bpl tlsr4 + ldx #3 +tlsr5 + set_abs zp1,$ff + lsr abst + tst_abs rLSR,fLSR,$ff-fnzc + dex + bpl tlsr5 + + ldx #3 +trol4 + set_abs zp1,0 + rol abst + tst_abs rROL,fROL,0 + dex + bpl trol4 + ldx #3 +trol5 + set_abs zp1,$ff-fc + rol abst + tst_abs rROL,fROL,$ff-fnzc + dex + bpl trol5 + + ldx #3 +trolc4 + set_abs zp1,fc + rol abst + tst_abs rROLc,fROLc,0 + dex + bpl trolc4 + ldx #3 +trolc5 + set_abs zp1,$ff + rol abst + tst_abs rROLc,fROLc,$ff-fnzc + dex + bpl trolc5 + + ldx #3 +tror4 + set_abs zp1,0 + ror abst + tst_abs rROR,fROR,0 + dex + bpl tror4 + ldx #3 +tror5 + set_abs zp1,$ff-fc + ror abst + tst_abs rROR,fROR,$ff-fnzc + dex + bpl tror5 + + ldx #3 +trorc4 + set_abs zp1,fc + ror abst + tst_abs rRORc,fRORc,0 + dex + bpl trorc4 + ldx #3 +trorc5 + set_abs zp1,$ff + ror abst + tst_abs rRORc,fRORc,$ff-fnzc + dex + bpl trorc5 + next_test + +; shifts - zp indexed + ldx #3 +tasl6 + set_zx zp1,0 + asl zpt,x + tst_zx rASL,fASL,0 + dex + bpl tasl6 + ldx #3 +tasl7 + set_zx zp1,$ff + asl zpt,x + tst_zx rASL,fASL,$ff-fnzc + dex + bpl tasl7 + + ldx #3 +tlsr6 + set_zx zp1,0 + lsr zpt,x + tst_zx rLSR,fLSR,0 + dex + bpl tlsr6 + ldx #3 +tlsr7 + set_zx zp1,$ff + lsr zpt,x + tst_zx rLSR,fLSR,$ff-fnzc + dex + bpl tlsr7 + + ldx #3 +trol6 + set_zx zp1,0 + rol zpt,x + tst_zx rROL,fROL,0 + dex + bpl trol6 + ldx #3 +trol7 + set_zx zp1,$ff-fc + rol zpt,x + tst_zx rROL,fROL,$ff-fnzc + dex + bpl trol7 + + ldx #3 +trolc6 + set_zx zp1,fc + rol zpt,x + tst_zx rROLc,fROLc,0 + dex + bpl trolc6 + ldx #3 +trolc7 + set_zx zp1,$ff + rol zpt,x + tst_zx rROLc,fROLc,$ff-fnzc + dex + bpl trolc7 + + ldx #3 +tror6 + set_zx zp1,0 + ror zpt,x + tst_zx rROR,fROR,0 + dex + bpl tror6 + ldx #3 +tror7 + set_zx zp1,$ff-fc + ror zpt,x + tst_zx rROR,fROR,$ff-fnzc + dex + bpl tror7 + + ldx #3 +trorc6 + set_zx zp1,fc + ror zpt,x + tst_zx rRORc,fRORc,0 + dex + bpl trorc6 + ldx #3 +trorc7 + set_zx zp1,$ff + ror zpt,x + tst_zx rRORc,fRORc,$ff-fnzc + dex + bpl trorc7 + next_test + +; shifts - abs indexed + ldx #3 +tasl8 + set_absx zp1,0 + asl abst,x + tst_absx rASL,fASL,0 + dex + bpl tasl8 + ldx #3 +tasl9 + set_absx zp1,$ff + asl abst,x + tst_absx rASL,fASL,$ff-fnzc + dex + bpl tasl9 + + ldx #3 +tlsr8 + set_absx zp1,0 + lsr abst,x + tst_absx rLSR,fLSR,0 + dex + bpl tlsr8 + ldx #3 +tlsr9 + set_absx zp1,$ff + lsr abst,x + tst_absx rLSR,fLSR,$ff-fnzc + dex + bpl tlsr9 + + ldx #3 +trol8 + set_absx zp1,0 + rol abst,x + tst_absx rROL,fROL,0 + dex + bpl trol8 + ldx #3 +trol9 + set_absx zp1,$ff-fc + rol abst,x + tst_absx rROL,fROL,$ff-fnzc + dex + bpl trol9 + + ldx #3 +trolc8 + set_absx zp1,fc + rol abst,x + tst_absx rROLc,fROLc,0 + dex + bpl trolc8 + ldx #3 +trolc9 + set_absx zp1,$ff + rol abst,x + tst_absx rROLc,fROLc,$ff-fnzc + dex + bpl trolc9 + + ldx #3 +tror8 + set_absx zp1,0 + ror abst,x + tst_absx rROR,fROR,0 + dex + bpl tror8 + ldx #3 +tror9 + set_absx zp1,$ff-fc + ror abst,x + tst_absx rROR,fROR,$ff-fnzc + dex + bpl tror9 + + ldx #3 +trorc8 + set_absx zp1,fc + ror abst,x + tst_absx rRORc,fRORc,0 + dex + bpl trorc8 + ldx #3 +trorc9 + set_absx zp1,$ff + ror abst,x + tst_absx rRORc,fRORc,$ff-fnzc + dex + bpl trorc9 + next_test + +; testing memory increment/decrement - INC DEC all addressing modes +; zeropage + ldx #0 + lda #$7e + sta zpt +tinc + set_stat 0 + inc zpt + tst_z rINC,fINC,0 + inx + cpx #2 + bne tinc1 + lda #$fe + sta zpt +tinc1 cpx #5 + bne tinc + dex + inc zpt +tdec + set_stat 0 + dec zpt + tst_z rINC,fINC,0 + dex + bmi tdec1 + cpx #1 + bne tdec + lda #$81 + sta zpt + bne tdec +tdec1 + ldx #0 + lda #$7e + sta zpt +tinc10 + set_stat $ff + inc zpt + tst_z rINC,fINC,$ff-fnz + inx + cpx #2 + bne tinc11 + lda #$fe + sta zpt +tinc11 cpx #5 + bne tinc10 + dex + inc zpt +tdec10 + set_stat $ff + dec zpt + tst_z rINC,fINC,$ff-fnz + dex + bmi tdec11 + cpx #1 + bne tdec10 + lda #$81 + sta zpt + bne tdec10 +tdec11 + next_test + +; absolute memory + ldx #0 + lda #$7e + sta abst +tinc2 + set_stat 0 + inc abst + tst_abs rINC,fINC,0 + inx + cpx #2 + bne tinc3 + lda #$fe + sta abst +tinc3 cpx #5 + bne tinc2 + dex + inc abst +tdec2 + set_stat 0 + dec abst + tst_abs rINC,fINC,0 + dex + bmi tdec3 + cpx #1 + bne tdec2 + lda #$81 + sta abst + bne tdec2 +tdec3 + ldx #0 + lda #$7e + sta abst +tinc12 + set_stat $ff + inc abst + tst_abs rINC,fINC,$ff-fnz + inx + cpx #2 + bne tinc13 + lda #$fe + sta abst +tinc13 cpx #5 + bne tinc12 + dex + inc abst +tdec12 + set_stat $ff + dec abst + tst_abs rINC,fINC,$ff-fnz + dex + bmi tdec13 + cpx #1 + bne tdec12 + lda #$81 + sta abst + bne tdec12 +tdec13 + next_test + +; zeropage indexed + ldx #0 + lda #$7e +tinc4 sta zpt,x + set_stat 0 + inc zpt,x + tst_zx rINC,fINC,0 + lda zpt,x + inx + cpx #2 + bne tinc5 + lda #$fe +tinc5 cpx #5 + bne tinc4 + dex + lda #2 +tdec4 sta zpt,x + set_stat 0 + dec zpt,x + tst_zx rINC,fINC,0 + lda zpt,x + dex + bmi tdec5 + cpx #1 + bne tdec4 + lda #$81 + bne tdec4 +tdec5 + ldx #0 + lda #$7e +tinc14 sta zpt,x + set_stat $ff + inc zpt,x + tst_zx rINC,fINC,$ff-fnz + lda zpt,x + inx + cpx #2 + bne tinc15 + lda #$fe +tinc15 cpx #5 + bne tinc14 + dex + lda #2 +tdec14 sta zpt,x + set_stat $ff + dec zpt,x + tst_zx rINC,fINC,$ff-fnz + lda zpt,x + dex + bmi tdec15 + cpx #1 + bne tdec14 + lda #$81 + bne tdec14 +tdec15 + next_test + +; memory indexed + ldx #0 + lda #$7e +tinc6 sta abst,x + set_stat 0 + inc abst,x + tst_absx rINC,fINC,0 + lda abst,x + inx + cpx #2 + bne tinc7 + lda #$fe +tinc7 cpx #5 + bne tinc6 + dex + lda #2 +tdec6 sta abst,x + set_stat 0 + dec abst,x + tst_absx rINC,fINC,0 + lda abst,x + dex + bmi tdec7 + cpx #1 + bne tdec6 + lda #$81 + bne tdec6 +tdec7 + ldx #0 + lda #$7e +tinc16 sta abst,x + set_stat $ff + inc abst,x + tst_absx rINC,fINC,$ff-fnz + lda abst,x + inx + cpx #2 + bne tinc17 + lda #$fe +tinc17 cpx #5 + bne tinc16 + dex + lda #2 +tdec16 sta abst,x + set_stat $ff + dec abst,x + tst_absx rINC,fINC,$ff-fnz + lda abst,x + dex + bmi tdec17 + cpx #1 + bne tdec16 + lda #$81 + bne tdec16 +tdec17 + next_test + +; testing logical instructions - AND EOR ORA all addressing modes +; AND + ldx #3 ;immediate +tand lda zpAN,x + sta ex_andi+1 ;set AND # operand + set_ax absANa,0 + jsr ex_andi ;execute AND # in RAM + tst_ax absrlo,absflo,0 + dex + bpl tand + ldx #3 +tand1 lda zpAN,x + sta ex_andi+1 ;set AND # operand + set_ax absANa,$ff + jsr ex_andi ;execute AND # in RAM + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tand1 + + ldx #3 ;zp +tand2 lda zpAN,x + sta zpt + set_ax absANa,0 + and zpt + tst_ax absrlo,absflo,0 + dex + bpl tand2 + ldx #3 +tand3 lda zpAN,x + sta zpt + set_ax absANa,$ff + and zpt + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tand3 + + ldx #3 ;abs +tand4 lda zpAN,x + sta abst + set_ax absANa,0 + and abst + tst_ax absrlo,absflo,0 + dex + bpl tand4 + ldx #3 +tand5 lda zpAN,x + sta abst + set_ax absANa,$ff + and abst + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tand6 + + ldx #3 ;zp,x +tand6 + set_ax absANa,0 + and zpAN,x + tst_ax absrlo,absflo,0 + dex + bpl tand6 + ldx #3 +tand7 + set_ax absANa,$ff + and zpAN,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tand7 + + ldx #3 ;abs,x +tand8 + set_ax absANa,0 + and absAN,x + tst_ax absrlo,absflo,0 + dex + bpl tand8 + ldx #3 +tand9 + set_ax absANa,$ff + and absAN,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tand9 + + ldy #3 ;abs,y +tand10 + set_ay absANa,0 + and absAN,y + tst_ay absrlo,absflo,0 + dey + bpl tand10 + ldy #3 +tand11 + set_ay absANa,$ff + and absAN,y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl tand11 + + ldx #6 ;(zp,x) + ldy #3 +tand12 + set_ay absANa,0 + and (indAN,x) + tst_ay absrlo,absflo,0 + dex + dex + dey + bpl tand12 + ldx #6 + ldy #3 +tand13 + set_ay absANa,$ff + and (indAN,x) + tst_ay absrlo,absflo,$ff-fnz + dex + dex + dey + bpl tand13 + + ldy #3 ;(zp),y +tand14 + set_ay absANa,0 + and (indAN),y + tst_ay absrlo,absflo,0 + dey + bpl tand14 + ldy #3 +tand15 + set_ay absANa,$ff + and (indAN),y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl tand15 + next_test + +; EOR + ldx #3 ;immediate - self modifying code +teor lda zpEO,x + sta ex_eori+1 ;set EOR # operand + set_ax absEOa,0 + jsr ex_eori ;execute EOR # in RAM + tst_ax absrlo,absflo,0 + dex + bpl teor + ldx #3 +teor1 lda zpEO,x + sta ex_eori+1 ;set EOR # operand + set_ax absEOa,$ff + jsr ex_eori ;execute EOR # in RAM + tst_ax absrlo,absflo,$ff-fnz + dex + bpl teor1 + + ldx #3 ;zp +teor2 lda zpEO,x + sta zpt + set_ax absEOa,0 + eor zpt + tst_ax absrlo,absflo,0 + dex + bpl teor2 + ldx #3 +teor3 lda zpEO,x + sta zpt + set_ax absEOa,$ff + eor zpt + tst_ax absrlo,absflo,$ff-fnz + dex + bpl teor3 + + ldx #3 ;abs +teor4 lda zpEO,x + sta abst + set_ax absEOa,0 + eor abst + tst_ax absrlo,absflo,0 + dex + bpl teor4 + ldx #3 +teor5 lda zpEO,x + sta abst + set_ax absEOa,$ff + eor abst + tst_ax absrlo,absflo,$ff-fnz + dex + bpl teor6 + + ldx #3 ;zp,x +teor6 + set_ax absEOa,0 + eor zpEO,x + tst_ax absrlo,absflo,0 + dex + bpl teor6 + ldx #3 +teor7 + set_ax absEOa,$ff + eor zpEO,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl teor7 + + ldx #3 ;abs,x +teor8 + set_ax absEOa,0 + eor absEO,x + tst_ax absrlo,absflo,0 + dex + bpl teor8 + ldx #3 +teor9 + set_ax absEOa,$ff + eor absEO,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl teor9 + + ldy #3 ;abs,y +teor10 + set_ay absEOa,0 + eor absEO,y + tst_ay absrlo,absflo,0 + dey + bpl teor10 + ldy #3 +teor11 + set_ay absEOa,$ff + eor absEO,y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl teor11 + + ldx #6 ;(zp,x) + ldy #3 +teor12 + set_ay absEOa,0 + eor (indEO,x) + tst_ay absrlo,absflo,0 + dex + dex + dey + bpl teor12 + ldx #6 + ldy #3 +teor13 + set_ay absEOa,$ff + eor (indEO,x) + tst_ay absrlo,absflo,$ff-fnz + dex + dex + dey + bpl teor13 + + ldy #3 ;(zp),y +teor14 + set_ay absEOa,0 + eor (indEO),y + tst_ay absrlo,absflo,0 + dey + bpl teor14 + ldy #3 +teor15 + set_ay absEOa,$ff + eor (indEO),y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl teor15 + next_test + +; OR + ldx #3 ;immediate - self modifying code +tora lda zpOR,x + sta ex_orai+1 ;set ORA # operand + set_ax absORa,0 + jsr ex_orai ;execute ORA # in RAM + tst_ax absrlo,absflo,0 + dex + bpl tora + ldx #3 +tora1 lda zpOR,x + sta ex_orai+1 ;set ORA # operand + set_ax absORa,$ff + jsr ex_orai ;execute ORA # in RAM + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tora1 + + ldx #3 ;zp +tora2 lda zpOR,x + sta zpt + set_ax absORa,0 + ora zpt + tst_ax absrlo,absflo,0 + dex + bpl tora2 + ldx #3 +tora3 lda zpOR,x + sta zpt + set_ax absORa,$ff + ora zpt + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tora3 + + ldx #3 ;abs +tora4 lda zpOR,x + sta abst + set_ax absORa,0 + ora abst + tst_ax absrlo,absflo,0 + dex + bpl tora4 + ldx #3 +tora5 lda zpOR,x + sta abst + set_ax absORa,$ff + ora abst + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tora6 + + ldx #3 ;zp,x +tora6 + set_ax absORa,0 + ora zpOR,x + tst_ax absrlo,absflo,0 + dex + bpl tora6 + ldx #3 +tora7 + set_ax absORa,$ff + ora zpOR,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tora7 + + ldx #3 ;abs,x +tora8 + set_ax absORa,0 + ora absOR,x + tst_ax absrlo,absflo,0 + dex + bpl tora8 + ldx #3 +tora9 + set_ax absORa,$ff + ora absOR,x + tst_ax absrlo,absflo,$ff-fnz + dex + bpl tora9 + + ldy #3 ;abs,y +tora10 + set_ay absORa,0 + ora absOR,y + tst_ay absrlo,absflo,0 + dey + bpl tora10 + ldy #3 +tora11 + set_ay absORa,$ff + ora absOR,y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl tora11 + + ldx #6 ;(zp,x) + ldy #3 +tora12 + set_ay absORa,0 + ora (indOR,x) + tst_ay absrlo,absflo,0 + dex + dex + dey + bpl tora12 + ldx #6 + ldy #3 +tora13 + set_ay absORa,$ff + ora (indOR,x) + tst_ay absrlo,absflo,$ff-fnz + dex + dex + dey + bpl tora13 + + ldy #3 ;(zp),y +tora14 + set_ay absORa,0 + ora (indOR),y + tst_ay absrlo,absflo,0 + dey + bpl tora14 + ldy #3 +tora15 + set_ay absORa,$ff + ora (indOR),y + tst_ay absrlo,absflo,$ff-fnz + dey + bpl tora15 + if I_flag = 3 + cli + endif + next_test + +; full binary add/subtract test +; iterates through all combinations of operands and carry input +; uses increments/decrements to predict result & result flags + cld + ldx #ad2 ;for indexed test + ldy #$ff ;max range + lda #0 ;start with adding zeroes & no carry + sta adfc ;carry in - for diag + sta ad1 ;operand 1 - accumulator + sta ad2 ;operand 2 - memory or immediate + sta ada2 ;non zp + sta adrl ;expected result bits 0-7 + sta adrh ;expected result bit 8 (carry out) + lda #$ff ;complemented operand 2 for subtract + sta sb2 + sta sba2 ;non zp + lda #2 ;expected Z-flag + sta adrf +tadd clc ;test with carry clear + jsr chkadd + inc adfc ;now with carry + inc adrl ;result +1 + php ;save N & Z from low result + php + pla ;accu holds expected flags + and #$82 ;mask N & Z + plp + bne tadd1 + inc adrh ;result bit 8 - carry +tadd1 ora adrh ;merge C to expected flags + sta adrf ;save expected flags except overflow + sec ;test with carry set + jsr chkadd + dec adfc ;same for operand +1 but no carry + inc ad1 + bne tadd ;iterate op1 + lda #0 ;preset result to op2 when op1 = 0 + sta adrh + inc ada2 + inc ad2 + php ;save NZ as operand 2 becomes the new result + pla + and #$82 ;mask N00000Z0 + sta adrf ;no need to check carry as we are adding to 0 + dec sb2 ;complement subtract operand 2 + dec sba2 + lda ad2 + sta adrl + bne tadd ;iterate op2 + if disable_decimal < 1 + next_test + +; decimal add/subtract test +; *** WARNING - tests documented behavior only! *** +; only valid BCD operands are tested, N V Z flags are ignored +; iterates through all valid combinations of operands and carry input +; uses increments/decrements to predict result & carry flag + sed + ldx #ad2 ;for indexed test + ldy #$ff ;max range + lda #$99 ;start with adding 99 to 99 with carry + sta ad1 ;operand 1 - accumulator + sta ad2 ;operand 2 - memory or immediate + sta ada2 ;non zp + sta adrl ;expected result bits 0-7 + lda #1 ;set carry in & out + sta adfc ;carry in - for diag + sta adrh ;expected result bit 8 (carry out) + lda #0 ;complemented operand 2 for subtract + sta sb2 + sta sba2 ;non zp +tdad sec ;test with carry set + jsr chkdad + dec adfc ;now with carry clear + lda adrl ;decimal adjust result + bne tdad1 ;skip clear carry & preset result 99 (9A-1) + dec adrh + lda #$99 + sta adrl + bne tdad3 +tdad1 and #$f ;lower nibble mask + bne tdad2 ;no decimal adjust needed + dec adrl ;decimal adjust (?0-6) + dec adrl + dec adrl + dec adrl + dec adrl + dec adrl +tdad2 dec adrl ;result -1 +tdad3 clc ;test with carry clear + jsr chkdad + inc adfc ;same for operand -1 but with carry + lda ad1 ;decimal adjust operand 1 + beq tdad5 ;iterate operand 2 + and #$f ;lower nibble mask + bne tdad4 ;skip decimal adjust + dec ad1 ;decimal adjust (?0-6) + dec ad1 + dec ad1 + dec ad1 + dec ad1 + dec ad1 +tdad4 dec ad1 ;operand 1 -1 + jmp tdad ;iterate op1 + +tdad5 lda #$99 ;precharge op1 max + sta ad1 + lda ad2 ;decimal adjust operand 2 + beq tdad7 ;end of iteration + and #$f ;lower nibble mask + bne tdad6 ;skip decimal adjust + dec ad2 ;decimal adjust (?0-6) + dec ad2 + dec ad2 + dec ad2 + dec ad2 + dec ad2 + inc sb2 ;complemented decimal adjust for subtract (?9+6) + inc sb2 + inc sb2 + inc sb2 + inc sb2 + inc sb2 +tdad6 dec ad2 ;operand 2 -1 + inc sb2 ;complemented operand for subtract + lda sb2 + sta sba2 ;copy as non zp operand + lda ad2 + sta ada2 ;copy as non zp operand + sta adrl ;new result since op1+carry=00+carry +op2=op2 + inc adrh ;result carry + bne tdad ;iterate op2 +tdad7 + next_test + +; decimal/binary switch test +; tests CLD, SED, PLP, RTI to properly switch between decimal & binary opcode +; tables + clc + cld + php + lda #$55 + adc #$55 + cmp #$aa + trap_ne ;expected binary result after cld + clc + sed + php + lda #$55 + adc #$55 + cmp #$10 + trap_ne ;expected decimal result after sed + cld + plp + lda #$55 + adc #$55 + cmp #$10 + trap_ne ;expected decimal result after plp D=1 + plp + lda #$55 + adc #$55 + cmp #$aa + trap_ne ;expected binary result after plp D=0 + clc + lda #hi bin_rti_ret ;emulated interrupt for rti + pha + lda #lo bin_rti_ret + pha + php + sed + lda #hi dec_rti_ret ;emulated interrupt for rti + pha + lda #lo dec_rti_ret + pha + php + cld + rti +dec_rti_ret + lda #$55 + adc #$55 + cmp #$10 + trap_ne ;expected decimal result after rti D=1 + rti +bin_rti_ret + lda #$55 + adc #$55 + cmp #$aa + trap_ne ;expected binary result after rti D=0 + endif + + lda test_case + cmp #test_num + trap_ne ;previous test is out of sequence + lda #$f0 ;mark opcode testing complete + sta test_case + +; final RAM integrity test +; verifies that none of the previous tests has altered RAM outside of the +; designated write areas. + check_ram +; *** DEBUG INFO *** +; to debug checksum errors uncomment check_ram in the next_test macro to +; narrow down the responsible opcode. +; may give false errors when monitor, OS or other background activity is +; allowed during previous tests. + + +; S U C C E S S ************************************************ +; ------------- + success ;if you get here everything went well +; ------------- +; S U C C E S S ************************************************ + jmp start ;run again + + if disable_decimal < 1 +; core subroutine of the decimal add/subtract test +; *** WARNING - tests documented behavior only! *** +; only valid BCD operands are tested, N V Z flags are ignored +; iterates through all valid combinations of operands and carry input +; uses increments/decrements to predict result & carry flag +chkdad +; decimal ADC / SBC zp + php ;save carry for subtract + lda ad1 + adc ad2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc sb2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad flags + plp +; decimal ADC / SBC abs + php ;save carry for subtract + lda ad1 + adc ada2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc sba2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC # + php ;save carry for subtract + lda ad2 + sta ex_adci+1 ;set ADC # operand + lda ad1 + jsr ex_adci ;execute ADC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda sb2 + sta ex_sbci+1 ;set SBC # operand + lda ad1 + jsr ex_sbci ;execute SBC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC zp,x + php ;save carry for subtract + lda ad1 + adc 0,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc sb2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC abs,x + php ;save carry for subtract + lda ad1 + adc ada2-ad2,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc sba2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC abs,y + php ;save carry for subtract + lda ad1 + adc ada2-$ff,y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc sba2-$ff,y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC (zp,x) + php ;save carry for subtract + lda ad1 + adc (lo adi2-ad2,x) ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc (lo sbi2-ad2,x) ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp +; decimal ADC / SBC (abs),y + php ;save carry for subtract + lda ad1 + adc (adiy2),y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + php ;save carry for next add + lda ad1 + sbc (sbiy2),y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #1 ;mask carry + cmp adrh + trap_ne ;bad carry + plp + rts + endif + +; core subroutine of the full binary add/subtract test +; iterates through all combinations of operands and carry input +; uses increments/decrements to predict result & result flags +chkadd lda adrf ;add V-flag if overflow + and #$83 ;keep N-----ZC / clear V + pha + lda ad1 ;test sign unequal between operands + eor ad2 + bmi ckad1 ;no overflow possible - operands have different sign + lda ad1 ;test sign equal between operands and result + eor adrl + bpl ckad1 ;no overflow occured - operand and result have same sign + pla + ora #$40 ;set V + pha +ckad1 pla + sta adrf ;save expected flags +; binary ADC / SBC zp + php ;save carry for subtract + lda ad1 + adc ad2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sb2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC abs + php ;save carry for subtract + lda ad1 + adc ada2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC # + php ;save carry for subtract + lda ad2 + sta ex_adci+1 ;set ADC # operand + lda ad1 + jsr ex_adci ;execute ADC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda sb2 + sta ex_sbci+1 ;set SBC # operand + lda ad1 + jsr ex_sbci ;execute SBC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC zp,x + php ;save carry for subtract + lda ad1 + adc 0,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sb2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC abs,x + php ;save carry for subtract + lda ad1 + adc ada2-ad2,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC abs,y + php ;save carry for subtract + lda ad1 + adc ada2-$ff,y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2-$ff,y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC (zp,x) + php ;save carry for subtract + lda ad1 + adc (lo adi2-ad2,x) ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (lo sbi2-ad2,x) ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp +; binary ADC / SBC (abs),y + php ;save carry for subtract + lda ad1 + adc (adiy2),y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (sbiy2),y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + rts + +; target for the jump absolute test + dey + dey +test_far + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_cs ;flags loaded? + trap_vs + trap_mi + trap_eq + cmp #'F' ;registers loaded? + trap_ne + cpx #'A' + trap_ne + cpy #('R'-3) + trap_ne + pha ;save a,x + txa + pha + tsx + cpx #$fd ;check SP + trap_ne + pla ;restore x + tax + set_stat $ff + pla ;restore a + inx ;return registers with modifications + eor #$aa ;N=1, V=1, Z=0, C=1 + jmp far_ret + +; target for the jump indirect test + align +ptr_tst_ind dw test_ind +ptr_ind_ret dw ind_ret + trap ;runover protection + dey + dey +test_ind + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_cs ;flags loaded? + trap_vs + trap_mi + trap_eq + cmp #'I' ;registers loaded? + trap_ne + cpx #'N' + trap_ne + cpy #('D'-3) + trap_ne + pha ;save a,x + txa + pha + tsx + cpx #$fd ;check SP + trap_ne + pla ;restore x + tax + set_stat $ff + pla ;restore a + inx ;return registers with modifications + eor #$aa ;N=1, V=1, Z=0, C=1 + jmp (ptr_ind_ret) + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +; target for the jump subroutine test + dey + dey +test_jsr + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_cs ;flags loaded? + trap_vs + trap_mi + trap_eq + cmp #'J' ;registers loaded? + trap_ne + cpx #'S' + trap_ne + cpy #('R'-3) + trap_ne + pha ;save a,x + txa + pha + tsx ;sp -4? (return addr,a,x) + cpx #$fb + trap_ne + lda $1ff ;propper return on stack + cmp #hi(jsr_ret) + trap_ne + lda $1fe + cmp #lo(jsr_ret) + trap_ne + set_stat $ff + pla ;pull x,a + tax + pla + inx ;return registers with modifications + eor #$aa ;N=1, V=1, Z=0, C=1 + rts + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +;trap in case of unexpected IRQ, NMI, BRK, RESET - BRK test target +nmi_trap + trap ;check stack for conditions at NMI + jmp start ;catastrophic error - cannot continue +res_trap + trap ;unexpected RESET + jmp start ;catastrophic error - cannot continue + + dey + dey +irq_trap ;BRK test or unextpected BRK or IRQ + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + ;next traps could be caused by unexpected BRK or IRQ + ;check stack for BREAK and originating location + ;possible jump/branch into weeds (uninitialized space) + cmp #$ff-'B' ;BRK pass 2 registers loaded? + beq break2 + cmp #'B' ;BRK pass 1 registers loaded? + trap_ne + cpx #'R' + trap_ne + cpy #'K'-3 + trap_ne + sta irq_a ;save registers during break test + stx irq_x + tsx ;test break on stack + lda $102,x + cmp_flag 0 ;break test should have B=1 & unused=1 on stack + trap_ne ; - no break flag on stack + pla + cmp_flag intdis ;should have added interrupt disable + trap_ne + tsx + cpx #$fc ;sp -3? (return addr, flags) + trap_ne + lda $1ff ;propper return on stack + cmp #hi(brk_ret0) + trap_ne + lda $1fe + cmp #lo(brk_ret0) + trap_ne + load_flag $ff + pha + ldx irq_x + inx ;return registers with modifications + lda irq_a + eor #$aa + plp ;N=1, V=1, Z=1, C=1 but original flags should be restored + rti + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +break2 ;BRK pass 2 + cpx #$ff-'R' + trap_ne + cpy #$ff-'K'-3 + trap_ne + sta irq_a ;save registers during break test + stx irq_x + tsx ;test break on stack + lda $102,x + cmp_flag $ff ;break test should have B=1 + trap_ne ; - no break flag on stack + pla + ora #decmode ;ignore decmode cleared if 65c02 + cmp_flag $ff ;actual passed flags + trap_ne + tsx + cpx #$fc ;sp -3? (return addr, flags) + trap_ne + lda $1ff ;propper return on stack + cmp #hi(brk_ret1) + trap_ne + lda $1fe + cmp #lo(brk_ret1) + trap_ne + load_flag intdis + pha + ldx irq_x + inx ;return registers with modifications + lda irq_a + eor #$aa + plp ;N=0, V=0, Z=0, C=0 but original flags should be restored + rti + trap ;runover protection + jmp start ;catastrophic error - cannot continue + + if report = 1 + include "report.i65" + endif + +;copy of data to initialize BSS segment + if load_data_direct != 1 +zp_init +zp1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +zp7f_ db $7f ;test pattern for compare +;logical zeropage operands +zpOR_ db 0,$1f,$71,$80 ;test pattern for OR +zpAN_ db $0f,$ff,$7f,$80 ;test pattern for AND +zpEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR +;indirect addressing pointers +ind1_ dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f +inw1_ dw abs1-$f8 ;indirect pointer for wrap-test pattern +indt_ dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 +inwt_ dw abst-$f8 ;indirect pointer for wrap-test store +indAN_ dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 +indEO_ dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 +indOR_ dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 +;add/subtract indirect pointers +adi2_ dw ada2 ;indirect pointer to operand 2 in absolute memory +sbi2_ dw sba2 ;indirect pointer to complemented operand 2 (SBC) +adiy2_ dw ada2-$ff ;with offset for indirect indexed +sbiy2_ dw sba2-$ff +zp_end + if (zp_end - zp_init) != (zp_bss_end - zp_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and zeropage data + endif +data_init +ex_and_ and #0 ;execute immediate opcodes + rts +ex_eor_ eor #0 ;execute immediate opcodes + rts +ex_ora_ ora #0 ;execute immediate opcodes + rts +ex_adc_ adc #0 ;execute immediate opcodes + rts +ex_sbc_ sbc #0 ;execute immediate opcodes + rts +abs1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +abs7f_ db $7f ;test pattern for compare +;loads +fLDx_ db fn,fn,0,fz ;expected flags for load +;shifts +rASL_ ;expected result ASL & ROL -carry +rROL_ db $86,$04,$82,0 ; " +rROLc_ db $87,$05,$83,1 ;expected result ROL +carry +rLSR_ ;expected result LSR & ROR -carry +rROR_ db $61,$41,$20,0 ; " +rRORc_ db $e1,$c1,$a0,$80 ;expected result ROR +carry +fASL_ ;expected flags for shifts +fROL_ db fnc,fc,fn,fz ;no carry in +fROLc_ db fnc,fc,fn,0 ;carry in +fLSR_ +fROR_ db fc,0,fc,fz ;no carry in +fRORc_ db fnc,fn,fnc,fn ;carry in +;increments (decrements) +rINC_ db $7f,$80,$ff,0,1 ;expected result for INC/DEC +fINC_ db 0,fn,fn,fz,0 ;expected flags for INC/DEC +;logical memory operand +absOR_ db 0,$1f,$71,$80 ;test pattern for OR +absAN_ db $0f,$ff,$7f,$80 ;test pattern for AND +absEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR +;logical accu operand +absORa_ db 0,$f1,$1f,0 ;test pattern for OR +absANa_ db $f0,$ff,$ff,$ff ;test pattern for AND +absEOa_ db $ff,$f0,$f0,$0f ;test pattern for EOR +;logical results +absrlo_ db 0,$ff,$7f,$80 +absflo_ db fz,fn,0,fn +data_end + if (data_end - data_init) != (data_bss_end - data_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and data + endif + +vec_init + dw nmi_trap + dw res_trap + dw irq_trap +vec_bss equ $fffa + endif ;end of RAM init data + + if (load_data_direct = 1) & (ROM_vectors = 1) + org $fffa ;vectors + dw nmi_trap + dw res_trap + dw irq_trap + endif + + end start + \ No newline at end of file diff --git a/src/test/kotlin/6502_functional_tests/6502_interrupt_test.a65 b/src/test/kotlin/6502_functional_tests/6502_interrupt_test.a65 new file mode 100644 index 0000000..bfc3754 --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/6502_interrupt_test.a65 @@ -0,0 +1,1026 @@ +; +; 6 5 0 2 I N T E R R U P T T E S T +; +; Copyright (C) 2013 Klaus Dormann +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . + + +; This program is designed to test IRQ and NMI of a 6502 emulator. It requires +; an internal or external feedback register to the IRQ & NMI inputs +; +; version 15-aug-2014 +; contact info at http://2m5.de or email K@2m5.de +; +; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/ +; command line switches: -l -m -s2 -w -h0 +; | | | | no page headers in listing +; | | | wide listing (133 char/col) +; | | write intel hex file instead of binary +; | expand macros in listing +; generate pass2 listing +; +; No IO - should be run from a monitor with access to registers. +; To run load intel hex image with a load command, than alter PC to 400 hex and +; enter a go command. +; Loop on program counter determines error or successful completion of test. +; Check listing for relevant traps (jump/branch *). +; +; Debugging hints: +; Most of the code is written sequentially. if you hit a trap, check the +; immediately preceeding code for the instruction to be tested. Results are +; tested first, flags are checked second by pushing them onto the stack and +; pulling them to the accumulator after the result was checked. The "real" +; flags are no longer valid for the tested instruction at this time! +; If the tested instruction was indexed, the relevant index (X or Y) must +; also be checked. Opposed to the flags, X and Y registers are still valid. +; +; versions: +; 19-jul-2013 1st version distributed for testing +; 16-aug-2013 added error report to standard output option +; 15-aug-2014 added filter to feedback (bit 7 will cause diag stop in emu) + + +; C O N F I G U R A T I O N +; +;ROM_vectors MUST be writable & the I_flag MUST be alterable + +;load_data_direct (0=move from code segment, 1=load directly) +;loading directly is preferred but may not be supported by your platform +;0 produces only consecutive object code, 1 is not suitable for a binary image +load_data_direct = 1 + +;NMI & IRQ are tested with a feedback register +;emulators diag register - set i_drive = 0 for a latch (74HC573) +I_port = $bffc ;feedback port address +I_ddr = 0 ;feedback DDR address, 0 = no DDR +I_drive = 1 ;0 = totem pole, 1 = open collector +IRQ_bit = 0 ;bit number of feedback to IRQ +NMI_bit = 1 ;bit number of feedback to NMI, -1 if not available +I_filter = $7f ;filtering bit 7 = diag stop + +;typical IO chip port B - set i_drive = 0 to avoid pullup resistors +;I_port = $bfb2 ;feedback port address +;I_ddr = $bfb3 ;feedback DDR address, 0 = no DDR +;I_drive = 1 ;0 = totem pole, 1 = open collector +;IRQ_bit = 0 ;bit number of feedback to IRQ +;NMI_bit = 1 ;bit number of feedback to NMI, -1 if not available +;I_filter = $ff ;no bits filtered + +;decimal mode flag during IRQ, NMI & BRK +D_clear = 0 ;0 = not cleared (NMOS), 1 = cleared (CMOS) + +;configure memory - try to stay away from memory used by the system +;zero_page memory start address, 6 consecutive Bytes required +zero_page = $a + +;data_segment memory start address, 4 consecutive Bytes required +data_segment = $200 + +;code_segment memory start address +code_segment = $400 + +;report errors through I/O channel (0=use standard self trap loops, 1=include +;report.i65 as I/O channel) +report = 0 + + noopt ;do not take shortcuts + +;macros for error & success traps to allow user modification +;example: +;trap macro +; jsr my_error_handler +; endm +;trap_eq macro +; bne skip\? +; trap ;failed equal (zero) +;skip\? +; endm +; +; my_error_handler should pop the calling address from the stack and report it. +; putting larger portions of code (more than 3 bytes) inside the trap macro +; may lead to branch range problems for some tests. + if report = 0 +trap macro + jmp * ;failed anyway + endm +trap_eq macro + beq * ;failed equal (zero) + endm +trap_ne macro + bne * ;failed not equal (non zero) + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jmp * ;test passed, no errors + endm + endif + if report = 1 +trap macro + jsr report_error + endm +trap_eq macro + bne skip\? + trap ;failed equal (zero) +skip\? + endm +trap_ne macro + beq skip\? + trap ;failed not equal (non zero) +skip\? + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jsr report_success + endm + endif + + +carry equ %00000001 ;flag bits in status +zero equ %00000010 +intdis equ %00000100 +decmode equ %00001000 +break equ %00010000 +reserv equ %00100000 +overfl equ %01000000 +minus equ %10000000 + +fc equ carry +fz equ zero +fzc equ carry+zero +fv equ overfl +fvz equ overfl+zero +fn equ minus +fnc equ minus+carry +fnz equ minus+zero +fnzc equ minus+zero+carry +fnv equ minus+overfl + +fao equ break+reserv ;bits always on after PHP, BRK +fai equ fao+intdis ;+ forced interrupt disable +m8 equ $ff ;8 bit mask +m8i equ $ff&~intdis ;8 bit mask - interrupt disable + +;macros to set status +push_stat macro ;setting flags in the processor status register + lda #\1 + pha ;use stack to load status + endm + +set_stat macro ;setting flags in the processor status register + lda #\1 + pha ;use stack to load status + plp + endm + + if load_data_direct = 1 + data + else + bss ;uninitialized segment, copy of data at end of code! + endif + org zero_page +;BRK, IRQ, NMI test interrupt save +zpt +irq_a ds 1 ;a register +irq_x ds 1 ;x register +irq_f ds 1 ;flags +nmi_a ds 1 ;a register +nmi_x ds 1 ;x register +nmi_f ds 1 ;flags +zp_bss + +;fixed stack locations +lst_f equ $1fe ;last flags before interrupt +lst_a equ $1ff ;last accumulator before interrupt + + org data_segment +;concurrent NMI, IRQ & BRK test result +nmi_count ds 1 ;lowest number handled first, $ff = never +irq_count ds 1 ;separation-1 = instructions between interrupts +brk_count ds 1 +;expected interrupt mask +I_src ds 1 ;bit: 0=BRK, 1=IRQ, 2=NMI +data_bss + + code + org code_segment +start cld + lda #0 ;clear expected interrupts for 2nd run + sta I_src + ldx #$ff + txs + +;initialize I/O for report channel + if report = 1 + jsr report_init + endif + +; load system vectors + if load_data_direct != 1 + ldx #5 +ld_vect lda vec_init,x + sta vec_bss,x + dex + bpl ld_vect + endif + +; IRQ & NMI test - requires a feedback register + if I_drive > 1 + ERROR ;invalid interrupt drive! + endif + if NMI_bit < 0 + if I_drive = 0 ;totem pole (push/pull, 0 -> I_port to force interrupt) +I_set macro ibit ;ibit = interrupt bit + lda I_port ;turn on interrupt by bit + and #I_filter-(1<<\1) + plp ;set flags + pha ;save to verify + php + sta I_port ;interrupt next instruction plus outbound delay + endm +I_clr macro ibit ;ibit = interrupt bit + lda I_port ;turn off interrupt by bit + and #I_filter + ora #(1< I_DDR or I_port to force interrupt + if I_ddr != 0 ;with DDR +I_set macro ibit ;ibit = interrupt bit + lda I_ddr ;turn on interrupt by bit + and #I_filter + ora #(1<<\1) + plp ;set flags + pha ;save to verify + php + sta I_ddr ;interrupt next instruction plus outbound delay + endm +I_clr macro ibit ;ibit = interrupt bit + lda I_ddr ;turn off interrupt by bit + and #I_filter-(1< I_port to force interrupt) +I_set macro ibit ;ibit = interrupt bit + lda I_port ;turn on interrupt by bit + if ibit > 7 ;set both NMI & IRQ + and #I_filter-(1< I_DDR or I_port to force interrupt + if I_ddr != 0 ;with DDR +I_set macro ibit ;ibit = interrupt bit + lda I_ddr ;turn on interrupt by bit + and #I_filter + if ibit > 7 ;set both NMI & IRQ + ora #(1< 7 ;set both NMI & IRQ + ora #(1<. + + +; This program is designed to test all additional 65C02 opcodes, addressing +; modes and functionality not available in the NMOS version of the 6502. +; The 6502_functional_test is a prerequisite to this test. +; NMI, IRQ, STP & WAI are covered in the 6502_interrupt_test. +; +; version 04-dec-2017 +; contact info at http://2m5.de or email K@2m5.de +; +; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/ +; command line switches: -l -m -s2 -w -x -h0 +; | | | | | no page headers in listing +; | | | | 65C02 extensions +; | | | wide listing (133 char/col) +; | | write intel hex file instead of binary +; | expand macros in listing +; generate pass2 listing +; +; No IO - should be run from a monitor with access to registers. +; To run load intel hex image with a load command, than alter PC to 400 hex +; (code_segment) and enter a go command. +; Loop on program counter determines error or successful completion of test. +; Check listing for relevant traps (jump/branch *). +; Please note that in early tests some instructions will have to be used before +; they are actually tested! +; +; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled. +; Tests documented behavior of the original 65C02 only! +; Decimal ops will only be tested with valid BCD operands and the V flag will +; be ignored as it is absolutely useless in decimal mode. +; +; Debugging hints: +; Most of the code is written sequentially. if you hit a trap, check the +; immediately preceeding code for the instruction to be tested. Results are +; tested first, flags are checked second by pushing them onto the stack and +; pulling them to the accumulator after the result was checked. The "real" +; flags are no longer valid for the tested instruction at this time! +; If the tested instruction was indexed, the relevant index (X or Y) must +; also be checked. Opposed to the flags, X and Y registers are still valid. +; +; versions: +; 19-jul-2013 1st version distributed for testing +; 23-jul-2013 fixed BRA out of range due to larger trap macros +; added RAM integrity check +; 16-aug-2013 added error report to standard output option +; 23-aug-2015 change revoked +; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM +; 28-aug-2015 fixed decimal adc/sbc immediate only testing carry +; 09-feb-2017 fixed RMB/SMB tested when they shouldn't be tested +; 04-dec-2017 fixed BRK not tested for actually going through the IRQ vector +; added option to skip the remainder of a failing test +; in report.i65 +; added skip override to undefined opcode as NOP test + + +; C O N F I G U R A T I O N + +;ROM_vectors writable (0=no, 1=yes) +;if ROM vectors can not be used interrupts will not be trapped +;as a consequence BRK can not be tested but will be emulated to test RTI +ROM_vectors = 1 + +;load_data_direct (0=move from code segment, 1=load directly) +;loading directly is preferred but may not be supported by your platform +;0 produces only consecutive object code, 1 is not suitable for a binary image +load_data_direct = 1 + +;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow +;change) 2 requires extra code and is not recommended. +I_flag = 3 + +;configure memory - try to stay away from memory used by the system +;zero_page memory start address, $4e (78) consecutive Bytes required +; add 2 if I_flag = 2 +zero_page = $a + +;data_segment memory start address, $63 (99) consecutive Bytes required +; + 12 Bytes at data_segment + $f9 (JMP indirect page cross test) +data_segment = $200 + if (data_segment & $ff) != 0 + ERROR ERROR ERROR low byte of data_segment MUST be $00 !! + endif + +;code_segment memory start address, 10kB of consecutive space required +; add 1 kB if I_flag = 2 +code_segment = $400 + +;added WDC only opcodes WAI & STP (0=test as NOPs, >0=no test) +wdc_op = 1 + +;added Rockwell & WDC opcodes BBR, BBS, RMB & SMB +;(0=test as NOPs, 1=full test, >1=no test) +rkwl_wdc_op = 1 + +;skip testing all undefined opcodes override +;0=test as NOP, >0=skip +skip_nop = 0 + +;report errors through I/O channel (0=use standard self trap loops, 1=include +;report.i65 as I/O channel, add 3 kB) +report = 0 + +;RAM integrity test option. Checks for undesired RAM writes. +;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k) +;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM +ram_top = -1 + + noopt ;do not take shortcuts + +;macros for error & success traps to allow user modification +;example: +;trap macro +; jsr my_error_handler +; endm +;trap_eq macro +; bne skip\? +; trap ;failed equal (zero) +;skip\? +; endm +; +; my_error_handler should pop the calling address from the stack and report it. +; putting larger portions of code (more than 3 bytes) inside the trap macro +; may lead to branch range problems for some tests. + if report = 0 +trap macro + jmp * ;failed anyway + endm +trap_eq macro + beq * ;failed equal (zero) + endm +trap_ne macro + bne * ;failed not equal (non zero) + endm +trap_cs macro + bcs * ;failed carry set + endm +trap_cc macro + bcc * ;failed carry clear + endm +trap_mi macro + bmi * ;failed minus (bit 7 set) + endm +trap_pl macro + bpl * ;failed plus (bit 7 clear) + endm +trap_vs macro + bvs * ;failed overflow set + endm +trap_vc macro + bvc * ;failed overflow clear + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jmp * ;test passed, no errors + endm + endif + if report = 1 +trap macro + jsr report_error + endm +trap_eq macro + bne skip\? + trap ;failed equal (zero) +skip\? + endm +trap_ne macro + beq skip\? + trap ;failed not equal (non zero) +skip\? + endm +trap_cs macro + bcc skip\? + trap ;failed carry set +skip\? + endm +trap_cc macro + bcs skip\? + trap ;failed carry clear +skip\? + endm +trap_mi macro + bpl skip\? + trap ;failed minus (bit 7 set) +skip\? + endm +trap_pl macro + bmi skip\? + trap ;failed plus (bit 7 clear) +skip\? + endm +trap_vs macro + bvc skip\? + trap ;failed overflow set +skip\? + endm +trap_vc macro + bvs skip\? + trap ;failed overflow clear +skip\? + endm +; please observe that during the test the stack gets invalidated +; therefore a RTS inside the success macro is not possible +success macro + jsr report_success + endm + endif + + +carry equ %00000001 ;flag bits in status +zero equ %00000010 +intdis equ %00000100 +decmode equ %00001000 +break equ %00010000 +reserv equ %00100000 +overfl equ %01000000 +minus equ %10000000 + +fc equ carry +fz equ zero +fzc equ carry+zero +fv equ overfl +fvz equ overfl+zero +fn equ minus +fnc equ minus+carry +fnz equ minus+zero +fnzc equ minus+zero+carry +fnv equ minus+overfl + +fao equ break+reserv ;bits always on after PHP, BRK +fai equ fao+intdis ;+ forced interrupt disable +m8 equ $ff ;8 bit mask +m8i equ $ff&~intdis ;8 bit mask - interrupt disable + +;macros to allow masking of status bits. +;masking of interrupt enable/disable on load and compare +;masking of always on bits after PHP or BRK (unused & break) on compare + if I_flag = 0 +load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm +cmp_flag macro + cmp #(\1|fao)&m8i ;I_flag is always enabled + always on bits + endm +eor_flag macro + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 +load_flag macro + lda #\1|intdis ;force disable interrupts + endm +cmp_flag macro + cmp #(\1|fai)&m8 ;I_flag is always disabled + always on bits + endm +eor_flag macro + eor #(\1|fai) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 +load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm +cmp_flag macro + eor flag_I_on ;I_flag is never changed + cmp #(\1|fao)&m8i ;expected flags + always on bits, mask I + endm +eor_flag macro + eor flag_I_on ;I_flag is never changed + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 +load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm +cmp_flag macro + cmp #(\1|fao)&m8 ;expected flags + always on bits + endm +eor_flag macro + eor #\1|fao ;invert expected flags + always on bits + endm + endif + +;macros to set (register|memory|zeropage) & status +set_stat macro ;setting flags in the processor status register + load_flag \1 + pha ;use stack to load status + plp + endm + +set_a macro ;precharging accu & status + load_flag \2 + pha ;use stack to load status + lda #\1 ;precharge accu + plp + endm + +set_x macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldx #\1 ;precharge index x + plp + endm + +set_y macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldy #\1 ;precharge index y + plp + endm + +set_ax macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;precharge accu + plp + endm + +set_ay macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,y ;precharge accu + plp + endm + +set_z macro ;precharging indexed zp & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to zeropage + sta zpt + plp + endm + +set_zx macro ;precharging zp,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed zeropage + sta zpt,x + plp + endm + +set_abs macro ;precharging indexed memory & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to memory + sta abst + plp + endm + +set_absx macro ;precharging abs,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed memory + sta abst,x + plp + endm + +;macros to test (register|memory|zeropage) & status & (mask) +tst_stat macro ;testing flags in the processor status register + php ;save status + pla ;use stack to retrieve status + pha + cmp_flag \1 + trap_ne + plp ;restore status + endm + +tst_a macro ;testing result in accu & flags + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_as macro ;testing result in accu & flags, save accu + pha + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + pla + endm + +tst_x macro ;testing result in x index & flags + php ;save flags + cpx #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_y macro ;testing result in y index & flags + php ;save flags + cpy #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + +tst_ax macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne ; + endm + +tst_ay macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,y ;test result + trap_ne ; + pla ;load status + eor_flag \3 + cmp \2,y ;test flags + trap_ne + endm + +tst_z macro ;indexed testing result in zp & flags + php ;save flags + lda zpt + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_zx macro ;testing result in zp,x & flags + php ;save flags + lda zpt,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_abs macro ;indexed testing result in memory & flags + php ;save flags + lda abst + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +tst_absx macro ;testing result in abs,x & flags + php ;save flags + lda abst,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + +; RAM integrity test +; verifies that none of the previous tests has altered RAM outside of the +; designated write areas. +; uses zpt word as indirect pointer, zpt+2 word as checksum + if ram_top > -1 +check_ram macro + cld + lda #0 + sta zpt ;set low byte of indirect pointer + sta zpt+3 ;checksum high byte + ldx #11 ;reset modifiable RAM +ccs1\? sta jxi_tab,x ;JMP indirect page cross area + dex + bpl ccs1\? + clc + ldx #zp_bss-zero_page ;zeropage - write test area +ccs3\? adc zero_page,x + bcc ccs2\? + inc zpt+3 ;carry to high byte + clc +ccs2\? inx + bne ccs3\? + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area +ccs5\? adc (zpt),y + bcc ccs4\? + inc zpt+3 ;carry to high byte + clc +ccs4\? iny + bne ccs5\? + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne ccs5\? + sta zpt+2 ;checksum low is + cmp ram_chksm ;checksum low expected + trap_ne ;checksum mismatch + lda zpt+3 ;checksum high is + cmp ram_chksm+1 ;checksum high expected + trap_ne ;checksum mismatch + endm + else +check_ram macro + ;RAM check disabled - RAM size not set + endm + endif + +next_test macro ;make sure, tests don't jump the fence + lda test_case ;previous test + cmp #test_num + trap_ne ;test is out of sequence +test_num = test_num + 1 + lda #test_num ;*** next tests' number + sta test_case + ;check_ram ;uncomment to find altered RAM after each test + endm + + if load_data_direct = 1 + data + else + bss ;uninitialized segment, copy of data at end of code! + endif + org zero_page +;break test interrupt save +irq_a ds 1 ;a register +irq_x ds 1 ;x register + if I_flag = 2 +;masking for I bit in status +flag_I_on ds 1 ;or mask to load flags +flag_I_off ds 1 ;and mask to load flags + endif +zpt ;5 bytes store/modify test area +;add/subtract operand generation and result/flag prediction +adfc ds 1 ;carry flag before op +ad1 ds 1 ;operand 1 - accumulator +ad2 ds 1 ;operand 2 - memory / immediate +adrl ds 1 ;expected result bits 0-7 +adrh ds 1 ;expected result bit 8 (carry) +adrf ds 1 ;expected flags NV0000ZC (-V in decimal mode) +sb2 ds 1 ;operand 2 complemented for subtract +zp_bss +zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +zp7f db $7f ;test pattern for compare +;logical zeropage operands +zpOR db 0,$1f,$71,$80 ;test pattern for OR +zpAN db $0f,$ff,$7f,$80 ;test pattern for AND +zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR +;indirect addressing pointers +ind1 dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f +inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern +indt dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 +inwt dw abst-$f8 ;indirect pointer for wrap-test store +indAN dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 +indEO dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 +indOR dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 +;add/subtract indirect pointers +adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory +sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC) +adiy2 dw ada2-$ff ;with offset for indirect indexed +sbiy2 dw sba2-$ff +zp_bss_end + + org data_segment +pg_x ds 2 ;high JMP indirect address for page cross bug +test_case ds 1 ;current test number +ram_chksm ds 2 ;checksum for RAM integrity test +;add/subtract operand copy - abs tests write area +abst ;5 bytes store/modify test area +ada2 ds 1 ;operand 2 +sba2 ds 1 ;operand 2 complemented for subtract + ds 3 ;fill remaining bytes +data_bss + if load_data_direct = 1 +ex_adci adc #0 ;execute immediate opcodes + rts +ex_sbci sbc #0 ;execute immediate opcodes + rts + else +ex_adci ds 3 +ex_sbci ds 3 + endif +abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +abs7f db $7f ;test pattern for compare +;loads +fLDx db fn,fn,0,fz ;expected flags for load +;shifts +rASL ;expected result ASL & ROL -carry +rROL db $86,$04,$82,0 ; " +rROLc db $87,$05,$83,1 ;expected result ROL +carry +rLSR ;expected result LSR & ROR -carry +rROR db $61,$41,$20,0 ; " +rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry +fASL ;expected flags for shifts +fROL db fnc,fc,fn,fz ;no carry in +fROLc db fnc,fc,fn,0 ;carry in +fLSR +fROR db fc,0,fc,fz ;no carry in +fRORc db fnc,fn,fnc,fn ;carry in +;increments (decrements) +rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC +fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC +;logical memory operand +absOR db 0,$1f,$71,$80 ;test pattern for OR +absAN db $0f,$ff,$7f,$80 ;test pattern for AND +absEO db $ff,$0f,$8f,$8f ;test pattern for EOR +;logical accu operand +absORa db 0,$f1,$1f,0 ;test pattern for OR +absANa db $f0,$ff,$ff,$ff ;test pattern for AND +absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR +;logical results +absrlo db 0,$ff,$7f,$80 +absflo db fz,fn,0,fn +data_bss_end +;define area for page crossing JMP (abs) & JMP (abs,x) test +jxi_tab equ data_segment + $100 - 7 ;JMP (jxi_tab,x) x=6 +ji_tab equ data_segment + $100 - 3 ;JMP (ji_tab+2) +jxp_tab equ data_segment + $100 ;JMP (jxp_tab-255) x=255 + + + code + org code_segment +start cld + ldx #$ff + txs + lda #0 ;*** test 0 = initialize + sta test_case +test_num = 0 + +;stop interrupts before initializing BSS + if I_flag = 1 + sei + endif + +;initialize I/O for report channel + if report = 1 + jsr report_init + endif + +;initialize BSS segment + if load_data_direct != 1 + ldx #zp_end-zp_init-1 +ld_zp lda zp_init,x + sta zp_bss,x + dex + bpl ld_zp + ldx #data_end-data_init-1 +ld_data lda data_init,x + sta data_bss,x + dex + bpl ld_data + if ROM_vectors = 1 + ldx #5 +ld_vect lda vec_init,x + sta vec_bss,x + dex + bpl ld_vect + endif + endif + +;retain status of interrupt flag + if I_flag = 2 + php + pla + and #4 ;isolate flag + sta flag_I_on ;or mask + eor #lo(~4) ;reverse + sta flag_I_off ;and mask + endif + +;generate checksum for RAM integrity test + if ram_top > -1 + lda #0 + sta zpt ;set low byte of indirect pointer + sta ram_chksm+1 ;checksum high byte + ldx #11 ;reset modifiable RAM +gcs1 sta jxi_tab,x ;JMP indirect page cross area + dex + bpl gcs1 + clc + ldx #zp_bss-zero_page ;zeropage - write test area +gcs3 adc zero_page,x + bcc gcs2 + inc ram_chksm+1 ;carry to high byte + clc +gcs2 inx + bne gcs3 + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area +gcs5 adc (zpt),y + bcc gcs4 + inc ram_chksm+1 ;carry to high byte + clc +gcs4 iny + bne gcs5 + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne gcs5 + sta ram_chksm ;checksum complete + endif + next_test + +;testing stack operations PHX PHY PLX PLY + lda #$99 ;protect a + ldx #$ff ;initialize stack + txs + ldx #$55 + phx + ldx #$aa + phx + cpx $1fe ;on stack ? + trap_ne + tsx + cpx #$fd ;sp decremented? + trap_ne + ply + cpy #$aa ;successful retreived from stack? + trap_ne + ply + cpy #$55 + trap_ne + cpy $1ff ;remains on stack? + trap_ne + tsx + cpx #$ff ;sp incremented? + trap_ne + + ldy #$a5 + phy + ldy #$5a + phy + cpy $1fe ;on stack ? + trap_ne + tsx + cpx #$fd ;sp decremented? + trap_ne + plx + cpx #$5a ;successful retreived from stack? + trap_ne + plx + cpx #$a5 + trap_ne + cpx $1ff ;remains on stack? + trap_ne + tsx + cpx #$ff ;sp incremented? + trap_ne + cmp #$99 ;unchanged? + trap_ne + next_test + +; test PHX does not alter flags or X but PLX does + ldy #$aa ;protect y + set_x 1,$ff ;push + phx + tst_x 1,$ff + set_x 0,0 + phx + tst_x 0,0 + set_x $ff,$ff + phx + tst_x $ff,$ff + set_x 1,0 + phx + tst_x 1,0 + set_x 0,$ff + phx + tst_x 0,$ff + set_x $ff,0 + phx + tst_x $ff,0 + set_x 0,$ff ;pull + plx + tst_x $ff,$ff-zero + set_x $ff,0 + plx + tst_x 0,zero + set_x $fe,$ff + plx + tst_x 1,$ff-zero-minus + set_x 0,0 + plx + tst_x $ff,minus + set_x $ff,$ff + plx + tst_x 0,$ff-minus + set_x $fe,0 + plx + tst_x 1,0 + cpy #$aa ;Y unchanged + trap_ne + next_test + +; test PHY does not alter flags or Y but PLY does + ldx #$55 ;x & a protected + set_y 1,$ff ;push + phy + tst_y 1,$ff + set_y 0,0 + phy + tst_y 0,0 + set_y $ff,$ff + phy + tst_y $ff,$ff + set_y 1,0 + phy + tst_y 1,0 + set_y 0,$ff + phy + tst_y 0,$ff + set_y $ff,0 + phy + tst_y $ff,0 + set_y 0,$ff ;pull + ply + tst_y $ff,$ff-zero + set_y $ff,0 + ply + tst_y 0,zero + set_y $fe,$ff + ply + tst_y 1,$ff-zero-minus + set_y 0,0 + ply + tst_y $ff,minus + set_y $ff,$ff + ply + tst_y 0,$ff-minus + set_y $fe,0 + ply + tst_y 1,0 + cpx #$55 ;x unchanged? + trap_ne + next_test + +; PC modifying instructions (BRA, BBR, BBS, 1, 2, 3 byte NOPs, JMP(abs,x)) +; testing unconditional branch BRA + + ldx #$81 ;protect unused registers + ldy #$7e + set_a 0,$ff + bra br1 ;branch should always be taken + trap +br1 + tst_a 0,$ff + set_a $ff,0 + bra br2 ;branch should always be taken + trap +br2 + tst_a $ff,0 + cpx #$81 + trap_ne + cpy #$7e + trap_ne + next_test + + ldy #0 ;branch range test + bra bra0 + +bra1 cpy #1 + trap_ne ;long range backward + iny + bra bra2 + +bra3 cpy #3 + trap_ne ;long range backward + iny + bra bra4 + +bra5 cpy #5 + trap_ne ;long range backward + iny + ldy #0 + bra brf0 + + iny + iny + iny + iny +brf0 bra brf1 + + iny + iny + iny +brf1 iny + bra brf2 + + iny + iny +brf2 iny + iny + bra brf3 + + iny +brf3 iny + iny + iny + bra brf4 + +brf4 iny + iny + iny + iny + cpy #10 + trap_ne ;short range forward + bra brb0 + +brb4 dey + dey + dey + dey + bra brb5 + +brb3 dey + dey + dey + bra brb4 + +brb2 dey + dey + bra brb3 + +brb1 dey + bra brb2 + +brb0 bra brb1 + +brb5 cpy #0 + trap_ne ;short range backward + bra bra6 + +bra4 cpy #4 + trap_ne ;long range forward + iny + bra bra5 + +bra2 cpy #2 + trap_ne ;long range forward + iny + bra bra3 + +bra0 cpy #0 + trap_ne ;long range forward + iny + bra bra1 + +bra6 + next_test + + if rkwl_wdc_op = 1 +; testing BBR & BBS + +bbt macro ;\1 = bitnum + lda #(1<<\1) ;testing 1 bit on + sta zpt + set_a $33,0 ;with flags off + bbr \1,zpt,fail1\? + bbs \1,zpt,ok1\? + trap ;bbs branch not taken +fail1\? + trap ;bbr branch taken +ok1\? + tst_a $33,0 + set_a $cc,$ff ;with flags on + bbr \1,zpt,fail2\? + bbs \1,zpt,ok2\? + trap ;bbs branch not taken +fail2\? + trap ;bbr branch taken +ok2\? + tst_a $cc,$ff + lda zpt + cmp #(1<<\1) + trap_ne ;zp altered + lda #$ff-(1<<\1) ;testing 1 bit off + sta zpt + set_a $33,0 ;with flags off + bbs \1,zpt,fail3\? + bbr \1,zpt,ok3\? + trap ;bbr branch not taken +fail3\? + trap ;bbs branch taken +ok3\? + tst_a $33,0 + set_a $cc,$ff ;with flags on + bbs \1,zpt,fail4\? + bbr \1,zpt,ok4\? + trap ;bbr branch not taken +fail4\? + trap ;bbs branch taken +ok4\? + tst_a $cc,$ff + lda zpt + cmp #$ff-(1<<\1) + trap_ne ;zp altered + endm + + ldx #$11 ;test bbr/bbs integrity + ldy #$22 + bbt 0 + bbt 1 + bbt 2 + bbt 3 + bbt 4 + bbt 5 + bbt 6 + bbt 7 + cpx #$11 + trap_ne ;x overwritten + cpy #$22 + trap_ne ;y overwritten + next_test + +bbrc macro ;\1 = bitnum + bbr \1,zpt,skip\? + eor #(1<<\1) +skip\? + endm +bbsc macro ;\1 = bitnum + bbs \1,zpt,skip\? + eor #(1<<\1) +skip\? + endm + + lda #0 ;combined bit test + sta zpt +bbcl lda #0 + bbrc 0 + bbrc 1 + bbrc 2 + bbrc 3 + bbrc 4 + bbrc 5 + bbrc 6 + bbrc 7 + eor zpt + trap_ne ;failed bbr bitnum in accu + lda #$ff + bbsc 0 + bbsc 1 + bbsc 2 + bbsc 3 + bbsc 4 + bbsc 5 + bbsc 6 + bbsc 7 + eor zpt + trap_ne ;failed bbs bitnum in accu + inc zpt + bne bbcl + next_test + endif + +; testing NOP + +nop_test macro ;\1 = opcode, \2 = # of bytes + ldy #$42 + ldx #4-\2 + db \1 ;test nop length + if \2 = 1 + dex + dex + endif + if \2 = 2 + iny + dex + endif + if \2 = 3 + iny + iny + endif + dex + trap_ne ;wrong number of bytes + set_a $ff-\1,0 + db \1 ;test nop integrity - flags off + nop + nop + tst_a $ff-\1,0 + set_a $aa-\1,$ff + db \1 ;test nop integrity - flags on + nop + nop + tst_a $aa-\1,$ff + cpy #$42 + trap_ne ;y changed + cpx #0 + trap_ne ;x changed + endm + + if skip_nop = 0 + nop_test $02,2 + nop_test $22,2 + nop_test $42,2 + nop_test $62,2 + nop_test $82,2 + nop_test $c2,2 + nop_test $e2,2 + nop_test $44,2 + nop_test $54,2 + nop_test $d4,2 + nop_test $f4,2 + nop_test $5c,3 + nop_test $dc,3 + nop_test $fc,3 + nop_test $03,1 + nop_test $13,1 + nop_test $23,1 + nop_test $33,1 + nop_test $43,1 + nop_test $53,1 + nop_test $63,1 + nop_test $73,1 + nop_test $83,1 + nop_test $93,1 + nop_test $a3,1 + nop_test $b3,1 + nop_test $c3,1 + nop_test $d3,1 + nop_test $e3,1 + nop_test $f3,1 + nop_test $0b,1 + nop_test $1b,1 + nop_test $2b,1 + nop_test $3b,1 + nop_test $4b,1 + nop_test $5b,1 + nop_test $6b,1 + nop_test $7b,1 + nop_test $8b,1 + nop_test $9b,1 + nop_test $ab,1 + nop_test $bb,1 + nop_test $eb,1 + nop_test $fb,1 + if rkwl_wdc_op = 0 ;NOPs not available on Rockwell & WDC 65C02 + nop_test $07,1 + nop_test $17,1 + nop_test $27,1 + nop_test $37,1 + nop_test $47,1 + nop_test $57,1 + nop_test $67,1 + nop_test $77,1 + nop_test $87,1 + nop_test $97,1 + nop_test $a7,1 + nop_test $b7,1 + nop_test $c7,1 + nop_test $d7,1 + nop_test $e7,1 + nop_test $f7,1 + nop_test $0f,1 + nop_test $1f,1 + nop_test $2f,1 + nop_test $3f,1 + nop_test $4f,1 + nop_test $5f,1 + nop_test $6f,1 + nop_test $7f,1 + nop_test $8f,1 + nop_test $9f,1 + nop_test $af,1 + nop_test $bf,1 + nop_test $cf,1 + nop_test $df,1 + nop_test $ef,1 + nop_test $ff,1 + endif + if wdc_op = 0 ;NOPs not available on WDC 65C02 (WAI, STP) + nop_test $cb,1 + nop_test $db,1 + endif + next_test + endif + +; jump indirect (test page cross bug is fixed) + ldx #3 ;prepare table +ji1 lda ji_adr,x + sta ji_tab,x + dex + bpl ji1 + lda #hi(ji_px) ;high address if page cross bug + sta pg_x + set_stat 0 + lda #'I' + ldx #'N' + ldy #'D' ;N=0, V=0, Z=0, C=0 + jmp (ji_tab) + nop + trap_ne ;runover protection + + dey + dey +ji_ret php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_eq ;returned flags OK? + trap_pl + trap_cc + trap_vc + cmp #('I'^$aa) ;returned registers OK? + trap_ne + cpx #('N'+1) + trap_ne + cpy #('D'-6) + trap_ne + tsx ;SP check + cpx #$ff + trap_ne + next_test + +; jump indexed indirect + ldx #11 ;prepare table +jxi1 lda jxi_adr,x + sta jxi_tab,x + dex + bpl jxi1 + lda #hi(jxi_px) ;high address if page cross bug + sta pg_x + set_stat 0 + lda #'X' + ldx #4 + ldy #'I' ;N=0, V=0, Z=0, C=0 + jmp (jxi_tab,x) + nop + trap_ne ;runover protection + + dey + dey +jxi_ret php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_eq ;returned flags OK? + trap_pl + trap_cc + trap_vc + cmp #('X'^$aa) ;returned registers OK? + trap_ne + cpx #6 + trap_ne + cpy #('I'-6) + trap_ne + tsx ;SP check + cpx #$ff + trap_ne + + lda #lo(jxp_ok) ;test with index causing a page cross + sta jxp_tab + lda #hi(jxp_ok) + sta jxp_tab+1 + lda #lo(jxp_px) + sta pg_x + lda #hi(jxp_px) + sta pg_x+1 + ldx #$ff + jmp (jxp_tab-$ff,x) + +jxp_px + trap ;page cross by index to wrong page + +jxp_ok + next_test + + if ROM_vectors = 1 +; test BRK clears decimal mode + load_flag 0 ;with interrupts enabled if allowed! + pha + lda #'B' + ldx #'R' + ldy #'K' + plp ;N=0, V=0, Z=0, C=0 + brk + dey ;should not be executed +brk_ret0 ;address of break return + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + cmp #'B'^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne + cpx #'R'+1 + trap_ne + cpy #'K'-6 + trap_ne + pla ;returned flags OK (unchanged)? + cmp_flag 0 + trap_ne + tsx ;sp? + cpx #$ff + trap_ne +;pass 2 + load_flag $ff ;with interrupts disabled if allowed! + pha + lda #$ff-'B' + ldx #$ff-'R' + ldy #$ff-'K' + plp ;N=1, V=1, Z=1, C=1 + brk + dey ;should not be executed +brk_ret1 ;address of break return + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + cmp #($ff-'B')^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne + cpx #$ff-'R'+1 + trap_ne + cpy #$ff-'K'-6 + trap_ne + pla ;returned flags OK (unchanged)? + cmp_flag $ff + trap_ne + tsx ;sp? + cpx #$ff + trap_ne + next_test + endif + +; testing accumulator increment/decrement INC A & DEC A + ldx #$ac ;protect x & y + ldy #$dc + set_a $fe,$ff + inc a ;ff + tst_as $ff,$ff-zero + inc a ;00 + tst_as 0,$ff-minus + inc a ;01 + tst_as 1,$ff-minus-zero + dec a ;00 + tst_as 0,$ff-minus + dec a ;ff + tst_as $ff,$ff-zero + dec a ;fe + set_a $fe,0 + inc a ;ff + tst_as $ff,minus + inc a ;00 + tst_as 0,zero + inc a ;01 + tst_as 1,0 + dec a ;00 + tst_as 0,zero + dec a ;ff + tst_as $ff,minus + cpx #$ac + trap_ne ;x altered during test + cpy #$dc + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; testing load / store accumulator LDA / STA (zp) + ldx #$99 ;protect x & y + ldy #$66 + set_stat 0 + lda (ind1) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt) + php ;flags after load/store sequence + eor #$c3 + cmp #$c3 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx ;test flags + trap_ne + set_stat 0 + lda (ind1+2) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+2) + php ;flags after load/store sequence + eor #$c3 + cmp #$82 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+1 ;test flags + trap_ne + set_stat 0 + lda (ind1+4) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+4) + php ;flags after load/store sequence + eor #$c3 + cmp #$41 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+2 ;test flags + trap_ne + set_stat 0 + lda (ind1+6) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+6) + php ;flags after load/store sequence + eor #$c3 + cmp #0 ;test result + trap_ne + pla ;load status + eor_flag 0 + cmp fLDx+3 ;test flags + trap_ne + cpx #$99 + trap_ne ;x altered during test + cpy #$66 + trap_ne ;y altered during test + + ldy #3 ;testing store result + ldx #0 +tstai1 lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to indirect data + txa + sta abst,y ;clear + dey + bpl tstai1 + + ldx #$99 ;protect x & y + ldy #$66 + set_stat $ff + lda (ind1) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt) + php ;flags after load/store sequence + eor #$c3 + cmp #$c3 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx ;test flags + trap_ne + set_stat $ff + lda (ind1+2) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+2) + php ;flags after load/store sequence + eor #$c3 + cmp #$82 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+1 ;test flags + trap_ne + set_stat $ff + lda (ind1+4) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+4) + php ;flags after load/store sequence + eor #$c3 + cmp #$41 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+2 ;test flags + trap_ne + set_stat $ff + lda (ind1+6) + php ;test stores do not alter flags + eor #$c3 + plp + sta (indt+6) + php ;flags after load/store sequence + eor #$c3 + cmp #0 ;test result + trap_ne + pla ;load status + eor_flag lo~fnz ;mask bits not altered + cmp fLDx+3 ;test flags + trap_ne + cpx #$99 + trap_ne ;x altered during test + cpy #$66 + trap_ne ;y altered during test + + ldy #3 ;testing store result + ldx #0 +tstai2 lda abst,y + eor #$c3 + cmp abs1,y + trap_ne ;store to indirect data + txa + sta abst,y ;clear + dey + bpl tstai2 + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; testing STZ - zp / abs / zp,x / abs,x + ldy #123 ;protect y + ldx #4 ;precharge test area + lda #7 +tstz1 sta zpt,x + asl a + dex + bpl tstz1 + ldx #4 + set_a $55,$ff + stz zpt + stz zpt+1 + stz zpt+2 + stz zpt+3 + stz zpt+4 + tst_a $55,$ff +tstz2 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz2 + ldx #4 ;precharge test area + lda #7 +tstz3 sta zpt,x + asl a + dex + bpl tstz3 + ldx #4 + set_a $aa,0 + stz zpt + stz zpt+1 + stz zpt+2 + stz zpt+3 + stz zpt+4 + tst_a $aa,0 +tstz4 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz4 + + ldx #4 ;precharge test area + lda #7 +tstz5 sta abst,x + asl a + dex + bpl tstz5 + ldx #4 + set_a $55,$ff + stz abst + stz abst+1 + stz abst+2 + stz abst+3 + stz abst+4 + tst_a $55,$ff +tstz6 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ abs + dex + bpl tstz6 + ldx #4 ;precharge test area + lda #7 +tstz7 sta abst,x + asl a + dex + bpl tstz7 + ldx #4 + set_a $aa,0 + stz abst + stz abst+1 + stz abst+2 + stz abst+3 + stz abst+4 + tst_a $aa,0 +tstz8 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ abs + dex + bpl tstz8 + + ldx #4 ;precharge test area + lda #7 +tstz11 sta zpt,x + asl a + dex + bpl tstz11 + ldx #4 +tstz15 + set_a $55,$ff + stz zpt,x + tst_a $55,$ff + dex + bpl tstz15 + ldx #4 +tstz12 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz12 + ldx #4 ;precharge test area + lda #7 +tstz13 sta zpt,x + asl a + dex + bpl tstz13 + ldx #4 +tstz16 + set_a $aa,0 + stz zpt,x + tst_a $aa,0 + dex + bpl tstz16 + ldx #4 +tstz14 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz14 + + ldx #4 ;precharge test area + lda #7 +tstz21 sta abst,x + asl a + dex + bpl tstz21 + ldx #4 +tstz25 + set_a $55,$ff + stz abst,x + tst_a $55,$ff + dex + bpl tstz25 + ldx #4 +tstz22 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz22 + ldx #4 ;precharge test area + lda #7 +tstz23 sta abst,x + asl a + dex + bpl tstz23 + ldx #4 +tstz26 + set_a $aa,0 + stz abst,x + tst_a $aa,0 + dex + bpl tstz26 + ldx #4 +tstz24 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ zp + dex + bpl tstz24 + + cpy #123 + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; testing BIT - zp,x / abs,x / # + ldy #$42 + ldx #3 + set_a $ff,0 + bit zp1,x ;00 - should set Z / clear NV + tst_a $ff,fz + dex + set_a 1,0 + bit zp1,x ;41 - should set V (M6) / clear NZ + tst_a 1,fv + dex + set_a 1,0 + bit zp1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz + dex + set_a 1,0 + bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv + + set_a 1,$ff + bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz + inx + set_a 1,$ff + bit zp1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv + inx + set_a 1,$ff + bit zp1,x ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz + inx + set_a $ff,$ff + bit zp1,x ;00 - should set Z / clear NV + tst_a $ff,~fnv + + set_a $ff,0 + bit abs1,x ;00 - should set Z / clear NV + tst_a $ff,fz + dex + set_a 1,0 + bit abs1,x ;41 - should set V (M6) / clear NZ + tst_a 1,fv + dex + set_a 1,0 + bit abs1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz + dex + set_a 1,0 + bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv + + set_a 1,$ff + bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz + inx + set_a 1,$ff + bit abs1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv + inx + set_a 1,$ff + bit abs1,x ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz + inx + set_a $ff,$ff + bit abs1,x ;00 - should set Z / clear NV + tst_a $ff,~fnv + + set_a $ff,0 + bit #$00 ;00 - should set Z + tst_a $ff,fz + dex + set_a 1,0 + bit #$41 ;41 - should clear Z + tst_a 1,0 +; *** DEBUG INFO *** +; if it fails the previous test and your BIT # has set the V flag +; see http://forum.6502.org/viewtopic.php?f=2&t=2241&p=27243#p27239 +; why it shouldn't alter N or V flags on a BIT # + dex + set_a 1,0 + bit #$82 ;82 - should set Z + tst_a 1,fz + dex + set_a 1,0 + bit #$c3 ;c3 - should clear Z + tst_a 1,0 + + set_a 1,$ff + bit #$c3 ;c3 - clear Z + tst_a 1,~fz + inx + set_a 1,$ff + bit #$82 ;82 - should set Z + tst_a 1,$ff + inx + set_a 1,$ff + bit #$41 ;41 - should clear Z + tst_a 1,~fz + inx + set_a $ff,$ff + bit #$00 ;00 - should set Z + tst_a $ff,$ff + + cpx #3 + trap_ne ;x altered during test + cpy #$42 + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; testing TRB, TSB - zp / abs + +trbt macro ;\1 = memory, \2 = flags + sty \1 + load_flag \2 + pha + lda zpt+1 + plp + trb \1 + php + cmp zpt+1 + trap_ne ;accu was changed + pla + pha + ora #fz ;mask Z + cmp_flag \2|fz + trap_ne ;flags changed except Z + pla + and #fz + cmp zpt+2 + trap_ne ;Z flag invalid + lda zpt+3 + cmp zpt + trap_ne ;altered bits in memory wrong + endm + +tsbt macro ;\1 = memory, \2 = flags + sty \1 + load_flag \2 + pha + lda zpt+1 + plp + tsb \1 + php + cmp zpt+1 + trap_ne ;accu was changed + pla + pha + ora #fz ;mask Z + cmp_flag \2|fz + trap_ne ;flags changed except Z + pla + and #fz + cmp zpt+2 + trap_ne ;Z flag invalid + lda zpt+4 + cmp zpt + trap_ne ;altered bits in memory wrong + endm + + ldx #$c0 + ldy #0 ;op1 - memory save + ; zpt ;op1 - memory modifiable + stz zpt+1 ;op2 - accu + ; zpt+2 ;and flags + ; zpt+3 ;memory after reset + ; zpt+4 ;memory after set + +tbt1 tya + and zpt+1 ;set Z by anding the 2 operands + php + pla + and #fz ;mask Z + sta zpt+2 + tya ;reset op1 bits by op2 + eor #$ff + ora zpt+1 + eor #$ff + sta zpt+3 + tya ;set op1 bits by op2 + ora zpt+1 + sta zpt+4 + + trbt zpt,$ff + trbt abst,$ff + trbt zpt,0 + trbt abst,0 + tsbt zpt,$ff + tsbt abst,$ff + tsbt zpt,0 + tsbt abst,0 + + iny ;iterate op1 + bne tbt3 + inc zpt+1 ;iterate op2 + beq tbt2 +tbt3 jmp tbt1 +tbt2 + cpx #$c0 + trap_ne ;x altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + + if rkwl_wdc_op = 1 +; testing RMB, SMB - zp +rmbt macro ;\1 = bitnum + lda #$ff + sta zpt + set_a $a5,0 + rmb \1,zpt + tst_a $a5,0 + lda zpt + cmp #$ff-(1<<\1) + trap_ne ;wrong bits set or cleared + lda #1<<\1 + sta zpt + set_a $5a,$ff + rmb \1,zpt + tst_a $5a,$ff + lda zpt + trap_ne ;wrong bits set or cleared + endm +smbt macro ;\1 = bitnum + lda #$ff-(1<<\1) + sta zpt + set_a $a5,0 + smb \1,zpt + tst_a $a5,0 + lda zpt + cmp #$ff + trap_ne ;wrong bits set or cleared + lda #0 + sta zpt + set_a $5a,$ff + smb \1,zpt + tst_a $5a,$ff + lda zpt + cmp #1<<\1 + trap_ne ;wrong bits set or cleared + endm + + ldx #$ba ;protect x & y + ldy #$d0 + rmbt 0 + rmbt 1 + rmbt 2 + rmbt 3 + rmbt 4 + rmbt 5 + rmbt 6 + rmbt 7 + smbt 0 + smbt 1 + smbt 2 + smbt 3 + smbt 4 + smbt 5 + smbt 6 + smbt 7 + cpx #$ba + trap_ne ;x altered during test + cpy #$d0 + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + endif + +; testing CMP - (zp) + ldx #$de ;protect x & y + ldy #$ad + set_a $80,0 + cmp (ind1+8) + tst_a $80,fc + set_a $7f,0 + cmp (ind1+8) + tst_a $7f,fzc + set_a $7e,0 + cmp (ind1+8) + tst_a $7e,fn + set_a $80,$ff + cmp (ind1+8) + tst_a $80,~fnz + set_a $7f,$ff + cmp (ind1+8) + tst_a $7f,~fn + set_a $7e,$ff + cmp (ind1+8) + tst_a $7e,~fzc + cpx #$de + trap_ne ;x altered during test + cpy #$ad + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; testing logical instructions - AND EOR ORA (zp) + ldx #$42 ;protect x & y + + ldy #0 ;AND + lda indAN ;set indirect address + sta zpt + lda indAN+1 + sta zpt+1 +tand1 + set_ay absANa,0 + and (zpt) + tst_ay absrlo,absflo,0 + inc zpt + iny + cpy #4 + bne tand1 + dey + dec zpt +tand2 + set_ay absANa,$ff + and (zpt) + tst_ay absrlo,absflo,$ff-fnz + dec zpt + dey + bpl tand2 + + ldy #0 ;EOR + lda indEO ;set indirect address + sta zpt + lda indEO+1 + sta zpt+1 +teor1 + set_ay absEOa,0 + eor (zpt) + tst_ay absrlo,absflo,0 + inc zpt + iny + cpy #4 + bne teor1 + dey + dec zpt +teor2 + set_ay absEOa,$ff + eor (zpt) + tst_ay absrlo,absflo,$ff-fnz + dec zpt + dey + bpl teor2 + + ldy #0 ;ORA + lda indOR ;set indirect address + sta zpt + lda indOR+1 + sta zpt+1 +tora1 + set_ay absORa,0 + ora (zpt) + tst_ay absrlo,absflo,0 + inc zpt + iny + cpy #4 + bne tora1 + dey + dec zpt +tora2 + set_ay absORa,$ff + ora (zpt) + tst_ay absrlo,absflo,$ff-fnz + dec zpt + dey + bpl tora2 + + cpx #$42 + trap_ne ;x altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + + if I_flag = 3 + cli + endif + +; full binary add/subtract test - (zp) only +; iterates through all combinations of operands and carry input +; uses increments/decrements to predict result & result flags + cld + ldx #ad2 ;for indexed test + ldy #$ff ;max range + lda #0 ;start with adding zeroes & no carry + sta adfc ;carry in - for diag + sta ad1 ;operand 1 - accumulator + sta ad2 ;operand 2 - memory or immediate + sta ada2 ;non zp + sta adrl ;expected result bits 0-7 + sta adrh ;expected result bit 8 (carry out) + lda #$ff ;complemented operand 2 for subtract + sta sb2 + sta sba2 ;non zp + lda #2 ;expected Z-flag + sta adrf +tadd clc ;test with carry clear + jsr chkadd + inc adfc ;now with carry + inc adrl ;result +1 + php ;save N & Z from low result + php + pla ;accu holds expected flags + and #$82 ;mask N & Z + plp + bne tadd1 + inc adrh ;result bit 8 - carry +tadd1 ora adrh ;merge C to expected flags + sta adrf ;save expected flags except overflow + sec ;test with carry set + jsr chkadd + dec adfc ;same for operand +1 but no carry + inc ad1 + bne tadd ;iterate op1 + lda #0 ;preset result to op2 when op1 = 0 + sta adrh + inc ada2 + inc ad2 + php ;save NZ as operand 2 becomes the new result + pla + and #$82 ;mask N00000Z0 + sta adrf ;no need to check carry as we are adding to 0 + dec sb2 ;complement subtract operand 2 + dec sba2 + lda ad2 + sta adrl + bne tadd ;iterate op2 + + cpx #ad2 + trap_ne ;x altered during test + cpy #$ff + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + next_test + +; decimal add/subtract test +; *** WARNING - tests documented behavior only! *** +; only valid BCD operands are tested, the V flag is ignored +; although V is declared as beeing valid on the 65C02 it has absolutely +; no use in BCD math. No sign = no overflow! +; iterates through all valid combinations of operands and carry input +; uses increments/decrements to predict result & carry flag + sed + ldx #ad2 ;for indexed test + ldy #$ff ;max range + lda #$99 ;start with adding 99 to 99 with carry + sta ad1 ;operand 1 - accumulator + sta ad2 ;operand 2 - memory or immediate + sta ada2 ;non zp + sta adrl ;expected result bits 0-7 + lda #1 ;set carry in & out + sta adfc ;carry in - for diag + sta adrh ;expected result bit 8 (carry out) + lda #$81 ;set N & C (99 + 99 + C = 99 + C) + sta adrf + lda #0 ;complemented operand 2 for subtract + sta sb2 + sta sba2 ;non zp +tdad sec ;test with carry set + jsr chkdad + dec adfc ;now with carry clear + lda adrl ;decimal adjust result + bne tdad1 ;skip clear carry & preset result 99 (9A-1) + dec adrh + lda #$99 + sta adrl + bne tdad3 +tdad1 and #$f ;lower nibble mask + bne tdad2 ;no decimal adjust needed + dec adrl ;decimal adjust (?0-6) + dec adrl + dec adrl + dec adrl + dec adrl + dec adrl +tdad2 dec adrl ;result -1 +tdad3 php ;save valid flags + pla + and #$82 ;N-----Z- + ora adrh ;N-----ZC + sta adrf + clc ;test with carry clear + jsr chkdad + inc adfc ;same for operand -1 but with carry + lda ad1 ;decimal adjust operand 1 + beq tdad5 ;iterate operand 2 + and #$f ;lower nibble mask + bne tdad4 ;skip decimal adjust + dec ad1 ;decimal adjust (?0-6) + dec ad1 + dec ad1 + dec ad1 + dec ad1 + dec ad1 +tdad4 dec ad1 ;operand 1 -1 + jmp tdad ;iterate op1 + +tdad5 lda #$99 ;precharge op1 max + sta ad1 + lda ad2 ;decimal adjust operand 2 + beq tdad7 ;end of iteration + and #$f ;lower nibble mask + bne tdad6 ;skip decimal adjust + dec ad2 ;decimal adjust (?0-6) + dec ad2 + dec ad2 + dec ad2 + dec ad2 + dec ad2 + inc sb2 ;complemented decimal adjust for subtract (?9+6) + inc sb2 + inc sb2 + inc sb2 + inc sb2 + inc sb2 +tdad6 dec ad2 ;operand 2 -1 + inc sb2 ;complemented operand for subtract + lda sb2 + sta sba2 ;copy as non zp operand + lda ad2 + sta ada2 ;copy as non zp operand + sta adrl ;new result since op1+carry=00+carry +op2=op2 + php ;save flags + pla + and #$82 ;N-----Z- + ora #1 ;N-----ZC + sta adrf + inc adrh ;result carry + jmp tdad ;iterate op2 + +tdad7 cpx #ad2 + trap_ne ;x altered during test + cpy #$ff + trap_ne ;y altered during test + tsx + cpx #$ff + trap_ne ;sp push/pop mismatch + cld + + lda test_case + cmp #test_num + trap_ne ;previous test is out of sequence + lda #$f0 ;mark opcode testing complete + sta test_case + +; final RAM integrity test +; verifies that none of the previous tests has altered RAM outside of the +; designated write areas. + check_ram +; *** DEBUG INFO *** +; to debug checksum errors uncomment check_ram in the next_test macro to +; narrow down the responsible opcode. +; may give false errors when monitor, OS or other background activity is +; allowed during previous tests. + + +; S U C C E S S ************************************************ +; ------------- + success ;if you get here everything went well +; ------------- +; S U C C E S S ************************************************ + jmp start ;run again + +; core subroutine of the decimal add/subtract test +; *** WARNING - tests documented behavior only! *** +; only valid BCD operands are tested, V flag is ignored +; iterates through all valid combinations of operands and carry input +; uses increments/decrements to predict result & carry flag +chkdad +; decimal ADC / SBC zp + php ;save carry for subtract + lda ad1 + adc ad2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sb2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC abs + php ;save carry for subtract + lda ad1 + adc ada2 ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2 ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC # + php ;save carry for subtract + lda ad2 + sta ex_adci+1 ;set ADC # operand + lda ad1 + jsr ex_adci ;execute ADC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda sb2 + sta ex_sbci+1 ;set SBC # operand + lda ad1 + jsr ex_sbci ;execute SBC # in RAM + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC zp,x + php ;save carry for subtract + lda ad1 + adc 0,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sb2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC abs,x + php ;save carry for subtract + lda ad1 + adc ada2-ad2,x ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2-ad2,x ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC abs,y + php ;save carry for subtract + lda ad1 + adc ada2-$ff,y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc sba2-$ff,y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC (zp,x) + php ;save carry for subtract + lda ad1 + adc (lo adi2-ad2,x) ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (lo sbi2-ad2,x) ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC (abs),y + php ;save carry for subtract + lda ad1 + adc (adiy2),y ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (sbiy2),y ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp +; decimal ADC / SBC (zp) + php ;save carry for subtract + lda ad1 + adc (adi2) ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (sbi2) ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$83 ;mask N-----ZC + cmp adrf + trap_ne ;bad flags + plp + rts + +; core subroutine of the full binary add/subtract test +; iterates through all combinations of operands and carry input +; uses increments/decrements to predict result & result flags +chkadd lda adrf ;add V-flag if overflow + and #$83 ;keep N-----ZC / clear V + pha + lda ad1 ;test sign unequal between operands + eor ad2 + bmi ckad1 ;no overflow possible - operands have different sign + lda ad1 ;test sign equal between operands and result + eor adrl + bpl ckad1 ;no overflow occured - operand and result have same sign + pla + ora #$40 ;set V + pha +ckad1 pla + sta adrf ;save expected flags +; binary ADC / SBC (zp) + php ;save carry for subtract + lda ad1 + adc (adi2) ;perform add + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + php ;save carry for next add + lda ad1 + sbc (sbi2) ;perform subtract + php + cmp adrl ;check result + trap_ne ;bad result + pla ;check flags + and #$c3 ;mask NV----ZC + cmp adrf + trap_ne ;bad flags + plp + rts + +; target for the jump indirect test +ji_adr dw test_ji + dw ji_ret + + dey + dey +test_ji + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_cs ;flags loaded? + trap_vs + trap_mi + trap_eq + cmp #'I' ;registers loaded? + trap_ne + cpx #'N' + trap_ne + cpy #('D'-3) + trap_ne + pha ;save a,x + txa + pha + tsx + cpx #$fd ;check SP + trap_ne + pla ;restore x + tax + set_stat $ff + pla ;restore a + inx ;return registers with modifications + eor #$aa ;N=1, V=1, Z=0, C=1 + jmp (ji_tab+2) + nop + nop + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +; target for the jump indirect test +jxi_adr dw trap_ind + dw trap_ind + dw test_jxi ;+4 + dw jxi_ret ;+6 + dw trap_ind + dw trap_ind + + dey + dey +test_jxi + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + plp + trap_cs ;flags loaded? + trap_vs + trap_mi + trap_eq + cmp #'X' ;registers loaded? + trap_ne + cpx #4 + trap_ne + cpy #('I'-3) + trap_ne + pha ;save a,x + txa + pha + tsx + cpx #$fd ;check SP + trap_ne + pla ;restore x + tax + set_stat $ff + pla ;restore a + inx ;return registers with modifications + inx + eor #$aa ;N=1, V=1, Z=0, C=1 + jmp (jxi_tab,x) + nop + nop + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +; JMP (abs,x) with bad x + nop + nop +trap_ind + nop + nop + trap ;near miss indexed indirect jump + jmp start ;catastrophic error - cannot continue + +;trap in case of unexpected IRQ, NMI, BRK, RESET +nmi_trap + trap ;check stack for conditions at NMI + jmp start ;catastrophic error - cannot continue +res_trap + trap ;unexpected RESET + jmp start ;catastrophic error - cannot continue + + dey + dey +irq_trap ;BRK test or unextpected BRK or IRQ + php ;either SP or Y count will fail, if we do not hit + dey + dey + dey + ;next traps could be caused by unexpected BRK or IRQ + ;check stack for BREAK and originating location + ;possible jump/branch into weeds (uninitialized space) + cmp #$ff-'B' ;BRK pass 2 registers loaded? + beq break2 + cmp #'B' ;BRK pass 1 registers loaded? + trap_ne + cpx #'R' + trap_ne + cpy #'K'-3 + trap_ne + sta irq_a ;save registers during break test + stx irq_x + tsx ;test break on stack + lda $102,x + cmp_flag 0 ;break test should have B=1 & unused=1 on stack + trap_ne ;possible no break flag on stack + pla + cmp_flag intdis ;should have added interrupt disable + trap_ne + tsx + cpx #$fc ;sp -3? (return addr, flags) + trap_ne + lda $1ff ;propper return on stack + cmp #hi(brk_ret0) + trap_ne + lda $1fe + cmp #lo(brk_ret0) + trap_ne + load_flag $ff + pha + ldx irq_x + inx ;return registers with modifications + lda irq_a + eor #$aa + plp ;N=1, V=1, Z=1, C=1 but original flags should be restored + rti + trap ;runover protection + jmp start ;catastrophic error - cannot continue + +break2 ;BRK pass 2 + cpx #$ff-'R' + trap_ne + cpy #$ff-'K'-3 + trap_ne + sta irq_a ;save registers during break test + stx irq_x + tsx ;test break on stack + lda $102,x + cmp_flag $ff ;break test should have B=1 + trap_ne ;possibly no break flag on stack + pla + cmp_flag $ff-decmode ;actual passed flags should have decmode cleared + trap_ne + tsx + cpx #$fc ;sp -3? (return addr, flags) + trap_ne + lda $1ff ;propper return on stack + cmp #hi(brk_ret1) + trap_ne + lda $1fe + cmp #lo(brk_ret1) + trap_ne + load_flag intdis + pha + ldx irq_x + inx ;return registers with modifications + lda irq_a + eor #$aa + plp ;N=0, V=0, Z=0, C=0 but original flags should be restored + rti + trap ;runover protection + jmp start ;catastrophic error - cannot continue + + if report = 1 + include "report.i65" + endif + +;copy of data to initialize BSS segment + if load_data_direct != 1 +zp_init +zp1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +zp7f_ db $7f ;test pattern for compare +;logical zeropage operands +zpOR_ db 0,$1f,$71,$80 ;test pattern for OR +zpAN_ db $0f,$ff,$7f,$80 ;test pattern for AND +zpEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR +;indirect addressing pointers +ind1_ dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f +inw1_ dw abs1-$f8 ;indirect pointer for wrap-test pattern +indt_ dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 +inwt_ dw abst-$f8 ;indirect pointer for wrap-test store +indAN_ dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 +indEO_ dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 +indOR_ dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 +;add/subtract indirect pointers +adi2_ dw ada2 ;indirect pointer to operand 2 in absolute memory +sbi2_ dw sba2 ;indirect pointer to complemented operand 2 (SBC) +adiy2_ dw ada2-$ff ;with offset for indirect indexed +sbiy2_ dw sba2-$ff +zp_end + if (zp_end - zp_init) != (zp_bss_end - zp_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and zeropage data + endif +data_init +ex_adc_ adc #0 ;execute immediate opcodes + rts +ex_sbc_ sbc #0 ;execute immediate opcodes + rts +abs1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +abs7f_ db $7f ;test pattern for compare +;loads +fLDx_ db fn,fn,0,fz ;expected flags for load +;shifts +rASL_ ;expected result ASL & ROL -carry +rROL_ db $86,$04,$82,0 ; " +rROLc_ db $87,$05,$83,1 ;expected result ROL +carry +rLSR_ ;expected result LSR & ROR -carry +rROR_ db $61,$41,$20,0 ; " +rRORc_ db $e1,$c1,$a0,$80 ;expected result ROR +carry +fASL_ ;expected flags for shifts +fROL_ db fnc,fc,fn,fz ;no carry in +fROLc_ db fnc,fc,fn,0 ;carry in +fLSR_ +fROR_ db fc,0,fc,fz ;no carry in +fRORc_ db fnc,fn,fnc,fn ;carry in +;increments (decrements) +rINC_ db $7f,$80,$ff,0,1 ;expected result for INC/DEC +fINC_ db 0,fn,fn,fz,0 ;expected flags for INC/DEC +;logical memory operand +absOR_ db 0,$1f,$71,$80 ;test pattern for OR +absAN_ db $0f,$ff,$7f,$80 ;test pattern for AND +absEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR +;logical accu operand +absORa_ db 0,$f1,$1f,0 ;test pattern for OR +absANa_ db $f0,$ff,$ff,$ff ;test pattern for AND +absEOa_ db $ff,$f0,$f0,$0f ;test pattern for EOR +;logical results +absrlo_ db 0,$ff,$7f,$80 +absflo_ db fz,fn,0,fn +data_end + if (data_end - data_init) != (data_bss_end - data_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and data + endif + +vec_init + dw nmi_trap + dw res_trap + dw irq_trap +vec_bss equ $fffa + endif ;end of RAM init data + +; code at end of image due to the need to add blank space as required + if ($ff & (ji_ret - * - 2)) < ($ff & (jxi_ret - * - 2)) +; JMP (abs) when $xxff and $xx00 are from same page + ds lo(ji_ret - * - 2) + nop + nop +ji_px nop ;low address byte matched with ji_ret + nop + trap ;jmp indirect page cross bug + +; JMP (abs,x) when $xxff and $xx00 are from same page + ds lo(jxi_ret - * - 2) + nop + nop +jxi_px nop ;low address byte matched with jxi_ret + nop + trap ;jmp indexed indirect page cross bug + else +; JMP (abs,x) when $xxff and $xx00 are from same page + ds lo(jxi_ret - * - 2) + nop + nop +jxi_px nop ;low address byte matched with jxi_ret + nop + trap ;jmp indexed indirect page cross bug + +; JMP (abs) when $xxff and $xx00 are from same page + ds lo(ji_ret - * - 2) + nop + nop +ji_px nop ;low address byte matched with ji_ret + nop + trap ;jmp indirect page cross bug + endif + + if (load_data_direct = 1) & (ROM_vectors = 1) + org $fffa ;vectors + dw nmi_trap + dw res_trap + dw irq_trap + endif + + end start diff --git a/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.bin b/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.bin new file mode 100644 index 0000000..c9a35e1 Binary files /dev/null and b/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.bin differ diff --git a/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.lst b/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.lst new file mode 100644 index 0000000..d178888 --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.lst @@ -0,0 +1,14360 @@ +AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1 +---------------------------------------------------- 6502_functional_test.a65 ---------------------------------------------------- + +6104 lines read, no errors in pass 1. + ; + ; 6 5 0 2 F U N C T I O N A L T E S T + ; + ; Copyright (C) 2012-2015 Klaus Dormann + ; + ; This program is free software: you can redistribute it and/or modify + ; it under the terms of the GNU General Public License as published by + ; the Free Software Foundation, either version 3 of the License, or + ; (at your option) any later version. + ; + ; This program is distributed in the hope that it will be useful, + ; but WITHOUT ANY WARRANTY; without even the implied warranty of + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ; GNU General Public License for more details. + ; + ; You should have received a copy of the GNU General Public License + ; along with this program. If not, see . + + + ; This program is designed to test all opcodes of a 6502 emulator using all + ; addressing modes with focus on propper setting of the processor status + ; register bits. + ; + ; version 04-dec-2017 + ; contact info at http://2m5.de or email K@2m5.de + ; + ; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/ + ; command line switches: -l -m -s2 -w -h0 + ; | | | | no page headers in listing + ; | | | wide listing (133 char/col) + ; | | write intel hex file instead of binary + ; | expand macros in listing + ; generate pass2 listing + ; + ; No IO - should be run from a monitor with access to registers. + ; To run load intel hex image with a load command, than alter PC to 400 hex + ; (code_segment) and enter a go command. + ; Loop on program counter determines error or successful completion of test. + ; Check listing for relevant traps (jump/branch *). + ; Please note that in early tests some instructions will have to be used before + ; they are actually tested! + ; + ; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled. + ; Tests documented behavior of the original NMOS 6502 only! No unofficial + ; opcodes. Additional opcodes of newer versions of the CPU (65C02, 65816) will + ; not be tested. Decimal ops will only be tested with valid BCD operands and + ; N V Z flags will be ignored. + ; + ; Debugging hints: + ; Most of the code is written sequentially. if you hit a trap, check the + ; immediately preceeding code for the instruction to be tested. Results are + ; tested first, flags are checked second by pushing them onto the stack and + ; pulling them to the accumulator after the result was checked. The "real" + ; flags are no longer valid for the tested instruction at this time! + ; If the tested instruction was indexed, the relevant index (X or Y) must + ; also be checked. Opposed to the flags, X and Y registers are still valid. + ; + ; versions: + ; 28-jul-2012 1st version distributed for testing + ; 29-jul-2012 fixed references to location 0, now #0 + ; added license - GPLv3 + ; 30-jul-2012 added configuration options + ; 01-aug-2012 added trap macro to allow user to change error handling + ; 01-dec-2012 fixed trap in branch field must be a branch + ; 02-mar-2013 fixed PLA flags not tested + ; 19-jul-2013 allowed ROM vectors to be loaded when load_data_direct = 0 + ; added test sequence check to detect if tests jump their fence + ; 23-jul-2013 added RAM integrity check option + ; 16-aug-2013 added error report to standard output option + ; 13-dec-2014 added binary/decimal opcode table switch test + ; 14-dec-2014 improved relative address test + ; 23-aug-2015 added option to disable self modifying tests + ; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM + ; added small branch offset pretest + ; 21-oct-2015 added option to disable decimal mode ADC & SBC tests + ; 04-dec-2017 fixed BRK only tested with interrupts enabled + ; added option to skip the remainder of a failing test + ; in report.i65 + + + ; C O N F I G U R A T I O N + + ;ROM_vectors writable (0=no, 1=yes) + ;if ROM vectors can not be used interrupts will not be trapped + ;as a consequence BRK can not be tested but will be emulated to test RTI +0001 = ROM_vectors = 1 + + ;load_data_direct (0=move from code segment, 1=load directly) + ;loading directly is preferred but may not be supported by your platform + ;0 produces only consecutive object code, 1 is not suitable for a binary image +0001 = load_data_direct = 1 + + ;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow + ;change) 2 requires extra code and is not recommended. SEI & CLI can only be + ;tested if you allow changing the interrupt status (I_flag = 3) +0003 = I_flag = 3 + + ;configure memory - try to stay away from memory used by the system + ;zero_page memory start address, $50 (80) consecutive Bytes required + ; add 2 if I_flag = 2 +000a = zero_page = $a + + ;data_segment memory start address, $6A (106) consecutive Bytes required +0200 = data_segment = $200 + if (data_segment & $ff) != 0 + ERROR ERROR ERROR low byte of data_segment MUST be $00 !! + endif + + ;code_segment memory start address, 13kB of consecutive space required + ; add 2.5 kB if I_flag = 2 +0400 = code_segment = $400 + + ;self modifying code may be disabled to allow running in ROM + ;0=part of the code is self modifying and must reside in RAM + ;1=tests disabled: branch range +0000 = disable_selfmod = 0 + + ;report errors through I/O channel (0=use standard self trap loops, 1=include + ;report.i65 as I/O channel, add 3.5 kB) +0000 = report = 0 + + ;RAM integrity test option. Checks for undesired RAM writes. + ;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k) + ;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM +ffff = ram_top = -1 + + ;disable test decimal mode ADC & SBC, 0=enable, 1=disable, + ;2=disable including decimal flag in processor status +0000 = disable_decimal = 0 + + noopt ;do not take shortcuts + + ;macros for error & success traps to allow user modification + ;example: + ;trap macro + ; jsr my_error_handler + ; endm + ;trap_eq macro + ; bne skip\? + ; trap ;failed equal (zero) + ;skip\? + ; endm + ; + ; my_error_handler should pop the calling address from the stack and report it. + ; putting larger portions of code (more than 3 bytes) inside the trap macro + ; may lead to branch range problems for some tests. + if report = 0 + trap macro + jmp * ;failed anyway + endm + trap_eq macro + beq * ;failed equal (zero) + endm + trap_ne macro + bne * ;failed not equal (non zero) + endm + trap_cs macro + bcs * ;failed carry set + endm + trap_cc macro + bcc * ;failed carry clear + endm + trap_mi macro + bmi * ;failed minus (bit 7 set) + endm + trap_pl macro + bpl * ;failed plus (bit 7 clear) + endm + trap_vs macro + bvs * ;failed overflow set + endm + trap_vc macro + bvc * ;failed overflow clear + endm + ; please observe that during the test the stack gets invalidated + ; therefore a RTS inside the success macro is not possible + success macro + jmp * ;test passed, no errors + endm + endif + if report = 1 + trap macro + jsr report_error + endm + trap_eq macro + bne skip\? + trap ;failed equal (zero) + skip\? + endm + trap_ne macro + beq skip\? + trap ;failed not equal (non zero) + skip\? + endm + trap_cs macro + bcc skip\? + trap ;failed carry set + skip\? + endm + trap_cc macro + bcs skip\? + trap ;failed carry clear + skip\? + endm + trap_mi macro + bpl skip\? + trap ;failed minus (bit 7 set) + skip\? + endm + trap_pl macro + bmi skip\? + trap ;failed plus (bit 7 clear) + skip\? + endm + trap_vs macro + bvc skip\? + trap ;failed overflow set + skip\? + endm + trap_vc macro + bvs skip\? + trap ;failed overflow clear + skip\? + endm + ; please observe that during the test the stack gets invalidated + ; therefore a RTS inside the success macro is not possible + success macro + jsr report_success + endm + endif + + +0001 = carry equ %00000001 ;flag bits in status +0002 = zero equ %00000010 +0004 = intdis equ %00000100 +0008 = decmode equ %00001000 +0010 = break equ %00010000 +0020 = reserv equ %00100000 +0040 = overfl equ %01000000 +0080 = minus equ %10000000 + +0001 = fc equ carry +0002 = fz equ zero +0003 = fzc equ carry+zero +0040 = fv equ overfl +0042 = fvz equ overfl+zero +0080 = fn equ minus +0081 = fnc equ minus+carry +0082 = fnz equ minus+zero +0083 = fnzc equ minus+zero+carry +00c0 = fnv equ minus+overfl + +0030 = fao equ break+reserv ;bits always on after PHP, BRK +0034 = fai equ fao+intdis ;+ forced interrupt disable +0038 = faod equ fao+decmode ;+ ignore decimal +003c = faid equ fai+decmode ;+ ignore decimal +00ff = m8 equ $ff ;8 bit mask +00fb = m8i equ $ff&~intdis ;8 bit mask - interrupt disable + + ;macros to allow masking of status bits. + ;masking test of decimal bit + ;masking of interrupt enable/disable on load and compare + ;masking of always on bits after PHP or BRK (unused & break) on compare + if disable_decimal < 2 + if I_flag = 0 + load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm + cmp_flag macro + cmp #(\1|fao)&m8i ;I_flag is always enabled + always on bits + endm + eor_flag macro + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 + load_flag macro + lda #\1|intdis ;force disable interrupts + endm + cmp_flag macro + cmp #(\1|fai)&m8 ;I_flag is always disabled + always on bits + endm + eor_flag macro + eor #(\1|fai) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 + load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm + cmp_flag macro + eor flag_I_on ;I_flag is never changed + cmp #(\1|fao)&m8i ;expected flags + always on bits, mask I + endm + eor_flag macro + eor flag_I_on ;I_flag is never changed + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 + load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm + cmp_flag macro + cmp #(\1|fao)&m8 ;expected flags + always on bits + endm + eor_flag macro + eor #\1|fao ;invert expected flags + always on bits + endm + endif + else + if I_flag = 0 + load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm + cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8i ;I_flag is always enabled + always on bits + endm + eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #(\1&m8i|faod) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 + load_flag macro + lda #\1|intdis ;force disable interrupts + endm + cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faid)&m8 ;I_flag is always disabled + always on bits + endm + eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #(\1|faid) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 + load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm + cmp_flag macro + eor flag_I_on ;I_flag is never changed + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8i ;expected flags + always on bits, mask I + endm + eor_flag macro + eor flag_I_on ;I_flag is never changed + ora #decmode ;ignore decimal mode bit + eor #(\1&m8i|faod) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 + load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm + cmp_flag macro + ora #decmode ;ignore decimal mode bit + cmp #(\1|faod)&m8 ;expected flags + always on bits + endm + eor_flag macro + ora #decmode ;ignore decimal mode bit + eor #\1|faod ;invert expected flags + always on bits + endm + endif + endif + + ;macros to set (register|memory|zeropage) & status + set_stat macro ;setting flags in the processor status register + load_flag \1 + pha ;use stack to load status + plp + endm + + set_a macro ;precharging accu & status + load_flag \2 + pha ;use stack to load status + lda #\1 ;precharge accu + plp + endm + + set_x macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldx #\1 ;precharge index x + plp + endm + + set_y macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldy #\1 ;precharge index y + plp + endm + + set_ax macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;precharge accu + plp + endm + + set_ay macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,y ;precharge accu + plp + endm + + set_z macro ;precharging indexed zp & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to zeropage + sta zpt + plp + endm + + set_zx macro ;precharging zp,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed zeropage + sta zpt,x + plp + endm + + set_abs macro ;precharging indexed memory & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to memory + sta abst + plp + endm + + set_absx macro ;precharging abs,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed memory + sta abst,x + plp + endm + + ;macros to test (register|memory|zeropage) & status & (mask) + tst_stat macro ;testing flags in the processor status register + php ;save status + pla ;use stack to retrieve status + pha + cmp_flag \1 + trap_ne + plp ;restore status + endm + + tst_a macro ;testing result in accu & flags + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_x macro ;testing result in x index & flags + php ;save flags + cpx #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_y macro ;testing result in y index & flags + php ;save flags + cpy #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_ax macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne ; + endm + + tst_ay macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,y ;test result + trap_ne ; + pla ;load status + eor_flag \3 + cmp \2,y ;test flags + trap_ne + endm + + tst_z macro ;indexed testing result in zp & flags + php ;save flags + lda zpt + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_zx macro ;testing result in zp,x & flags + php ;save flags + lda zpt,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_abs macro ;indexed testing result in memory & flags + php ;save flags + lda abst + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_absx macro ;testing result in abs,x & flags + php ;save flags + lda abst,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + ; RAM integrity test + ; verifies that none of the previous tests has altered RAM outside of the + ; designated write areas. + ; uses zpt word as indirect pointer, zpt+2 word as checksum + if ram_top > -1 + check_ram macro + cld + lda #0 + sta zpt ;set low byte of indirect pointer + sta zpt+3 ;checksum high byte + if disable_selfmod = 0 + sta range_adr ;reset self modifying code + endif + clc + ldx #zp_bss-zero_page ;zeropage - write test area + ccs3\? adc zero_page,x + bcc ccs2\? + inc zpt+3 ;carry to high byte + clc + ccs2\? inx + bne ccs3\? + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area + ccs5\? adc (zpt),y + bcc ccs4\? + inc zpt+3 ;carry to high byte + clc + ccs4\? iny + bne ccs5\? + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne ccs5\? + sta zpt+2 ;checksum low is + cmp ram_chksm ;checksum low expected + trap_ne ;checksum mismatch + lda zpt+3 ;checksum high is + cmp ram_chksm+1 ;checksum high expected + trap_ne ;checksum mismatch + endm + else + check_ram macro + ;RAM check disabled - RAM size not set + endm + endif + + next_test macro ;make sure, tests don't jump the fence + lda test_case ;previous test + cmp #test_num + trap_ne ;test is out of sequence + test_num = test_num + 1 + lda #test_num ;*** next tests' number + sta test_case + ;check_ram ;uncomment to find altered RAM after each test + endm + + if load_data_direct = 1 + data + else + bss ;uninitialized segment, copy of data at end of code! + endif + ; org zero_page +0000 = org 0 ;edited to provide binaries loading from 0 +0000 : 00000000000000.. ds zero_page + ;break test interrupt save +000a : 00 irq_a ds 1 ;a register +000b : 00 irq_x ds 1 ;x register + if I_flag = 2 + ;masking for I bit in status + flag_I_on ds 1 ;or mask to load flags + flag_I_off ds 1 ;and mask to load flags + endif +000c : zpt ;5 bytes store/modify test area + ;add/subtract operand generation and result/flag prediction +000c : 00 adfc ds 1 ;carry flag before op +000d : 00 ad1 ds 1 ;operand 1 - accumulator +000e : 00 ad2 ds 1 ;operand 2 - memory / immediate +000f : 00 adrl ds 1 ;expected result bits 0-7 +0010 : 00 adrh ds 1 ;expected result bit 8 (carry) +0011 : 00 adrf ds 1 ;expected flags NV0000ZC (only binary mode) +0012 : 00 sb2 ds 1 ;operand 2 complemented for subtract +0013 : zp_bss +0013 : c3824100 zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +0017 : 7f zp7f db $7f ;test pattern for compare + ;logical zeropage operands +0018 : 001f7180 zpOR db 0,$1f,$71,$80 ;test pattern for OR +001c : 0fff7f80 zpAN db $0f,$ff,$7f,$80 ;test pattern for AND +0020 : ff0f8f8f zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR + ;indirect addressing pointers +0024 : 1702 ind1 dw abs1 ;indirect pointer to pattern in absolute memory +0026 : 1802 dw abs1+1 +0028 : 1902 dw abs1+2 +002a : 1a02 dw abs1+3 +002c : 1b02 dw abs7f +002e : 1f01 inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern +0030 : 0302 indt dw abst ;indirect pointer to store area in absolute memory +0032 : 0402 dw abst+1 +0034 : 0502 dw abst+2 +0036 : 0602 dw abst+3 +0038 : 0b01 inwt dw abst-$f8 ;indirect pointer for wrap-test store +003a : 4e02 indAN dw absAN ;indirect pointer to AND pattern in absolute memory +003c : 4f02 dw absAN+1 +003e : 5002 dw absAN+2 +0040 : 5102 dw absAN+3 +0042 : 5202 indEO dw absEO ;indirect pointer to EOR pattern in absolute memory +0044 : 5302 dw absEO+1 +0046 : 5402 dw absEO+2 +0048 : 5502 dw absEO+3 +004a : 4a02 indOR dw absOR ;indirect pointer to OR pattern in absolute memory +004c : 4b02 dw absOR+1 +004e : 4c02 dw absOR+2 +0050 : 4d02 dw absOR+3 + ;add/subtract indirect pointers +0052 : 0302 adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory +0054 : 0402 sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC) +0056 : 0401 adiy2 dw ada2-$ff ;with offset for indirect indexed +0058 : 0501 sbiy2 dw sba2-$ff +005a : zp_bss_end + +0200 = org data_segment +0200 : 00 test_case ds 1 ;current test number +0201 : 0000 ram_chksm ds 2 ;checksum for RAM integrity test + ;add/subtract operand copy - abs tests write area +0203 : abst ;5 bytes store/modify test area +0203 : 00 ada2 ds 1 ;operand 2 +0204 : 00 sba2 ds 1 ;operand 2 complemented for subtract +0205 : 000000 ds 3 ;fill remaining bytes +0208 : data_bss + if load_data_direct = 1 +0208 : 2900 ex_andi and #0 ;execute immediate opcodes +020a : 60 rts +020b : 4900 ex_eori eor #0 ;execute immediate opcodes +020d : 60 rts +020e : 0900 ex_orai ora #0 ;execute immediate opcodes +0210 : 60 rts +0211 : 6900 ex_adci adc #0 ;execute immediate opcodes +0213 : 60 rts +0214 : e900 ex_sbci sbc #0 ;execute immediate opcodes +0216 : 60 rts + else + ex_andi ds 3 + ex_eori ds 3 + ex_orai ds 3 + ex_adci ds 3 + ex_sbci ds 3 + endif +0217 : c3824100 abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +021b : 7f abs7f db $7f ;test pattern for compare + ;loads +021c : 80800002 fLDx db fn,fn,0,fz ;expected flags for load + ;shifts +0220 : rASL ;expected result ASL & ROL -carry +0220 : 86048200 rROL db $86,$04,$82,0 ; " +0224 : 87058301 rROLc db $87,$05,$83,1 ;expected result ROL +carry +0228 : rLSR ;expected result LSR & ROR -carry +0228 : 61412000 rROR db $61,$41,$20,0 ; " +022c : e1c1a080 rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry +0230 : fASL ;expected flags for shifts +0230 : 81018002 fROL db fnc,fc,fn,fz ;no carry in +0234 : 81018000 fROLc db fnc,fc,fn,0 ;carry in +0238 : fLSR +0238 : 01000102 fROR db fc,0,fc,fz ;no carry in +023c : 81808180 fRORc db fnc,fn,fnc,fn ;carry in + ;increments (decrements) +0240 : 7f80ff0001 rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC +0245 : 0080800200 fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC + ;logical memory operand +024a : 001f7180 absOR db 0,$1f,$71,$80 ;test pattern for OR +024e : 0fff7f80 absAN db $0f,$ff,$7f,$80 ;test pattern for AND +0252 : ff0f8f8f absEO db $ff,$0f,$8f,$8f ;test pattern for EOR + ;logical accu operand +0256 : 00f11f00 absORa db 0,$f1,$1f,0 ;test pattern for OR +025a : f0ffffff absANa db $f0,$ff,$ff,$ff ;test pattern for AND +025e : fff0f00f absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR + ;logical results +0262 : 00ff7f80 absrlo db 0,$ff,$7f,$80 +0266 : 02800080 absflo db fz,fn,0,fn +026a : data_bss_end + + + code +0400 = org code_segment +0400 : d8 start cld +0401 : a2ff ldx #$ff +0403 : 9a txs +0404 : a900 lda #0 ;*** test 0 = initialize +0406 : 8d0002 sta test_case +0000 = test_num = 0 + + ;stop interrupts before initializing BSS + if I_flag = 1 + sei + endif + + ;initialize I/O for report channel + if report = 1 + jsr report_init + endif + + ;pretest small branch offset +0409 : a205 ldx #5 +040b : 4c3304 jmp psb_test +040e : psb_bwok +040e : a005 ldy #5 +0410 : d008 bne psb_forw + trap ;branch should be taken +0412 : 4c1204 > jmp * ;failed anyway + +0415 : 88 dey ;forward landing zone +0416 : 88 dey +0417 : 88 dey +0418 : 88 dey +0419 : 88 dey +041a : psb_forw +041a : 88 dey +041b : 88 dey +041c : 88 dey +041d : 88 dey +041e : 88 dey +041f : f017 beq psb_fwok + trap ;forward offset +0421 : 4c2104 > jmp * ;failed anyway + + +0424 : ca dex ;backward landing zone +0425 : ca dex +0426 : ca dex +0427 : ca dex +0428 : ca dex +0429 : psb_back +0429 : ca dex +042a : ca dex +042b : ca dex +042c : ca dex +042d : ca dex +042e : f0de beq psb_bwok + trap ;backward offset +0430 : 4c3004 > jmp * ;failed anyway + +0433 : psb_test +0433 : d0f4 bne psb_back + trap ;branch should be taken +0435 : 4c3504 > jmp * ;failed anyway + +0438 : psb_fwok + + ;initialize BSS segment + if load_data_direct != 1 + ldx #zp_end-zp_init-1 + ld_zp lda zp_init,x + sta zp_bss,x + dex + bpl ld_zp + ldx #data_end-data_init-1 + ld_data lda data_init,x + sta data_bss,x + dex + bpl ld_data + if ROM_vectors = 1 + ldx #5 + ld_vect lda vec_init,x + sta vec_bss,x + dex + bpl ld_vect + endif + endif + + ;retain status of interrupt flag + if I_flag = 2 + php + pla + and #4 ;isolate flag + sta flag_I_on ;or mask + eor #lo(~4) ;reverse + sta flag_I_off ;and mask + endif + + ;generate checksum for RAM integrity test + if ram_top > -1 + lda #0 + sta zpt ;set low byte of indirect pointer + sta ram_chksm+1 ;checksum high byte + if disable_selfmod = 0 + sta range_adr ;reset self modifying code + endif + clc + ldx #zp_bss-zero_page ;zeropage - write test area + gcs3 adc zero_page,x + bcc gcs2 + inc ram_chksm+1 ;carry to high byte + clc + gcs2 inx + bne gcs3 + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area + gcs5 adc (zpt),y + bcc gcs4 + inc ram_chksm+1 ;carry to high byte + clc + gcs4 iny + bne gcs5 + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne gcs5 + sta ram_chksm ;checksum complete + endif + next_test +0438 : ad0002 > lda test_case ;previous test +043b : c900 > cmp #test_num + > trap_ne ;test is out of sequence +043d : d0fe > bne * ;failed not equal (non zero) + > +0001 = >test_num = test_num + 1 +043f : a901 > lda #test_num ;*** next tests' number +0441 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + if disable_selfmod = 0 + ;testing relative addressing with BEQ +0444 : a0fe ldy #$fe ;testing maximum range, not -1/-2 (invalid/self adr) +0446 : range_loop +0446 : 88 dey ;next relative address +0447 : 98 tya +0448 : aa tax ;precharge count to end of loop +0449 : 1008 bpl range_fw ;calculate relative address +044b : 18 clc ;avoid branch self or to relative address of branch +044c : 6902 adc #2 +044e : ea nop ;offset landing zone - tolerate +/-5 offset to branch +044f : ea nop +0450 : ea nop +0451 : ea nop +0452 : ea nop +0453 : range_fw +0453 : ea nop +0454 : ea nop +0455 : ea nop +0456 : ea nop +0457 : ea nop +0458 : 497f eor #$7f ;complement except sign +045a : 8de604 sta range_adr ;load into test target +045d : a900 lda #0 ;should set zero flag in status register +045f : 4ce504 jmp range_op + +0462 : ca dex ; offset landing zone - backward branch too far +0463 : ca dex +0464 : ca dex +0465 : ca dex +0466 : ca dex + ;relative address target field with branch under test in the middle +0467 : ca dex ;-128 - max backward +0468 : ca dex +0469 : ca dex +046a : ca dex +046b : ca dex +046c : ca dex +046d : ca dex +046e : ca dex +046f : ca dex ;-120 +0470 : ca dex +0471 : ca dex +0472 : ca dex +0473 : ca dex +0474 : ca dex +0475 : ca dex +0476 : ca dex +0477 : ca dex +0478 : ca dex +0479 : ca dex ;-110 +047a : ca dex +047b : ca dex +047c : ca dex +047d : ca dex +047e : ca dex +047f : ca dex +0480 : ca dex +0481 : ca dex +0482 : ca dex +0483 : ca dex ;-100 +0484 : ca dex +0485 : ca dex +0486 : ca dex +0487 : ca dex +0488 : ca dex +0489 : ca dex +048a : ca dex +048b : ca dex +048c : ca dex +048d : ca dex ;-90 +048e : ca dex +048f : ca dex +0490 : ca dex +0491 : ca dex +0492 : ca dex +0493 : ca dex +0494 : ca dex +0495 : ca dex +0496 : ca dex +0497 : ca dex ;-80 +0498 : ca dex +0499 : ca dex +049a : ca dex +049b : ca dex +049c : ca dex +049d : ca dex +049e : ca dex +049f : ca dex +04a0 : ca dex +04a1 : ca dex ;-70 +04a2 : ca dex +04a3 : ca dex +04a4 : ca dex +04a5 : ca dex +04a6 : ca dex +04a7 : ca dex +04a8 : ca dex +04a9 : ca dex +04aa : ca dex +04ab : ca dex ;-60 +04ac : ca dex +04ad : ca dex +04ae : ca dex +04af : ca dex +04b0 : ca dex +04b1 : ca dex +04b2 : ca dex +04b3 : ca dex +04b4 : ca dex +04b5 : ca dex ;-50 +04b6 : ca dex +04b7 : ca dex +04b8 : ca dex +04b9 : ca dex +04ba : ca dex +04bb : ca dex +04bc : ca dex +04bd : ca dex +04be : ca dex +04bf : ca dex ;-40 +04c0 : ca dex +04c1 : ca dex +04c2 : ca dex +04c3 : ca dex +04c4 : ca dex +04c5 : ca dex +04c6 : ca dex +04c7 : ca dex +04c8 : ca dex +04c9 : ca dex ;-30 +04ca : ca dex +04cb : ca dex +04cc : ca dex +04cd : ca dex +04ce : ca dex +04cf : ca dex +04d0 : ca dex +04d1 : ca dex +04d2 : ca dex +04d3 : ca dex ;-20 +04d4 : ca dex +04d5 : ca dex +04d6 : ca dex +04d7 : ca dex +04d8 : ca dex +04d9 : ca dex +04da : ca dex +04db : ca dex +04dc : ca dex +04dd : ca dex ;-10 +04de : ca dex +04df : ca dex +04e0 : ca dex +04e1 : ca dex +04e2 : ca dex +04e3 : ca dex +04e4 : ca dex ;-3 +04e5 : range_op ;test target with zero flag=0, z=1 if previous dex +04e6 = range_adr = *+1 ;modifiable relative address +04e5 : f03e beq *+64 ;+64 if called without modification +04e7 : ca dex ;+0 +04e8 : ca dex +04e9 : ca dex +04ea : ca dex +04eb : ca dex +04ec : ca dex +04ed : ca dex +04ee : ca dex +04ef : ca dex +04f0 : ca dex +04f1 : ca dex ;+10 +04f2 : ca dex +04f3 : ca dex +04f4 : ca dex +04f5 : ca dex +04f6 : ca dex +04f7 : ca dex +04f8 : ca dex +04f9 : ca dex +04fa : ca dex +04fb : ca dex ;+20 +04fc : ca dex +04fd : ca dex +04fe : ca dex +04ff : ca dex +0500 : ca dex +0501 : ca dex +0502 : ca dex +0503 : ca dex +0504 : ca dex +0505 : ca dex ;+30 +0506 : ca dex +0507 : ca dex +0508 : ca dex +0509 : ca dex +050a : ca dex +050b : ca dex +050c : ca dex +050d : ca dex +050e : ca dex +050f : ca dex ;+40 +0510 : ca dex +0511 : ca dex +0512 : ca dex +0513 : ca dex +0514 : ca dex +0515 : ca dex +0516 : ca dex +0517 : ca dex +0518 : ca dex +0519 : ca dex ;+50 +051a : ca dex +051b : ca dex +051c : ca dex +051d : ca dex +051e : ca dex +051f : ca dex +0520 : ca dex +0521 : ca dex +0522 : ca dex +0523 : ca dex ;+60 +0524 : ca dex +0525 : ca dex +0526 : ca dex +0527 : ca dex +0528 : ca dex +0529 : ca dex +052a : ca dex +052b : ca dex +052c : ca dex +052d : ca dex ;+70 +052e : ca dex +052f : ca dex +0530 : ca dex +0531 : ca dex +0532 : ca dex +0533 : ca dex +0534 : ca dex +0535 : ca dex +0536 : ca dex +0537 : ca dex ;+80 +0538 : ca dex +0539 : ca dex +053a : ca dex +053b : ca dex +053c : ca dex +053d : ca dex +053e : ca dex +053f : ca dex +0540 : ca dex +0541 : ca dex ;+90 +0542 : ca dex +0543 : ca dex +0544 : ca dex +0545 : ca dex +0546 : ca dex +0547 : ca dex +0548 : ca dex +0549 : ca dex +054a : ca dex +054b : ca dex ;+100 +054c : ca dex +054d : ca dex +054e : ca dex +054f : ca dex +0550 : ca dex +0551 : ca dex +0552 : ca dex +0553 : ca dex +0554 : ca dex +0555 : ca dex ;+110 +0556 : ca dex +0557 : ca dex +0558 : ca dex +0559 : ca dex +055a : ca dex +055b : ca dex +055c : ca dex +055d : ca dex +055e : ca dex +055f : ca dex ;+120 +0560 : ca dex +0561 : ca dex +0562 : ca dex +0563 : ca dex +0564 : ca dex +0565 : ca dex +0566 : ea nop ;offset landing zone - forward branch too far +0567 : ea nop +0568 : ea nop +0569 : ea nop +056a : ea nop +056b : f008 beq range_ok ;+127 - max forward + trap ; bad range +056d : 4c6d05 > jmp * ;failed anyway + +0570 : ea nop ;offset landing zone - tolerate +/-5 offset to branch +0571 : ea nop +0572 : ea nop +0573 : ea nop +0574 : ea nop +0575 : range_ok +0575 : ea nop +0576 : ea nop +0577 : ea nop +0578 : ea nop +0579 : ea nop +057a : c000 cpy #0 +057c : f003 beq range_end +057e : 4c4604 jmp range_loop +0581 : range_end ;range test successful + endif + next_test +0581 : ad0002 > lda test_case ;previous test +0584 : c901 > cmp #test_num + > trap_ne ;test is out of sequence +0586 : d0fe > bne * ;failed not equal (non zero) + > +0002 = >test_num = test_num + 1 +0588 : a902 > lda #test_num ;*** next tests' number +058a : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ;partial test BNE & CMP, CPX, CPY immediate +058d : c001 cpy #1 ;testing BNE true +058f : d003 bne test_bne + trap +0591 : 4c9105 > jmp * ;failed anyway + +0594 : test_bne +0594 : a900 lda #0 +0596 : c900 cmp #0 ;test compare immediate + trap_ne +0598 : d0fe > bne * ;failed not equal (non zero) + + trap_cc +059a : 90fe > bcc * ;failed carry clear + + trap_mi +059c : 30fe > bmi * ;failed minus (bit 7 set) + +059e : c901 cmp #1 + trap_eq +05a0 : f0fe > beq * ;failed equal (zero) + + trap_cs +05a2 : b0fe > bcs * ;failed carry set + + trap_pl +05a4 : 10fe > bpl * ;failed plus (bit 7 clear) + +05a6 : aa tax +05a7 : e000 cpx #0 ;test compare x immediate + trap_ne +05a9 : d0fe > bne * ;failed not equal (non zero) + + trap_cc +05ab : 90fe > bcc * ;failed carry clear + + trap_mi +05ad : 30fe > bmi * ;failed minus (bit 7 set) + +05af : e001 cpx #1 + trap_eq +05b1 : f0fe > beq * ;failed equal (zero) + + trap_cs +05b3 : b0fe > bcs * ;failed carry set + + trap_pl +05b5 : 10fe > bpl * ;failed plus (bit 7 clear) + +05b7 : a8 tay +05b8 : c000 cpy #0 ;test compare y immediate + trap_ne +05ba : d0fe > bne * ;failed not equal (non zero) + + trap_cc +05bc : 90fe > bcc * ;failed carry clear + + trap_mi +05be : 30fe > bmi * ;failed minus (bit 7 set) + +05c0 : c001 cpy #1 + trap_eq +05c2 : f0fe > beq * ;failed equal (zero) + + trap_cs +05c4 : b0fe > bcs * ;failed carry set + + trap_pl +05c6 : 10fe > bpl * ;failed plus (bit 7 clear) + + next_test +05c8 : ad0002 > lda test_case ;previous test +05cb : c902 > cmp #test_num + > trap_ne ;test is out of sequence +05cd : d0fe > bne * ;failed not equal (non zero) + > +0003 = >test_num = test_num + 1 +05cf : a903 > lda #test_num ;*** next tests' number +05d1 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + ;testing stack operations PHA PHP PLA PLP + +05d4 : a2ff ldx #$ff ;initialize stack +05d6 : 9a txs +05d7 : a955 lda #$55 +05d9 : 48 pha +05da : a9aa lda #$aa +05dc : 48 pha +05dd : cdfe01 cmp $1fe ;on stack ? + trap_ne +05e0 : d0fe > bne * ;failed not equal (non zero) + +05e2 : ba tsx +05e3 : 8a txa ;overwrite accu +05e4 : c9fd cmp #$fd ;sp decremented? + trap_ne +05e6 : d0fe > bne * ;failed not equal (non zero) + +05e8 : 68 pla +05e9 : c9aa cmp #$aa ;successful retreived from stack? + trap_ne +05eb : d0fe > bne * ;failed not equal (non zero) + +05ed : 68 pla +05ee : c955 cmp #$55 + trap_ne +05f0 : d0fe > bne * ;failed not equal (non zero) + +05f2 : cdff01 cmp $1ff ;remains on stack? + trap_ne +05f5 : d0fe > bne * ;failed not equal (non zero) + +05f7 : ba tsx +05f8 : e0ff cpx #$ff ;sp incremented? + trap_ne +05fa : d0fe > bne * ;failed not equal (non zero) + + next_test +05fc : ad0002 > lda test_case ;previous test +05ff : c903 > cmp #test_num + > trap_ne ;test is out of sequence +0601 : d0fe > bne * ;failed not equal (non zero) + > +0004 = >test_num = test_num + 1 +0603 : a904 > lda #test_num ;*** next tests' number +0605 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ;testing branch decisions BPL BMI BVC BVS BCC BCS BNE BEQ + set_stat $ff ;all on + > load_flag $ff +0608 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +060a : 48 > pha ;use stack to load status +060b : 28 > plp + +060c : 101a bpl nbr1 ;branches should not be taken +060e : 501b bvc nbr2 +0610 : 901c bcc nbr3 +0612 : d01d bne nbr4 +0614 : 3003 bmi br1 ;branches should be taken + trap +0616 : 4c1606 > jmp * ;failed anyway + +0619 : 7003 br1 bvs br2 + trap +061b : 4c1b06 > jmp * ;failed anyway + +061e : b003 br2 bcs br3 + trap +0620 : 4c2006 > jmp * ;failed anyway + +0623 : f00f br3 beq br4 + trap +0625 : 4c2506 > jmp * ;failed anyway + +0628 : nbr1 + trap ;previous bpl taken +0628 : 4c2806 > jmp * ;failed anyway + +062b : nbr2 + trap ;previous bvc taken +062b : 4c2b06 > jmp * ;failed anyway + +062e : nbr3 + trap ;previous bcc taken +062e : 4c2e06 > jmp * ;failed anyway + +0631 : nbr4 + trap ;previous bne taken +0631 : 4c3106 > jmp * ;failed anyway + +0634 : 08 br4 php +0635 : ba tsx +0636 : e0fe cpx #$fe ;sp after php? + trap_ne +0638 : d0fe > bne * ;failed not equal (non zero) + +063a : 68 pla + cmp_flag $ff ;returned all flags on? +063b : c9ff > cmp #($ff |fao)&m8 ;expected flags + always on bits + + trap_ne +063d : d0fe > bne * ;failed not equal (non zero) + +063f : ba tsx +0640 : e0ff cpx #$ff ;sp after php? + trap_ne +0642 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 ;all off + > load_flag 0 +0644 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0646 : 48 > pha ;use stack to load status +0647 : 28 > plp + +0648 : 301a bmi nbr11 ;branches should not be taken +064a : 701b bvs nbr12 +064c : b01c bcs nbr13 +064e : f01d beq nbr14 +0650 : 1003 bpl br11 ;branches should be taken + trap +0652 : 4c5206 > jmp * ;failed anyway + +0655 : 5003 br11 bvc br12 + trap +0657 : 4c5706 > jmp * ;failed anyway + +065a : 9003 br12 bcc br13 + trap +065c : 4c5c06 > jmp * ;failed anyway + +065f : d00f br13 bne br14 + trap +0661 : 4c6106 > jmp * ;failed anyway + +0664 : nbr11 + trap ;previous bmi taken +0664 : 4c6406 > jmp * ;failed anyway + +0667 : nbr12 + trap ;previous bvs taken +0667 : 4c6706 > jmp * ;failed anyway + +066a : nbr13 + trap ;previous bcs taken +066a : 4c6a06 > jmp * ;failed anyway + +066d : nbr14 + trap ;previous beq taken +066d : 4c6d06 > jmp * ;failed anyway + +0670 : 08 br14 php +0671 : 68 pla + cmp_flag 0 ;flags off except break (pushed by sw) + reserved? +0672 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits + + trap_ne +0674 : d0fe > bne * ;failed not equal (non zero) + + ;crosscheck flags + set_stat zero + > load_flag zero +0676 : a902 > lda #zero ;allow test to change I-flag (no mask) + > +0678 : 48 > pha ;use stack to load status +0679 : 28 > plp + +067a : d002 bne brzs1 +067c : f003 beq brzs2 +067e : brzs1 + trap ;branch zero/non zero +067e : 4c7e06 > jmp * ;failed anyway + +0681 : b002 brzs2 bcs brzs3 +0683 : 9003 bcc brzs4 +0685 : brzs3 + trap ;branch carry/no carry +0685 : 4c8506 > jmp * ;failed anyway + +0688 : 3002 brzs4 bmi brzs5 +068a : 1003 bpl brzs6 +068c : brzs5 + trap ;branch minus/plus +068c : 4c8c06 > jmp * ;failed anyway + +068f : 7002 brzs6 bvs brzs7 +0691 : 5003 bvc brzs8 +0693 : brzs7 + trap ;branch overflow/no overflow +0693 : 4c9306 > jmp * ;failed anyway + +0696 : brzs8 + set_stat carry + > load_flag carry +0696 : a901 > lda #carry ;allow test to change I-flag (no mask) + > +0698 : 48 > pha ;use stack to load status +0699 : 28 > plp + +069a : f002 beq brcs1 +069c : d003 bne brcs2 +069e : brcs1 + trap ;branch zero/non zero +069e : 4c9e06 > jmp * ;failed anyway + +06a1 : 9002 brcs2 bcc brcs3 +06a3 : b003 bcs brcs4 +06a5 : brcs3 + trap ;branch carry/no carry +06a5 : 4ca506 > jmp * ;failed anyway + +06a8 : 3002 brcs4 bmi brcs5 +06aa : 1003 bpl brcs6 +06ac : brcs5 + trap ;branch minus/plus +06ac : 4cac06 > jmp * ;failed anyway + +06af : 7002 brcs6 bvs brcs7 +06b1 : 5003 bvc brcs8 +06b3 : brcs7 + trap ;branch overflow/no overflow +06b3 : 4cb306 > jmp * ;failed anyway + + +06b6 : brcs8 + set_stat minus + > load_flag minus +06b6 : a980 > lda #minus ;allow test to change I-flag (no mask) + > +06b8 : 48 > pha ;use stack to load status +06b9 : 28 > plp + +06ba : f002 beq brmi1 +06bc : d003 bne brmi2 +06be : brmi1 + trap ;branch zero/non zero +06be : 4cbe06 > jmp * ;failed anyway + +06c1 : b002 brmi2 bcs brmi3 +06c3 : 9003 bcc brmi4 +06c5 : brmi3 + trap ;branch carry/no carry +06c5 : 4cc506 > jmp * ;failed anyway + +06c8 : 1002 brmi4 bpl brmi5 +06ca : 3003 bmi brmi6 +06cc : brmi5 + trap ;branch minus/plus +06cc : 4ccc06 > jmp * ;failed anyway + +06cf : 7002 brmi6 bvs brmi7 +06d1 : 5003 bvc brmi8 +06d3 : brmi7 + trap ;branch overflow/no overflow +06d3 : 4cd306 > jmp * ;failed anyway + +06d6 : brmi8 + set_stat overfl + > load_flag overfl +06d6 : a940 > lda #overfl ;allow test to change I-flag (no mask) + > +06d8 : 48 > pha ;use stack to load status +06d9 : 28 > plp + +06da : f002 beq brvs1 +06dc : d003 bne brvs2 +06de : brvs1 + trap ;branch zero/non zero +06de : 4cde06 > jmp * ;failed anyway + +06e1 : b002 brvs2 bcs brvs3 +06e3 : 9003 bcc brvs4 +06e5 : brvs3 + trap ;branch carry/no carry +06e5 : 4ce506 > jmp * ;failed anyway + +06e8 : 3002 brvs4 bmi brvs5 +06ea : 1003 bpl brvs6 +06ec : brvs5 + trap ;branch minus/plus +06ec : 4cec06 > jmp * ;failed anyway + +06ef : 5002 brvs6 bvc brvs7 +06f1 : 7003 bvs brvs8 +06f3 : brvs7 + trap ;branch overflow/no overflow +06f3 : 4cf306 > jmp * ;failed anyway + +06f6 : brvs8 + set_stat $ff-zero + > load_flag $ff-zero +06f6 : a9fd > lda #$ff-zero ;allow test to change I-flag (no mask) + > +06f8 : 48 > pha ;use stack to load status +06f9 : 28 > plp + +06fa : f002 beq brzc1 +06fc : d003 bne brzc2 +06fe : brzc1 + trap ;branch zero/non zero +06fe : 4cfe06 > jmp * ;failed anyway + +0701 : 9002 brzc2 bcc brzc3 +0703 : b003 bcs brzc4 +0705 : brzc3 + trap ;branch carry/no carry +0705 : 4c0507 > jmp * ;failed anyway + +0708 : 1002 brzc4 bpl brzc5 +070a : 3003 bmi brzc6 +070c : brzc5 + trap ;branch minus/plus +070c : 4c0c07 > jmp * ;failed anyway + +070f : 5002 brzc6 bvc brzc7 +0711 : 7003 bvs brzc8 +0713 : brzc7 + trap ;branch overflow/no overflow +0713 : 4c1307 > jmp * ;failed anyway + +0716 : brzc8 + set_stat $ff-carry + > load_flag $ff-carry +0716 : a9fe > lda #$ff-carry ;allow test to change I-flag (no mask) + > +0718 : 48 > pha ;use stack to load status +0719 : 28 > plp + +071a : d002 bne brcc1 +071c : f003 beq brcc2 +071e : brcc1 + trap ;branch zero/non zero +071e : 4c1e07 > jmp * ;failed anyway + +0721 : b002 brcc2 bcs brcc3 +0723 : 9003 bcc brcc4 +0725 : brcc3 + trap ;branch carry/no carry +0725 : 4c2507 > jmp * ;failed anyway + +0728 : 1002 brcc4 bpl brcc5 +072a : 3003 bmi brcc6 +072c : brcc5 + trap ;branch minus/plus +072c : 4c2c07 > jmp * ;failed anyway + +072f : 5002 brcc6 bvc brcc7 +0731 : 7003 bvs brcc8 +0733 : brcc7 + trap ;branch overflow/no overflow +0733 : 4c3307 > jmp * ;failed anyway + +0736 : brcc8 + set_stat $ff-minus + > load_flag $ff-minus +0736 : a97f > lda #$ff-minus ;allow test to change I-flag (no mask) + > +0738 : 48 > pha ;use stack to load status +0739 : 28 > plp + +073a : d002 bne brpl1 +073c : f003 beq brpl2 +073e : brpl1 + trap ;branch zero/non zero +073e : 4c3e07 > jmp * ;failed anyway + +0741 : 9002 brpl2 bcc brpl3 +0743 : b003 bcs brpl4 +0745 : brpl3 + trap ;branch carry/no carry +0745 : 4c4507 > jmp * ;failed anyway + +0748 : 3002 brpl4 bmi brpl5 +074a : 1003 bpl brpl6 +074c : brpl5 + trap ;branch minus/plus +074c : 4c4c07 > jmp * ;failed anyway + +074f : 5002 brpl6 bvc brpl7 +0751 : 7003 bvs brpl8 +0753 : brpl7 + trap ;branch overflow/no overflow +0753 : 4c5307 > jmp * ;failed anyway + +0756 : brpl8 + set_stat $ff-overfl + > load_flag $ff-overfl +0756 : a9bf > lda #$ff-overfl ;allow test to change I-flag (no mask) + > +0758 : 48 > pha ;use stack to load status +0759 : 28 > plp + +075a : d002 bne brvc1 +075c : f003 beq brvc2 +075e : brvc1 + trap ;branch zero/non zero +075e : 4c5e07 > jmp * ;failed anyway + +0761 : 9002 brvc2 bcc brvc3 +0763 : b003 bcs brvc4 +0765 : brvc3 + trap ;branch carry/no carry +0765 : 4c6507 > jmp * ;failed anyway + +0768 : 1002 brvc4 bpl brvc5 +076a : 3003 bmi brvc6 +076c : brvc5 + trap ;branch minus/plus +076c : 4c6c07 > jmp * ;failed anyway + +076f : 7002 brvc6 bvs brvc7 +0771 : 5003 bvc brvc8 +0773 : brvc7 + trap ;branch overflow/no overflow +0773 : 4c7307 > jmp * ;failed anyway + +0776 : brvc8 + next_test +0776 : ad0002 > lda test_case ;previous test +0779 : c904 > cmp #test_num + > trap_ne ;test is out of sequence +077b : d0fe > bne * ;failed not equal (non zero) + > +0005 = >test_num = test_num + 1 +077d : a905 > lda #test_num ;*** next tests' number +077f : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; test PHA does not alter flags or accumulator but PLA does +0782 : a255 ldx #$55 ;x & y protected +0784 : a0aa ldy #$aa + set_a 1,$ff ;push + > load_flag $ff +0786 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0788 : 48 > pha ;use stack to load status +0789 : a901 > lda #1 ;precharge accu +078b : 28 > plp + +078c : 48 pha + tst_a 1,$ff +078d : 08 > php ;save flags +078e : c901 > cmp #1 ;test result + > trap_ne +0790 : d0fe > bne * ;failed not equal (non zero) + > +0792 : 68 > pla ;load status +0793 : 48 > pha + > cmp_flag $ff +0794 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0796 : d0fe > bne * ;failed not equal (non zero) + > +0798 : 28 > plp ;restore status + + set_a 0,0 + > load_flag 0 +0799 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +079b : 48 > pha ;use stack to load status +079c : a900 > lda #0 ;precharge accu +079e : 28 > plp + +079f : 48 pha + tst_a 0,0 +07a0 : 08 > php ;save flags +07a1 : c900 > cmp #0 ;test result + > trap_ne +07a3 : d0fe > bne * ;failed not equal (non zero) + > +07a5 : 68 > pla ;load status +07a6 : 48 > pha + > cmp_flag 0 +07a7 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07a9 : d0fe > bne * ;failed not equal (non zero) + > +07ab : 28 > plp ;restore status + + set_a $ff,$ff + > load_flag $ff +07ac : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +07ae : 48 > pha ;use stack to load status +07af : a9ff > lda #$ff ;precharge accu +07b1 : 28 > plp + +07b2 : 48 pha + tst_a $ff,$ff +07b3 : 08 > php ;save flags +07b4 : c9ff > cmp #$ff ;test result + > trap_ne +07b6 : d0fe > bne * ;failed not equal (non zero) + > +07b8 : 68 > pla ;load status +07b9 : 48 > pha + > cmp_flag $ff +07ba : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07bc : d0fe > bne * ;failed not equal (non zero) + > +07be : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +07bf : a900 > lda #0 ;allow test to change I-flag (no mask) + > +07c1 : 48 > pha ;use stack to load status +07c2 : a901 > lda #1 ;precharge accu +07c4 : 28 > plp + +07c5 : 48 pha + tst_a 1,0 +07c6 : 08 > php ;save flags +07c7 : c901 > cmp #1 ;test result + > trap_ne +07c9 : d0fe > bne * ;failed not equal (non zero) + > +07cb : 68 > pla ;load status +07cc : 48 > pha + > cmp_flag 0 +07cd : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07cf : d0fe > bne * ;failed not equal (non zero) + > +07d1 : 28 > plp ;restore status + + set_a 0,$ff + > load_flag $ff +07d2 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +07d4 : 48 > pha ;use stack to load status +07d5 : a900 > lda #0 ;precharge accu +07d7 : 28 > plp + +07d8 : 48 pha + tst_a 0,$ff +07d9 : 08 > php ;save flags +07da : c900 > cmp #0 ;test result + > trap_ne +07dc : d0fe > bne * ;failed not equal (non zero) + > +07de : 68 > pla ;load status +07df : 48 > pha + > cmp_flag $ff +07e0 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07e2 : d0fe > bne * ;failed not equal (non zero) + > +07e4 : 28 > plp ;restore status + + set_a $ff,0 + > load_flag 0 +07e5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +07e7 : 48 > pha ;use stack to load status +07e8 : a9ff > lda #$ff ;precharge accu +07ea : 28 > plp + +07eb : 48 pha + tst_a $ff,0 +07ec : 08 > php ;save flags +07ed : c9ff > cmp #$ff ;test result + > trap_ne +07ef : d0fe > bne * ;failed not equal (non zero) + > +07f1 : 68 > pla ;load status +07f2 : 48 > pha + > cmp_flag 0 +07f3 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07f5 : d0fe > bne * ;failed not equal (non zero) + > +07f7 : 28 > plp ;restore status + + set_a 0,$ff ;pull + > load_flag $ff +07f8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +07fa : 48 > pha ;use stack to load status +07fb : a900 > lda #0 ;precharge accu +07fd : 28 > plp + +07fe : 68 pla + tst_a $ff,$ff-zero +07ff : 08 > php ;save flags +0800 : c9ff > cmp #$ff ;test result + > trap_ne +0802 : d0fe > bne * ;failed not equal (non zero) + > +0804 : 68 > pla ;load status +0805 : 48 > pha + > cmp_flag $ff-zero +0806 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0808 : d0fe > bne * ;failed not equal (non zero) + > +080a : 28 > plp ;restore status + + set_a $ff,0 + > load_flag 0 +080b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +080d : 48 > pha ;use stack to load status +080e : a9ff > lda #$ff ;precharge accu +0810 : 28 > plp + +0811 : 68 pla + tst_a 0,zero +0812 : 08 > php ;save flags +0813 : c900 > cmp #0 ;test result + > trap_ne +0815 : d0fe > bne * ;failed not equal (non zero) + > +0817 : 68 > pla ;load status +0818 : 48 > pha + > cmp_flag zero +0819 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +081b : d0fe > bne * ;failed not equal (non zero) + > +081d : 28 > plp ;restore status + + set_a $fe,$ff + > load_flag $ff +081e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0820 : 48 > pha ;use stack to load status +0821 : a9fe > lda #$fe ;precharge accu +0823 : 28 > plp + +0824 : 68 pla + tst_a 1,$ff-zero-minus +0825 : 08 > php ;save flags +0826 : c901 > cmp #1 ;test result + > trap_ne +0828 : d0fe > bne * ;failed not equal (non zero) + > +082a : 68 > pla ;load status +082b : 48 > pha + > cmp_flag $ff-zero-minus +082c : c97d > cmp #($ff-zero-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +082e : d0fe > bne * ;failed not equal (non zero) + > +0830 : 28 > plp ;restore status + + set_a 0,0 + > load_flag 0 +0831 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0833 : 48 > pha ;use stack to load status +0834 : a900 > lda #0 ;precharge accu +0836 : 28 > plp + +0837 : 68 pla + tst_a $ff,minus +0838 : 08 > php ;save flags +0839 : c9ff > cmp #$ff ;test result + > trap_ne +083b : d0fe > bne * ;failed not equal (non zero) + > +083d : 68 > pla ;load status +083e : 48 > pha + > cmp_flag minus +083f : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0841 : d0fe > bne * ;failed not equal (non zero) + > +0843 : 28 > plp ;restore status + + set_a $ff,$ff + > load_flag $ff +0844 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0846 : 48 > pha ;use stack to load status +0847 : a9ff > lda #$ff ;precharge accu +0849 : 28 > plp + +084a : 68 pla + tst_a 0,$ff-minus +084b : 08 > php ;save flags +084c : c900 > cmp #0 ;test result + > trap_ne +084e : d0fe > bne * ;failed not equal (non zero) + > +0850 : 68 > pla ;load status +0851 : 48 > pha + > cmp_flag $ff-minus +0852 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0854 : d0fe > bne * ;failed not equal (non zero) + > +0856 : 28 > plp ;restore status + + set_a $fe,0 + > load_flag 0 +0857 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0859 : 48 > pha ;use stack to load status +085a : a9fe > lda #$fe ;precharge accu +085c : 28 > plp + +085d : 68 pla + tst_a 1,0 +085e : 08 > php ;save flags +085f : c901 > cmp #1 ;test result + > trap_ne +0861 : d0fe > bne * ;failed not equal (non zero) + > +0863 : 68 > pla ;load status +0864 : 48 > pha + > cmp_flag 0 +0865 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0867 : d0fe > bne * ;failed not equal (non zero) + > +0869 : 28 > plp ;restore status + +086a : e055 cpx #$55 ;x & y unchanged? + trap_ne +086c : d0fe > bne * ;failed not equal (non zero) + +086e : c0aa cpy #$aa + trap_ne +0870 : d0fe > bne * ;failed not equal (non zero) + + next_test +0872 : ad0002 > lda test_case ;previous test +0875 : c905 > cmp #test_num + > trap_ne ;test is out of sequence +0877 : d0fe > bne * ;failed not equal (non zero) + > +0006 = >test_num = test_num + 1 +0879 : a906 > lda #test_num ;*** next tests' number +087b : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; partial pretest EOR # + set_a $3c,0 + > load_flag 0 +087e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0880 : 48 > pha ;use stack to load status +0881 : a93c > lda #$3c ;precharge accu +0883 : 28 > plp + +0884 : 49c3 eor #$c3 + tst_a $ff,fn +0886 : 08 > php ;save flags +0887 : c9ff > cmp #$ff ;test result + > trap_ne +0889 : d0fe > bne * ;failed not equal (non zero) + > +088b : 68 > pla ;load status +088c : 48 > pha + > cmp_flag fn +088d : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +088f : d0fe > bne * ;failed not equal (non zero) + > +0891 : 28 > plp ;restore status + + set_a $c3,0 + > load_flag 0 +0892 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0894 : 48 > pha ;use stack to load status +0895 : a9c3 > lda #$c3 ;precharge accu +0897 : 28 > plp + +0898 : 49c3 eor #$c3 + tst_a 0,fz +089a : 08 > php ;save flags +089b : c900 > cmp #0 ;test result + > trap_ne +089d : d0fe > bne * ;failed not equal (non zero) + > +089f : 68 > pla ;load status +08a0 : 48 > pha + > cmp_flag fz +08a1 : c932 > cmp #(fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +08a3 : d0fe > bne * ;failed not equal (non zero) + > +08a5 : 28 > plp ;restore status + + next_test +08a6 : ad0002 > lda test_case ;previous test +08a9 : c906 > cmp #test_num + > trap_ne ;test is out of sequence +08ab : d0fe > bne * ;failed not equal (non zero) + > +0007 = >test_num = test_num + 1 +08ad : a907 > lda #test_num ;*** next tests' number +08af : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; PC modifying instructions except branches (NOP, JMP, JSR, RTS, BRK, RTI) + ; testing NOP +08b2 : a224 ldx #$24 +08b4 : a042 ldy #$42 + set_a $18,0 + > load_flag 0 +08b6 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +08b8 : 48 > pha ;use stack to load status +08b9 : a918 > lda #$18 ;precharge accu +08bb : 28 > plp + +08bc : ea nop + tst_a $18,0 +08bd : 08 > php ;save flags +08be : c918 > cmp #$18 ;test result + > trap_ne +08c0 : d0fe > bne * ;failed not equal (non zero) + > +08c2 : 68 > pla ;load status +08c3 : 48 > pha + > cmp_flag 0 +08c4 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +08c6 : d0fe > bne * ;failed not equal (non zero) + > +08c8 : 28 > plp ;restore status + +08c9 : e024 cpx #$24 + trap_ne +08cb : d0fe > bne * ;failed not equal (non zero) + +08cd : c042 cpy #$42 + trap_ne +08cf : d0fe > bne * ;failed not equal (non zero) + +08d1 : a2db ldx #$db +08d3 : a0bd ldy #$bd + set_a $e7,$ff + > load_flag $ff +08d5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +08d7 : 48 > pha ;use stack to load status +08d8 : a9e7 > lda #$e7 ;precharge accu +08da : 28 > plp + +08db : ea nop + tst_a $e7,$ff +08dc : 08 > php ;save flags +08dd : c9e7 > cmp #$e7 ;test result + > trap_ne +08df : d0fe > bne * ;failed not equal (non zero) + > +08e1 : 68 > pla ;load status +08e2 : 48 > pha + > cmp_flag $ff +08e3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +08e5 : d0fe > bne * ;failed not equal (non zero) + > +08e7 : 28 > plp ;restore status + +08e8 : e0db cpx #$db + trap_ne +08ea : d0fe > bne * ;failed not equal (non zero) + +08ec : c0bd cpy #$bd + trap_ne +08ee : d0fe > bne * ;failed not equal (non zero) + + next_test +08f0 : ad0002 > lda test_case ;previous test +08f3 : c907 > cmp #test_num + > trap_ne ;test is out of sequence +08f5 : d0fe > bne * ;failed not equal (non zero) + > +0008 = >test_num = test_num + 1 +08f7 : a908 > lda #test_num ;*** next tests' number +08f9 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; jump absolute + set_stat $0 + > load_flag $0 +08fc : a900 > lda #$0 ;allow test to change I-flag (no mask) + > +08fe : 48 > pha ;use stack to load status +08ff : 28 > plp + +0900 : a946 lda #'F' +0902 : a241 ldx #'A' +0904 : a052 ldy #'R' ;N=0, V=0, Z=0, C=0 +0906 : 4cef36 jmp test_far +0909 : ea nop +090a : ea nop + trap_ne ;runover protection +090b : d0fe > bne * ;failed not equal (non zero) + +090d : e8 inx +090e : e8 inx +090f : far_ret + trap_eq ;returned flags OK? +090f : f0fe > beq * ;failed equal (zero) + + trap_pl +0911 : 10fe > bpl * ;failed plus (bit 7 clear) + + trap_cc +0913 : 90fe > bcc * ;failed carry clear + + trap_vc +0915 : 50fe > bvc * ;failed overflow clear + +0917 : c9ec cmp #('F'^$aa) ;returned registers OK? + trap_ne +0919 : d0fe > bne * ;failed not equal (non zero) + +091b : e042 cpx #('A'+1) + trap_ne +091d : d0fe > bne * ;failed not equal (non zero) + +091f : c04f cpy #('R'-3) + trap_ne +0921 : d0fe > bne * ;failed not equal (non zero) + +0923 : ca dex +0924 : c8 iny +0925 : c8 iny +0926 : c8 iny +0927 : 49aa eor #$aa ;N=0, V=1, Z=0, C=1 +0929 : 4c3209 jmp test_near +092c : ea nop +092d : ea nop + trap_ne ;runover protection +092e : d0fe > bne * ;failed not equal (non zero) + +0930 : e8 inx +0931 : e8 inx +0932 : test_near + trap_eq ;passed flags OK? +0932 : f0fe > beq * ;failed equal (zero) + + trap_mi +0934 : 30fe > bmi * ;failed minus (bit 7 set) + + trap_cc +0936 : 90fe > bcc * ;failed carry clear + + trap_vc +0938 : 50fe > bvc * ;failed overflow clear + +093a : c946 cmp #'F' ;passed registers OK? + trap_ne +093c : d0fe > bne * ;failed not equal (non zero) + +093e : e041 cpx #'A' + trap_ne +0940 : d0fe > bne * ;failed not equal (non zero) + +0942 : c052 cpy #'R' + trap_ne +0944 : d0fe > bne * ;failed not equal (non zero) + + next_test +0946 : ad0002 > lda test_case ;previous test +0949 : c908 > cmp #test_num + > trap_ne ;test is out of sequence +094b : d0fe > bne * ;failed not equal (non zero) + > +0009 = >test_num = test_num + 1 +094d : a909 > lda #test_num ;*** next tests' number +094f : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; jump indirect + set_stat 0 + > load_flag 0 +0952 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0954 : 48 > pha ;use stack to load status +0955 : 28 > plp + +0956 : a949 lda #'I' +0958 : a24e ldx #'N' +095a : a044 ldy #'D' ;N=0, V=0, Z=0, C=0 +095c : 6c1e37 jmp (ptr_tst_ind) +095f : ea nop + trap_ne ;runover protection +0960 : d0fe > bne * ;failed not equal (non zero) + +0962 : 88 dey +0963 : 88 dey +0964 : ind_ret +0964 : 08 php ;either SP or Y count will fail, if we do not hit +0965 : 88 dey +0966 : 88 dey +0967 : 88 dey +0968 : 28 plp + trap_eq ;returned flags OK? +0969 : f0fe > beq * ;failed equal (zero) + + trap_pl +096b : 10fe > bpl * ;failed plus (bit 7 clear) + + trap_cc +096d : 90fe > bcc * ;failed carry clear + + trap_vc +096f : 50fe > bvc * ;failed overflow clear + +0971 : c9e3 cmp #('I'^$aa) ;returned registers OK? + trap_ne +0973 : d0fe > bne * ;failed not equal (non zero) + +0975 : e04f cpx #('N'+1) + trap_ne +0977 : d0fe > bne * ;failed not equal (non zero) + +0979 : c03e cpy #('D'-6) + trap_ne +097b : d0fe > bne * ;failed not equal (non zero) + +097d : ba tsx ;SP check +097e : e0ff cpx #$ff + trap_ne +0980 : d0fe > bne * ;failed not equal (non zero) + + next_test +0982 : ad0002 > lda test_case ;previous test +0985 : c909 > cmp #test_num + > trap_ne ;test is out of sequence +0987 : d0fe > bne * ;failed not equal (non zero) + > +000a = >test_num = test_num + 1 +0989 : a90a > lda #test_num ;*** next tests' number +098b : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; jump subroutine & return from subroutine + set_stat 0 + > load_flag 0 +098e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0990 : 48 > pha ;use stack to load status +0991 : 28 > plp + +0992 : a94a lda #'J' +0994 : a253 ldx #'S' +0996 : a052 ldy #'R' ;N=0, V=0, Z=0, C=0 +0998 : 205d37 jsr test_jsr +099a = jsr_ret = *-1 ;last address of jsr = return address +099b : 08 php ;either SP or Y count will fail, if we do not hit +099c : 88 dey +099d : 88 dey +099e : 88 dey +099f : 28 plp + trap_eq ;returned flags OK? +09a0 : f0fe > beq * ;failed equal (zero) + + trap_pl +09a2 : 10fe > bpl * ;failed plus (bit 7 clear) + + trap_cc +09a4 : 90fe > bcc * ;failed carry clear + + trap_vc +09a6 : 50fe > bvc * ;failed overflow clear + +09a8 : c9e0 cmp #('J'^$aa) ;returned registers OK? + trap_ne +09aa : d0fe > bne * ;failed not equal (non zero) + +09ac : e054 cpx #('S'+1) + trap_ne +09ae : d0fe > bne * ;failed not equal (non zero) + +09b0 : c04c cpy #('R'-6) + trap_ne +09b2 : d0fe > bne * ;failed not equal (non zero) + +09b4 : ba tsx ;sp? +09b5 : e0ff cpx #$ff + trap_ne +09b7 : d0fe > bne * ;failed not equal (non zero) + + next_test +09b9 : ad0002 > lda test_case ;previous test +09bc : c90a > cmp #test_num + > trap_ne ;test is out of sequence +09be : d0fe > bne * ;failed not equal (non zero) + > +000b = >test_num = test_num + 1 +09c0 : a90b > lda #test_num ;*** next tests' number +09c2 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; break & return from interrupt + if ROM_vectors = 1 + load_flag 0 ;with interrupts enabled if allowed! +09c5 : a900 > lda #0 ;allow test to change I-flag (no mask) + +09c7 : 48 pha +09c8 : a942 lda #'B' +09ca : a252 ldx #'R' +09cc : a04b ldy #'K' +09ce : 28 plp ;N=0, V=0, Z=0, C=0 +09cf : 00 brk + else + lda #hi brk_ret0 ;emulated break + pha + lda #lo brk_ret0 + pha + load_flag fao ;set break & unused on stack + pha + load_flag intdis ;during interrupt + pha + lda #'B' + ldx #'R' + ldy #'K' + plp ;N=0, V=0, Z=0, C=0 + jmp irq_trap + endif +09d0 : 88 dey ;should not be executed +09d1 : brk_ret0 ;address of break return +09d1 : 08 php ;either SP or Y count will fail, if we do not hit +09d2 : 88 dey +09d3 : 88 dey +09d4 : 88 dey +09d5 : c9e8 cmp #'B'^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne +09d7 : d0fe > bne * ;failed not equal (non zero) + +09d9 : e053 cpx #'R'+1 + trap_ne +09db : d0fe > bne * ;failed not equal (non zero) + +09dd : c045 cpy #'K'-6 + trap_ne +09df : d0fe > bne * ;failed not equal (non zero) + +09e1 : 68 pla ;returned flags OK (unchanged)? + cmp_flag 0 +09e2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + trap_ne +09e4 : d0fe > bne * ;failed not equal (non zero) + +09e6 : ba tsx ;sp? +09e7 : e0ff cpx #$ff + trap_ne +09e9 : d0fe > bne * ;failed not equal (non zero) + + if ROM_vectors = 1 + load_flag $ff ;with interrupts disabled if allowed! +09eb : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +09ed : 48 pha +09ee : a9bd lda #$ff-'B' +09f0 : a2ad ldx #$ff-'R' +09f2 : a0b4 ldy #$ff-'K' +09f4 : 28 plp ;N=1, V=1, Z=1, C=1 +09f5 : 00 brk + else + lda #hi brk_ret1 ;emulated break + pha + lda #lo brk_ret1 + pha + load_flag $ff + pha ;set break & unused on stack + pha ;actual flags + lda #$ff-'B' + ldx #$ff-'R' + ldy #$ff-'K' + plp ;N=1, V=1, Z=1, C=1 + jmp irq_trap + endif +09f6 : 88 dey ;should not be executed +09f7 : brk_ret1 ;address of break return +09f7 : 08 php ;either SP or Y count will fail, if we do not hit +09f8 : 88 dey +09f9 : 88 dey +09fa : 88 dey +09fb : c917 cmp #($ff-'B')^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne +09fd : d0fe > bne * ;failed not equal (non zero) + +09ff : e0ae cpx #$ff-'R'+1 + trap_ne +0a01 : d0fe > bne * ;failed not equal (non zero) + +0a03 : c0ae cpy #$ff-'K'-6 + trap_ne +0a05 : d0fe > bne * ;failed not equal (non zero) + +0a07 : 68 pla ;returned flags OK (unchanged)? + cmp_flag $ff +0a08 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + + trap_ne +0a0a : d0fe > bne * ;failed not equal (non zero) + +0a0c : ba tsx ;sp? +0a0d : e0ff cpx #$ff + trap_ne +0a0f : d0fe > bne * ;failed not equal (non zero) + + next_test +0a11 : ad0002 > lda test_case ;previous test +0a14 : c90b > cmp #test_num + > trap_ne ;test is out of sequence +0a16 : d0fe > bne * ;failed not equal (non zero) + > +000c = >test_num = test_num + 1 +0a18 : a90c > lda #test_num ;*** next tests' number +0a1a : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; test set and clear flags CLC CLI CLD CLV SEC SEI SED + set_stat $ff + > load_flag $ff +0a1d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0a1f : 48 > pha ;use stack to load status +0a20 : 28 > plp + +0a21 : 18 clc + tst_stat $ff-carry +0a22 : 08 > php ;save status +0a23 : 68 > pla ;use stack to retrieve status +0a24 : 48 > pha + > cmp_flag $ff-carry +0a25 : c9fe > cmp #($ff-carry|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a27 : d0fe > bne * ;failed not equal (non zero) + > +0a29 : 28 > plp ;restore status + +0a2a : 38 sec + tst_stat $ff +0a2b : 08 > php ;save status +0a2c : 68 > pla ;use stack to retrieve status +0a2d : 48 > pha + > cmp_flag $ff +0a2e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a30 : d0fe > bne * ;failed not equal (non zero) + > +0a32 : 28 > plp ;restore status + + if I_flag = 3 +0a33 : 58 cli + tst_stat $ff-intdis +0a34 : 08 > php ;save status +0a35 : 68 > pla ;use stack to retrieve status +0a36 : 48 > pha + > cmp_flag $ff-intdis +0a37 : c9fb > cmp #($ff-intdis|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a39 : d0fe > bne * ;failed not equal (non zero) + > +0a3b : 28 > plp ;restore status + +0a3c : 78 sei + tst_stat $ff +0a3d : 08 > php ;save status +0a3e : 68 > pla ;use stack to retrieve status +0a3f : 48 > pha + > cmp_flag $ff +0a40 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a42 : d0fe > bne * ;failed not equal (non zero) + > +0a44 : 28 > plp ;restore status + + endif +0a45 : d8 cld + tst_stat $ff-decmode +0a46 : 08 > php ;save status +0a47 : 68 > pla ;use stack to retrieve status +0a48 : 48 > pha + > cmp_flag $ff-decmode +0a49 : c9f7 > cmp #($ff-decmode|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a4b : d0fe > bne * ;failed not equal (non zero) + > +0a4d : 28 > plp ;restore status + +0a4e : f8 sed + tst_stat $ff +0a4f : 08 > php ;save status +0a50 : 68 > pla ;use stack to retrieve status +0a51 : 48 > pha + > cmp_flag $ff +0a52 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a54 : d0fe > bne * ;failed not equal (non zero) + > +0a56 : 28 > plp ;restore status + +0a57 : b8 clv + tst_stat $ff-overfl +0a58 : 08 > php ;save status +0a59 : 68 > pla ;use stack to retrieve status +0a5a : 48 > pha + > cmp_flag $ff-overfl +0a5b : c9bf > cmp #($ff-overfl|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a5d : d0fe > bne * ;failed not equal (non zero) + > +0a5f : 28 > plp ;restore status + + set_stat 0 + > load_flag 0 +0a60 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0a62 : 48 > pha ;use stack to load status +0a63 : 28 > plp + + tst_stat 0 +0a64 : 08 > php ;save status +0a65 : 68 > pla ;use stack to retrieve status +0a66 : 48 > pha + > cmp_flag 0 +0a67 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a69 : d0fe > bne * ;failed not equal (non zero) + > +0a6b : 28 > plp ;restore status + +0a6c : 38 sec + tst_stat carry +0a6d : 08 > php ;save status +0a6e : 68 > pla ;use stack to retrieve status +0a6f : 48 > pha + > cmp_flag carry +0a70 : c931 > cmp #(carry|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a72 : d0fe > bne * ;failed not equal (non zero) + > +0a74 : 28 > plp ;restore status + +0a75 : 18 clc + tst_stat 0 +0a76 : 08 > php ;save status +0a77 : 68 > pla ;use stack to retrieve status +0a78 : 48 > pha + > cmp_flag 0 +0a79 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a7b : d0fe > bne * ;failed not equal (non zero) + > +0a7d : 28 > plp ;restore status + + if I_flag = 3 +0a7e : 78 sei + tst_stat intdis +0a7f : 08 > php ;save status +0a80 : 68 > pla ;use stack to retrieve status +0a81 : 48 > pha + > cmp_flag intdis +0a82 : c934 > cmp #(intdis|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a84 : d0fe > bne * ;failed not equal (non zero) + > +0a86 : 28 > plp ;restore status + +0a87 : 58 cli + tst_stat 0 +0a88 : 08 > php ;save status +0a89 : 68 > pla ;use stack to retrieve status +0a8a : 48 > pha + > cmp_flag 0 +0a8b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a8d : d0fe > bne * ;failed not equal (non zero) + > +0a8f : 28 > plp ;restore status + + endif +0a90 : f8 sed + tst_stat decmode +0a91 : 08 > php ;save status +0a92 : 68 > pla ;use stack to retrieve status +0a93 : 48 > pha + > cmp_flag decmode +0a94 : c938 > cmp #(decmode|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a96 : d0fe > bne * ;failed not equal (non zero) + > +0a98 : 28 > plp ;restore status + +0a99 : d8 cld + tst_stat 0 +0a9a : 08 > php ;save status +0a9b : 68 > pla ;use stack to retrieve status +0a9c : 48 > pha + > cmp_flag 0 +0a9d : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a9f : d0fe > bne * ;failed not equal (non zero) + > +0aa1 : 28 > plp ;restore status + + set_stat overfl + > load_flag overfl +0aa2 : a940 > lda #overfl ;allow test to change I-flag (no mask) + > +0aa4 : 48 > pha ;use stack to load status +0aa5 : 28 > plp + + tst_stat overfl +0aa6 : 08 > php ;save status +0aa7 : 68 > pla ;use stack to retrieve status +0aa8 : 48 > pha + > cmp_flag overfl +0aa9 : c970 > cmp #(overfl|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0aab : d0fe > bne * ;failed not equal (non zero) + > +0aad : 28 > plp ;restore status + +0aae : b8 clv + tst_stat 0 +0aaf : 08 > php ;save status +0ab0 : 68 > pla ;use stack to retrieve status +0ab1 : 48 > pha + > cmp_flag 0 +0ab2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ab4 : d0fe > bne * ;failed not equal (non zero) + > +0ab6 : 28 > plp ;restore status + + next_test +0ab7 : ad0002 > lda test_case ;previous test +0aba : c90c > cmp #test_num + > trap_ne ;test is out of sequence +0abc : d0fe > bne * ;failed not equal (non zero) + > +000d = >test_num = test_num + 1 +0abe : a90d > lda #test_num ;*** next tests' number +0ac0 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + ; testing index register increment/decrement and transfer + ; INX INY DEX DEY TAX TXA TAY TYA +0ac3 : a2fe ldx #$fe + set_stat $ff + > load_flag $ff +0ac5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0ac7 : 48 > pha ;use stack to load status +0ac8 : 28 > plp + +0ac9 : e8 inx ;ff + tst_x $ff,$ff-zero +0aca : 08 > php ;save flags +0acb : e0ff > cpx #$ff ;test result + > trap_ne +0acd : d0fe > bne * ;failed not equal (non zero) + > +0acf : 68 > pla ;load status +0ad0 : 48 > pha + > cmp_flag $ff-zero +0ad1 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ad3 : d0fe > bne * ;failed not equal (non zero) + > +0ad5 : 28 > plp ;restore status + +0ad6 : e8 inx ;00 + tst_x 0,$ff-minus +0ad7 : 08 > php ;save flags +0ad8 : e000 > cpx #0 ;test result + > trap_ne +0ada : d0fe > bne * ;failed not equal (non zero) + > +0adc : 68 > pla ;load status +0add : 48 > pha + > cmp_flag $ff-minus +0ade : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ae0 : d0fe > bne * ;failed not equal (non zero) + > +0ae2 : 28 > plp ;restore status + +0ae3 : e8 inx ;01 + tst_x 1,$ff-minus-zero +0ae4 : 08 > php ;save flags +0ae5 : e001 > cpx #1 ;test result + > trap_ne +0ae7 : d0fe > bne * ;failed not equal (non zero) + > +0ae9 : 68 > pla ;load status +0aea : 48 > pha + > cmp_flag $ff-minus-zero +0aeb : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0aed : d0fe > bne * ;failed not equal (non zero) + > +0aef : 28 > plp ;restore status + +0af0 : ca dex ;00 + tst_x 0,$ff-minus +0af1 : 08 > php ;save flags +0af2 : e000 > cpx #0 ;test result + > trap_ne +0af4 : d0fe > bne * ;failed not equal (non zero) + > +0af6 : 68 > pla ;load status +0af7 : 48 > pha + > cmp_flag $ff-minus +0af8 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0afa : d0fe > bne * ;failed not equal (non zero) + > +0afc : 28 > plp ;restore status + +0afd : ca dex ;ff + tst_x $ff,$ff-zero +0afe : 08 > php ;save flags +0aff : e0ff > cpx #$ff ;test result + > trap_ne +0b01 : d0fe > bne * ;failed not equal (non zero) + > +0b03 : 68 > pla ;load status +0b04 : 48 > pha + > cmp_flag $ff-zero +0b05 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b07 : d0fe > bne * ;failed not equal (non zero) + > +0b09 : 28 > plp ;restore status + +0b0a : ca dex ;fe + set_stat 0 + > load_flag 0 +0b0b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0b0d : 48 > pha ;use stack to load status +0b0e : 28 > plp + +0b0f : e8 inx ;ff + tst_x $ff,minus +0b10 : 08 > php ;save flags +0b11 : e0ff > cpx #$ff ;test result + > trap_ne +0b13 : d0fe > bne * ;failed not equal (non zero) + > +0b15 : 68 > pla ;load status +0b16 : 48 > pha + > cmp_flag minus +0b17 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b19 : d0fe > bne * ;failed not equal (non zero) + > +0b1b : 28 > plp ;restore status + +0b1c : e8 inx ;00 + tst_x 0,zero +0b1d : 08 > php ;save flags +0b1e : e000 > cpx #0 ;test result + > trap_ne +0b20 : d0fe > bne * ;failed not equal (non zero) + > +0b22 : 68 > pla ;load status +0b23 : 48 > pha + > cmp_flag zero +0b24 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b26 : d0fe > bne * ;failed not equal (non zero) + > +0b28 : 28 > plp ;restore status + +0b29 : e8 inx ;01 + tst_x 1,0 +0b2a : 08 > php ;save flags +0b2b : e001 > cpx #1 ;test result + > trap_ne +0b2d : d0fe > bne * ;failed not equal (non zero) + > +0b2f : 68 > pla ;load status +0b30 : 48 > pha + > cmp_flag 0 +0b31 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b33 : d0fe > bne * ;failed not equal (non zero) + > +0b35 : 28 > plp ;restore status + +0b36 : ca dex ;00 + tst_x 0,zero +0b37 : 08 > php ;save flags +0b38 : e000 > cpx #0 ;test result + > trap_ne +0b3a : d0fe > bne * ;failed not equal (non zero) + > +0b3c : 68 > pla ;load status +0b3d : 48 > pha + > cmp_flag zero +0b3e : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b40 : d0fe > bne * ;failed not equal (non zero) + > +0b42 : 28 > plp ;restore status + +0b43 : ca dex ;ff + tst_x $ff,minus +0b44 : 08 > php ;save flags +0b45 : e0ff > cpx #$ff ;test result + > trap_ne +0b47 : d0fe > bne * ;failed not equal (non zero) + > +0b49 : 68 > pla ;load status +0b4a : 48 > pha + > cmp_flag minus +0b4b : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b4d : d0fe > bne * ;failed not equal (non zero) + > +0b4f : 28 > plp ;restore status + + +0b50 : a0fe ldy #$fe + set_stat $ff + > load_flag $ff +0b52 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0b54 : 48 > pha ;use stack to load status +0b55 : 28 > plp + +0b56 : c8 iny ;ff + tst_y $ff,$ff-zero +0b57 : 08 > php ;save flags +0b58 : c0ff > cpy #$ff ;test result + > trap_ne +0b5a : d0fe > bne * ;failed not equal (non zero) + > +0b5c : 68 > pla ;load status +0b5d : 48 > pha + > cmp_flag $ff-zero +0b5e : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b60 : d0fe > bne * ;failed not equal (non zero) + > +0b62 : 28 > plp ;restore status + +0b63 : c8 iny ;00 + tst_y 0,$ff-minus +0b64 : 08 > php ;save flags +0b65 : c000 > cpy #0 ;test result + > trap_ne +0b67 : d0fe > bne * ;failed not equal (non zero) + > +0b69 : 68 > pla ;load status +0b6a : 48 > pha + > cmp_flag $ff-minus +0b6b : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b6d : d0fe > bne * ;failed not equal (non zero) + > +0b6f : 28 > plp ;restore status + +0b70 : c8 iny ;01 + tst_y 1,$ff-minus-zero +0b71 : 08 > php ;save flags +0b72 : c001 > cpy #1 ;test result + > trap_ne +0b74 : d0fe > bne * ;failed not equal (non zero) + > +0b76 : 68 > pla ;load status +0b77 : 48 > pha + > cmp_flag $ff-minus-zero +0b78 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b7a : d0fe > bne * ;failed not equal (non zero) + > +0b7c : 28 > plp ;restore status + +0b7d : 88 dey ;00 + tst_y 0,$ff-minus +0b7e : 08 > php ;save flags +0b7f : c000 > cpy #0 ;test result + > trap_ne +0b81 : d0fe > bne * ;failed not equal (non zero) + > +0b83 : 68 > pla ;load status +0b84 : 48 > pha + > cmp_flag $ff-minus +0b85 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b87 : d0fe > bne * ;failed not equal (non zero) + > +0b89 : 28 > plp ;restore status + +0b8a : 88 dey ;ff + tst_y $ff,$ff-zero +0b8b : 08 > php ;save flags +0b8c : c0ff > cpy #$ff ;test result + > trap_ne +0b8e : d0fe > bne * ;failed not equal (non zero) + > +0b90 : 68 > pla ;load status +0b91 : 48 > pha + > cmp_flag $ff-zero +0b92 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b94 : d0fe > bne * ;failed not equal (non zero) + > +0b96 : 28 > plp ;restore status + +0b97 : 88 dey ;fe + set_stat 0 + > load_flag 0 +0b98 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0b9a : 48 > pha ;use stack to load status +0b9b : 28 > plp + +0b9c : c8 iny ;ff + tst_y $ff,0+minus +0b9d : 08 > php ;save flags +0b9e : c0ff > cpy #$ff ;test result + > trap_ne +0ba0 : d0fe > bne * ;failed not equal (non zero) + > +0ba2 : 68 > pla ;load status +0ba3 : 48 > pha + > cmp_flag 0+minus +0ba4 : c9b0 > cmp #(0+minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ba6 : d0fe > bne * ;failed not equal (non zero) + > +0ba8 : 28 > plp ;restore status + +0ba9 : c8 iny ;00 + tst_y 0,zero +0baa : 08 > php ;save flags +0bab : c000 > cpy #0 ;test result + > trap_ne +0bad : d0fe > bne * ;failed not equal (non zero) + > +0baf : 68 > pla ;load status +0bb0 : 48 > pha + > cmp_flag zero +0bb1 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bb3 : d0fe > bne * ;failed not equal (non zero) + > +0bb5 : 28 > plp ;restore status + +0bb6 : c8 iny ;01 + tst_y 1,0 +0bb7 : 08 > php ;save flags +0bb8 : c001 > cpy #1 ;test result + > trap_ne +0bba : d0fe > bne * ;failed not equal (non zero) + > +0bbc : 68 > pla ;load status +0bbd : 48 > pha + > cmp_flag 0 +0bbe : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bc0 : d0fe > bne * ;failed not equal (non zero) + > +0bc2 : 28 > plp ;restore status + +0bc3 : 88 dey ;00 + tst_y 0,zero +0bc4 : 08 > php ;save flags +0bc5 : c000 > cpy #0 ;test result + > trap_ne +0bc7 : d0fe > bne * ;failed not equal (non zero) + > +0bc9 : 68 > pla ;load status +0bca : 48 > pha + > cmp_flag zero +0bcb : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bcd : d0fe > bne * ;failed not equal (non zero) + > +0bcf : 28 > plp ;restore status + +0bd0 : 88 dey ;ff + tst_y $ff,minus +0bd1 : 08 > php ;save flags +0bd2 : c0ff > cpy #$ff ;test result + > trap_ne +0bd4 : d0fe > bne * ;failed not equal (non zero) + > +0bd6 : 68 > pla ;load status +0bd7 : 48 > pha + > cmp_flag minus +0bd8 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bda : d0fe > bne * ;failed not equal (non zero) + > +0bdc : 28 > plp ;restore status + + +0bdd : a2ff ldx #$ff + set_stat $ff + > load_flag $ff +0bdf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0be1 : 48 > pha ;use stack to load status +0be2 : 28 > plp + +0be3 : 8a txa + tst_a $ff,$ff-zero +0be4 : 08 > php ;save flags +0be5 : c9ff > cmp #$ff ;test result + > trap_ne +0be7 : d0fe > bne * ;failed not equal (non zero) + > +0be9 : 68 > pla ;load status +0bea : 48 > pha + > cmp_flag $ff-zero +0beb : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bed : d0fe > bne * ;failed not equal (non zero) + > +0bef : 28 > plp ;restore status + +0bf0 : 08 php +0bf1 : e8 inx ;00 +0bf2 : 28 plp +0bf3 : 8a txa + tst_a 0,$ff-minus +0bf4 : 08 > php ;save flags +0bf5 : c900 > cmp #0 ;test result + > trap_ne +0bf7 : d0fe > bne * ;failed not equal (non zero) + > +0bf9 : 68 > pla ;load status +0bfa : 48 > pha + > cmp_flag $ff-minus +0bfb : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0bfd : d0fe > bne * ;failed not equal (non zero) + > +0bff : 28 > plp ;restore status + +0c00 : 08 php +0c01 : e8 inx ;01 +0c02 : 28 plp +0c03 : 8a txa + tst_a 1,$ff-minus-zero +0c04 : 08 > php ;save flags +0c05 : c901 > cmp #1 ;test result + > trap_ne +0c07 : d0fe > bne * ;failed not equal (non zero) + > +0c09 : 68 > pla ;load status +0c0a : 48 > pha + > cmp_flag $ff-minus-zero +0c0b : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c0d : d0fe > bne * ;failed not equal (non zero) + > +0c0f : 28 > plp ;restore status + + set_stat 0 + > load_flag 0 +0c10 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0c12 : 48 > pha ;use stack to load status +0c13 : 28 > plp + +0c14 : 8a txa + tst_a 1,0 +0c15 : 08 > php ;save flags +0c16 : c901 > cmp #1 ;test result + > trap_ne +0c18 : d0fe > bne * ;failed not equal (non zero) + > +0c1a : 68 > pla ;load status +0c1b : 48 > pha + > cmp_flag 0 +0c1c : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c1e : d0fe > bne * ;failed not equal (non zero) + > +0c20 : 28 > plp ;restore status + +0c21 : 08 php +0c22 : ca dex ;00 +0c23 : 28 plp +0c24 : 8a txa + tst_a 0,zero +0c25 : 08 > php ;save flags +0c26 : c900 > cmp #0 ;test result + > trap_ne +0c28 : d0fe > bne * ;failed not equal (non zero) + > +0c2a : 68 > pla ;load status +0c2b : 48 > pha + > cmp_flag zero +0c2c : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c2e : d0fe > bne * ;failed not equal (non zero) + > +0c30 : 28 > plp ;restore status + +0c31 : 08 php +0c32 : ca dex ;ff +0c33 : 28 plp +0c34 : 8a txa + tst_a $ff,minus +0c35 : 08 > php ;save flags +0c36 : c9ff > cmp #$ff ;test result + > trap_ne +0c38 : d0fe > bne * ;failed not equal (non zero) + > +0c3a : 68 > pla ;load status +0c3b : 48 > pha + > cmp_flag minus +0c3c : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c3e : d0fe > bne * ;failed not equal (non zero) + > +0c40 : 28 > plp ;restore status + + +0c41 : a0ff ldy #$ff + set_stat $ff + > load_flag $ff +0c43 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0c45 : 48 > pha ;use stack to load status +0c46 : 28 > plp + +0c47 : 98 tya + tst_a $ff,$ff-zero +0c48 : 08 > php ;save flags +0c49 : c9ff > cmp #$ff ;test result + > trap_ne +0c4b : d0fe > bne * ;failed not equal (non zero) + > +0c4d : 68 > pla ;load status +0c4e : 48 > pha + > cmp_flag $ff-zero +0c4f : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c51 : d0fe > bne * ;failed not equal (non zero) + > +0c53 : 28 > plp ;restore status + +0c54 : 08 php +0c55 : c8 iny ;00 +0c56 : 28 plp +0c57 : 98 tya + tst_a 0,$ff-minus +0c58 : 08 > php ;save flags +0c59 : c900 > cmp #0 ;test result + > trap_ne +0c5b : d0fe > bne * ;failed not equal (non zero) + > +0c5d : 68 > pla ;load status +0c5e : 48 > pha + > cmp_flag $ff-minus +0c5f : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c61 : d0fe > bne * ;failed not equal (non zero) + > +0c63 : 28 > plp ;restore status + +0c64 : 08 php +0c65 : c8 iny ;01 +0c66 : 28 plp +0c67 : 98 tya + tst_a 1,$ff-minus-zero +0c68 : 08 > php ;save flags +0c69 : c901 > cmp #1 ;test result + > trap_ne +0c6b : d0fe > bne * ;failed not equal (non zero) + > +0c6d : 68 > pla ;load status +0c6e : 48 > pha + > cmp_flag $ff-minus-zero +0c6f : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c71 : d0fe > bne * ;failed not equal (non zero) + > +0c73 : 28 > plp ;restore status + + set_stat 0 + > load_flag 0 +0c74 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0c76 : 48 > pha ;use stack to load status +0c77 : 28 > plp + +0c78 : 98 tya + tst_a 1,0 +0c79 : 08 > php ;save flags +0c7a : c901 > cmp #1 ;test result + > trap_ne +0c7c : d0fe > bne * ;failed not equal (non zero) + > +0c7e : 68 > pla ;load status +0c7f : 48 > pha + > cmp_flag 0 +0c80 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c82 : d0fe > bne * ;failed not equal (non zero) + > +0c84 : 28 > plp ;restore status + +0c85 : 08 php +0c86 : 88 dey ;00 +0c87 : 28 plp +0c88 : 98 tya + tst_a 0,zero +0c89 : 08 > php ;save flags +0c8a : c900 > cmp #0 ;test result + > trap_ne +0c8c : d0fe > bne * ;failed not equal (non zero) + > +0c8e : 68 > pla ;load status +0c8f : 48 > pha + > cmp_flag zero +0c90 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c92 : d0fe > bne * ;failed not equal (non zero) + > +0c94 : 28 > plp ;restore status + +0c95 : 08 php +0c96 : 88 dey ;ff +0c97 : 28 plp +0c98 : 98 tya + tst_a $ff,minus +0c99 : 08 > php ;save flags +0c9a : c9ff > cmp #$ff ;test result + > trap_ne +0c9c : d0fe > bne * ;failed not equal (non zero) + > +0c9e : 68 > pla ;load status +0c9f : 48 > pha + > cmp_flag minus +0ca0 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ca2 : d0fe > bne * ;failed not equal (non zero) + > +0ca4 : 28 > plp ;restore status + + + load_flag $ff +0ca5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +0ca7 : 48 pha +0ca8 : a2ff ldx #$ff ;ff +0caa : 8a txa +0cab : 28 plp +0cac : a8 tay + tst_y $ff,$ff-zero +0cad : 08 > php ;save flags +0cae : c0ff > cpy #$ff ;test result + > trap_ne +0cb0 : d0fe > bne * ;failed not equal (non zero) + > +0cb2 : 68 > pla ;load status +0cb3 : 48 > pha + > cmp_flag $ff-zero +0cb4 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cb6 : d0fe > bne * ;failed not equal (non zero) + > +0cb8 : 28 > plp ;restore status + +0cb9 : 08 php +0cba : e8 inx ;00 +0cbb : 8a txa +0cbc : 28 plp +0cbd : a8 tay + tst_y 0,$ff-minus +0cbe : 08 > php ;save flags +0cbf : c000 > cpy #0 ;test result + > trap_ne +0cc1 : d0fe > bne * ;failed not equal (non zero) + > +0cc3 : 68 > pla ;load status +0cc4 : 48 > pha + > cmp_flag $ff-minus +0cc5 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cc7 : d0fe > bne * ;failed not equal (non zero) + > +0cc9 : 28 > plp ;restore status + +0cca : 08 php +0ccb : e8 inx ;01 +0ccc : 8a txa +0ccd : 28 plp +0cce : a8 tay + tst_y 1,$ff-minus-zero +0ccf : 08 > php ;save flags +0cd0 : c001 > cpy #1 ;test result + > trap_ne +0cd2 : d0fe > bne * ;failed not equal (non zero) + > +0cd4 : 68 > pla ;load status +0cd5 : 48 > pha + > cmp_flag $ff-minus-zero +0cd6 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cd8 : d0fe > bne * ;failed not equal (non zero) + > +0cda : 28 > plp ;restore status + + load_flag 0 +0cdb : a900 > lda #0 ;allow test to change I-flag (no mask) + +0cdd : 48 pha +0cde : a900 lda #0 +0ce0 : 8a txa +0ce1 : 28 plp +0ce2 : a8 tay + tst_y 1,0 +0ce3 : 08 > php ;save flags +0ce4 : c001 > cpy #1 ;test result + > trap_ne +0ce6 : d0fe > bne * ;failed not equal (non zero) + > +0ce8 : 68 > pla ;load status +0ce9 : 48 > pha + > cmp_flag 0 +0cea : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cec : d0fe > bne * ;failed not equal (non zero) + > +0cee : 28 > plp ;restore status + +0cef : 08 php +0cf0 : ca dex ;00 +0cf1 : 8a txa +0cf2 : 28 plp +0cf3 : a8 tay + tst_y 0,zero +0cf4 : 08 > php ;save flags +0cf5 : c000 > cpy #0 ;test result + > trap_ne +0cf7 : d0fe > bne * ;failed not equal (non zero) + > +0cf9 : 68 > pla ;load status +0cfa : 48 > pha + > cmp_flag zero +0cfb : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cfd : d0fe > bne * ;failed not equal (non zero) + > +0cff : 28 > plp ;restore status + +0d00 : 08 php +0d01 : ca dex ;ff +0d02 : 8a txa +0d03 : 28 plp +0d04 : a8 tay + tst_y $ff,minus +0d05 : 08 > php ;save flags +0d06 : c0ff > cpy #$ff ;test result + > trap_ne +0d08 : d0fe > bne * ;failed not equal (non zero) + > +0d0a : 68 > pla ;load status +0d0b : 48 > pha + > cmp_flag minus +0d0c : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d0e : d0fe > bne * ;failed not equal (non zero) + > +0d10 : 28 > plp ;restore status + + + + load_flag $ff +0d11 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +0d13 : 48 pha +0d14 : a0ff ldy #$ff ;ff +0d16 : 98 tya +0d17 : 28 plp +0d18 : aa tax + tst_x $ff,$ff-zero +0d19 : 08 > php ;save flags +0d1a : e0ff > cpx #$ff ;test result + > trap_ne +0d1c : d0fe > bne * ;failed not equal (non zero) + > +0d1e : 68 > pla ;load status +0d1f : 48 > pha + > cmp_flag $ff-zero +0d20 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d22 : d0fe > bne * ;failed not equal (non zero) + > +0d24 : 28 > plp ;restore status + +0d25 : 08 php +0d26 : c8 iny ;00 +0d27 : 98 tya +0d28 : 28 plp +0d29 : aa tax + tst_x 0,$ff-minus +0d2a : 08 > php ;save flags +0d2b : e000 > cpx #0 ;test result + > trap_ne +0d2d : d0fe > bne * ;failed not equal (non zero) + > +0d2f : 68 > pla ;load status +0d30 : 48 > pha + > cmp_flag $ff-minus +0d31 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d33 : d0fe > bne * ;failed not equal (non zero) + > +0d35 : 28 > plp ;restore status + +0d36 : 08 php +0d37 : c8 iny ;01 +0d38 : 98 tya +0d39 : 28 plp +0d3a : aa tax + tst_x 1,$ff-minus-zero +0d3b : 08 > php ;save flags +0d3c : e001 > cpx #1 ;test result + > trap_ne +0d3e : d0fe > bne * ;failed not equal (non zero) + > +0d40 : 68 > pla ;load status +0d41 : 48 > pha + > cmp_flag $ff-minus-zero +0d42 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d44 : d0fe > bne * ;failed not equal (non zero) + > +0d46 : 28 > plp ;restore status + + load_flag 0 +0d47 : a900 > lda #0 ;allow test to change I-flag (no mask) + +0d49 : 48 pha +0d4a : a900 lda #0 ;preset status +0d4c : 98 tya +0d4d : 28 plp +0d4e : aa tax + tst_x 1,0 +0d4f : 08 > php ;save flags +0d50 : e001 > cpx #1 ;test result + > trap_ne +0d52 : d0fe > bne * ;failed not equal (non zero) + > +0d54 : 68 > pla ;load status +0d55 : 48 > pha + > cmp_flag 0 +0d56 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d58 : d0fe > bne * ;failed not equal (non zero) + > +0d5a : 28 > plp ;restore status + +0d5b : 08 php +0d5c : 88 dey ;00 +0d5d : 98 tya +0d5e : 28 plp +0d5f : aa tax + tst_x 0,zero +0d60 : 08 > php ;save flags +0d61 : e000 > cpx #0 ;test result + > trap_ne +0d63 : d0fe > bne * ;failed not equal (non zero) + > +0d65 : 68 > pla ;load status +0d66 : 48 > pha + > cmp_flag zero +0d67 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d69 : d0fe > bne * ;failed not equal (non zero) + > +0d6b : 28 > plp ;restore status + +0d6c : 08 php +0d6d : 88 dey ;ff +0d6e : 98 tya +0d6f : 28 plp +0d70 : aa tax + tst_x $ff,minus +0d71 : 08 > php ;save flags +0d72 : e0ff > cpx #$ff ;test result + > trap_ne +0d74 : d0fe > bne * ;failed not equal (non zero) + > +0d76 : 68 > pla ;load status +0d77 : 48 > pha + > cmp_flag minus +0d78 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d7a : d0fe > bne * ;failed not equal (non zero) + > +0d7c : 28 > plp ;restore status + + next_test +0d7d : ad0002 > lda test_case ;previous test +0d80 : c90d > cmp #test_num + > trap_ne ;test is out of sequence +0d82 : d0fe > bne * ;failed not equal (non zero) + > +000e = >test_num = test_num + 1 +0d84 : a90e > lda #test_num ;*** next tests' number +0d86 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ;TSX sets NZ - TXS does not + ; This section also tests for proper stack wrap around. +0d89 : a201 ldx #1 ;01 + set_stat $ff + > load_flag $ff +0d8b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0d8d : 48 > pha ;use stack to load status +0d8e : 28 > plp + +0d8f : 9a txs +0d90 : 08 php +0d91 : ad0101 lda $101 + cmp_flag $ff +0d94 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + + trap_ne +0d96 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +0d98 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0d9a : 48 > pha ;use stack to load status +0d9b : 28 > plp + +0d9c : 9a txs +0d9d : 08 php +0d9e : ad0101 lda $101 + cmp_flag 0 +0da1 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + trap_ne +0da3 : d0fe > bne * ;failed not equal (non zero) + +0da5 : ca dex ;00 + set_stat $ff + > load_flag $ff +0da6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0da8 : 48 > pha ;use stack to load status +0da9 : 28 > plp + +0daa : 9a txs +0dab : 08 php +0dac : ad0001 lda $100 + cmp_flag $ff +0daf : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + + trap_ne +0db1 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +0db3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0db5 : 48 > pha ;use stack to load status +0db6 : 28 > plp + +0db7 : 9a txs +0db8 : 08 php +0db9 : ad0001 lda $100 + cmp_flag 0 +0dbc : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + trap_ne +0dbe : d0fe > bne * ;failed not equal (non zero) + +0dc0 : ca dex ;ff + set_stat $ff + > load_flag $ff +0dc1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0dc3 : 48 > pha ;use stack to load status +0dc4 : 28 > plp + +0dc5 : 9a txs +0dc6 : 08 php +0dc7 : adff01 lda $1ff + cmp_flag $ff +0dca : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + + trap_ne +0dcc : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +0dce : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0dd0 : 48 > pha ;use stack to load status +0dd1 : 28 > plp + +0dd2 : 9a txs +0dd3 : 08 php +0dd4 : adff01 lda $1ff + cmp_flag 0 +0dd7 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + +0dd9 : a201 ldx #1 +0ddb : 9a txs ;sp=01 + set_stat $ff + > load_flag $ff +0ddc : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0dde : 48 > pha ;use stack to load status +0ddf : 28 > plp + +0de0 : ba tsx ;clears Z, N +0de1 : 08 php ;sp=00 +0de2 : e001 cpx #1 + trap_ne +0de4 : d0fe > bne * ;failed not equal (non zero) + +0de6 : ad0101 lda $101 + cmp_flag $ff-minus-zero +0de9 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + + trap_ne +0deb : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +0ded : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0def : 48 > pha ;use stack to load status +0df0 : 28 > plp + +0df1 : ba tsx ;clears N, sets Z +0df2 : 08 php ;sp=ff +0df3 : e000 cpx #0 + trap_ne +0df5 : d0fe > bne * ;failed not equal (non zero) + +0df7 : ad0001 lda $100 + cmp_flag $ff-minus +0dfa : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + + trap_ne +0dfc : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +0dfe : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0e00 : 48 > pha ;use stack to load status +0e01 : 28 > plp + +0e02 : ba tsx ;clears N, sets Z +0e03 : 08 php ;sp=fe +0e04 : e0ff cpx #$ff + trap_ne +0e06 : d0fe > bne * ;failed not equal (non zero) + +0e08 : adff01 lda $1ff + cmp_flag $ff-zero +0e0b : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + + trap_ne +0e0d : d0fe > bne * ;failed not equal (non zero) + + +0e0f : a201 ldx #1 +0e11 : 9a txs ;sp=01 + set_stat 0 + > load_flag 0 +0e12 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e14 : 48 > pha ;use stack to load status +0e15 : 28 > plp + +0e16 : ba tsx ;clears Z, N +0e17 : 08 php ;sp=00 +0e18 : e001 cpx #1 + trap_ne +0e1a : d0fe > bne * ;failed not equal (non zero) + +0e1c : ad0101 lda $101 + cmp_flag 0 +0e1f : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + trap_ne +0e21 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +0e23 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e25 : 48 > pha ;use stack to load status +0e26 : 28 > plp + +0e27 : ba tsx ;clears N, sets Z +0e28 : 08 php ;sp=ff +0e29 : e000 cpx #0 + trap_ne +0e2b : d0fe > bne * ;failed not equal (non zero) + +0e2d : ad0001 lda $100 + cmp_flag zero +0e30 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + + trap_ne +0e32 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +0e34 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e36 : 48 > pha ;use stack to load status +0e37 : 28 > plp + +0e38 : ba tsx ;clears N, sets Z +0e39 : 08 php ;sp=fe +0e3a : e0ff cpx #$ff + trap_ne +0e3c : d0fe > bne * ;failed not equal (non zero) + +0e3e : adff01 lda $1ff + cmp_flag minus +0e41 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + + trap_ne +0e43 : d0fe > bne * ;failed not equal (non zero) + +0e45 : 68 pla ;sp=ff + next_test +0e46 : ad0002 > lda test_case ;previous test +0e49 : c90e > cmp #test_num + > trap_ne ;test is out of sequence +0e4b : d0fe > bne * ;failed not equal (non zero) + > +000f = >test_num = test_num + 1 +0e4d : a90f > lda #test_num ;*** next tests' number +0e4f : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing index register load & store LDY LDX STY STX all addressing modes + ; LDX / STX - zp,y / abs,y +0e52 : a003 ldy #3 +0e54 : tldx + set_stat 0 + > load_flag 0 +0e54 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e56 : 48 > pha ;use stack to load status +0e57 : 28 > plp + +0e58 : b613 ldx zp1,y +0e5a : 08 php ;test stores do not alter flags +0e5b : 8a txa +0e5c : 49c3 eor #$c3 +0e5e : 28 plp +0e5f : 990302 sta abst,y +0e62 : 08 php ;flags after load/store sequence +0e63 : 49c3 eor #$c3 +0e65 : d91702 cmp abs1,y ;test result + trap_ne +0e68 : d0fe > bne * ;failed not equal (non zero) + +0e6a : 68 pla ;load status + eor_flag 0 +0e6b : 4930 > eor #0|fao ;invert expected flags + always on bits + +0e6d : d91c02 cmp fLDx,y ;test flags + trap_ne +0e70 : d0fe > bne * ;failed not equal (non zero) + +0e72 : 88 dey +0e73 : 10df bpl tldx + +0e75 : a003 ldy #3 +0e77 : tldx1 + set_stat $ff + > load_flag $ff +0e77 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0e79 : 48 > pha ;use stack to load status +0e7a : 28 > plp + +0e7b : b613 ldx zp1,y +0e7d : 08 php ;test stores do not alter flags +0e7e : 8a txa +0e7f : 49c3 eor #$c3 +0e81 : 28 plp +0e82 : 990302 sta abst,y +0e85 : 08 php ;flags after load/store sequence +0e86 : 49c3 eor #$c3 +0e88 : d91702 cmp abs1,y ;test result + trap_ne +0e8b : d0fe > bne * ;failed not equal (non zero) + +0e8d : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +0e8e : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +0e90 : d91c02 cmp fLDx,y ;test flags + trap_ne +0e93 : d0fe > bne * ;failed not equal (non zero) + +0e95 : 88 dey +0e96 : 10df bpl tldx1 + +0e98 : a003 ldy #3 +0e9a : tldx2 + set_stat 0 + > load_flag 0 +0e9a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e9c : 48 > pha ;use stack to load status +0e9d : 28 > plp + +0e9e : be1702 ldx abs1,y +0ea1 : 08 php ;test stores do not alter flags +0ea2 : 8a txa +0ea3 : 49c3 eor #$c3 +0ea5 : aa tax +0ea6 : 28 plp +0ea7 : 960c stx zpt,y +0ea9 : 08 php ;flags after load/store sequence +0eaa : 49c3 eor #$c3 +0eac : d91300 cmp zp1,y ;test result + trap_ne +0eaf : d0fe > bne * ;failed not equal (non zero) + +0eb1 : 68 pla ;load status + eor_flag 0 +0eb2 : 4930 > eor #0|fao ;invert expected flags + always on bits + +0eb4 : d91c02 cmp fLDx,y ;test flags + trap_ne +0eb7 : d0fe > bne * ;failed not equal (non zero) + +0eb9 : 88 dey +0eba : 10de bpl tldx2 + +0ebc : a003 ldy #3 +0ebe : tldx3 + set_stat $ff + > load_flag $ff +0ebe : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0ec0 : 48 > pha ;use stack to load status +0ec1 : 28 > plp + +0ec2 : be1702 ldx abs1,y +0ec5 : 08 php ;test stores do not alter flags +0ec6 : 8a txa +0ec7 : 49c3 eor #$c3 +0ec9 : aa tax +0eca : 28 plp +0ecb : 960c stx zpt,y +0ecd : 08 php ;flags after load/store sequence +0ece : 49c3 eor #$c3 +0ed0 : d91300 cmp zp1,y ;test result + trap_ne +0ed3 : d0fe > bne * ;failed not equal (non zero) + +0ed5 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +0ed6 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +0ed8 : d91c02 cmp fLDx,y ;test flags + trap_ne +0edb : d0fe > bne * ;failed not equal (non zero) + +0edd : 88 dey +0ede : 10de bpl tldx3 + +0ee0 : a003 ldy #3 ;testing store result +0ee2 : a200 ldx #0 +0ee4 : b90c00 tstx lda zpt,y +0ee7 : 49c3 eor #$c3 +0ee9 : d91300 cmp zp1,y + trap_ne ;store to zp data +0eec : d0fe > bne * ;failed not equal (non zero) + +0eee : 960c stx zpt,y ;clear +0ef0 : b90302 lda abst,y +0ef3 : 49c3 eor #$c3 +0ef5 : d91702 cmp abs1,y + trap_ne ;store to abs data +0ef8 : d0fe > bne * ;failed not equal (non zero) + +0efa : 8a txa +0efb : 990302 sta abst,y ;clear +0efe : 88 dey +0eff : 10e3 bpl tstx + next_test +0f01 : ad0002 > lda test_case ;previous test +0f04 : c90f > cmp #test_num + > trap_ne ;test is out of sequence +0f06 : d0fe > bne * ;failed not equal (non zero) + > +0010 = >test_num = test_num + 1 +0f08 : a910 > lda #test_num ;*** next tests' number +0f0a : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; indexed wraparound test (only zp should wrap) +0f0d : a0fd ldy #3+$fa +0f0f : b619 tldx4 ldx zp1-$fa&$ff,y ;wrap on indexed zp +0f11 : 8a txa +0f12 : 990901 sta abst-$fa,y ;no STX abs,y! +0f15 : 88 dey +0f16 : c0fa cpy #$fa +0f18 : b0f5 bcs tldx4 +0f1a : a0fd ldy #3+$fa +0f1c : be1d01 tldx5 ldx abs1-$fa,y ;no wrap on indexed abs +0f1f : 9612 stx zpt-$fa&$ff,y +0f21 : 88 dey +0f22 : c0fa cpy #$fa +0f24 : b0f6 bcs tldx5 +0f26 : a003 ldy #3 ;testing wraparound result +0f28 : a200 ldx #0 +0f2a : b90c00 tstx1 lda zpt,y +0f2d : d91300 cmp zp1,y + trap_ne ;store to zp data +0f30 : d0fe > bne * ;failed not equal (non zero) + +0f32 : 960c stx zpt,y ;clear +0f34 : b90302 lda abst,y +0f37 : d91702 cmp abs1,y + trap_ne ;store to abs data +0f3a : d0fe > bne * ;failed not equal (non zero) + +0f3c : 8a txa +0f3d : 990302 sta abst,y ;clear +0f40 : 88 dey +0f41 : 10e7 bpl tstx1 + next_test +0f43 : ad0002 > lda test_case ;previous test +0f46 : c910 > cmp #test_num + > trap_ne ;test is out of sequence +0f48 : d0fe > bne * ;failed not equal (non zero) + > +0011 = >test_num = test_num + 1 +0f4a : a911 > lda #test_num ;*** next tests' number +0f4c : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; LDY / STY - zp,x / abs,x +0f4f : a203 ldx #3 +0f51 : tldy + set_stat 0 + > load_flag 0 +0f51 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0f53 : 48 > pha ;use stack to load status +0f54 : 28 > plp + +0f55 : b413 ldy zp1,x +0f57 : 08 php ;test stores do not alter flags +0f58 : 98 tya +0f59 : 49c3 eor #$c3 +0f5b : 28 plp +0f5c : 9d0302 sta abst,x +0f5f : 08 php ;flags after load/store sequence +0f60 : 49c3 eor #$c3 +0f62 : dd1702 cmp abs1,x ;test result + trap_ne +0f65 : d0fe > bne * ;failed not equal (non zero) + +0f67 : 68 pla ;load status + eor_flag 0 +0f68 : 4930 > eor #0|fao ;invert expected flags + always on bits + +0f6a : dd1c02 cmp fLDx,x ;test flags + trap_ne +0f6d : d0fe > bne * ;failed not equal (non zero) + +0f6f : ca dex +0f70 : 10df bpl tldy + +0f72 : a203 ldx #3 +0f74 : tldy1 + set_stat $ff + > load_flag $ff +0f74 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0f76 : 48 > pha ;use stack to load status +0f77 : 28 > plp + +0f78 : b413 ldy zp1,x +0f7a : 08 php ;test stores do not alter flags +0f7b : 98 tya +0f7c : 49c3 eor #$c3 +0f7e : 28 plp +0f7f : 9d0302 sta abst,x +0f82 : 08 php ;flags after load/store sequence +0f83 : 49c3 eor #$c3 +0f85 : dd1702 cmp abs1,x ;test result + trap_ne +0f88 : d0fe > bne * ;failed not equal (non zero) + +0f8a : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +0f8b : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +0f8d : dd1c02 cmp fLDx,x ;test flags + trap_ne +0f90 : d0fe > bne * ;failed not equal (non zero) + +0f92 : ca dex +0f93 : 10df bpl tldy1 + +0f95 : a203 ldx #3 +0f97 : tldy2 + set_stat 0 + > load_flag 0 +0f97 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0f99 : 48 > pha ;use stack to load status +0f9a : 28 > plp + +0f9b : bc1702 ldy abs1,x +0f9e : 08 php ;test stores do not alter flags +0f9f : 98 tya +0fa0 : 49c3 eor #$c3 +0fa2 : a8 tay +0fa3 : 28 plp +0fa4 : 940c sty zpt,x +0fa6 : 08 php ;flags after load/store sequence +0fa7 : 49c3 eor #$c3 +0fa9 : d513 cmp zp1,x ;test result + trap_ne +0fab : d0fe > bne * ;failed not equal (non zero) + +0fad : 68 pla ;load status + eor_flag 0 +0fae : 4930 > eor #0|fao ;invert expected flags + always on bits + +0fb0 : dd1c02 cmp fLDx,x ;test flags + trap_ne +0fb3 : d0fe > bne * ;failed not equal (non zero) + +0fb5 : ca dex +0fb6 : 10df bpl tldy2 + +0fb8 : a203 ldx #3 +0fba : tldy3 + set_stat $ff + > load_flag $ff +0fba : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0fbc : 48 > pha ;use stack to load status +0fbd : 28 > plp + +0fbe : bc1702 ldy abs1,x +0fc1 : 08 php ;test stores do not alter flags +0fc2 : 98 tya +0fc3 : 49c3 eor #$c3 +0fc5 : a8 tay +0fc6 : 28 plp +0fc7 : 940c sty zpt,x +0fc9 : 08 php ;flags after load/store sequence +0fca : 49c3 eor #$c3 +0fcc : d513 cmp zp1,x ;test result + trap_ne +0fce : d0fe > bne * ;failed not equal (non zero) + +0fd0 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +0fd1 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +0fd3 : dd1c02 cmp fLDx,x ;test flags + trap_ne +0fd6 : d0fe > bne * ;failed not equal (non zero) + +0fd8 : ca dex +0fd9 : 10df bpl tldy3 + +0fdb : a203 ldx #3 ;testing store result +0fdd : a000 ldy #0 +0fdf : b50c tsty lda zpt,x +0fe1 : 49c3 eor #$c3 +0fe3 : d513 cmp zp1,x + trap_ne ;store to zp,x data +0fe5 : d0fe > bne * ;failed not equal (non zero) + +0fe7 : 940c sty zpt,x ;clear +0fe9 : bd0302 lda abst,x +0fec : 49c3 eor #$c3 +0fee : dd1702 cmp abs1,x + trap_ne ;store to abs,x data +0ff1 : d0fe > bne * ;failed not equal (non zero) + +0ff3 : 8a txa +0ff4 : 9d0302 sta abst,x ;clear +0ff7 : ca dex +0ff8 : 10e5 bpl tsty + next_test +0ffa : ad0002 > lda test_case ;previous test +0ffd : c911 > cmp #test_num + > trap_ne ;test is out of sequence +0fff : d0fe > bne * ;failed not equal (non zero) + > +0012 = >test_num = test_num + 1 +1001 : a912 > lda #test_num ;*** next tests' number +1003 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; indexed wraparound test (only zp should wrap) +1006 : a2fd ldx #3+$fa +1008 : b419 tldy4 ldy zp1-$fa&$ff,x ;wrap on indexed zp +100a : 98 tya +100b : 9d0901 sta abst-$fa,x ;no STX abs,x! +100e : ca dex +100f : e0fa cpx #$fa +1011 : b0f5 bcs tldy4 +1013 : a2fd ldx #3+$fa +1015 : bc1d01 tldy5 ldy abs1-$fa,x ;no wrap on indexed abs +1018 : 9412 sty zpt-$fa&$ff,x +101a : ca dex +101b : e0fa cpx #$fa +101d : b0f6 bcs tldy5 +101f : a203 ldx #3 ;testing wraparound result +1021 : a000 ldy #0 +1023 : b50c tsty1 lda zpt,x +1025 : d513 cmp zp1,x + trap_ne ;store to zp,x data +1027 : d0fe > bne * ;failed not equal (non zero) + +1029 : 940c sty zpt,x ;clear +102b : bd0302 lda abst,x +102e : dd1702 cmp abs1,x + trap_ne ;store to abs,x data +1031 : d0fe > bne * ;failed not equal (non zero) + +1033 : 8a txa +1034 : 9d0302 sta abst,x ;clear +1037 : ca dex +1038 : 10e9 bpl tsty1 + next_test +103a : ad0002 > lda test_case ;previous test +103d : c912 > cmp #test_num + > trap_ne ;test is out of sequence +103f : d0fe > bne * ;failed not equal (non zero) + > +0013 = >test_num = test_num + 1 +1041 : a913 > lda #test_num ;*** next tests' number +1043 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; LDX / STX - zp / abs / # + set_stat 0 + > load_flag 0 +1046 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1048 : 48 > pha ;use stack to load status +1049 : 28 > plp + +104a : a613 ldx zp1 +104c : 08 php ;test stores do not alter flags +104d : 8a txa +104e : 49c3 eor #$c3 +1050 : aa tax +1051 : 28 plp +1052 : 8e0302 stx abst +1055 : 08 php ;flags after load/store sequence +1056 : 49c3 eor #$c3 +1058 : aa tax +1059 : e0c3 cpx #$c3 ;test result + trap_ne +105b : d0fe > bne * ;failed not equal (non zero) + +105d : 68 pla ;load status + eor_flag 0 +105e : 4930 > eor #0|fao ;invert expected flags + always on bits + +1060 : cd1c02 cmp fLDx ;test flags + trap_ne +1063 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1065 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1067 : 48 > pha ;use stack to load status +1068 : 28 > plp + +1069 : a614 ldx zp1+1 +106b : 08 php ;test stores do not alter flags +106c : 8a txa +106d : 49c3 eor #$c3 +106f : aa tax +1070 : 28 plp +1071 : 8e0402 stx abst+1 +1074 : 08 php ;flags after load/store sequence +1075 : 49c3 eor #$c3 +1077 : aa tax +1078 : e082 cpx #$82 ;test result + trap_ne +107a : d0fe > bne * ;failed not equal (non zero) + +107c : 68 pla ;load status + eor_flag 0 +107d : 4930 > eor #0|fao ;invert expected flags + always on bits + +107f : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1082 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1084 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1086 : 48 > pha ;use stack to load status +1087 : 28 > plp + +1088 : a615 ldx zp1+2 +108a : 08 php ;test stores do not alter flags +108b : 8a txa +108c : 49c3 eor #$c3 +108e : aa tax +108f : 28 plp +1090 : 8e0502 stx abst+2 +1093 : 08 php ;flags after load/store sequence +1094 : 49c3 eor #$c3 +1096 : aa tax +1097 : e041 cpx #$41 ;test result + trap_ne +1099 : d0fe > bne * ;failed not equal (non zero) + +109b : 68 pla ;load status + eor_flag 0 +109c : 4930 > eor #0|fao ;invert expected flags + always on bits + +109e : cd1e02 cmp fLDx+2 ;test flags + trap_ne +10a1 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +10a3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +10a5 : 48 > pha ;use stack to load status +10a6 : 28 > plp + +10a7 : a616 ldx zp1+3 +10a9 : 08 php ;test stores do not alter flags +10aa : 8a txa +10ab : 49c3 eor #$c3 +10ad : aa tax +10ae : 28 plp +10af : 8e0602 stx abst+3 +10b2 : 08 php ;flags after load/store sequence +10b3 : 49c3 eor #$c3 +10b5 : aa tax +10b6 : e000 cpx #0 ;test result + trap_ne +10b8 : d0fe > bne * ;failed not equal (non zero) + +10ba : 68 pla ;load status + eor_flag 0 +10bb : 4930 > eor #0|fao ;invert expected flags + always on bits + +10bd : cd1f02 cmp fLDx+3 ;test flags + trap_ne +10c0 : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +10c2 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +10c4 : 48 > pha ;use stack to load status +10c5 : 28 > plp + +10c6 : a613 ldx zp1 +10c8 : 08 php ;test stores do not alter flags +10c9 : 8a txa +10ca : 49c3 eor #$c3 +10cc : aa tax +10cd : 28 plp +10ce : 8e0302 stx abst +10d1 : 08 php ;flags after load/store sequence +10d2 : 49c3 eor #$c3 +10d4 : aa tax +10d5 : e0c3 cpx #$c3 ;test result + trap_ne ; +10d7 : d0fe > bne * ;failed not equal (non zero) + +10d9 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +10da : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +10dc : cd1c02 cmp fLDx ;test flags + trap_ne +10df : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +10e1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +10e3 : 48 > pha ;use stack to load status +10e4 : 28 > plp + +10e5 : a614 ldx zp1+1 +10e7 : 08 php ;test stores do not alter flags +10e8 : 8a txa +10e9 : 49c3 eor #$c3 +10eb : aa tax +10ec : 28 plp +10ed : 8e0402 stx abst+1 +10f0 : 08 php ;flags after load/store sequence +10f1 : 49c3 eor #$c3 +10f3 : aa tax +10f4 : e082 cpx #$82 ;test result + trap_ne +10f6 : d0fe > bne * ;failed not equal (non zero) + +10f8 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +10f9 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +10fb : cd1d02 cmp fLDx+1 ;test flags + trap_ne +10fe : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1100 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1102 : 48 > pha ;use stack to load status +1103 : 28 > plp + +1104 : a615 ldx zp1+2 +1106 : 08 php ;test stores do not alter flags +1107 : 8a txa +1108 : 49c3 eor #$c3 +110a : aa tax +110b : 28 plp +110c : 8e0502 stx abst+2 +110f : 08 php ;flags after load/store sequence +1110 : 49c3 eor #$c3 +1112 : aa tax +1113 : e041 cpx #$41 ;test result + trap_ne ; +1115 : d0fe > bne * ;failed not equal (non zero) + +1117 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1118 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +111a : cd1e02 cmp fLDx+2 ;test flags + trap_ne +111d : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +111f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1121 : 48 > pha ;use stack to load status +1122 : 28 > plp + +1123 : a616 ldx zp1+3 +1125 : 08 php ;test stores do not alter flags +1126 : 8a txa +1127 : 49c3 eor #$c3 +1129 : aa tax +112a : 28 plp +112b : 8e0602 stx abst+3 +112e : 08 php ;flags after load/store sequence +112f : 49c3 eor #$c3 +1131 : aa tax +1132 : e000 cpx #0 ;test result + trap_ne +1134 : d0fe > bne * ;failed not equal (non zero) + +1136 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1137 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1139 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +113c : d0fe > bne * ;failed not equal (non zero) + + + set_stat 0 + > load_flag 0 +113e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1140 : 48 > pha ;use stack to load status +1141 : 28 > plp + +1142 : ae1702 ldx abs1 +1145 : 08 php ;test stores do not alter flags +1146 : 8a txa +1147 : 49c3 eor #$c3 +1149 : aa tax +114a : 28 plp +114b : 860c stx zpt +114d : 08 php ;flags after load/store sequence +114e : 49c3 eor #$c3 +1150 : c513 cmp zp1 ;test result + trap_ne +1152 : d0fe > bne * ;failed not equal (non zero) + +1154 : 68 pla ;load status + eor_flag 0 +1155 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1157 : cd1c02 cmp fLDx ;test flags + trap_ne +115a : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +115c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +115e : 48 > pha ;use stack to load status +115f : 28 > plp + +1160 : ae1802 ldx abs1+1 +1163 : 08 php ;test stores do not alter flags +1164 : 8a txa +1165 : 49c3 eor #$c3 +1167 : aa tax +1168 : 28 plp +1169 : 860d stx zpt+1 +116b : 08 php ;flags after load/store sequence +116c : 49c3 eor #$c3 +116e : c514 cmp zp1+1 ;test result + trap_ne +1170 : d0fe > bne * ;failed not equal (non zero) + +1172 : 68 pla ;load status + eor_flag 0 +1173 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1175 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1178 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +117a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +117c : 48 > pha ;use stack to load status +117d : 28 > plp + +117e : ae1902 ldx abs1+2 +1181 : 08 php ;test stores do not alter flags +1182 : 8a txa +1183 : 49c3 eor #$c3 +1185 : aa tax +1186 : 28 plp +1187 : 860e stx zpt+2 +1189 : 08 php ;flags after load/store sequence +118a : 49c3 eor #$c3 +118c : c515 cmp zp1+2 ;test result + trap_ne +118e : d0fe > bne * ;failed not equal (non zero) + +1190 : 68 pla ;load status + eor_flag 0 +1191 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1193 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1196 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1198 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +119a : 48 > pha ;use stack to load status +119b : 28 > plp + +119c : ae1a02 ldx abs1+3 +119f : 08 php ;test stores do not alter flags +11a0 : 8a txa +11a1 : 49c3 eor #$c3 +11a3 : aa tax +11a4 : 28 plp +11a5 : 860f stx zpt+3 +11a7 : 08 php ;flags after load/store sequence +11a8 : 49c3 eor #$c3 +11aa : c516 cmp zp1+3 ;test result + trap_ne +11ac : d0fe > bne * ;failed not equal (non zero) + +11ae : 68 pla ;load status + eor_flag 0 +11af : 4930 > eor #0|fao ;invert expected flags + always on bits + +11b1 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +11b4 : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +11b6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +11b8 : 48 > pha ;use stack to load status +11b9 : 28 > plp + +11ba : ae1702 ldx abs1 +11bd : 08 php ;test stores do not alter flags +11be : 8a txa +11bf : 49c3 eor #$c3 +11c1 : aa tax +11c2 : 28 plp +11c3 : 860c stx zpt +11c5 : 08 php ;flags after load/store sequence +11c6 : 49c3 eor #$c3 +11c8 : aa tax +11c9 : e413 cpx zp1 ;test result + trap_ne +11cb : d0fe > bne * ;failed not equal (non zero) + +11cd : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +11ce : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +11d0 : cd1c02 cmp fLDx ;test flags + trap_ne +11d3 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +11d5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +11d7 : 48 > pha ;use stack to load status +11d8 : 28 > plp + +11d9 : ae1802 ldx abs1+1 +11dc : 08 php ;test stores do not alter flags +11dd : 8a txa +11de : 49c3 eor #$c3 +11e0 : aa tax +11e1 : 28 plp +11e2 : 860d stx zpt+1 +11e4 : 08 php ;flags after load/store sequence +11e5 : 49c3 eor #$c3 +11e7 : aa tax +11e8 : e414 cpx zp1+1 ;test result + trap_ne +11ea : d0fe > bne * ;failed not equal (non zero) + +11ec : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +11ed : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +11ef : cd1d02 cmp fLDx+1 ;test flags + trap_ne +11f2 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +11f4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +11f6 : 48 > pha ;use stack to load status +11f7 : 28 > plp + +11f8 : ae1902 ldx abs1+2 +11fb : 08 php ;test stores do not alter flags +11fc : 8a txa +11fd : 49c3 eor #$c3 +11ff : aa tax +1200 : 28 plp +1201 : 860e stx zpt+2 +1203 : 08 php ;flags after load/store sequence +1204 : 49c3 eor #$c3 +1206 : aa tax +1207 : e415 cpx zp1+2 ;test result + trap_ne +1209 : d0fe > bne * ;failed not equal (non zero) + +120b : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +120c : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +120e : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1211 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1213 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1215 : 48 > pha ;use stack to load status +1216 : 28 > plp + +1217 : ae1a02 ldx abs1+3 +121a : 08 php ;test stores do not alter flags +121b : 8a txa +121c : 49c3 eor #$c3 +121e : aa tax +121f : 28 plp +1220 : 860f stx zpt+3 +1222 : 08 php ;flags after load/store sequence +1223 : 49c3 eor #$c3 +1225 : aa tax +1226 : e416 cpx zp1+3 ;test result + trap_ne +1228 : d0fe > bne * ;failed not equal (non zero) + +122a : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +122b : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +122d : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1230 : d0fe > bne * ;failed not equal (non zero) + + + set_stat 0 + > load_flag 0 +1232 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1234 : 48 > pha ;use stack to load status +1235 : 28 > plp + +1236 : a2c3 ldx #$c3 +1238 : 08 php +1239 : ec1702 cpx abs1 ;test result + trap_ne +123c : d0fe > bne * ;failed not equal (non zero) + +123e : 68 pla ;load status + eor_flag 0 +123f : 4930 > eor #0|fao ;invert expected flags + always on bits + +1241 : cd1c02 cmp fLDx ;test flags + trap_ne +1244 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1246 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1248 : 48 > pha ;use stack to load status +1249 : 28 > plp + +124a : a282 ldx #$82 +124c : 08 php +124d : ec1802 cpx abs1+1 ;test result + trap_ne +1250 : d0fe > bne * ;failed not equal (non zero) + +1252 : 68 pla ;load status + eor_flag 0 +1253 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1255 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1258 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +125a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +125c : 48 > pha ;use stack to load status +125d : 28 > plp + +125e : a241 ldx #$41 +1260 : 08 php +1261 : ec1902 cpx abs1+2 ;test result + trap_ne +1264 : d0fe > bne * ;failed not equal (non zero) + +1266 : 68 pla ;load status + eor_flag 0 +1267 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1269 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +126c : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +126e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1270 : 48 > pha ;use stack to load status +1271 : 28 > plp + +1272 : a200 ldx #0 +1274 : 08 php +1275 : ec1a02 cpx abs1+3 ;test result + trap_ne +1278 : d0fe > bne * ;failed not equal (non zero) + +127a : 68 pla ;load status + eor_flag 0 +127b : 4930 > eor #0|fao ;invert expected flags + always on bits + +127d : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1280 : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +1282 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1284 : 48 > pha ;use stack to load status +1285 : 28 > plp + +1286 : a2c3 ldx #$c3 +1288 : 08 php +1289 : ec1702 cpx abs1 ;test result + trap_ne +128c : d0fe > bne * ;failed not equal (non zero) + +128e : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +128f : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1291 : cd1c02 cmp fLDx ;test flags + trap_ne +1294 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1296 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1298 : 48 > pha ;use stack to load status +1299 : 28 > plp + +129a : a282 ldx #$82 +129c : 08 php +129d : ec1802 cpx abs1+1 ;test result + trap_ne +12a0 : d0fe > bne * ;failed not equal (non zero) + +12a2 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +12a3 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +12a5 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +12a8 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +12aa : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +12ac : 48 > pha ;use stack to load status +12ad : 28 > plp + +12ae : a241 ldx #$41 +12b0 : 08 php +12b1 : ec1902 cpx abs1+2 ;test result + trap_ne +12b4 : d0fe > bne * ;failed not equal (non zero) + +12b6 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +12b7 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +12b9 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +12bc : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +12be : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +12c0 : 48 > pha ;use stack to load status +12c1 : 28 > plp + +12c2 : a200 ldx #0 +12c4 : 08 php +12c5 : ec1a02 cpx abs1+3 ;test result + trap_ne +12c8 : d0fe > bne * ;failed not equal (non zero) + +12ca : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +12cb : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +12cd : cd1f02 cmp fLDx+3 ;test flags + trap_ne +12d0 : d0fe > bne * ;failed not equal (non zero) + + +12d2 : a200 ldx #0 +12d4 : a50c lda zpt +12d6 : 49c3 eor #$c3 +12d8 : c513 cmp zp1 + trap_ne ;store to zp data +12da : d0fe > bne * ;failed not equal (non zero) + +12dc : 860c stx zpt ;clear +12de : ad0302 lda abst +12e1 : 49c3 eor #$c3 +12e3 : cd1702 cmp abs1 + trap_ne ;store to abs data +12e6 : d0fe > bne * ;failed not equal (non zero) + +12e8 : 8e0302 stx abst ;clear +12eb : a50d lda zpt+1 +12ed : 49c3 eor #$c3 +12ef : c514 cmp zp1+1 + trap_ne ;store to zp data +12f1 : d0fe > bne * ;failed not equal (non zero) + +12f3 : 860d stx zpt+1 ;clear +12f5 : ad0402 lda abst+1 +12f8 : 49c3 eor #$c3 +12fa : cd1802 cmp abs1+1 + trap_ne ;store to abs data +12fd : d0fe > bne * ;failed not equal (non zero) + +12ff : 8e0402 stx abst+1 ;clear +1302 : a50e lda zpt+2 +1304 : 49c3 eor #$c3 +1306 : c515 cmp zp1+2 + trap_ne ;store to zp data +1308 : d0fe > bne * ;failed not equal (non zero) + +130a : 860e stx zpt+2 ;clear +130c : ad0502 lda abst+2 +130f : 49c3 eor #$c3 +1311 : cd1902 cmp abs1+2 + trap_ne ;store to abs data +1314 : d0fe > bne * ;failed not equal (non zero) + +1316 : 8e0502 stx abst+2 ;clear +1319 : a50f lda zpt+3 +131b : 49c3 eor #$c3 +131d : c516 cmp zp1+3 + trap_ne ;store to zp data +131f : d0fe > bne * ;failed not equal (non zero) + +1321 : 860f stx zpt+3 ;clear +1323 : ad0602 lda abst+3 +1326 : 49c3 eor #$c3 +1328 : cd1a02 cmp abs1+3 + trap_ne ;store to abs data +132b : d0fe > bne * ;failed not equal (non zero) + +132d : 8e0602 stx abst+3 ;clear + next_test +1330 : ad0002 > lda test_case ;previous test +1333 : c913 > cmp #test_num + > trap_ne ;test is out of sequence +1335 : d0fe > bne * ;failed not equal (non zero) + > +0014 = >test_num = test_num + 1 +1337 : a914 > lda #test_num ;*** next tests' number +1339 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; LDY / STY - zp / abs / # + set_stat 0 + > load_flag 0 +133c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +133e : 48 > pha ;use stack to load status +133f : 28 > plp + +1340 : a413 ldy zp1 +1342 : 08 php ;test stores do not alter flags +1343 : 98 tya +1344 : 49c3 eor #$c3 +1346 : a8 tay +1347 : 28 plp +1348 : 8c0302 sty abst +134b : 08 php ;flags after load/store sequence +134c : 49c3 eor #$c3 +134e : a8 tay +134f : c0c3 cpy #$c3 ;test result + trap_ne +1351 : d0fe > bne * ;failed not equal (non zero) + +1353 : 68 pla ;load status + eor_flag 0 +1354 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1356 : cd1c02 cmp fLDx ;test flags + trap_ne +1359 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +135b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +135d : 48 > pha ;use stack to load status +135e : 28 > plp + +135f : a414 ldy zp1+1 +1361 : 08 php ;test stores do not alter flags +1362 : 98 tya +1363 : 49c3 eor #$c3 +1365 : a8 tay +1366 : 28 plp +1367 : 8c0402 sty abst+1 +136a : 08 php ;flags after load/store sequence +136b : 49c3 eor #$c3 +136d : a8 tay +136e : c082 cpy #$82 ;test result + trap_ne +1370 : d0fe > bne * ;failed not equal (non zero) + +1372 : 68 pla ;load status + eor_flag 0 +1373 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1375 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1378 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +137a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +137c : 48 > pha ;use stack to load status +137d : 28 > plp + +137e : a415 ldy zp1+2 +1380 : 08 php ;test stores do not alter flags +1381 : 98 tya +1382 : 49c3 eor #$c3 +1384 : a8 tay +1385 : 28 plp +1386 : 8c0502 sty abst+2 +1389 : 08 php ;flags after load/store sequence +138a : 49c3 eor #$c3 +138c : a8 tay +138d : c041 cpy #$41 ;test result + trap_ne +138f : d0fe > bne * ;failed not equal (non zero) + +1391 : 68 pla ;load status + eor_flag 0 +1392 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1394 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1397 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1399 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +139b : 48 > pha ;use stack to load status +139c : 28 > plp + +139d : a416 ldy zp1+3 +139f : 08 php ;test stores do not alter flags +13a0 : 98 tya +13a1 : 49c3 eor #$c3 +13a3 : a8 tay +13a4 : 28 plp +13a5 : 8c0602 sty abst+3 +13a8 : 08 php ;flags after load/store sequence +13a9 : 49c3 eor #$c3 +13ab : a8 tay +13ac : c000 cpy #0 ;test result + trap_ne +13ae : d0fe > bne * ;failed not equal (non zero) + +13b0 : 68 pla ;load status + eor_flag 0 +13b1 : 4930 > eor #0|fao ;invert expected flags + always on bits + +13b3 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +13b6 : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +13b8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +13ba : 48 > pha ;use stack to load status +13bb : 28 > plp + +13bc : a413 ldy zp1 +13be : 08 php ;test stores do not alter flags +13bf : 98 tya +13c0 : 49c3 eor #$c3 +13c2 : a8 tay +13c3 : 28 plp +13c4 : 8c0302 sty abst +13c7 : 08 php ;flags after load/store sequence +13c8 : 49c3 eor #$c3 +13ca : a8 tay +13cb : c0c3 cpy #$c3 ;test result + trap_ne +13cd : d0fe > bne * ;failed not equal (non zero) + +13cf : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +13d0 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +13d2 : cd1c02 cmp fLDx ;test flags + trap_ne +13d5 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +13d7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +13d9 : 48 > pha ;use stack to load status +13da : 28 > plp + +13db : a414 ldy zp1+1 +13dd : 08 php ;test stores do not alter flags +13de : 98 tya +13df : 49c3 eor #$c3 +13e1 : a8 tay +13e2 : 28 plp +13e3 : 8c0402 sty abst+1 +13e6 : 08 php ;flags after load/store sequence +13e7 : 49c3 eor #$c3 +13e9 : a8 tay +13ea : c082 cpy #$82 ;test result + trap_ne +13ec : d0fe > bne * ;failed not equal (non zero) + +13ee : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +13ef : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +13f1 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +13f4 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +13f6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +13f8 : 48 > pha ;use stack to load status +13f9 : 28 > plp + +13fa : a415 ldy zp1+2 +13fc : 08 php ;test stores do not alter flags +13fd : 98 tya +13fe : 49c3 eor #$c3 +1400 : a8 tay +1401 : 28 plp +1402 : 8c0502 sty abst+2 +1405 : 08 php ;flags after load/store sequence +1406 : 49c3 eor #$c3 +1408 : a8 tay +1409 : c041 cpy #$41 ;test result + trap_ne +140b : d0fe > bne * ;failed not equal (non zero) + +140d : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +140e : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1410 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1413 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1415 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1417 : 48 > pha ;use stack to load status +1418 : 28 > plp + +1419 : a416 ldy zp1+3 +141b : 08 php ;test stores do not alter flags +141c : 98 tya +141d : 49c3 eor #$c3 +141f : a8 tay +1420 : 28 plp +1421 : 8c0602 sty abst+3 +1424 : 08 php ;flags after load/store sequence +1425 : 49c3 eor #$c3 +1427 : a8 tay +1428 : c000 cpy #0 ;test result + trap_ne +142a : d0fe > bne * ;failed not equal (non zero) + +142c : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +142d : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +142f : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1432 : d0fe > bne * ;failed not equal (non zero) + + + set_stat 0 + > load_flag 0 +1434 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1436 : 48 > pha ;use stack to load status +1437 : 28 > plp + +1438 : ac1702 ldy abs1 +143b : 08 php ;test stores do not alter flags +143c : 98 tya +143d : 49c3 eor #$c3 +143f : a8 tay +1440 : 28 plp +1441 : 840c sty zpt +1443 : 08 php ;flags after load/store sequence +1444 : 49c3 eor #$c3 +1446 : a8 tay +1447 : c413 cpy zp1 ;test result + trap_ne +1449 : d0fe > bne * ;failed not equal (non zero) + +144b : 68 pla ;load status + eor_flag 0 +144c : 4930 > eor #0|fao ;invert expected flags + always on bits + +144e : cd1c02 cmp fLDx ;test flags + trap_ne +1451 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1453 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1455 : 48 > pha ;use stack to load status +1456 : 28 > plp + +1457 : ac1802 ldy abs1+1 +145a : 08 php ;test stores do not alter flags +145b : 98 tya +145c : 49c3 eor #$c3 +145e : a8 tay +145f : 28 plp +1460 : 840d sty zpt+1 +1462 : 08 php ;flags after load/store sequence +1463 : 49c3 eor #$c3 +1465 : a8 tay +1466 : c414 cpy zp1+1 ;test result + trap_ne +1468 : d0fe > bne * ;failed not equal (non zero) + +146a : 68 pla ;load status + eor_flag 0 +146b : 4930 > eor #0|fao ;invert expected flags + always on bits + +146d : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1470 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1472 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1474 : 48 > pha ;use stack to load status +1475 : 28 > plp + +1476 : ac1902 ldy abs1+2 +1479 : 08 php ;test stores do not alter flags +147a : 98 tya +147b : 49c3 eor #$c3 +147d : a8 tay +147e : 28 plp +147f : 840e sty zpt+2 +1481 : 08 php ;flags after load/store sequence +1482 : 49c3 eor #$c3 +1484 : a8 tay +1485 : c415 cpy zp1+2 ;test result + trap_ne +1487 : d0fe > bne * ;failed not equal (non zero) + +1489 : 68 pla ;load status + eor_flag 0 +148a : 4930 > eor #0|fao ;invert expected flags + always on bits + +148c : cd1e02 cmp fLDx+2 ;test flags + trap_ne +148f : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1491 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1493 : 48 > pha ;use stack to load status +1494 : 28 > plp + +1495 : ac1a02 ldy abs1+3 +1498 : 08 php ;test stores do not alter flags +1499 : 98 tya +149a : 49c3 eor #$c3 +149c : a8 tay +149d : 28 plp +149e : 840f sty zpt+3 +14a0 : 08 php ;flags after load/store sequence +14a1 : 49c3 eor #$c3 +14a3 : a8 tay +14a4 : c416 cpy zp1+3 ;test result + trap_ne +14a6 : d0fe > bne * ;failed not equal (non zero) + +14a8 : 68 pla ;load status + eor_flag 0 +14a9 : 4930 > eor #0|fao ;invert expected flags + always on bits + +14ab : cd1f02 cmp fLDx+3 ;test flags + trap_ne +14ae : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +14b0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +14b2 : 48 > pha ;use stack to load status +14b3 : 28 > plp + +14b4 : ac1702 ldy abs1 +14b7 : 08 php ;test stores do not alter flags +14b8 : 98 tya +14b9 : 49c3 eor #$c3 +14bb : a8 tay +14bc : 28 plp +14bd : 840c sty zpt +14bf : 08 php ;flags after load/store sequence +14c0 : 49c3 eor #$c3 +14c2 : a8 tay +14c3 : c513 cmp zp1 ;test result + trap_ne +14c5 : d0fe > bne * ;failed not equal (non zero) + +14c7 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +14c8 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +14ca : cd1c02 cmp fLDx ;test flags + trap_ne +14cd : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +14cf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +14d1 : 48 > pha ;use stack to load status +14d2 : 28 > plp + +14d3 : ac1802 ldy abs1+1 +14d6 : 08 php ;test stores do not alter flags +14d7 : 98 tya +14d8 : 49c3 eor #$c3 +14da : a8 tay +14db : 28 plp +14dc : 840d sty zpt+1 +14de : 08 php ;flags after load/store sequence +14df : 49c3 eor #$c3 +14e1 : a8 tay +14e2 : c514 cmp zp1+1 ;test result + trap_ne +14e4 : d0fe > bne * ;failed not equal (non zero) + +14e6 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +14e7 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +14e9 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +14ec : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +14ee : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +14f0 : 48 > pha ;use stack to load status +14f1 : 28 > plp + +14f2 : ac1902 ldy abs1+2 +14f5 : 08 php ;test stores do not alter flags +14f6 : 98 tya +14f7 : 49c3 eor #$c3 +14f9 : a8 tay +14fa : 28 plp +14fb : 840e sty zpt+2 +14fd : 08 php ;flags after load/store sequence +14fe : 49c3 eor #$c3 +1500 : a8 tay +1501 : c515 cmp zp1+2 ;test result + trap_ne +1503 : d0fe > bne * ;failed not equal (non zero) + +1505 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1506 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1508 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +150b : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +150d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +150f : 48 > pha ;use stack to load status +1510 : 28 > plp + +1511 : ac1a02 ldy abs1+3 +1514 : 08 php ;test stores do not alter flags +1515 : 98 tya +1516 : 49c3 eor #$c3 +1518 : a8 tay +1519 : 28 plp +151a : 840f sty zpt+3 +151c : 08 php ;flags after load/store sequence +151d : 49c3 eor #$c3 +151f : a8 tay +1520 : c516 cmp zp1+3 ;test result + trap_ne +1522 : d0fe > bne * ;failed not equal (non zero) + +1524 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1525 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1527 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +152a : d0fe > bne * ;failed not equal (non zero) + + + + set_stat 0 + > load_flag 0 +152c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +152e : 48 > pha ;use stack to load status +152f : 28 > plp + +1530 : a0c3 ldy #$c3 +1532 : 08 php +1533 : cc1702 cpy abs1 ;test result + trap_ne +1536 : d0fe > bne * ;failed not equal (non zero) + +1538 : 68 pla ;load status + eor_flag 0 +1539 : 4930 > eor #0|fao ;invert expected flags + always on bits + +153b : cd1c02 cmp fLDx ;test flags + trap_ne +153e : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1540 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1542 : 48 > pha ;use stack to load status +1543 : 28 > plp + +1544 : a082 ldy #$82 +1546 : 08 php +1547 : cc1802 cpy abs1+1 ;test result + trap_ne +154a : d0fe > bne * ;failed not equal (non zero) + +154c : 68 pla ;load status + eor_flag 0 +154d : 4930 > eor #0|fao ;invert expected flags + always on bits + +154f : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1552 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1554 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1556 : 48 > pha ;use stack to load status +1557 : 28 > plp + +1558 : a041 ldy #$41 +155a : 08 php +155b : cc1902 cpy abs1+2 ;test result + trap_ne +155e : d0fe > bne * ;failed not equal (non zero) + +1560 : 68 pla ;load status + eor_flag 0 +1561 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1563 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1566 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1568 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +156a : 48 > pha ;use stack to load status +156b : 28 > plp + +156c : a000 ldy #0 +156e : 08 php +156f : cc1a02 cpy abs1+3 ;test result + trap_ne +1572 : d0fe > bne * ;failed not equal (non zero) + +1574 : 68 pla ;load status + eor_flag 0 +1575 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1577 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +157a : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +157c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +157e : 48 > pha ;use stack to load status +157f : 28 > plp + +1580 : a0c3 ldy #$c3 +1582 : 08 php +1583 : cc1702 cpy abs1 ;test result + trap_ne +1586 : d0fe > bne * ;failed not equal (non zero) + +1588 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1589 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +158b : cd1c02 cmp fLDx ;test flags + trap_ne +158e : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1590 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1592 : 48 > pha ;use stack to load status +1593 : 28 > plp + +1594 : a082 ldy #$82 +1596 : 08 php +1597 : cc1802 cpy abs1+1 ;test result + trap_ne +159a : d0fe > bne * ;failed not equal (non zero) + +159c : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +159d : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +159f : cd1d02 cmp fLDx+1 ;test flags + trap_ne +15a2 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +15a4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +15a6 : 48 > pha ;use stack to load status +15a7 : 28 > plp + +15a8 : a041 ldy #$41 +15aa : 08 php +15ab : cc1902 cpy abs1+2 ;test result + trap_ne +15ae : d0fe > bne * ;failed not equal (non zero) + +15b0 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +15b1 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +15b3 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +15b6 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +15b8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +15ba : 48 > pha ;use stack to load status +15bb : 28 > plp + +15bc : a000 ldy #0 +15be : 08 php +15bf : cc1a02 cpy abs1+3 ;test result + trap_ne +15c2 : d0fe > bne * ;failed not equal (non zero) + +15c4 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +15c5 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +15c7 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +15ca : d0fe > bne * ;failed not equal (non zero) + + +15cc : a000 ldy #0 +15ce : a50c lda zpt +15d0 : 49c3 eor #$c3 +15d2 : c513 cmp zp1 + trap_ne ;store to zp data +15d4 : d0fe > bne * ;failed not equal (non zero) + +15d6 : 840c sty zpt ;clear +15d8 : ad0302 lda abst +15db : 49c3 eor #$c3 +15dd : cd1702 cmp abs1 + trap_ne ;store to abs data +15e0 : d0fe > bne * ;failed not equal (non zero) + +15e2 : 8c0302 sty abst ;clear +15e5 : a50d lda zpt+1 +15e7 : 49c3 eor #$c3 +15e9 : c514 cmp zp1+1 + trap_ne ;store to zp+1 data +15eb : d0fe > bne * ;failed not equal (non zero) + +15ed : 840d sty zpt+1 ;clear +15ef : ad0402 lda abst+1 +15f2 : 49c3 eor #$c3 +15f4 : cd1802 cmp abs1+1 + trap_ne ;store to abs+1 data +15f7 : d0fe > bne * ;failed not equal (non zero) + +15f9 : 8c0402 sty abst+1 ;clear +15fc : a50e lda zpt+2 +15fe : 49c3 eor #$c3 +1600 : c515 cmp zp1+2 + trap_ne ;store to zp+2 data +1602 : d0fe > bne * ;failed not equal (non zero) + +1604 : 840e sty zpt+2 ;clear +1606 : ad0502 lda abst+2 +1609 : 49c3 eor #$c3 +160b : cd1902 cmp abs1+2 + trap_ne ;store to abs+2 data +160e : d0fe > bne * ;failed not equal (non zero) + +1610 : 8c0502 sty abst+2 ;clear +1613 : a50f lda zpt+3 +1615 : 49c3 eor #$c3 +1617 : c516 cmp zp1+3 + trap_ne ;store to zp+3 data +1619 : d0fe > bne * ;failed not equal (non zero) + +161b : 840f sty zpt+3 ;clear +161d : ad0602 lda abst+3 +1620 : 49c3 eor #$c3 +1622 : cd1a02 cmp abs1+3 + trap_ne ;store to abs+3 data +1625 : d0fe > bne * ;failed not equal (non zero) + +1627 : 8c0602 sty abst+3 ;clear + next_test +162a : ad0002 > lda test_case ;previous test +162d : c914 > cmp #test_num + > trap_ne ;test is out of sequence +162f : d0fe > bne * ;failed not equal (non zero) + > +0015 = >test_num = test_num + 1 +1631 : a915 > lda #test_num ;*** next tests' number +1633 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing load / store accumulator LDA / STA all addressing modes + ; LDA / STA - zp,x / abs,x +1636 : a203 ldx #3 +1638 : tldax + set_stat 0 + > load_flag 0 +1638 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +163a : 48 > pha ;use stack to load status +163b : 28 > plp + +163c : b513 lda zp1,x +163e : 08 php ;test stores do not alter flags +163f : 49c3 eor #$c3 +1641 : 28 plp +1642 : 9d0302 sta abst,x +1645 : 08 php ;flags after load/store sequence +1646 : 49c3 eor #$c3 +1648 : dd1702 cmp abs1,x ;test result + trap_ne +164b : d0fe > bne * ;failed not equal (non zero) + +164d : 68 pla ;load status + eor_flag 0 +164e : 4930 > eor #0|fao ;invert expected flags + always on bits + +1650 : dd1c02 cmp fLDx,x ;test flags + trap_ne +1653 : d0fe > bne * ;failed not equal (non zero) + +1655 : ca dex +1656 : 10e0 bpl tldax + +1658 : a203 ldx #3 +165a : tldax1 + set_stat $ff + > load_flag $ff +165a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +165c : 48 > pha ;use stack to load status +165d : 28 > plp + +165e : b513 lda zp1,x +1660 : 08 php ;test stores do not alter flags +1661 : 49c3 eor #$c3 +1663 : 28 plp +1664 : 9d0302 sta abst,x +1667 : 08 php ;flags after load/store sequence +1668 : 49c3 eor #$c3 +166a : dd1702 cmp abs1,x ;test result + trap_ne +166d : d0fe > bne * ;failed not equal (non zero) + +166f : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1670 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1672 : dd1c02 cmp fLDx,x ;test flags + trap_ne +1675 : d0fe > bne * ;failed not equal (non zero) + +1677 : ca dex +1678 : 10e0 bpl tldax1 + +167a : a203 ldx #3 +167c : tldax2 + set_stat 0 + > load_flag 0 +167c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +167e : 48 > pha ;use stack to load status +167f : 28 > plp + +1680 : bd1702 lda abs1,x +1683 : 08 php ;test stores do not alter flags +1684 : 49c3 eor #$c3 +1686 : 28 plp +1687 : 950c sta zpt,x +1689 : 08 php ;flags after load/store sequence +168a : 49c3 eor #$c3 +168c : d513 cmp zp1,x ;test result + trap_ne +168e : d0fe > bne * ;failed not equal (non zero) + +1690 : 68 pla ;load status + eor_flag 0 +1691 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1693 : dd1c02 cmp fLDx,x ;test flags + trap_ne +1696 : d0fe > bne * ;failed not equal (non zero) + +1698 : ca dex +1699 : 10e1 bpl tldax2 + +169b : a203 ldx #3 +169d : tldax3 + set_stat $ff + > load_flag $ff +169d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +169f : 48 > pha ;use stack to load status +16a0 : 28 > plp + +16a1 : bd1702 lda abs1,x +16a4 : 08 php ;test stores do not alter flags +16a5 : 49c3 eor #$c3 +16a7 : 28 plp +16a8 : 950c sta zpt,x +16aa : 08 php ;flags after load/store sequence +16ab : 49c3 eor #$c3 +16ad : d513 cmp zp1,x ;test result + trap_ne +16af : d0fe > bne * ;failed not equal (non zero) + +16b1 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +16b2 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +16b4 : dd1c02 cmp fLDx,x ;test flags + trap_ne +16b7 : d0fe > bne * ;failed not equal (non zero) + +16b9 : ca dex +16ba : 10e1 bpl tldax3 + +16bc : a203 ldx #3 ;testing store result +16be : a000 ldy #0 +16c0 : b50c tstax lda zpt,x +16c2 : 49c3 eor #$c3 +16c4 : d513 cmp zp1,x + trap_ne ;store to zp,x data +16c6 : d0fe > bne * ;failed not equal (non zero) + +16c8 : 940c sty zpt,x ;clear +16ca : bd0302 lda abst,x +16cd : 49c3 eor #$c3 +16cf : dd1702 cmp abs1,x + trap_ne ;store to abs,x data +16d2 : d0fe > bne * ;failed not equal (non zero) + +16d4 : 8a txa +16d5 : 9d0302 sta abst,x ;clear +16d8 : ca dex +16d9 : 10e5 bpl tstax + next_test +16db : ad0002 > lda test_case ;previous test +16de : c915 > cmp #test_num + > trap_ne ;test is out of sequence +16e0 : d0fe > bne * ;failed not equal (non zero) + > +0016 = >test_num = test_num + 1 +16e2 : a916 > lda #test_num ;*** next tests' number +16e4 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; LDA / STA - (zp),y / abs,y / (zp,x) +16e7 : a003 ldy #3 +16e9 : tlday + set_stat 0 + > load_flag 0 +16e9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +16eb : 48 > pha ;use stack to load status +16ec : 28 > plp + +16ed : b124 lda (ind1),y +16ef : 08 php ;test stores do not alter flags +16f0 : 49c3 eor #$c3 +16f2 : 28 plp +16f3 : 990302 sta abst,y +16f6 : 08 php ;flags after load/store sequence +16f7 : 49c3 eor #$c3 +16f9 : d91702 cmp abs1,y ;test result + trap_ne +16fc : d0fe > bne * ;failed not equal (non zero) + +16fe : 68 pla ;load status + eor_flag 0 +16ff : 4930 > eor #0|fao ;invert expected flags + always on bits + +1701 : d91c02 cmp fLDx,y ;test flags + trap_ne +1704 : d0fe > bne * ;failed not equal (non zero) + +1706 : 88 dey +1707 : 10e0 bpl tlday + +1709 : a003 ldy #3 +170b : tlday1 + set_stat $ff + > load_flag $ff +170b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +170d : 48 > pha ;use stack to load status +170e : 28 > plp + +170f : b124 lda (ind1),y +1711 : 08 php ;test stores do not alter flags +1712 : 49c3 eor #$c3 +1714 : 28 plp +1715 : 990302 sta abst,y +1718 : 08 php ;flags after load/store sequence +1719 : 49c3 eor #$c3 +171b : d91702 cmp abs1,y ;test result + trap_ne +171e : d0fe > bne * ;failed not equal (non zero) + +1720 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1721 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1723 : d91c02 cmp fLDx,y ;test flags + trap_ne +1726 : d0fe > bne * ;failed not equal (non zero) + +1728 : 88 dey +1729 : 10e0 bpl tlday1 + +172b : a003 ldy #3 ;testing store result +172d : a200 ldx #0 +172f : b90302 tstay lda abst,y +1732 : 49c3 eor #$c3 +1734 : d91702 cmp abs1,y + trap_ne ;store to abs data +1737 : d0fe > bne * ;failed not equal (non zero) + +1739 : 8a txa +173a : 990302 sta abst,y ;clear +173d : 88 dey +173e : 10ef bpl tstay + +1740 : a003 ldy #3 +1742 : tlday2 + set_stat 0 + > load_flag 0 +1742 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1744 : 48 > pha ;use stack to load status +1745 : 28 > plp + +1746 : b91702 lda abs1,y +1749 : 08 php ;test stores do not alter flags +174a : 49c3 eor #$c3 +174c : 28 plp +174d : 9130 sta (indt),y +174f : 08 php ;flags after load/store sequence +1750 : 49c3 eor #$c3 +1752 : d124 cmp (ind1),y ;test result + trap_ne +1754 : d0fe > bne * ;failed not equal (non zero) + +1756 : 68 pla ;load status + eor_flag 0 +1757 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1759 : d91c02 cmp fLDx,y ;test flags + trap_ne +175c : d0fe > bne * ;failed not equal (non zero) + +175e : 88 dey +175f : 10e1 bpl tlday2 + +1761 : a003 ldy #3 +1763 : tlday3 + set_stat $ff + > load_flag $ff +1763 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1765 : 48 > pha ;use stack to load status +1766 : 28 > plp + +1767 : b91702 lda abs1,y +176a : 08 php ;test stores do not alter flags +176b : 49c3 eor #$c3 +176d : 28 plp +176e : 9130 sta (indt),y +1770 : 08 php ;flags after load/store sequence +1771 : 49c3 eor #$c3 +1773 : d124 cmp (ind1),y ;test result + trap_ne +1775 : d0fe > bne * ;failed not equal (non zero) + +1777 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1778 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +177a : d91c02 cmp fLDx,y ;test flags + trap_ne +177d : d0fe > bne * ;failed not equal (non zero) + +177f : 88 dey +1780 : 10e1 bpl tlday3 + +1782 : a003 ldy #3 ;testing store result +1784 : a200 ldx #0 +1786 : b90302 tstay1 lda abst,y +1789 : 49c3 eor #$c3 +178b : d91702 cmp abs1,y + trap_ne ;store to abs data +178e : d0fe > bne * ;failed not equal (non zero) + +1790 : 8a txa +1791 : 990302 sta abst,y ;clear +1794 : 88 dey +1795 : 10ef bpl tstay1 + +1797 : a206 ldx #6 +1799 : a003 ldy #3 +179b : tldax4 + set_stat 0 + > load_flag 0 +179b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +179d : 48 > pha ;use stack to load status +179e : 28 > plp + +179f : a124 lda (ind1,x) +17a1 : 08 php ;test stores do not alter flags +17a2 : 49c3 eor #$c3 +17a4 : 28 plp +17a5 : 8130 sta (indt,x) +17a7 : 08 php ;flags after load/store sequence +17a8 : 49c3 eor #$c3 +17aa : d91702 cmp abs1,y ;test result + trap_ne +17ad : d0fe > bne * ;failed not equal (non zero) + +17af : 68 pla ;load status + eor_flag 0 +17b0 : 4930 > eor #0|fao ;invert expected flags + always on bits + +17b2 : d91c02 cmp fLDx,y ;test flags + trap_ne +17b5 : d0fe > bne * ;failed not equal (non zero) + +17b7 : ca dex +17b8 : ca dex +17b9 : 88 dey +17ba : 10df bpl tldax4 + +17bc : a206 ldx #6 +17be : a003 ldy #3 +17c0 : tldax5 + set_stat $ff + > load_flag $ff +17c0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +17c2 : 48 > pha ;use stack to load status +17c3 : 28 > plp + +17c4 : a124 lda (ind1,x) +17c6 : 08 php ;test stores do not alter flags +17c7 : 49c3 eor #$c3 +17c9 : 28 plp +17ca : 8130 sta (indt,x) +17cc : 08 php ;flags after load/store sequence +17cd : 49c3 eor #$c3 +17cf : d91702 cmp abs1,y ;test result + trap_ne +17d2 : d0fe > bne * ;failed not equal (non zero) + +17d4 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +17d5 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +17d7 : d91c02 cmp fLDx,y ;test flags + trap_ne +17da : d0fe > bne * ;failed not equal (non zero) + +17dc : ca dex +17dd : ca dex +17de : 88 dey +17df : 10df bpl tldax5 + +17e1 : a003 ldy #3 ;testing store result +17e3 : a200 ldx #0 +17e5 : b90302 tstay2 lda abst,y +17e8 : 49c3 eor #$c3 +17ea : d91702 cmp abs1,y + trap_ne ;store to abs data +17ed : d0fe > bne * ;failed not equal (non zero) + +17ef : 8a txa +17f0 : 990302 sta abst,y ;clear +17f3 : 88 dey +17f4 : 10ef bpl tstay2 + next_test +17f6 : ad0002 > lda test_case ;previous test +17f9 : c916 > cmp #test_num + > trap_ne ;test is out of sequence +17fb : d0fe > bne * ;failed not equal (non zero) + > +0017 = >test_num = test_num + 1 +17fd : a917 > lda #test_num ;*** next tests' number +17ff : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; indexed wraparound test (only zp should wrap) +1802 : a2fd ldx #3+$fa +1804 : b519 tldax6 lda zp1-$fa&$ff,x ;wrap on indexed zp +1806 : 9d0901 sta abst-$fa,x ;no STX abs,x! +1809 : ca dex +180a : e0fa cpx #$fa +180c : b0f6 bcs tldax6 +180e : a2fd ldx #3+$fa +1810 : bd1d01 tldax7 lda abs1-$fa,x ;no wrap on indexed abs +1813 : 9512 sta zpt-$fa&$ff,x +1815 : ca dex +1816 : e0fa cpx #$fa +1818 : b0f6 bcs tldax7 + +181a : a203 ldx #3 ;testing wraparound result +181c : a000 ldy #0 +181e : b50c tstax1 lda zpt,x +1820 : d513 cmp zp1,x + trap_ne ;store to zp,x data +1822 : d0fe > bne * ;failed not equal (non zero) + +1824 : 940c sty zpt,x ;clear +1826 : bd0302 lda abst,x +1829 : dd1702 cmp abs1,x + trap_ne ;store to abs,x data +182c : d0fe > bne * ;failed not equal (non zero) + +182e : 8a txa +182f : 9d0302 sta abst,x ;clear +1832 : ca dex +1833 : 10e9 bpl tstax1 + +1835 : a0fb ldy #3+$f8 +1837 : a2fe ldx #6+$f8 +1839 : a12c tlday4 lda (ind1-$f8&$ff,x) ;wrap on indexed zp indirect +183b : 990b01 sta abst-$f8,y +183e : ca dex +183f : ca dex +1840 : 88 dey +1841 : c0f8 cpy #$f8 +1843 : b0f4 bcs tlday4 +1845 : a003 ldy #3 ;testing wraparound result +1847 : a200 ldx #0 +1849 : b90302 tstay4 lda abst,y +184c : d91702 cmp abs1,y + trap_ne ;store to abs data +184f : d0fe > bne * ;failed not equal (non zero) + +1851 : 8a txa +1852 : 990302 sta abst,y ;clear +1855 : 88 dey +1856 : 10f1 bpl tstay4 + +1858 : a0fb ldy #3+$f8 +185a : b91f01 tlday5 lda abs1-$f8,y ;no wrap on indexed abs +185d : 9138 sta (inwt),y +185f : 88 dey +1860 : c0f8 cpy #$f8 +1862 : b0f6 bcs tlday5 +1864 : a003 ldy #3 ;testing wraparound result +1866 : a200 ldx #0 +1868 : b90302 tstay5 lda abst,y +186b : d91702 cmp abs1,y + trap_ne ;store to abs data +186e : d0fe > bne * ;failed not equal (non zero) + +1870 : 8a txa +1871 : 990302 sta abst,y ;clear +1874 : 88 dey +1875 : 10f1 bpl tstay5 + +1877 : a0fb ldy #3+$f8 +1879 : a2fe ldx #6+$f8 +187b : b12e tlday6 lda (inw1),y ;no wrap on zp indirect indexed +187d : 8138 sta (indt-$f8&$ff,x) +187f : ca dex +1880 : ca dex +1881 : 88 dey +1882 : c0f8 cpy #$f8 +1884 : b0f5 bcs tlday6 +1886 : a003 ldy #3 ;testing wraparound result +1888 : a200 ldx #0 +188a : b90302 tstay6 lda abst,y +188d : d91702 cmp abs1,y + trap_ne ;store to abs data +1890 : d0fe > bne * ;failed not equal (non zero) + +1892 : 8a txa +1893 : 990302 sta abst,y ;clear +1896 : 88 dey +1897 : 10f1 bpl tstay6 + next_test +1899 : ad0002 > lda test_case ;previous test +189c : c917 > cmp #test_num + > trap_ne ;test is out of sequence +189e : d0fe > bne * ;failed not equal (non zero) + > +0018 = >test_num = test_num + 1 +18a0 : a918 > lda #test_num ;*** next tests' number +18a2 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; LDA / STA - zp / abs / # + set_stat 0 + > load_flag 0 +18a5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +18a7 : 48 > pha ;use stack to load status +18a8 : 28 > plp + +18a9 : a513 lda zp1 +18ab : 08 php ;test stores do not alter flags +18ac : 49c3 eor #$c3 +18ae : 28 plp +18af : 8d0302 sta abst +18b2 : 08 php ;flags after load/store sequence +18b3 : 49c3 eor #$c3 +18b5 : c9c3 cmp #$c3 ;test result + trap_ne +18b7 : d0fe > bne * ;failed not equal (non zero) + +18b9 : 68 pla ;load status + eor_flag 0 +18ba : 4930 > eor #0|fao ;invert expected flags + always on bits + +18bc : cd1c02 cmp fLDx ;test flags + trap_ne +18bf : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +18c1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +18c3 : 48 > pha ;use stack to load status +18c4 : 28 > plp + +18c5 : a514 lda zp1+1 +18c7 : 08 php ;test stores do not alter flags +18c8 : 49c3 eor #$c3 +18ca : 28 plp +18cb : 8d0402 sta abst+1 +18ce : 08 php ;flags after load/store sequence +18cf : 49c3 eor #$c3 +18d1 : c982 cmp #$82 ;test result + trap_ne +18d3 : d0fe > bne * ;failed not equal (non zero) + +18d5 : 68 pla ;load status + eor_flag 0 +18d6 : 4930 > eor #0|fao ;invert expected flags + always on bits + +18d8 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +18db : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +18dd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +18df : 48 > pha ;use stack to load status +18e0 : 28 > plp + +18e1 : a515 lda zp1+2 +18e3 : 08 php ;test stores do not alter flags +18e4 : 49c3 eor #$c3 +18e6 : 28 plp +18e7 : 8d0502 sta abst+2 +18ea : 08 php ;flags after load/store sequence +18eb : 49c3 eor #$c3 +18ed : c941 cmp #$41 ;test result + trap_ne +18ef : d0fe > bne * ;failed not equal (non zero) + +18f1 : 68 pla ;load status + eor_flag 0 +18f2 : 4930 > eor #0|fao ;invert expected flags + always on bits + +18f4 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +18f7 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +18f9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +18fb : 48 > pha ;use stack to load status +18fc : 28 > plp + +18fd : a516 lda zp1+3 +18ff : 08 php ;test stores do not alter flags +1900 : 49c3 eor #$c3 +1902 : 28 plp +1903 : 8d0602 sta abst+3 +1906 : 08 php ;flags after load/store sequence +1907 : 49c3 eor #$c3 +1909 : c900 cmp #0 ;test result + trap_ne +190b : d0fe > bne * ;failed not equal (non zero) + +190d : 68 pla ;load status + eor_flag 0 +190e : 4930 > eor #0|fao ;invert expected flags + always on bits + +1910 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1913 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1915 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1917 : 48 > pha ;use stack to load status +1918 : 28 > plp + +1919 : a513 lda zp1 +191b : 08 php ;test stores do not alter flags +191c : 49c3 eor #$c3 +191e : 28 plp +191f : 8d0302 sta abst +1922 : 08 php ;flags after load/store sequence +1923 : 49c3 eor #$c3 +1925 : c9c3 cmp #$c3 ;test result + trap_ne +1927 : d0fe > bne * ;failed not equal (non zero) + +1929 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +192a : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +192c : cd1c02 cmp fLDx ;test flags + trap_ne +192f : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1931 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1933 : 48 > pha ;use stack to load status +1934 : 28 > plp + +1935 : a514 lda zp1+1 +1937 : 08 php ;test stores do not alter flags +1938 : 49c3 eor #$c3 +193a : 28 plp +193b : 8d0402 sta abst+1 +193e : 08 php ;flags after load/store sequence +193f : 49c3 eor #$c3 +1941 : c982 cmp #$82 ;test result + trap_ne +1943 : d0fe > bne * ;failed not equal (non zero) + +1945 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1946 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1948 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +194b : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +194d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +194f : 48 > pha ;use stack to load status +1950 : 28 > plp + +1951 : a515 lda zp1+2 +1953 : 08 php ;test stores do not alter flags +1954 : 49c3 eor #$c3 +1956 : 28 plp +1957 : 8d0502 sta abst+2 +195a : 08 php ;flags after load/store sequence +195b : 49c3 eor #$c3 +195d : c941 cmp #$41 ;test result + trap_ne +195f : d0fe > bne * ;failed not equal (non zero) + +1961 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1962 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1964 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1967 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1969 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +196b : 48 > pha ;use stack to load status +196c : 28 > plp + +196d : a516 lda zp1+3 +196f : 08 php ;test stores do not alter flags +1970 : 49c3 eor #$c3 +1972 : 28 plp +1973 : 8d0602 sta abst+3 +1976 : 08 php ;flags after load/store sequence +1977 : 49c3 eor #$c3 +1979 : c900 cmp #0 ;test result + trap_ne +197b : d0fe > bne * ;failed not equal (non zero) + +197d : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +197e : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1980 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1983 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1985 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1987 : 48 > pha ;use stack to load status +1988 : 28 > plp + +1989 : ad1702 lda abs1 +198c : 08 php ;test stores do not alter flags +198d : 49c3 eor #$c3 +198f : 28 plp +1990 : 850c sta zpt +1992 : 08 php ;flags after load/store sequence +1993 : 49c3 eor #$c3 +1995 : c513 cmp zp1 ;test result + trap_ne +1997 : d0fe > bne * ;failed not equal (non zero) + +1999 : 68 pla ;load status + eor_flag 0 +199a : 4930 > eor #0|fao ;invert expected flags + always on bits + +199c : cd1c02 cmp fLDx ;test flags + trap_ne +199f : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +19a1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +19a3 : 48 > pha ;use stack to load status +19a4 : 28 > plp + +19a5 : ad1802 lda abs1+1 +19a8 : 08 php ;test stores do not alter flags +19a9 : 49c3 eor #$c3 +19ab : 28 plp +19ac : 850d sta zpt+1 +19ae : 08 php ;flags after load/store sequence +19af : 49c3 eor #$c3 +19b1 : c514 cmp zp1+1 ;test result + trap_ne +19b3 : d0fe > bne * ;failed not equal (non zero) + +19b5 : 68 pla ;load status + eor_flag 0 +19b6 : 4930 > eor #0|fao ;invert expected flags + always on bits + +19b8 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +19bb : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +19bd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +19bf : 48 > pha ;use stack to load status +19c0 : 28 > plp + +19c1 : ad1902 lda abs1+2 +19c4 : 08 php ;test stores do not alter flags +19c5 : 49c3 eor #$c3 +19c7 : 28 plp +19c8 : 850e sta zpt+2 +19ca : 08 php ;flags after load/store sequence +19cb : 49c3 eor #$c3 +19cd : c515 cmp zp1+2 ;test result + trap_ne +19cf : d0fe > bne * ;failed not equal (non zero) + +19d1 : 68 pla ;load status + eor_flag 0 +19d2 : 4930 > eor #0|fao ;invert expected flags + always on bits + +19d4 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +19d7 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +19d9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +19db : 48 > pha ;use stack to load status +19dc : 28 > plp + +19dd : ad1a02 lda abs1+3 +19e0 : 08 php ;test stores do not alter flags +19e1 : 49c3 eor #$c3 +19e3 : 28 plp +19e4 : 850f sta zpt+3 +19e6 : 08 php ;flags after load/store sequence +19e7 : 49c3 eor #$c3 +19e9 : c516 cmp zp1+3 ;test result + trap_ne +19eb : d0fe > bne * ;failed not equal (non zero) + +19ed : 68 pla ;load status + eor_flag 0 +19ee : 4930 > eor #0|fao ;invert expected flags + always on bits + +19f0 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +19f3 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +19f5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +19f7 : 48 > pha ;use stack to load status +19f8 : 28 > plp + +19f9 : ad1702 lda abs1 +19fc : 08 php ;test stores do not alter flags +19fd : 49c3 eor #$c3 +19ff : 28 plp +1a00 : 850c sta zpt +1a02 : 08 php ;flags after load/store sequence +1a03 : 49c3 eor #$c3 +1a05 : c513 cmp zp1 ;test result + trap_ne +1a07 : d0fe > bne * ;failed not equal (non zero) + +1a09 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1a0a : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1a0c : cd1c02 cmp fLDx ;test flags + trap_ne +1a0f : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1a11 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1a13 : 48 > pha ;use stack to load status +1a14 : 28 > plp + +1a15 : ad1802 lda abs1+1 +1a18 : 08 php ;test stores do not alter flags +1a19 : 49c3 eor #$c3 +1a1b : 28 plp +1a1c : 850d sta zpt+1 +1a1e : 08 php ;flags after load/store sequence +1a1f : 49c3 eor #$c3 +1a21 : c514 cmp zp1+1 ;test result + trap_ne +1a23 : d0fe > bne * ;failed not equal (non zero) + +1a25 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1a26 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1a28 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1a2b : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1a2d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1a2f : 48 > pha ;use stack to load status +1a30 : 28 > plp + +1a31 : ad1902 lda abs1+2 +1a34 : 08 php ;test stores do not alter flags +1a35 : 49c3 eor #$c3 +1a37 : 28 plp +1a38 : 850e sta zpt+2 +1a3a : 08 php ;flags after load/store sequence +1a3b : 49c3 eor #$c3 +1a3d : c515 cmp zp1+2 ;test result + trap_ne +1a3f : d0fe > bne * ;failed not equal (non zero) + +1a41 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1a42 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1a44 : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1a47 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1a49 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1a4b : 48 > pha ;use stack to load status +1a4c : 28 > plp + +1a4d : ad1a02 lda abs1+3 +1a50 : 08 php ;test stores do not alter flags +1a51 : 49c3 eor #$c3 +1a53 : 28 plp +1a54 : 850f sta zpt+3 +1a56 : 08 php ;flags after load/store sequence +1a57 : 49c3 eor #$c3 +1a59 : c516 cmp zp1+3 ;test result + trap_ne +1a5b : d0fe > bne * ;failed not equal (non zero) + +1a5d : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1a5e : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1a60 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1a63 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1a65 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1a67 : 48 > pha ;use stack to load status +1a68 : 28 > plp + +1a69 : a9c3 lda #$c3 +1a6b : 08 php +1a6c : cd1702 cmp abs1 ;test result + trap_ne +1a6f : d0fe > bne * ;failed not equal (non zero) + +1a71 : 68 pla ;load status + eor_flag 0 +1a72 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1a74 : cd1c02 cmp fLDx ;test flags + trap_ne +1a77 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1a79 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1a7b : 48 > pha ;use stack to load status +1a7c : 28 > plp + +1a7d : a982 lda #$82 +1a7f : 08 php +1a80 : cd1802 cmp abs1+1 ;test result + trap_ne +1a83 : d0fe > bne * ;failed not equal (non zero) + +1a85 : 68 pla ;load status + eor_flag 0 +1a86 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1a88 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1a8b : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1a8d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1a8f : 48 > pha ;use stack to load status +1a90 : 28 > plp + +1a91 : a941 lda #$41 +1a93 : 08 php +1a94 : cd1902 cmp abs1+2 ;test result + trap_ne +1a97 : d0fe > bne * ;failed not equal (non zero) + +1a99 : 68 pla ;load status + eor_flag 0 +1a9a : 4930 > eor #0|fao ;invert expected flags + always on bits + +1a9c : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1a9f : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1aa1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1aa3 : 48 > pha ;use stack to load status +1aa4 : 28 > plp + +1aa5 : a900 lda #0 +1aa7 : 08 php +1aa8 : cd1a02 cmp abs1+3 ;test result + trap_ne +1aab : d0fe > bne * ;failed not equal (non zero) + +1aad : 68 pla ;load status + eor_flag 0 +1aae : 4930 > eor #0|fao ;invert expected flags + always on bits + +1ab0 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1ab3 : d0fe > bne * ;failed not equal (non zero) + + + set_stat $ff + > load_flag $ff +1ab5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1ab7 : 48 > pha ;use stack to load status +1ab8 : 28 > plp + +1ab9 : a9c3 lda #$c3 +1abb : 08 php +1abc : cd1702 cmp abs1 ;test result + trap_ne +1abf : d0fe > bne * ;failed not equal (non zero) + +1ac1 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1ac2 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1ac4 : cd1c02 cmp fLDx ;test flags + trap_ne +1ac7 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1ac9 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1acb : 48 > pha ;use stack to load status +1acc : 28 > plp + +1acd : a982 lda #$82 +1acf : 08 php +1ad0 : cd1802 cmp abs1+1 ;test result + trap_ne +1ad3 : d0fe > bne * ;failed not equal (non zero) + +1ad5 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1ad6 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1ad8 : cd1d02 cmp fLDx+1 ;test flags + trap_ne +1adb : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1add : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1adf : 48 > pha ;use stack to load status +1ae0 : 28 > plp + +1ae1 : a941 lda #$41 +1ae3 : 08 php +1ae4 : cd1902 cmp abs1+2 ;test result + trap_ne +1ae7 : d0fe > bne * ;failed not equal (non zero) + +1ae9 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1aea : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1aec : cd1e02 cmp fLDx+2 ;test flags + trap_ne +1aef : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +1af1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1af3 : 48 > pha ;use stack to load status +1af4 : 28 > plp + +1af5 : a900 lda #0 +1af7 : 08 php +1af8 : cd1a02 cmp abs1+3 ;test result + trap_ne +1afb : d0fe > bne * ;failed not equal (non zero) + +1afd : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1afe : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1b00 : cd1f02 cmp fLDx+3 ;test flags + trap_ne +1b03 : d0fe > bne * ;failed not equal (non zero) + + +1b05 : a200 ldx #0 +1b07 : a50c lda zpt +1b09 : 49c3 eor #$c3 +1b0b : c513 cmp zp1 + trap_ne ;store to zp data +1b0d : d0fe > bne * ;failed not equal (non zero) + +1b0f : 860c stx zpt ;clear +1b11 : ad0302 lda abst +1b14 : 49c3 eor #$c3 +1b16 : cd1702 cmp abs1 + trap_ne ;store to abs data +1b19 : d0fe > bne * ;failed not equal (non zero) + +1b1b : 8e0302 stx abst ;clear +1b1e : a50d lda zpt+1 +1b20 : 49c3 eor #$c3 +1b22 : c514 cmp zp1+1 + trap_ne ;store to zp data +1b24 : d0fe > bne * ;failed not equal (non zero) + +1b26 : 860d stx zpt+1 ;clear +1b28 : ad0402 lda abst+1 +1b2b : 49c3 eor #$c3 +1b2d : cd1802 cmp abs1+1 + trap_ne ;store to abs data +1b30 : d0fe > bne * ;failed not equal (non zero) + +1b32 : 8e0402 stx abst+1 ;clear +1b35 : a50e lda zpt+2 +1b37 : 49c3 eor #$c3 +1b39 : c515 cmp zp1+2 + trap_ne ;store to zp data +1b3b : d0fe > bne * ;failed not equal (non zero) + +1b3d : 860e stx zpt+2 ;clear +1b3f : ad0502 lda abst+2 +1b42 : 49c3 eor #$c3 +1b44 : cd1902 cmp abs1+2 + trap_ne ;store to abs data +1b47 : d0fe > bne * ;failed not equal (non zero) + +1b49 : 8e0502 stx abst+2 ;clear +1b4c : a50f lda zpt+3 +1b4e : 49c3 eor #$c3 +1b50 : c516 cmp zp1+3 + trap_ne ;store to zp data +1b52 : d0fe > bne * ;failed not equal (non zero) + +1b54 : 860f stx zpt+3 ;clear +1b56 : ad0602 lda abst+3 +1b59 : 49c3 eor #$c3 +1b5b : cd1a02 cmp abs1+3 + trap_ne ;store to abs data +1b5e : d0fe > bne * ;failed not equal (non zero) + +1b60 : 8e0602 stx abst+3 ;clear + next_test +1b63 : ad0002 > lda test_case ;previous test +1b66 : c918 > cmp #test_num + > trap_ne ;test is out of sequence +1b68 : d0fe > bne * ;failed not equal (non zero) + > +0019 = >test_num = test_num + 1 +1b6a : a919 > lda #test_num ;*** next tests' number +1b6c : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing bit test & compares BIT CPX CPY CMP all addressing modes + ; BIT - zp / abs + set_a $ff,0 + > load_flag 0 +1b6f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b71 : 48 > pha ;use stack to load status +1b72 : a9ff > lda #$ff ;precharge accu +1b74 : 28 > plp + +1b75 : 2416 bit zp1+3 ;00 - should set Z / clear NV + tst_a $ff,fz +1b77 : 08 > php ;save flags +1b78 : c9ff > cmp #$ff ;test result + > trap_ne +1b7a : d0fe > bne * ;failed not equal (non zero) + > +1b7c : 68 > pla ;load status +1b7d : 48 > pha + > cmp_flag fz +1b7e : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b80 : d0fe > bne * ;failed not equal (non zero) + > +1b82 : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1b83 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b85 : 48 > pha ;use stack to load status +1b86 : a901 > lda #1 ;precharge accu +1b88 : 28 > plp + +1b89 : 2415 bit zp1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,fv +1b8b : 08 > php ;save flags +1b8c : c901 > cmp #1 ;test result + > trap_ne +1b8e : d0fe > bne * ;failed not equal (non zero) + > +1b90 : 68 > pla ;load status +1b91 : 48 > pha + > cmp_flag fv +1b92 : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b94 : d0fe > bne * ;failed not equal (non zero) + > +1b96 : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1b97 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b99 : 48 > pha ;use stack to load status +1b9a : a901 > lda #1 ;precharge accu +1b9c : 28 > plp + +1b9d : 2414 bit zp1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz +1b9f : 08 > php ;save flags +1ba0 : c901 > cmp #1 ;test result + > trap_ne +1ba2 : d0fe > bne * ;failed not equal (non zero) + > +1ba4 : 68 > pla ;load status +1ba5 : 48 > pha + > cmp_flag fnz +1ba6 : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ba8 : d0fe > bne * ;failed not equal (non zero) + > +1baa : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1bab : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1bad : 48 > pha ;use stack to load status +1bae : a901 > lda #1 ;precharge accu +1bb0 : 28 > plp + +1bb1 : 2413 bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv +1bb3 : 08 > php ;save flags +1bb4 : c901 > cmp #1 ;test result + > trap_ne +1bb6 : d0fe > bne * ;failed not equal (non zero) + > +1bb8 : 68 > pla ;load status +1bb9 : 48 > pha + > cmp_flag fnv +1bba : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bbc : d0fe > bne * ;failed not equal (non zero) + > +1bbe : 28 > plp ;restore status + + + set_a $ff,$ff + > load_flag $ff +1bbf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1bc1 : 48 > pha ;use stack to load status +1bc2 : a9ff > lda #$ff ;precharge accu +1bc4 : 28 > plp + +1bc5 : 2416 bit zp1+3 ;00 - should set Z / clear NV + tst_a $ff,~fnv +1bc7 : 08 > php ;save flags +1bc8 : c9ff > cmp #$ff ;test result + > trap_ne +1bca : d0fe > bne * ;failed not equal (non zero) + > +1bcc : 68 > pla ;load status +1bcd : 48 > pha + > cmp_flag ~fnv +1bce : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bd0 : d0fe > bne * ;failed not equal (non zero) + > +1bd2 : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1bd3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1bd5 : 48 > pha ;use stack to load status +1bd6 : a901 > lda #1 ;precharge accu +1bd8 : 28 > plp + +1bd9 : 2415 bit zp1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz +1bdb : 08 > php ;save flags +1bdc : c901 > cmp #1 ;test result + > trap_ne +1bde : d0fe > bne * ;failed not equal (non zero) + > +1be0 : 68 > pla ;load status +1be1 : 48 > pha + > cmp_flag ~fnz +1be2 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1be4 : d0fe > bne * ;failed not equal (non zero) + > +1be6 : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1be7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1be9 : 48 > pha ;use stack to load status +1bea : a901 > lda #1 ;precharge accu +1bec : 28 > plp + +1bed : 2414 bit zp1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv +1bef : 08 > php ;save flags +1bf0 : c901 > cmp #1 ;test result + > trap_ne +1bf2 : d0fe > bne * ;failed not equal (non zero) + > +1bf4 : 68 > pla ;load status +1bf5 : 48 > pha + > cmp_flag ~fv +1bf6 : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bf8 : d0fe > bne * ;failed not equal (non zero) + > +1bfa : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1bfb : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1bfd : 48 > pha ;use stack to load status +1bfe : a901 > lda #1 ;precharge accu +1c00 : 28 > plp + +1c01 : 2413 bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz +1c03 : 08 > php ;save flags +1c04 : c901 > cmp #1 ;test result + > trap_ne +1c06 : d0fe > bne * ;failed not equal (non zero) + > +1c08 : 68 > pla ;load status +1c09 : 48 > pha + > cmp_flag ~fz +1c0a : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c0c : d0fe > bne * ;failed not equal (non zero) + > +1c0e : 28 > plp ;restore status + + + set_a $ff,0 + > load_flag 0 +1c0f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c11 : 48 > pha ;use stack to load status +1c12 : a9ff > lda #$ff ;precharge accu +1c14 : 28 > plp + +1c15 : 2c1a02 bit abs1+3 ;00 - should set Z / clear NV + tst_a $ff,fz +1c18 : 08 > php ;save flags +1c19 : c9ff > cmp #$ff ;test result + > trap_ne +1c1b : d0fe > bne * ;failed not equal (non zero) + > +1c1d : 68 > pla ;load status +1c1e : 48 > pha + > cmp_flag fz +1c1f : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c21 : d0fe > bne * ;failed not equal (non zero) + > +1c23 : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1c24 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c26 : 48 > pha ;use stack to load status +1c27 : a901 > lda #1 ;precharge accu +1c29 : 28 > plp + +1c2a : 2c1902 bit abs1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,fv +1c2d : 08 > php ;save flags +1c2e : c901 > cmp #1 ;test result + > trap_ne +1c30 : d0fe > bne * ;failed not equal (non zero) + > +1c32 : 68 > pla ;load status +1c33 : 48 > pha + > cmp_flag fv +1c34 : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c36 : d0fe > bne * ;failed not equal (non zero) + > +1c38 : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1c39 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c3b : 48 > pha ;use stack to load status +1c3c : a901 > lda #1 ;precharge accu +1c3e : 28 > plp + +1c3f : 2c1802 bit abs1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz +1c42 : 08 > php ;save flags +1c43 : c901 > cmp #1 ;test result + > trap_ne +1c45 : d0fe > bne * ;failed not equal (non zero) + > +1c47 : 68 > pla ;load status +1c48 : 48 > pha + > cmp_flag fnz +1c49 : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c4b : d0fe > bne * ;failed not equal (non zero) + > +1c4d : 28 > plp ;restore status + + set_a 1,0 + > load_flag 0 +1c4e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c50 : 48 > pha ;use stack to load status +1c51 : a901 > lda #1 ;precharge accu +1c53 : 28 > plp + +1c54 : 2c1702 bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv +1c57 : 08 > php ;save flags +1c58 : c901 > cmp #1 ;test result + > trap_ne +1c5a : d0fe > bne * ;failed not equal (non zero) + > +1c5c : 68 > pla ;load status +1c5d : 48 > pha + > cmp_flag fnv +1c5e : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c60 : d0fe > bne * ;failed not equal (non zero) + > +1c62 : 28 > plp ;restore status + + + set_a $ff,$ff + > load_flag $ff +1c63 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c65 : 48 > pha ;use stack to load status +1c66 : a9ff > lda #$ff ;precharge accu +1c68 : 28 > plp + +1c69 : 2c1a02 bit abs1+3 ;00 - should set Z / clear NV + tst_a $ff,~fnv +1c6c : 08 > php ;save flags +1c6d : c9ff > cmp #$ff ;test result + > trap_ne +1c6f : d0fe > bne * ;failed not equal (non zero) + > +1c71 : 68 > pla ;load status +1c72 : 48 > pha + > cmp_flag ~fnv +1c73 : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c75 : d0fe > bne * ;failed not equal (non zero) + > +1c77 : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1c78 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c7a : 48 > pha ;use stack to load status +1c7b : a901 > lda #1 ;precharge accu +1c7d : 28 > plp + +1c7e : 2c1902 bit abs1+2 ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz +1c81 : 08 > php ;save flags +1c82 : c901 > cmp #1 ;test result + > trap_ne +1c84 : d0fe > bne * ;failed not equal (non zero) + > +1c86 : 68 > pla ;load status +1c87 : 48 > pha + > cmp_flag ~fnz +1c88 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c8a : d0fe > bne * ;failed not equal (non zero) + > +1c8c : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1c8d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c8f : 48 > pha ;use stack to load status +1c90 : a901 > lda #1 ;precharge accu +1c92 : 28 > plp + +1c93 : 2c1802 bit abs1+1 ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv +1c96 : 08 > php ;save flags +1c97 : c901 > cmp #1 ;test result + > trap_ne +1c99 : d0fe > bne * ;failed not equal (non zero) + > +1c9b : 68 > pla ;load status +1c9c : 48 > pha + > cmp_flag ~fv +1c9d : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c9f : d0fe > bne * ;failed not equal (non zero) + > +1ca1 : 28 > plp ;restore status + + set_a 1,$ff + > load_flag $ff +1ca2 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1ca4 : 48 > pha ;use stack to load status +1ca5 : a901 > lda #1 ;precharge accu +1ca7 : 28 > plp + +1ca8 : 2c1702 bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz +1cab : 08 > php ;save flags +1cac : c901 > cmp #1 ;test result + > trap_ne +1cae : d0fe > bne * ;failed not equal (non zero) + > +1cb0 : 68 > pla ;load status +1cb1 : 48 > pha + > cmp_flag ~fz +1cb2 : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cb4 : d0fe > bne * ;failed not equal (non zero) + > +1cb6 : 28 > plp ;restore status + + next_test +1cb7 : ad0002 > lda test_case ;previous test +1cba : c919 > cmp #test_num + > trap_ne ;test is out of sequence +1cbc : d0fe > bne * ;failed not equal (non zero) + > +001a = >test_num = test_num + 1 +1cbe : a91a > lda #test_num ;*** next tests' number +1cc0 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; CPX - zp / abs / # + set_x $80,0 + > load_flag 0 +1cc3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1cc5 : 48 > pha ;use stack to load status +1cc6 : a280 > ldx #$80 ;precharge index x +1cc8 : 28 > plp + +1cc9 : e417 cpx zp7f + tst_stat fc +1ccb : 08 > php ;save status +1ccc : 68 > pla ;use stack to retrieve status +1ccd : 48 > pha + > cmp_flag fc +1cce : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cd0 : d0fe > bne * ;failed not equal (non zero) + > +1cd2 : 28 > plp ;restore status + +1cd3 : ca dex +1cd4 : e417 cpx zp7f + tst_stat fzc +1cd6 : 08 > php ;save status +1cd7 : 68 > pla ;use stack to retrieve status +1cd8 : 48 > pha + > cmp_flag fzc +1cd9 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cdb : d0fe > bne * ;failed not equal (non zero) + > +1cdd : 28 > plp ;restore status + +1cde : ca dex +1cdf : e417 cpx zp7f + tst_x $7e,fn +1ce1 : 08 > php ;save flags +1ce2 : e07e > cpx #$7e ;test result + > trap_ne +1ce4 : d0fe > bne * ;failed not equal (non zero) + > +1ce6 : 68 > pla ;load status +1ce7 : 48 > pha + > cmp_flag fn +1ce8 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cea : d0fe > bne * ;failed not equal (non zero) + > +1cec : 28 > plp ;restore status + + set_x $80,$ff + > load_flag $ff +1ced : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1cef : 48 > pha ;use stack to load status +1cf0 : a280 > ldx #$80 ;precharge index x +1cf2 : 28 > plp + +1cf3 : e417 cpx zp7f + tst_stat ~fnz +1cf5 : 08 > php ;save status +1cf6 : 68 > pla ;use stack to retrieve status +1cf7 : 48 > pha + > cmp_flag ~fnz +1cf8 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cfa : d0fe > bne * ;failed not equal (non zero) + > +1cfc : 28 > plp ;restore status + +1cfd : ca dex +1cfe : e417 cpx zp7f + tst_stat ~fn +1d00 : 08 > php ;save status +1d01 : 68 > pla ;use stack to retrieve status +1d02 : 48 > pha + > cmp_flag ~fn +1d03 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d05 : d0fe > bne * ;failed not equal (non zero) + > +1d07 : 28 > plp ;restore status + +1d08 : ca dex +1d09 : e417 cpx zp7f + tst_x $7e,~fzc +1d0b : 08 > php ;save flags +1d0c : e07e > cpx #$7e ;test result + > trap_ne +1d0e : d0fe > bne * ;failed not equal (non zero) + > +1d10 : 68 > pla ;load status +1d11 : 48 > pha + > cmp_flag ~fzc +1d12 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d14 : d0fe > bne * ;failed not equal (non zero) + > +1d16 : 28 > plp ;restore status + + + set_x $80,0 + > load_flag 0 +1d17 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1d19 : 48 > pha ;use stack to load status +1d1a : a280 > ldx #$80 ;precharge index x +1d1c : 28 > plp + +1d1d : ec1b02 cpx abs7f + tst_stat fc +1d20 : 08 > php ;save status +1d21 : 68 > pla ;use stack to retrieve status +1d22 : 48 > pha + > cmp_flag fc +1d23 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d25 : d0fe > bne * ;failed not equal (non zero) + > +1d27 : 28 > plp ;restore status + +1d28 : ca dex +1d29 : ec1b02 cpx abs7f + tst_stat fzc +1d2c : 08 > php ;save status +1d2d : 68 > pla ;use stack to retrieve status +1d2e : 48 > pha + > cmp_flag fzc +1d2f : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d31 : d0fe > bne * ;failed not equal (non zero) + > +1d33 : 28 > plp ;restore status + +1d34 : ca dex +1d35 : ec1b02 cpx abs7f + tst_x $7e,fn +1d38 : 08 > php ;save flags +1d39 : e07e > cpx #$7e ;test result + > trap_ne +1d3b : d0fe > bne * ;failed not equal (non zero) + > +1d3d : 68 > pla ;load status +1d3e : 48 > pha + > cmp_flag fn +1d3f : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d41 : d0fe > bne * ;failed not equal (non zero) + > +1d43 : 28 > plp ;restore status + + set_x $80,$ff + > load_flag $ff +1d44 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1d46 : 48 > pha ;use stack to load status +1d47 : a280 > ldx #$80 ;precharge index x +1d49 : 28 > plp + +1d4a : ec1b02 cpx abs7f + tst_stat ~fnz +1d4d : 08 > php ;save status +1d4e : 68 > pla ;use stack to retrieve status +1d4f : 48 > pha + > cmp_flag ~fnz +1d50 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d52 : d0fe > bne * ;failed not equal (non zero) + > +1d54 : 28 > plp ;restore status + +1d55 : ca dex +1d56 : ec1b02 cpx abs7f + tst_stat ~fn +1d59 : 08 > php ;save status +1d5a : 68 > pla ;use stack to retrieve status +1d5b : 48 > pha + > cmp_flag ~fn +1d5c : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d5e : d0fe > bne * ;failed not equal (non zero) + > +1d60 : 28 > plp ;restore status + +1d61 : ca dex +1d62 : ec1b02 cpx abs7f + tst_x $7e,~fzc +1d65 : 08 > php ;save flags +1d66 : e07e > cpx #$7e ;test result + > trap_ne +1d68 : d0fe > bne * ;failed not equal (non zero) + > +1d6a : 68 > pla ;load status +1d6b : 48 > pha + > cmp_flag ~fzc +1d6c : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d6e : d0fe > bne * ;failed not equal (non zero) + > +1d70 : 28 > plp ;restore status + + + set_x $80,0 + > load_flag 0 +1d71 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1d73 : 48 > pha ;use stack to load status +1d74 : a280 > ldx #$80 ;precharge index x +1d76 : 28 > plp + +1d77 : e07f cpx #$7f + tst_stat fc +1d79 : 08 > php ;save status +1d7a : 68 > pla ;use stack to retrieve status +1d7b : 48 > pha + > cmp_flag fc +1d7c : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d7e : d0fe > bne * ;failed not equal (non zero) + > +1d80 : 28 > plp ;restore status + +1d81 : ca dex +1d82 : e07f cpx #$7f + tst_stat fzc +1d84 : 08 > php ;save status +1d85 : 68 > pla ;use stack to retrieve status +1d86 : 48 > pha + > cmp_flag fzc +1d87 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d89 : d0fe > bne * ;failed not equal (non zero) + > +1d8b : 28 > plp ;restore status + +1d8c : ca dex +1d8d : e07f cpx #$7f + tst_x $7e,fn +1d8f : 08 > php ;save flags +1d90 : e07e > cpx #$7e ;test result + > trap_ne +1d92 : d0fe > bne * ;failed not equal (non zero) + > +1d94 : 68 > pla ;load status +1d95 : 48 > pha + > cmp_flag fn +1d96 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1d98 : d0fe > bne * ;failed not equal (non zero) + > +1d9a : 28 > plp ;restore status + + set_x $80,$ff + > load_flag $ff +1d9b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1d9d : 48 > pha ;use stack to load status +1d9e : a280 > ldx #$80 ;precharge index x +1da0 : 28 > plp + +1da1 : e07f cpx #$7f + tst_stat ~fnz +1da3 : 08 > php ;save status +1da4 : 68 > pla ;use stack to retrieve status +1da5 : 48 > pha + > cmp_flag ~fnz +1da6 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1da8 : d0fe > bne * ;failed not equal (non zero) + > +1daa : 28 > plp ;restore status + +1dab : ca dex +1dac : e07f cpx #$7f + tst_stat ~fn +1dae : 08 > php ;save status +1daf : 68 > pla ;use stack to retrieve status +1db0 : 48 > pha + > cmp_flag ~fn +1db1 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1db3 : d0fe > bne * ;failed not equal (non zero) + > +1db5 : 28 > plp ;restore status + +1db6 : ca dex +1db7 : e07f cpx #$7f + tst_x $7e,~fzc +1db9 : 08 > php ;save flags +1dba : e07e > cpx #$7e ;test result + > trap_ne +1dbc : d0fe > bne * ;failed not equal (non zero) + > +1dbe : 68 > pla ;load status +1dbf : 48 > pha + > cmp_flag ~fzc +1dc0 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1dc2 : d0fe > bne * ;failed not equal (non zero) + > +1dc4 : 28 > plp ;restore status + + next_test +1dc5 : ad0002 > lda test_case ;previous test +1dc8 : c91a > cmp #test_num + > trap_ne ;test is out of sequence +1dca : d0fe > bne * ;failed not equal (non zero) + > +001b = >test_num = test_num + 1 +1dcc : a91b > lda #test_num ;*** next tests' number +1dce : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; CPY - zp / abs / # + set_y $80,0 + > load_flag 0 +1dd1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1dd3 : 48 > pha ;use stack to load status +1dd4 : a080 > ldy #$80 ;precharge index y +1dd6 : 28 > plp + +1dd7 : c417 cpy zp7f + tst_stat fc +1dd9 : 08 > php ;save status +1dda : 68 > pla ;use stack to retrieve status +1ddb : 48 > pha + > cmp_flag fc +1ddc : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1dde : d0fe > bne * ;failed not equal (non zero) + > +1de0 : 28 > plp ;restore status + +1de1 : 88 dey +1de2 : c417 cpy zp7f + tst_stat fzc +1de4 : 08 > php ;save status +1de5 : 68 > pla ;use stack to retrieve status +1de6 : 48 > pha + > cmp_flag fzc +1de7 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1de9 : d0fe > bne * ;failed not equal (non zero) + > +1deb : 28 > plp ;restore status + +1dec : 88 dey +1ded : c417 cpy zp7f + tst_y $7e,fn +1def : 08 > php ;save flags +1df0 : c07e > cpy #$7e ;test result + > trap_ne +1df2 : d0fe > bne * ;failed not equal (non zero) + > +1df4 : 68 > pla ;load status +1df5 : 48 > pha + > cmp_flag fn +1df6 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1df8 : d0fe > bne * ;failed not equal (non zero) + > +1dfa : 28 > plp ;restore status + + set_y $80,$ff + > load_flag $ff +1dfb : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1dfd : 48 > pha ;use stack to load status +1dfe : a080 > ldy #$80 ;precharge index y +1e00 : 28 > plp + +1e01 : c417 cpy zp7f + tst_stat ~fnz +1e03 : 08 > php ;save status +1e04 : 68 > pla ;use stack to retrieve status +1e05 : 48 > pha + > cmp_flag ~fnz +1e06 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e08 : d0fe > bne * ;failed not equal (non zero) + > +1e0a : 28 > plp ;restore status + +1e0b : 88 dey +1e0c : c417 cpy zp7f + tst_stat ~fn +1e0e : 08 > php ;save status +1e0f : 68 > pla ;use stack to retrieve status +1e10 : 48 > pha + > cmp_flag ~fn +1e11 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e13 : d0fe > bne * ;failed not equal (non zero) + > +1e15 : 28 > plp ;restore status + +1e16 : 88 dey +1e17 : c417 cpy zp7f + tst_y $7e,~fzc +1e19 : 08 > php ;save flags +1e1a : c07e > cpy #$7e ;test result + > trap_ne +1e1c : d0fe > bne * ;failed not equal (non zero) + > +1e1e : 68 > pla ;load status +1e1f : 48 > pha + > cmp_flag ~fzc +1e20 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e22 : d0fe > bne * ;failed not equal (non zero) + > +1e24 : 28 > plp ;restore status + + + set_y $80,0 + > load_flag 0 +1e25 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1e27 : 48 > pha ;use stack to load status +1e28 : a080 > ldy #$80 ;precharge index y +1e2a : 28 > plp + +1e2b : cc1b02 cpy abs7f + tst_stat fc +1e2e : 08 > php ;save status +1e2f : 68 > pla ;use stack to retrieve status +1e30 : 48 > pha + > cmp_flag fc +1e31 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e33 : d0fe > bne * ;failed not equal (non zero) + > +1e35 : 28 > plp ;restore status + +1e36 : 88 dey +1e37 : cc1b02 cpy abs7f + tst_stat fzc +1e3a : 08 > php ;save status +1e3b : 68 > pla ;use stack to retrieve status +1e3c : 48 > pha + > cmp_flag fzc +1e3d : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e3f : d0fe > bne * ;failed not equal (non zero) + > +1e41 : 28 > plp ;restore status + +1e42 : 88 dey +1e43 : cc1b02 cpy abs7f + tst_y $7e,fn +1e46 : 08 > php ;save flags +1e47 : c07e > cpy #$7e ;test result + > trap_ne +1e49 : d0fe > bne * ;failed not equal (non zero) + > +1e4b : 68 > pla ;load status +1e4c : 48 > pha + > cmp_flag fn +1e4d : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e4f : d0fe > bne * ;failed not equal (non zero) + > +1e51 : 28 > plp ;restore status + + set_y $80,$ff + > load_flag $ff +1e52 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1e54 : 48 > pha ;use stack to load status +1e55 : a080 > ldy #$80 ;precharge index y +1e57 : 28 > plp + +1e58 : cc1b02 cpy abs7f + tst_stat ~fnz +1e5b : 08 > php ;save status +1e5c : 68 > pla ;use stack to retrieve status +1e5d : 48 > pha + > cmp_flag ~fnz +1e5e : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e60 : d0fe > bne * ;failed not equal (non zero) + > +1e62 : 28 > plp ;restore status + +1e63 : 88 dey +1e64 : cc1b02 cpy abs7f + tst_stat ~fn +1e67 : 08 > php ;save status +1e68 : 68 > pla ;use stack to retrieve status +1e69 : 48 > pha + > cmp_flag ~fn +1e6a : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e6c : d0fe > bne * ;failed not equal (non zero) + > +1e6e : 28 > plp ;restore status + +1e6f : 88 dey +1e70 : cc1b02 cpy abs7f + tst_y $7e,~fzc +1e73 : 08 > php ;save flags +1e74 : c07e > cpy #$7e ;test result + > trap_ne +1e76 : d0fe > bne * ;failed not equal (non zero) + > +1e78 : 68 > pla ;load status +1e79 : 48 > pha + > cmp_flag ~fzc +1e7a : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e7c : d0fe > bne * ;failed not equal (non zero) + > +1e7e : 28 > plp ;restore status + + + set_y $80,0 + > load_flag 0 +1e7f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1e81 : 48 > pha ;use stack to load status +1e82 : a080 > ldy #$80 ;precharge index y +1e84 : 28 > plp + +1e85 : c07f cpy #$7f + tst_stat fc +1e87 : 08 > php ;save status +1e88 : 68 > pla ;use stack to retrieve status +1e89 : 48 > pha + > cmp_flag fc +1e8a : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e8c : d0fe > bne * ;failed not equal (non zero) + > +1e8e : 28 > plp ;restore status + +1e8f : 88 dey +1e90 : c07f cpy #$7f + tst_stat fzc +1e92 : 08 > php ;save status +1e93 : 68 > pla ;use stack to retrieve status +1e94 : 48 > pha + > cmp_flag fzc +1e95 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e97 : d0fe > bne * ;failed not equal (non zero) + > +1e99 : 28 > plp ;restore status + +1e9a : 88 dey +1e9b : c07f cpy #$7f + tst_y $7e,fn +1e9d : 08 > php ;save flags +1e9e : c07e > cpy #$7e ;test result + > trap_ne +1ea0 : d0fe > bne * ;failed not equal (non zero) + > +1ea2 : 68 > pla ;load status +1ea3 : 48 > pha + > cmp_flag fn +1ea4 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ea6 : d0fe > bne * ;failed not equal (non zero) + > +1ea8 : 28 > plp ;restore status + + set_y $80,$ff + > load_flag $ff +1ea9 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1eab : 48 > pha ;use stack to load status +1eac : a080 > ldy #$80 ;precharge index y +1eae : 28 > plp + +1eaf : c07f cpy #$7f + tst_stat ~fnz +1eb1 : 08 > php ;save status +1eb2 : 68 > pla ;use stack to retrieve status +1eb3 : 48 > pha + > cmp_flag ~fnz +1eb4 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1eb6 : d0fe > bne * ;failed not equal (non zero) + > +1eb8 : 28 > plp ;restore status + +1eb9 : 88 dey +1eba : c07f cpy #$7f + tst_stat ~fn +1ebc : 08 > php ;save status +1ebd : 68 > pla ;use stack to retrieve status +1ebe : 48 > pha + > cmp_flag ~fn +1ebf : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ec1 : d0fe > bne * ;failed not equal (non zero) + > +1ec3 : 28 > plp ;restore status + +1ec4 : 88 dey +1ec5 : c07f cpy #$7f + tst_y $7e,~fzc +1ec7 : 08 > php ;save flags +1ec8 : c07e > cpy #$7e ;test result + > trap_ne +1eca : d0fe > bne * ;failed not equal (non zero) + > +1ecc : 68 > pla ;load status +1ecd : 48 > pha + > cmp_flag ~fzc +1ece : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ed0 : d0fe > bne * ;failed not equal (non zero) + > +1ed2 : 28 > plp ;restore status + + next_test +1ed3 : ad0002 > lda test_case ;previous test +1ed6 : c91b > cmp #test_num + > trap_ne ;test is out of sequence +1ed8 : d0fe > bne * ;failed not equal (non zero) + > +001c = >test_num = test_num + 1 +1eda : a91c > lda #test_num ;*** next tests' number +1edc : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; CMP - zp / abs / # + set_a $80,0 + > load_flag 0 +1edf : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1ee1 : 48 > pha ;use stack to load status +1ee2 : a980 > lda #$80 ;precharge accu +1ee4 : 28 > plp + +1ee5 : c517 cmp zp7f + tst_a $80,fc +1ee7 : 08 > php ;save flags +1ee8 : c980 > cmp #$80 ;test result + > trap_ne +1eea : d0fe > bne * ;failed not equal (non zero) + > +1eec : 68 > pla ;load status +1eed : 48 > pha + > cmp_flag fc +1eee : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ef0 : d0fe > bne * ;failed not equal (non zero) + > +1ef2 : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +1ef3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1ef5 : 48 > pha ;use stack to load status +1ef6 : a97f > lda #$7f ;precharge accu +1ef8 : 28 > plp + +1ef9 : c517 cmp zp7f + tst_a $7f,fzc +1efb : 08 > php ;save flags +1efc : c97f > cmp #$7f ;test result + > trap_ne +1efe : d0fe > bne * ;failed not equal (non zero) + > +1f00 : 68 > pla ;load status +1f01 : 48 > pha + > cmp_flag fzc +1f02 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f04 : d0fe > bne * ;failed not equal (non zero) + > +1f06 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +1f07 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f09 : 48 > pha ;use stack to load status +1f0a : a97e > lda #$7e ;precharge accu +1f0c : 28 > plp + +1f0d : c517 cmp zp7f + tst_a $7e,fn +1f0f : 08 > php ;save flags +1f10 : c97e > cmp #$7e ;test result + > trap_ne +1f12 : d0fe > bne * ;failed not equal (non zero) + > +1f14 : 68 > pla ;load status +1f15 : 48 > pha + > cmp_flag fn +1f16 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f18 : d0fe > bne * ;failed not equal (non zero) + > +1f1a : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +1f1b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f1d : 48 > pha ;use stack to load status +1f1e : a980 > lda #$80 ;precharge accu +1f20 : 28 > plp + +1f21 : c517 cmp zp7f + tst_a $80,~fnz +1f23 : 08 > php ;save flags +1f24 : c980 > cmp #$80 ;test result + > trap_ne +1f26 : d0fe > bne * ;failed not equal (non zero) + > +1f28 : 68 > pla ;load status +1f29 : 48 > pha + > cmp_flag ~fnz +1f2a : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f2c : d0fe > bne * ;failed not equal (non zero) + > +1f2e : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +1f2f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f31 : 48 > pha ;use stack to load status +1f32 : a97f > lda #$7f ;precharge accu +1f34 : 28 > plp + +1f35 : c517 cmp zp7f + tst_a $7f,~fn +1f37 : 08 > php ;save flags +1f38 : c97f > cmp #$7f ;test result + > trap_ne +1f3a : d0fe > bne * ;failed not equal (non zero) + > +1f3c : 68 > pla ;load status +1f3d : 48 > pha + > cmp_flag ~fn +1f3e : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f40 : d0fe > bne * ;failed not equal (non zero) + > +1f42 : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +1f43 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f45 : 48 > pha ;use stack to load status +1f46 : a97e > lda #$7e ;precharge accu +1f48 : 28 > plp + +1f49 : c517 cmp zp7f + tst_a $7e,~fzc +1f4b : 08 > php ;save flags +1f4c : c97e > cmp #$7e ;test result + > trap_ne +1f4e : d0fe > bne * ;failed not equal (non zero) + > +1f50 : 68 > pla ;load status +1f51 : 48 > pha + > cmp_flag ~fzc +1f52 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f54 : d0fe > bne * ;failed not equal (non zero) + > +1f56 : 28 > plp ;restore status + + + set_a $80,0 + > load_flag 0 +1f57 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f59 : 48 > pha ;use stack to load status +1f5a : a980 > lda #$80 ;precharge accu +1f5c : 28 > plp + +1f5d : cd1b02 cmp abs7f + tst_a $80,fc +1f60 : 08 > php ;save flags +1f61 : c980 > cmp #$80 ;test result + > trap_ne +1f63 : d0fe > bne * ;failed not equal (non zero) + > +1f65 : 68 > pla ;load status +1f66 : 48 > pha + > cmp_flag fc +1f67 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f69 : d0fe > bne * ;failed not equal (non zero) + > +1f6b : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +1f6c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f6e : 48 > pha ;use stack to load status +1f6f : a97f > lda #$7f ;precharge accu +1f71 : 28 > plp + +1f72 : cd1b02 cmp abs7f + tst_a $7f,fzc +1f75 : 08 > php ;save flags +1f76 : c97f > cmp #$7f ;test result + > trap_ne +1f78 : d0fe > bne * ;failed not equal (non zero) + > +1f7a : 68 > pla ;load status +1f7b : 48 > pha + > cmp_flag fzc +1f7c : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f7e : d0fe > bne * ;failed not equal (non zero) + > +1f80 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +1f81 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f83 : 48 > pha ;use stack to load status +1f84 : a97e > lda #$7e ;precharge accu +1f86 : 28 > plp + +1f87 : cd1b02 cmp abs7f + tst_a $7e,fn +1f8a : 08 > php ;save flags +1f8b : c97e > cmp #$7e ;test result + > trap_ne +1f8d : d0fe > bne * ;failed not equal (non zero) + > +1f8f : 68 > pla ;load status +1f90 : 48 > pha + > cmp_flag fn +1f91 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f93 : d0fe > bne * ;failed not equal (non zero) + > +1f95 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +1f96 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f98 : 48 > pha ;use stack to load status +1f99 : a980 > lda #$80 ;precharge accu +1f9b : 28 > plp + +1f9c : cd1b02 cmp abs7f + tst_a $80,~fnz +1f9f : 08 > php ;save flags +1fa0 : c980 > cmp #$80 ;test result + > trap_ne +1fa2 : d0fe > bne * ;failed not equal (non zero) + > +1fa4 : 68 > pla ;load status +1fa5 : 48 > pha + > cmp_flag ~fnz +1fa6 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fa8 : d0fe > bne * ;failed not equal (non zero) + > +1faa : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +1fab : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1fad : 48 > pha ;use stack to load status +1fae : a97f > lda #$7f ;precharge accu +1fb0 : 28 > plp + +1fb1 : cd1b02 cmp abs7f + tst_a $7f,~fn +1fb4 : 08 > php ;save flags +1fb5 : c97f > cmp #$7f ;test result + > trap_ne +1fb7 : d0fe > bne * ;failed not equal (non zero) + > +1fb9 : 68 > pla ;load status +1fba : 48 > pha + > cmp_flag ~fn +1fbb : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fbd : d0fe > bne * ;failed not equal (non zero) + > +1fbf : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +1fc0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1fc2 : 48 > pha ;use stack to load status +1fc3 : a97e > lda #$7e ;precharge accu +1fc5 : 28 > plp + +1fc6 : cd1b02 cmp abs7f + tst_a $7e,~fzc +1fc9 : 08 > php ;save flags +1fca : c97e > cmp #$7e ;test result + > trap_ne +1fcc : d0fe > bne * ;failed not equal (non zero) + > +1fce : 68 > pla ;load status +1fcf : 48 > pha + > cmp_flag ~fzc +1fd0 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fd2 : d0fe > bne * ;failed not equal (non zero) + > +1fd4 : 28 > plp ;restore status + + + set_a $80,0 + > load_flag 0 +1fd5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1fd7 : 48 > pha ;use stack to load status +1fd8 : a980 > lda #$80 ;precharge accu +1fda : 28 > plp + +1fdb : c97f cmp #$7f + tst_a $80,fc +1fdd : 08 > php ;save flags +1fde : c980 > cmp #$80 ;test result + > trap_ne +1fe0 : d0fe > bne * ;failed not equal (non zero) + > +1fe2 : 68 > pla ;load status +1fe3 : 48 > pha + > cmp_flag fc +1fe4 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fe6 : d0fe > bne * ;failed not equal (non zero) + > +1fe8 : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +1fe9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1feb : 48 > pha ;use stack to load status +1fec : a97f > lda #$7f ;precharge accu +1fee : 28 > plp + +1fef : c97f cmp #$7f + tst_a $7f,fzc +1ff1 : 08 > php ;save flags +1ff2 : c97f > cmp #$7f ;test result + > trap_ne +1ff4 : d0fe > bne * ;failed not equal (non zero) + > +1ff6 : 68 > pla ;load status +1ff7 : 48 > pha + > cmp_flag fzc +1ff8 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ffa : d0fe > bne * ;failed not equal (non zero) + > +1ffc : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +1ffd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1fff : 48 > pha ;use stack to load status +2000 : a97e > lda #$7e ;precharge accu +2002 : 28 > plp + +2003 : c97f cmp #$7f + tst_a $7e,fn +2005 : 08 > php ;save flags +2006 : c97e > cmp #$7e ;test result + > trap_ne +2008 : d0fe > bne * ;failed not equal (non zero) + > +200a : 68 > pla ;load status +200b : 48 > pha + > cmp_flag fn +200c : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +200e : d0fe > bne * ;failed not equal (non zero) + > +2010 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +2011 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2013 : 48 > pha ;use stack to load status +2014 : a980 > lda #$80 ;precharge accu +2016 : 28 > plp + +2017 : c97f cmp #$7f + tst_a $80,~fnz +2019 : 08 > php ;save flags +201a : c980 > cmp #$80 ;test result + > trap_ne +201c : d0fe > bne * ;failed not equal (non zero) + > +201e : 68 > pla ;load status +201f : 48 > pha + > cmp_flag ~fnz +2020 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2022 : d0fe > bne * ;failed not equal (non zero) + > +2024 : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +2025 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2027 : 48 > pha ;use stack to load status +2028 : a97f > lda #$7f ;precharge accu +202a : 28 > plp + +202b : c97f cmp #$7f + tst_a $7f,~fn +202d : 08 > php ;save flags +202e : c97f > cmp #$7f ;test result + > trap_ne +2030 : d0fe > bne * ;failed not equal (non zero) + > +2032 : 68 > pla ;load status +2033 : 48 > pha + > cmp_flag ~fn +2034 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2036 : d0fe > bne * ;failed not equal (non zero) + > +2038 : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +2039 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +203b : 48 > pha ;use stack to load status +203c : a97e > lda #$7e ;precharge accu +203e : 28 > plp + +203f : c97f cmp #$7f + tst_a $7e,~fzc +2041 : 08 > php ;save flags +2042 : c97e > cmp #$7e ;test result + > trap_ne +2044 : d0fe > bne * ;failed not equal (non zero) + > +2046 : 68 > pla ;load status +2047 : 48 > pha + > cmp_flag ~fzc +2048 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +204a : d0fe > bne * ;failed not equal (non zero) + > +204c : 28 > plp ;restore status + + +204d : a204 ldx #4 ;with indexing by X + set_a $80,0 + > load_flag 0 +204f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2051 : 48 > pha ;use stack to load status +2052 : a980 > lda #$80 ;precharge accu +2054 : 28 > plp + +2055 : d513 cmp zp1,x + tst_a $80,fc +2057 : 08 > php ;save flags +2058 : c980 > cmp #$80 ;test result + > trap_ne +205a : d0fe > bne * ;failed not equal (non zero) + > +205c : 68 > pla ;load status +205d : 48 > pha + > cmp_flag fc +205e : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2060 : d0fe > bne * ;failed not equal (non zero) + > +2062 : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +2063 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2065 : 48 > pha ;use stack to load status +2066 : a97f > lda #$7f ;precharge accu +2068 : 28 > plp + +2069 : d513 cmp zp1,x + tst_a $7f,fzc +206b : 08 > php ;save flags +206c : c97f > cmp #$7f ;test result + > trap_ne +206e : d0fe > bne * ;failed not equal (non zero) + > +2070 : 68 > pla ;load status +2071 : 48 > pha + > cmp_flag fzc +2072 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2074 : d0fe > bne * ;failed not equal (non zero) + > +2076 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +2077 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2079 : 48 > pha ;use stack to load status +207a : a97e > lda #$7e ;precharge accu +207c : 28 > plp + +207d : d513 cmp zp1,x + tst_a $7e,fn +207f : 08 > php ;save flags +2080 : c97e > cmp #$7e ;test result + > trap_ne +2082 : d0fe > bne * ;failed not equal (non zero) + > +2084 : 68 > pla ;load status +2085 : 48 > pha + > cmp_flag fn +2086 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2088 : d0fe > bne * ;failed not equal (non zero) + > +208a : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +208b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +208d : 48 > pha ;use stack to load status +208e : a980 > lda #$80 ;precharge accu +2090 : 28 > plp + +2091 : d513 cmp zp1,x + tst_a $80,~fnz +2093 : 08 > php ;save flags +2094 : c980 > cmp #$80 ;test result + > trap_ne +2096 : d0fe > bne * ;failed not equal (non zero) + > +2098 : 68 > pla ;load status +2099 : 48 > pha + > cmp_flag ~fnz +209a : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +209c : d0fe > bne * ;failed not equal (non zero) + > +209e : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +209f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +20a1 : 48 > pha ;use stack to load status +20a2 : a97f > lda #$7f ;precharge accu +20a4 : 28 > plp + +20a5 : d513 cmp zp1,x + tst_a $7f,~fn +20a7 : 08 > php ;save flags +20a8 : c97f > cmp #$7f ;test result + > trap_ne +20aa : d0fe > bne * ;failed not equal (non zero) + > +20ac : 68 > pla ;load status +20ad : 48 > pha + > cmp_flag ~fn +20ae : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20b0 : d0fe > bne * ;failed not equal (non zero) + > +20b2 : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +20b3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +20b5 : 48 > pha ;use stack to load status +20b6 : a97e > lda #$7e ;precharge accu +20b8 : 28 > plp + +20b9 : d513 cmp zp1,x + tst_a $7e,~fzc +20bb : 08 > php ;save flags +20bc : c97e > cmp #$7e ;test result + > trap_ne +20be : d0fe > bne * ;failed not equal (non zero) + > +20c0 : 68 > pla ;load status +20c1 : 48 > pha + > cmp_flag ~fzc +20c2 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20c4 : d0fe > bne * ;failed not equal (non zero) + > +20c6 : 28 > plp ;restore status + + + set_a $80,0 + > load_flag 0 +20c7 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +20c9 : 48 > pha ;use stack to load status +20ca : a980 > lda #$80 ;precharge accu +20cc : 28 > plp + +20cd : dd1702 cmp abs1,x + tst_a $80,fc +20d0 : 08 > php ;save flags +20d1 : c980 > cmp #$80 ;test result + > trap_ne +20d3 : d0fe > bne * ;failed not equal (non zero) + > +20d5 : 68 > pla ;load status +20d6 : 48 > pha + > cmp_flag fc +20d7 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20d9 : d0fe > bne * ;failed not equal (non zero) + > +20db : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +20dc : a900 > lda #0 ;allow test to change I-flag (no mask) + > +20de : 48 > pha ;use stack to load status +20df : a97f > lda #$7f ;precharge accu +20e1 : 28 > plp + +20e2 : dd1702 cmp abs1,x + tst_a $7f,fzc +20e5 : 08 > php ;save flags +20e6 : c97f > cmp #$7f ;test result + > trap_ne +20e8 : d0fe > bne * ;failed not equal (non zero) + > +20ea : 68 > pla ;load status +20eb : 48 > pha + > cmp_flag fzc +20ec : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20ee : d0fe > bne * ;failed not equal (non zero) + > +20f0 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +20f1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +20f3 : 48 > pha ;use stack to load status +20f4 : a97e > lda #$7e ;precharge accu +20f6 : 28 > plp + +20f7 : dd1702 cmp abs1,x + tst_a $7e,fn +20fa : 08 > php ;save flags +20fb : c97e > cmp #$7e ;test result + > trap_ne +20fd : d0fe > bne * ;failed not equal (non zero) + > +20ff : 68 > pla ;load status +2100 : 48 > pha + > cmp_flag fn +2101 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2103 : d0fe > bne * ;failed not equal (non zero) + > +2105 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +2106 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2108 : 48 > pha ;use stack to load status +2109 : a980 > lda #$80 ;precharge accu +210b : 28 > plp + +210c : dd1702 cmp abs1,x + tst_a $80,~fnz +210f : 08 > php ;save flags +2110 : c980 > cmp #$80 ;test result + > trap_ne +2112 : d0fe > bne * ;failed not equal (non zero) + > +2114 : 68 > pla ;load status +2115 : 48 > pha + > cmp_flag ~fnz +2116 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2118 : d0fe > bne * ;failed not equal (non zero) + > +211a : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +211b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +211d : 48 > pha ;use stack to load status +211e : a97f > lda #$7f ;precharge accu +2120 : 28 > plp + +2121 : dd1702 cmp abs1,x + tst_a $7f,~fn +2124 : 08 > php ;save flags +2125 : c97f > cmp #$7f ;test result + > trap_ne +2127 : d0fe > bne * ;failed not equal (non zero) + > +2129 : 68 > pla ;load status +212a : 48 > pha + > cmp_flag ~fn +212b : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +212d : d0fe > bne * ;failed not equal (non zero) + > +212f : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +2130 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2132 : 48 > pha ;use stack to load status +2133 : a97e > lda #$7e ;precharge accu +2135 : 28 > plp + +2136 : dd1702 cmp abs1,x + tst_a $7e,~fzc +2139 : 08 > php ;save flags +213a : c97e > cmp #$7e ;test result + > trap_ne +213c : d0fe > bne * ;failed not equal (non zero) + > +213e : 68 > pla ;load status +213f : 48 > pha + > cmp_flag ~fzc +2140 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2142 : d0fe > bne * ;failed not equal (non zero) + > +2144 : 28 > plp ;restore status + + +2145 : a004 ldy #4 ;with indexing by Y +2147 : a208 ldx #8 ;with indexed indirect + set_a $80,0 + > load_flag 0 +2149 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +214b : 48 > pha ;use stack to load status +214c : a980 > lda #$80 ;precharge accu +214e : 28 > plp + +214f : d91702 cmp abs1,y + tst_a $80,fc +2152 : 08 > php ;save flags +2153 : c980 > cmp #$80 ;test result + > trap_ne +2155 : d0fe > bne * ;failed not equal (non zero) + > +2157 : 68 > pla ;load status +2158 : 48 > pha + > cmp_flag fc +2159 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +215b : d0fe > bne * ;failed not equal (non zero) + > +215d : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +215e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2160 : 48 > pha ;use stack to load status +2161 : a97f > lda #$7f ;precharge accu +2163 : 28 > plp + +2164 : d91702 cmp abs1,y + tst_a $7f,fzc +2167 : 08 > php ;save flags +2168 : c97f > cmp #$7f ;test result + > trap_ne +216a : d0fe > bne * ;failed not equal (non zero) + > +216c : 68 > pla ;load status +216d : 48 > pha + > cmp_flag fzc +216e : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2170 : d0fe > bne * ;failed not equal (non zero) + > +2172 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +2173 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2175 : 48 > pha ;use stack to load status +2176 : a97e > lda #$7e ;precharge accu +2178 : 28 > plp + +2179 : d91702 cmp abs1,y + tst_a $7e,fn +217c : 08 > php ;save flags +217d : c97e > cmp #$7e ;test result + > trap_ne +217f : d0fe > bne * ;failed not equal (non zero) + > +2181 : 68 > pla ;load status +2182 : 48 > pha + > cmp_flag fn +2183 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2185 : d0fe > bne * ;failed not equal (non zero) + > +2187 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +2188 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +218a : 48 > pha ;use stack to load status +218b : a980 > lda #$80 ;precharge accu +218d : 28 > plp + +218e : d91702 cmp abs1,y + tst_a $80,~fnz +2191 : 08 > php ;save flags +2192 : c980 > cmp #$80 ;test result + > trap_ne +2194 : d0fe > bne * ;failed not equal (non zero) + > +2196 : 68 > pla ;load status +2197 : 48 > pha + > cmp_flag ~fnz +2198 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +219a : d0fe > bne * ;failed not equal (non zero) + > +219c : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +219d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +219f : 48 > pha ;use stack to load status +21a0 : a97f > lda #$7f ;precharge accu +21a2 : 28 > plp + +21a3 : d91702 cmp abs1,y + tst_a $7f,~fn +21a6 : 08 > php ;save flags +21a7 : c97f > cmp #$7f ;test result + > trap_ne +21a9 : d0fe > bne * ;failed not equal (non zero) + > +21ab : 68 > pla ;load status +21ac : 48 > pha + > cmp_flag ~fn +21ad : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21af : d0fe > bne * ;failed not equal (non zero) + > +21b1 : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +21b2 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +21b4 : 48 > pha ;use stack to load status +21b5 : a97e > lda #$7e ;precharge accu +21b7 : 28 > plp + +21b8 : d91702 cmp abs1,y + tst_a $7e,~fzc +21bb : 08 > php ;save flags +21bc : c97e > cmp #$7e ;test result + > trap_ne +21be : d0fe > bne * ;failed not equal (non zero) + > +21c0 : 68 > pla ;load status +21c1 : 48 > pha + > cmp_flag ~fzc +21c2 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21c4 : d0fe > bne * ;failed not equal (non zero) + > +21c6 : 28 > plp ;restore status + + + set_a $80,0 + > load_flag 0 +21c7 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +21c9 : 48 > pha ;use stack to load status +21ca : a980 > lda #$80 ;precharge accu +21cc : 28 > plp + +21cd : c124 cmp (ind1,x) + tst_a $80,fc +21cf : 08 > php ;save flags +21d0 : c980 > cmp #$80 ;test result + > trap_ne +21d2 : d0fe > bne * ;failed not equal (non zero) + > +21d4 : 68 > pla ;load status +21d5 : 48 > pha + > cmp_flag fc +21d6 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21d8 : d0fe > bne * ;failed not equal (non zero) + > +21da : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +21db : a900 > lda #0 ;allow test to change I-flag (no mask) + > +21dd : 48 > pha ;use stack to load status +21de : a97f > lda #$7f ;precharge accu +21e0 : 28 > plp + +21e1 : c124 cmp (ind1,x) + tst_a $7f,fzc +21e3 : 08 > php ;save flags +21e4 : c97f > cmp #$7f ;test result + > trap_ne +21e6 : d0fe > bne * ;failed not equal (non zero) + > +21e8 : 68 > pla ;load status +21e9 : 48 > pha + > cmp_flag fzc +21ea : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21ec : d0fe > bne * ;failed not equal (non zero) + > +21ee : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +21ef : a900 > lda #0 ;allow test to change I-flag (no mask) + > +21f1 : 48 > pha ;use stack to load status +21f2 : a97e > lda #$7e ;precharge accu +21f4 : 28 > plp + +21f5 : c124 cmp (ind1,x) + tst_a $7e,fn +21f7 : 08 > php ;save flags +21f8 : c97e > cmp #$7e ;test result + > trap_ne +21fa : d0fe > bne * ;failed not equal (non zero) + > +21fc : 68 > pla ;load status +21fd : 48 > pha + > cmp_flag fn +21fe : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2200 : d0fe > bne * ;failed not equal (non zero) + > +2202 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +2203 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2205 : 48 > pha ;use stack to load status +2206 : a980 > lda #$80 ;precharge accu +2208 : 28 > plp + +2209 : c124 cmp (ind1,x) + tst_a $80,~fnz +220b : 08 > php ;save flags +220c : c980 > cmp #$80 ;test result + > trap_ne +220e : d0fe > bne * ;failed not equal (non zero) + > +2210 : 68 > pla ;load status +2211 : 48 > pha + > cmp_flag ~fnz +2212 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2214 : d0fe > bne * ;failed not equal (non zero) + > +2216 : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +2217 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2219 : 48 > pha ;use stack to load status +221a : a97f > lda #$7f ;precharge accu +221c : 28 > plp + +221d : c124 cmp (ind1,x) + tst_a $7f,~fn +221f : 08 > php ;save flags +2220 : c97f > cmp #$7f ;test result + > trap_ne +2222 : d0fe > bne * ;failed not equal (non zero) + > +2224 : 68 > pla ;load status +2225 : 48 > pha + > cmp_flag ~fn +2226 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2228 : d0fe > bne * ;failed not equal (non zero) + > +222a : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +222b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +222d : 48 > pha ;use stack to load status +222e : a97e > lda #$7e ;precharge accu +2230 : 28 > plp + +2231 : c124 cmp (ind1,x) + tst_a $7e,~fzc +2233 : 08 > php ;save flags +2234 : c97e > cmp #$7e ;test result + > trap_ne +2236 : d0fe > bne * ;failed not equal (non zero) + > +2238 : 68 > pla ;load status +2239 : 48 > pha + > cmp_flag ~fzc +223a : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +223c : d0fe > bne * ;failed not equal (non zero) + > +223e : 28 > plp ;restore status + + + set_a $80,0 + > load_flag 0 +223f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2241 : 48 > pha ;use stack to load status +2242 : a980 > lda #$80 ;precharge accu +2244 : 28 > plp + +2245 : d124 cmp (ind1),y + tst_a $80,fc +2247 : 08 > php ;save flags +2248 : c980 > cmp #$80 ;test result + > trap_ne +224a : d0fe > bne * ;failed not equal (non zero) + > +224c : 68 > pla ;load status +224d : 48 > pha + > cmp_flag fc +224e : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2250 : d0fe > bne * ;failed not equal (non zero) + > +2252 : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +2253 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2255 : 48 > pha ;use stack to load status +2256 : a97f > lda #$7f ;precharge accu +2258 : 28 > plp + +2259 : d124 cmp (ind1),y + tst_a $7f,fzc +225b : 08 > php ;save flags +225c : c97f > cmp #$7f ;test result + > trap_ne +225e : d0fe > bne * ;failed not equal (non zero) + > +2260 : 68 > pla ;load status +2261 : 48 > pha + > cmp_flag fzc +2262 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2264 : d0fe > bne * ;failed not equal (non zero) + > +2266 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +2267 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2269 : 48 > pha ;use stack to load status +226a : a97e > lda #$7e ;precharge accu +226c : 28 > plp + +226d : d124 cmp (ind1),y + tst_a $7e,fn +226f : 08 > php ;save flags +2270 : c97e > cmp #$7e ;test result + > trap_ne +2272 : d0fe > bne * ;failed not equal (non zero) + > +2274 : 68 > pla ;load status +2275 : 48 > pha + > cmp_flag fn +2276 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2278 : d0fe > bne * ;failed not equal (non zero) + > +227a : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +227b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +227d : 48 > pha ;use stack to load status +227e : a980 > lda #$80 ;precharge accu +2280 : 28 > plp + +2281 : d124 cmp (ind1),y + tst_a $80,~fnz +2283 : 08 > php ;save flags +2284 : c980 > cmp #$80 ;test result + > trap_ne +2286 : d0fe > bne * ;failed not equal (non zero) + > +2288 : 68 > pla ;load status +2289 : 48 > pha + > cmp_flag ~fnz +228a : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +228c : d0fe > bne * ;failed not equal (non zero) + > +228e : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +228f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2291 : 48 > pha ;use stack to load status +2292 : a97f > lda #$7f ;precharge accu +2294 : 28 > plp + +2295 : d124 cmp (ind1),y + tst_a $7f,~fn +2297 : 08 > php ;save flags +2298 : c97f > cmp #$7f ;test result + > trap_ne +229a : d0fe > bne * ;failed not equal (non zero) + > +229c : 68 > pla ;load status +229d : 48 > pha + > cmp_flag ~fn +229e : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +22a0 : d0fe > bne * ;failed not equal (non zero) + > +22a2 : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +22a3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +22a5 : 48 > pha ;use stack to load status +22a6 : a97e > lda #$7e ;precharge accu +22a8 : 28 > plp + +22a9 : d124 cmp (ind1),y + tst_a $7e,~fzc +22ab : 08 > php ;save flags +22ac : c97e > cmp #$7e ;test result + > trap_ne +22ae : d0fe > bne * ;failed not equal (non zero) + > +22b0 : 68 > pla ;load status +22b1 : 48 > pha + > cmp_flag ~fzc +22b2 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +22b4 : d0fe > bne * ;failed not equal (non zero) + > +22b6 : 28 > plp ;restore status + + next_test +22b7 : ad0002 > lda test_case ;previous test +22ba : c91c > cmp #test_num + > trap_ne ;test is out of sequence +22bc : d0fe > bne * ;failed not equal (non zero) + > +001d = >test_num = test_num + 1 +22be : a91d > lda #test_num ;*** next tests' number +22c0 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing shifts - ASL LSR ROL ROR all addressing modes + ; shifts - accumulator +22c3 : a203 ldx #3 +22c5 : tasl + set_ax zp1,0 + > load_flag 0 +22c5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +22c7 : 48 > pha ;use stack to load status +22c8 : b513 > lda zp1,x ;precharge accu +22ca : 28 > plp + +22cb : 0a asl a + tst_ax rASL,fASL,0 +22cc : 08 > php ;save flags +22cd : dd2002 > cmp rASL,x ;test result + > trap_ne +22d0 : d0fe > bne * ;failed not equal (non zero) + > +22d2 : 68 > pla ;load status + > eor_flag 0 +22d3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +22d5 : dd3002 > cmp fASL,x ;test flags + > trap_ne ; +22d8 : d0fe > bne * ;failed not equal (non zero) + > + +22da : ca dex +22db : 10e8 bpl tasl +22dd : a203 ldx #3 +22df : tasl1 + set_ax zp1,$ff + > load_flag $ff +22df : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +22e1 : 48 > pha ;use stack to load status +22e2 : b513 > lda zp1,x ;precharge accu +22e4 : 28 > plp + +22e5 : 0a asl a + tst_ax rASL,fASL,$ff-fnzc +22e6 : 08 > php ;save flags +22e7 : dd2002 > cmp rASL,x ;test result + > trap_ne +22ea : d0fe > bne * ;failed not equal (non zero) + > +22ec : 68 > pla ;load status + > eor_flag $ff-fnzc +22ed : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +22ef : dd3002 > cmp fASL,x ;test flags + > trap_ne ; +22f2 : d0fe > bne * ;failed not equal (non zero) + > + +22f4 : ca dex +22f5 : 10e8 bpl tasl1 + +22f7 : a203 ldx #3 +22f9 : tlsr + set_ax zp1,0 + > load_flag 0 +22f9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +22fb : 48 > pha ;use stack to load status +22fc : b513 > lda zp1,x ;precharge accu +22fe : 28 > plp + +22ff : 4a lsr a + tst_ax rLSR,fLSR,0 +2300 : 08 > php ;save flags +2301 : dd2802 > cmp rLSR,x ;test result + > trap_ne +2304 : d0fe > bne * ;failed not equal (non zero) + > +2306 : 68 > pla ;load status + > eor_flag 0 +2307 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2309 : dd3802 > cmp fLSR,x ;test flags + > trap_ne ; +230c : d0fe > bne * ;failed not equal (non zero) + > + +230e : ca dex +230f : 10e8 bpl tlsr +2311 : a203 ldx #3 +2313 : tlsr1 + set_ax zp1,$ff + > load_flag $ff +2313 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2315 : 48 > pha ;use stack to load status +2316 : b513 > lda zp1,x ;precharge accu +2318 : 28 > plp + +2319 : 4a lsr a + tst_ax rLSR,fLSR,$ff-fnzc +231a : 08 > php ;save flags +231b : dd2802 > cmp rLSR,x ;test result + > trap_ne +231e : d0fe > bne * ;failed not equal (non zero) + > +2320 : 68 > pla ;load status + > eor_flag $ff-fnzc +2321 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2323 : dd3802 > cmp fLSR,x ;test flags + > trap_ne ; +2326 : d0fe > bne * ;failed not equal (non zero) + > + +2328 : ca dex +2329 : 10e8 bpl tlsr1 + +232b : a203 ldx #3 +232d : trol + set_ax zp1,0 + > load_flag 0 +232d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +232f : 48 > pha ;use stack to load status +2330 : b513 > lda zp1,x ;precharge accu +2332 : 28 > plp + +2333 : 2a rol a + tst_ax rROL,fROL,0 +2334 : 08 > php ;save flags +2335 : dd2002 > cmp rROL,x ;test result + > trap_ne +2338 : d0fe > bne * ;failed not equal (non zero) + > +233a : 68 > pla ;load status + > eor_flag 0 +233b : 4930 > eor #0|fao ;invert expected flags + always on bits + > +233d : dd3002 > cmp fROL,x ;test flags + > trap_ne ; +2340 : d0fe > bne * ;failed not equal (non zero) + > + +2342 : ca dex +2343 : 10e8 bpl trol +2345 : a203 ldx #3 +2347 : trol1 + set_ax zp1,$ff-fc + > load_flag $ff-fc +2347 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +2349 : 48 > pha ;use stack to load status +234a : b513 > lda zp1,x ;precharge accu +234c : 28 > plp + +234d : 2a rol a + tst_ax rROL,fROL,$ff-fnzc +234e : 08 > php ;save flags +234f : dd2002 > cmp rROL,x ;test result + > trap_ne +2352 : d0fe > bne * ;failed not equal (non zero) + > +2354 : 68 > pla ;load status + > eor_flag $ff-fnzc +2355 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2357 : dd3002 > cmp fROL,x ;test flags + > trap_ne ; +235a : d0fe > bne * ;failed not equal (non zero) + > + +235c : ca dex +235d : 10e8 bpl trol1 + +235f : a203 ldx #3 +2361 : trolc + set_ax zp1,fc + > load_flag fc +2361 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +2363 : 48 > pha ;use stack to load status +2364 : b513 > lda zp1,x ;precharge accu +2366 : 28 > plp + +2367 : 2a rol a + tst_ax rROLc,fROLc,0 +2368 : 08 > php ;save flags +2369 : dd2402 > cmp rROLc,x ;test result + > trap_ne +236c : d0fe > bne * ;failed not equal (non zero) + > +236e : 68 > pla ;load status + > eor_flag 0 +236f : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2371 : dd3402 > cmp fROLc,x ;test flags + > trap_ne ; +2374 : d0fe > bne * ;failed not equal (non zero) + > + +2376 : ca dex +2377 : 10e8 bpl trolc +2379 : a203 ldx #3 +237b : trolc1 + set_ax zp1,$ff + > load_flag $ff +237b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +237d : 48 > pha ;use stack to load status +237e : b513 > lda zp1,x ;precharge accu +2380 : 28 > plp + +2381 : 2a rol a + tst_ax rROLc,fROLc,$ff-fnzc +2382 : 08 > php ;save flags +2383 : dd2402 > cmp rROLc,x ;test result + > trap_ne +2386 : d0fe > bne * ;failed not equal (non zero) + > +2388 : 68 > pla ;load status + > eor_flag $ff-fnzc +2389 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +238b : dd3402 > cmp fROLc,x ;test flags + > trap_ne ; +238e : d0fe > bne * ;failed not equal (non zero) + > + +2390 : ca dex +2391 : 10e8 bpl trolc1 + +2393 : a203 ldx #3 +2395 : tror + set_ax zp1,0 + > load_flag 0 +2395 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2397 : 48 > pha ;use stack to load status +2398 : b513 > lda zp1,x ;precharge accu +239a : 28 > plp + +239b : 6a ror a + tst_ax rROR,fROR,0 +239c : 08 > php ;save flags +239d : dd2802 > cmp rROR,x ;test result + > trap_ne +23a0 : d0fe > bne * ;failed not equal (non zero) + > +23a2 : 68 > pla ;load status + > eor_flag 0 +23a3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +23a5 : dd3802 > cmp fROR,x ;test flags + > trap_ne ; +23a8 : d0fe > bne * ;failed not equal (non zero) + > + +23aa : ca dex +23ab : 10e8 bpl tror +23ad : a203 ldx #3 +23af : tror1 + set_ax zp1,$ff-fc + > load_flag $ff-fc +23af : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +23b1 : 48 > pha ;use stack to load status +23b2 : b513 > lda zp1,x ;precharge accu +23b4 : 28 > plp + +23b5 : 6a ror a + tst_ax rROR,fROR,$ff-fnzc +23b6 : 08 > php ;save flags +23b7 : dd2802 > cmp rROR,x ;test result + > trap_ne +23ba : d0fe > bne * ;failed not equal (non zero) + > +23bc : 68 > pla ;load status + > eor_flag $ff-fnzc +23bd : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +23bf : dd3802 > cmp fROR,x ;test flags + > trap_ne ; +23c2 : d0fe > bne * ;failed not equal (non zero) + > + +23c4 : ca dex +23c5 : 10e8 bpl tror1 + +23c7 : a203 ldx #3 +23c9 : trorc + set_ax zp1,fc + > load_flag fc +23c9 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +23cb : 48 > pha ;use stack to load status +23cc : b513 > lda zp1,x ;precharge accu +23ce : 28 > plp + +23cf : 6a ror a + tst_ax rRORc,fRORc,0 +23d0 : 08 > php ;save flags +23d1 : dd2c02 > cmp rRORc,x ;test result + > trap_ne +23d4 : d0fe > bne * ;failed not equal (non zero) + > +23d6 : 68 > pla ;load status + > eor_flag 0 +23d7 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +23d9 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne ; +23dc : d0fe > bne * ;failed not equal (non zero) + > + +23de : ca dex +23df : 10e8 bpl trorc +23e1 : a203 ldx #3 +23e3 : trorc1 + set_ax zp1,$ff + > load_flag $ff +23e3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +23e5 : 48 > pha ;use stack to load status +23e6 : b513 > lda zp1,x ;precharge accu +23e8 : 28 > plp + +23e9 : 6a ror a + tst_ax rRORc,fRORc,$ff-fnzc +23ea : 08 > php ;save flags +23eb : dd2c02 > cmp rRORc,x ;test result + > trap_ne +23ee : d0fe > bne * ;failed not equal (non zero) + > +23f0 : 68 > pla ;load status + > eor_flag $ff-fnzc +23f1 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +23f3 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne ; +23f6 : d0fe > bne * ;failed not equal (non zero) + > + +23f8 : ca dex +23f9 : 10e8 bpl trorc1 + next_test +23fb : ad0002 > lda test_case ;previous test +23fe : c91d > cmp #test_num + > trap_ne ;test is out of sequence +2400 : d0fe > bne * ;failed not equal (non zero) + > +001e = >test_num = test_num + 1 +2402 : a91e > lda #test_num ;*** next tests' number +2404 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; shifts - zeropage +2407 : a203 ldx #3 +2409 : tasl2 + set_z zp1,0 + > load_flag 0 +2409 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +240b : 48 > pha ;use stack to load status +240c : b513 > lda zp1,x ;load to zeropage +240e : 850c > sta zpt +2410 : 28 > plp + +2411 : 060c asl zpt + tst_z rASL,fASL,0 +2413 : 08 > php ;save flags +2414 : a50c > lda zpt +2416 : dd2002 > cmp rASL,x ;test result + > trap_ne +2419 : d0fe > bne * ;failed not equal (non zero) + > +241b : 68 > pla ;load status + > eor_flag 0 +241c : 4930 > eor #0|fao ;invert expected flags + always on bits + > +241e : dd3002 > cmp fASL,x ;test flags + > trap_ne +2421 : d0fe > bne * ;failed not equal (non zero) + > + +2423 : ca dex +2424 : 10e3 bpl tasl2 +2426 : a203 ldx #3 +2428 : tasl3 + set_z zp1,$ff + > load_flag $ff +2428 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +242a : 48 > pha ;use stack to load status +242b : b513 > lda zp1,x ;load to zeropage +242d : 850c > sta zpt +242f : 28 > plp + +2430 : 060c asl zpt + tst_z rASL,fASL,$ff-fnzc +2432 : 08 > php ;save flags +2433 : a50c > lda zpt +2435 : dd2002 > cmp rASL,x ;test result + > trap_ne +2438 : d0fe > bne * ;failed not equal (non zero) + > +243a : 68 > pla ;load status + > eor_flag $ff-fnzc +243b : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +243d : dd3002 > cmp fASL,x ;test flags + > trap_ne +2440 : d0fe > bne * ;failed not equal (non zero) + > + +2442 : ca dex +2443 : 10e3 bpl tasl3 + +2445 : a203 ldx #3 +2447 : tlsr2 + set_z zp1,0 + > load_flag 0 +2447 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2449 : 48 > pha ;use stack to load status +244a : b513 > lda zp1,x ;load to zeropage +244c : 850c > sta zpt +244e : 28 > plp + +244f : 460c lsr zpt + tst_z rLSR,fLSR,0 +2451 : 08 > php ;save flags +2452 : a50c > lda zpt +2454 : dd2802 > cmp rLSR,x ;test result + > trap_ne +2457 : d0fe > bne * ;failed not equal (non zero) + > +2459 : 68 > pla ;load status + > eor_flag 0 +245a : 4930 > eor #0|fao ;invert expected flags + always on bits + > +245c : dd3802 > cmp fLSR,x ;test flags + > trap_ne +245f : d0fe > bne * ;failed not equal (non zero) + > + +2461 : ca dex +2462 : 10e3 bpl tlsr2 +2464 : a203 ldx #3 +2466 : tlsr3 + set_z zp1,$ff + > load_flag $ff +2466 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2468 : 48 > pha ;use stack to load status +2469 : b513 > lda zp1,x ;load to zeropage +246b : 850c > sta zpt +246d : 28 > plp + +246e : 460c lsr zpt + tst_z rLSR,fLSR,$ff-fnzc +2470 : 08 > php ;save flags +2471 : a50c > lda zpt +2473 : dd2802 > cmp rLSR,x ;test result + > trap_ne +2476 : d0fe > bne * ;failed not equal (non zero) + > +2478 : 68 > pla ;load status + > eor_flag $ff-fnzc +2479 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +247b : dd3802 > cmp fLSR,x ;test flags + > trap_ne +247e : d0fe > bne * ;failed not equal (non zero) + > + +2480 : ca dex +2481 : 10e3 bpl tlsr3 + +2483 : a203 ldx #3 +2485 : trol2 + set_z zp1,0 + > load_flag 0 +2485 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2487 : 48 > pha ;use stack to load status +2488 : b513 > lda zp1,x ;load to zeropage +248a : 850c > sta zpt +248c : 28 > plp + +248d : 260c rol zpt + tst_z rROL,fROL,0 +248f : 08 > php ;save flags +2490 : a50c > lda zpt +2492 : dd2002 > cmp rROL,x ;test result + > trap_ne +2495 : d0fe > bne * ;failed not equal (non zero) + > +2497 : 68 > pla ;load status + > eor_flag 0 +2498 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +249a : dd3002 > cmp fROL,x ;test flags + > trap_ne +249d : d0fe > bne * ;failed not equal (non zero) + > + +249f : ca dex +24a0 : 10e3 bpl trol2 +24a2 : a203 ldx #3 +24a4 : trol3 + set_z zp1,$ff-fc + > load_flag $ff-fc +24a4 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +24a6 : 48 > pha ;use stack to load status +24a7 : b513 > lda zp1,x ;load to zeropage +24a9 : 850c > sta zpt +24ab : 28 > plp + +24ac : 260c rol zpt + tst_z rROL,fROL,$ff-fnzc +24ae : 08 > php ;save flags +24af : a50c > lda zpt +24b1 : dd2002 > cmp rROL,x ;test result + > trap_ne +24b4 : d0fe > bne * ;failed not equal (non zero) + > +24b6 : 68 > pla ;load status + > eor_flag $ff-fnzc +24b7 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +24b9 : dd3002 > cmp fROL,x ;test flags + > trap_ne +24bc : d0fe > bne * ;failed not equal (non zero) + > + +24be : ca dex +24bf : 10e3 bpl trol3 + +24c1 : a203 ldx #3 +24c3 : trolc2 + set_z zp1,fc + > load_flag fc +24c3 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +24c5 : 48 > pha ;use stack to load status +24c6 : b513 > lda zp1,x ;load to zeropage +24c8 : 850c > sta zpt +24ca : 28 > plp + +24cb : 260c rol zpt + tst_z rROLc,fROLc,0 +24cd : 08 > php ;save flags +24ce : a50c > lda zpt +24d0 : dd2402 > cmp rROLc,x ;test result + > trap_ne +24d3 : d0fe > bne * ;failed not equal (non zero) + > +24d5 : 68 > pla ;load status + > eor_flag 0 +24d6 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +24d8 : dd3402 > cmp fROLc,x ;test flags + > trap_ne +24db : d0fe > bne * ;failed not equal (non zero) + > + +24dd : ca dex +24de : 10e3 bpl trolc2 +24e0 : a203 ldx #3 +24e2 : trolc3 + set_z zp1,$ff + > load_flag $ff +24e2 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +24e4 : 48 > pha ;use stack to load status +24e5 : b513 > lda zp1,x ;load to zeropage +24e7 : 850c > sta zpt +24e9 : 28 > plp + +24ea : 260c rol zpt + tst_z rROLc,fROLc,$ff-fnzc +24ec : 08 > php ;save flags +24ed : a50c > lda zpt +24ef : dd2402 > cmp rROLc,x ;test result + > trap_ne +24f2 : d0fe > bne * ;failed not equal (non zero) + > +24f4 : 68 > pla ;load status + > eor_flag $ff-fnzc +24f5 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +24f7 : dd3402 > cmp fROLc,x ;test flags + > trap_ne +24fa : d0fe > bne * ;failed not equal (non zero) + > + +24fc : ca dex +24fd : 10e3 bpl trolc3 + +24ff : a203 ldx #3 +2501 : tror2 + set_z zp1,0 + > load_flag 0 +2501 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2503 : 48 > pha ;use stack to load status +2504 : b513 > lda zp1,x ;load to zeropage +2506 : 850c > sta zpt +2508 : 28 > plp + +2509 : 660c ror zpt + tst_z rROR,fROR,0 +250b : 08 > php ;save flags +250c : a50c > lda zpt +250e : dd2802 > cmp rROR,x ;test result + > trap_ne +2511 : d0fe > bne * ;failed not equal (non zero) + > +2513 : 68 > pla ;load status + > eor_flag 0 +2514 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2516 : dd3802 > cmp fROR,x ;test flags + > trap_ne +2519 : d0fe > bne * ;failed not equal (non zero) + > + +251b : ca dex +251c : 10e3 bpl tror2 +251e : a203 ldx #3 +2520 : tror3 + set_z zp1,$ff-fc + > load_flag $ff-fc +2520 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +2522 : 48 > pha ;use stack to load status +2523 : b513 > lda zp1,x ;load to zeropage +2525 : 850c > sta zpt +2527 : 28 > plp + +2528 : 660c ror zpt + tst_z rROR,fROR,$ff-fnzc +252a : 08 > php ;save flags +252b : a50c > lda zpt +252d : dd2802 > cmp rROR,x ;test result + > trap_ne +2530 : d0fe > bne * ;failed not equal (non zero) + > +2532 : 68 > pla ;load status + > eor_flag $ff-fnzc +2533 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2535 : dd3802 > cmp fROR,x ;test flags + > trap_ne +2538 : d0fe > bne * ;failed not equal (non zero) + > + +253a : ca dex +253b : 10e3 bpl tror3 + +253d : a203 ldx #3 +253f : trorc2 + set_z zp1,fc + > load_flag fc +253f : a901 > lda #fc ;allow test to change I-flag (no mask) + > +2541 : 48 > pha ;use stack to load status +2542 : b513 > lda zp1,x ;load to zeropage +2544 : 850c > sta zpt +2546 : 28 > plp + +2547 : 660c ror zpt + tst_z rRORc,fRORc,0 +2549 : 08 > php ;save flags +254a : a50c > lda zpt +254c : dd2c02 > cmp rRORc,x ;test result + > trap_ne +254f : d0fe > bne * ;failed not equal (non zero) + > +2551 : 68 > pla ;load status + > eor_flag 0 +2552 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2554 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +2557 : d0fe > bne * ;failed not equal (non zero) + > + +2559 : ca dex +255a : 10e3 bpl trorc2 +255c : a203 ldx #3 +255e : trorc3 + set_z zp1,$ff + > load_flag $ff +255e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2560 : 48 > pha ;use stack to load status +2561 : b513 > lda zp1,x ;load to zeropage +2563 : 850c > sta zpt +2565 : 28 > plp + +2566 : 660c ror zpt + tst_z rRORc,fRORc,$ff-fnzc +2568 : 08 > php ;save flags +2569 : a50c > lda zpt +256b : dd2c02 > cmp rRORc,x ;test result + > trap_ne +256e : d0fe > bne * ;failed not equal (non zero) + > +2570 : 68 > pla ;load status + > eor_flag $ff-fnzc +2571 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2573 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +2576 : d0fe > bne * ;failed not equal (non zero) + > + +2578 : ca dex +2579 : 10e3 bpl trorc3 + next_test +257b : ad0002 > lda test_case ;previous test +257e : c91e > cmp #test_num + > trap_ne ;test is out of sequence +2580 : d0fe > bne * ;failed not equal (non zero) + > +001f = >test_num = test_num + 1 +2582 : a91f > lda #test_num ;*** next tests' number +2584 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; shifts - absolute +2587 : a203 ldx #3 +2589 : tasl4 + set_abs zp1,0 + > load_flag 0 +2589 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +258b : 48 > pha ;use stack to load status +258c : b513 > lda zp1,x ;load to memory +258e : 8d0302 > sta abst +2591 : 28 > plp + +2592 : 0e0302 asl abst + tst_abs rASL,fASL,0 +2595 : 08 > php ;save flags +2596 : ad0302 > lda abst +2599 : dd2002 > cmp rASL,x ;test result + > trap_ne +259c : d0fe > bne * ;failed not equal (non zero) + > +259e : 68 > pla ;load status + > eor_flag 0 +259f : 4930 > eor #0|fao ;invert expected flags + always on bits + > +25a1 : dd3002 > cmp fASL,x ;test flags + > trap_ne +25a4 : d0fe > bne * ;failed not equal (non zero) + > + +25a6 : ca dex +25a7 : 10e0 bpl tasl4 +25a9 : a203 ldx #3 +25ab : tasl5 + set_abs zp1,$ff + > load_flag $ff +25ab : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +25ad : 48 > pha ;use stack to load status +25ae : b513 > lda zp1,x ;load to memory +25b0 : 8d0302 > sta abst +25b3 : 28 > plp + +25b4 : 0e0302 asl abst + tst_abs rASL,fASL,$ff-fnzc +25b7 : 08 > php ;save flags +25b8 : ad0302 > lda abst +25bb : dd2002 > cmp rASL,x ;test result + > trap_ne +25be : d0fe > bne * ;failed not equal (non zero) + > +25c0 : 68 > pla ;load status + > eor_flag $ff-fnzc +25c1 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +25c3 : dd3002 > cmp fASL,x ;test flags + > trap_ne +25c6 : d0fe > bne * ;failed not equal (non zero) + > + +25c8 : ca dex +25c9 : 10e0 bpl tasl5 + +25cb : a203 ldx #3 +25cd : tlsr4 + set_abs zp1,0 + > load_flag 0 +25cd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +25cf : 48 > pha ;use stack to load status +25d0 : b513 > lda zp1,x ;load to memory +25d2 : 8d0302 > sta abst +25d5 : 28 > plp + +25d6 : 4e0302 lsr abst + tst_abs rLSR,fLSR,0 +25d9 : 08 > php ;save flags +25da : ad0302 > lda abst +25dd : dd2802 > cmp rLSR,x ;test result + > trap_ne +25e0 : d0fe > bne * ;failed not equal (non zero) + > +25e2 : 68 > pla ;load status + > eor_flag 0 +25e3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +25e5 : dd3802 > cmp fLSR,x ;test flags + > trap_ne +25e8 : d0fe > bne * ;failed not equal (non zero) + > + +25ea : ca dex +25eb : 10e0 bpl tlsr4 +25ed : a203 ldx #3 +25ef : tlsr5 + set_abs zp1,$ff + > load_flag $ff +25ef : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +25f1 : 48 > pha ;use stack to load status +25f2 : b513 > lda zp1,x ;load to memory +25f4 : 8d0302 > sta abst +25f7 : 28 > plp + +25f8 : 4e0302 lsr abst + tst_abs rLSR,fLSR,$ff-fnzc +25fb : 08 > php ;save flags +25fc : ad0302 > lda abst +25ff : dd2802 > cmp rLSR,x ;test result + > trap_ne +2602 : d0fe > bne * ;failed not equal (non zero) + > +2604 : 68 > pla ;load status + > eor_flag $ff-fnzc +2605 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2607 : dd3802 > cmp fLSR,x ;test flags + > trap_ne +260a : d0fe > bne * ;failed not equal (non zero) + > + +260c : ca dex +260d : 10e0 bpl tlsr5 + +260f : a203 ldx #3 +2611 : trol4 + set_abs zp1,0 + > load_flag 0 +2611 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2613 : 48 > pha ;use stack to load status +2614 : b513 > lda zp1,x ;load to memory +2616 : 8d0302 > sta abst +2619 : 28 > plp + +261a : 2e0302 rol abst + tst_abs rROL,fROL,0 +261d : 08 > php ;save flags +261e : ad0302 > lda abst +2621 : dd2002 > cmp rROL,x ;test result + > trap_ne +2624 : d0fe > bne * ;failed not equal (non zero) + > +2626 : 68 > pla ;load status + > eor_flag 0 +2627 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2629 : dd3002 > cmp fROL,x ;test flags + > trap_ne +262c : d0fe > bne * ;failed not equal (non zero) + > + +262e : ca dex +262f : 10e0 bpl trol4 +2631 : a203 ldx #3 +2633 : trol5 + set_abs zp1,$ff-fc + > load_flag $ff-fc +2633 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +2635 : 48 > pha ;use stack to load status +2636 : b513 > lda zp1,x ;load to memory +2638 : 8d0302 > sta abst +263b : 28 > plp + +263c : 2e0302 rol abst + tst_abs rROL,fROL,$ff-fnzc +263f : 08 > php ;save flags +2640 : ad0302 > lda abst +2643 : dd2002 > cmp rROL,x ;test result + > trap_ne +2646 : d0fe > bne * ;failed not equal (non zero) + > +2648 : 68 > pla ;load status + > eor_flag $ff-fnzc +2649 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +264b : dd3002 > cmp fROL,x ;test flags + > trap_ne +264e : d0fe > bne * ;failed not equal (non zero) + > + +2650 : ca dex +2651 : 10e0 bpl trol5 + +2653 : a203 ldx #3 +2655 : trolc4 + set_abs zp1,fc + > load_flag fc +2655 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +2657 : 48 > pha ;use stack to load status +2658 : b513 > lda zp1,x ;load to memory +265a : 8d0302 > sta abst +265d : 28 > plp + +265e : 2e0302 rol abst + tst_abs rROLc,fROLc,0 +2661 : 08 > php ;save flags +2662 : ad0302 > lda abst +2665 : dd2402 > cmp rROLc,x ;test result + > trap_ne +2668 : d0fe > bne * ;failed not equal (non zero) + > +266a : 68 > pla ;load status + > eor_flag 0 +266b : 4930 > eor #0|fao ;invert expected flags + always on bits + > +266d : dd3402 > cmp fROLc,x ;test flags + > trap_ne +2670 : d0fe > bne * ;failed not equal (non zero) + > + +2672 : ca dex +2673 : 10e0 bpl trolc4 +2675 : a203 ldx #3 +2677 : trolc5 + set_abs zp1,$ff + > load_flag $ff +2677 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2679 : 48 > pha ;use stack to load status +267a : b513 > lda zp1,x ;load to memory +267c : 8d0302 > sta abst +267f : 28 > plp + +2680 : 2e0302 rol abst + tst_abs rROLc,fROLc,$ff-fnzc +2683 : 08 > php ;save flags +2684 : ad0302 > lda abst +2687 : dd2402 > cmp rROLc,x ;test result + > trap_ne +268a : d0fe > bne * ;failed not equal (non zero) + > +268c : 68 > pla ;load status + > eor_flag $ff-fnzc +268d : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +268f : dd3402 > cmp fROLc,x ;test flags + > trap_ne +2692 : d0fe > bne * ;failed not equal (non zero) + > + +2694 : ca dex +2695 : 10e0 bpl trolc5 + +2697 : a203 ldx #3 +2699 : tror4 + set_abs zp1,0 + > load_flag 0 +2699 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +269b : 48 > pha ;use stack to load status +269c : b513 > lda zp1,x ;load to memory +269e : 8d0302 > sta abst +26a1 : 28 > plp + +26a2 : 6e0302 ror abst + tst_abs rROR,fROR,0 +26a5 : 08 > php ;save flags +26a6 : ad0302 > lda abst +26a9 : dd2802 > cmp rROR,x ;test result + > trap_ne +26ac : d0fe > bne * ;failed not equal (non zero) + > +26ae : 68 > pla ;load status + > eor_flag 0 +26af : 4930 > eor #0|fao ;invert expected flags + always on bits + > +26b1 : dd3802 > cmp fROR,x ;test flags + > trap_ne +26b4 : d0fe > bne * ;failed not equal (non zero) + > + +26b6 : ca dex +26b7 : 10e0 bpl tror4 +26b9 : a203 ldx #3 +26bb : tror5 + set_abs zp1,$ff-fc + > load_flag $ff-fc +26bb : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +26bd : 48 > pha ;use stack to load status +26be : b513 > lda zp1,x ;load to memory +26c0 : 8d0302 > sta abst +26c3 : 28 > plp + +26c4 : 6e0302 ror abst + tst_abs rROR,fROR,$ff-fnzc +26c7 : 08 > php ;save flags +26c8 : ad0302 > lda abst +26cb : dd2802 > cmp rROR,x ;test result + > trap_ne +26ce : d0fe > bne * ;failed not equal (non zero) + > +26d0 : 68 > pla ;load status + > eor_flag $ff-fnzc +26d1 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +26d3 : dd3802 > cmp fROR,x ;test flags + > trap_ne +26d6 : d0fe > bne * ;failed not equal (non zero) + > + +26d8 : ca dex +26d9 : 10e0 bpl tror5 + +26db : a203 ldx #3 +26dd : trorc4 + set_abs zp1,fc + > load_flag fc +26dd : a901 > lda #fc ;allow test to change I-flag (no mask) + > +26df : 48 > pha ;use stack to load status +26e0 : b513 > lda zp1,x ;load to memory +26e2 : 8d0302 > sta abst +26e5 : 28 > plp + +26e6 : 6e0302 ror abst + tst_abs rRORc,fRORc,0 +26e9 : 08 > php ;save flags +26ea : ad0302 > lda abst +26ed : dd2c02 > cmp rRORc,x ;test result + > trap_ne +26f0 : d0fe > bne * ;failed not equal (non zero) + > +26f2 : 68 > pla ;load status + > eor_flag 0 +26f3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +26f5 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +26f8 : d0fe > bne * ;failed not equal (non zero) + > + +26fa : ca dex +26fb : 10e0 bpl trorc4 +26fd : a203 ldx #3 +26ff : trorc5 + set_abs zp1,$ff + > load_flag $ff +26ff : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2701 : 48 > pha ;use stack to load status +2702 : b513 > lda zp1,x ;load to memory +2704 : 8d0302 > sta abst +2707 : 28 > plp + +2708 : 6e0302 ror abst + tst_abs rRORc,fRORc,$ff-fnzc +270b : 08 > php ;save flags +270c : ad0302 > lda abst +270f : dd2c02 > cmp rRORc,x ;test result + > trap_ne +2712 : d0fe > bne * ;failed not equal (non zero) + > +2714 : 68 > pla ;load status + > eor_flag $ff-fnzc +2715 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2717 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +271a : d0fe > bne * ;failed not equal (non zero) + > + +271c : ca dex +271d : 10e0 bpl trorc5 + next_test +271f : ad0002 > lda test_case ;previous test +2722 : c91f > cmp #test_num + > trap_ne ;test is out of sequence +2724 : d0fe > bne * ;failed not equal (non zero) + > +0020 = >test_num = test_num + 1 +2726 : a920 > lda #test_num ;*** next tests' number +2728 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; shifts - zp indexed +272b : a203 ldx #3 +272d : tasl6 + set_zx zp1,0 + > load_flag 0 +272d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +272f : 48 > pha ;use stack to load status +2730 : b513 > lda zp1,x ;load to indexed zeropage +2732 : 950c > sta zpt,x +2734 : 28 > plp + +2735 : 160c asl zpt,x + tst_zx rASL,fASL,0 +2737 : 08 > php ;save flags +2738 : b50c > lda zpt,x +273a : dd2002 > cmp rASL,x ;test result + > trap_ne +273d : d0fe > bne * ;failed not equal (non zero) + > +273f : 68 > pla ;load status + > eor_flag 0 +2740 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2742 : dd3002 > cmp fASL,x ;test flags + > trap_ne +2745 : d0fe > bne * ;failed not equal (non zero) + > + +2747 : ca dex +2748 : 10e3 bpl tasl6 +274a : a203 ldx #3 +274c : tasl7 + set_zx zp1,$ff + > load_flag $ff +274c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +274e : 48 > pha ;use stack to load status +274f : b513 > lda zp1,x ;load to indexed zeropage +2751 : 950c > sta zpt,x +2753 : 28 > plp + +2754 : 160c asl zpt,x + tst_zx rASL,fASL,$ff-fnzc +2756 : 08 > php ;save flags +2757 : b50c > lda zpt,x +2759 : dd2002 > cmp rASL,x ;test result + > trap_ne +275c : d0fe > bne * ;failed not equal (non zero) + > +275e : 68 > pla ;load status + > eor_flag $ff-fnzc +275f : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2761 : dd3002 > cmp fASL,x ;test flags + > trap_ne +2764 : d0fe > bne * ;failed not equal (non zero) + > + +2766 : ca dex +2767 : 10e3 bpl tasl7 + +2769 : a203 ldx #3 +276b : tlsr6 + set_zx zp1,0 + > load_flag 0 +276b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +276d : 48 > pha ;use stack to load status +276e : b513 > lda zp1,x ;load to indexed zeropage +2770 : 950c > sta zpt,x +2772 : 28 > plp + +2773 : 560c lsr zpt,x + tst_zx rLSR,fLSR,0 +2775 : 08 > php ;save flags +2776 : b50c > lda zpt,x +2778 : dd2802 > cmp rLSR,x ;test result + > trap_ne +277b : d0fe > bne * ;failed not equal (non zero) + > +277d : 68 > pla ;load status + > eor_flag 0 +277e : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2780 : dd3802 > cmp fLSR,x ;test flags + > trap_ne +2783 : d0fe > bne * ;failed not equal (non zero) + > + +2785 : ca dex +2786 : 10e3 bpl tlsr6 +2788 : a203 ldx #3 +278a : tlsr7 + set_zx zp1,$ff + > load_flag $ff +278a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +278c : 48 > pha ;use stack to load status +278d : b513 > lda zp1,x ;load to indexed zeropage +278f : 950c > sta zpt,x +2791 : 28 > plp + +2792 : 560c lsr zpt,x + tst_zx rLSR,fLSR,$ff-fnzc +2794 : 08 > php ;save flags +2795 : b50c > lda zpt,x +2797 : dd2802 > cmp rLSR,x ;test result + > trap_ne +279a : d0fe > bne * ;failed not equal (non zero) + > +279c : 68 > pla ;load status + > eor_flag $ff-fnzc +279d : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +279f : dd3802 > cmp fLSR,x ;test flags + > trap_ne +27a2 : d0fe > bne * ;failed not equal (non zero) + > + +27a4 : ca dex +27a5 : 10e3 bpl tlsr7 + +27a7 : a203 ldx #3 +27a9 : trol6 + set_zx zp1,0 + > load_flag 0 +27a9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +27ab : 48 > pha ;use stack to load status +27ac : b513 > lda zp1,x ;load to indexed zeropage +27ae : 950c > sta zpt,x +27b0 : 28 > plp + +27b1 : 360c rol zpt,x + tst_zx rROL,fROL,0 +27b3 : 08 > php ;save flags +27b4 : b50c > lda zpt,x +27b6 : dd2002 > cmp rROL,x ;test result + > trap_ne +27b9 : d0fe > bne * ;failed not equal (non zero) + > +27bb : 68 > pla ;load status + > eor_flag 0 +27bc : 4930 > eor #0|fao ;invert expected flags + always on bits + > +27be : dd3002 > cmp fROL,x ;test flags + > trap_ne +27c1 : d0fe > bne * ;failed not equal (non zero) + > + +27c3 : ca dex +27c4 : 10e3 bpl trol6 +27c6 : a203 ldx #3 +27c8 : trol7 + set_zx zp1,$ff-fc + > load_flag $ff-fc +27c8 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +27ca : 48 > pha ;use stack to load status +27cb : b513 > lda zp1,x ;load to indexed zeropage +27cd : 950c > sta zpt,x +27cf : 28 > plp + +27d0 : 360c rol zpt,x + tst_zx rROL,fROL,$ff-fnzc +27d2 : 08 > php ;save flags +27d3 : b50c > lda zpt,x +27d5 : dd2002 > cmp rROL,x ;test result + > trap_ne +27d8 : d0fe > bne * ;failed not equal (non zero) + > +27da : 68 > pla ;load status + > eor_flag $ff-fnzc +27db : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +27dd : dd3002 > cmp fROL,x ;test flags + > trap_ne +27e0 : d0fe > bne * ;failed not equal (non zero) + > + +27e2 : ca dex +27e3 : 10e3 bpl trol7 + +27e5 : a203 ldx #3 +27e7 : trolc6 + set_zx zp1,fc + > load_flag fc +27e7 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +27e9 : 48 > pha ;use stack to load status +27ea : b513 > lda zp1,x ;load to indexed zeropage +27ec : 950c > sta zpt,x +27ee : 28 > plp + +27ef : 360c rol zpt,x + tst_zx rROLc,fROLc,0 +27f1 : 08 > php ;save flags +27f2 : b50c > lda zpt,x +27f4 : dd2402 > cmp rROLc,x ;test result + > trap_ne +27f7 : d0fe > bne * ;failed not equal (non zero) + > +27f9 : 68 > pla ;load status + > eor_flag 0 +27fa : 4930 > eor #0|fao ;invert expected flags + always on bits + > +27fc : dd3402 > cmp fROLc,x ;test flags + > trap_ne +27ff : d0fe > bne * ;failed not equal (non zero) + > + +2801 : ca dex +2802 : 10e3 bpl trolc6 +2804 : a203 ldx #3 +2806 : trolc7 + set_zx zp1,$ff + > load_flag $ff +2806 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2808 : 48 > pha ;use stack to load status +2809 : b513 > lda zp1,x ;load to indexed zeropage +280b : 950c > sta zpt,x +280d : 28 > plp + +280e : 360c rol zpt,x + tst_zx rROLc,fROLc,$ff-fnzc +2810 : 08 > php ;save flags +2811 : b50c > lda zpt,x +2813 : dd2402 > cmp rROLc,x ;test result + > trap_ne +2816 : d0fe > bne * ;failed not equal (non zero) + > +2818 : 68 > pla ;load status + > eor_flag $ff-fnzc +2819 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +281b : dd3402 > cmp fROLc,x ;test flags + > trap_ne +281e : d0fe > bne * ;failed not equal (non zero) + > + +2820 : ca dex +2821 : 10e3 bpl trolc7 + +2823 : a203 ldx #3 +2825 : tror6 + set_zx zp1,0 + > load_flag 0 +2825 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2827 : 48 > pha ;use stack to load status +2828 : b513 > lda zp1,x ;load to indexed zeropage +282a : 950c > sta zpt,x +282c : 28 > plp + +282d : 760c ror zpt,x + tst_zx rROR,fROR,0 +282f : 08 > php ;save flags +2830 : b50c > lda zpt,x +2832 : dd2802 > cmp rROR,x ;test result + > trap_ne +2835 : d0fe > bne * ;failed not equal (non zero) + > +2837 : 68 > pla ;load status + > eor_flag 0 +2838 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +283a : dd3802 > cmp fROR,x ;test flags + > trap_ne +283d : d0fe > bne * ;failed not equal (non zero) + > + +283f : ca dex +2840 : 10e3 bpl tror6 +2842 : a203 ldx #3 +2844 : tror7 + set_zx zp1,$ff-fc + > load_flag $ff-fc +2844 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +2846 : 48 > pha ;use stack to load status +2847 : b513 > lda zp1,x ;load to indexed zeropage +2849 : 950c > sta zpt,x +284b : 28 > plp + +284c : 760c ror zpt,x + tst_zx rROR,fROR,$ff-fnzc +284e : 08 > php ;save flags +284f : b50c > lda zpt,x +2851 : dd2802 > cmp rROR,x ;test result + > trap_ne +2854 : d0fe > bne * ;failed not equal (non zero) + > +2856 : 68 > pla ;load status + > eor_flag $ff-fnzc +2857 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2859 : dd3802 > cmp fROR,x ;test flags + > trap_ne +285c : d0fe > bne * ;failed not equal (non zero) + > + +285e : ca dex +285f : 10e3 bpl tror7 + +2861 : a203 ldx #3 +2863 : trorc6 + set_zx zp1,fc + > load_flag fc +2863 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +2865 : 48 > pha ;use stack to load status +2866 : b513 > lda zp1,x ;load to indexed zeropage +2868 : 950c > sta zpt,x +286a : 28 > plp + +286b : 760c ror zpt,x + tst_zx rRORc,fRORc,0 +286d : 08 > php ;save flags +286e : b50c > lda zpt,x +2870 : dd2c02 > cmp rRORc,x ;test result + > trap_ne +2873 : d0fe > bne * ;failed not equal (non zero) + > +2875 : 68 > pla ;load status + > eor_flag 0 +2876 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2878 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +287b : d0fe > bne * ;failed not equal (non zero) + > + +287d : ca dex +287e : 10e3 bpl trorc6 +2880 : a203 ldx #3 +2882 : trorc7 + set_zx zp1,$ff + > load_flag $ff +2882 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2884 : 48 > pha ;use stack to load status +2885 : b513 > lda zp1,x ;load to indexed zeropage +2887 : 950c > sta zpt,x +2889 : 28 > plp + +288a : 760c ror zpt,x + tst_zx rRORc,fRORc,$ff-fnzc +288c : 08 > php ;save flags +288d : b50c > lda zpt,x +288f : dd2c02 > cmp rRORc,x ;test result + > trap_ne +2892 : d0fe > bne * ;failed not equal (non zero) + > +2894 : 68 > pla ;load status + > eor_flag $ff-fnzc +2895 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2897 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +289a : d0fe > bne * ;failed not equal (non zero) + > + +289c : ca dex +289d : 10e3 bpl trorc7 + next_test +289f : ad0002 > lda test_case ;previous test +28a2 : c920 > cmp #test_num + > trap_ne ;test is out of sequence +28a4 : d0fe > bne * ;failed not equal (non zero) + > +0021 = >test_num = test_num + 1 +28a6 : a921 > lda #test_num ;*** next tests' number +28a8 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; shifts - abs indexed +28ab : a203 ldx #3 +28ad : tasl8 + set_absx zp1,0 + > load_flag 0 +28ad : a900 > lda #0 ;allow test to change I-flag (no mask) + > +28af : 48 > pha ;use stack to load status +28b0 : b513 > lda zp1,x ;load to indexed memory +28b2 : 9d0302 > sta abst,x +28b5 : 28 > plp + +28b6 : 1e0302 asl abst,x + tst_absx rASL,fASL,0 +28b9 : 08 > php ;save flags +28ba : bd0302 > lda abst,x +28bd : dd2002 > cmp rASL,x ;test result + > trap_ne +28c0 : d0fe > bne * ;failed not equal (non zero) + > +28c2 : 68 > pla ;load status + > eor_flag 0 +28c3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +28c5 : dd3002 > cmp fASL,x ;test flags + > trap_ne +28c8 : d0fe > bne * ;failed not equal (non zero) + > + +28ca : ca dex +28cb : 10e0 bpl tasl8 +28cd : a203 ldx #3 +28cf : tasl9 + set_absx zp1,$ff + > load_flag $ff +28cf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +28d1 : 48 > pha ;use stack to load status +28d2 : b513 > lda zp1,x ;load to indexed memory +28d4 : 9d0302 > sta abst,x +28d7 : 28 > plp + +28d8 : 1e0302 asl abst,x + tst_absx rASL,fASL,$ff-fnzc +28db : 08 > php ;save flags +28dc : bd0302 > lda abst,x +28df : dd2002 > cmp rASL,x ;test result + > trap_ne +28e2 : d0fe > bne * ;failed not equal (non zero) + > +28e4 : 68 > pla ;load status + > eor_flag $ff-fnzc +28e5 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +28e7 : dd3002 > cmp fASL,x ;test flags + > trap_ne +28ea : d0fe > bne * ;failed not equal (non zero) + > + +28ec : ca dex +28ed : 10e0 bpl tasl9 + +28ef : a203 ldx #3 +28f1 : tlsr8 + set_absx zp1,0 + > load_flag 0 +28f1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +28f3 : 48 > pha ;use stack to load status +28f4 : b513 > lda zp1,x ;load to indexed memory +28f6 : 9d0302 > sta abst,x +28f9 : 28 > plp + +28fa : 5e0302 lsr abst,x + tst_absx rLSR,fLSR,0 +28fd : 08 > php ;save flags +28fe : bd0302 > lda abst,x +2901 : dd2802 > cmp rLSR,x ;test result + > trap_ne +2904 : d0fe > bne * ;failed not equal (non zero) + > +2906 : 68 > pla ;load status + > eor_flag 0 +2907 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2909 : dd3802 > cmp fLSR,x ;test flags + > trap_ne +290c : d0fe > bne * ;failed not equal (non zero) + > + +290e : ca dex +290f : 10e0 bpl tlsr8 +2911 : a203 ldx #3 +2913 : tlsr9 + set_absx zp1,$ff + > load_flag $ff +2913 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2915 : 48 > pha ;use stack to load status +2916 : b513 > lda zp1,x ;load to indexed memory +2918 : 9d0302 > sta abst,x +291b : 28 > plp + +291c : 5e0302 lsr abst,x + tst_absx rLSR,fLSR,$ff-fnzc +291f : 08 > php ;save flags +2920 : bd0302 > lda abst,x +2923 : dd2802 > cmp rLSR,x ;test result + > trap_ne +2926 : d0fe > bne * ;failed not equal (non zero) + > +2928 : 68 > pla ;load status + > eor_flag $ff-fnzc +2929 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +292b : dd3802 > cmp fLSR,x ;test flags + > trap_ne +292e : d0fe > bne * ;failed not equal (non zero) + > + +2930 : ca dex +2931 : 10e0 bpl tlsr9 + +2933 : a203 ldx #3 +2935 : trol8 + set_absx zp1,0 + > load_flag 0 +2935 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2937 : 48 > pha ;use stack to load status +2938 : b513 > lda zp1,x ;load to indexed memory +293a : 9d0302 > sta abst,x +293d : 28 > plp + +293e : 3e0302 rol abst,x + tst_absx rROL,fROL,0 +2941 : 08 > php ;save flags +2942 : bd0302 > lda abst,x +2945 : dd2002 > cmp rROL,x ;test result + > trap_ne +2948 : d0fe > bne * ;failed not equal (non zero) + > +294a : 68 > pla ;load status + > eor_flag 0 +294b : 4930 > eor #0|fao ;invert expected flags + always on bits + > +294d : dd3002 > cmp fROL,x ;test flags + > trap_ne +2950 : d0fe > bne * ;failed not equal (non zero) + > + +2952 : ca dex +2953 : 10e0 bpl trol8 +2955 : a203 ldx #3 +2957 : trol9 + set_absx zp1,$ff-fc + > load_flag $ff-fc +2957 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +2959 : 48 > pha ;use stack to load status +295a : b513 > lda zp1,x ;load to indexed memory +295c : 9d0302 > sta abst,x +295f : 28 > plp + +2960 : 3e0302 rol abst,x + tst_absx rROL,fROL,$ff-fnzc +2963 : 08 > php ;save flags +2964 : bd0302 > lda abst,x +2967 : dd2002 > cmp rROL,x ;test result + > trap_ne +296a : d0fe > bne * ;failed not equal (non zero) + > +296c : 68 > pla ;load status + > eor_flag $ff-fnzc +296d : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +296f : dd3002 > cmp fROL,x ;test flags + > trap_ne +2972 : d0fe > bne * ;failed not equal (non zero) + > + +2974 : ca dex +2975 : 10e0 bpl trol9 + +2977 : a203 ldx #3 +2979 : trolc8 + set_absx zp1,fc + > load_flag fc +2979 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +297b : 48 > pha ;use stack to load status +297c : b513 > lda zp1,x ;load to indexed memory +297e : 9d0302 > sta abst,x +2981 : 28 > plp + +2982 : 3e0302 rol abst,x + tst_absx rROLc,fROLc,0 +2985 : 08 > php ;save flags +2986 : bd0302 > lda abst,x +2989 : dd2402 > cmp rROLc,x ;test result + > trap_ne +298c : d0fe > bne * ;failed not equal (non zero) + > +298e : 68 > pla ;load status + > eor_flag 0 +298f : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2991 : dd3402 > cmp fROLc,x ;test flags + > trap_ne +2994 : d0fe > bne * ;failed not equal (non zero) + > + +2996 : ca dex +2997 : 10e0 bpl trolc8 +2999 : a203 ldx #3 +299b : trolc9 + set_absx zp1,$ff + > load_flag $ff +299b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +299d : 48 > pha ;use stack to load status +299e : b513 > lda zp1,x ;load to indexed memory +29a0 : 9d0302 > sta abst,x +29a3 : 28 > plp + +29a4 : 3e0302 rol abst,x + tst_absx rROLc,fROLc,$ff-fnzc +29a7 : 08 > php ;save flags +29a8 : bd0302 > lda abst,x +29ab : dd2402 > cmp rROLc,x ;test result + > trap_ne +29ae : d0fe > bne * ;failed not equal (non zero) + > +29b0 : 68 > pla ;load status + > eor_flag $ff-fnzc +29b1 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +29b3 : dd3402 > cmp fROLc,x ;test flags + > trap_ne +29b6 : d0fe > bne * ;failed not equal (non zero) + > + +29b8 : ca dex +29b9 : 10e0 bpl trolc9 + +29bb : a203 ldx #3 +29bd : tror8 + set_absx zp1,0 + > load_flag 0 +29bd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +29bf : 48 > pha ;use stack to load status +29c0 : b513 > lda zp1,x ;load to indexed memory +29c2 : 9d0302 > sta abst,x +29c5 : 28 > plp + +29c6 : 7e0302 ror abst,x + tst_absx rROR,fROR,0 +29c9 : 08 > php ;save flags +29ca : bd0302 > lda abst,x +29cd : dd2802 > cmp rROR,x ;test result + > trap_ne +29d0 : d0fe > bne * ;failed not equal (non zero) + > +29d2 : 68 > pla ;load status + > eor_flag 0 +29d3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +29d5 : dd3802 > cmp fROR,x ;test flags + > trap_ne +29d8 : d0fe > bne * ;failed not equal (non zero) + > + +29da : ca dex +29db : 10e0 bpl tror8 +29dd : a203 ldx #3 +29df : tror9 + set_absx zp1,$ff-fc + > load_flag $ff-fc +29df : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask) + > +29e1 : 48 > pha ;use stack to load status +29e2 : b513 > lda zp1,x ;load to indexed memory +29e4 : 9d0302 > sta abst,x +29e7 : 28 > plp + +29e8 : 7e0302 ror abst,x + tst_absx rROR,fROR,$ff-fnzc +29eb : 08 > php ;save flags +29ec : bd0302 > lda abst,x +29ef : dd2802 > cmp rROR,x ;test result + > trap_ne +29f2 : d0fe > bne * ;failed not equal (non zero) + > +29f4 : 68 > pla ;load status + > eor_flag $ff-fnzc +29f5 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +29f7 : dd3802 > cmp fROR,x ;test flags + > trap_ne +29fa : d0fe > bne * ;failed not equal (non zero) + > + +29fc : ca dex +29fd : 10e0 bpl tror9 + +29ff : a203 ldx #3 +2a01 : trorc8 + set_absx zp1,fc + > load_flag fc +2a01 : a901 > lda #fc ;allow test to change I-flag (no mask) + > +2a03 : 48 > pha ;use stack to load status +2a04 : b513 > lda zp1,x ;load to indexed memory +2a06 : 9d0302 > sta abst,x +2a09 : 28 > plp + +2a0a : 7e0302 ror abst,x + tst_absx rRORc,fRORc,0 +2a0d : 08 > php ;save flags +2a0e : bd0302 > lda abst,x +2a11 : dd2c02 > cmp rRORc,x ;test result + > trap_ne +2a14 : d0fe > bne * ;failed not equal (non zero) + > +2a16 : 68 > pla ;load status + > eor_flag 0 +2a17 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2a19 : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +2a1c : d0fe > bne * ;failed not equal (non zero) + > + +2a1e : ca dex +2a1f : 10e0 bpl trorc8 +2a21 : a203 ldx #3 +2a23 : trorc9 + set_absx zp1,$ff + > load_flag $ff +2a23 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2a25 : 48 > pha ;use stack to load status +2a26 : b513 > lda zp1,x ;load to indexed memory +2a28 : 9d0302 > sta abst,x +2a2b : 28 > plp + +2a2c : 7e0302 ror abst,x + tst_absx rRORc,fRORc,$ff-fnzc +2a2f : 08 > php ;save flags +2a30 : bd0302 > lda abst,x +2a33 : dd2c02 > cmp rRORc,x ;test result + > trap_ne +2a36 : d0fe > bne * ;failed not equal (non zero) + > +2a38 : 68 > pla ;load status + > eor_flag $ff-fnzc +2a39 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits + > +2a3b : dd3c02 > cmp fRORc,x ;test flags + > trap_ne +2a3e : d0fe > bne * ;failed not equal (non zero) + > + +2a40 : ca dex +2a41 : 10e0 bpl trorc9 + next_test +2a43 : ad0002 > lda test_case ;previous test +2a46 : c921 > cmp #test_num + > trap_ne ;test is out of sequence +2a48 : d0fe > bne * ;failed not equal (non zero) + > +0022 = >test_num = test_num + 1 +2a4a : a922 > lda #test_num ;*** next tests' number +2a4c : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing memory increment/decrement - INC DEC all addressing modes + ; zeropage +2a4f : a200 ldx #0 +2a51 : a97e lda #$7e +2a53 : 850c sta zpt +2a55 : tinc + set_stat 0 + > load_flag 0 +2a55 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2a57 : 48 > pha ;use stack to load status +2a58 : 28 > plp + +2a59 : e60c inc zpt + tst_z rINC,fINC,0 +2a5b : 08 > php ;save flags +2a5c : a50c > lda zpt +2a5e : dd4002 > cmp rINC,x ;test result + > trap_ne +2a61 : d0fe > bne * ;failed not equal (non zero) + > +2a63 : 68 > pla ;load status + > eor_flag 0 +2a64 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2a66 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2a69 : d0fe > bne * ;failed not equal (non zero) + > + +2a6b : e8 inx +2a6c : e002 cpx #2 +2a6e : d004 bne tinc1 +2a70 : a9fe lda #$fe +2a72 : 850c sta zpt +2a74 : e005 tinc1 cpx #5 +2a76 : d0dd bne tinc +2a78 : ca dex +2a79 : e60c inc zpt +2a7b : tdec + set_stat 0 + > load_flag 0 +2a7b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2a7d : 48 > pha ;use stack to load status +2a7e : 28 > plp + +2a7f : c60c dec zpt + tst_z rINC,fINC,0 +2a81 : 08 > php ;save flags +2a82 : a50c > lda zpt +2a84 : dd4002 > cmp rINC,x ;test result + > trap_ne +2a87 : d0fe > bne * ;failed not equal (non zero) + > +2a89 : 68 > pla ;load status + > eor_flag 0 +2a8a : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2a8c : dd4502 > cmp fINC,x ;test flags + > trap_ne +2a8f : d0fe > bne * ;failed not equal (non zero) + > + +2a91 : ca dex +2a92 : 300a bmi tdec1 +2a94 : e001 cpx #1 +2a96 : d0e3 bne tdec +2a98 : a981 lda #$81 +2a9a : 850c sta zpt +2a9c : d0dd bne tdec +2a9e : tdec1 +2a9e : a200 ldx #0 +2aa0 : a97e lda #$7e +2aa2 : 850c sta zpt +2aa4 : tinc10 + set_stat $ff + > load_flag $ff +2aa4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2aa6 : 48 > pha ;use stack to load status +2aa7 : 28 > plp + +2aa8 : e60c inc zpt + tst_z rINC,fINC,$ff-fnz +2aaa : 08 > php ;save flags +2aab : a50c > lda zpt +2aad : dd4002 > cmp rINC,x ;test result + > trap_ne +2ab0 : d0fe > bne * ;failed not equal (non zero) + > +2ab2 : 68 > pla ;load status + > eor_flag $ff-fnz +2ab3 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2ab5 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2ab8 : d0fe > bne * ;failed not equal (non zero) + > + +2aba : e8 inx +2abb : e002 cpx #2 +2abd : d004 bne tinc11 +2abf : a9fe lda #$fe +2ac1 : 850c sta zpt +2ac3 : e005 tinc11 cpx #5 +2ac5 : d0dd bne tinc10 +2ac7 : ca dex +2ac8 : e60c inc zpt +2aca : tdec10 + set_stat $ff + > load_flag $ff +2aca : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2acc : 48 > pha ;use stack to load status +2acd : 28 > plp + +2ace : c60c dec zpt + tst_z rINC,fINC,$ff-fnz +2ad0 : 08 > php ;save flags +2ad1 : a50c > lda zpt +2ad3 : dd4002 > cmp rINC,x ;test result + > trap_ne +2ad6 : d0fe > bne * ;failed not equal (non zero) + > +2ad8 : 68 > pla ;load status + > eor_flag $ff-fnz +2ad9 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2adb : dd4502 > cmp fINC,x ;test flags + > trap_ne +2ade : d0fe > bne * ;failed not equal (non zero) + > + +2ae0 : ca dex +2ae1 : 300a bmi tdec11 +2ae3 : e001 cpx #1 +2ae5 : d0e3 bne tdec10 +2ae7 : a981 lda #$81 +2ae9 : 850c sta zpt +2aeb : d0dd bne tdec10 +2aed : tdec11 + next_test +2aed : ad0002 > lda test_case ;previous test +2af0 : c922 > cmp #test_num + > trap_ne ;test is out of sequence +2af2 : d0fe > bne * ;failed not equal (non zero) + > +0023 = >test_num = test_num + 1 +2af4 : a923 > lda #test_num ;*** next tests' number +2af6 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; absolute memory +2af9 : a200 ldx #0 +2afb : a97e lda #$7e +2afd : 8d0302 sta abst +2b00 : tinc2 + set_stat 0 + > load_flag 0 +2b00 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2b02 : 48 > pha ;use stack to load status +2b03 : 28 > plp + +2b04 : ee0302 inc abst + tst_abs rINC,fINC,0 +2b07 : 08 > php ;save flags +2b08 : ad0302 > lda abst +2b0b : dd4002 > cmp rINC,x ;test result + > trap_ne +2b0e : d0fe > bne * ;failed not equal (non zero) + > +2b10 : 68 > pla ;load status + > eor_flag 0 +2b11 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2b13 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2b16 : d0fe > bne * ;failed not equal (non zero) + > + +2b18 : e8 inx +2b19 : e002 cpx #2 +2b1b : d005 bne tinc3 +2b1d : a9fe lda #$fe +2b1f : 8d0302 sta abst +2b22 : e005 tinc3 cpx #5 +2b24 : d0da bne tinc2 +2b26 : ca dex +2b27 : ee0302 inc abst +2b2a : tdec2 + set_stat 0 + > load_flag 0 +2b2a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2b2c : 48 > pha ;use stack to load status +2b2d : 28 > plp + +2b2e : ce0302 dec abst + tst_abs rINC,fINC,0 +2b31 : 08 > php ;save flags +2b32 : ad0302 > lda abst +2b35 : dd4002 > cmp rINC,x ;test result + > trap_ne +2b38 : d0fe > bne * ;failed not equal (non zero) + > +2b3a : 68 > pla ;load status + > eor_flag 0 +2b3b : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2b3d : dd4502 > cmp fINC,x ;test flags + > trap_ne +2b40 : d0fe > bne * ;failed not equal (non zero) + > + +2b42 : ca dex +2b43 : 300b bmi tdec3 +2b45 : e001 cpx #1 +2b47 : d0e1 bne tdec2 +2b49 : a981 lda #$81 +2b4b : 8d0302 sta abst +2b4e : d0da bne tdec2 +2b50 : tdec3 +2b50 : a200 ldx #0 +2b52 : a97e lda #$7e +2b54 : 8d0302 sta abst +2b57 : tinc12 + set_stat $ff + > load_flag $ff +2b57 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2b59 : 48 > pha ;use stack to load status +2b5a : 28 > plp + +2b5b : ee0302 inc abst + tst_abs rINC,fINC,$ff-fnz +2b5e : 08 > php ;save flags +2b5f : ad0302 > lda abst +2b62 : dd4002 > cmp rINC,x ;test result + > trap_ne +2b65 : d0fe > bne * ;failed not equal (non zero) + > +2b67 : 68 > pla ;load status + > eor_flag $ff-fnz +2b68 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2b6a : dd4502 > cmp fINC,x ;test flags + > trap_ne +2b6d : d0fe > bne * ;failed not equal (non zero) + > + +2b6f : e8 inx +2b70 : e002 cpx #2 +2b72 : d005 bne tinc13 +2b74 : a9fe lda #$fe +2b76 : 8d0302 sta abst +2b79 : e005 tinc13 cpx #5 +2b7b : d0da bne tinc12 +2b7d : ca dex +2b7e : ee0302 inc abst +2b81 : tdec12 + set_stat $ff + > load_flag $ff +2b81 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2b83 : 48 > pha ;use stack to load status +2b84 : 28 > plp + +2b85 : ce0302 dec abst + tst_abs rINC,fINC,$ff-fnz +2b88 : 08 > php ;save flags +2b89 : ad0302 > lda abst +2b8c : dd4002 > cmp rINC,x ;test result + > trap_ne +2b8f : d0fe > bne * ;failed not equal (non zero) + > +2b91 : 68 > pla ;load status + > eor_flag $ff-fnz +2b92 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2b94 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2b97 : d0fe > bne * ;failed not equal (non zero) + > + +2b99 : ca dex +2b9a : 300b bmi tdec13 +2b9c : e001 cpx #1 +2b9e : d0e1 bne tdec12 +2ba0 : a981 lda #$81 +2ba2 : 8d0302 sta abst +2ba5 : d0da bne tdec12 +2ba7 : tdec13 + next_test +2ba7 : ad0002 > lda test_case ;previous test +2baa : c923 > cmp #test_num + > trap_ne ;test is out of sequence +2bac : d0fe > bne * ;failed not equal (non zero) + > +0024 = >test_num = test_num + 1 +2bae : a924 > lda #test_num ;*** next tests' number +2bb0 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; zeropage indexed +2bb3 : a200 ldx #0 +2bb5 : a97e lda #$7e +2bb7 : 950c tinc4 sta zpt,x + set_stat 0 + > load_flag 0 +2bb9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2bbb : 48 > pha ;use stack to load status +2bbc : 28 > plp + +2bbd : f60c inc zpt,x + tst_zx rINC,fINC,0 +2bbf : 08 > php ;save flags +2bc0 : b50c > lda zpt,x +2bc2 : dd4002 > cmp rINC,x ;test result + > trap_ne +2bc5 : d0fe > bne * ;failed not equal (non zero) + > +2bc7 : 68 > pla ;load status + > eor_flag 0 +2bc8 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2bca : dd4502 > cmp fINC,x ;test flags + > trap_ne +2bcd : d0fe > bne * ;failed not equal (non zero) + > + +2bcf : b50c lda zpt,x +2bd1 : e8 inx +2bd2 : e002 cpx #2 +2bd4 : d002 bne tinc5 +2bd6 : a9fe lda #$fe +2bd8 : e005 tinc5 cpx #5 +2bda : d0db bne tinc4 +2bdc : ca dex +2bdd : a902 lda #2 +2bdf : 950c tdec4 sta zpt,x + set_stat 0 + > load_flag 0 +2be1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2be3 : 48 > pha ;use stack to load status +2be4 : 28 > plp + +2be5 : d60c dec zpt,x + tst_zx rINC,fINC,0 +2be7 : 08 > php ;save flags +2be8 : b50c > lda zpt,x +2bea : dd4002 > cmp rINC,x ;test result + > trap_ne +2bed : d0fe > bne * ;failed not equal (non zero) + > +2bef : 68 > pla ;load status + > eor_flag 0 +2bf0 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2bf2 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2bf5 : d0fe > bne * ;failed not equal (non zero) + > + +2bf7 : b50c lda zpt,x +2bf9 : ca dex +2bfa : 3008 bmi tdec5 +2bfc : e001 cpx #1 +2bfe : d0df bne tdec4 +2c00 : a981 lda #$81 +2c02 : d0db bne tdec4 +2c04 : tdec5 +2c04 : a200 ldx #0 +2c06 : a97e lda #$7e +2c08 : 950c tinc14 sta zpt,x + set_stat $ff + > load_flag $ff +2c0a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2c0c : 48 > pha ;use stack to load status +2c0d : 28 > plp + +2c0e : f60c inc zpt,x + tst_zx rINC,fINC,$ff-fnz +2c10 : 08 > php ;save flags +2c11 : b50c > lda zpt,x +2c13 : dd4002 > cmp rINC,x ;test result + > trap_ne +2c16 : d0fe > bne * ;failed not equal (non zero) + > +2c18 : 68 > pla ;load status + > eor_flag $ff-fnz +2c19 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2c1b : dd4502 > cmp fINC,x ;test flags + > trap_ne +2c1e : d0fe > bne * ;failed not equal (non zero) + > + +2c20 : b50c lda zpt,x +2c22 : e8 inx +2c23 : e002 cpx #2 +2c25 : d002 bne tinc15 +2c27 : a9fe lda #$fe +2c29 : e005 tinc15 cpx #5 +2c2b : d0db bne tinc14 +2c2d : ca dex +2c2e : a902 lda #2 +2c30 : 950c tdec14 sta zpt,x + set_stat $ff + > load_flag $ff +2c32 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2c34 : 48 > pha ;use stack to load status +2c35 : 28 > plp + +2c36 : d60c dec zpt,x + tst_zx rINC,fINC,$ff-fnz +2c38 : 08 > php ;save flags +2c39 : b50c > lda zpt,x +2c3b : dd4002 > cmp rINC,x ;test result + > trap_ne +2c3e : d0fe > bne * ;failed not equal (non zero) + > +2c40 : 68 > pla ;load status + > eor_flag $ff-fnz +2c41 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2c43 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2c46 : d0fe > bne * ;failed not equal (non zero) + > + +2c48 : b50c lda zpt,x +2c4a : ca dex +2c4b : 3008 bmi tdec15 +2c4d : e001 cpx #1 +2c4f : d0df bne tdec14 +2c51 : a981 lda #$81 +2c53 : d0db bne tdec14 +2c55 : tdec15 + next_test +2c55 : ad0002 > lda test_case ;previous test +2c58 : c924 > cmp #test_num + > trap_ne ;test is out of sequence +2c5a : d0fe > bne * ;failed not equal (non zero) + > +0025 = >test_num = test_num + 1 +2c5c : a925 > lda #test_num ;*** next tests' number +2c5e : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; memory indexed +2c61 : a200 ldx #0 +2c63 : a97e lda #$7e +2c65 : 9d0302 tinc6 sta abst,x + set_stat 0 + > load_flag 0 +2c68 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2c6a : 48 > pha ;use stack to load status +2c6b : 28 > plp + +2c6c : fe0302 inc abst,x + tst_absx rINC,fINC,0 +2c6f : 08 > php ;save flags +2c70 : bd0302 > lda abst,x +2c73 : dd4002 > cmp rINC,x ;test result + > trap_ne +2c76 : d0fe > bne * ;failed not equal (non zero) + > +2c78 : 68 > pla ;load status + > eor_flag 0 +2c79 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2c7b : dd4502 > cmp fINC,x ;test flags + > trap_ne +2c7e : d0fe > bne * ;failed not equal (non zero) + > + +2c80 : bd0302 lda abst,x +2c83 : e8 inx +2c84 : e002 cpx #2 +2c86 : d002 bne tinc7 +2c88 : a9fe lda #$fe +2c8a : e005 tinc7 cpx #5 +2c8c : d0d7 bne tinc6 +2c8e : ca dex +2c8f : a902 lda #2 +2c91 : 9d0302 tdec6 sta abst,x + set_stat 0 + > load_flag 0 +2c94 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2c96 : 48 > pha ;use stack to load status +2c97 : 28 > plp + +2c98 : de0302 dec abst,x + tst_absx rINC,fINC,0 +2c9b : 08 > php ;save flags +2c9c : bd0302 > lda abst,x +2c9f : dd4002 > cmp rINC,x ;test result + > trap_ne +2ca2 : d0fe > bne * ;failed not equal (non zero) + > +2ca4 : 68 > pla ;load status + > eor_flag 0 +2ca5 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2ca7 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2caa : d0fe > bne * ;failed not equal (non zero) + > + +2cac : bd0302 lda abst,x +2caf : ca dex +2cb0 : 3008 bmi tdec7 +2cb2 : e001 cpx #1 +2cb4 : d0db bne tdec6 +2cb6 : a981 lda #$81 +2cb8 : d0d7 bne tdec6 +2cba : tdec7 +2cba : a200 ldx #0 +2cbc : a97e lda #$7e +2cbe : 9d0302 tinc16 sta abst,x + set_stat $ff + > load_flag $ff +2cc1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2cc3 : 48 > pha ;use stack to load status +2cc4 : 28 > plp + +2cc5 : fe0302 inc abst,x + tst_absx rINC,fINC,$ff-fnz +2cc8 : 08 > php ;save flags +2cc9 : bd0302 > lda abst,x +2ccc : dd4002 > cmp rINC,x ;test result + > trap_ne +2ccf : d0fe > bne * ;failed not equal (non zero) + > +2cd1 : 68 > pla ;load status + > eor_flag $ff-fnz +2cd2 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2cd4 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2cd7 : d0fe > bne * ;failed not equal (non zero) + > + +2cd9 : bd0302 lda abst,x +2cdc : e8 inx +2cdd : e002 cpx #2 +2cdf : d002 bne tinc17 +2ce1 : a9fe lda #$fe +2ce3 : e005 tinc17 cpx #5 +2ce5 : d0d7 bne tinc16 +2ce7 : ca dex +2ce8 : a902 lda #2 +2cea : 9d0302 tdec16 sta abst,x + set_stat $ff + > load_flag $ff +2ced : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2cef : 48 > pha ;use stack to load status +2cf0 : 28 > plp + +2cf1 : de0302 dec abst,x + tst_absx rINC,fINC,$ff-fnz +2cf4 : 08 > php ;save flags +2cf5 : bd0302 > lda abst,x +2cf8 : dd4002 > cmp rINC,x ;test result + > trap_ne +2cfb : d0fe > bne * ;failed not equal (non zero) + > +2cfd : 68 > pla ;load status + > eor_flag $ff-fnz +2cfe : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2d00 : dd4502 > cmp fINC,x ;test flags + > trap_ne +2d03 : d0fe > bne * ;failed not equal (non zero) + > + +2d05 : bd0302 lda abst,x +2d08 : ca dex +2d09 : 3008 bmi tdec17 +2d0b : e001 cpx #1 +2d0d : d0db bne tdec16 +2d0f : a981 lda #$81 +2d11 : d0d7 bne tdec16 +2d13 : tdec17 + next_test +2d13 : ad0002 > lda test_case ;previous test +2d16 : c925 > cmp #test_num + > trap_ne ;test is out of sequence +2d18 : d0fe > bne * ;failed not equal (non zero) + > +0026 = >test_num = test_num + 1 +2d1a : a926 > lda #test_num ;*** next tests' number +2d1c : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing logical instructions - AND EOR ORA all addressing modes + ; AND +2d1f : a203 ldx #3 ;immediate +2d21 : b51c tand lda zpAN,x +2d23 : 8d0902 sta ex_andi+1 ;set AND # operand + set_ax absANa,0 + > load_flag 0 +2d26 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2d28 : 48 > pha ;use stack to load status +2d29 : bd5a02 > lda absANa,x ;precharge accu +2d2c : 28 > plp + +2d2d : 200802 jsr ex_andi ;execute AND # in RAM + tst_ax absrlo,absflo,0 +2d30 : 08 > php ;save flags +2d31 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2d34 : d0fe > bne * ;failed not equal (non zero) + > +2d36 : 68 > pla ;load status + > eor_flag 0 +2d37 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2d39 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2d3c : d0fe > bne * ;failed not equal (non zero) + > + +2d3e : ca dex +2d3f : 10e0 bpl tand +2d41 : a203 ldx #3 +2d43 : b51c tand1 lda zpAN,x +2d45 : 8d0902 sta ex_andi+1 ;set AND # operand + set_ax absANa,$ff + > load_flag $ff +2d48 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2d4a : 48 > pha ;use stack to load status +2d4b : bd5a02 > lda absANa,x ;precharge accu +2d4e : 28 > plp + +2d4f : 200802 jsr ex_andi ;execute AND # in RAM + tst_ax absrlo,absflo,$ff-fnz +2d52 : 08 > php ;save flags +2d53 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2d56 : d0fe > bne * ;failed not equal (non zero) + > +2d58 : 68 > pla ;load status + > eor_flag $ff-fnz +2d59 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2d5b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2d5e : d0fe > bne * ;failed not equal (non zero) + > + +2d60 : ca dex +2d61 : 10e0 bpl tand1 + +2d63 : a203 ldx #3 ;zp +2d65 : b51c tand2 lda zpAN,x +2d67 : 850c sta zpt + set_ax absANa,0 + > load_flag 0 +2d69 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2d6b : 48 > pha ;use stack to load status +2d6c : bd5a02 > lda absANa,x ;precharge accu +2d6f : 28 > plp + +2d70 : 250c and zpt + tst_ax absrlo,absflo,0 +2d72 : 08 > php ;save flags +2d73 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2d76 : d0fe > bne * ;failed not equal (non zero) + > +2d78 : 68 > pla ;load status + > eor_flag 0 +2d79 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2d7b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2d7e : d0fe > bne * ;failed not equal (non zero) + > + +2d80 : ca dex +2d81 : 10e2 bpl tand2 +2d83 : a203 ldx #3 +2d85 : b51c tand3 lda zpAN,x +2d87 : 850c sta zpt + set_ax absANa,$ff + > load_flag $ff +2d89 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2d8b : 48 > pha ;use stack to load status +2d8c : bd5a02 > lda absANa,x ;precharge accu +2d8f : 28 > plp + +2d90 : 250c and zpt + tst_ax absrlo,absflo,$ff-fnz +2d92 : 08 > php ;save flags +2d93 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2d96 : d0fe > bne * ;failed not equal (non zero) + > +2d98 : 68 > pla ;load status + > eor_flag $ff-fnz +2d99 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2d9b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2d9e : d0fe > bne * ;failed not equal (non zero) + > + +2da0 : ca dex +2da1 : 10e2 bpl tand3 + +2da3 : a203 ldx #3 ;abs +2da5 : b51c tand4 lda zpAN,x +2da7 : 8d0302 sta abst + set_ax absANa,0 + > load_flag 0 +2daa : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2dac : 48 > pha ;use stack to load status +2dad : bd5a02 > lda absANa,x ;precharge accu +2db0 : 28 > plp + +2db1 : 2d0302 and abst + tst_ax absrlo,absflo,0 +2db4 : 08 > php ;save flags +2db5 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2db8 : d0fe > bne * ;failed not equal (non zero) + > +2dba : 68 > pla ;load status + > eor_flag 0 +2dbb : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2dbd : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2dc0 : d0fe > bne * ;failed not equal (non zero) + > + +2dc2 : ca dex +2dc3 : 10e0 bpl tand4 +2dc5 : a203 ldx #3 +2dc7 : b51c tand5 lda zpAN,x +2dc9 : 8d0302 sta abst + set_ax absANa,$ff + > load_flag $ff +2dcc : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2dce : 48 > pha ;use stack to load status +2dcf : bd5a02 > lda absANa,x ;precharge accu +2dd2 : 28 > plp + +2dd3 : 2d0302 and abst + tst_ax absrlo,absflo,$ff-fnz +2dd6 : 08 > php ;save flags +2dd7 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2dda : d0fe > bne * ;failed not equal (non zero) + > +2ddc : 68 > pla ;load status + > eor_flag $ff-fnz +2ddd : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2ddf : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2de2 : d0fe > bne * ;failed not equal (non zero) + > + +2de4 : ca dex +2de5 : 1002 bpl tand6 + +2de7 : a203 ldx #3 ;zp,x +2de9 : tand6 + set_ax absANa,0 + > load_flag 0 +2de9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2deb : 48 > pha ;use stack to load status +2dec : bd5a02 > lda absANa,x ;precharge accu +2def : 28 > plp + +2df0 : 351c and zpAN,x + tst_ax absrlo,absflo,0 +2df2 : 08 > php ;save flags +2df3 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2df6 : d0fe > bne * ;failed not equal (non zero) + > +2df8 : 68 > pla ;load status + > eor_flag 0 +2df9 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2dfb : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2dfe : d0fe > bne * ;failed not equal (non zero) + > + +2e00 : ca dex +2e01 : 10e6 bpl tand6 +2e03 : a203 ldx #3 +2e05 : tand7 + set_ax absANa,$ff + > load_flag $ff +2e05 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2e07 : 48 > pha ;use stack to load status +2e08 : bd5a02 > lda absANa,x ;precharge accu +2e0b : 28 > plp + +2e0c : 351c and zpAN,x + tst_ax absrlo,absflo,$ff-fnz +2e0e : 08 > php ;save flags +2e0f : dd6202 > cmp absrlo,x ;test result + > trap_ne +2e12 : d0fe > bne * ;failed not equal (non zero) + > +2e14 : 68 > pla ;load status + > eor_flag $ff-fnz +2e15 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2e17 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2e1a : d0fe > bne * ;failed not equal (non zero) + > + +2e1c : ca dex +2e1d : 10e6 bpl tand7 + +2e1f : a203 ldx #3 ;abs,x +2e21 : tand8 + set_ax absANa,0 + > load_flag 0 +2e21 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2e23 : 48 > pha ;use stack to load status +2e24 : bd5a02 > lda absANa,x ;precharge accu +2e27 : 28 > plp + +2e28 : 3d4e02 and absAN,x + tst_ax absrlo,absflo,0 +2e2b : 08 > php ;save flags +2e2c : dd6202 > cmp absrlo,x ;test result + > trap_ne +2e2f : d0fe > bne * ;failed not equal (non zero) + > +2e31 : 68 > pla ;load status + > eor_flag 0 +2e32 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2e34 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2e37 : d0fe > bne * ;failed not equal (non zero) + > + +2e39 : ca dex +2e3a : 10e5 bpl tand8 +2e3c : a203 ldx #3 +2e3e : tand9 + set_ax absANa,$ff + > load_flag $ff +2e3e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2e40 : 48 > pha ;use stack to load status +2e41 : bd5a02 > lda absANa,x ;precharge accu +2e44 : 28 > plp + +2e45 : 3d4e02 and absAN,x + tst_ax absrlo,absflo,$ff-fnz +2e48 : 08 > php ;save flags +2e49 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2e4c : d0fe > bne * ;failed not equal (non zero) + > +2e4e : 68 > pla ;load status + > eor_flag $ff-fnz +2e4f : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2e51 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2e54 : d0fe > bne * ;failed not equal (non zero) + > + +2e56 : ca dex +2e57 : 10e5 bpl tand9 + +2e59 : a003 ldy #3 ;abs,y +2e5b : tand10 + set_ay absANa,0 + > load_flag 0 +2e5b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2e5d : 48 > pha ;use stack to load status +2e5e : b95a02 > lda absANa,y ;precharge accu +2e61 : 28 > plp + +2e62 : 394e02 and absAN,y + tst_ay absrlo,absflo,0 +2e65 : 08 > php ;save flags +2e66 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2e69 : d0fe > bne * ;failed not equal (non zero) + > +2e6b : 68 > pla ;load status + > eor_flag 0 +2e6c : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2e6e : d96602 > cmp absflo,y ;test flags + > trap_ne +2e71 : d0fe > bne * ;failed not equal (non zero) + > + +2e73 : 88 dey +2e74 : 10e5 bpl tand10 +2e76 : a003 ldy #3 +2e78 : tand11 + set_ay absANa,$ff + > load_flag $ff +2e78 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2e7a : 48 > pha ;use stack to load status +2e7b : b95a02 > lda absANa,y ;precharge accu +2e7e : 28 > plp + +2e7f : 394e02 and absAN,y + tst_ay absrlo,absflo,$ff-fnz +2e82 : 08 > php ;save flags +2e83 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2e86 : d0fe > bne * ;failed not equal (non zero) + > +2e88 : 68 > pla ;load status + > eor_flag $ff-fnz +2e89 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2e8b : d96602 > cmp absflo,y ;test flags + > trap_ne +2e8e : d0fe > bne * ;failed not equal (non zero) + > + +2e90 : 88 dey +2e91 : 10e5 bpl tand11 + +2e93 : a206 ldx #6 ;(zp,x) +2e95 : a003 ldy #3 +2e97 : tand12 + set_ay absANa,0 + > load_flag 0 +2e97 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2e99 : 48 > pha ;use stack to load status +2e9a : b95a02 > lda absANa,y ;precharge accu +2e9d : 28 > plp + +2e9e : 213a and (indAN,x) + tst_ay absrlo,absflo,0 +2ea0 : 08 > php ;save flags +2ea1 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2ea4 : d0fe > bne * ;failed not equal (non zero) + > +2ea6 : 68 > pla ;load status + > eor_flag 0 +2ea7 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2ea9 : d96602 > cmp absflo,y ;test flags + > trap_ne +2eac : d0fe > bne * ;failed not equal (non zero) + > + +2eae : ca dex +2eaf : ca dex +2eb0 : 88 dey +2eb1 : 10e4 bpl tand12 +2eb3 : a206 ldx #6 +2eb5 : a003 ldy #3 +2eb7 : tand13 + set_ay absANa,$ff + > load_flag $ff +2eb7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2eb9 : 48 > pha ;use stack to load status +2eba : b95a02 > lda absANa,y ;precharge accu +2ebd : 28 > plp + +2ebe : 213a and (indAN,x) + tst_ay absrlo,absflo,$ff-fnz +2ec0 : 08 > php ;save flags +2ec1 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2ec4 : d0fe > bne * ;failed not equal (non zero) + > +2ec6 : 68 > pla ;load status + > eor_flag $ff-fnz +2ec7 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2ec9 : d96602 > cmp absflo,y ;test flags + > trap_ne +2ecc : d0fe > bne * ;failed not equal (non zero) + > + +2ece : ca dex +2ecf : ca dex +2ed0 : 88 dey +2ed1 : 10e4 bpl tand13 + +2ed3 : a003 ldy #3 ;(zp),y +2ed5 : tand14 + set_ay absANa,0 + > load_flag 0 +2ed5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2ed7 : 48 > pha ;use stack to load status +2ed8 : b95a02 > lda absANa,y ;precharge accu +2edb : 28 > plp + +2edc : 313a and (indAN),y + tst_ay absrlo,absflo,0 +2ede : 08 > php ;save flags +2edf : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2ee2 : d0fe > bne * ;failed not equal (non zero) + > +2ee4 : 68 > pla ;load status + > eor_flag 0 +2ee5 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2ee7 : d96602 > cmp absflo,y ;test flags + > trap_ne +2eea : d0fe > bne * ;failed not equal (non zero) + > + +2eec : 88 dey +2eed : 10e6 bpl tand14 +2eef : a003 ldy #3 +2ef1 : tand15 + set_ay absANa,$ff + > load_flag $ff +2ef1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2ef3 : 48 > pha ;use stack to load status +2ef4 : b95a02 > lda absANa,y ;precharge accu +2ef7 : 28 > plp + +2ef8 : 313a and (indAN),y + tst_ay absrlo,absflo,$ff-fnz +2efa : 08 > php ;save flags +2efb : d96202 > cmp absrlo,y ;test result + > trap_ne ; +2efe : d0fe > bne * ;failed not equal (non zero) + > +2f00 : 68 > pla ;load status + > eor_flag $ff-fnz +2f01 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2f03 : d96602 > cmp absflo,y ;test flags + > trap_ne +2f06 : d0fe > bne * ;failed not equal (non zero) + > + +2f08 : 88 dey +2f09 : 10e6 bpl tand15 + next_test +2f0b : ad0002 > lda test_case ;previous test +2f0e : c926 > cmp #test_num + > trap_ne ;test is out of sequence +2f10 : d0fe > bne * ;failed not equal (non zero) + > +0027 = >test_num = test_num + 1 +2f12 : a927 > lda #test_num ;*** next tests' number +2f14 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; EOR +2f17 : a203 ldx #3 ;immediate - self modifying code +2f19 : b520 teor lda zpEO,x +2f1b : 8d0c02 sta ex_eori+1 ;set EOR # operand + set_ax absEOa,0 + > load_flag 0 +2f1e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2f20 : 48 > pha ;use stack to load status +2f21 : bd5e02 > lda absEOa,x ;precharge accu +2f24 : 28 > plp + +2f25 : 200b02 jsr ex_eori ;execute EOR # in RAM + tst_ax absrlo,absflo,0 +2f28 : 08 > php ;save flags +2f29 : dd6202 > cmp absrlo,x ;test result + > trap_ne +2f2c : d0fe > bne * ;failed not equal (non zero) + > +2f2e : 68 > pla ;load status + > eor_flag 0 +2f2f : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2f31 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2f34 : d0fe > bne * ;failed not equal (non zero) + > + +2f36 : ca dex +2f37 : 10e0 bpl teor +2f39 : a203 ldx #3 +2f3b : b520 teor1 lda zpEO,x +2f3d : 8d0c02 sta ex_eori+1 ;set EOR # operand + set_ax absEOa,$ff + > load_flag $ff +2f40 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2f42 : 48 > pha ;use stack to load status +2f43 : bd5e02 > lda absEOa,x ;precharge accu +2f46 : 28 > plp + +2f47 : 200b02 jsr ex_eori ;execute EOR # in RAM + tst_ax absrlo,absflo,$ff-fnz +2f4a : 08 > php ;save flags +2f4b : dd6202 > cmp absrlo,x ;test result + > trap_ne +2f4e : d0fe > bne * ;failed not equal (non zero) + > +2f50 : 68 > pla ;load status + > eor_flag $ff-fnz +2f51 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2f53 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2f56 : d0fe > bne * ;failed not equal (non zero) + > + +2f58 : ca dex +2f59 : 10e0 bpl teor1 + +2f5b : a203 ldx #3 ;zp +2f5d : b520 teor2 lda zpEO,x +2f5f : 850c sta zpt + set_ax absEOa,0 + > load_flag 0 +2f61 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2f63 : 48 > pha ;use stack to load status +2f64 : bd5e02 > lda absEOa,x ;precharge accu +2f67 : 28 > plp + +2f68 : 450c eor zpt + tst_ax absrlo,absflo,0 +2f6a : 08 > php ;save flags +2f6b : dd6202 > cmp absrlo,x ;test result + > trap_ne +2f6e : d0fe > bne * ;failed not equal (non zero) + > +2f70 : 68 > pla ;load status + > eor_flag 0 +2f71 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2f73 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2f76 : d0fe > bne * ;failed not equal (non zero) + > + +2f78 : ca dex +2f79 : 10e2 bpl teor2 +2f7b : a203 ldx #3 +2f7d : b520 teor3 lda zpEO,x +2f7f : 850c sta zpt + set_ax absEOa,$ff + > load_flag $ff +2f81 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2f83 : 48 > pha ;use stack to load status +2f84 : bd5e02 > lda absEOa,x ;precharge accu +2f87 : 28 > plp + +2f88 : 450c eor zpt + tst_ax absrlo,absflo,$ff-fnz +2f8a : 08 > php ;save flags +2f8b : dd6202 > cmp absrlo,x ;test result + > trap_ne +2f8e : d0fe > bne * ;failed not equal (non zero) + > +2f90 : 68 > pla ;load status + > eor_flag $ff-fnz +2f91 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2f93 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2f96 : d0fe > bne * ;failed not equal (non zero) + > + +2f98 : ca dex +2f99 : 10e2 bpl teor3 + +2f9b : a203 ldx #3 ;abs +2f9d : b520 teor4 lda zpEO,x +2f9f : 8d0302 sta abst + set_ax absEOa,0 + > load_flag 0 +2fa2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2fa4 : 48 > pha ;use stack to load status +2fa5 : bd5e02 > lda absEOa,x ;precharge accu +2fa8 : 28 > plp + +2fa9 : 4d0302 eor abst + tst_ax absrlo,absflo,0 +2fac : 08 > php ;save flags +2fad : dd6202 > cmp absrlo,x ;test result + > trap_ne +2fb0 : d0fe > bne * ;failed not equal (non zero) + > +2fb2 : 68 > pla ;load status + > eor_flag 0 +2fb3 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2fb5 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2fb8 : d0fe > bne * ;failed not equal (non zero) + > + +2fba : ca dex +2fbb : 10e0 bpl teor4 +2fbd : a203 ldx #3 +2fbf : b520 teor5 lda zpEO,x +2fc1 : 8d0302 sta abst + set_ax absEOa,$ff + > load_flag $ff +2fc4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2fc6 : 48 > pha ;use stack to load status +2fc7 : bd5e02 > lda absEOa,x ;precharge accu +2fca : 28 > plp + +2fcb : 4d0302 eor abst + tst_ax absrlo,absflo,$ff-fnz +2fce : 08 > php ;save flags +2fcf : dd6202 > cmp absrlo,x ;test result + > trap_ne +2fd2 : d0fe > bne * ;failed not equal (non zero) + > +2fd4 : 68 > pla ;load status + > eor_flag $ff-fnz +2fd5 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2fd7 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2fda : d0fe > bne * ;failed not equal (non zero) + > + +2fdc : ca dex +2fdd : 1002 bpl teor6 + +2fdf : a203 ldx #3 ;zp,x +2fe1 : teor6 + set_ax absEOa,0 + > load_flag 0 +2fe1 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2fe3 : 48 > pha ;use stack to load status +2fe4 : bd5e02 > lda absEOa,x ;precharge accu +2fe7 : 28 > plp + +2fe8 : 5520 eor zpEO,x + tst_ax absrlo,absflo,0 +2fea : 08 > php ;save flags +2feb : dd6202 > cmp absrlo,x ;test result + > trap_ne +2fee : d0fe > bne * ;failed not equal (non zero) + > +2ff0 : 68 > pla ;load status + > eor_flag 0 +2ff1 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2ff3 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +2ff6 : d0fe > bne * ;failed not equal (non zero) + > + +2ff8 : ca dex +2ff9 : 10e6 bpl teor6 +2ffb : a203 ldx #3 +2ffd : teor7 + set_ax absEOa,$ff + > load_flag $ff +2ffd : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2fff : 48 > pha ;use stack to load status +3000 : bd5e02 > lda absEOa,x ;precharge accu +3003 : 28 > plp + +3004 : 5520 eor zpEO,x + tst_ax absrlo,absflo,$ff-fnz +3006 : 08 > php ;save flags +3007 : dd6202 > cmp absrlo,x ;test result + > trap_ne +300a : d0fe > bne * ;failed not equal (non zero) + > +300c : 68 > pla ;load status + > eor_flag $ff-fnz +300d : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +300f : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +3012 : d0fe > bne * ;failed not equal (non zero) + > + +3014 : ca dex +3015 : 10e6 bpl teor7 + +3017 : a203 ldx #3 ;abs,x +3019 : teor8 + set_ax absEOa,0 + > load_flag 0 +3019 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +301b : 48 > pha ;use stack to load status +301c : bd5e02 > lda absEOa,x ;precharge accu +301f : 28 > plp + +3020 : 5d5202 eor absEO,x + tst_ax absrlo,absflo,0 +3023 : 08 > php ;save flags +3024 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3027 : d0fe > bne * ;failed not equal (non zero) + > +3029 : 68 > pla ;load status + > eor_flag 0 +302a : 4930 > eor #0|fao ;invert expected flags + always on bits + > +302c : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +302f : d0fe > bne * ;failed not equal (non zero) + > + +3031 : ca dex +3032 : 10e5 bpl teor8 +3034 : a203 ldx #3 +3036 : teor9 + set_ax absEOa,$ff + > load_flag $ff +3036 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +3038 : 48 > pha ;use stack to load status +3039 : bd5e02 > lda absEOa,x ;precharge accu +303c : 28 > plp + +303d : 5d5202 eor absEO,x + tst_ax absrlo,absflo,$ff-fnz +3040 : 08 > php ;save flags +3041 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3044 : d0fe > bne * ;failed not equal (non zero) + > +3046 : 68 > pla ;load status + > eor_flag $ff-fnz +3047 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +3049 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +304c : d0fe > bne * ;failed not equal (non zero) + > + +304e : ca dex +304f : 10e5 bpl teor9 + +3051 : a003 ldy #3 ;abs,y +3053 : teor10 + set_ay absEOa,0 + > load_flag 0 +3053 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +3055 : 48 > pha ;use stack to load status +3056 : b95e02 > lda absEOa,y ;precharge accu +3059 : 28 > plp + +305a : 595202 eor absEO,y + tst_ay absrlo,absflo,0 +305d : 08 > php ;save flags +305e : d96202 > cmp absrlo,y ;test result + > trap_ne ; +3061 : d0fe > bne * ;failed not equal (non zero) + > +3063 : 68 > pla ;load status + > eor_flag 0 +3064 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +3066 : d96602 > cmp absflo,y ;test flags + > trap_ne +3069 : d0fe > bne * ;failed not equal (non zero) + > + +306b : 88 dey +306c : 10e5 bpl teor10 +306e : a003 ldy #3 +3070 : teor11 + set_ay absEOa,$ff + > load_flag $ff +3070 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +3072 : 48 > pha ;use stack to load status +3073 : b95e02 > lda absEOa,y ;precharge accu +3076 : 28 > plp + +3077 : 595202 eor absEO,y + tst_ay absrlo,absflo,$ff-fnz +307a : 08 > php ;save flags +307b : d96202 > cmp absrlo,y ;test result + > trap_ne ; +307e : d0fe > bne * ;failed not equal (non zero) + > +3080 : 68 > pla ;load status + > eor_flag $ff-fnz +3081 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +3083 : d96602 > cmp absflo,y ;test flags + > trap_ne +3086 : d0fe > bne * ;failed not equal (non zero) + > + +3088 : 88 dey +3089 : 10e5 bpl teor11 + +308b : a206 ldx #6 ;(zp,x) +308d : a003 ldy #3 +308f : teor12 + set_ay absEOa,0 + > load_flag 0 +308f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +3091 : 48 > pha ;use stack to load status +3092 : b95e02 > lda absEOa,y ;precharge accu +3095 : 28 > plp + +3096 : 4142 eor (indEO,x) + tst_ay absrlo,absflo,0 +3098 : 08 > php ;save flags +3099 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +309c : d0fe > bne * ;failed not equal (non zero) + > +309e : 68 > pla ;load status + > eor_flag 0 +309f : 4930 > eor #0|fao ;invert expected flags + always on bits + > +30a1 : d96602 > cmp absflo,y ;test flags + > trap_ne +30a4 : d0fe > bne * ;failed not equal (non zero) + > + +30a6 : ca dex +30a7 : ca dex +30a8 : 88 dey +30a9 : 10e4 bpl teor12 +30ab : a206 ldx #6 +30ad : a003 ldy #3 +30af : teor13 + set_ay absEOa,$ff + > load_flag $ff +30af : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +30b1 : 48 > pha ;use stack to load status +30b2 : b95e02 > lda absEOa,y ;precharge accu +30b5 : 28 > plp + +30b6 : 4142 eor (indEO,x) + tst_ay absrlo,absflo,$ff-fnz +30b8 : 08 > php ;save flags +30b9 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +30bc : d0fe > bne * ;failed not equal (non zero) + > +30be : 68 > pla ;load status + > eor_flag $ff-fnz +30bf : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +30c1 : d96602 > cmp absflo,y ;test flags + > trap_ne +30c4 : d0fe > bne * ;failed not equal (non zero) + > + +30c6 : ca dex +30c7 : ca dex +30c8 : 88 dey +30c9 : 10e4 bpl teor13 + +30cb : a003 ldy #3 ;(zp),y +30cd : teor14 + set_ay absEOa,0 + > load_flag 0 +30cd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +30cf : 48 > pha ;use stack to load status +30d0 : b95e02 > lda absEOa,y ;precharge accu +30d3 : 28 > plp + +30d4 : 5142 eor (indEO),y + tst_ay absrlo,absflo,0 +30d6 : 08 > php ;save flags +30d7 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +30da : d0fe > bne * ;failed not equal (non zero) + > +30dc : 68 > pla ;load status + > eor_flag 0 +30dd : 4930 > eor #0|fao ;invert expected flags + always on bits + > +30df : d96602 > cmp absflo,y ;test flags + > trap_ne +30e2 : d0fe > bne * ;failed not equal (non zero) + > + +30e4 : 88 dey +30e5 : 10e6 bpl teor14 +30e7 : a003 ldy #3 +30e9 : teor15 + set_ay absEOa,$ff + > load_flag $ff +30e9 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +30eb : 48 > pha ;use stack to load status +30ec : b95e02 > lda absEOa,y ;precharge accu +30ef : 28 > plp + +30f0 : 5142 eor (indEO),y + tst_ay absrlo,absflo,$ff-fnz +30f2 : 08 > php ;save flags +30f3 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +30f6 : d0fe > bne * ;failed not equal (non zero) + > +30f8 : 68 > pla ;load status + > eor_flag $ff-fnz +30f9 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +30fb : d96602 > cmp absflo,y ;test flags + > trap_ne +30fe : d0fe > bne * ;failed not equal (non zero) + > + +3100 : 88 dey +3101 : 10e6 bpl teor15 + next_test +3103 : ad0002 > lda test_case ;previous test +3106 : c927 > cmp #test_num + > trap_ne ;test is out of sequence +3108 : d0fe > bne * ;failed not equal (non zero) + > +0028 = >test_num = test_num + 1 +310a : a928 > lda #test_num ;*** next tests' number +310c : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; OR +310f : a203 ldx #3 ;immediate - self modifying code +3111 : b518 tora lda zpOR,x +3113 : 8d0f02 sta ex_orai+1 ;set ORA # operand + set_ax absORa,0 + > load_flag 0 +3116 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +3118 : 48 > pha ;use stack to load status +3119 : bd5602 > lda absORa,x ;precharge accu +311c : 28 > plp + +311d : 200e02 jsr ex_orai ;execute ORA # in RAM + tst_ax absrlo,absflo,0 +3120 : 08 > php ;save flags +3121 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3124 : d0fe > bne * ;failed not equal (non zero) + > +3126 : 68 > pla ;load status + > eor_flag 0 +3127 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +3129 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +312c : d0fe > bne * ;failed not equal (non zero) + > + +312e : ca dex +312f : 10e0 bpl tora +3131 : a203 ldx #3 +3133 : b518 tora1 lda zpOR,x +3135 : 8d0f02 sta ex_orai+1 ;set ORA # operand + set_ax absORa,$ff + > load_flag $ff +3138 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +313a : 48 > pha ;use stack to load status +313b : bd5602 > lda absORa,x ;precharge accu +313e : 28 > plp + +313f : 200e02 jsr ex_orai ;execute ORA # in RAM + tst_ax absrlo,absflo,$ff-fnz +3142 : 08 > php ;save flags +3143 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3146 : d0fe > bne * ;failed not equal (non zero) + > +3148 : 68 > pla ;load status + > eor_flag $ff-fnz +3149 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +314b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +314e : d0fe > bne * ;failed not equal (non zero) + > + +3150 : ca dex +3151 : 10e0 bpl tora1 + +3153 : a203 ldx #3 ;zp +3155 : b518 tora2 lda zpOR,x +3157 : 850c sta zpt + set_ax absORa,0 + > load_flag 0 +3159 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +315b : 48 > pha ;use stack to load status +315c : bd5602 > lda absORa,x ;precharge accu +315f : 28 > plp + +3160 : 050c ora zpt + tst_ax absrlo,absflo,0 +3162 : 08 > php ;save flags +3163 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3166 : d0fe > bne * ;failed not equal (non zero) + > +3168 : 68 > pla ;load status + > eor_flag 0 +3169 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +316b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +316e : d0fe > bne * ;failed not equal (non zero) + > + +3170 : ca dex +3171 : 10e2 bpl tora2 +3173 : a203 ldx #3 +3175 : b518 tora3 lda zpOR,x +3177 : 850c sta zpt + set_ax absORa,$ff + > load_flag $ff +3179 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +317b : 48 > pha ;use stack to load status +317c : bd5602 > lda absORa,x ;precharge accu +317f : 28 > plp + +3180 : 050c ora zpt + tst_ax absrlo,absflo,$ff-fnz +3182 : 08 > php ;save flags +3183 : dd6202 > cmp absrlo,x ;test result + > trap_ne +3186 : d0fe > bne * ;failed not equal (non zero) + > +3188 : 68 > pla ;load status + > eor_flag $ff-fnz +3189 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +318b : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +318e : d0fe > bne * ;failed not equal (non zero) + > + +3190 : ca dex +3191 : 10e2 bpl tora3 + +3193 : a203 ldx #3 ;abs +3195 : b518 tora4 lda zpOR,x +3197 : 8d0302 sta abst + set_ax absORa,0 + > load_flag 0 +319a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +319c : 48 > pha ;use stack to load status +319d : bd5602 > lda absORa,x ;precharge accu +31a0 : 28 > plp + +31a1 : 0d0302 ora abst + tst_ax absrlo,absflo,0 +31a4 : 08 > php ;save flags +31a5 : dd6202 > cmp absrlo,x ;test result + > trap_ne +31a8 : d0fe > bne * ;failed not equal (non zero) + > +31aa : 68 > pla ;load status + > eor_flag 0 +31ab : 4930 > eor #0|fao ;invert expected flags + always on bits + > +31ad : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +31b0 : d0fe > bne * ;failed not equal (non zero) + > + +31b2 : ca dex +31b3 : 10e0 bpl tora4 +31b5 : a203 ldx #3 +31b7 : b518 tora5 lda zpOR,x +31b9 : 8d0302 sta abst + set_ax absORa,$ff + > load_flag $ff +31bc : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +31be : 48 > pha ;use stack to load status +31bf : bd5602 > lda absORa,x ;precharge accu +31c2 : 28 > plp + +31c3 : 0d0302 ora abst + tst_ax absrlo,absflo,$ff-fnz +31c6 : 08 > php ;save flags +31c7 : dd6202 > cmp absrlo,x ;test result + > trap_ne +31ca : d0fe > bne * ;failed not equal (non zero) + > +31cc : 68 > pla ;load status + > eor_flag $ff-fnz +31cd : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +31cf : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +31d2 : d0fe > bne * ;failed not equal (non zero) + > + +31d4 : ca dex +31d5 : 1002 bpl tora6 + +31d7 : a203 ldx #3 ;zp,x +31d9 : tora6 + set_ax absORa,0 + > load_flag 0 +31d9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +31db : 48 > pha ;use stack to load status +31dc : bd5602 > lda absORa,x ;precharge accu +31df : 28 > plp + +31e0 : 1518 ora zpOR,x + tst_ax absrlo,absflo,0 +31e2 : 08 > php ;save flags +31e3 : dd6202 > cmp absrlo,x ;test result + > trap_ne +31e6 : d0fe > bne * ;failed not equal (non zero) + > +31e8 : 68 > pla ;load status + > eor_flag 0 +31e9 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +31eb : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +31ee : d0fe > bne * ;failed not equal (non zero) + > + +31f0 : ca dex +31f1 : 10e6 bpl tora6 +31f3 : a203 ldx #3 +31f5 : tora7 + set_ax absORa,$ff + > load_flag $ff +31f5 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +31f7 : 48 > pha ;use stack to load status +31f8 : bd5602 > lda absORa,x ;precharge accu +31fb : 28 > plp + +31fc : 1518 ora zpOR,x + tst_ax absrlo,absflo,$ff-fnz +31fe : 08 > php ;save flags +31ff : dd6202 > cmp absrlo,x ;test result + > trap_ne +3202 : d0fe > bne * ;failed not equal (non zero) + > +3204 : 68 > pla ;load status + > eor_flag $ff-fnz +3205 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +3207 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +320a : d0fe > bne * ;failed not equal (non zero) + > + +320c : ca dex +320d : 10e6 bpl tora7 + +320f : a203 ldx #3 ;abs,x +3211 : tora8 + set_ax absORa,0 + > load_flag 0 +3211 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +3213 : 48 > pha ;use stack to load status +3214 : bd5602 > lda absORa,x ;precharge accu +3217 : 28 > plp + +3218 : 1d4a02 ora absOR,x + tst_ax absrlo,absflo,0 +321b : 08 > php ;save flags +321c : dd6202 > cmp absrlo,x ;test result + > trap_ne +321f : d0fe > bne * ;failed not equal (non zero) + > +3221 : 68 > pla ;load status + > eor_flag 0 +3222 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +3224 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +3227 : d0fe > bne * ;failed not equal (non zero) + > + +3229 : ca dex +322a : 10e5 bpl tora8 +322c : a203 ldx #3 +322e : tora9 + set_ax absORa,$ff + > load_flag $ff +322e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +3230 : 48 > pha ;use stack to load status +3231 : bd5602 > lda absORa,x ;precharge accu +3234 : 28 > plp + +3235 : 1d4a02 ora absOR,x + tst_ax absrlo,absflo,$ff-fnz +3238 : 08 > php ;save flags +3239 : dd6202 > cmp absrlo,x ;test result + > trap_ne +323c : d0fe > bne * ;failed not equal (non zero) + > +323e : 68 > pla ;load status + > eor_flag $ff-fnz +323f : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +3241 : dd6602 > cmp absflo,x ;test flags + > trap_ne ; +3244 : d0fe > bne * ;failed not equal (non zero) + > + +3246 : ca dex +3247 : 10e5 bpl tora9 + +3249 : a003 ldy #3 ;abs,y +324b : tora10 + set_ay absORa,0 + > load_flag 0 +324b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +324d : 48 > pha ;use stack to load status +324e : b95602 > lda absORa,y ;precharge accu +3251 : 28 > plp + +3252 : 194a02 ora absOR,y + tst_ay absrlo,absflo,0 +3255 : 08 > php ;save flags +3256 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +3259 : d0fe > bne * ;failed not equal (non zero) + > +325b : 68 > pla ;load status + > eor_flag 0 +325c : 4930 > eor #0|fao ;invert expected flags + always on bits + > +325e : d96602 > cmp absflo,y ;test flags + > trap_ne +3261 : d0fe > bne * ;failed not equal (non zero) + > + +3263 : 88 dey +3264 : 10e5 bpl tora10 +3266 : a003 ldy #3 +3268 : tora11 + set_ay absORa,$ff + > load_flag $ff +3268 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +326a : 48 > pha ;use stack to load status +326b : b95602 > lda absORa,y ;precharge accu +326e : 28 > plp + +326f : 194a02 ora absOR,y + tst_ay absrlo,absflo,$ff-fnz +3272 : 08 > php ;save flags +3273 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +3276 : d0fe > bne * ;failed not equal (non zero) + > +3278 : 68 > pla ;load status + > eor_flag $ff-fnz +3279 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +327b : d96602 > cmp absflo,y ;test flags + > trap_ne +327e : d0fe > bne * ;failed not equal (non zero) + > + +3280 : 88 dey +3281 : 10e5 bpl tora11 + +3283 : a206 ldx #6 ;(zp,x) +3285 : a003 ldy #3 +3287 : tora12 + set_ay absORa,0 + > load_flag 0 +3287 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +3289 : 48 > pha ;use stack to load status +328a : b95602 > lda absORa,y ;precharge accu +328d : 28 > plp + +328e : 014a ora (indOR,x) + tst_ay absrlo,absflo,0 +3290 : 08 > php ;save flags +3291 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +3294 : d0fe > bne * ;failed not equal (non zero) + > +3296 : 68 > pla ;load status + > eor_flag 0 +3297 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +3299 : d96602 > cmp absflo,y ;test flags + > trap_ne +329c : d0fe > bne * ;failed not equal (non zero) + > + +329e : ca dex +329f : ca dex +32a0 : 88 dey +32a1 : 10e4 bpl tora12 +32a3 : a206 ldx #6 +32a5 : a003 ldy #3 +32a7 : tora13 + set_ay absORa,$ff + > load_flag $ff +32a7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +32a9 : 48 > pha ;use stack to load status +32aa : b95602 > lda absORa,y ;precharge accu +32ad : 28 > plp + +32ae : 014a ora (indOR,x) + tst_ay absrlo,absflo,$ff-fnz +32b0 : 08 > php ;save flags +32b1 : d96202 > cmp absrlo,y ;test result + > trap_ne ; +32b4 : d0fe > bne * ;failed not equal (non zero) + > +32b6 : 68 > pla ;load status + > eor_flag $ff-fnz +32b7 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +32b9 : d96602 > cmp absflo,y ;test flags + > trap_ne +32bc : d0fe > bne * ;failed not equal (non zero) + > + +32be : ca dex +32bf : ca dex +32c0 : 88 dey +32c1 : 10e4 bpl tora13 + +32c3 : a003 ldy #3 ;(zp),y +32c5 : tora14 + set_ay absORa,0 + > load_flag 0 +32c5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +32c7 : 48 > pha ;use stack to load status +32c8 : b95602 > lda absORa,y ;precharge accu +32cb : 28 > plp + +32cc : 114a ora (indOR),y + tst_ay absrlo,absflo,0 +32ce : 08 > php ;save flags +32cf : d96202 > cmp absrlo,y ;test result + > trap_ne ; +32d2 : d0fe > bne * ;failed not equal (non zero) + > +32d4 : 68 > pla ;load status + > eor_flag 0 +32d5 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +32d7 : d96602 > cmp absflo,y ;test flags + > trap_ne +32da : d0fe > bne * ;failed not equal (non zero) + > + +32dc : 88 dey +32dd : 10e6 bpl tora14 +32df : a003 ldy #3 +32e1 : tora15 + set_ay absORa,$ff + > load_flag $ff +32e1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +32e3 : 48 > pha ;use stack to load status +32e4 : b95602 > lda absORa,y ;precharge accu +32e7 : 28 > plp + +32e8 : 114a ora (indOR),y + tst_ay absrlo,absflo,$ff-fnz +32ea : 08 > php ;save flags +32eb : d96202 > cmp absrlo,y ;test result + > trap_ne ; +32ee : d0fe > bne * ;failed not equal (non zero) + > +32f0 : 68 > pla ;load status + > eor_flag $ff-fnz +32f1 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +32f3 : d96602 > cmp absflo,y ;test flags + > trap_ne +32f6 : d0fe > bne * ;failed not equal (non zero) + > + +32f8 : 88 dey +32f9 : 10e6 bpl tora15 + if I_flag = 3 +32fb : 58 cli + endif + next_test +32fc : ad0002 > lda test_case ;previous test +32ff : c928 > cmp #test_num + > trap_ne ;test is out of sequence +3301 : d0fe > bne * ;failed not equal (non zero) + > +0029 = >test_num = test_num + 1 +3303 : a929 > lda #test_num ;*** next tests' number +3305 : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; full binary add/subtract test + ; iterates through all combinations of operands and carry input + ; uses increments/decrements to predict result & result flags +3308 : d8 cld +3309 : a20e ldx #ad2 ;for indexed test +330b : a0ff ldy #$ff ;max range +330d : a900 lda #0 ;start with adding zeroes & no carry +330f : 850c sta adfc ;carry in - for diag +3311 : 850d sta ad1 ;operand 1 - accumulator +3313 : 850e sta ad2 ;operand 2 - memory or immediate +3315 : 8d0302 sta ada2 ;non zp +3318 : 850f sta adrl ;expected result bits 0-7 +331a : 8510 sta adrh ;expected result bit 8 (carry out) +331c : a9ff lda #$ff ;complemented operand 2 for subtract +331e : 8512 sta sb2 +3320 : 8d0402 sta sba2 ;non zp +3323 : a902 lda #2 ;expected Z-flag +3325 : 8511 sta adrf +3327 : 18 tadd clc ;test with carry clear +3328 : 20a235 jsr chkadd +332b : e60c inc adfc ;now with carry +332d : e60f inc adrl ;result +1 +332f : 08 php ;save N & Z from low result +3330 : 08 php +3331 : 68 pla ;accu holds expected flags +3332 : 2982 and #$82 ;mask N & Z +3334 : 28 plp +3335 : d002 bne tadd1 +3337 : e610 inc adrh ;result bit 8 - carry +3339 : 0510 tadd1 ora adrh ;merge C to expected flags +333b : 8511 sta adrf ;save expected flags except overflow +333d : 38 sec ;test with carry set +333e : 20a235 jsr chkadd +3341 : c60c dec adfc ;same for operand +1 but no carry +3343 : e60d inc ad1 +3345 : d0e0 bne tadd ;iterate op1 +3347 : a900 lda #0 ;preset result to op2 when op1 = 0 +3349 : 8510 sta adrh +334b : ee0302 inc ada2 +334e : e60e inc ad2 +3350 : 08 php ;save NZ as operand 2 becomes the new result +3351 : 68 pla +3352 : 2982 and #$82 ;mask N00000Z0 +3354 : 8511 sta adrf ;no need to check carry as we are adding to 0 +3356 : c612 dec sb2 ;complement subtract operand 2 +3358 : ce0402 dec sba2 +335b : a50e lda ad2 +335d : 850f sta adrl +335f : d0c6 bne tadd ;iterate op2 + if disable_decimal < 1 + next_test +3361 : ad0002 > lda test_case ;previous test +3364 : c929 > cmp #test_num + > trap_ne ;test is out of sequence +3366 : d0fe > bne * ;failed not equal (non zero) + > +002a = >test_num = test_num + 1 +3368 : a92a > lda #test_num ;*** next tests' number +336a : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; decimal add/subtract test + ; *** WARNING - tests documented behavior only! *** + ; only valid BCD operands are tested, N V Z flags are ignored + ; iterates through all valid combinations of operands and carry input + ; uses increments/decrements to predict result & carry flag +336d : f8 sed +336e : a20e ldx #ad2 ;for indexed test +3370 : a0ff ldy #$ff ;max range +3372 : a999 lda #$99 ;start with adding 99 to 99 with carry +3374 : 850d sta ad1 ;operand 1 - accumulator +3376 : 850e sta ad2 ;operand 2 - memory or immediate +3378 : 8d0302 sta ada2 ;non zp +337b : 850f sta adrl ;expected result bits 0-7 +337d : a901 lda #1 ;set carry in & out +337f : 850c sta adfc ;carry in - for diag +3381 : 8510 sta adrh ;expected result bit 8 (carry out) +3383 : a900 lda #0 ;complemented operand 2 for subtract +3385 : 8512 sta sb2 +3387 : 8d0402 sta sba2 ;non zp +338a : 38 tdad sec ;test with carry set +338b : 206f34 jsr chkdad +338e : c60c dec adfc ;now with carry clear +3390 : a50f lda adrl ;decimal adjust result +3392 : d008 bne tdad1 ;skip clear carry & preset result 99 (9A-1) +3394 : c610 dec adrh +3396 : a999 lda #$99 +3398 : 850f sta adrl +339a : d012 bne tdad3 +339c : 290f tdad1 and #$f ;lower nibble mask +339e : d00c bne tdad2 ;no decimal adjust needed +33a0 : c60f dec adrl ;decimal adjust (?0-6) +33a2 : c60f dec adrl +33a4 : c60f dec adrl +33a6 : c60f dec adrl +33a8 : c60f dec adrl +33aa : c60f dec adrl +33ac : c60f tdad2 dec adrl ;result -1 +33ae : 18 tdad3 clc ;test with carry clear +33af : 206f34 jsr chkdad +33b2 : e60c inc adfc ;same for operand -1 but with carry +33b4 : a50d lda ad1 ;decimal adjust operand 1 +33b6 : f015 beq tdad5 ;iterate operand 2 +33b8 : 290f and #$f ;lower nibble mask +33ba : d00c bne tdad4 ;skip decimal adjust +33bc : c60d dec ad1 ;decimal adjust (?0-6) +33be : c60d dec ad1 +33c0 : c60d dec ad1 +33c2 : c60d dec ad1 +33c4 : c60d dec ad1 +33c6 : c60d dec ad1 +33c8 : c60d tdad4 dec ad1 ;operand 1 -1 +33ca : 4c8a33 jmp tdad ;iterate op1 + +33cd : a999 tdad5 lda #$99 ;precharge op1 max +33cf : 850d sta ad1 +33d1 : a50e lda ad2 ;decimal adjust operand 2 +33d3 : f030 beq tdad7 ;end of iteration +33d5 : 290f and #$f ;lower nibble mask +33d7 : d018 bne tdad6 ;skip decimal adjust +33d9 : c60e dec ad2 ;decimal adjust (?0-6) +33db : c60e dec ad2 +33dd : c60e dec ad2 +33df : c60e dec ad2 +33e1 : c60e dec ad2 +33e3 : c60e dec ad2 +33e5 : e612 inc sb2 ;complemented decimal adjust for subtract (?9+6) +33e7 : e612 inc sb2 +33e9 : e612 inc sb2 +33eb : e612 inc sb2 +33ed : e612 inc sb2 +33ef : e612 inc sb2 +33f1 : c60e tdad6 dec ad2 ;operand 2 -1 +33f3 : e612 inc sb2 ;complemented operand for subtract +33f5 : a512 lda sb2 +33f7 : 8d0402 sta sba2 ;copy as non zp operand +33fa : a50e lda ad2 +33fc : 8d0302 sta ada2 ;copy as non zp operand +33ff : 850f sta adrl ;new result since op1+carry=00+carry +op2=op2 +3401 : e610 inc adrh ;result carry +3403 : d085 bne tdad ;iterate op2 +3405 : tdad7 + next_test +3405 : ad0002 > lda test_case ;previous test +3408 : c92a > cmp #test_num + > trap_ne ;test is out of sequence +340a : d0fe > bne * ;failed not equal (non zero) + > +002b = >test_num = test_num + 1 +340c : a92b > lda #test_num ;*** next tests' number +340e : 8d0002 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; decimal/binary switch test + ; tests CLD, SED, PLP, RTI to properly switch between decimal & binary opcode + ; tables +3411 : 18 clc +3412 : d8 cld +3413 : 08 php +3414 : a955 lda #$55 +3416 : 6955 adc #$55 +3418 : c9aa cmp #$aa + trap_ne ;expected binary result after cld +341a : d0fe > bne * ;failed not equal (non zero) + +341c : 18 clc +341d : f8 sed +341e : 08 php +341f : a955 lda #$55 +3421 : 6955 adc #$55 +3423 : c910 cmp #$10 + trap_ne ;expected decimal result after sed +3425 : d0fe > bne * ;failed not equal (non zero) + +3427 : d8 cld +3428 : 28 plp +3429 : a955 lda #$55 +342b : 6955 adc #$55 +342d : c910 cmp #$10 + trap_ne ;expected decimal result after plp D=1 +342f : d0fe > bne * ;failed not equal (non zero) + +3431 : 28 plp +3432 : a955 lda #$55 +3434 : 6955 adc #$55 +3436 : c9aa cmp #$aa + trap_ne ;expected binary result after plp D=0 +3438 : d0fe > bne * ;failed not equal (non zero) + +343a : 18 clc +343b : a934 lda #hi bin_rti_ret ;emulated interrupt for rti +343d : 48 pha +343e : a955 lda #lo bin_rti_ret +3440 : 48 pha +3441 : 08 php +3442 : f8 sed +3443 : a934 lda #hi dec_rti_ret ;emulated interrupt for rti +3445 : 48 pha +3446 : a94c lda #lo dec_rti_ret +3448 : 48 pha +3449 : 08 php +344a : d8 cld +344b : 40 rti +344c : dec_rti_ret +344c : a955 lda #$55 +344e : 6955 adc #$55 +3450 : c910 cmp #$10 + trap_ne ;expected decimal result after rti D=1 +3452 : d0fe > bne * ;failed not equal (non zero) + +3454 : 40 rti +3455 : bin_rti_ret +3455 : a955 lda #$55 +3457 : 6955 adc #$55 +3459 : c9aa cmp #$aa + trap_ne ;expected binary result after rti D=0 +345b : d0fe > bne * ;failed not equal (non zero) + + endif + +345d : ad0002 lda test_case +3460 : c92b cmp #test_num + trap_ne ;previous test is out of sequence +3462 : d0fe > bne * ;failed not equal (non zero) + +3464 : a9f0 lda #$f0 ;mark opcode testing complete +3466 : 8d0002 sta test_case + + ; final RAM integrity test + ; verifies that none of the previous tests has altered RAM outside of the + ; designated write areas. + check_ram + > ;RAM check disabled - RAM size not set + + ; *** DEBUG INFO *** + ; to debug checksum errors uncomment check_ram in the next_test macro to + ; narrow down the responsible opcode. + ; may give false errors when monitor, OS or other background activity is + ; allowed during previous tests. + + + ; S U C C E S S ************************************************ + ; ------------- + success ;if you get here everything went well +3469 : 4c6934 > jmp * ;test passed, no errors + + ; ------------- + ; S U C C E S S ************************************************ +346c : 4c0004 jmp start ;run again + + if disable_decimal < 1 + ; core subroutine of the decimal add/subtract test + ; *** WARNING - tests documented behavior only! *** + ; only valid BCD operands are tested, N V Z flags are ignored + ; iterates through all valid combinations of operands and carry input + ; uses increments/decrements to predict result & carry flag +346f : chkdad + ; decimal ADC / SBC zp +346f : 08 php ;save carry for subtract +3470 : a50d lda ad1 +3472 : 650e adc ad2 ;perform add +3474 : 08 php +3475 : c50f cmp adrl ;check result + trap_ne ;bad result +3477 : d0fe > bne * ;failed not equal (non zero) + +3479 : 68 pla ;check flags +347a : 2901 and #1 ;mask carry +347c : c510 cmp adrh + trap_ne ;bad carry +347e : d0fe > bne * ;failed not equal (non zero) + +3480 : 28 plp +3481 : 08 php ;save carry for next add +3482 : a50d lda ad1 +3484 : e512 sbc sb2 ;perform subtract +3486 : 08 php +3487 : c50f cmp adrl ;check result + trap_ne ;bad result +3489 : d0fe > bne * ;failed not equal (non zero) + +348b : 68 pla ;check flags +348c : 2901 and #1 ;mask carry +348e : c510 cmp adrh + trap_ne ;bad flags +3490 : d0fe > bne * ;failed not equal (non zero) + +3492 : 28 plp + ; decimal ADC / SBC abs +3493 : 08 php ;save carry for subtract +3494 : a50d lda ad1 +3496 : 6d0302 adc ada2 ;perform add +3499 : 08 php +349a : c50f cmp adrl ;check result + trap_ne ;bad result +349c : d0fe > bne * ;failed not equal (non zero) + +349e : 68 pla ;check flags +349f : 2901 and #1 ;mask carry +34a1 : c510 cmp adrh + trap_ne ;bad carry +34a3 : d0fe > bne * ;failed not equal (non zero) + +34a5 : 28 plp +34a6 : 08 php ;save carry for next add +34a7 : a50d lda ad1 +34a9 : ed0402 sbc sba2 ;perform subtract +34ac : 08 php +34ad : c50f cmp adrl ;check result + trap_ne ;bad result +34af : d0fe > bne * ;failed not equal (non zero) + +34b1 : 68 pla ;check flags +34b2 : 2901 and #1 ;mask carry +34b4 : c510 cmp adrh + trap_ne ;bad carry +34b6 : d0fe > bne * ;failed not equal (non zero) + +34b8 : 28 plp + ; decimal ADC / SBC # +34b9 : 08 php ;save carry for subtract +34ba : a50e lda ad2 +34bc : 8d1202 sta ex_adci+1 ;set ADC # operand +34bf : a50d lda ad1 +34c1 : 201102 jsr ex_adci ;execute ADC # in RAM +34c4 : 08 php +34c5 : c50f cmp adrl ;check result + trap_ne ;bad result +34c7 : d0fe > bne * ;failed not equal (non zero) + +34c9 : 68 pla ;check flags +34ca : 2901 and #1 ;mask carry +34cc : c510 cmp adrh + trap_ne ;bad carry +34ce : d0fe > bne * ;failed not equal (non zero) + +34d0 : 28 plp +34d1 : 08 php ;save carry for next add +34d2 : a512 lda sb2 +34d4 : 8d1502 sta ex_sbci+1 ;set SBC # operand +34d7 : a50d lda ad1 +34d9 : 201402 jsr ex_sbci ;execute SBC # in RAM +34dc : 08 php +34dd : c50f cmp adrl ;check result + trap_ne ;bad result +34df : d0fe > bne * ;failed not equal (non zero) + +34e1 : 68 pla ;check flags +34e2 : 2901 and #1 ;mask carry +34e4 : c510 cmp adrh + trap_ne ;bad carry +34e6 : d0fe > bne * ;failed not equal (non zero) + +34e8 : 28 plp + ; decimal ADC / SBC zp,x +34e9 : 08 php ;save carry for subtract +34ea : a50d lda ad1 +34ec : 7500 adc 0,x ;perform add +34ee : 08 php +34ef : c50f cmp adrl ;check result + trap_ne ;bad result +34f1 : d0fe > bne * ;failed not equal (non zero) + +34f3 : 68 pla ;check flags +34f4 : 2901 and #1 ;mask carry +34f6 : c510 cmp adrh + trap_ne ;bad carry +34f8 : d0fe > bne * ;failed not equal (non zero) + +34fa : 28 plp +34fb : 08 php ;save carry for next add +34fc : a50d lda ad1 +34fe : f504 sbc sb2-ad2,x ;perform subtract +3500 : 08 php +3501 : c50f cmp adrl ;check result + trap_ne ;bad result +3503 : d0fe > bne * ;failed not equal (non zero) + +3505 : 68 pla ;check flags +3506 : 2901 and #1 ;mask carry +3508 : c510 cmp adrh + trap_ne ;bad carry +350a : d0fe > bne * ;failed not equal (non zero) + +350c : 28 plp + ; decimal ADC / SBC abs,x +350d : 08 php ;save carry for subtract +350e : a50d lda ad1 +3510 : 7df501 adc ada2-ad2,x ;perform add +3513 : 08 php +3514 : c50f cmp adrl ;check result + trap_ne ;bad result +3516 : d0fe > bne * ;failed not equal (non zero) + +3518 : 68 pla ;check flags +3519 : 2901 and #1 ;mask carry +351b : c510 cmp adrh + trap_ne ;bad carry +351d : d0fe > bne * ;failed not equal (non zero) + +351f : 28 plp +3520 : 08 php ;save carry for next add +3521 : a50d lda ad1 +3523 : fdf601 sbc sba2-ad2,x ;perform subtract +3526 : 08 php +3527 : c50f cmp adrl ;check result + trap_ne ;bad result +3529 : d0fe > bne * ;failed not equal (non zero) + +352b : 68 pla ;check flags +352c : 2901 and #1 ;mask carry +352e : c510 cmp adrh + trap_ne ;bad carry +3530 : d0fe > bne * ;failed not equal (non zero) + +3532 : 28 plp + ; decimal ADC / SBC abs,y +3533 : 08 php ;save carry for subtract +3534 : a50d lda ad1 +3536 : 790401 adc ada2-$ff,y ;perform add +3539 : 08 php +353a : c50f cmp adrl ;check result + trap_ne ;bad result +353c : d0fe > bne * ;failed not equal (non zero) + +353e : 68 pla ;check flags +353f : 2901 and #1 ;mask carry +3541 : c510 cmp adrh + trap_ne ;bad carry +3543 : d0fe > bne * ;failed not equal (non zero) + +3545 : 28 plp +3546 : 08 php ;save carry for next add +3547 : a50d lda ad1 +3549 : f90501 sbc sba2-$ff,y ;perform subtract +354c : 08 php +354d : c50f cmp adrl ;check result + trap_ne ;bad result +354f : d0fe > bne * ;failed not equal (non zero) + +3551 : 68 pla ;check flags +3552 : 2901 and #1 ;mask carry +3554 : c510 cmp adrh + trap_ne ;bad carry +3556 : d0fe > bne * ;failed not equal (non zero) + +3558 : 28 plp + ; decimal ADC / SBC (zp,x) +3559 : 08 php ;save carry for subtract +355a : a50d lda ad1 +355c : 6144 adc (lo adi2-ad2,x) ;perform add +355e : 08 php +355f : c50f cmp adrl ;check result + trap_ne ;bad result +3561 : d0fe > bne * ;failed not equal (non zero) + +3563 : 68 pla ;check flags +3564 : 2901 and #1 ;mask carry +3566 : c510 cmp adrh + trap_ne ;bad carry +3568 : d0fe > bne * ;failed not equal (non zero) + +356a : 28 plp +356b : 08 php ;save carry for next add +356c : a50d lda ad1 +356e : e146 sbc (lo sbi2-ad2,x) ;perform subtract +3570 : 08 php +3571 : c50f cmp adrl ;check result + trap_ne ;bad result +3573 : d0fe > bne * ;failed not equal (non zero) + +3575 : 68 pla ;check flags +3576 : 2901 and #1 ;mask carry +3578 : c510 cmp adrh + trap_ne ;bad carry +357a : d0fe > bne * ;failed not equal (non zero) + +357c : 28 plp + ; decimal ADC / SBC (abs),y +357d : 08 php ;save carry for subtract +357e : a50d lda ad1 +3580 : 7156 adc (adiy2),y ;perform add +3582 : 08 php +3583 : c50f cmp adrl ;check result + trap_ne ;bad result +3585 : d0fe > bne * ;failed not equal (non zero) + +3587 : 68 pla ;check flags +3588 : 2901 and #1 ;mask carry +358a : c510 cmp adrh + trap_ne ;bad carry +358c : d0fe > bne * ;failed not equal (non zero) + +358e : 28 plp +358f : 08 php ;save carry for next add +3590 : a50d lda ad1 +3592 : f158 sbc (sbiy2),y ;perform subtract +3594 : 08 php +3595 : c50f cmp adrl ;check result + trap_ne ;bad result +3597 : d0fe > bne * ;failed not equal (non zero) + +3599 : 68 pla ;check flags +359a : 2901 and #1 ;mask carry +359c : c510 cmp adrh + trap_ne ;bad carry +359e : d0fe > bne * ;failed not equal (non zero) + +35a0 : 28 plp +35a1 : 60 rts + endif + + ; core subroutine of the full binary add/subtract test + ; iterates through all combinations of operands and carry input + ; uses increments/decrements to predict result & result flags +35a2 : a511 chkadd lda adrf ;add V-flag if overflow +35a4 : 2983 and #$83 ;keep N-----ZC / clear V +35a6 : 48 pha +35a7 : a50d lda ad1 ;test sign unequal between operands +35a9 : 450e eor ad2 +35ab : 300a bmi ckad1 ;no overflow possible - operands have different sign +35ad : a50d lda ad1 ;test sign equal between operands and result +35af : 450f eor adrl +35b1 : 1004 bpl ckad1 ;no overflow occured - operand and result have same sign +35b3 : 68 pla +35b4 : 0940 ora #$40 ;set V +35b6 : 48 pha +35b7 : 68 ckad1 pla +35b8 : 8511 sta adrf ;save expected flags + ; binary ADC / SBC zp +35ba : 08 php ;save carry for subtract +35bb : a50d lda ad1 +35bd : 650e adc ad2 ;perform add +35bf : 08 php +35c0 : c50f cmp adrl ;check result + trap_ne ;bad result +35c2 : d0fe > bne * ;failed not equal (non zero) + +35c4 : 68 pla ;check flags +35c5 : 29c3 and #$c3 ;mask NV----ZC +35c7 : c511 cmp adrf + trap_ne ;bad flags +35c9 : d0fe > bne * ;failed not equal (non zero) + +35cb : 28 plp +35cc : 08 php ;save carry for next add +35cd : a50d lda ad1 +35cf : e512 sbc sb2 ;perform subtract +35d1 : 08 php +35d2 : c50f cmp adrl ;check result + trap_ne ;bad result +35d4 : d0fe > bne * ;failed not equal (non zero) + +35d6 : 68 pla ;check flags +35d7 : 29c3 and #$c3 ;mask NV----ZC +35d9 : c511 cmp adrf + trap_ne ;bad flags +35db : d0fe > bne * ;failed not equal (non zero) + +35dd : 28 plp + ; binary ADC / SBC abs +35de : 08 php ;save carry for subtract +35df : a50d lda ad1 +35e1 : 6d0302 adc ada2 ;perform add +35e4 : 08 php +35e5 : c50f cmp adrl ;check result + trap_ne ;bad result +35e7 : d0fe > bne * ;failed not equal (non zero) + +35e9 : 68 pla ;check flags +35ea : 29c3 and #$c3 ;mask NV----ZC +35ec : c511 cmp adrf + trap_ne ;bad flags +35ee : d0fe > bne * ;failed not equal (non zero) + +35f0 : 28 plp +35f1 : 08 php ;save carry for next add +35f2 : a50d lda ad1 +35f4 : ed0402 sbc sba2 ;perform subtract +35f7 : 08 php +35f8 : c50f cmp adrl ;check result + trap_ne ;bad result +35fa : d0fe > bne * ;failed not equal (non zero) + +35fc : 68 pla ;check flags +35fd : 29c3 and #$c3 ;mask NV----ZC +35ff : c511 cmp adrf + trap_ne ;bad flags +3601 : d0fe > bne * ;failed not equal (non zero) + +3603 : 28 plp + ; binary ADC / SBC # +3604 : 08 php ;save carry for subtract +3605 : a50e lda ad2 +3607 : 8d1202 sta ex_adci+1 ;set ADC # operand +360a : a50d lda ad1 +360c : 201102 jsr ex_adci ;execute ADC # in RAM +360f : 08 php +3610 : c50f cmp adrl ;check result + trap_ne ;bad result +3612 : d0fe > bne * ;failed not equal (non zero) + +3614 : 68 pla ;check flags +3615 : 29c3 and #$c3 ;mask NV----ZC +3617 : c511 cmp adrf + trap_ne ;bad flags +3619 : d0fe > bne * ;failed not equal (non zero) + +361b : 28 plp +361c : 08 php ;save carry for next add +361d : a512 lda sb2 +361f : 8d1502 sta ex_sbci+1 ;set SBC # operand +3622 : a50d lda ad1 +3624 : 201402 jsr ex_sbci ;execute SBC # in RAM +3627 : 08 php +3628 : c50f cmp adrl ;check result + trap_ne ;bad result +362a : d0fe > bne * ;failed not equal (non zero) + +362c : 68 pla ;check flags +362d : 29c3 and #$c3 ;mask NV----ZC +362f : c511 cmp adrf + trap_ne ;bad flags +3631 : d0fe > bne * ;failed not equal (non zero) + +3633 : 28 plp + ; binary ADC / SBC zp,x +3634 : 08 php ;save carry for subtract +3635 : a50d lda ad1 +3637 : 7500 adc 0,x ;perform add +3639 : 08 php +363a : c50f cmp adrl ;check result + trap_ne ;bad result +363c : d0fe > bne * ;failed not equal (non zero) + +363e : 68 pla ;check flags +363f : 29c3 and #$c3 ;mask NV----ZC +3641 : c511 cmp adrf + trap_ne ;bad flags +3643 : d0fe > bne * ;failed not equal (non zero) + +3645 : 28 plp +3646 : 08 php ;save carry for next add +3647 : a50d lda ad1 +3649 : f504 sbc sb2-ad2,x ;perform subtract +364b : 08 php +364c : c50f cmp adrl ;check result + trap_ne ;bad result +364e : d0fe > bne * ;failed not equal (non zero) + +3650 : 68 pla ;check flags +3651 : 29c3 and #$c3 ;mask NV----ZC +3653 : c511 cmp adrf + trap_ne ;bad flags +3655 : d0fe > bne * ;failed not equal (non zero) + +3657 : 28 plp + ; binary ADC / SBC abs,x +3658 : 08 php ;save carry for subtract +3659 : a50d lda ad1 +365b : 7df501 adc ada2-ad2,x ;perform add +365e : 08 php +365f : c50f cmp adrl ;check result + trap_ne ;bad result +3661 : d0fe > bne * ;failed not equal (non zero) + +3663 : 68 pla ;check flags +3664 : 29c3 and #$c3 ;mask NV----ZC +3666 : c511 cmp adrf + trap_ne ;bad flags +3668 : d0fe > bne * ;failed not equal (non zero) + +366a : 28 plp +366b : 08 php ;save carry for next add +366c : a50d lda ad1 +366e : fdf601 sbc sba2-ad2,x ;perform subtract +3671 : 08 php +3672 : c50f cmp adrl ;check result + trap_ne ;bad result +3674 : d0fe > bne * ;failed not equal (non zero) + +3676 : 68 pla ;check flags +3677 : 29c3 and #$c3 ;mask NV----ZC +3679 : c511 cmp adrf + trap_ne ;bad flags +367b : d0fe > bne * ;failed not equal (non zero) + +367d : 28 plp + ; binary ADC / SBC abs,y +367e : 08 php ;save carry for subtract +367f : a50d lda ad1 +3681 : 790401 adc ada2-$ff,y ;perform add +3684 : 08 php +3685 : c50f cmp adrl ;check result + trap_ne ;bad result +3687 : d0fe > bne * ;failed not equal (non zero) + +3689 : 68 pla ;check flags +368a : 29c3 and #$c3 ;mask NV----ZC +368c : c511 cmp adrf + trap_ne ;bad flags +368e : d0fe > bne * ;failed not equal (non zero) + +3690 : 28 plp +3691 : 08 php ;save carry for next add +3692 : a50d lda ad1 +3694 : f90501 sbc sba2-$ff,y ;perform subtract +3697 : 08 php +3698 : c50f cmp adrl ;check result + trap_ne ;bad result +369a : d0fe > bne * ;failed not equal (non zero) + +369c : 68 pla ;check flags +369d : 29c3 and #$c3 ;mask NV----ZC +369f : c511 cmp adrf + trap_ne ;bad flags +36a1 : d0fe > bne * ;failed not equal (non zero) + +36a3 : 28 plp + ; binary ADC / SBC (zp,x) +36a4 : 08 php ;save carry for subtract +36a5 : a50d lda ad1 +36a7 : 6144 adc (lo adi2-ad2,x) ;perform add +36a9 : 08 php +36aa : c50f cmp adrl ;check result + trap_ne ;bad result +36ac : d0fe > bne * ;failed not equal (non zero) + +36ae : 68 pla ;check flags +36af : 29c3 and #$c3 ;mask NV----ZC +36b1 : c511 cmp adrf + trap_ne ;bad flags +36b3 : d0fe > bne * ;failed not equal (non zero) + +36b5 : 28 plp +36b6 : 08 php ;save carry for next add +36b7 : a50d lda ad1 +36b9 : e146 sbc (lo sbi2-ad2,x) ;perform subtract +36bb : 08 php +36bc : c50f cmp adrl ;check result + trap_ne ;bad result +36be : d0fe > bne * ;failed not equal (non zero) + +36c0 : 68 pla ;check flags +36c1 : 29c3 and #$c3 ;mask NV----ZC +36c3 : c511 cmp adrf + trap_ne ;bad flags +36c5 : d0fe > bne * ;failed not equal (non zero) + +36c7 : 28 plp + ; binary ADC / SBC (abs),y +36c8 : 08 php ;save carry for subtract +36c9 : a50d lda ad1 +36cb : 7156 adc (adiy2),y ;perform add +36cd : 08 php +36ce : c50f cmp adrl ;check result + trap_ne ;bad result +36d0 : d0fe > bne * ;failed not equal (non zero) + +36d2 : 68 pla ;check flags +36d3 : 29c3 and #$c3 ;mask NV----ZC +36d5 : c511 cmp adrf + trap_ne ;bad flags +36d7 : d0fe > bne * ;failed not equal (non zero) + +36d9 : 28 plp +36da : 08 php ;save carry for next add +36db : a50d lda ad1 +36dd : f158 sbc (sbiy2),y ;perform subtract +36df : 08 php +36e0 : c50f cmp adrl ;check result + trap_ne ;bad result +36e2 : d0fe > bne * ;failed not equal (non zero) + +36e4 : 68 pla ;check flags +36e5 : 29c3 and #$c3 ;mask NV----ZC +36e7 : c511 cmp adrf + trap_ne ;bad flags +36e9 : d0fe > bne * ;failed not equal (non zero) + +36eb : 28 plp +36ec : 60 rts + + ; target for the jump absolute test +36ed : 88 dey +36ee : 88 dey +36ef : test_far +36ef : 08 php ;either SP or Y count will fail, if we do not hit +36f0 : 88 dey +36f1 : 88 dey +36f2 : 88 dey +36f3 : 28 plp + trap_cs ;flags loaded? +36f4 : b0fe > bcs * ;failed carry set + + trap_vs +36f6 : 70fe > bvs * ;failed overflow set + + trap_mi +36f8 : 30fe > bmi * ;failed minus (bit 7 set) + + trap_eq +36fa : f0fe > beq * ;failed equal (zero) + +36fc : c946 cmp #'F' ;registers loaded? + trap_ne +36fe : d0fe > bne * ;failed not equal (non zero) + +3700 : e041 cpx #'A' + trap_ne +3702 : d0fe > bne * ;failed not equal (non zero) + +3704 : c04f cpy #('R'-3) + trap_ne +3706 : d0fe > bne * ;failed not equal (non zero) + +3708 : 48 pha ;save a,x +3709 : 8a txa +370a : 48 pha +370b : ba tsx +370c : e0fd cpx #$fd ;check SP + trap_ne +370e : d0fe > bne * ;failed not equal (non zero) + +3710 : 68 pla ;restore x +3711 : aa tax + set_stat $ff + > load_flag $ff +3712 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +3714 : 48 > pha ;use stack to load status +3715 : 28 > plp + +3716 : 68 pla ;restore a +3717 : e8 inx ;return registers with modifications +3718 : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 +371a : 4c0f09 jmp far_ret + + ; target for the jump indirect test +371d : 00 align +371e : 2737 ptr_tst_ind dw test_ind +3720 : 6409 ptr_ind_ret dw ind_ret + trap ;runover protection +3722 : 4c2237 > jmp * ;failed anyway + +3725 : 88 dey +3726 : 88 dey +3727 : test_ind +3727 : 08 php ;either SP or Y count will fail, if we do not hit +3728 : 88 dey +3729 : 88 dey +372a : 88 dey +372b : 28 plp + trap_cs ;flags loaded? +372c : b0fe > bcs * ;failed carry set + + trap_vs +372e : 70fe > bvs * ;failed overflow set + + trap_mi +3730 : 30fe > bmi * ;failed minus (bit 7 set) + + trap_eq +3732 : f0fe > beq * ;failed equal (zero) + +3734 : c949 cmp #'I' ;registers loaded? + trap_ne +3736 : d0fe > bne * ;failed not equal (non zero) + +3738 : e04e cpx #'N' + trap_ne +373a : d0fe > bne * ;failed not equal (non zero) + +373c : c041 cpy #('D'-3) + trap_ne +373e : d0fe > bne * ;failed not equal (non zero) + +3740 : 48 pha ;save a,x +3741 : 8a txa +3742 : 48 pha +3743 : ba tsx +3744 : e0fd cpx #$fd ;check SP + trap_ne +3746 : d0fe > bne * ;failed not equal (non zero) + +3748 : 68 pla ;restore x +3749 : aa tax + set_stat $ff + > load_flag $ff +374a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +374c : 48 > pha ;use stack to load status +374d : 28 > plp + +374e : 68 pla ;restore a +374f : e8 inx ;return registers with modifications +3750 : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 +3752 : 6c2037 jmp (ptr_ind_ret) + trap ;runover protection +3755 : 4c5537 > jmp * ;failed anyway + +3758 : 4c0004 jmp start ;catastrophic error - cannot continue + + ; target for the jump subroutine test +375b : 88 dey +375c : 88 dey +375d : test_jsr +375d : 08 php ;either SP or Y count will fail, if we do not hit +375e : 88 dey +375f : 88 dey +3760 : 88 dey +3761 : 28 plp + trap_cs ;flags loaded? +3762 : b0fe > bcs * ;failed carry set + + trap_vs +3764 : 70fe > bvs * ;failed overflow set + + trap_mi +3766 : 30fe > bmi * ;failed minus (bit 7 set) + + trap_eq +3768 : f0fe > beq * ;failed equal (zero) + +376a : c94a cmp #'J' ;registers loaded? + trap_ne +376c : d0fe > bne * ;failed not equal (non zero) + +376e : e053 cpx #'S' + trap_ne +3770 : d0fe > bne * ;failed not equal (non zero) + +3772 : c04f cpy #('R'-3) + trap_ne +3774 : d0fe > bne * ;failed not equal (non zero) + +3776 : 48 pha ;save a,x +3777 : 8a txa +3778 : 48 pha +3779 : ba tsx ;sp -4? (return addr,a,x) +377a : e0fb cpx #$fb + trap_ne +377c : d0fe > bne * ;failed not equal (non zero) + +377e : adff01 lda $1ff ;propper return on stack +3781 : c909 cmp #hi(jsr_ret) + trap_ne +3783 : d0fe > bne * ;failed not equal (non zero) + +3785 : adfe01 lda $1fe +3788 : c99a cmp #lo(jsr_ret) + trap_ne +378a : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +378c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +378e : 48 > pha ;use stack to load status +378f : 28 > plp + +3790 : 68 pla ;pull x,a +3791 : aa tax +3792 : 68 pla +3793 : e8 inx ;return registers with modifications +3794 : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 +3796 : 60 rts + trap ;runover protection +3797 : 4c9737 > jmp * ;failed anyway + +379a : 4c0004 jmp start ;catastrophic error - cannot continue + + ;trap in case of unexpected IRQ, NMI, BRK, RESET - BRK test target +379d : nmi_trap + trap ;check stack for conditions at NMI +379d : 4c9d37 > jmp * ;failed anyway + +37a0 : 4c0004 jmp start ;catastrophic error - cannot continue +37a3 : res_trap + trap ;unexpected RESET +37a3 : 4ca337 > jmp * ;failed anyway + +37a6 : 4c0004 jmp start ;catastrophic error - cannot continue + +37a9 : 88 dey +37aa : 88 dey +37ab : irq_trap ;BRK test or unextpected BRK or IRQ +37ab : 08 php ;either SP or Y count will fail, if we do not hit +37ac : 88 dey +37ad : 88 dey +37ae : 88 dey + ;next traps could be caused by unexpected BRK or IRQ + ;check stack for BREAK and originating location + ;possible jump/branch into weeds (uninitialized space) +37af : c9bd cmp #$ff-'B' ;BRK pass 2 registers loaded? +37b1 : f042 beq break2 +37b3 : c942 cmp #'B' ;BRK pass 1 registers loaded? + trap_ne +37b5 : d0fe > bne * ;failed not equal (non zero) + +37b7 : e052 cpx #'R' + trap_ne +37b9 : d0fe > bne * ;failed not equal (non zero) + +37bb : c048 cpy #'K'-3 + trap_ne +37bd : d0fe > bne * ;failed not equal (non zero) + +37bf : 850a sta irq_a ;save registers during break test +37c1 : 860b stx irq_x +37c3 : ba tsx ;test break on stack +37c4 : bd0201 lda $102,x + cmp_flag 0 ;break test should have B=1 & unused=1 on stack +37c7 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits + + trap_ne ; - no break flag on stack +37c9 : d0fe > bne * ;failed not equal (non zero) + +37cb : 68 pla + cmp_flag intdis ;should have added interrupt disable +37cc : c934 > cmp #(intdis |fao)&m8 ;expected flags + always on bits + + trap_ne +37ce : d0fe > bne * ;failed not equal (non zero) + +37d0 : ba tsx +37d1 : e0fc cpx #$fc ;sp -3? (return addr, flags) + trap_ne +37d3 : d0fe > bne * ;failed not equal (non zero) + +37d5 : adff01 lda $1ff ;propper return on stack +37d8 : c909 cmp #hi(brk_ret0) + trap_ne +37da : d0fe > bne * ;failed not equal (non zero) + +37dc : adfe01 lda $1fe +37df : c9d1 cmp #lo(brk_ret0) + trap_ne +37e1 : d0fe > bne * ;failed not equal (non zero) + + load_flag $ff +37e3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +37e5 : 48 pha +37e6 : a60b ldx irq_x +37e8 : e8 inx ;return registers with modifications +37e9 : a50a lda irq_a +37eb : 49aa eor #$aa +37ed : 28 plp ;N=1, V=1, Z=1, C=1 but original flags should be restored +37ee : 40 rti + trap ;runover protection +37ef : 4cef37 > jmp * ;failed anyway + +37f2 : 4c0004 jmp start ;catastrophic error - cannot continue + +37f5 : break2 ;BRK pass 2 +37f5 : e0ad cpx #$ff-'R' + trap_ne +37f7 : d0fe > bne * ;failed not equal (non zero) + +37f9 : c0b1 cpy #$ff-'K'-3 + trap_ne +37fb : d0fe > bne * ;failed not equal (non zero) + +37fd : 850a sta irq_a ;save registers during break test +37ff : 860b stx irq_x +3801 : ba tsx ;test break on stack +3802 : bd0201 lda $102,x + cmp_flag $ff ;break test should have B=1 +3805 : c9ff > cmp #($ff |fao)&m8 ;expected flags + always on bits + + trap_ne ; - no break flag on stack +3807 : d0fe > bne * ;failed not equal (non zero) + +3809 : 68 pla +380a : 0908 ora #decmode ;ignore decmode cleared if 65c02 + cmp_flag $ff ;actual passed flags +380c : c9ff > cmp #($ff |fao)&m8 ;expected flags + always on bits + + trap_ne +380e : d0fe > bne * ;failed not equal (non zero) + +3810 : ba tsx +3811 : e0fc cpx #$fc ;sp -3? (return addr, flags) + trap_ne +3813 : d0fe > bne * ;failed not equal (non zero) + +3815 : adff01 lda $1ff ;propper return on stack +3818 : c909 cmp #hi(brk_ret1) + trap_ne +381a : d0fe > bne * ;failed not equal (non zero) + +381c : adfe01 lda $1fe +381f : c9f7 cmp #lo(brk_ret1) + trap_ne +3821 : d0fe > bne * ;failed not equal (non zero) + + load_flag intdis +3823 : a904 > lda #intdis ;allow test to change I-flag (no mask) + +3825 : 48 pha +3826 : a60b ldx irq_x +3828 : e8 inx ;return registers with modifications +3829 : a50a lda irq_a +382b : 49aa eor #$aa +382d : 28 plp ;N=0, V=0, Z=0, C=0 but original flags should be restored +382e : 40 rti + trap ;runover protection +382f : 4c2f38 > jmp * ;failed anyway + +3832 : 4c0004 jmp start ;catastrophic error - cannot continue + + if report = 1 + include "report.i65" + endif + + ;copy of data to initialize BSS segment + if load_data_direct != 1 + zp_init + zp1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR + zp7f_ db $7f ;test pattern for compare + ;logical zeropage operands + zpOR_ db 0,$1f,$71,$80 ;test pattern for OR + zpAN_ db $0f,$ff,$7f,$80 ;test pattern for AND + zpEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR + ;indirect addressing pointers + ind1_ dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f + inw1_ dw abs1-$f8 ;indirect pointer for wrap-test pattern + indt_ dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 + inwt_ dw abst-$f8 ;indirect pointer for wrap-test store + indAN_ dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 + indEO_ dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 + indOR_ dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 + ;add/subtract indirect pointers + adi2_ dw ada2 ;indirect pointer to operand 2 in absolute memory + sbi2_ dw sba2 ;indirect pointer to complemented operand 2 (SBC) + adiy2_ dw ada2-$ff ;with offset for indirect indexed + sbiy2_ dw sba2-$ff + zp_end + if (zp_end - zp_init) != (zp_bss_end - zp_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and zeropage data + endif + data_init + ex_and_ and #0 ;execute immediate opcodes + rts + ex_eor_ eor #0 ;execute immediate opcodes + rts + ex_ora_ ora #0 ;execute immediate opcodes + rts + ex_adc_ adc #0 ;execute immediate opcodes + rts + ex_sbc_ sbc #0 ;execute immediate opcodes + rts + abs1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR + abs7f_ db $7f ;test pattern for compare + ;loads + fLDx_ db fn,fn,0,fz ;expected flags for load + ;shifts + rASL_ ;expected result ASL & ROL -carry + rROL_ db $86,$04,$82,0 ; " + rROLc_ db $87,$05,$83,1 ;expected result ROL +carry + rLSR_ ;expected result LSR & ROR -carry + rROR_ db $61,$41,$20,0 ; " + rRORc_ db $e1,$c1,$a0,$80 ;expected result ROR +carry + fASL_ ;expected flags for shifts + fROL_ db fnc,fc,fn,fz ;no carry in + fROLc_ db fnc,fc,fn,0 ;carry in + fLSR_ + fROR_ db fc,0,fc,fz ;no carry in + fRORc_ db fnc,fn,fnc,fn ;carry in + ;increments (decrements) + rINC_ db $7f,$80,$ff,0,1 ;expected result for INC/DEC + fINC_ db 0,fn,fn,fz,0 ;expected flags for INC/DEC + ;logical memory operand + absOR_ db 0,$1f,$71,$80 ;test pattern for OR + absAN_ db $0f,$ff,$7f,$80 ;test pattern for AND + absEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR + ;logical accu operand + absORa_ db 0,$f1,$1f,0 ;test pattern for OR + absANa_ db $f0,$ff,$ff,$ff ;test pattern for AND + absEOa_ db $ff,$f0,$f0,$0f ;test pattern for EOR + ;logical results + absrlo_ db 0,$ff,$7f,$80 + absflo_ db fz,fn,0,fn + data_end + if (data_end - data_init) != (data_bss_end - data_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and data + endif + + vec_init + dw nmi_trap + dw res_trap + dw irq_trap + vec_bss equ $fffa + endif ;end of RAM init data + + if (load_data_direct = 1) & (ROM_vectors = 1) +fffa = org $fffa ;vectors +fffa : 9d37 dw nmi_trap +fffc : a337 dw res_trap +fffe : ab37 dw irq_trap + endif + +fffa = end start + +No errors in pass 2. +Wrote binary from address $0000 through $ffff. +Total size 65536 bytes. +Program start address is at $0400 (1024). + \ No newline at end of file diff --git a/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.bin b/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.bin new file mode 100644 index 0000000..b1ea946 Binary files /dev/null and b/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.bin differ diff --git a/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.lst b/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.lst new file mode 100644 index 0000000..d44487e --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/bin_files/65C02_extended_opcodes_test.lst @@ -0,0 +1,11510 @@ +AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1 +------------------------------------------------ 65C02_extended_opcodes_test.a65c ------------------------------------------------ + +2884 lines read, no errors in pass 1. + ; + ; 6 5 C 0 2 E X T E N D E D O P C O D E S T E S T + ; + ; Copyright (C) 2013-2017 Klaus Dormann + ; + ; This program is free software: you can redistribute it and/or modify + ; it under the terms of the GNU General Public License as published by + ; the Free Software Foundation, either version 3 of the License, or + ; (at your option) any later version. + ; + ; This program is distributed in the hope that it will be useful, + ; but WITHOUT ANY WARRANTY; without even the implied warranty of + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ; GNU General Public License for more details. + ; + ; You should have received a copy of the GNU General Public License + ; along with this program. If not, see . + + + ; This program is designed to test all additional 65C02 opcodes, addressing + ; modes and functionality not available in the NMOS version of the 6502. + ; The 6502_functional_test is a prerequisite to this test. + ; NMI, IRQ, STP & WAI are covered in the 6502_interrupt_test. + ; + ; version 04-dec-2017 + ; contact info at http://2m5.de or email K@2m5.de + ; + ; assembled with AS65 from http://www.kingswood-consulting.co.uk/assemblers/ + ; command line switches: -l -m -s2 -w -x -h0 + ; | | | | | no page headers in listing + ; | | | | 65C02 extensions + ; | | | wide listing (133 char/col) + ; | | write intel hex file instead of binary + ; | expand macros in listing + ; generate pass2 listing + ; + ; No IO - should be run from a monitor with access to registers. + ; To run load intel hex image with a load command, than alter PC to 400 hex + ; (code_segment) and enter a go command. + ; Loop on program counter determines error or successful completion of test. + ; Check listing for relevant traps (jump/branch *). + ; Please note that in early tests some instructions will have to be used before + ; they are actually tested! + ; + ; RESET, NMI or IRQ should not occur and will be trapped if vectors are enabled. + ; Tests documented behavior of the original 65C02 only! + ; Decimal ops will only be tested with valid BCD operands and the V flag will + ; be ignored as it is absolutely useless in decimal mode. + ; + ; Debugging hints: + ; Most of the code is written sequentially. if you hit a trap, check the + ; immediately preceeding code for the instruction to be tested. Results are + ; tested first, flags are checked second by pushing them onto the stack and + ; pulling them to the accumulator after the result was checked. The "real" + ; flags are no longer valid for the tested instruction at this time! + ; If the tested instruction was indexed, the relevant index (X or Y) must + ; also be checked. Opposed to the flags, X and Y registers are still valid. + ; + ; versions: + ; 19-jul-2013 1st version distributed for testing + ; 23-jul-2013 fixed BRA out of range due to larger trap macros + ; added RAM integrity check + ; 16-aug-2013 added error report to standard output option + ; 23-aug-2015 change revoked + ; 24-aug-2015 all self modifying immediate opcodes now execute in data RAM + ; 28-aug-2015 fixed decimal adc/sbc immediate only testing carry + ; 09-feb-2017 fixed RMB/SMB tested when they shouldn't be tested + ; 04-dec-2017 fixed BRK not tested for actually going through the IRQ vector + ; added option to skip the remainder of a failing test + ; in report.i65 + ; added skip override to undefined opcode as NOP test + + + ; C O N F I G U R A T I O N + + ;ROM_vectors writable (0=no, 1=yes) + ;if ROM vectors can not be used interrupts will not be trapped + ;as a consequence BRK can not be tested but will be emulated to test RTI +0001 = ROM_vectors = 1 + + ;load_data_direct (0=move from code segment, 1=load directly) + ;loading directly is preferred but may not be supported by your platform + ;0 produces only consecutive object code, 1 is not suitable for a binary image +0001 = load_data_direct = 1 + + ;I_flag behavior (0=force enabled, 1=force disabled, 2=prohibit change, 3=allow + ;change) 2 requires extra code and is not recommended. +0003 = I_flag = 3 + + ;configure memory - try to stay away from memory used by the system + ;zero_page memory start address, $4e (78) consecutive Bytes required + ; add 2 if I_flag = 2 +000a = zero_page = $a + + ;data_segment memory start address, $63 (99) consecutive Bytes required + ; + 12 Bytes at data_segment + $f9 (JMP indirect page cross test) +0200 = data_segment = $200 + if (data_segment & $ff) != 0 + ERROR ERROR ERROR low byte of data_segment MUST be $00 !! + endif + + ;code_segment memory start address, 10kB of consecutive space required + ; add 1 kB if I_flag = 2 +0400 = code_segment = $400 + + ;added WDC only opcodes WAI & STP (0=test as NOPs, >0=no test) +0001 = wdc_op = 1 + + ;added Rockwell & WDC opcodes BBR, BBS, RMB & SMB + ;(0=test as NOPs, 1=full test, >1=no test) +0001 = rkwl_wdc_op = 1 + + ;skip testing all undefined opcodes override + ;0=test as NOP, >0=skip +0000 = skip_nop = 0 + + ;report errors through I/O channel (0=use standard self trap loops, 1=include + ;report.i65 as I/O channel, add 3 kB) +0000 = report = 0 + + ;RAM integrity test option. Checks for undesired RAM writes. + ;set lowest non RAM or RAM mirror address page (-1=disable, 0=64k, $40=16k) + ;leave disabled if a monitor, OS or background interrupt is allowed to alter RAM +ffff = ram_top = -1 + + noopt ;do not take shortcuts + + ;macros for error & success traps to allow user modification + ;example: + ;trap macro + ; jsr my_error_handler + ; endm + ;trap_eq macro + ; bne skip\? + ; trap ;failed equal (zero) + ;skip\? + ; endm + ; + ; my_error_handler should pop the calling address from the stack and report it. + ; putting larger portions of code (more than 3 bytes) inside the trap macro + ; may lead to branch range problems for some tests. + if report = 0 + trap macro + jmp * ;failed anyway + endm + trap_eq macro + beq * ;failed equal (zero) + endm + trap_ne macro + bne * ;failed not equal (non zero) + endm + trap_cs macro + bcs * ;failed carry set + endm + trap_cc macro + bcc * ;failed carry clear + endm + trap_mi macro + bmi * ;failed minus (bit 7 set) + endm + trap_pl macro + bpl * ;failed plus (bit 7 clear) + endm + trap_vs macro + bvs * ;failed overflow set + endm + trap_vc macro + bvc * ;failed overflow clear + endm + ; please observe that during the test the stack gets invalidated + ; therefore a RTS inside the success macro is not possible + success macro + jmp * ;test passed, no errors + endm + endif + if report = 1 + trap macro + jsr report_error + endm + trap_eq macro + bne skip\? + trap ;failed equal (zero) + skip\? + endm + trap_ne macro + beq skip\? + trap ;failed not equal (non zero) + skip\? + endm + trap_cs macro + bcc skip\? + trap ;failed carry set + skip\? + endm + trap_cc macro + bcs skip\? + trap ;failed carry clear + skip\? + endm + trap_mi macro + bpl skip\? + trap ;failed minus (bit 7 set) + skip\? + endm + trap_pl macro + bmi skip\? + trap ;failed plus (bit 7 clear) + skip\? + endm + trap_vs macro + bvc skip\? + trap ;failed overflow set + skip\? + endm + trap_vc macro + bvs skip\? + trap ;failed overflow clear + skip\? + endm + ; please observe that during the test the stack gets invalidated + ; therefore a RTS inside the success macro is not possible + success macro + jsr report_success + endm + endif + + +0001 = carry equ %00000001 ;flag bits in status +0002 = zero equ %00000010 +0004 = intdis equ %00000100 +0008 = decmode equ %00001000 +0010 = break equ %00010000 +0020 = reserv equ %00100000 +0040 = overfl equ %01000000 +0080 = minus equ %10000000 + +0001 = fc equ carry +0002 = fz equ zero +0003 = fzc equ carry+zero +0040 = fv equ overfl +0042 = fvz equ overfl+zero +0080 = fn equ minus +0081 = fnc equ minus+carry +0082 = fnz equ minus+zero +0083 = fnzc equ minus+zero+carry +00c0 = fnv equ minus+overfl + +0030 = fao equ break+reserv ;bits always on after PHP, BRK +0034 = fai equ fao+intdis ;+ forced interrupt disable +00ff = m8 equ $ff ;8 bit mask +00fb = m8i equ $ff&~intdis ;8 bit mask - interrupt disable + + ;macros to allow masking of status bits. + ;masking of interrupt enable/disable on load and compare + ;masking of always on bits after PHP or BRK (unused & break) on compare + if I_flag = 0 + load_flag macro + lda #\1&m8i ;force enable interrupts (mask I) + endm + cmp_flag macro + cmp #(\1|fao)&m8i ;I_flag is always enabled + always on bits + endm + eor_flag macro + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 1 + load_flag macro + lda #\1|intdis ;force disable interrupts + endm + cmp_flag macro + cmp #(\1|fai)&m8 ;I_flag is always disabled + always on bits + endm + eor_flag macro + eor #(\1|fai) ;invert expected flags + always on bits + I + endm + endif + if I_flag = 2 + load_flag macro + lda #\1 + ora flag_I_on ;restore I-flag + and flag_I_off + endm + cmp_flag macro + eor flag_I_on ;I_flag is never changed + cmp #(\1|fao)&m8i ;expected flags + always on bits, mask I + endm + eor_flag macro + eor flag_I_on ;I_flag is never changed + eor #(\1&m8i|fao) ;mask I, invert expected flags + always on bits + endm + endif + if I_flag = 3 + load_flag macro + lda #\1 ;allow test to change I-flag (no mask) + endm + cmp_flag macro + cmp #(\1|fao)&m8 ;expected flags + always on bits + endm + eor_flag macro + eor #\1|fao ;invert expected flags + always on bits + endm + endif + + ;macros to set (register|memory|zeropage) & status + set_stat macro ;setting flags in the processor status register + load_flag \1 + pha ;use stack to load status + plp + endm + + set_a macro ;precharging accu & status + load_flag \2 + pha ;use stack to load status + lda #\1 ;precharge accu + plp + endm + + set_x macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldx #\1 ;precharge index x + plp + endm + + set_y macro ;precharging index & status + load_flag \2 + pha ;use stack to load status + ldy #\1 ;precharge index y + plp + endm + + set_ax macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;precharge accu + plp + endm + + set_ay macro ;precharging indexed accu & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,y ;precharge accu + plp + endm + + set_z macro ;precharging indexed zp & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to zeropage + sta zpt + plp + endm + + set_zx macro ;precharging zp,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed zeropage + sta zpt,x + plp + endm + + set_abs macro ;precharging indexed memory & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to memory + sta abst + plp + endm + + set_absx macro ;precharging abs,x & immediate status + load_flag \2 + pha ;use stack to load status + lda \1,x ;load to indexed memory + sta abst,x + plp + endm + + ;macros to test (register|memory|zeropage) & status & (mask) + tst_stat macro ;testing flags in the processor status register + php ;save status + pla ;use stack to retrieve status + pha + cmp_flag \1 + trap_ne + plp ;restore status + endm + + tst_a macro ;testing result in accu & flags + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_as macro ;testing result in accu & flags, save accu + pha + php ;save flags + cmp #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + pla + endm + + tst_x macro ;testing result in x index & flags + php ;save flags + cpx #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_y macro ;testing result in y index & flags + php ;save flags + cpy #\1 ;test result + trap_ne + pla ;load status + pha + cmp_flag \2 + trap_ne + plp ;restore status + endm + + tst_ax macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne ; + endm + + tst_ay macro ;indexed testing result in accu & flags + php ;save flags + cmp \1,y ;test result + trap_ne ; + pla ;load status + eor_flag \3 + cmp \2,y ;test flags + trap_ne + endm + + tst_z macro ;indexed testing result in zp & flags + php ;save flags + lda zpt + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_zx macro ;testing result in zp,x & flags + php ;save flags + lda zpt,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_abs macro ;indexed testing result in memory & flags + php ;save flags + lda abst + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + tst_absx macro ;testing result in abs,x & flags + php ;save flags + lda abst,x + cmp \1,x ;test result + trap_ne + pla ;load status + eor_flag \3 + cmp \2,x ;test flags + trap_ne + endm + + ; RAM integrity test + ; verifies that none of the previous tests has altered RAM outside of the + ; designated write areas. + ; uses zpt word as indirect pointer, zpt+2 word as checksum + if ram_top > -1 + check_ram macro + cld + lda #0 + sta zpt ;set low byte of indirect pointer + sta zpt+3 ;checksum high byte + ldx #11 ;reset modifiable RAM + ccs1\? sta jxi_tab,x ;JMP indirect page cross area + dex + bpl ccs1\? + clc + ldx #zp_bss-zero_page ;zeropage - write test area + ccs3\? adc zero_page,x + bcc ccs2\? + inc zpt+3 ;carry to high byte + clc + ccs2\? inx + bne ccs3\? + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area + ccs5\? adc (zpt),y + bcc ccs4\? + inc zpt+3 ;carry to high byte + clc + ccs4\? iny + bne ccs5\? + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne ccs5\? + sta zpt+2 ;checksum low is + cmp ram_chksm ;checksum low expected + trap_ne ;checksum mismatch + lda zpt+3 ;checksum high is + cmp ram_chksm+1 ;checksum high expected + trap_ne ;checksum mismatch + endm + else + check_ram macro + ;RAM check disabled - RAM size not set + endm + endif + + next_test macro ;make sure, tests don't jump the fence + lda test_case ;previous test + cmp #test_num + trap_ne ;test is out of sequence + test_num = test_num + 1 + lda #test_num ;*** next tests' number + sta test_case + ;check_ram ;uncomment to find altered RAM after each test + endm + + if load_data_direct = 1 + data + else + bss ;uninitialized segment, copy of data at end of code! + endif + ; org zero_page +0000 = org 0 ;edited to provide binaries loading from 0 +0000 : 00000000000000.. ds zero_page + ;break test interrupt save +000a : 00 irq_a ds 1 ;a register +000b : 00 irq_x ds 1 ;x register + if I_flag = 2 + ;masking for I bit in status + flag_I_on ds 1 ;or mask to load flags + flag_I_off ds 1 ;and mask to load flags + endif +000c : zpt ;5 bytes store/modify test area + ;add/subtract operand generation and result/flag prediction +000c : 00 adfc ds 1 ;carry flag before op +000d : 00 ad1 ds 1 ;operand 1 - accumulator +000e : 00 ad2 ds 1 ;operand 2 - memory / immediate +000f : 00 adrl ds 1 ;expected result bits 0-7 +0010 : 00 adrh ds 1 ;expected result bit 8 (carry) +0011 : 00 adrf ds 1 ;expected flags NV0000ZC (-V in decimal mode) +0012 : 00 sb2 ds 1 ;operand 2 complemented for subtract +0013 : zp_bss +0013 : c3824100 zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +0017 : 7f zp7f db $7f ;test pattern for compare + ;logical zeropage operands +0018 : 001f7180 zpOR db 0,$1f,$71,$80 ;test pattern for OR +001c : 0fff7f80 zpAN db $0f,$ff,$7f,$80 ;test pattern for AND +0020 : ff0f8f8f zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR + ;indirect addressing pointers +0024 : 1002 ind1 dw abs1 ;indirect pointer to pattern in absolute memory +0026 : 1102 dw abs1+1 +0028 : 1202 dw abs1+2 +002a : 1302 dw abs1+3 +002c : 1402 dw abs7f +002e : 1801 inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern +0030 : 0502 indt dw abst ;indirect pointer to store area in absolute memory +0032 : 0602 dw abst+1 +0034 : 0702 dw abst+2 +0036 : 0802 dw abst+3 +0038 : 0d01 inwt dw abst-$f8 ;indirect pointer for wrap-test store +003a : 4702 indAN dw absAN ;indirect pointer to AND pattern in absolute memory +003c : 4802 dw absAN+1 +003e : 4902 dw absAN+2 +0040 : 4a02 dw absAN+3 +0042 : 4b02 indEO dw absEO ;indirect pointer to EOR pattern in absolute memory +0044 : 4c02 dw absEO+1 +0046 : 4d02 dw absEO+2 +0048 : 4e02 dw absEO+3 +004a : 4302 indOR dw absOR ;indirect pointer to OR pattern in absolute memory +004c : 4402 dw absOR+1 +004e : 4502 dw absOR+2 +0050 : 4602 dw absOR+3 + ;add/subtract indirect pointers +0052 : 0502 adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory +0054 : 0602 sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC) +0056 : 0601 adiy2 dw ada2-$ff ;with offset for indirect indexed +0058 : 0701 sbiy2 dw sba2-$ff +005a : zp_bss_end + +0200 = org data_segment +0200 : 0000 pg_x ds 2 ;high JMP indirect address for page cross bug +0202 : 00 test_case ds 1 ;current test number +0203 : 0000 ram_chksm ds 2 ;checksum for RAM integrity test + ;add/subtract operand copy - abs tests write area +0205 : abst ;5 bytes store/modify test area +0205 : 00 ada2 ds 1 ;operand 2 +0206 : 00 sba2 ds 1 ;operand 2 complemented for subtract +0207 : 000000 ds 3 ;fill remaining bytes +020a : data_bss + if load_data_direct = 1 +020a : 6900 ex_adci adc #0 ;execute immediate opcodes +020c : 60 rts +020d : e900 ex_sbci sbc #0 ;execute immediate opcodes +020f : 60 rts + else + ex_adci ds 3 + ex_sbci ds 3 + endif +0210 : c3824100 abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR +0214 : 7f abs7f db $7f ;test pattern for compare + ;loads +0215 : 80800002 fLDx db fn,fn,0,fz ;expected flags for load + ;shifts +0219 : rASL ;expected result ASL & ROL -carry +0219 : 86048200 rROL db $86,$04,$82,0 ; " +021d : 87058301 rROLc db $87,$05,$83,1 ;expected result ROL +carry +0221 : rLSR ;expected result LSR & ROR -carry +0221 : 61412000 rROR db $61,$41,$20,0 ; " +0225 : e1c1a080 rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry +0229 : fASL ;expected flags for shifts +0229 : 81018002 fROL db fnc,fc,fn,fz ;no carry in +022d : 81018000 fROLc db fnc,fc,fn,0 ;carry in +0231 : fLSR +0231 : 01000102 fROR db fc,0,fc,fz ;no carry in +0235 : 81808180 fRORc db fnc,fn,fnc,fn ;carry in + ;increments (decrements) +0239 : 7f80ff0001 rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC +023e : 0080800200 fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC + ;logical memory operand +0243 : 001f7180 absOR db 0,$1f,$71,$80 ;test pattern for OR +0247 : 0fff7f80 absAN db $0f,$ff,$7f,$80 ;test pattern for AND +024b : ff0f8f8f absEO db $ff,$0f,$8f,$8f ;test pattern for EOR + ;logical accu operand +024f : 00f11f00 absORa db 0,$f1,$1f,0 ;test pattern for OR +0253 : f0ffffff absANa db $f0,$ff,$ff,$ff ;test pattern for AND +0257 : fff0f00f absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR + ;logical results +025b : 00ff7f80 absrlo db 0,$ff,$7f,$80 +025f : 02800080 absflo db fz,fn,0,fn +0263 : data_bss_end + ;define area for page crossing JMP (abs) & JMP (abs,x) test +02f9 = jxi_tab equ data_segment + $100 - 7 ;JMP (jxi_tab,x) x=6 +02fd = ji_tab equ data_segment + $100 - 3 ;JMP (ji_tab+2) +0300 = jxp_tab equ data_segment + $100 ;JMP (jxp_tab-255) x=255 + + + code +0400 = org code_segment +0400 : d8 start cld +0401 : a2ff ldx #$ff +0403 : 9a txs +0404 : a900 lda #0 ;*** test 0 = initialize +0406 : 8d0202 sta test_case +0000 = test_num = 0 + + ;stop interrupts before initializing BSS + if I_flag = 1 + sei + endif + + ;initialize I/O for report channel + if report = 1 + jsr report_init + endif + + ;initialize BSS segment + if load_data_direct != 1 + ldx #zp_end-zp_init-1 + ld_zp lda zp_init,x + sta zp_bss,x + dex + bpl ld_zp + ldx #data_end-data_init-1 + ld_data lda data_init,x + sta data_bss,x + dex + bpl ld_data + if ROM_vectors = 1 + ldx #5 + ld_vect lda vec_init,x + sta vec_bss,x + dex + bpl ld_vect + endif + endif + + ;retain status of interrupt flag + if I_flag = 2 + php + pla + and #4 ;isolate flag + sta flag_I_on ;or mask + eor #lo(~4) ;reverse + sta flag_I_off ;and mask + endif + + ;generate checksum for RAM integrity test + if ram_top > -1 + lda #0 + sta zpt ;set low byte of indirect pointer + sta ram_chksm+1 ;checksum high byte + ldx #11 ;reset modifiable RAM + gcs1 sta jxi_tab,x ;JMP indirect page cross area + dex + bpl gcs1 + clc + ldx #zp_bss-zero_page ;zeropage - write test area + gcs3 adc zero_page,x + bcc gcs2 + inc ram_chksm+1 ;carry to high byte + clc + gcs2 inx + bne gcs3 + ldx #hi(abs1) ;set high byte of indirect pointer + stx zpt+1 + ldy #lo(abs1) ;data after write & execute test area + gcs5 adc (zpt),y + bcc gcs4 + inc ram_chksm+1 ;carry to high byte + clc + gcs4 iny + bne gcs5 + inx ;advance RAM high address + stx zpt+1 + cpx #ram_top + bne gcs5 + sta ram_chksm ;checksum complete + endif + next_test +0409 : ad0202 > lda test_case ;previous test +040c : c900 > cmp #test_num + > trap_ne ;test is out of sequence +040e : d0fe > bne * ;failed not equal (non zero) + > +0001 = >test_num = test_num + 1 +0410 : a901 > lda #test_num ;*** next tests' number +0412 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ;testing stack operations PHX PHY PLX PLY +0415 : a999 lda #$99 ;protect a +0417 : a2ff ldx #$ff ;initialize stack +0419 : 9a txs +041a : a255 ldx #$55 +041c : da phx +041d : a2aa ldx #$aa +041f : da phx +0420 : ecfe01 cpx $1fe ;on stack ? + trap_ne +0423 : d0fe > bne * ;failed not equal (non zero) + +0425 : ba tsx +0426 : e0fd cpx #$fd ;sp decremented? + trap_ne +0428 : d0fe > bne * ;failed not equal (non zero) + +042a : 7a ply +042b : c0aa cpy #$aa ;successful retreived from stack? + trap_ne +042d : d0fe > bne * ;failed not equal (non zero) + +042f : 7a ply +0430 : c055 cpy #$55 + trap_ne +0432 : d0fe > bne * ;failed not equal (non zero) + +0434 : ccff01 cpy $1ff ;remains on stack? + trap_ne +0437 : d0fe > bne * ;failed not equal (non zero) + +0439 : ba tsx +043a : e0ff cpx #$ff ;sp incremented? + trap_ne +043c : d0fe > bne * ;failed not equal (non zero) + + +043e : a0a5 ldy #$a5 +0440 : 5a phy +0441 : a05a ldy #$5a +0443 : 5a phy +0444 : ccfe01 cpy $1fe ;on stack ? + trap_ne +0447 : d0fe > bne * ;failed not equal (non zero) + +0449 : ba tsx +044a : e0fd cpx #$fd ;sp decremented? + trap_ne +044c : d0fe > bne * ;failed not equal (non zero) + +044e : fa plx +044f : e05a cpx #$5a ;successful retreived from stack? + trap_ne +0451 : d0fe > bne * ;failed not equal (non zero) + +0453 : fa plx +0454 : e0a5 cpx #$a5 + trap_ne +0456 : d0fe > bne * ;failed not equal (non zero) + +0458 : ecff01 cpx $1ff ;remains on stack? + trap_ne +045b : d0fe > bne * ;failed not equal (non zero) + +045d : ba tsx +045e : e0ff cpx #$ff ;sp incremented? + trap_ne +0460 : d0fe > bne * ;failed not equal (non zero) + +0462 : c999 cmp #$99 ;unchanged? + trap_ne +0464 : d0fe > bne * ;failed not equal (non zero) + + next_test +0466 : ad0202 > lda test_case ;previous test +0469 : c901 > cmp #test_num + > trap_ne ;test is out of sequence +046b : d0fe > bne * ;failed not equal (non zero) + > +0002 = >test_num = test_num + 1 +046d : a902 > lda #test_num ;*** next tests' number +046f : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; test PHX does not alter flags or X but PLX does +0472 : a0aa ldy #$aa ;protect y + set_x 1,$ff ;push + > load_flag $ff +0474 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0476 : 48 > pha ;use stack to load status +0477 : a201 > ldx #1 ;precharge index x +0479 : 28 > plp + +047a : da phx + tst_x 1,$ff +047b : 08 > php ;save flags +047c : e001 > cpx #1 ;test result + > trap_ne +047e : d0fe > bne * ;failed not equal (non zero) + > +0480 : 68 > pla ;load status +0481 : 48 > pha + > cmp_flag $ff +0482 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0484 : d0fe > bne * ;failed not equal (non zero) + > +0486 : 28 > plp ;restore status + + set_x 0,0 + > load_flag 0 +0487 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0489 : 48 > pha ;use stack to load status +048a : a200 > ldx #0 ;precharge index x +048c : 28 > plp + +048d : da phx + tst_x 0,0 +048e : 08 > php ;save flags +048f : e000 > cpx #0 ;test result + > trap_ne +0491 : d0fe > bne * ;failed not equal (non zero) + > +0493 : 68 > pla ;load status +0494 : 48 > pha + > cmp_flag 0 +0495 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0497 : d0fe > bne * ;failed not equal (non zero) + > +0499 : 28 > plp ;restore status + + set_x $ff,$ff + > load_flag $ff +049a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +049c : 48 > pha ;use stack to load status +049d : a2ff > ldx #$ff ;precharge index x +049f : 28 > plp + +04a0 : da phx + tst_x $ff,$ff +04a1 : 08 > php ;save flags +04a2 : e0ff > cpx #$ff ;test result + > trap_ne +04a4 : d0fe > bne * ;failed not equal (non zero) + > +04a6 : 68 > pla ;load status +04a7 : 48 > pha + > cmp_flag $ff +04a8 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +04aa : d0fe > bne * ;failed not equal (non zero) + > +04ac : 28 > plp ;restore status + + set_x 1,0 + > load_flag 0 +04ad : a900 > lda #0 ;allow test to change I-flag (no mask) + > +04af : 48 > pha ;use stack to load status +04b0 : a201 > ldx #1 ;precharge index x +04b2 : 28 > plp + +04b3 : da phx + tst_x 1,0 +04b4 : 08 > php ;save flags +04b5 : e001 > cpx #1 ;test result + > trap_ne +04b7 : d0fe > bne * ;failed not equal (non zero) + > +04b9 : 68 > pla ;load status +04ba : 48 > pha + > cmp_flag 0 +04bb : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +04bd : d0fe > bne * ;failed not equal (non zero) + > +04bf : 28 > plp ;restore status + + set_x 0,$ff + > load_flag $ff +04c0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +04c2 : 48 > pha ;use stack to load status +04c3 : a200 > ldx #0 ;precharge index x +04c5 : 28 > plp + +04c6 : da phx + tst_x 0,$ff +04c7 : 08 > php ;save flags +04c8 : e000 > cpx #0 ;test result + > trap_ne +04ca : d0fe > bne * ;failed not equal (non zero) + > +04cc : 68 > pla ;load status +04cd : 48 > pha + > cmp_flag $ff +04ce : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +04d0 : d0fe > bne * ;failed not equal (non zero) + > +04d2 : 28 > plp ;restore status + + set_x $ff,0 + > load_flag 0 +04d3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +04d5 : 48 > pha ;use stack to load status +04d6 : a2ff > ldx #$ff ;precharge index x +04d8 : 28 > plp + +04d9 : da phx + tst_x $ff,0 +04da : 08 > php ;save flags +04db : e0ff > cpx #$ff ;test result + > trap_ne +04dd : d0fe > bne * ;failed not equal (non zero) + > +04df : 68 > pla ;load status +04e0 : 48 > pha + > cmp_flag 0 +04e1 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +04e3 : d0fe > bne * ;failed not equal (non zero) + > +04e5 : 28 > plp ;restore status + + set_x 0,$ff ;pull + > load_flag $ff +04e6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +04e8 : 48 > pha ;use stack to load status +04e9 : a200 > ldx #0 ;precharge index x +04eb : 28 > plp + +04ec : fa plx + tst_x $ff,$ff-zero +04ed : 08 > php ;save flags +04ee : e0ff > cpx #$ff ;test result + > trap_ne +04f0 : d0fe > bne * ;failed not equal (non zero) + > +04f2 : 68 > pla ;load status +04f3 : 48 > pha + > cmp_flag $ff-zero +04f4 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +04f6 : d0fe > bne * ;failed not equal (non zero) + > +04f8 : 28 > plp ;restore status + + set_x $ff,0 + > load_flag 0 +04f9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +04fb : 48 > pha ;use stack to load status +04fc : a2ff > ldx #$ff ;precharge index x +04fe : 28 > plp + +04ff : fa plx + tst_x 0,zero +0500 : 08 > php ;save flags +0501 : e000 > cpx #0 ;test result + > trap_ne +0503 : d0fe > bne * ;failed not equal (non zero) + > +0505 : 68 > pla ;load status +0506 : 48 > pha + > cmp_flag zero +0507 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0509 : d0fe > bne * ;failed not equal (non zero) + > +050b : 28 > plp ;restore status + + set_x $fe,$ff + > load_flag $ff +050c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +050e : 48 > pha ;use stack to load status +050f : a2fe > ldx #$fe ;precharge index x +0511 : 28 > plp + +0512 : fa plx + tst_x 1,$ff-zero-minus +0513 : 08 > php ;save flags +0514 : e001 > cpx #1 ;test result + > trap_ne +0516 : d0fe > bne * ;failed not equal (non zero) + > +0518 : 68 > pla ;load status +0519 : 48 > pha + > cmp_flag $ff-zero-minus +051a : c97d > cmp #($ff-zero-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +051c : d0fe > bne * ;failed not equal (non zero) + > +051e : 28 > plp ;restore status + + set_x 0,0 + > load_flag 0 +051f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0521 : 48 > pha ;use stack to load status +0522 : a200 > ldx #0 ;precharge index x +0524 : 28 > plp + +0525 : fa plx + tst_x $ff,minus +0526 : 08 > php ;save flags +0527 : e0ff > cpx #$ff ;test result + > trap_ne +0529 : d0fe > bne * ;failed not equal (non zero) + > +052b : 68 > pla ;load status +052c : 48 > pha + > cmp_flag minus +052d : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +052f : d0fe > bne * ;failed not equal (non zero) + > +0531 : 28 > plp ;restore status + + set_x $ff,$ff + > load_flag $ff +0532 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0534 : 48 > pha ;use stack to load status +0535 : a2ff > ldx #$ff ;precharge index x +0537 : 28 > plp + +0538 : fa plx + tst_x 0,$ff-minus +0539 : 08 > php ;save flags +053a : e000 > cpx #0 ;test result + > trap_ne +053c : d0fe > bne * ;failed not equal (non zero) + > +053e : 68 > pla ;load status +053f : 48 > pha + > cmp_flag $ff-minus +0540 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0542 : d0fe > bne * ;failed not equal (non zero) + > +0544 : 28 > plp ;restore status + + set_x $fe,0 + > load_flag 0 +0545 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0547 : 48 > pha ;use stack to load status +0548 : a2fe > ldx #$fe ;precharge index x +054a : 28 > plp + +054b : fa plx + tst_x 1,0 +054c : 08 > php ;save flags +054d : e001 > cpx #1 ;test result + > trap_ne +054f : d0fe > bne * ;failed not equal (non zero) + > +0551 : 68 > pla ;load status +0552 : 48 > pha + > cmp_flag 0 +0553 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0555 : d0fe > bne * ;failed not equal (non zero) + > +0557 : 28 > plp ;restore status + +0558 : c0aa cpy #$aa ;Y unchanged + trap_ne +055a : d0fe > bne * ;failed not equal (non zero) + + next_test +055c : ad0202 > lda test_case ;previous test +055f : c902 > cmp #test_num + > trap_ne ;test is out of sequence +0561 : d0fe > bne * ;failed not equal (non zero) + > +0003 = >test_num = test_num + 1 +0563 : a903 > lda #test_num ;*** next tests' number +0565 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; test PHY does not alter flags or Y but PLY does +0568 : a255 ldx #$55 ;x & a protected + set_y 1,$ff ;push + > load_flag $ff +056a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +056c : 48 > pha ;use stack to load status +056d : a001 > ldy #1 ;precharge index y +056f : 28 > plp + +0570 : 5a phy + tst_y 1,$ff +0571 : 08 > php ;save flags +0572 : c001 > cpy #1 ;test result + > trap_ne +0574 : d0fe > bne * ;failed not equal (non zero) + > +0576 : 68 > pla ;load status +0577 : 48 > pha + > cmp_flag $ff +0578 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +057a : d0fe > bne * ;failed not equal (non zero) + > +057c : 28 > plp ;restore status + + set_y 0,0 + > load_flag 0 +057d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +057f : 48 > pha ;use stack to load status +0580 : a000 > ldy #0 ;precharge index y +0582 : 28 > plp + +0583 : 5a phy + tst_y 0,0 +0584 : 08 > php ;save flags +0585 : c000 > cpy #0 ;test result + > trap_ne +0587 : d0fe > bne * ;failed not equal (non zero) + > +0589 : 68 > pla ;load status +058a : 48 > pha + > cmp_flag 0 +058b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +058d : d0fe > bne * ;failed not equal (non zero) + > +058f : 28 > plp ;restore status + + set_y $ff,$ff + > load_flag $ff +0590 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0592 : 48 > pha ;use stack to load status +0593 : a0ff > ldy #$ff ;precharge index y +0595 : 28 > plp + +0596 : 5a phy + tst_y $ff,$ff +0597 : 08 > php ;save flags +0598 : c0ff > cpy #$ff ;test result + > trap_ne +059a : d0fe > bne * ;failed not equal (non zero) + > +059c : 68 > pla ;load status +059d : 48 > pha + > cmp_flag $ff +059e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05a0 : d0fe > bne * ;failed not equal (non zero) + > +05a2 : 28 > plp ;restore status + + set_y 1,0 + > load_flag 0 +05a3 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +05a5 : 48 > pha ;use stack to load status +05a6 : a001 > ldy #1 ;precharge index y +05a8 : 28 > plp + +05a9 : 5a phy + tst_y 1,0 +05aa : 08 > php ;save flags +05ab : c001 > cpy #1 ;test result + > trap_ne +05ad : d0fe > bne * ;failed not equal (non zero) + > +05af : 68 > pla ;load status +05b0 : 48 > pha + > cmp_flag 0 +05b1 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05b3 : d0fe > bne * ;failed not equal (non zero) + > +05b5 : 28 > plp ;restore status + + set_y 0,$ff + > load_flag $ff +05b6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +05b8 : 48 > pha ;use stack to load status +05b9 : a000 > ldy #0 ;precharge index y +05bb : 28 > plp + +05bc : 5a phy + tst_y 0,$ff +05bd : 08 > php ;save flags +05be : c000 > cpy #0 ;test result + > trap_ne +05c0 : d0fe > bne * ;failed not equal (non zero) + > +05c2 : 68 > pla ;load status +05c3 : 48 > pha + > cmp_flag $ff +05c4 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05c6 : d0fe > bne * ;failed not equal (non zero) + > +05c8 : 28 > plp ;restore status + + set_y $ff,0 + > load_flag 0 +05c9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +05cb : 48 > pha ;use stack to load status +05cc : a0ff > ldy #$ff ;precharge index y +05ce : 28 > plp + +05cf : 5a phy + tst_y $ff,0 +05d0 : 08 > php ;save flags +05d1 : c0ff > cpy #$ff ;test result + > trap_ne +05d3 : d0fe > bne * ;failed not equal (non zero) + > +05d5 : 68 > pla ;load status +05d6 : 48 > pha + > cmp_flag 0 +05d7 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05d9 : d0fe > bne * ;failed not equal (non zero) + > +05db : 28 > plp ;restore status + + set_y 0,$ff ;pull + > load_flag $ff +05dc : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +05de : 48 > pha ;use stack to load status +05df : a000 > ldy #0 ;precharge index y +05e1 : 28 > plp + +05e2 : 7a ply + tst_y $ff,$ff-zero +05e3 : 08 > php ;save flags +05e4 : c0ff > cpy #$ff ;test result + > trap_ne +05e6 : d0fe > bne * ;failed not equal (non zero) + > +05e8 : 68 > pla ;load status +05e9 : 48 > pha + > cmp_flag $ff-zero +05ea : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05ec : d0fe > bne * ;failed not equal (non zero) + > +05ee : 28 > plp ;restore status + + set_y $ff,0 + > load_flag 0 +05ef : a900 > lda #0 ;allow test to change I-flag (no mask) + > +05f1 : 48 > pha ;use stack to load status +05f2 : a0ff > ldy #$ff ;precharge index y +05f4 : 28 > plp + +05f5 : 7a ply + tst_y 0,zero +05f6 : 08 > php ;save flags +05f7 : c000 > cpy #0 ;test result + > trap_ne +05f9 : d0fe > bne * ;failed not equal (non zero) + > +05fb : 68 > pla ;load status +05fc : 48 > pha + > cmp_flag zero +05fd : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +05ff : d0fe > bne * ;failed not equal (non zero) + > +0601 : 28 > plp ;restore status + + set_y $fe,$ff + > load_flag $ff +0602 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0604 : 48 > pha ;use stack to load status +0605 : a0fe > ldy #$fe ;precharge index y +0607 : 28 > plp + +0608 : 7a ply + tst_y 1,$ff-zero-minus +0609 : 08 > php ;save flags +060a : c001 > cpy #1 ;test result + > trap_ne +060c : d0fe > bne * ;failed not equal (non zero) + > +060e : 68 > pla ;load status +060f : 48 > pha + > cmp_flag $ff-zero-minus +0610 : c97d > cmp #($ff-zero-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0612 : d0fe > bne * ;failed not equal (non zero) + > +0614 : 28 > plp ;restore status + + set_y 0,0 + > load_flag 0 +0615 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0617 : 48 > pha ;use stack to load status +0618 : a000 > ldy #0 ;precharge index y +061a : 28 > plp + +061b : 7a ply + tst_y $ff,minus +061c : 08 > php ;save flags +061d : c0ff > cpy #$ff ;test result + > trap_ne +061f : d0fe > bne * ;failed not equal (non zero) + > +0621 : 68 > pla ;load status +0622 : 48 > pha + > cmp_flag minus +0623 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0625 : d0fe > bne * ;failed not equal (non zero) + > +0627 : 28 > plp ;restore status + + set_y $ff,$ff + > load_flag $ff +0628 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +062a : 48 > pha ;use stack to load status +062b : a0ff > ldy #$ff ;precharge index y +062d : 28 > plp + +062e : 7a ply + tst_y 0,$ff-minus +062f : 08 > php ;save flags +0630 : c000 > cpy #0 ;test result + > trap_ne +0632 : d0fe > bne * ;failed not equal (non zero) + > +0634 : 68 > pla ;load status +0635 : 48 > pha + > cmp_flag $ff-minus +0636 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0638 : d0fe > bne * ;failed not equal (non zero) + > +063a : 28 > plp ;restore status + + set_y $fe,0 + > load_flag 0 +063b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +063d : 48 > pha ;use stack to load status +063e : a0fe > ldy #$fe ;precharge index y +0640 : 28 > plp + +0641 : 7a ply + tst_y 1,0 +0642 : 08 > php ;save flags +0643 : c001 > cpy #1 ;test result + > trap_ne +0645 : d0fe > bne * ;failed not equal (non zero) + > +0647 : 68 > pla ;load status +0648 : 48 > pha + > cmp_flag 0 +0649 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +064b : d0fe > bne * ;failed not equal (non zero) + > +064d : 28 > plp ;restore status + +064e : e055 cpx #$55 ;x unchanged? + trap_ne +0650 : d0fe > bne * ;failed not equal (non zero) + + next_test +0652 : ad0202 > lda test_case ;previous test +0655 : c903 > cmp #test_num + > trap_ne ;test is out of sequence +0657 : d0fe > bne * ;failed not equal (non zero) + > +0004 = >test_num = test_num + 1 +0659 : a904 > lda #test_num ;*** next tests' number +065b : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; PC modifying instructions (BRA, BBR, BBS, 1, 2, 3 byte NOPs, JMP(abs,x)) + ; testing unconditional branch BRA + +065e : a281 ldx #$81 ;protect unused registers +0660 : a07e ldy #$7e + set_a 0,$ff + > load_flag $ff +0662 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0664 : 48 > pha ;use stack to load status +0665 : a900 > lda #0 ;precharge accu +0667 : 28 > plp + +0668 : 8003 bra br1 ;branch should always be taken + trap +066a : 4c6a06 > jmp * ;failed anyway + +066d : br1 + tst_a 0,$ff +066d : 08 > php ;save flags +066e : c900 > cmp #0 ;test result + > trap_ne +0670 : d0fe > bne * ;failed not equal (non zero) + > +0672 : 68 > pla ;load status +0673 : 48 > pha + > cmp_flag $ff +0674 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0676 : d0fe > bne * ;failed not equal (non zero) + > +0678 : 28 > plp ;restore status + + set_a $ff,0 + > load_flag 0 +0679 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +067b : 48 > pha ;use stack to load status +067c : a9ff > lda #$ff ;precharge accu +067e : 28 > plp + +067f : 8003 bra br2 ;branch should always be taken + trap +0681 : 4c8106 > jmp * ;failed anyway + +0684 : br2 + tst_a $ff,0 +0684 : 08 > php ;save flags +0685 : c9ff > cmp #$ff ;test result + > trap_ne +0687 : d0fe > bne * ;failed not equal (non zero) + > +0689 : 68 > pla ;load status +068a : 48 > pha + > cmp_flag 0 +068b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +068d : d0fe > bne * ;failed not equal (non zero) + > +068f : 28 > plp ;restore status + +0690 : e081 cpx #$81 + trap_ne +0692 : d0fe > bne * ;failed not equal (non zero) + +0694 : c07e cpy #$7e + trap_ne +0696 : d0fe > bne * ;failed not equal (non zero) + + next_test +0698 : ad0202 > lda test_case ;previous test +069b : c904 > cmp #test_num + > trap_ne ;test is out of sequence +069d : d0fe > bne * ;failed not equal (non zero) + > +0005 = >test_num = test_num + 1 +069f : a905 > lda #test_num ;*** next tests' number +06a1 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + +06a4 : a000 ldy #0 ;branch range test +06a6 : 8061 bra bra0 + +06a8 : c001 bra1 cpy #1 + trap_ne ;long range backward +06aa : d0fe > bne * ;failed not equal (non zero) + +06ac : c8 iny +06ad : 8053 bra bra2 + +06af : c003 bra3 cpy #3 + trap_ne ;long range backward +06b1 : d0fe > bne * ;failed not equal (non zero) + +06b3 : c8 iny +06b4 : 8045 bra bra4 + +06b6 : c005 bra5 cpy #5 + trap_ne ;long range backward +06b8 : d0fe > bne * ;failed not equal (non zero) + +06ba : c8 iny +06bb : a000 ldy #0 +06bd : 8004 bra brf0 + +06bf : c8 iny +06c0 : c8 iny +06c1 : c8 iny +06c2 : c8 iny +06c3 : 8003 brf0 bra brf1 + +06c5 : c8 iny +06c6 : c8 iny +06c7 : c8 iny +06c8 : c8 brf1 iny +06c9 : 8002 bra brf2 + +06cb : c8 iny +06cc : c8 iny +06cd : c8 brf2 iny +06ce : c8 iny +06cf : 8001 bra brf3 + +06d1 : c8 iny +06d2 : c8 brf3 iny +06d3 : c8 iny +06d4 : c8 iny +06d5 : 8000 bra brf4 + +06d7 : c8 brf4 iny +06d8 : c8 iny +06d9 : c8 iny +06da : c8 iny +06db : c00a cpy #10 + trap_ne ;short range forward +06dd : d0fe > bne * ;failed not equal (non zero) + +06df : 8012 bra brb0 + +06e1 : 88 brb4 dey +06e2 : 88 dey +06e3 : 88 dey +06e4 : 88 dey +06e5 : 800e bra brb5 + +06e7 : 88 brb3 dey +06e8 : 88 dey +06e9 : 88 dey +06ea : 80f5 bra brb4 + +06ec : 88 brb2 dey +06ed : 88 dey +06ee : 80f7 bra brb3 + +06f0 : 88 brb1 dey +06f1 : 80f9 bra brb2 + +06f3 : 80fb brb0 bra brb1 + +06f5 : c000 brb5 cpy #0 + trap_ne ;short range backward +06f7 : d0fe > bne * ;failed not equal (non zero) + +06f9 : 8015 bra bra6 + +06fb : c004 bra4 cpy #4 + trap_ne ;long range forward +06fd : d0fe > bne * ;failed not equal (non zero) + +06ff : c8 iny +0700 : 80b4 bra bra5 + +0702 : c002 bra2 cpy #2 + trap_ne ;long range forward +0704 : d0fe > bne * ;failed not equal (non zero) + +0706 : c8 iny +0707 : 80a6 bra bra3 + +0709 : c000 bra0 cpy #0 + trap_ne ;long range forward +070b : d0fe > bne * ;failed not equal (non zero) + +070d : c8 iny +070e : 8098 bra bra1 + +0710 : bra6 + next_test +0710 : ad0202 > lda test_case ;previous test +0713 : c905 > cmp #test_num + > trap_ne ;test is out of sequence +0715 : d0fe > bne * ;failed not equal (non zero) + > +0006 = >test_num = test_num + 1 +0717 : a906 > lda #test_num ;*** next tests' number +0719 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + if rkwl_wdc_op = 1 + ; testing BBR & BBS + + bbt macro ;\1 = bitnum + lda #(1<<\1) ;testing 1 bit on + sta zpt + set_a $33,0 ;with flags off + bbr \1,zpt,fail1\? + bbs \1,zpt,ok1\? + trap ;bbs branch not taken + fail1\? + trap ;bbr branch taken + ok1\? + tst_a $33,0 + set_a $cc,$ff ;with flags on + bbr \1,zpt,fail2\? + bbs \1,zpt,ok2\? + trap ;bbs branch not taken + fail2\? + trap ;bbr branch taken + ok2\? + tst_a $cc,$ff + lda zpt + cmp #(1<<\1) + trap_ne ;zp altered + lda #$ff-(1<<\1) ;testing 1 bit off + sta zpt + set_a $33,0 ;with flags off + bbs \1,zpt,fail3\? + bbr \1,zpt,ok3\? + trap ;bbr branch not taken + fail3\? + trap ;bbs branch taken + ok3\? + tst_a $33,0 + set_a $cc,$ff ;with flags on + bbs \1,zpt,fail4\? + bbr \1,zpt,ok4\? + trap ;bbr branch not taken + fail4\? + trap ;bbs branch taken + ok4\? + tst_a $cc,$ff + lda zpt + cmp #$ff-(1<<\1) + trap_ne ;zp altered + endm + +071c : a211 ldx #$11 ;test bbr/bbs integrity +071e : a022 ldy #$22 + bbt 0 +0720 : a901 > lda #(1<<0) ;testing 1 bit on +0722 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0724 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0726 : 48 > pha ;use stack to load status +0727 : a933 > lda #$33 ;precharge accu +0729 : 28 > plp + > +072a : 0f0c06 > bbr 0,zpt,fail10196 +072d : 8f0c06 > bbs 0,zpt,ok10196 + > trap ;bbs branch not taken +0730 : 4c3007 > jmp * ;failed anyway + > +0733 : >fail10196 + > trap ;bbr branch taken +0733 : 4c3307 > jmp * ;failed anyway + > +0736 : >ok10196 + > tst_a $33,0 +0736 : 08 > php ;save flags +0737 : c933 > cmp #$33 ;test result + > trap_ne +0739 : d0fe > bne * ;failed not equal (non zero) + > +073b : 68 > pla ;load status +073c : 48 > pha + > cmp_flag 0 +073d : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +073f : d0fe > bne * ;failed not equal (non zero) + > +0741 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0742 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0744 : 48 > pha ;use stack to load status +0745 : a9cc > lda #$cc ;precharge accu +0747 : 28 > plp + > +0748 : 0f0c06 > bbr 0,zpt,fail20196 +074b : 8f0c06 > bbs 0,zpt,ok20196 + > trap ;bbs branch not taken +074e : 4c4e07 > jmp * ;failed anyway + > +0751 : >fail20196 + > trap ;bbr branch taken +0751 : 4c5107 > jmp * ;failed anyway + > +0754 : >ok20196 + > tst_a $cc,$ff +0754 : 08 > php ;save flags +0755 : c9cc > cmp #$cc ;test result + > trap_ne +0757 : d0fe > bne * ;failed not equal (non zero) + > +0759 : 68 > pla ;load status +075a : 48 > pha + > cmp_flag $ff +075b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +075d : d0fe > bne * ;failed not equal (non zero) + > +075f : 28 > plp ;restore status + > +0760 : a50c > lda zpt +0762 : c901 > cmp #(1<<0) + > trap_ne ;zp altered +0764 : d0fe > bne * ;failed not equal (non zero) + > +0766 : a9fe > lda #$ff-(1<<0) ;testing 1 bit off +0768 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +076a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +076c : 48 > pha ;use stack to load status +076d : a933 > lda #$33 ;precharge accu +076f : 28 > plp + > +0770 : 8f0c06 > bbs 0,zpt,fail30196 +0773 : 0f0c06 > bbr 0,zpt,ok30196 + > trap ;bbr branch not taken +0776 : 4c7607 > jmp * ;failed anyway + > +0779 : >fail30196 + > trap ;bbs branch taken +0779 : 4c7907 > jmp * ;failed anyway + > +077c : >ok30196 + > tst_a $33,0 +077c : 08 > php ;save flags +077d : c933 > cmp #$33 ;test result + > trap_ne +077f : d0fe > bne * ;failed not equal (non zero) + > +0781 : 68 > pla ;load status +0782 : 48 > pha + > cmp_flag 0 +0783 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0785 : d0fe > bne * ;failed not equal (non zero) + > +0787 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0788 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +078a : 48 > pha ;use stack to load status +078b : a9cc > lda #$cc ;precharge accu +078d : 28 > plp + > +078e : 8f0c06 > bbs 0,zpt,fail40196 +0791 : 0f0c06 > bbr 0,zpt,ok40196 + > trap ;bbr branch not taken +0794 : 4c9407 > jmp * ;failed anyway + > +0797 : >fail40196 + > trap ;bbs branch taken +0797 : 4c9707 > jmp * ;failed anyway + > +079a : >ok40196 + > tst_a $cc,$ff +079a : 08 > php ;save flags +079b : c9cc > cmp #$cc ;test result + > trap_ne +079d : d0fe > bne * ;failed not equal (non zero) + > +079f : 68 > pla ;load status +07a0 : 48 > pha + > cmp_flag $ff +07a1 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07a3 : d0fe > bne * ;failed not equal (non zero) + > +07a5 : 28 > plp ;restore status + > +07a6 : a50c > lda zpt +07a8 : c9fe > cmp #$ff-(1<<0) + > trap_ne ;zp altered +07aa : d0fe > bne * ;failed not equal (non zero) + > + + bbt 1 +07ac : a902 > lda #(1<<1) ;testing 1 bit on +07ae : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +07b0 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +07b2 : 48 > pha ;use stack to load status +07b3 : a933 > lda #$33 ;precharge accu +07b5 : 28 > plp + > +07b6 : 1f0c06 > bbr 1,zpt,fail10231 +07b9 : 9f0c06 > bbs 1,zpt,ok10231 + > trap ;bbs branch not taken +07bc : 4cbc07 > jmp * ;failed anyway + > +07bf : >fail10231 + > trap ;bbr branch taken +07bf : 4cbf07 > jmp * ;failed anyway + > +07c2 : >ok10231 + > tst_a $33,0 +07c2 : 08 > php ;save flags +07c3 : c933 > cmp #$33 ;test result + > trap_ne +07c5 : d0fe > bne * ;failed not equal (non zero) + > +07c7 : 68 > pla ;load status +07c8 : 48 > pha + > cmp_flag 0 +07c9 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07cb : d0fe > bne * ;failed not equal (non zero) + > +07cd : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +07ce : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +07d0 : 48 > pha ;use stack to load status +07d1 : a9cc > lda #$cc ;precharge accu +07d3 : 28 > plp + > +07d4 : 1f0c06 > bbr 1,zpt,fail20231 +07d7 : 9f0c06 > bbs 1,zpt,ok20231 + > trap ;bbs branch not taken +07da : 4cda07 > jmp * ;failed anyway + > +07dd : >fail20231 + > trap ;bbr branch taken +07dd : 4cdd07 > jmp * ;failed anyway + > +07e0 : >ok20231 + > tst_a $cc,$ff +07e0 : 08 > php ;save flags +07e1 : c9cc > cmp #$cc ;test result + > trap_ne +07e3 : d0fe > bne * ;failed not equal (non zero) + > +07e5 : 68 > pla ;load status +07e6 : 48 > pha + > cmp_flag $ff +07e7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +07e9 : d0fe > bne * ;failed not equal (non zero) + > +07eb : 28 > plp ;restore status + > +07ec : a50c > lda zpt +07ee : c902 > cmp #(1<<1) + > trap_ne ;zp altered +07f0 : d0fe > bne * ;failed not equal (non zero) + > +07f2 : a9fd > lda #$ff-(1<<1) ;testing 1 bit off +07f4 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +07f6 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +07f8 : 48 > pha ;use stack to load status +07f9 : a933 > lda #$33 ;precharge accu +07fb : 28 > plp + > +07fc : 9f0c06 > bbs 1,zpt,fail30231 +07ff : 1f0c06 > bbr 1,zpt,ok30231 + > trap ;bbr branch not taken +0802 : 4c0208 > jmp * ;failed anyway + > +0805 : >fail30231 + > trap ;bbs branch taken +0805 : 4c0508 > jmp * ;failed anyway + > +0808 : >ok30231 + > tst_a $33,0 +0808 : 08 > php ;save flags +0809 : c933 > cmp #$33 ;test result + > trap_ne +080b : d0fe > bne * ;failed not equal (non zero) + > +080d : 68 > pla ;load status +080e : 48 > pha + > cmp_flag 0 +080f : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0811 : d0fe > bne * ;failed not equal (non zero) + > +0813 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0814 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0816 : 48 > pha ;use stack to load status +0817 : a9cc > lda #$cc ;precharge accu +0819 : 28 > plp + > +081a : 9f0c06 > bbs 1,zpt,fail40231 +081d : 1f0c06 > bbr 1,zpt,ok40231 + > trap ;bbr branch not taken +0820 : 4c2008 > jmp * ;failed anyway + > +0823 : >fail40231 + > trap ;bbs branch taken +0823 : 4c2308 > jmp * ;failed anyway + > +0826 : >ok40231 + > tst_a $cc,$ff +0826 : 08 > php ;save flags +0827 : c9cc > cmp #$cc ;test result + > trap_ne +0829 : d0fe > bne * ;failed not equal (non zero) + > +082b : 68 > pla ;load status +082c : 48 > pha + > cmp_flag $ff +082d : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +082f : d0fe > bne * ;failed not equal (non zero) + > +0831 : 28 > plp ;restore status + > +0832 : a50c > lda zpt +0834 : c9fd > cmp #$ff-(1<<1) + > trap_ne ;zp altered +0836 : d0fe > bne * ;failed not equal (non zero) + > + + bbt 2 +0838 : a904 > lda #(1<<2) ;testing 1 bit on +083a : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +083c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +083e : 48 > pha ;use stack to load status +083f : a933 > lda #$33 ;precharge accu +0841 : 28 > plp + > +0842 : 2f0c06 > bbr 2,zpt,fail10266 +0845 : af0c06 > bbs 2,zpt,ok10266 + > trap ;bbs branch not taken +0848 : 4c4808 > jmp * ;failed anyway + > +084b : >fail10266 + > trap ;bbr branch taken +084b : 4c4b08 > jmp * ;failed anyway + > +084e : >ok10266 + > tst_a $33,0 +084e : 08 > php ;save flags +084f : c933 > cmp #$33 ;test result + > trap_ne +0851 : d0fe > bne * ;failed not equal (non zero) + > +0853 : 68 > pla ;load status +0854 : 48 > pha + > cmp_flag 0 +0855 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0857 : d0fe > bne * ;failed not equal (non zero) + > +0859 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +085a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +085c : 48 > pha ;use stack to load status +085d : a9cc > lda #$cc ;precharge accu +085f : 28 > plp + > +0860 : 2f0c06 > bbr 2,zpt,fail20266 +0863 : af0c06 > bbs 2,zpt,ok20266 + > trap ;bbs branch not taken +0866 : 4c6608 > jmp * ;failed anyway + > +0869 : >fail20266 + > trap ;bbr branch taken +0869 : 4c6908 > jmp * ;failed anyway + > +086c : >ok20266 + > tst_a $cc,$ff +086c : 08 > php ;save flags +086d : c9cc > cmp #$cc ;test result + > trap_ne +086f : d0fe > bne * ;failed not equal (non zero) + > +0871 : 68 > pla ;load status +0872 : 48 > pha + > cmp_flag $ff +0873 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0875 : d0fe > bne * ;failed not equal (non zero) + > +0877 : 28 > plp ;restore status + > +0878 : a50c > lda zpt +087a : c904 > cmp #(1<<2) + > trap_ne ;zp altered +087c : d0fe > bne * ;failed not equal (non zero) + > +087e : a9fb > lda #$ff-(1<<2) ;testing 1 bit off +0880 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0882 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0884 : 48 > pha ;use stack to load status +0885 : a933 > lda #$33 ;precharge accu +0887 : 28 > plp + > +0888 : af0c06 > bbs 2,zpt,fail30266 +088b : 2f0c06 > bbr 2,zpt,ok30266 + > trap ;bbr branch not taken +088e : 4c8e08 > jmp * ;failed anyway + > +0891 : >fail30266 + > trap ;bbs branch taken +0891 : 4c9108 > jmp * ;failed anyway + > +0894 : >ok30266 + > tst_a $33,0 +0894 : 08 > php ;save flags +0895 : c933 > cmp #$33 ;test result + > trap_ne +0897 : d0fe > bne * ;failed not equal (non zero) + > +0899 : 68 > pla ;load status +089a : 48 > pha + > cmp_flag 0 +089b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +089d : d0fe > bne * ;failed not equal (non zero) + > +089f : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +08a0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +08a2 : 48 > pha ;use stack to load status +08a3 : a9cc > lda #$cc ;precharge accu +08a5 : 28 > plp + > +08a6 : af0c06 > bbs 2,zpt,fail40266 +08a9 : 2f0c06 > bbr 2,zpt,ok40266 + > trap ;bbr branch not taken +08ac : 4cac08 > jmp * ;failed anyway + > +08af : >fail40266 + > trap ;bbs branch taken +08af : 4caf08 > jmp * ;failed anyway + > +08b2 : >ok40266 + > tst_a $cc,$ff +08b2 : 08 > php ;save flags +08b3 : c9cc > cmp #$cc ;test result + > trap_ne +08b5 : d0fe > bne * ;failed not equal (non zero) + > +08b7 : 68 > pla ;load status +08b8 : 48 > pha + > cmp_flag $ff +08b9 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +08bb : d0fe > bne * ;failed not equal (non zero) + > +08bd : 28 > plp ;restore status + > +08be : a50c > lda zpt +08c0 : c9fb > cmp #$ff-(1<<2) + > trap_ne ;zp altered +08c2 : d0fe > bne * ;failed not equal (non zero) + > + + bbt 3 +08c4 : a908 > lda #(1<<3) ;testing 1 bit on +08c6 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +08c8 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +08ca : 48 > pha ;use stack to load status +08cb : a933 > lda #$33 ;precharge accu +08cd : 28 > plp + > +08ce : 3f0c06 > bbr 3,zpt,fail10301 +08d1 : bf0c06 > bbs 3,zpt,ok10301 + > trap ;bbs branch not taken +08d4 : 4cd408 > jmp * ;failed anyway + > +08d7 : >fail10301 + > trap ;bbr branch taken +08d7 : 4cd708 > jmp * ;failed anyway + > +08da : >ok10301 + > tst_a $33,0 +08da : 08 > php ;save flags +08db : c933 > cmp #$33 ;test result + > trap_ne +08dd : d0fe > bne * ;failed not equal (non zero) + > +08df : 68 > pla ;load status +08e0 : 48 > pha + > cmp_flag 0 +08e1 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +08e3 : d0fe > bne * ;failed not equal (non zero) + > +08e5 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +08e6 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +08e8 : 48 > pha ;use stack to load status +08e9 : a9cc > lda #$cc ;precharge accu +08eb : 28 > plp + > +08ec : 3f0c06 > bbr 3,zpt,fail20301 +08ef : bf0c06 > bbs 3,zpt,ok20301 + > trap ;bbs branch not taken +08f2 : 4cf208 > jmp * ;failed anyway + > +08f5 : >fail20301 + > trap ;bbr branch taken +08f5 : 4cf508 > jmp * ;failed anyway + > +08f8 : >ok20301 + > tst_a $cc,$ff +08f8 : 08 > php ;save flags +08f9 : c9cc > cmp #$cc ;test result + > trap_ne +08fb : d0fe > bne * ;failed not equal (non zero) + > +08fd : 68 > pla ;load status +08fe : 48 > pha + > cmp_flag $ff +08ff : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0901 : d0fe > bne * ;failed not equal (non zero) + > +0903 : 28 > plp ;restore status + > +0904 : a50c > lda zpt +0906 : c908 > cmp #(1<<3) + > trap_ne ;zp altered +0908 : d0fe > bne * ;failed not equal (non zero) + > +090a : a9f7 > lda #$ff-(1<<3) ;testing 1 bit off +090c : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +090e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0910 : 48 > pha ;use stack to load status +0911 : a933 > lda #$33 ;precharge accu +0913 : 28 > plp + > +0914 : bf0c06 > bbs 3,zpt,fail30301 +0917 : 3f0c06 > bbr 3,zpt,ok30301 + > trap ;bbr branch not taken +091a : 4c1a09 > jmp * ;failed anyway + > +091d : >fail30301 + > trap ;bbs branch taken +091d : 4c1d09 > jmp * ;failed anyway + > +0920 : >ok30301 + > tst_a $33,0 +0920 : 08 > php ;save flags +0921 : c933 > cmp #$33 ;test result + > trap_ne +0923 : d0fe > bne * ;failed not equal (non zero) + > +0925 : 68 > pla ;load status +0926 : 48 > pha + > cmp_flag 0 +0927 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0929 : d0fe > bne * ;failed not equal (non zero) + > +092b : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +092c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +092e : 48 > pha ;use stack to load status +092f : a9cc > lda #$cc ;precharge accu +0931 : 28 > plp + > +0932 : bf0c06 > bbs 3,zpt,fail40301 +0935 : 3f0c06 > bbr 3,zpt,ok40301 + > trap ;bbr branch not taken +0938 : 4c3809 > jmp * ;failed anyway + > +093b : >fail40301 + > trap ;bbs branch taken +093b : 4c3b09 > jmp * ;failed anyway + > +093e : >ok40301 + > tst_a $cc,$ff +093e : 08 > php ;save flags +093f : c9cc > cmp #$cc ;test result + > trap_ne +0941 : d0fe > bne * ;failed not equal (non zero) + > +0943 : 68 > pla ;load status +0944 : 48 > pha + > cmp_flag $ff +0945 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0947 : d0fe > bne * ;failed not equal (non zero) + > +0949 : 28 > plp ;restore status + > +094a : a50c > lda zpt +094c : c9f7 > cmp #$ff-(1<<3) + > trap_ne ;zp altered +094e : d0fe > bne * ;failed not equal (non zero) + > + + bbt 4 +0950 : a910 > lda #(1<<4) ;testing 1 bit on +0952 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0954 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0956 : 48 > pha ;use stack to load status +0957 : a933 > lda #$33 ;precharge accu +0959 : 28 > plp + > +095a : 4f0c06 > bbr 4,zpt,fail10336 +095d : cf0c06 > bbs 4,zpt,ok10336 + > trap ;bbs branch not taken +0960 : 4c6009 > jmp * ;failed anyway + > +0963 : >fail10336 + > trap ;bbr branch taken +0963 : 4c6309 > jmp * ;failed anyway + > +0966 : >ok10336 + > tst_a $33,0 +0966 : 08 > php ;save flags +0967 : c933 > cmp #$33 ;test result + > trap_ne +0969 : d0fe > bne * ;failed not equal (non zero) + > +096b : 68 > pla ;load status +096c : 48 > pha + > cmp_flag 0 +096d : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +096f : d0fe > bne * ;failed not equal (non zero) + > +0971 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0972 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0974 : 48 > pha ;use stack to load status +0975 : a9cc > lda #$cc ;precharge accu +0977 : 28 > plp + > +0978 : 4f0c06 > bbr 4,zpt,fail20336 +097b : cf0c06 > bbs 4,zpt,ok20336 + > trap ;bbs branch not taken +097e : 4c7e09 > jmp * ;failed anyway + > +0981 : >fail20336 + > trap ;bbr branch taken +0981 : 4c8109 > jmp * ;failed anyway + > +0984 : >ok20336 + > tst_a $cc,$ff +0984 : 08 > php ;save flags +0985 : c9cc > cmp #$cc ;test result + > trap_ne +0987 : d0fe > bne * ;failed not equal (non zero) + > +0989 : 68 > pla ;load status +098a : 48 > pha + > cmp_flag $ff +098b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +098d : d0fe > bne * ;failed not equal (non zero) + > +098f : 28 > plp ;restore status + > +0990 : a50c > lda zpt +0992 : c910 > cmp #(1<<4) + > trap_ne ;zp altered +0994 : d0fe > bne * ;failed not equal (non zero) + > +0996 : a9ef > lda #$ff-(1<<4) ;testing 1 bit off +0998 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +099a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +099c : 48 > pha ;use stack to load status +099d : a933 > lda #$33 ;precharge accu +099f : 28 > plp + > +09a0 : cf0c06 > bbs 4,zpt,fail30336 +09a3 : 4f0c06 > bbr 4,zpt,ok30336 + > trap ;bbr branch not taken +09a6 : 4ca609 > jmp * ;failed anyway + > +09a9 : >fail30336 + > trap ;bbs branch taken +09a9 : 4ca909 > jmp * ;failed anyway + > +09ac : >ok30336 + > tst_a $33,0 +09ac : 08 > php ;save flags +09ad : c933 > cmp #$33 ;test result + > trap_ne +09af : d0fe > bne * ;failed not equal (non zero) + > +09b1 : 68 > pla ;load status +09b2 : 48 > pha + > cmp_flag 0 +09b3 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +09b5 : d0fe > bne * ;failed not equal (non zero) + > +09b7 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +09b8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +09ba : 48 > pha ;use stack to load status +09bb : a9cc > lda #$cc ;precharge accu +09bd : 28 > plp + > +09be : cf0c06 > bbs 4,zpt,fail40336 +09c1 : 4f0c06 > bbr 4,zpt,ok40336 + > trap ;bbr branch not taken +09c4 : 4cc409 > jmp * ;failed anyway + > +09c7 : >fail40336 + > trap ;bbs branch taken +09c7 : 4cc709 > jmp * ;failed anyway + > +09ca : >ok40336 + > tst_a $cc,$ff +09ca : 08 > php ;save flags +09cb : c9cc > cmp #$cc ;test result + > trap_ne +09cd : d0fe > bne * ;failed not equal (non zero) + > +09cf : 68 > pla ;load status +09d0 : 48 > pha + > cmp_flag $ff +09d1 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +09d3 : d0fe > bne * ;failed not equal (non zero) + > +09d5 : 28 > plp ;restore status + > +09d6 : a50c > lda zpt +09d8 : c9ef > cmp #$ff-(1<<4) + > trap_ne ;zp altered +09da : d0fe > bne * ;failed not equal (non zero) + > + + bbt 5 +09dc : a920 > lda #(1<<5) ;testing 1 bit on +09de : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +09e0 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +09e2 : 48 > pha ;use stack to load status +09e3 : a933 > lda #$33 ;precharge accu +09e5 : 28 > plp + > +09e6 : 5f0c06 > bbr 5,zpt,fail10371 +09e9 : df0c06 > bbs 5,zpt,ok10371 + > trap ;bbs branch not taken +09ec : 4cec09 > jmp * ;failed anyway + > +09ef : >fail10371 + > trap ;bbr branch taken +09ef : 4cef09 > jmp * ;failed anyway + > +09f2 : >ok10371 + > tst_a $33,0 +09f2 : 08 > php ;save flags +09f3 : c933 > cmp #$33 ;test result + > trap_ne +09f5 : d0fe > bne * ;failed not equal (non zero) + > +09f7 : 68 > pla ;load status +09f8 : 48 > pha + > cmp_flag 0 +09f9 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +09fb : d0fe > bne * ;failed not equal (non zero) + > +09fd : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +09fe : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0a00 : 48 > pha ;use stack to load status +0a01 : a9cc > lda #$cc ;precharge accu +0a03 : 28 > plp + > +0a04 : 5f0c06 > bbr 5,zpt,fail20371 +0a07 : df0c06 > bbs 5,zpt,ok20371 + > trap ;bbs branch not taken +0a0a : 4c0a0a > jmp * ;failed anyway + > +0a0d : >fail20371 + > trap ;bbr branch taken +0a0d : 4c0d0a > jmp * ;failed anyway + > +0a10 : >ok20371 + > tst_a $cc,$ff +0a10 : 08 > php ;save flags +0a11 : c9cc > cmp #$cc ;test result + > trap_ne +0a13 : d0fe > bne * ;failed not equal (non zero) + > +0a15 : 68 > pla ;load status +0a16 : 48 > pha + > cmp_flag $ff +0a17 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a19 : d0fe > bne * ;failed not equal (non zero) + > +0a1b : 28 > plp ;restore status + > +0a1c : a50c > lda zpt +0a1e : c920 > cmp #(1<<5) + > trap_ne ;zp altered +0a20 : d0fe > bne * ;failed not equal (non zero) + > +0a22 : a9df > lda #$ff-(1<<5) ;testing 1 bit off +0a24 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0a26 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0a28 : 48 > pha ;use stack to load status +0a29 : a933 > lda #$33 ;precharge accu +0a2b : 28 > plp + > +0a2c : df0c06 > bbs 5,zpt,fail30371 +0a2f : 5f0c06 > bbr 5,zpt,ok30371 + > trap ;bbr branch not taken +0a32 : 4c320a > jmp * ;failed anyway + > +0a35 : >fail30371 + > trap ;bbs branch taken +0a35 : 4c350a > jmp * ;failed anyway + > +0a38 : >ok30371 + > tst_a $33,0 +0a38 : 08 > php ;save flags +0a39 : c933 > cmp #$33 ;test result + > trap_ne +0a3b : d0fe > bne * ;failed not equal (non zero) + > +0a3d : 68 > pla ;load status +0a3e : 48 > pha + > cmp_flag 0 +0a3f : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a41 : d0fe > bne * ;failed not equal (non zero) + > +0a43 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0a44 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0a46 : 48 > pha ;use stack to load status +0a47 : a9cc > lda #$cc ;precharge accu +0a49 : 28 > plp + > +0a4a : df0c06 > bbs 5,zpt,fail40371 +0a4d : 5f0c06 > bbr 5,zpt,ok40371 + > trap ;bbr branch not taken +0a50 : 4c500a > jmp * ;failed anyway + > +0a53 : >fail40371 + > trap ;bbs branch taken +0a53 : 4c530a > jmp * ;failed anyway + > +0a56 : >ok40371 + > tst_a $cc,$ff +0a56 : 08 > php ;save flags +0a57 : c9cc > cmp #$cc ;test result + > trap_ne +0a59 : d0fe > bne * ;failed not equal (non zero) + > +0a5b : 68 > pla ;load status +0a5c : 48 > pha + > cmp_flag $ff +0a5d : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a5f : d0fe > bne * ;failed not equal (non zero) + > +0a61 : 28 > plp ;restore status + > +0a62 : a50c > lda zpt +0a64 : c9df > cmp #$ff-(1<<5) + > trap_ne ;zp altered +0a66 : d0fe > bne * ;failed not equal (non zero) + > + + bbt 6 +0a68 : a940 > lda #(1<<6) ;testing 1 bit on +0a6a : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0a6c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0a6e : 48 > pha ;use stack to load status +0a6f : a933 > lda #$33 ;precharge accu +0a71 : 28 > plp + > +0a72 : 6f0c06 > bbr 6,zpt,fail10406 +0a75 : ef0c06 > bbs 6,zpt,ok10406 + > trap ;bbs branch not taken +0a78 : 4c780a > jmp * ;failed anyway + > +0a7b : >fail10406 + > trap ;bbr branch taken +0a7b : 4c7b0a > jmp * ;failed anyway + > +0a7e : >ok10406 + > tst_a $33,0 +0a7e : 08 > php ;save flags +0a7f : c933 > cmp #$33 ;test result + > trap_ne +0a81 : d0fe > bne * ;failed not equal (non zero) + > +0a83 : 68 > pla ;load status +0a84 : 48 > pha + > cmp_flag 0 +0a85 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0a87 : d0fe > bne * ;failed not equal (non zero) + > +0a89 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0a8a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0a8c : 48 > pha ;use stack to load status +0a8d : a9cc > lda #$cc ;precharge accu +0a8f : 28 > plp + > +0a90 : 6f0c06 > bbr 6,zpt,fail20406 +0a93 : ef0c06 > bbs 6,zpt,ok20406 + > trap ;bbs branch not taken +0a96 : 4c960a > jmp * ;failed anyway + > +0a99 : >fail20406 + > trap ;bbr branch taken +0a99 : 4c990a > jmp * ;failed anyway + > +0a9c : >ok20406 + > tst_a $cc,$ff +0a9c : 08 > php ;save flags +0a9d : c9cc > cmp #$cc ;test result + > trap_ne +0a9f : d0fe > bne * ;failed not equal (non zero) + > +0aa1 : 68 > pla ;load status +0aa2 : 48 > pha + > cmp_flag $ff +0aa3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0aa5 : d0fe > bne * ;failed not equal (non zero) + > +0aa7 : 28 > plp ;restore status + > +0aa8 : a50c > lda zpt +0aaa : c940 > cmp #(1<<6) + > trap_ne ;zp altered +0aac : d0fe > bne * ;failed not equal (non zero) + > +0aae : a9bf > lda #$ff-(1<<6) ;testing 1 bit off +0ab0 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0ab2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0ab4 : 48 > pha ;use stack to load status +0ab5 : a933 > lda #$33 ;precharge accu +0ab7 : 28 > plp + > +0ab8 : ef0c06 > bbs 6,zpt,fail30406 +0abb : 6f0c06 > bbr 6,zpt,ok30406 + > trap ;bbr branch not taken +0abe : 4cbe0a > jmp * ;failed anyway + > +0ac1 : >fail30406 + > trap ;bbs branch taken +0ac1 : 4cc10a > jmp * ;failed anyway + > +0ac4 : >ok30406 + > tst_a $33,0 +0ac4 : 08 > php ;save flags +0ac5 : c933 > cmp #$33 ;test result + > trap_ne +0ac7 : d0fe > bne * ;failed not equal (non zero) + > +0ac9 : 68 > pla ;load status +0aca : 48 > pha + > cmp_flag 0 +0acb : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0acd : d0fe > bne * ;failed not equal (non zero) + > +0acf : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0ad0 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0ad2 : 48 > pha ;use stack to load status +0ad3 : a9cc > lda #$cc ;precharge accu +0ad5 : 28 > plp + > +0ad6 : ef0c06 > bbs 6,zpt,fail40406 +0ad9 : 6f0c06 > bbr 6,zpt,ok40406 + > trap ;bbr branch not taken +0adc : 4cdc0a > jmp * ;failed anyway + > +0adf : >fail40406 + > trap ;bbs branch taken +0adf : 4cdf0a > jmp * ;failed anyway + > +0ae2 : >ok40406 + > tst_a $cc,$ff +0ae2 : 08 > php ;save flags +0ae3 : c9cc > cmp #$cc ;test result + > trap_ne +0ae5 : d0fe > bne * ;failed not equal (non zero) + > +0ae7 : 68 > pla ;load status +0ae8 : 48 > pha + > cmp_flag $ff +0ae9 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0aeb : d0fe > bne * ;failed not equal (non zero) + > +0aed : 28 > plp ;restore status + > +0aee : a50c > lda zpt +0af0 : c9bf > cmp #$ff-(1<<6) + > trap_ne ;zp altered +0af2 : d0fe > bne * ;failed not equal (non zero) + > + + bbt 7 +0af4 : a980 > lda #(1<<7) ;testing 1 bit on +0af6 : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0af8 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0afa : 48 > pha ;use stack to load status +0afb : a933 > lda #$33 ;precharge accu +0afd : 28 > plp + > +0afe : 7f0c06 > bbr 7,zpt,fail10441 +0b01 : ff0c06 > bbs 7,zpt,ok10441 + > trap ;bbs branch not taken +0b04 : 4c040b > jmp * ;failed anyway + > +0b07 : >fail10441 + > trap ;bbr branch taken +0b07 : 4c070b > jmp * ;failed anyway + > +0b0a : >ok10441 + > tst_a $33,0 +0b0a : 08 > php ;save flags +0b0b : c933 > cmp #$33 ;test result + > trap_ne +0b0d : d0fe > bne * ;failed not equal (non zero) + > +0b0f : 68 > pla ;load status +0b10 : 48 > pha + > cmp_flag 0 +0b11 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b13 : d0fe > bne * ;failed not equal (non zero) + > +0b15 : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0b16 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0b18 : 48 > pha ;use stack to load status +0b19 : a9cc > lda #$cc ;precharge accu +0b1b : 28 > plp + > +0b1c : 7f0c06 > bbr 7,zpt,fail20441 +0b1f : ff0c06 > bbs 7,zpt,ok20441 + > trap ;bbs branch not taken +0b22 : 4c220b > jmp * ;failed anyway + > +0b25 : >fail20441 + > trap ;bbr branch taken +0b25 : 4c250b > jmp * ;failed anyway + > +0b28 : >ok20441 + > tst_a $cc,$ff +0b28 : 08 > php ;save flags +0b29 : c9cc > cmp #$cc ;test result + > trap_ne +0b2b : d0fe > bne * ;failed not equal (non zero) + > +0b2d : 68 > pla ;load status +0b2e : 48 > pha + > cmp_flag $ff +0b2f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b31 : d0fe > bne * ;failed not equal (non zero) + > +0b33 : 28 > plp ;restore status + > +0b34 : a50c > lda zpt +0b36 : c980 > cmp #(1<<7) + > trap_ne ;zp altered +0b38 : d0fe > bne * ;failed not equal (non zero) + > +0b3a : a97f > lda #$ff-(1<<7) ;testing 1 bit off +0b3c : 850c > sta zpt + > set_a $33,0 ;with flags off + > load_flag 0 +0b3e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0b40 : 48 > pha ;use stack to load status +0b41 : a933 > lda #$33 ;precharge accu +0b43 : 28 > plp + > +0b44 : ff0c06 > bbs 7,zpt,fail30441 +0b47 : 7f0c06 > bbr 7,zpt,ok30441 + > trap ;bbr branch not taken +0b4a : 4c4a0b > jmp * ;failed anyway + > +0b4d : >fail30441 + > trap ;bbs branch taken +0b4d : 4c4d0b > jmp * ;failed anyway + > +0b50 : >ok30441 + > tst_a $33,0 +0b50 : 08 > php ;save flags +0b51 : c933 > cmp #$33 ;test result + > trap_ne +0b53 : d0fe > bne * ;failed not equal (non zero) + > +0b55 : 68 > pla ;load status +0b56 : 48 > pha + > cmp_flag 0 +0b57 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b59 : d0fe > bne * ;failed not equal (non zero) + > +0b5b : 28 > plp ;restore status + > + > set_a $cc,$ff ;with flags on + > load_flag $ff +0b5c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0b5e : 48 > pha ;use stack to load status +0b5f : a9cc > lda #$cc ;precharge accu +0b61 : 28 > plp + > +0b62 : ff0c06 > bbs 7,zpt,fail40441 +0b65 : 7f0c06 > bbr 7,zpt,ok40441 + > trap ;bbr branch not taken +0b68 : 4c680b > jmp * ;failed anyway + > +0b6b : >fail40441 + > trap ;bbs branch taken +0b6b : 4c6b0b > jmp * ;failed anyway + > +0b6e : >ok40441 + > tst_a $cc,$ff +0b6e : 08 > php ;save flags +0b6f : c9cc > cmp #$cc ;test result + > trap_ne +0b71 : d0fe > bne * ;failed not equal (non zero) + > +0b73 : 68 > pla ;load status +0b74 : 48 > pha + > cmp_flag $ff +0b75 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0b77 : d0fe > bne * ;failed not equal (non zero) + > +0b79 : 28 > plp ;restore status + > +0b7a : a50c > lda zpt +0b7c : c97f > cmp #$ff-(1<<7) + > trap_ne ;zp altered +0b7e : d0fe > bne * ;failed not equal (non zero) + > + +0b80 : e011 cpx #$11 + trap_ne ;x overwritten +0b82 : d0fe > bne * ;failed not equal (non zero) + +0b84 : c022 cpy #$22 + trap_ne ;y overwritten +0b86 : d0fe > bne * ;failed not equal (non zero) + + next_test +0b88 : ad0202 > lda test_case ;previous test +0b8b : c906 > cmp #test_num + > trap_ne ;test is out of sequence +0b8d : d0fe > bne * ;failed not equal (non zero) + > +0007 = >test_num = test_num + 1 +0b8f : a907 > lda #test_num ;*** next tests' number +0b91 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + bbrc macro ;\1 = bitnum + bbr \1,zpt,skip\? + eor #(1<<\1) + skip\? + endm + bbsc macro ;\1 = bitnum + bbs \1,zpt,skip\? + eor #(1<<\1) + skip\? + endm + +0b94 : a900 lda #0 ;combined bit test +0b96 : 850c sta zpt +0b98 : a900 bbcl lda #0 + bbrc 0 +0b9a : 0f0c02 > bbr 0,zpt,skip0480 +0b9d : 4901 > eor #(1<<0) +0b9f : >skip0480 + + bbrc 1 +0b9f : 1f0c02 > bbr 1,zpt,skip0481 +0ba2 : 4902 > eor #(1<<1) +0ba4 : >skip0481 + + bbrc 2 +0ba4 : 2f0c02 > bbr 2,zpt,skip0482 +0ba7 : 4904 > eor #(1<<2) +0ba9 : >skip0482 + + bbrc 3 +0ba9 : 3f0c02 > bbr 3,zpt,skip0483 +0bac : 4908 > eor #(1<<3) +0bae : >skip0483 + + bbrc 4 +0bae : 4f0c02 > bbr 4,zpt,skip0484 +0bb1 : 4910 > eor #(1<<4) +0bb3 : >skip0484 + + bbrc 5 +0bb3 : 5f0c02 > bbr 5,zpt,skip0485 +0bb6 : 4920 > eor #(1<<5) +0bb8 : >skip0485 + + bbrc 6 +0bb8 : 6f0c02 > bbr 6,zpt,skip0486 +0bbb : 4940 > eor #(1<<6) +0bbd : >skip0486 + + bbrc 7 +0bbd : 7f0c02 > bbr 7,zpt,skip0487 +0bc0 : 4980 > eor #(1<<7) +0bc2 : >skip0487 + +0bc2 : 450c eor zpt + trap_ne ;failed bbr bitnum in accu +0bc4 : d0fe > bne * ;failed not equal (non zero) + +0bc6 : a9ff lda #$ff + bbsc 0 +0bc8 : 8f0c02 > bbs 0,zpt,skip0489 +0bcb : 4901 > eor #(1<<0) +0bcd : >skip0489 + + bbsc 1 +0bcd : 9f0c02 > bbs 1,zpt,skip0490 +0bd0 : 4902 > eor #(1<<1) +0bd2 : >skip0490 + + bbsc 2 +0bd2 : af0c02 > bbs 2,zpt,skip0491 +0bd5 : 4904 > eor #(1<<2) +0bd7 : >skip0491 + + bbsc 3 +0bd7 : bf0c02 > bbs 3,zpt,skip0492 +0bda : 4908 > eor #(1<<3) +0bdc : >skip0492 + + bbsc 4 +0bdc : cf0c02 > bbs 4,zpt,skip0493 +0bdf : 4910 > eor #(1<<4) +0be1 : >skip0493 + + bbsc 5 +0be1 : df0c02 > bbs 5,zpt,skip0494 +0be4 : 4920 > eor #(1<<5) +0be6 : >skip0494 + + bbsc 6 +0be6 : ef0c02 > bbs 6,zpt,skip0495 +0be9 : 4940 > eor #(1<<6) +0beb : >skip0495 + + bbsc 7 +0beb : ff0c02 > bbs 7,zpt,skip0496 +0bee : 4980 > eor #(1<<7) +0bf0 : >skip0496 + +0bf0 : 450c eor zpt + trap_ne ;failed bbs bitnum in accu +0bf2 : d0fe > bne * ;failed not equal (non zero) + +0bf4 : e60c inc zpt +0bf6 : d0a0 bne bbcl + next_test +0bf8 : ad0202 > lda test_case ;previous test +0bfb : c907 > cmp #test_num + > trap_ne ;test is out of sequence +0bfd : d0fe > bne * ;failed not equal (non zero) + > +0008 = >test_num = test_num + 1 +0bff : a908 > lda #test_num ;*** next tests' number +0c01 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + endif + + ; testing NOP + + nop_test macro ;\1 = opcode, \2 = # of bytes + ldy #$42 + ldx #4-\2 + db \1 ;test nop length + if \2 = 1 + dex + dex + endif + if \2 = 2 + iny + dex + endif + if \2 = 3 + iny + iny + endif + dex + trap_ne ;wrong number of bytes + set_a $ff-\1,0 + db \1 ;test nop integrity - flags off + nop + nop + tst_a $ff-\1,0 + set_a $aa-\1,$ff + db \1 ;test nop integrity - flags on + nop + nop + tst_a $aa-\1,$ff + cpy #$42 + trap_ne ;y changed + cpx #0 + trap_ne ;x changed + endm + + if skip_nop = 0 + nop_test $02,2 +0c04 : a042 > ldy #$42 +0c06 : a202 > ldx #4-2 +0c08 : 02 > db $02 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0c09 : c8 > iny +0c0a : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0c0b : ca > dex + > trap_ne ;wrong number of bytes +0c0c : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$02,0 + > load_flag 0 +0c0e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0c10 : 48 > pha ;use stack to load status +0c11 : a9fd > lda #$ff-$02 ;precharge accu +0c13 : 28 > plp + > +0c14 : 02 > db $02 ;test nop integrity - flags off +0c15 : ea > nop +0c16 : ea > nop + > tst_a $ff-$02,0 +0c17 : 08 > php ;save flags +0c18 : c9fd > cmp #$ff-$02 ;test result + > trap_ne +0c1a : d0fe > bne * ;failed not equal (non zero) + > +0c1c : 68 > pla ;load status +0c1d : 48 > pha + > cmp_flag 0 +0c1e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c20 : d0fe > bne * ;failed not equal (non zero) + > +0c22 : 28 > plp ;restore status + > + > set_a $aa-$02,$ff + > load_flag $ff +0c23 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0c25 : 48 > pha ;use stack to load status +0c26 : a9a8 > lda #$aa-$02 ;precharge accu +0c28 : 28 > plp + > +0c29 : 02 > db $02 ;test nop integrity - flags on +0c2a : ea > nop +0c2b : ea > nop + > tst_a $aa-$02,$ff +0c2c : 08 > php ;save flags +0c2d : c9a8 > cmp #$aa-$02 ;test result + > trap_ne +0c2f : d0fe > bne * ;failed not equal (non zero) + > +0c31 : 68 > pla ;load status +0c32 : 48 > pha + > cmp_flag $ff +0c33 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c35 : d0fe > bne * ;failed not equal (non zero) + > +0c37 : 28 > plp ;restore status + > +0c38 : c042 > cpy #$42 + > trap_ne ;y changed +0c3a : d0fe > bne * ;failed not equal (non zero) + > +0c3c : e000 > cpx #0 + > trap_ne ;x changed +0c3e : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $22,2 +0c40 : a042 > ldy #$42 +0c42 : a202 > ldx #4-2 +0c44 : 22 > db $22 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0c45 : c8 > iny +0c46 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0c47 : ca > dex + > trap_ne ;wrong number of bytes +0c48 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$22,0 + > load_flag 0 +0c4a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0c4c : 48 > pha ;use stack to load status +0c4d : a9dd > lda #$ff-$22 ;precharge accu +0c4f : 28 > plp + > +0c50 : 22 > db $22 ;test nop integrity - flags off +0c51 : ea > nop +0c52 : ea > nop + > tst_a $ff-$22,0 +0c53 : 08 > php ;save flags +0c54 : c9dd > cmp #$ff-$22 ;test result + > trap_ne +0c56 : d0fe > bne * ;failed not equal (non zero) + > +0c58 : 68 > pla ;load status +0c59 : 48 > pha + > cmp_flag 0 +0c5a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c5c : d0fe > bne * ;failed not equal (non zero) + > +0c5e : 28 > plp ;restore status + > + > set_a $aa-$22,$ff + > load_flag $ff +0c5f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0c61 : 48 > pha ;use stack to load status +0c62 : a988 > lda #$aa-$22 ;precharge accu +0c64 : 28 > plp + > +0c65 : 22 > db $22 ;test nop integrity - flags on +0c66 : ea > nop +0c67 : ea > nop + > tst_a $aa-$22,$ff +0c68 : 08 > php ;save flags +0c69 : c988 > cmp #$aa-$22 ;test result + > trap_ne +0c6b : d0fe > bne * ;failed not equal (non zero) + > +0c6d : 68 > pla ;load status +0c6e : 48 > pha + > cmp_flag $ff +0c6f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c71 : d0fe > bne * ;failed not equal (non zero) + > +0c73 : 28 > plp ;restore status + > +0c74 : c042 > cpy #$42 + > trap_ne ;y changed +0c76 : d0fe > bne * ;failed not equal (non zero) + > +0c78 : e000 > cpx #0 + > trap_ne ;x changed +0c7a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $42,2 +0c7c : a042 > ldy #$42 +0c7e : a202 > ldx #4-2 +0c80 : 42 > db $42 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0c81 : c8 > iny +0c82 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0c83 : ca > dex + > trap_ne ;wrong number of bytes +0c84 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$42,0 + > load_flag 0 +0c86 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0c88 : 48 > pha ;use stack to load status +0c89 : a9bd > lda #$ff-$42 ;precharge accu +0c8b : 28 > plp + > +0c8c : 42 > db $42 ;test nop integrity - flags off +0c8d : ea > nop +0c8e : ea > nop + > tst_a $ff-$42,0 +0c8f : 08 > php ;save flags +0c90 : c9bd > cmp #$ff-$42 ;test result + > trap_ne +0c92 : d0fe > bne * ;failed not equal (non zero) + > +0c94 : 68 > pla ;load status +0c95 : 48 > pha + > cmp_flag 0 +0c96 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0c98 : d0fe > bne * ;failed not equal (non zero) + > +0c9a : 28 > plp ;restore status + > + > set_a $aa-$42,$ff + > load_flag $ff +0c9b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0c9d : 48 > pha ;use stack to load status +0c9e : a968 > lda #$aa-$42 ;precharge accu +0ca0 : 28 > plp + > +0ca1 : 42 > db $42 ;test nop integrity - flags on +0ca2 : ea > nop +0ca3 : ea > nop + > tst_a $aa-$42,$ff +0ca4 : 08 > php ;save flags +0ca5 : c968 > cmp #$aa-$42 ;test result + > trap_ne +0ca7 : d0fe > bne * ;failed not equal (non zero) + > +0ca9 : 68 > pla ;load status +0caa : 48 > pha + > cmp_flag $ff +0cab : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cad : d0fe > bne * ;failed not equal (non zero) + > +0caf : 28 > plp ;restore status + > +0cb0 : c042 > cpy #$42 + > trap_ne ;y changed +0cb2 : d0fe > bne * ;failed not equal (non zero) + > +0cb4 : e000 > cpx #0 + > trap_ne ;x changed +0cb6 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $62,2 +0cb8 : a042 > ldy #$42 +0cba : a202 > ldx #4-2 +0cbc : 62 > db $62 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0cbd : c8 > iny +0cbe : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0cbf : ca > dex + > trap_ne ;wrong number of bytes +0cc0 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$62,0 + > load_flag 0 +0cc2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0cc4 : 48 > pha ;use stack to load status +0cc5 : a99d > lda #$ff-$62 ;precharge accu +0cc7 : 28 > plp + > +0cc8 : 62 > db $62 ;test nop integrity - flags off +0cc9 : ea > nop +0cca : ea > nop + > tst_a $ff-$62,0 +0ccb : 08 > php ;save flags +0ccc : c99d > cmp #$ff-$62 ;test result + > trap_ne +0cce : d0fe > bne * ;failed not equal (non zero) + > +0cd0 : 68 > pla ;load status +0cd1 : 48 > pha + > cmp_flag 0 +0cd2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0cd4 : d0fe > bne * ;failed not equal (non zero) + > +0cd6 : 28 > plp ;restore status + > + > set_a $aa-$62,$ff + > load_flag $ff +0cd7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0cd9 : 48 > pha ;use stack to load status +0cda : a948 > lda #$aa-$62 ;precharge accu +0cdc : 28 > plp + > +0cdd : 62 > db $62 ;test nop integrity - flags on +0cde : ea > nop +0cdf : ea > nop + > tst_a $aa-$62,$ff +0ce0 : 08 > php ;save flags +0ce1 : c948 > cmp #$aa-$62 ;test result + > trap_ne +0ce3 : d0fe > bne * ;failed not equal (non zero) + > +0ce5 : 68 > pla ;load status +0ce6 : 48 > pha + > cmp_flag $ff +0ce7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ce9 : d0fe > bne * ;failed not equal (non zero) + > +0ceb : 28 > plp ;restore status + > +0cec : c042 > cpy #$42 + > trap_ne ;y changed +0cee : d0fe > bne * ;failed not equal (non zero) + > +0cf0 : e000 > cpx #0 + > trap_ne ;x changed +0cf2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $82,2 +0cf4 : a042 > ldy #$42 +0cf6 : a202 > ldx #4-2 +0cf8 : 82 > db $82 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0cf9 : c8 > iny +0cfa : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0cfb : ca > dex + > trap_ne ;wrong number of bytes +0cfc : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$82,0 + > load_flag 0 +0cfe : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0d00 : 48 > pha ;use stack to load status +0d01 : a97d > lda #$ff-$82 ;precharge accu +0d03 : 28 > plp + > +0d04 : 82 > db $82 ;test nop integrity - flags off +0d05 : ea > nop +0d06 : ea > nop + > tst_a $ff-$82,0 +0d07 : 08 > php ;save flags +0d08 : c97d > cmp #$ff-$82 ;test result + > trap_ne +0d0a : d0fe > bne * ;failed not equal (non zero) + > +0d0c : 68 > pla ;load status +0d0d : 48 > pha + > cmp_flag 0 +0d0e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d10 : d0fe > bne * ;failed not equal (non zero) + > +0d12 : 28 > plp ;restore status + > + > set_a $aa-$82,$ff + > load_flag $ff +0d13 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0d15 : 48 > pha ;use stack to load status +0d16 : a928 > lda #$aa-$82 ;precharge accu +0d18 : 28 > plp + > +0d19 : 82 > db $82 ;test nop integrity - flags on +0d1a : ea > nop +0d1b : ea > nop + > tst_a $aa-$82,$ff +0d1c : 08 > php ;save flags +0d1d : c928 > cmp #$aa-$82 ;test result + > trap_ne +0d1f : d0fe > bne * ;failed not equal (non zero) + > +0d21 : 68 > pla ;load status +0d22 : 48 > pha + > cmp_flag $ff +0d23 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d25 : d0fe > bne * ;failed not equal (non zero) + > +0d27 : 28 > plp ;restore status + > +0d28 : c042 > cpy #$42 + > trap_ne ;y changed +0d2a : d0fe > bne * ;failed not equal (non zero) + > +0d2c : e000 > cpx #0 + > trap_ne ;x changed +0d2e : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $c2,2 +0d30 : a042 > ldy #$42 +0d32 : a202 > ldx #4-2 +0d34 : c2 > db $c2 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0d35 : c8 > iny +0d36 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0d37 : ca > dex + > trap_ne ;wrong number of bytes +0d38 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$c2,0 + > load_flag 0 +0d3a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0d3c : 48 > pha ;use stack to load status +0d3d : a93d > lda #$ff-$c2 ;precharge accu +0d3f : 28 > plp + > +0d40 : c2 > db $c2 ;test nop integrity - flags off +0d41 : ea > nop +0d42 : ea > nop + > tst_a $ff-$c2,0 +0d43 : 08 > php ;save flags +0d44 : c93d > cmp #$ff-$c2 ;test result + > trap_ne +0d46 : d0fe > bne * ;failed not equal (non zero) + > +0d48 : 68 > pla ;load status +0d49 : 48 > pha + > cmp_flag 0 +0d4a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d4c : d0fe > bne * ;failed not equal (non zero) + > +0d4e : 28 > plp ;restore status + > + > set_a $aa-$c2,$ff + > load_flag $ff +0d4f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0d51 : 48 > pha ;use stack to load status +0d52 : a9e8 > lda #$aa-$c2 ;precharge accu +0d54 : 28 > plp + > +0d55 : c2 > db $c2 ;test nop integrity - flags on +0d56 : ea > nop +0d57 : ea > nop + > tst_a $aa-$c2,$ff +0d58 : 08 > php ;save flags +0d59 : c9e8 > cmp #$aa-$c2 ;test result + > trap_ne +0d5b : d0fe > bne * ;failed not equal (non zero) + > +0d5d : 68 > pla ;load status +0d5e : 48 > pha + > cmp_flag $ff +0d5f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d61 : d0fe > bne * ;failed not equal (non zero) + > +0d63 : 28 > plp ;restore status + > +0d64 : c042 > cpy #$42 + > trap_ne ;y changed +0d66 : d0fe > bne * ;failed not equal (non zero) + > +0d68 : e000 > cpx #0 + > trap_ne ;x changed +0d6a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $e2,2 +0d6c : a042 > ldy #$42 +0d6e : a202 > ldx #4-2 +0d70 : e2 > db $e2 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0d71 : c8 > iny +0d72 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0d73 : ca > dex + > trap_ne ;wrong number of bytes +0d74 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$e2,0 + > load_flag 0 +0d76 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0d78 : 48 > pha ;use stack to load status +0d79 : a91d > lda #$ff-$e2 ;precharge accu +0d7b : 28 > plp + > +0d7c : e2 > db $e2 ;test nop integrity - flags off +0d7d : ea > nop +0d7e : ea > nop + > tst_a $ff-$e2,0 +0d7f : 08 > php ;save flags +0d80 : c91d > cmp #$ff-$e2 ;test result + > trap_ne +0d82 : d0fe > bne * ;failed not equal (non zero) + > +0d84 : 68 > pla ;load status +0d85 : 48 > pha + > cmp_flag 0 +0d86 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d88 : d0fe > bne * ;failed not equal (non zero) + > +0d8a : 28 > plp ;restore status + > + > set_a $aa-$e2,$ff + > load_flag $ff +0d8b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0d8d : 48 > pha ;use stack to load status +0d8e : a9c8 > lda #$aa-$e2 ;precharge accu +0d90 : 28 > plp + > +0d91 : e2 > db $e2 ;test nop integrity - flags on +0d92 : ea > nop +0d93 : ea > nop + > tst_a $aa-$e2,$ff +0d94 : 08 > php ;save flags +0d95 : c9c8 > cmp #$aa-$e2 ;test result + > trap_ne +0d97 : d0fe > bne * ;failed not equal (non zero) + > +0d99 : 68 > pla ;load status +0d9a : 48 > pha + > cmp_flag $ff +0d9b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0d9d : d0fe > bne * ;failed not equal (non zero) + > +0d9f : 28 > plp ;restore status + > +0da0 : c042 > cpy #$42 + > trap_ne ;y changed +0da2 : d0fe > bne * ;failed not equal (non zero) + > +0da4 : e000 > cpx #0 + > trap_ne ;x changed +0da6 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $44,2 +0da8 : a042 > ldy #$42 +0daa : a202 > ldx #4-2 +0dac : 44 > db $44 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0dad : c8 > iny +0dae : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0daf : ca > dex + > trap_ne ;wrong number of bytes +0db0 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$44,0 + > load_flag 0 +0db2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0db4 : 48 > pha ;use stack to load status +0db5 : a9bb > lda #$ff-$44 ;precharge accu +0db7 : 28 > plp + > +0db8 : 44 > db $44 ;test nop integrity - flags off +0db9 : ea > nop +0dba : ea > nop + > tst_a $ff-$44,0 +0dbb : 08 > php ;save flags +0dbc : c9bb > cmp #$ff-$44 ;test result + > trap_ne +0dbe : d0fe > bne * ;failed not equal (non zero) + > +0dc0 : 68 > pla ;load status +0dc1 : 48 > pha + > cmp_flag 0 +0dc2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0dc4 : d0fe > bne * ;failed not equal (non zero) + > +0dc6 : 28 > plp ;restore status + > + > set_a $aa-$44,$ff + > load_flag $ff +0dc7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0dc9 : 48 > pha ;use stack to load status +0dca : a966 > lda #$aa-$44 ;precharge accu +0dcc : 28 > plp + > +0dcd : 44 > db $44 ;test nop integrity - flags on +0dce : ea > nop +0dcf : ea > nop + > tst_a $aa-$44,$ff +0dd0 : 08 > php ;save flags +0dd1 : c966 > cmp #$aa-$44 ;test result + > trap_ne +0dd3 : d0fe > bne * ;failed not equal (non zero) + > +0dd5 : 68 > pla ;load status +0dd6 : 48 > pha + > cmp_flag $ff +0dd7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0dd9 : d0fe > bne * ;failed not equal (non zero) + > +0ddb : 28 > plp ;restore status + > +0ddc : c042 > cpy #$42 + > trap_ne ;y changed +0dde : d0fe > bne * ;failed not equal (non zero) + > +0de0 : e000 > cpx #0 + > trap_ne ;x changed +0de2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $54,2 +0de4 : a042 > ldy #$42 +0de6 : a202 > ldx #4-2 +0de8 : 54 > db $54 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0de9 : c8 > iny +0dea : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0deb : ca > dex + > trap_ne ;wrong number of bytes +0dec : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$54,0 + > load_flag 0 +0dee : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0df0 : 48 > pha ;use stack to load status +0df1 : a9ab > lda #$ff-$54 ;precharge accu +0df3 : 28 > plp + > +0df4 : 54 > db $54 ;test nop integrity - flags off +0df5 : ea > nop +0df6 : ea > nop + > tst_a $ff-$54,0 +0df7 : 08 > php ;save flags +0df8 : c9ab > cmp #$ff-$54 ;test result + > trap_ne +0dfa : d0fe > bne * ;failed not equal (non zero) + > +0dfc : 68 > pla ;load status +0dfd : 48 > pha + > cmp_flag 0 +0dfe : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e00 : d0fe > bne * ;failed not equal (non zero) + > +0e02 : 28 > plp ;restore status + > + > set_a $aa-$54,$ff + > load_flag $ff +0e03 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0e05 : 48 > pha ;use stack to load status +0e06 : a956 > lda #$aa-$54 ;precharge accu +0e08 : 28 > plp + > +0e09 : 54 > db $54 ;test nop integrity - flags on +0e0a : ea > nop +0e0b : ea > nop + > tst_a $aa-$54,$ff +0e0c : 08 > php ;save flags +0e0d : c956 > cmp #$aa-$54 ;test result + > trap_ne +0e0f : d0fe > bne * ;failed not equal (non zero) + > +0e11 : 68 > pla ;load status +0e12 : 48 > pha + > cmp_flag $ff +0e13 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e15 : d0fe > bne * ;failed not equal (non zero) + > +0e17 : 28 > plp ;restore status + > +0e18 : c042 > cpy #$42 + > trap_ne ;y changed +0e1a : d0fe > bne * ;failed not equal (non zero) + > +0e1c : e000 > cpx #0 + > trap_ne ;x changed +0e1e : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $d4,2 +0e20 : a042 > ldy #$42 +0e22 : a202 > ldx #4-2 +0e24 : d4 > db $d4 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0e25 : c8 > iny +0e26 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0e27 : ca > dex + > trap_ne ;wrong number of bytes +0e28 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$d4,0 + > load_flag 0 +0e2a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e2c : 48 > pha ;use stack to load status +0e2d : a92b > lda #$ff-$d4 ;precharge accu +0e2f : 28 > plp + > +0e30 : d4 > db $d4 ;test nop integrity - flags off +0e31 : ea > nop +0e32 : ea > nop + > tst_a $ff-$d4,0 +0e33 : 08 > php ;save flags +0e34 : c92b > cmp #$ff-$d4 ;test result + > trap_ne +0e36 : d0fe > bne * ;failed not equal (non zero) + > +0e38 : 68 > pla ;load status +0e39 : 48 > pha + > cmp_flag 0 +0e3a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e3c : d0fe > bne * ;failed not equal (non zero) + > +0e3e : 28 > plp ;restore status + > + > set_a $aa-$d4,$ff + > load_flag $ff +0e3f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0e41 : 48 > pha ;use stack to load status +0e42 : a9d6 > lda #$aa-$d4 ;precharge accu +0e44 : 28 > plp + > +0e45 : d4 > db $d4 ;test nop integrity - flags on +0e46 : ea > nop +0e47 : ea > nop + > tst_a $aa-$d4,$ff +0e48 : 08 > php ;save flags +0e49 : c9d6 > cmp #$aa-$d4 ;test result + > trap_ne +0e4b : d0fe > bne * ;failed not equal (non zero) + > +0e4d : 68 > pla ;load status +0e4e : 48 > pha + > cmp_flag $ff +0e4f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e51 : d0fe > bne * ;failed not equal (non zero) + > +0e53 : 28 > plp ;restore status + > +0e54 : c042 > cpy #$42 + > trap_ne ;y changed +0e56 : d0fe > bne * ;failed not equal (non zero) + > +0e58 : e000 > cpx #0 + > trap_ne ;x changed +0e5a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $f4,2 +0e5c : a042 > ldy #$42 +0e5e : a202 > ldx #4-2 +0e60 : f4 > db $f4 ;test nop length + > if 2 = 1 + > dex + > dex + > endif + > if 2 = 2 +0e61 : c8 > iny +0e62 : ca > dex + > endif + > if 2 = 3 + > iny + > iny + > endif +0e63 : ca > dex + > trap_ne ;wrong number of bytes +0e64 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$f4,0 + > load_flag 0 +0e66 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0e68 : 48 > pha ;use stack to load status +0e69 : a90b > lda #$ff-$f4 ;precharge accu +0e6b : 28 > plp + > +0e6c : f4 > db $f4 ;test nop integrity - flags off +0e6d : ea > nop +0e6e : ea > nop + > tst_a $ff-$f4,0 +0e6f : 08 > php ;save flags +0e70 : c90b > cmp #$ff-$f4 ;test result + > trap_ne +0e72 : d0fe > bne * ;failed not equal (non zero) + > +0e74 : 68 > pla ;load status +0e75 : 48 > pha + > cmp_flag 0 +0e76 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e78 : d0fe > bne * ;failed not equal (non zero) + > +0e7a : 28 > plp ;restore status + > + > set_a $aa-$f4,$ff + > load_flag $ff +0e7b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0e7d : 48 > pha ;use stack to load status +0e7e : a9b6 > lda #$aa-$f4 ;precharge accu +0e80 : 28 > plp + > +0e81 : f4 > db $f4 ;test nop integrity - flags on +0e82 : ea > nop +0e83 : ea > nop + > tst_a $aa-$f4,$ff +0e84 : 08 > php ;save flags +0e85 : c9b6 > cmp #$aa-$f4 ;test result + > trap_ne +0e87 : d0fe > bne * ;failed not equal (non zero) + > +0e89 : 68 > pla ;load status +0e8a : 48 > pha + > cmp_flag $ff +0e8b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0e8d : d0fe > bne * ;failed not equal (non zero) + > +0e8f : 28 > plp ;restore status + > +0e90 : c042 > cpy #$42 + > trap_ne ;y changed +0e92 : d0fe > bne * ;failed not equal (non zero) + > +0e94 : e000 > cpx #0 + > trap_ne ;x changed +0e96 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $5c,3 +0e98 : a042 > ldy #$42 +0e9a : a201 > ldx #4-3 +0e9c : 5c > db $5c ;test nop length + > if 3 = 1 + > dex + > dex + > endif + > if 3 = 2 + > iny + > dex + > endif + > if 3 = 3 +0e9d : c8 > iny +0e9e : c8 > iny + > endif +0e9f : ca > dex + > trap_ne ;wrong number of bytes +0ea0 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$5c,0 + > load_flag 0 +0ea2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0ea4 : 48 > pha ;use stack to load status +0ea5 : a9a3 > lda #$ff-$5c ;precharge accu +0ea7 : 28 > plp + > +0ea8 : 5c > db $5c ;test nop integrity - flags off +0ea9 : ea > nop +0eaa : ea > nop + > tst_a $ff-$5c,0 +0eab : 08 > php ;save flags +0eac : c9a3 > cmp #$ff-$5c ;test result + > trap_ne +0eae : d0fe > bne * ;failed not equal (non zero) + > +0eb0 : 68 > pla ;load status +0eb1 : 48 > pha + > cmp_flag 0 +0eb2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0eb4 : d0fe > bne * ;failed not equal (non zero) + > +0eb6 : 28 > plp ;restore status + > + > set_a $aa-$5c,$ff + > load_flag $ff +0eb7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0eb9 : 48 > pha ;use stack to load status +0eba : a94e > lda #$aa-$5c ;precharge accu +0ebc : 28 > plp + > +0ebd : 5c > db $5c ;test nop integrity - flags on +0ebe : ea > nop +0ebf : ea > nop + > tst_a $aa-$5c,$ff +0ec0 : 08 > php ;save flags +0ec1 : c94e > cmp #$aa-$5c ;test result + > trap_ne +0ec3 : d0fe > bne * ;failed not equal (non zero) + > +0ec5 : 68 > pla ;load status +0ec6 : 48 > pha + > cmp_flag $ff +0ec7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ec9 : d0fe > bne * ;failed not equal (non zero) + > +0ecb : 28 > plp ;restore status + > +0ecc : c042 > cpy #$42 + > trap_ne ;y changed +0ece : d0fe > bne * ;failed not equal (non zero) + > +0ed0 : e000 > cpx #0 + > trap_ne ;x changed +0ed2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $dc,3 +0ed4 : a042 > ldy #$42 +0ed6 : a201 > ldx #4-3 +0ed8 : dc > db $dc ;test nop length + > if 3 = 1 + > dex + > dex + > endif + > if 3 = 2 + > iny + > dex + > endif + > if 3 = 3 +0ed9 : c8 > iny +0eda : c8 > iny + > endif +0edb : ca > dex + > trap_ne ;wrong number of bytes +0edc : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$dc,0 + > load_flag 0 +0ede : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0ee0 : 48 > pha ;use stack to load status +0ee1 : a923 > lda #$ff-$dc ;precharge accu +0ee3 : 28 > plp + > +0ee4 : dc > db $dc ;test nop integrity - flags off +0ee5 : ea > nop +0ee6 : ea > nop + > tst_a $ff-$dc,0 +0ee7 : 08 > php ;save flags +0ee8 : c923 > cmp #$ff-$dc ;test result + > trap_ne +0eea : d0fe > bne * ;failed not equal (non zero) + > +0eec : 68 > pla ;load status +0eed : 48 > pha + > cmp_flag 0 +0eee : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ef0 : d0fe > bne * ;failed not equal (non zero) + > +0ef2 : 28 > plp ;restore status + > + > set_a $aa-$dc,$ff + > load_flag $ff +0ef3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0ef5 : 48 > pha ;use stack to load status +0ef6 : a9ce > lda #$aa-$dc ;precharge accu +0ef8 : 28 > plp + > +0ef9 : dc > db $dc ;test nop integrity - flags on +0efa : ea > nop +0efb : ea > nop + > tst_a $aa-$dc,$ff +0efc : 08 > php ;save flags +0efd : c9ce > cmp #$aa-$dc ;test result + > trap_ne +0eff : d0fe > bne * ;failed not equal (non zero) + > +0f01 : 68 > pla ;load status +0f02 : 48 > pha + > cmp_flag $ff +0f03 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0f05 : d0fe > bne * ;failed not equal (non zero) + > +0f07 : 28 > plp ;restore status + > +0f08 : c042 > cpy #$42 + > trap_ne ;y changed +0f0a : d0fe > bne * ;failed not equal (non zero) + > +0f0c : e000 > cpx #0 + > trap_ne ;x changed +0f0e : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $fc,3 +0f10 : a042 > ldy #$42 +0f12 : a201 > ldx #4-3 +0f14 : fc > db $fc ;test nop length + > if 3 = 1 + > dex + > dex + > endif + > if 3 = 2 + > iny + > dex + > endif + > if 3 = 3 +0f15 : c8 > iny +0f16 : c8 > iny + > endif +0f17 : ca > dex + > trap_ne ;wrong number of bytes +0f18 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$fc,0 + > load_flag 0 +0f1a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0f1c : 48 > pha ;use stack to load status +0f1d : a903 > lda #$ff-$fc ;precharge accu +0f1f : 28 > plp + > +0f20 : fc > db $fc ;test nop integrity - flags off +0f21 : ea > nop +0f22 : ea > nop + > tst_a $ff-$fc,0 +0f23 : 08 > php ;save flags +0f24 : c903 > cmp #$ff-$fc ;test result + > trap_ne +0f26 : d0fe > bne * ;failed not equal (non zero) + > +0f28 : 68 > pla ;load status +0f29 : 48 > pha + > cmp_flag 0 +0f2a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0f2c : d0fe > bne * ;failed not equal (non zero) + > +0f2e : 28 > plp ;restore status + > + > set_a $aa-$fc,$ff + > load_flag $ff +0f2f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0f31 : 48 > pha ;use stack to load status +0f32 : a9ae > lda #$aa-$fc ;precharge accu +0f34 : 28 > plp + > +0f35 : fc > db $fc ;test nop integrity - flags on +0f36 : ea > nop +0f37 : ea > nop + > tst_a $aa-$fc,$ff +0f38 : 08 > php ;save flags +0f39 : c9ae > cmp #$aa-$fc ;test result + > trap_ne +0f3b : d0fe > bne * ;failed not equal (non zero) + > +0f3d : 68 > pla ;load status +0f3e : 48 > pha + > cmp_flag $ff +0f3f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0f41 : d0fe > bne * ;failed not equal (non zero) + > +0f43 : 28 > plp ;restore status + > +0f44 : c042 > cpy #$42 + > trap_ne ;y changed +0f46 : d0fe > bne * ;failed not equal (non zero) + > +0f48 : e000 > cpx #0 + > trap_ne ;x changed +0f4a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $03,1 +0f4c : a042 > ldy #$42 +0f4e : a203 > ldx #4-1 +0f50 : 03 > db $03 ;test nop length + > if 1 = 1 +0f51 : ca > dex +0f52 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +0f53 : ca > dex + > trap_ne ;wrong number of bytes +0f54 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$03,0 + > load_flag 0 +0f56 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0f58 : 48 > pha ;use stack to load status +0f59 : a9fc > lda #$ff-$03 ;precharge accu +0f5b : 28 > plp + > +0f5c : 03 > db $03 ;test nop integrity - flags off +0f5d : ea > nop +0f5e : ea > nop + > tst_a $ff-$03,0 +0f5f : 08 > php ;save flags +0f60 : c9fc > cmp #$ff-$03 ;test result + > trap_ne +0f62 : d0fe > bne * ;failed not equal (non zero) + > +0f64 : 68 > pla ;load status +0f65 : 48 > pha + > cmp_flag 0 +0f66 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0f68 : d0fe > bne * ;failed not equal (non zero) + > +0f6a : 28 > plp ;restore status + > + > set_a $aa-$03,$ff + > load_flag $ff +0f6b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0f6d : 48 > pha ;use stack to load status +0f6e : a9a7 > lda #$aa-$03 ;precharge accu +0f70 : 28 > plp + > +0f71 : 03 > db $03 ;test nop integrity - flags on +0f72 : ea > nop +0f73 : ea > nop + > tst_a $aa-$03,$ff +0f74 : 08 > php ;save flags +0f75 : c9a7 > cmp #$aa-$03 ;test result + > trap_ne +0f77 : d0fe > bne * ;failed not equal (non zero) + > +0f79 : 68 > pla ;load status +0f7a : 48 > pha + > cmp_flag $ff +0f7b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0f7d : d0fe > bne * ;failed not equal (non zero) + > +0f7f : 28 > plp ;restore status + > +0f80 : c042 > cpy #$42 + > trap_ne ;y changed +0f82 : d0fe > bne * ;failed not equal (non zero) + > +0f84 : e000 > cpx #0 + > trap_ne ;x changed +0f86 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $13,1 +0f88 : a042 > ldy #$42 +0f8a : a203 > ldx #4-1 +0f8c : 13 > db $13 ;test nop length + > if 1 = 1 +0f8d : ca > dex +0f8e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +0f8f : ca > dex + > trap_ne ;wrong number of bytes +0f90 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$13,0 + > load_flag 0 +0f92 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0f94 : 48 > pha ;use stack to load status +0f95 : a9ec > lda #$ff-$13 ;precharge accu +0f97 : 28 > plp + > +0f98 : 13 > db $13 ;test nop integrity - flags off +0f99 : ea > nop +0f9a : ea > nop + > tst_a $ff-$13,0 +0f9b : 08 > php ;save flags +0f9c : c9ec > cmp #$ff-$13 ;test result + > trap_ne +0f9e : d0fe > bne * ;failed not equal (non zero) + > +0fa0 : 68 > pla ;load status +0fa1 : 48 > pha + > cmp_flag 0 +0fa2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0fa4 : d0fe > bne * ;failed not equal (non zero) + > +0fa6 : 28 > plp ;restore status + > + > set_a $aa-$13,$ff + > load_flag $ff +0fa7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0fa9 : 48 > pha ;use stack to load status +0faa : a997 > lda #$aa-$13 ;precharge accu +0fac : 28 > plp + > +0fad : 13 > db $13 ;test nop integrity - flags on +0fae : ea > nop +0faf : ea > nop + > tst_a $aa-$13,$ff +0fb0 : 08 > php ;save flags +0fb1 : c997 > cmp #$aa-$13 ;test result + > trap_ne +0fb3 : d0fe > bne * ;failed not equal (non zero) + > +0fb5 : 68 > pla ;load status +0fb6 : 48 > pha + > cmp_flag $ff +0fb7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0fb9 : d0fe > bne * ;failed not equal (non zero) + > +0fbb : 28 > plp ;restore status + > +0fbc : c042 > cpy #$42 + > trap_ne ;y changed +0fbe : d0fe > bne * ;failed not equal (non zero) + > +0fc0 : e000 > cpx #0 + > trap_ne ;x changed +0fc2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $23,1 +0fc4 : a042 > ldy #$42 +0fc6 : a203 > ldx #4-1 +0fc8 : 23 > db $23 ;test nop length + > if 1 = 1 +0fc9 : ca > dex +0fca : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +0fcb : ca > dex + > trap_ne ;wrong number of bytes +0fcc : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$23,0 + > load_flag 0 +0fce : a900 > lda #0 ;allow test to change I-flag (no mask) + > +0fd0 : 48 > pha ;use stack to load status +0fd1 : a9dc > lda #$ff-$23 ;precharge accu +0fd3 : 28 > plp + > +0fd4 : 23 > db $23 ;test nop integrity - flags off +0fd5 : ea > nop +0fd6 : ea > nop + > tst_a $ff-$23,0 +0fd7 : 08 > php ;save flags +0fd8 : c9dc > cmp #$ff-$23 ;test result + > trap_ne +0fda : d0fe > bne * ;failed not equal (non zero) + > +0fdc : 68 > pla ;load status +0fdd : 48 > pha + > cmp_flag 0 +0fde : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0fe0 : d0fe > bne * ;failed not equal (non zero) + > +0fe2 : 28 > plp ;restore status + > + > set_a $aa-$23,$ff + > load_flag $ff +0fe3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +0fe5 : 48 > pha ;use stack to load status +0fe6 : a987 > lda #$aa-$23 ;precharge accu +0fe8 : 28 > plp + > +0fe9 : 23 > db $23 ;test nop integrity - flags on +0fea : ea > nop +0feb : ea > nop + > tst_a $aa-$23,$ff +0fec : 08 > php ;save flags +0fed : c987 > cmp #$aa-$23 ;test result + > trap_ne +0fef : d0fe > bne * ;failed not equal (non zero) + > +0ff1 : 68 > pla ;load status +0ff2 : 48 > pha + > cmp_flag $ff +0ff3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +0ff5 : d0fe > bne * ;failed not equal (non zero) + > +0ff7 : 28 > plp ;restore status + > +0ff8 : c042 > cpy #$42 + > trap_ne ;y changed +0ffa : d0fe > bne * ;failed not equal (non zero) + > +0ffc : e000 > cpx #0 + > trap_ne ;x changed +0ffe : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $33,1 +1000 : a042 > ldy #$42 +1002 : a203 > ldx #4-1 +1004 : 33 > db $33 ;test nop length + > if 1 = 1 +1005 : ca > dex +1006 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1007 : ca > dex + > trap_ne ;wrong number of bytes +1008 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$33,0 + > load_flag 0 +100a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +100c : 48 > pha ;use stack to load status +100d : a9cc > lda #$ff-$33 ;precharge accu +100f : 28 > plp + > +1010 : 33 > db $33 ;test nop integrity - flags off +1011 : ea > nop +1012 : ea > nop + > tst_a $ff-$33,0 +1013 : 08 > php ;save flags +1014 : c9cc > cmp #$ff-$33 ;test result + > trap_ne +1016 : d0fe > bne * ;failed not equal (non zero) + > +1018 : 68 > pla ;load status +1019 : 48 > pha + > cmp_flag 0 +101a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +101c : d0fe > bne * ;failed not equal (non zero) + > +101e : 28 > plp ;restore status + > + > set_a $aa-$33,$ff + > load_flag $ff +101f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1021 : 48 > pha ;use stack to load status +1022 : a977 > lda #$aa-$33 ;precharge accu +1024 : 28 > plp + > +1025 : 33 > db $33 ;test nop integrity - flags on +1026 : ea > nop +1027 : ea > nop + > tst_a $aa-$33,$ff +1028 : 08 > php ;save flags +1029 : c977 > cmp #$aa-$33 ;test result + > trap_ne +102b : d0fe > bne * ;failed not equal (non zero) + > +102d : 68 > pla ;load status +102e : 48 > pha + > cmp_flag $ff +102f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1031 : d0fe > bne * ;failed not equal (non zero) + > +1033 : 28 > plp ;restore status + > +1034 : c042 > cpy #$42 + > trap_ne ;y changed +1036 : d0fe > bne * ;failed not equal (non zero) + > +1038 : e000 > cpx #0 + > trap_ne ;x changed +103a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $43,1 +103c : a042 > ldy #$42 +103e : a203 > ldx #4-1 +1040 : 43 > db $43 ;test nop length + > if 1 = 1 +1041 : ca > dex +1042 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1043 : ca > dex + > trap_ne ;wrong number of bytes +1044 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$43,0 + > load_flag 0 +1046 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1048 : 48 > pha ;use stack to load status +1049 : a9bc > lda #$ff-$43 ;precharge accu +104b : 28 > plp + > +104c : 43 > db $43 ;test nop integrity - flags off +104d : ea > nop +104e : ea > nop + > tst_a $ff-$43,0 +104f : 08 > php ;save flags +1050 : c9bc > cmp #$ff-$43 ;test result + > trap_ne +1052 : d0fe > bne * ;failed not equal (non zero) + > +1054 : 68 > pla ;load status +1055 : 48 > pha + > cmp_flag 0 +1056 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1058 : d0fe > bne * ;failed not equal (non zero) + > +105a : 28 > plp ;restore status + > + > set_a $aa-$43,$ff + > load_flag $ff +105b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +105d : 48 > pha ;use stack to load status +105e : a967 > lda #$aa-$43 ;precharge accu +1060 : 28 > plp + > +1061 : 43 > db $43 ;test nop integrity - flags on +1062 : ea > nop +1063 : ea > nop + > tst_a $aa-$43,$ff +1064 : 08 > php ;save flags +1065 : c967 > cmp #$aa-$43 ;test result + > trap_ne +1067 : d0fe > bne * ;failed not equal (non zero) + > +1069 : 68 > pla ;load status +106a : 48 > pha + > cmp_flag $ff +106b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +106d : d0fe > bne * ;failed not equal (non zero) + > +106f : 28 > plp ;restore status + > +1070 : c042 > cpy #$42 + > trap_ne ;y changed +1072 : d0fe > bne * ;failed not equal (non zero) + > +1074 : e000 > cpx #0 + > trap_ne ;x changed +1076 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $53,1 +1078 : a042 > ldy #$42 +107a : a203 > ldx #4-1 +107c : 53 > db $53 ;test nop length + > if 1 = 1 +107d : ca > dex +107e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +107f : ca > dex + > trap_ne ;wrong number of bytes +1080 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$53,0 + > load_flag 0 +1082 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1084 : 48 > pha ;use stack to load status +1085 : a9ac > lda #$ff-$53 ;precharge accu +1087 : 28 > plp + > +1088 : 53 > db $53 ;test nop integrity - flags off +1089 : ea > nop +108a : ea > nop + > tst_a $ff-$53,0 +108b : 08 > php ;save flags +108c : c9ac > cmp #$ff-$53 ;test result + > trap_ne +108e : d0fe > bne * ;failed not equal (non zero) + > +1090 : 68 > pla ;load status +1091 : 48 > pha + > cmp_flag 0 +1092 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1094 : d0fe > bne * ;failed not equal (non zero) + > +1096 : 28 > plp ;restore status + > + > set_a $aa-$53,$ff + > load_flag $ff +1097 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1099 : 48 > pha ;use stack to load status +109a : a957 > lda #$aa-$53 ;precharge accu +109c : 28 > plp + > +109d : 53 > db $53 ;test nop integrity - flags on +109e : ea > nop +109f : ea > nop + > tst_a $aa-$53,$ff +10a0 : 08 > php ;save flags +10a1 : c957 > cmp #$aa-$53 ;test result + > trap_ne +10a3 : d0fe > bne * ;failed not equal (non zero) + > +10a5 : 68 > pla ;load status +10a6 : 48 > pha + > cmp_flag $ff +10a7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +10a9 : d0fe > bne * ;failed not equal (non zero) + > +10ab : 28 > plp ;restore status + > +10ac : c042 > cpy #$42 + > trap_ne ;y changed +10ae : d0fe > bne * ;failed not equal (non zero) + > +10b0 : e000 > cpx #0 + > trap_ne ;x changed +10b2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $63,1 +10b4 : a042 > ldy #$42 +10b6 : a203 > ldx #4-1 +10b8 : 63 > db $63 ;test nop length + > if 1 = 1 +10b9 : ca > dex +10ba : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +10bb : ca > dex + > trap_ne ;wrong number of bytes +10bc : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$63,0 + > load_flag 0 +10be : a900 > lda #0 ;allow test to change I-flag (no mask) + > +10c0 : 48 > pha ;use stack to load status +10c1 : a99c > lda #$ff-$63 ;precharge accu +10c3 : 28 > plp + > +10c4 : 63 > db $63 ;test nop integrity - flags off +10c5 : ea > nop +10c6 : ea > nop + > tst_a $ff-$63,0 +10c7 : 08 > php ;save flags +10c8 : c99c > cmp #$ff-$63 ;test result + > trap_ne +10ca : d0fe > bne * ;failed not equal (non zero) + > +10cc : 68 > pla ;load status +10cd : 48 > pha + > cmp_flag 0 +10ce : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +10d0 : d0fe > bne * ;failed not equal (non zero) + > +10d2 : 28 > plp ;restore status + > + > set_a $aa-$63,$ff + > load_flag $ff +10d3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +10d5 : 48 > pha ;use stack to load status +10d6 : a947 > lda #$aa-$63 ;precharge accu +10d8 : 28 > plp + > +10d9 : 63 > db $63 ;test nop integrity - flags on +10da : ea > nop +10db : ea > nop + > tst_a $aa-$63,$ff +10dc : 08 > php ;save flags +10dd : c947 > cmp #$aa-$63 ;test result + > trap_ne +10df : d0fe > bne * ;failed not equal (non zero) + > +10e1 : 68 > pla ;load status +10e2 : 48 > pha + > cmp_flag $ff +10e3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +10e5 : d0fe > bne * ;failed not equal (non zero) + > +10e7 : 28 > plp ;restore status + > +10e8 : c042 > cpy #$42 + > trap_ne ;y changed +10ea : d0fe > bne * ;failed not equal (non zero) + > +10ec : e000 > cpx #0 + > trap_ne ;x changed +10ee : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $73,1 +10f0 : a042 > ldy #$42 +10f2 : a203 > ldx #4-1 +10f4 : 73 > db $73 ;test nop length + > if 1 = 1 +10f5 : ca > dex +10f6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +10f7 : ca > dex + > trap_ne ;wrong number of bytes +10f8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$73,0 + > load_flag 0 +10fa : a900 > lda #0 ;allow test to change I-flag (no mask) + > +10fc : 48 > pha ;use stack to load status +10fd : a98c > lda #$ff-$73 ;precharge accu +10ff : 28 > plp + > +1100 : 73 > db $73 ;test nop integrity - flags off +1101 : ea > nop +1102 : ea > nop + > tst_a $ff-$73,0 +1103 : 08 > php ;save flags +1104 : c98c > cmp #$ff-$73 ;test result + > trap_ne +1106 : d0fe > bne * ;failed not equal (non zero) + > +1108 : 68 > pla ;load status +1109 : 48 > pha + > cmp_flag 0 +110a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +110c : d0fe > bne * ;failed not equal (non zero) + > +110e : 28 > plp ;restore status + > + > set_a $aa-$73,$ff + > load_flag $ff +110f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1111 : 48 > pha ;use stack to load status +1112 : a937 > lda #$aa-$73 ;precharge accu +1114 : 28 > plp + > +1115 : 73 > db $73 ;test nop integrity - flags on +1116 : ea > nop +1117 : ea > nop + > tst_a $aa-$73,$ff +1118 : 08 > php ;save flags +1119 : c937 > cmp #$aa-$73 ;test result + > trap_ne +111b : d0fe > bne * ;failed not equal (non zero) + > +111d : 68 > pla ;load status +111e : 48 > pha + > cmp_flag $ff +111f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1121 : d0fe > bne * ;failed not equal (non zero) + > +1123 : 28 > plp ;restore status + > +1124 : c042 > cpy #$42 + > trap_ne ;y changed +1126 : d0fe > bne * ;failed not equal (non zero) + > +1128 : e000 > cpx #0 + > trap_ne ;x changed +112a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $83,1 +112c : a042 > ldy #$42 +112e : a203 > ldx #4-1 +1130 : 83 > db $83 ;test nop length + > if 1 = 1 +1131 : ca > dex +1132 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1133 : ca > dex + > trap_ne ;wrong number of bytes +1134 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$83,0 + > load_flag 0 +1136 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1138 : 48 > pha ;use stack to load status +1139 : a97c > lda #$ff-$83 ;precharge accu +113b : 28 > plp + > +113c : 83 > db $83 ;test nop integrity - flags off +113d : ea > nop +113e : ea > nop + > tst_a $ff-$83,0 +113f : 08 > php ;save flags +1140 : c97c > cmp #$ff-$83 ;test result + > trap_ne +1142 : d0fe > bne * ;failed not equal (non zero) + > +1144 : 68 > pla ;load status +1145 : 48 > pha + > cmp_flag 0 +1146 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1148 : d0fe > bne * ;failed not equal (non zero) + > +114a : 28 > plp ;restore status + > + > set_a $aa-$83,$ff + > load_flag $ff +114b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +114d : 48 > pha ;use stack to load status +114e : a927 > lda #$aa-$83 ;precharge accu +1150 : 28 > plp + > +1151 : 83 > db $83 ;test nop integrity - flags on +1152 : ea > nop +1153 : ea > nop + > tst_a $aa-$83,$ff +1154 : 08 > php ;save flags +1155 : c927 > cmp #$aa-$83 ;test result + > trap_ne +1157 : d0fe > bne * ;failed not equal (non zero) + > +1159 : 68 > pla ;load status +115a : 48 > pha + > cmp_flag $ff +115b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +115d : d0fe > bne * ;failed not equal (non zero) + > +115f : 28 > plp ;restore status + > +1160 : c042 > cpy #$42 + > trap_ne ;y changed +1162 : d0fe > bne * ;failed not equal (non zero) + > +1164 : e000 > cpx #0 + > trap_ne ;x changed +1166 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $93,1 +1168 : a042 > ldy #$42 +116a : a203 > ldx #4-1 +116c : 93 > db $93 ;test nop length + > if 1 = 1 +116d : ca > dex +116e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +116f : ca > dex + > trap_ne ;wrong number of bytes +1170 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$93,0 + > load_flag 0 +1172 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1174 : 48 > pha ;use stack to load status +1175 : a96c > lda #$ff-$93 ;precharge accu +1177 : 28 > plp + > +1178 : 93 > db $93 ;test nop integrity - flags off +1179 : ea > nop +117a : ea > nop + > tst_a $ff-$93,0 +117b : 08 > php ;save flags +117c : c96c > cmp #$ff-$93 ;test result + > trap_ne +117e : d0fe > bne * ;failed not equal (non zero) + > +1180 : 68 > pla ;load status +1181 : 48 > pha + > cmp_flag 0 +1182 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1184 : d0fe > bne * ;failed not equal (non zero) + > +1186 : 28 > plp ;restore status + > + > set_a $aa-$93,$ff + > load_flag $ff +1187 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1189 : 48 > pha ;use stack to load status +118a : a917 > lda #$aa-$93 ;precharge accu +118c : 28 > plp + > +118d : 93 > db $93 ;test nop integrity - flags on +118e : ea > nop +118f : ea > nop + > tst_a $aa-$93,$ff +1190 : 08 > php ;save flags +1191 : c917 > cmp #$aa-$93 ;test result + > trap_ne +1193 : d0fe > bne * ;failed not equal (non zero) + > +1195 : 68 > pla ;load status +1196 : 48 > pha + > cmp_flag $ff +1197 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1199 : d0fe > bne * ;failed not equal (non zero) + > +119b : 28 > plp ;restore status + > +119c : c042 > cpy #$42 + > trap_ne ;y changed +119e : d0fe > bne * ;failed not equal (non zero) + > +11a0 : e000 > cpx #0 + > trap_ne ;x changed +11a2 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $a3,1 +11a4 : a042 > ldy #$42 +11a6 : a203 > ldx #4-1 +11a8 : a3 > db $a3 ;test nop length + > if 1 = 1 +11a9 : ca > dex +11aa : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +11ab : ca > dex + > trap_ne ;wrong number of bytes +11ac : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$a3,0 + > load_flag 0 +11ae : a900 > lda #0 ;allow test to change I-flag (no mask) + > +11b0 : 48 > pha ;use stack to load status +11b1 : a95c > lda #$ff-$a3 ;precharge accu +11b3 : 28 > plp + > +11b4 : a3 > db $a3 ;test nop integrity - flags off +11b5 : ea > nop +11b6 : ea > nop + > tst_a $ff-$a3,0 +11b7 : 08 > php ;save flags +11b8 : c95c > cmp #$ff-$a3 ;test result + > trap_ne +11ba : d0fe > bne * ;failed not equal (non zero) + > +11bc : 68 > pla ;load status +11bd : 48 > pha + > cmp_flag 0 +11be : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +11c0 : d0fe > bne * ;failed not equal (non zero) + > +11c2 : 28 > plp ;restore status + > + > set_a $aa-$a3,$ff + > load_flag $ff +11c3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +11c5 : 48 > pha ;use stack to load status +11c6 : a907 > lda #$aa-$a3 ;precharge accu +11c8 : 28 > plp + > +11c9 : a3 > db $a3 ;test nop integrity - flags on +11ca : ea > nop +11cb : ea > nop + > tst_a $aa-$a3,$ff +11cc : 08 > php ;save flags +11cd : c907 > cmp #$aa-$a3 ;test result + > trap_ne +11cf : d0fe > bne * ;failed not equal (non zero) + > +11d1 : 68 > pla ;load status +11d2 : 48 > pha + > cmp_flag $ff +11d3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +11d5 : d0fe > bne * ;failed not equal (non zero) + > +11d7 : 28 > plp ;restore status + > +11d8 : c042 > cpy #$42 + > trap_ne ;y changed +11da : d0fe > bne * ;failed not equal (non zero) + > +11dc : e000 > cpx #0 + > trap_ne ;x changed +11de : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $b3,1 +11e0 : a042 > ldy #$42 +11e2 : a203 > ldx #4-1 +11e4 : b3 > db $b3 ;test nop length + > if 1 = 1 +11e5 : ca > dex +11e6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +11e7 : ca > dex + > trap_ne ;wrong number of bytes +11e8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$b3,0 + > load_flag 0 +11ea : a900 > lda #0 ;allow test to change I-flag (no mask) + > +11ec : 48 > pha ;use stack to load status +11ed : a94c > lda #$ff-$b3 ;precharge accu +11ef : 28 > plp + > +11f0 : b3 > db $b3 ;test nop integrity - flags off +11f1 : ea > nop +11f2 : ea > nop + > tst_a $ff-$b3,0 +11f3 : 08 > php ;save flags +11f4 : c94c > cmp #$ff-$b3 ;test result + > trap_ne +11f6 : d0fe > bne * ;failed not equal (non zero) + > +11f8 : 68 > pla ;load status +11f9 : 48 > pha + > cmp_flag 0 +11fa : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +11fc : d0fe > bne * ;failed not equal (non zero) + > +11fe : 28 > plp ;restore status + > + > set_a $aa-$b3,$ff + > load_flag $ff +11ff : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1201 : 48 > pha ;use stack to load status +1202 : a9f7 > lda #$aa-$b3 ;precharge accu +1204 : 28 > plp + > +1205 : b3 > db $b3 ;test nop integrity - flags on +1206 : ea > nop +1207 : ea > nop + > tst_a $aa-$b3,$ff +1208 : 08 > php ;save flags +1209 : c9f7 > cmp #$aa-$b3 ;test result + > trap_ne +120b : d0fe > bne * ;failed not equal (non zero) + > +120d : 68 > pla ;load status +120e : 48 > pha + > cmp_flag $ff +120f : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1211 : d0fe > bne * ;failed not equal (non zero) + > +1213 : 28 > plp ;restore status + > +1214 : c042 > cpy #$42 + > trap_ne ;y changed +1216 : d0fe > bne * ;failed not equal (non zero) + > +1218 : e000 > cpx #0 + > trap_ne ;x changed +121a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $c3,1 +121c : a042 > ldy #$42 +121e : a203 > ldx #4-1 +1220 : c3 > db $c3 ;test nop length + > if 1 = 1 +1221 : ca > dex +1222 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1223 : ca > dex + > trap_ne ;wrong number of bytes +1224 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$c3,0 + > load_flag 0 +1226 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1228 : 48 > pha ;use stack to load status +1229 : a93c > lda #$ff-$c3 ;precharge accu +122b : 28 > plp + > +122c : c3 > db $c3 ;test nop integrity - flags off +122d : ea > nop +122e : ea > nop + > tst_a $ff-$c3,0 +122f : 08 > php ;save flags +1230 : c93c > cmp #$ff-$c3 ;test result + > trap_ne +1232 : d0fe > bne * ;failed not equal (non zero) + > +1234 : 68 > pla ;load status +1235 : 48 > pha + > cmp_flag 0 +1236 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1238 : d0fe > bne * ;failed not equal (non zero) + > +123a : 28 > plp ;restore status + > + > set_a $aa-$c3,$ff + > load_flag $ff +123b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +123d : 48 > pha ;use stack to load status +123e : a9e7 > lda #$aa-$c3 ;precharge accu +1240 : 28 > plp + > +1241 : c3 > db $c3 ;test nop integrity - flags on +1242 : ea > nop +1243 : ea > nop + > tst_a $aa-$c3,$ff +1244 : 08 > php ;save flags +1245 : c9e7 > cmp #$aa-$c3 ;test result + > trap_ne +1247 : d0fe > bne * ;failed not equal (non zero) + > +1249 : 68 > pla ;load status +124a : 48 > pha + > cmp_flag $ff +124b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +124d : d0fe > bne * ;failed not equal (non zero) + > +124f : 28 > plp ;restore status + > +1250 : c042 > cpy #$42 + > trap_ne ;y changed +1252 : d0fe > bne * ;failed not equal (non zero) + > +1254 : e000 > cpx #0 + > trap_ne ;x changed +1256 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $d3,1 +1258 : a042 > ldy #$42 +125a : a203 > ldx #4-1 +125c : d3 > db $d3 ;test nop length + > if 1 = 1 +125d : ca > dex +125e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +125f : ca > dex + > trap_ne ;wrong number of bytes +1260 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$d3,0 + > load_flag 0 +1262 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1264 : 48 > pha ;use stack to load status +1265 : a92c > lda #$ff-$d3 ;precharge accu +1267 : 28 > plp + > +1268 : d3 > db $d3 ;test nop integrity - flags off +1269 : ea > nop +126a : ea > nop + > tst_a $ff-$d3,0 +126b : 08 > php ;save flags +126c : c92c > cmp #$ff-$d3 ;test result + > trap_ne +126e : d0fe > bne * ;failed not equal (non zero) + > +1270 : 68 > pla ;load status +1271 : 48 > pha + > cmp_flag 0 +1272 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1274 : d0fe > bne * ;failed not equal (non zero) + > +1276 : 28 > plp ;restore status + > + > set_a $aa-$d3,$ff + > load_flag $ff +1277 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1279 : 48 > pha ;use stack to load status +127a : a9d7 > lda #$aa-$d3 ;precharge accu +127c : 28 > plp + > +127d : d3 > db $d3 ;test nop integrity - flags on +127e : ea > nop +127f : ea > nop + > tst_a $aa-$d3,$ff +1280 : 08 > php ;save flags +1281 : c9d7 > cmp #$aa-$d3 ;test result + > trap_ne +1283 : d0fe > bne * ;failed not equal (non zero) + > +1285 : 68 > pla ;load status +1286 : 48 > pha + > cmp_flag $ff +1287 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1289 : d0fe > bne * ;failed not equal (non zero) + > +128b : 28 > plp ;restore status + > +128c : c042 > cpy #$42 + > trap_ne ;y changed +128e : d0fe > bne * ;failed not equal (non zero) + > +1290 : e000 > cpx #0 + > trap_ne ;x changed +1292 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $e3,1 +1294 : a042 > ldy #$42 +1296 : a203 > ldx #4-1 +1298 : e3 > db $e3 ;test nop length + > if 1 = 1 +1299 : ca > dex +129a : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +129b : ca > dex + > trap_ne ;wrong number of bytes +129c : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$e3,0 + > load_flag 0 +129e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +12a0 : 48 > pha ;use stack to load status +12a1 : a91c > lda #$ff-$e3 ;precharge accu +12a3 : 28 > plp + > +12a4 : e3 > db $e3 ;test nop integrity - flags off +12a5 : ea > nop +12a6 : ea > nop + > tst_a $ff-$e3,0 +12a7 : 08 > php ;save flags +12a8 : c91c > cmp #$ff-$e3 ;test result + > trap_ne +12aa : d0fe > bne * ;failed not equal (non zero) + > +12ac : 68 > pla ;load status +12ad : 48 > pha + > cmp_flag 0 +12ae : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +12b0 : d0fe > bne * ;failed not equal (non zero) + > +12b2 : 28 > plp ;restore status + > + > set_a $aa-$e3,$ff + > load_flag $ff +12b3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +12b5 : 48 > pha ;use stack to load status +12b6 : a9c7 > lda #$aa-$e3 ;precharge accu +12b8 : 28 > plp + > +12b9 : e3 > db $e3 ;test nop integrity - flags on +12ba : ea > nop +12bb : ea > nop + > tst_a $aa-$e3,$ff +12bc : 08 > php ;save flags +12bd : c9c7 > cmp #$aa-$e3 ;test result + > trap_ne +12bf : d0fe > bne * ;failed not equal (non zero) + > +12c1 : 68 > pla ;load status +12c2 : 48 > pha + > cmp_flag $ff +12c3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +12c5 : d0fe > bne * ;failed not equal (non zero) + > +12c7 : 28 > plp ;restore status + > +12c8 : c042 > cpy #$42 + > trap_ne ;y changed +12ca : d0fe > bne * ;failed not equal (non zero) + > +12cc : e000 > cpx #0 + > trap_ne ;x changed +12ce : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $f3,1 +12d0 : a042 > ldy #$42 +12d2 : a203 > ldx #4-1 +12d4 : f3 > db $f3 ;test nop length + > if 1 = 1 +12d5 : ca > dex +12d6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +12d7 : ca > dex + > trap_ne ;wrong number of bytes +12d8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$f3,0 + > load_flag 0 +12da : a900 > lda #0 ;allow test to change I-flag (no mask) + > +12dc : 48 > pha ;use stack to load status +12dd : a90c > lda #$ff-$f3 ;precharge accu +12df : 28 > plp + > +12e0 : f3 > db $f3 ;test nop integrity - flags off +12e1 : ea > nop +12e2 : ea > nop + > tst_a $ff-$f3,0 +12e3 : 08 > php ;save flags +12e4 : c90c > cmp #$ff-$f3 ;test result + > trap_ne +12e6 : d0fe > bne * ;failed not equal (non zero) + > +12e8 : 68 > pla ;load status +12e9 : 48 > pha + > cmp_flag 0 +12ea : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +12ec : d0fe > bne * ;failed not equal (non zero) + > +12ee : 28 > plp ;restore status + > + > set_a $aa-$f3,$ff + > load_flag $ff +12ef : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +12f1 : 48 > pha ;use stack to load status +12f2 : a9b7 > lda #$aa-$f3 ;precharge accu +12f4 : 28 > plp + > +12f5 : f3 > db $f3 ;test nop integrity - flags on +12f6 : ea > nop +12f7 : ea > nop + > tst_a $aa-$f3,$ff +12f8 : 08 > php ;save flags +12f9 : c9b7 > cmp #$aa-$f3 ;test result + > trap_ne +12fb : d0fe > bne * ;failed not equal (non zero) + > +12fd : 68 > pla ;load status +12fe : 48 > pha + > cmp_flag $ff +12ff : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1301 : d0fe > bne * ;failed not equal (non zero) + > +1303 : 28 > plp ;restore status + > +1304 : c042 > cpy #$42 + > trap_ne ;y changed +1306 : d0fe > bne * ;failed not equal (non zero) + > +1308 : e000 > cpx #0 + > trap_ne ;x changed +130a : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $0b,1 +130c : a042 > ldy #$42 +130e : a203 > ldx #4-1 +1310 : 0b > db $0b ;test nop length + > if 1 = 1 +1311 : ca > dex +1312 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1313 : ca > dex + > trap_ne ;wrong number of bytes +1314 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$0b,0 + > load_flag 0 +1316 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1318 : 48 > pha ;use stack to load status +1319 : a9f4 > lda #$ff-$0b ;precharge accu +131b : 28 > plp + > +131c : 0b > db $0b ;test nop integrity - flags off +131d : ea > nop +131e : ea > nop + > tst_a $ff-$0b,0 +131f : 08 > php ;save flags +1320 : c9f4 > cmp #$ff-$0b ;test result + > trap_ne +1322 : d0fe > bne * ;failed not equal (non zero) + > +1324 : 68 > pla ;load status +1325 : 48 > pha + > cmp_flag 0 +1326 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1328 : d0fe > bne * ;failed not equal (non zero) + > +132a : 28 > plp ;restore status + > + > set_a $aa-$0b,$ff + > load_flag $ff +132b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +132d : 48 > pha ;use stack to load status +132e : a99f > lda #$aa-$0b ;precharge accu +1330 : 28 > plp + > +1331 : 0b > db $0b ;test nop integrity - flags on +1332 : ea > nop +1333 : ea > nop + > tst_a $aa-$0b,$ff +1334 : 08 > php ;save flags +1335 : c99f > cmp #$aa-$0b ;test result + > trap_ne +1337 : d0fe > bne * ;failed not equal (non zero) + > +1339 : 68 > pla ;load status +133a : 48 > pha + > cmp_flag $ff +133b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +133d : d0fe > bne * ;failed not equal (non zero) + > +133f : 28 > plp ;restore status + > +1340 : c042 > cpy #$42 + > trap_ne ;y changed +1342 : d0fe > bne * ;failed not equal (non zero) + > +1344 : e000 > cpx #0 + > trap_ne ;x changed +1346 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $1b,1 +1348 : a042 > ldy #$42 +134a : a203 > ldx #4-1 +134c : 1b > db $1b ;test nop length + > if 1 = 1 +134d : ca > dex +134e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +134f : ca > dex + > trap_ne ;wrong number of bytes +1350 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$1b,0 + > load_flag 0 +1352 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1354 : 48 > pha ;use stack to load status +1355 : a9e4 > lda #$ff-$1b ;precharge accu +1357 : 28 > plp + > +1358 : 1b > db $1b ;test nop integrity - flags off +1359 : ea > nop +135a : ea > nop + > tst_a $ff-$1b,0 +135b : 08 > php ;save flags +135c : c9e4 > cmp #$ff-$1b ;test result + > trap_ne +135e : d0fe > bne * ;failed not equal (non zero) + > +1360 : 68 > pla ;load status +1361 : 48 > pha + > cmp_flag 0 +1362 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1364 : d0fe > bne * ;failed not equal (non zero) + > +1366 : 28 > plp ;restore status + > + > set_a $aa-$1b,$ff + > load_flag $ff +1367 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1369 : 48 > pha ;use stack to load status +136a : a98f > lda #$aa-$1b ;precharge accu +136c : 28 > plp + > +136d : 1b > db $1b ;test nop integrity - flags on +136e : ea > nop +136f : ea > nop + > tst_a $aa-$1b,$ff +1370 : 08 > php ;save flags +1371 : c98f > cmp #$aa-$1b ;test result + > trap_ne +1373 : d0fe > bne * ;failed not equal (non zero) + > +1375 : 68 > pla ;load status +1376 : 48 > pha + > cmp_flag $ff +1377 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1379 : d0fe > bne * ;failed not equal (non zero) + > +137b : 28 > plp ;restore status + > +137c : c042 > cpy #$42 + > trap_ne ;y changed +137e : d0fe > bne * ;failed not equal (non zero) + > +1380 : e000 > cpx #0 + > trap_ne ;x changed +1382 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $2b,1 +1384 : a042 > ldy #$42 +1386 : a203 > ldx #4-1 +1388 : 2b > db $2b ;test nop length + > if 1 = 1 +1389 : ca > dex +138a : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +138b : ca > dex + > trap_ne ;wrong number of bytes +138c : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$2b,0 + > load_flag 0 +138e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1390 : 48 > pha ;use stack to load status +1391 : a9d4 > lda #$ff-$2b ;precharge accu +1393 : 28 > plp + > +1394 : 2b > db $2b ;test nop integrity - flags off +1395 : ea > nop +1396 : ea > nop + > tst_a $ff-$2b,0 +1397 : 08 > php ;save flags +1398 : c9d4 > cmp #$ff-$2b ;test result + > trap_ne +139a : d0fe > bne * ;failed not equal (non zero) + > +139c : 68 > pla ;load status +139d : 48 > pha + > cmp_flag 0 +139e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +13a0 : d0fe > bne * ;failed not equal (non zero) + > +13a2 : 28 > plp ;restore status + > + > set_a $aa-$2b,$ff + > load_flag $ff +13a3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +13a5 : 48 > pha ;use stack to load status +13a6 : a97f > lda #$aa-$2b ;precharge accu +13a8 : 28 > plp + > +13a9 : 2b > db $2b ;test nop integrity - flags on +13aa : ea > nop +13ab : ea > nop + > tst_a $aa-$2b,$ff +13ac : 08 > php ;save flags +13ad : c97f > cmp #$aa-$2b ;test result + > trap_ne +13af : d0fe > bne * ;failed not equal (non zero) + > +13b1 : 68 > pla ;load status +13b2 : 48 > pha + > cmp_flag $ff +13b3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +13b5 : d0fe > bne * ;failed not equal (non zero) + > +13b7 : 28 > plp ;restore status + > +13b8 : c042 > cpy #$42 + > trap_ne ;y changed +13ba : d0fe > bne * ;failed not equal (non zero) + > +13bc : e000 > cpx #0 + > trap_ne ;x changed +13be : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $3b,1 +13c0 : a042 > ldy #$42 +13c2 : a203 > ldx #4-1 +13c4 : 3b > db $3b ;test nop length + > if 1 = 1 +13c5 : ca > dex +13c6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +13c7 : ca > dex + > trap_ne ;wrong number of bytes +13c8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$3b,0 + > load_flag 0 +13ca : a900 > lda #0 ;allow test to change I-flag (no mask) + > +13cc : 48 > pha ;use stack to load status +13cd : a9c4 > lda #$ff-$3b ;precharge accu +13cf : 28 > plp + > +13d0 : 3b > db $3b ;test nop integrity - flags off +13d1 : ea > nop +13d2 : ea > nop + > tst_a $ff-$3b,0 +13d3 : 08 > php ;save flags +13d4 : c9c4 > cmp #$ff-$3b ;test result + > trap_ne +13d6 : d0fe > bne * ;failed not equal (non zero) + > +13d8 : 68 > pla ;load status +13d9 : 48 > pha + > cmp_flag 0 +13da : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +13dc : d0fe > bne * ;failed not equal (non zero) + > +13de : 28 > plp ;restore status + > + > set_a $aa-$3b,$ff + > load_flag $ff +13df : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +13e1 : 48 > pha ;use stack to load status +13e2 : a96f > lda #$aa-$3b ;precharge accu +13e4 : 28 > plp + > +13e5 : 3b > db $3b ;test nop integrity - flags on +13e6 : ea > nop +13e7 : ea > nop + > tst_a $aa-$3b,$ff +13e8 : 08 > php ;save flags +13e9 : c96f > cmp #$aa-$3b ;test result + > trap_ne +13eb : d0fe > bne * ;failed not equal (non zero) + > +13ed : 68 > pla ;load status +13ee : 48 > pha + > cmp_flag $ff +13ef : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +13f1 : d0fe > bne * ;failed not equal (non zero) + > +13f3 : 28 > plp ;restore status + > +13f4 : c042 > cpy #$42 + > trap_ne ;y changed +13f6 : d0fe > bne * ;failed not equal (non zero) + > +13f8 : e000 > cpx #0 + > trap_ne ;x changed +13fa : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $4b,1 +13fc : a042 > ldy #$42 +13fe : a203 > ldx #4-1 +1400 : 4b > db $4b ;test nop length + > if 1 = 1 +1401 : ca > dex +1402 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +1403 : ca > dex + > trap_ne ;wrong number of bytes +1404 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$4b,0 + > load_flag 0 +1406 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1408 : 48 > pha ;use stack to load status +1409 : a9b4 > lda #$ff-$4b ;precharge accu +140b : 28 > plp + > +140c : 4b > db $4b ;test nop integrity - flags off +140d : ea > nop +140e : ea > nop + > tst_a $ff-$4b,0 +140f : 08 > php ;save flags +1410 : c9b4 > cmp #$ff-$4b ;test result + > trap_ne +1412 : d0fe > bne * ;failed not equal (non zero) + > +1414 : 68 > pla ;load status +1415 : 48 > pha + > cmp_flag 0 +1416 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1418 : d0fe > bne * ;failed not equal (non zero) + > +141a : 28 > plp ;restore status + > + > set_a $aa-$4b,$ff + > load_flag $ff +141b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +141d : 48 > pha ;use stack to load status +141e : a95f > lda #$aa-$4b ;precharge accu +1420 : 28 > plp + > +1421 : 4b > db $4b ;test nop integrity - flags on +1422 : ea > nop +1423 : ea > nop + > tst_a $aa-$4b,$ff +1424 : 08 > php ;save flags +1425 : c95f > cmp #$aa-$4b ;test result + > trap_ne +1427 : d0fe > bne * ;failed not equal (non zero) + > +1429 : 68 > pla ;load status +142a : 48 > pha + > cmp_flag $ff +142b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +142d : d0fe > bne * ;failed not equal (non zero) + > +142f : 28 > plp ;restore status + > +1430 : c042 > cpy #$42 + > trap_ne ;y changed +1432 : d0fe > bne * ;failed not equal (non zero) + > +1434 : e000 > cpx #0 + > trap_ne ;x changed +1436 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $5b,1 +1438 : a042 > ldy #$42 +143a : a203 > ldx #4-1 +143c : 5b > db $5b ;test nop length + > if 1 = 1 +143d : ca > dex +143e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +143f : ca > dex + > trap_ne ;wrong number of bytes +1440 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$5b,0 + > load_flag 0 +1442 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1444 : 48 > pha ;use stack to load status +1445 : a9a4 > lda #$ff-$5b ;precharge accu +1447 : 28 > plp + > +1448 : 5b > db $5b ;test nop integrity - flags off +1449 : ea > nop +144a : ea > nop + > tst_a $ff-$5b,0 +144b : 08 > php ;save flags +144c : c9a4 > cmp #$ff-$5b ;test result + > trap_ne +144e : d0fe > bne * ;failed not equal (non zero) + > +1450 : 68 > pla ;load status +1451 : 48 > pha + > cmp_flag 0 +1452 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1454 : d0fe > bne * ;failed not equal (non zero) + > +1456 : 28 > plp ;restore status + > + > set_a $aa-$5b,$ff + > load_flag $ff +1457 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1459 : 48 > pha ;use stack to load status +145a : a94f > lda #$aa-$5b ;precharge accu +145c : 28 > plp + > +145d : 5b > db $5b ;test nop integrity - flags on +145e : ea > nop +145f : ea > nop + > tst_a $aa-$5b,$ff +1460 : 08 > php ;save flags +1461 : c94f > cmp #$aa-$5b ;test result + > trap_ne +1463 : d0fe > bne * ;failed not equal (non zero) + > +1465 : 68 > pla ;load status +1466 : 48 > pha + > cmp_flag $ff +1467 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1469 : d0fe > bne * ;failed not equal (non zero) + > +146b : 28 > plp ;restore status + > +146c : c042 > cpy #$42 + > trap_ne ;y changed +146e : d0fe > bne * ;failed not equal (non zero) + > +1470 : e000 > cpx #0 + > trap_ne ;x changed +1472 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $6b,1 +1474 : a042 > ldy #$42 +1476 : a203 > ldx #4-1 +1478 : 6b > db $6b ;test nop length + > if 1 = 1 +1479 : ca > dex +147a : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +147b : ca > dex + > trap_ne ;wrong number of bytes +147c : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$6b,0 + > load_flag 0 +147e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1480 : 48 > pha ;use stack to load status +1481 : a994 > lda #$ff-$6b ;precharge accu +1483 : 28 > plp + > +1484 : 6b > db $6b ;test nop integrity - flags off +1485 : ea > nop +1486 : ea > nop + > tst_a $ff-$6b,0 +1487 : 08 > php ;save flags +1488 : c994 > cmp #$ff-$6b ;test result + > trap_ne +148a : d0fe > bne * ;failed not equal (non zero) + > +148c : 68 > pla ;load status +148d : 48 > pha + > cmp_flag 0 +148e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1490 : d0fe > bne * ;failed not equal (non zero) + > +1492 : 28 > plp ;restore status + > + > set_a $aa-$6b,$ff + > load_flag $ff +1493 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1495 : 48 > pha ;use stack to load status +1496 : a93f > lda #$aa-$6b ;precharge accu +1498 : 28 > plp + > +1499 : 6b > db $6b ;test nop integrity - flags on +149a : ea > nop +149b : ea > nop + > tst_a $aa-$6b,$ff +149c : 08 > php ;save flags +149d : c93f > cmp #$aa-$6b ;test result + > trap_ne +149f : d0fe > bne * ;failed not equal (non zero) + > +14a1 : 68 > pla ;load status +14a2 : 48 > pha + > cmp_flag $ff +14a3 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +14a5 : d0fe > bne * ;failed not equal (non zero) + > +14a7 : 28 > plp ;restore status + > +14a8 : c042 > cpy #$42 + > trap_ne ;y changed +14aa : d0fe > bne * ;failed not equal (non zero) + > +14ac : e000 > cpx #0 + > trap_ne ;x changed +14ae : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $7b,1 +14b0 : a042 > ldy #$42 +14b2 : a203 > ldx #4-1 +14b4 : 7b > db $7b ;test nop length + > if 1 = 1 +14b5 : ca > dex +14b6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +14b7 : ca > dex + > trap_ne ;wrong number of bytes +14b8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$7b,0 + > load_flag 0 +14ba : a900 > lda #0 ;allow test to change I-flag (no mask) + > +14bc : 48 > pha ;use stack to load status +14bd : a984 > lda #$ff-$7b ;precharge accu +14bf : 28 > plp + > +14c0 : 7b > db $7b ;test nop integrity - flags off +14c1 : ea > nop +14c2 : ea > nop + > tst_a $ff-$7b,0 +14c3 : 08 > php ;save flags +14c4 : c984 > cmp #$ff-$7b ;test result + > trap_ne +14c6 : d0fe > bne * ;failed not equal (non zero) + > +14c8 : 68 > pla ;load status +14c9 : 48 > pha + > cmp_flag 0 +14ca : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +14cc : d0fe > bne * ;failed not equal (non zero) + > +14ce : 28 > plp ;restore status + > + > set_a $aa-$7b,$ff + > load_flag $ff +14cf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +14d1 : 48 > pha ;use stack to load status +14d2 : a92f > lda #$aa-$7b ;precharge accu +14d4 : 28 > plp + > +14d5 : 7b > db $7b ;test nop integrity - flags on +14d6 : ea > nop +14d7 : ea > nop + > tst_a $aa-$7b,$ff +14d8 : 08 > php ;save flags +14d9 : c92f > cmp #$aa-$7b ;test result + > trap_ne +14db : d0fe > bne * ;failed not equal (non zero) + > +14dd : 68 > pla ;load status +14de : 48 > pha + > cmp_flag $ff +14df : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +14e1 : d0fe > bne * ;failed not equal (non zero) + > +14e3 : 28 > plp ;restore status + > +14e4 : c042 > cpy #$42 + > trap_ne ;y changed +14e6 : d0fe > bne * ;failed not equal (non zero) + > +14e8 : e000 > cpx #0 + > trap_ne ;x changed +14ea : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $8b,1 +14ec : a042 > ldy #$42 +14ee : a203 > ldx #4-1 +14f0 : 8b > db $8b ;test nop length + > if 1 = 1 +14f1 : ca > dex +14f2 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +14f3 : ca > dex + > trap_ne ;wrong number of bytes +14f4 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$8b,0 + > load_flag 0 +14f6 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +14f8 : 48 > pha ;use stack to load status +14f9 : a974 > lda #$ff-$8b ;precharge accu +14fb : 28 > plp + > +14fc : 8b > db $8b ;test nop integrity - flags off +14fd : ea > nop +14fe : ea > nop + > tst_a $ff-$8b,0 +14ff : 08 > php ;save flags +1500 : c974 > cmp #$ff-$8b ;test result + > trap_ne +1502 : d0fe > bne * ;failed not equal (non zero) + > +1504 : 68 > pla ;load status +1505 : 48 > pha + > cmp_flag 0 +1506 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1508 : d0fe > bne * ;failed not equal (non zero) + > +150a : 28 > plp ;restore status + > + > set_a $aa-$8b,$ff + > load_flag $ff +150b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +150d : 48 > pha ;use stack to load status +150e : a91f > lda #$aa-$8b ;precharge accu +1510 : 28 > plp + > +1511 : 8b > db $8b ;test nop integrity - flags on +1512 : ea > nop +1513 : ea > nop + > tst_a $aa-$8b,$ff +1514 : 08 > php ;save flags +1515 : c91f > cmp #$aa-$8b ;test result + > trap_ne +1517 : d0fe > bne * ;failed not equal (non zero) + > +1519 : 68 > pla ;load status +151a : 48 > pha + > cmp_flag $ff +151b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +151d : d0fe > bne * ;failed not equal (non zero) + > +151f : 28 > plp ;restore status + > +1520 : c042 > cpy #$42 + > trap_ne ;y changed +1522 : d0fe > bne * ;failed not equal (non zero) + > +1524 : e000 > cpx #0 + > trap_ne ;x changed +1526 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $9b,1 +1528 : a042 > ldy #$42 +152a : a203 > ldx #4-1 +152c : 9b > db $9b ;test nop length + > if 1 = 1 +152d : ca > dex +152e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +152f : ca > dex + > trap_ne ;wrong number of bytes +1530 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$9b,0 + > load_flag 0 +1532 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1534 : 48 > pha ;use stack to load status +1535 : a964 > lda #$ff-$9b ;precharge accu +1537 : 28 > plp + > +1538 : 9b > db $9b ;test nop integrity - flags off +1539 : ea > nop +153a : ea > nop + > tst_a $ff-$9b,0 +153b : 08 > php ;save flags +153c : c964 > cmp #$ff-$9b ;test result + > trap_ne +153e : d0fe > bne * ;failed not equal (non zero) + > +1540 : 68 > pla ;load status +1541 : 48 > pha + > cmp_flag 0 +1542 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1544 : d0fe > bne * ;failed not equal (non zero) + > +1546 : 28 > plp ;restore status + > + > set_a $aa-$9b,$ff + > load_flag $ff +1547 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1549 : 48 > pha ;use stack to load status +154a : a90f > lda #$aa-$9b ;precharge accu +154c : 28 > plp + > +154d : 9b > db $9b ;test nop integrity - flags on +154e : ea > nop +154f : ea > nop + > tst_a $aa-$9b,$ff +1550 : 08 > php ;save flags +1551 : c90f > cmp #$aa-$9b ;test result + > trap_ne +1553 : d0fe > bne * ;failed not equal (non zero) + > +1555 : 68 > pla ;load status +1556 : 48 > pha + > cmp_flag $ff +1557 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1559 : d0fe > bne * ;failed not equal (non zero) + > +155b : 28 > plp ;restore status + > +155c : c042 > cpy #$42 + > trap_ne ;y changed +155e : d0fe > bne * ;failed not equal (non zero) + > +1560 : e000 > cpx #0 + > trap_ne ;x changed +1562 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $ab,1 +1564 : a042 > ldy #$42 +1566 : a203 > ldx #4-1 +1568 : ab > db $ab ;test nop length + > if 1 = 1 +1569 : ca > dex +156a : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +156b : ca > dex + > trap_ne ;wrong number of bytes +156c : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$ab,0 + > load_flag 0 +156e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1570 : 48 > pha ;use stack to load status +1571 : a954 > lda #$ff-$ab ;precharge accu +1573 : 28 > plp + > +1574 : ab > db $ab ;test nop integrity - flags off +1575 : ea > nop +1576 : ea > nop + > tst_a $ff-$ab,0 +1577 : 08 > php ;save flags +1578 : c954 > cmp #$ff-$ab ;test result + > trap_ne +157a : d0fe > bne * ;failed not equal (non zero) + > +157c : 68 > pla ;load status +157d : 48 > pha + > cmp_flag 0 +157e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1580 : d0fe > bne * ;failed not equal (non zero) + > +1582 : 28 > plp ;restore status + > + > set_a $aa-$ab,$ff + > load_flag $ff +1583 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1585 : 48 > pha ;use stack to load status +1586 : a9ff > lda #$aa-$ab ;precharge accu +1588 : 28 > plp + > +1589 : ab > db $ab ;test nop integrity - flags on +158a : ea > nop +158b : ea > nop + > tst_a $aa-$ab,$ff +158c : 08 > php ;save flags +158d : c9ff > cmp #$aa-$ab ;test result + > trap_ne +158f : d0fe > bne * ;failed not equal (non zero) + > +1591 : 68 > pla ;load status +1592 : 48 > pha + > cmp_flag $ff +1593 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1595 : d0fe > bne * ;failed not equal (non zero) + > +1597 : 28 > plp ;restore status + > +1598 : c042 > cpy #$42 + > trap_ne ;y changed +159a : d0fe > bne * ;failed not equal (non zero) + > +159c : e000 > cpx #0 + > trap_ne ;x changed +159e : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $bb,1 +15a0 : a042 > ldy #$42 +15a2 : a203 > ldx #4-1 +15a4 : bb > db $bb ;test nop length + > if 1 = 1 +15a5 : ca > dex +15a6 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +15a7 : ca > dex + > trap_ne ;wrong number of bytes +15a8 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$bb,0 + > load_flag 0 +15aa : a900 > lda #0 ;allow test to change I-flag (no mask) + > +15ac : 48 > pha ;use stack to load status +15ad : a944 > lda #$ff-$bb ;precharge accu +15af : 28 > plp + > +15b0 : bb > db $bb ;test nop integrity - flags off +15b1 : ea > nop +15b2 : ea > nop + > tst_a $ff-$bb,0 +15b3 : 08 > php ;save flags +15b4 : c944 > cmp #$ff-$bb ;test result + > trap_ne +15b6 : d0fe > bne * ;failed not equal (non zero) + > +15b8 : 68 > pla ;load status +15b9 : 48 > pha + > cmp_flag 0 +15ba : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +15bc : d0fe > bne * ;failed not equal (non zero) + > +15be : 28 > plp ;restore status + > + > set_a $aa-$bb,$ff + > load_flag $ff +15bf : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +15c1 : 48 > pha ;use stack to load status +15c2 : a9ef > lda #$aa-$bb ;precharge accu +15c4 : 28 > plp + > +15c5 : bb > db $bb ;test nop integrity - flags on +15c6 : ea > nop +15c7 : ea > nop + > tst_a $aa-$bb,$ff +15c8 : 08 > php ;save flags +15c9 : c9ef > cmp #$aa-$bb ;test result + > trap_ne +15cb : d0fe > bne * ;failed not equal (non zero) + > +15cd : 68 > pla ;load status +15ce : 48 > pha + > cmp_flag $ff +15cf : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +15d1 : d0fe > bne * ;failed not equal (non zero) + > +15d3 : 28 > plp ;restore status + > +15d4 : c042 > cpy #$42 + > trap_ne ;y changed +15d6 : d0fe > bne * ;failed not equal (non zero) + > +15d8 : e000 > cpx #0 + > trap_ne ;x changed +15da : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $eb,1 +15dc : a042 > ldy #$42 +15de : a203 > ldx #4-1 +15e0 : eb > db $eb ;test nop length + > if 1 = 1 +15e1 : ca > dex +15e2 : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +15e3 : ca > dex + > trap_ne ;wrong number of bytes +15e4 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$eb,0 + > load_flag 0 +15e6 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +15e8 : 48 > pha ;use stack to load status +15e9 : a914 > lda #$ff-$eb ;precharge accu +15eb : 28 > plp + > +15ec : eb > db $eb ;test nop integrity - flags off +15ed : ea > nop +15ee : ea > nop + > tst_a $ff-$eb,0 +15ef : 08 > php ;save flags +15f0 : c914 > cmp #$ff-$eb ;test result + > trap_ne +15f2 : d0fe > bne * ;failed not equal (non zero) + > +15f4 : 68 > pla ;load status +15f5 : 48 > pha + > cmp_flag 0 +15f6 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +15f8 : d0fe > bne * ;failed not equal (non zero) + > +15fa : 28 > plp ;restore status + > + > set_a $aa-$eb,$ff + > load_flag $ff +15fb : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +15fd : 48 > pha ;use stack to load status +15fe : a9bf > lda #$aa-$eb ;precharge accu +1600 : 28 > plp + > +1601 : eb > db $eb ;test nop integrity - flags on +1602 : ea > nop +1603 : ea > nop + > tst_a $aa-$eb,$ff +1604 : 08 > php ;save flags +1605 : c9bf > cmp #$aa-$eb ;test result + > trap_ne +1607 : d0fe > bne * ;failed not equal (non zero) + > +1609 : 68 > pla ;load status +160a : 48 > pha + > cmp_flag $ff +160b : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +160d : d0fe > bne * ;failed not equal (non zero) + > +160f : 28 > plp ;restore status + > +1610 : c042 > cpy #$42 + > trap_ne ;y changed +1612 : d0fe > bne * ;failed not equal (non zero) + > +1614 : e000 > cpx #0 + > trap_ne ;x changed +1616 : d0fe > bne * ;failed not equal (non zero) + > + + nop_test $fb,1 +1618 : a042 > ldy #$42 +161a : a203 > ldx #4-1 +161c : fb > db $fb ;test nop length + > if 1 = 1 +161d : ca > dex +161e : ca > dex + > endif + > if 1 = 2 + > iny + > dex + > endif + > if 1 = 3 + > iny + > iny + > endif +161f : ca > dex + > trap_ne ;wrong number of bytes +1620 : d0fe > bne * ;failed not equal (non zero) + > + > set_a $ff-$fb,0 + > load_flag 0 +1622 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1624 : 48 > pha ;use stack to load status +1625 : a904 > lda #$ff-$fb ;precharge accu +1627 : 28 > plp + > +1628 : fb > db $fb ;test nop integrity - flags off +1629 : ea > nop +162a : ea > nop + > tst_a $ff-$fb,0 +162b : 08 > php ;save flags +162c : c904 > cmp #$ff-$fb ;test result + > trap_ne +162e : d0fe > bne * ;failed not equal (non zero) + > +1630 : 68 > pla ;load status +1631 : 48 > pha + > cmp_flag 0 +1632 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1634 : d0fe > bne * ;failed not equal (non zero) + > +1636 : 28 > plp ;restore status + > + > set_a $aa-$fb,$ff + > load_flag $ff +1637 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1639 : 48 > pha ;use stack to load status +163a : a9af > lda #$aa-$fb ;precharge accu +163c : 28 > plp + > +163d : fb > db $fb ;test nop integrity - flags on +163e : ea > nop +163f : ea > nop + > tst_a $aa-$fb,$ff +1640 : 08 > php ;save flags +1641 : c9af > cmp #$aa-$fb ;test result + > trap_ne +1643 : d0fe > bne * ;failed not equal (non zero) + > +1645 : 68 > pla ;load status +1646 : 48 > pha + > cmp_flag $ff +1647 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1649 : d0fe > bne * ;failed not equal (non zero) + > +164b : 28 > plp ;restore status + > +164c : c042 > cpy #$42 + > trap_ne ;y changed +164e : d0fe > bne * ;failed not equal (non zero) + > +1650 : e000 > cpx #0 + > trap_ne ;x changed +1652 : d0fe > bne * ;failed not equal (non zero) + > + + if rkwl_wdc_op = 0 ;NOPs not available on Rockwell & WDC 65C02 + nop_test $07,1 + nop_test $17,1 + nop_test $27,1 + nop_test $37,1 + nop_test $47,1 + nop_test $57,1 + nop_test $67,1 + nop_test $77,1 + nop_test $87,1 + nop_test $97,1 + nop_test $a7,1 + nop_test $b7,1 + nop_test $c7,1 + nop_test $d7,1 + nop_test $e7,1 + nop_test $f7,1 + nop_test $0f,1 + nop_test $1f,1 + nop_test $2f,1 + nop_test $3f,1 + nop_test $4f,1 + nop_test $5f,1 + nop_test $6f,1 + nop_test $7f,1 + nop_test $8f,1 + nop_test $9f,1 + nop_test $af,1 + nop_test $bf,1 + nop_test $cf,1 + nop_test $df,1 + nop_test $ef,1 + nop_test $ff,1 + endif + if wdc_op = 0 ;NOPs not available on WDC 65C02 (WAI, STP) + nop_test $cb,1 + nop_test $db,1 + endif + next_test +1654 : ad0202 > lda test_case ;previous test +1657 : c908 > cmp #test_num + > trap_ne ;test is out of sequence +1659 : d0fe > bne * ;failed not equal (non zero) + > +0009 = >test_num = test_num + 1 +165b : a909 > lda #test_num ;*** next tests' number +165d : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + endif + + ; jump indirect (test page cross bug is fixed) +1660 : a203 ldx #3 ;prepare table +1662 : bd8b26 ji1 lda ji_adr,x +1665 : 9dfd02 sta ji_tab,x +1668 : ca dex +1669 : 10f7 bpl ji1 +166b : a928 lda #hi(ji_px) ;high address if page cross bug +166d : 8d0002 sta pg_x + set_stat 0 + > load_flag 0 +1670 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1672 : 48 > pha ;use stack to load status +1673 : 28 > plp + +1674 : a949 lda #'I' +1676 : a24e ldx #'N' +1678 : a044 ldy #'D' ;N=0, V=0, Z=0, C=0 +167a : 6cfd02 jmp (ji_tab) +167d : ea nop + trap_ne ;runover protection +167e : d0fe > bne * ;failed not equal (non zero) + + +1680 : 88 dey +1681 : 88 dey +1682 : 08 ji_ret php ;either SP or Y count will fail, if we do not hit +1683 : 88 dey +1684 : 88 dey +1685 : 88 dey +1686 : 28 plp + trap_eq ;returned flags OK? +1687 : f0fe > beq * ;failed equal (zero) + + trap_pl +1689 : 10fe > bpl * ;failed plus (bit 7 clear) + + trap_cc +168b : 90fe > bcc * ;failed carry clear + + trap_vc +168d : 50fe > bvc * ;failed overflow clear + +168f : c9e3 cmp #('I'^$aa) ;returned registers OK? + trap_ne +1691 : d0fe > bne * ;failed not equal (non zero) + +1693 : e04f cpx #('N'+1) + trap_ne +1695 : d0fe > bne * ;failed not equal (non zero) + +1697 : c03e cpy #('D'-6) + trap_ne +1699 : d0fe > bne * ;failed not equal (non zero) + +169b : ba tsx ;SP check +169c : e0ff cpx #$ff + trap_ne +169e : d0fe > bne * ;failed not equal (non zero) + + next_test +16a0 : ad0202 > lda test_case ;previous test +16a3 : c909 > cmp #test_num + > trap_ne ;test is out of sequence +16a5 : d0fe > bne * ;failed not equal (non zero) + > +000a = >test_num = test_num + 1 +16a7 : a90a > lda #test_num ;*** next tests' number +16a9 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; jump indexed indirect +16ac : a20b ldx #11 ;prepare table +16ae : bdc726 jxi1 lda jxi_adr,x +16b1 : 9df902 sta jxi_tab,x +16b4 : ca dex +16b5 : 10f7 bpl jxi1 +16b7 : a927 lda #hi(jxi_px) ;high address if page cross bug +16b9 : 8d0002 sta pg_x + set_stat 0 + > load_flag 0 +16bc : a900 > lda #0 ;allow test to change I-flag (no mask) + > +16be : 48 > pha ;use stack to load status +16bf : 28 > plp + +16c0 : a958 lda #'X' +16c2 : a204 ldx #4 +16c4 : a049 ldy #'I' ;N=0, V=0, Z=0, C=0 +16c6 : 7cf902 jmp (jxi_tab,x) +16c9 : ea nop + trap_ne ;runover protection +16ca : d0fe > bne * ;failed not equal (non zero) + + +16cc : 88 dey +16cd : 88 dey +16ce : 08 jxi_ret php ;either SP or Y count will fail, if we do not hit +16cf : 88 dey +16d0 : 88 dey +16d1 : 88 dey +16d2 : 28 plp + trap_eq ;returned flags OK? +16d3 : f0fe > beq * ;failed equal (zero) + + trap_pl +16d5 : 10fe > bpl * ;failed plus (bit 7 clear) + + trap_cc +16d7 : 90fe > bcc * ;failed carry clear + + trap_vc +16d9 : 50fe > bvc * ;failed overflow clear + +16db : c9f2 cmp #('X'^$aa) ;returned registers OK? + trap_ne +16dd : d0fe > bne * ;failed not equal (non zero) + +16df : e006 cpx #6 + trap_ne +16e1 : d0fe > bne * ;failed not equal (non zero) + +16e3 : c043 cpy #('I'-6) + trap_ne +16e5 : d0fe > bne * ;failed not equal (non zero) + +16e7 : ba tsx ;SP check +16e8 : e0ff cpx #$ff + trap_ne +16ea : d0fe > bne * ;failed not equal (non zero) + + +16ec : a908 lda #lo(jxp_ok) ;test with index causing a page cross +16ee : 8d0003 sta jxp_tab +16f1 : a917 lda #hi(jxp_ok) +16f3 : 8d0103 sta jxp_tab+1 +16f6 : a905 lda #lo(jxp_px) +16f8 : 8d0002 sta pg_x +16fb : a917 lda #hi(jxp_px) +16fd : 8d0102 sta pg_x+1 +1700 : a2ff ldx #$ff +1702 : 7c0102 jmp (jxp_tab-$ff,x) + +1705 : jxp_px + trap ;page cross by index to wrong page +1705 : 4c0517 > jmp * ;failed anyway + + +1708 : jxp_ok + next_test +1708 : ad0202 > lda test_case ;previous test +170b : c90a > cmp #test_num + > trap_ne ;test is out of sequence +170d : d0fe > bne * ;failed not equal (non zero) + > +000b = >test_num = test_num + 1 +170f : a90b > lda #test_num ;*** next tests' number +1711 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + if ROM_vectors = 1 + ; test BRK clears decimal mode + load_flag 0 ;with interrupts enabled if allowed! +1714 : a900 > lda #0 ;allow test to change I-flag (no mask) + +1716 : 48 pha +1717 : a942 lda #'B' +1719 : a252 ldx #'R' +171b : a04b ldy #'K' +171d : 28 plp ;N=0, V=0, Z=0, C=0 +171e : 00 brk +171f : 88 dey ;should not be executed +1720 : brk_ret0 ;address of break return +1720 : 08 php ;either SP or Y count will fail, if we do not hit +1721 : 88 dey +1722 : 88 dey +1723 : 88 dey +1724 : c9e8 cmp #'B'^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne +1726 : d0fe > bne * ;failed not equal (non zero) + +1728 : e053 cpx #'R'+1 + trap_ne +172a : d0fe > bne * ;failed not equal (non zero) + +172c : c045 cpy #'K'-6 + trap_ne +172e : d0fe > bne * ;failed not equal (non zero) + +1730 : 68 pla ;returned flags OK (unchanged)? + cmp_flag 0 +1731 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + + trap_ne +1733 : d0fe > bne * ;failed not equal (non zero) + +1735 : ba tsx ;sp? +1736 : e0ff cpx #$ff + trap_ne +1738 : d0fe > bne * ;failed not equal (non zero) + + ;pass 2 + load_flag $ff ;with interrupts disabled if allowed! +173a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +173c : 48 pha +173d : a9bd lda #$ff-'B' +173f : a2ad ldx #$ff-'R' +1741 : a0b4 ldy #$ff-'K' +1743 : 28 plp ;N=1, V=1, Z=1, C=1 +1744 : 00 brk +1745 : 88 dey ;should not be executed +1746 : brk_ret1 ;address of break return +1746 : 08 php ;either SP or Y count will fail, if we do not hit +1747 : 88 dey +1748 : 88 dey +1749 : 88 dey +174a : c917 cmp #($ff-'B')^$aa ;returned registers OK? + ;the IRQ vector was never executed if A & X stay unmodified + trap_ne +174c : d0fe > bne * ;failed not equal (non zero) + +174e : e0ae cpx #$ff-'R'+1 + trap_ne +1750 : d0fe > bne * ;failed not equal (non zero) + +1752 : c0ae cpy #$ff-'K'-6 + trap_ne +1754 : d0fe > bne * ;failed not equal (non zero) + +1756 : 68 pla ;returned flags OK (unchanged)? + cmp_flag $ff +1757 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + + trap_ne +1759 : d0fe > bne * ;failed not equal (non zero) + +175b : ba tsx ;sp? +175c : e0ff cpx #$ff + trap_ne +175e : d0fe > bne * ;failed not equal (non zero) + + next_test +1760 : ad0202 > lda test_case ;previous test +1763 : c90b > cmp #test_num + > trap_ne ;test is out of sequence +1765 : d0fe > bne * ;failed not equal (non zero) + > +000c = >test_num = test_num + 1 +1767 : a90c > lda #test_num ;*** next tests' number +1769 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + endif + + ; testing accumulator increment/decrement INC A & DEC A +176c : a2ac ldx #$ac ;protect x & y +176e : a0dc ldy #$dc + set_a $fe,$ff + > load_flag $ff +1770 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1772 : 48 > pha ;use stack to load status +1773 : a9fe > lda #$fe ;precharge accu +1775 : 28 > plp + +1776 : 1a inc a ;ff + tst_as $ff,$ff-zero +1777 : 48 > pha +1778 : 08 > php ;save flags +1779 : c9ff > cmp #$ff ;test result + > trap_ne +177b : d0fe > bne * ;failed not equal (non zero) + > +177d : 68 > pla ;load status +177e : 48 > pha + > cmp_flag $ff-zero +177f : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1781 : d0fe > bne * ;failed not equal (non zero) + > +1783 : 28 > plp ;restore status +1784 : 68 > pla + +1785 : 1a inc a ;00 + tst_as 0,$ff-minus +1786 : 48 > pha +1787 : 08 > php ;save flags +1788 : c900 > cmp #0 ;test result + > trap_ne +178a : d0fe > bne * ;failed not equal (non zero) + > +178c : 68 > pla ;load status +178d : 48 > pha + > cmp_flag $ff-minus +178e : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1790 : d0fe > bne * ;failed not equal (non zero) + > +1792 : 28 > plp ;restore status +1793 : 68 > pla + +1794 : 1a inc a ;01 + tst_as 1,$ff-minus-zero +1795 : 48 > pha +1796 : 08 > php ;save flags +1797 : c901 > cmp #1 ;test result + > trap_ne +1799 : d0fe > bne * ;failed not equal (non zero) + > +179b : 68 > pla ;load status +179c : 48 > pha + > cmp_flag $ff-minus-zero +179d : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +179f : d0fe > bne * ;failed not equal (non zero) + > +17a1 : 28 > plp ;restore status +17a2 : 68 > pla + +17a3 : 3a dec a ;00 + tst_as 0,$ff-minus +17a4 : 48 > pha +17a5 : 08 > php ;save flags +17a6 : c900 > cmp #0 ;test result + > trap_ne +17a8 : d0fe > bne * ;failed not equal (non zero) + > +17aa : 68 > pla ;load status +17ab : 48 > pha + > cmp_flag $ff-minus +17ac : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +17ae : d0fe > bne * ;failed not equal (non zero) + > +17b0 : 28 > plp ;restore status +17b1 : 68 > pla + +17b2 : 3a dec a ;ff + tst_as $ff,$ff-zero +17b3 : 48 > pha +17b4 : 08 > php ;save flags +17b5 : c9ff > cmp #$ff ;test result + > trap_ne +17b7 : d0fe > bne * ;failed not equal (non zero) + > +17b9 : 68 > pla ;load status +17ba : 48 > pha + > cmp_flag $ff-zero +17bb : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +17bd : d0fe > bne * ;failed not equal (non zero) + > +17bf : 28 > plp ;restore status +17c0 : 68 > pla + +17c1 : 3a dec a ;fe + set_a $fe,0 + > load_flag 0 +17c2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +17c4 : 48 > pha ;use stack to load status +17c5 : a9fe > lda #$fe ;precharge accu +17c7 : 28 > plp + +17c8 : 1a inc a ;ff + tst_as $ff,minus +17c9 : 48 > pha +17ca : 08 > php ;save flags +17cb : c9ff > cmp #$ff ;test result + > trap_ne +17cd : d0fe > bne * ;failed not equal (non zero) + > +17cf : 68 > pla ;load status +17d0 : 48 > pha + > cmp_flag minus +17d1 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +17d3 : d0fe > bne * ;failed not equal (non zero) + > +17d5 : 28 > plp ;restore status +17d6 : 68 > pla + +17d7 : 1a inc a ;00 + tst_as 0,zero +17d8 : 48 > pha +17d9 : 08 > php ;save flags +17da : c900 > cmp #0 ;test result + > trap_ne +17dc : d0fe > bne * ;failed not equal (non zero) + > +17de : 68 > pla ;load status +17df : 48 > pha + > cmp_flag zero +17e0 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +17e2 : d0fe > bne * ;failed not equal (non zero) + > +17e4 : 28 > plp ;restore status +17e5 : 68 > pla + +17e6 : 1a inc a ;01 + tst_as 1,0 +17e7 : 48 > pha +17e8 : 08 > php ;save flags +17e9 : c901 > cmp #1 ;test result + > trap_ne +17eb : d0fe > bne * ;failed not equal (non zero) + > +17ed : 68 > pla ;load status +17ee : 48 > pha + > cmp_flag 0 +17ef : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +17f1 : d0fe > bne * ;failed not equal (non zero) + > +17f3 : 28 > plp ;restore status +17f4 : 68 > pla + +17f5 : 3a dec a ;00 + tst_as 0,zero +17f6 : 48 > pha +17f7 : 08 > php ;save flags +17f8 : c900 > cmp #0 ;test result + > trap_ne +17fa : d0fe > bne * ;failed not equal (non zero) + > +17fc : 68 > pla ;load status +17fd : 48 > pha + > cmp_flag zero +17fe : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1800 : d0fe > bne * ;failed not equal (non zero) + > +1802 : 28 > plp ;restore status +1803 : 68 > pla + +1804 : 3a dec a ;ff + tst_as $ff,minus +1805 : 48 > pha +1806 : 08 > php ;save flags +1807 : c9ff > cmp #$ff ;test result + > trap_ne +1809 : d0fe > bne * ;failed not equal (non zero) + > +180b : 68 > pla ;load status +180c : 48 > pha + > cmp_flag minus +180d : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits + > + > trap_ne +180f : d0fe > bne * ;failed not equal (non zero) + > +1811 : 28 > plp ;restore status +1812 : 68 > pla + +1813 : e0ac cpx #$ac + trap_ne ;x altered during test +1815 : d0fe > bne * ;failed not equal (non zero) + +1817 : c0dc cpy #$dc + trap_ne ;y altered during test +1819 : d0fe > bne * ;failed not equal (non zero) + +181b : ba tsx +181c : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +181e : d0fe > bne * ;failed not equal (non zero) + + next_test +1820 : ad0202 > lda test_case ;previous test +1823 : c90c > cmp #test_num + > trap_ne ;test is out of sequence +1825 : d0fe > bne * ;failed not equal (non zero) + > +000d = >test_num = test_num + 1 +1827 : a90d > lda #test_num ;*** next tests' number +1829 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing load / store accumulator LDA / STA (zp) +182c : a299 ldx #$99 ;protect x & y +182e : a066 ldy #$66 + set_stat 0 + > load_flag 0 +1830 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1832 : 48 > pha ;use stack to load status +1833 : 28 > plp + +1834 : b224 lda (ind1) +1836 : 08 php ;test stores do not alter flags +1837 : 49c3 eor #$c3 +1839 : 28 plp +183a : 9230 sta (indt) +183c : 08 php ;flags after load/store sequence +183d : 49c3 eor #$c3 +183f : c9c3 cmp #$c3 ;test result + trap_ne +1841 : d0fe > bne * ;failed not equal (non zero) + +1843 : 68 pla ;load status + eor_flag 0 +1844 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1846 : cd1502 cmp fLDx ;test flags + trap_ne +1849 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +184b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +184d : 48 > pha ;use stack to load status +184e : 28 > plp + +184f : b226 lda (ind1+2) +1851 : 08 php ;test stores do not alter flags +1852 : 49c3 eor #$c3 +1854 : 28 plp +1855 : 9232 sta (indt+2) +1857 : 08 php ;flags after load/store sequence +1858 : 49c3 eor #$c3 +185a : c982 cmp #$82 ;test result + trap_ne +185c : d0fe > bne * ;failed not equal (non zero) + +185e : 68 pla ;load status + eor_flag 0 +185f : 4930 > eor #0|fao ;invert expected flags + always on bits + +1861 : cd1602 cmp fLDx+1 ;test flags + trap_ne +1864 : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1866 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1868 : 48 > pha ;use stack to load status +1869 : 28 > plp + +186a : b228 lda (ind1+4) +186c : 08 php ;test stores do not alter flags +186d : 49c3 eor #$c3 +186f : 28 plp +1870 : 9234 sta (indt+4) +1872 : 08 php ;flags after load/store sequence +1873 : 49c3 eor #$c3 +1875 : c941 cmp #$41 ;test result + trap_ne +1877 : d0fe > bne * ;failed not equal (non zero) + +1879 : 68 pla ;load status + eor_flag 0 +187a : 4930 > eor #0|fao ;invert expected flags + always on bits + +187c : cd1702 cmp fLDx+2 ;test flags + trap_ne +187f : d0fe > bne * ;failed not equal (non zero) + + set_stat 0 + > load_flag 0 +1881 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1883 : 48 > pha ;use stack to load status +1884 : 28 > plp + +1885 : b22a lda (ind1+6) +1887 : 08 php ;test stores do not alter flags +1888 : 49c3 eor #$c3 +188a : 28 plp +188b : 9236 sta (indt+6) +188d : 08 php ;flags after load/store sequence +188e : 49c3 eor #$c3 +1890 : c900 cmp #0 ;test result + trap_ne +1892 : d0fe > bne * ;failed not equal (non zero) + +1894 : 68 pla ;load status + eor_flag 0 +1895 : 4930 > eor #0|fao ;invert expected flags + always on bits + +1897 : cd1802 cmp fLDx+3 ;test flags + trap_ne +189a : d0fe > bne * ;failed not equal (non zero) + +189c : e099 cpx #$99 + trap_ne ;x altered during test +189e : d0fe > bne * ;failed not equal (non zero) + +18a0 : c066 cpy #$66 + trap_ne ;y altered during test +18a2 : d0fe > bne * ;failed not equal (non zero) + + +18a4 : a003 ldy #3 ;testing store result +18a6 : a200 ldx #0 +18a8 : b90502 tstai1 lda abst,y +18ab : 49c3 eor #$c3 +18ad : d91002 cmp abs1,y + trap_ne ;store to indirect data +18b0 : d0fe > bne * ;failed not equal (non zero) + +18b2 : 8a txa +18b3 : 990502 sta abst,y ;clear +18b6 : 88 dey +18b7 : 10ef bpl tstai1 + +18b9 : a299 ldx #$99 ;protect x & y +18bb : a066 ldy #$66 + set_stat $ff + > load_flag $ff +18bd : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +18bf : 48 > pha ;use stack to load status +18c0 : 28 > plp + +18c1 : b224 lda (ind1) +18c3 : 08 php ;test stores do not alter flags +18c4 : 49c3 eor #$c3 +18c6 : 28 plp +18c7 : 9230 sta (indt) +18c9 : 08 php ;flags after load/store sequence +18ca : 49c3 eor #$c3 +18cc : c9c3 cmp #$c3 ;test result + trap_ne +18ce : d0fe > bne * ;failed not equal (non zero) + +18d0 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +18d1 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +18d3 : cd1502 cmp fLDx ;test flags + trap_ne +18d6 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +18d8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +18da : 48 > pha ;use stack to load status +18db : 28 > plp + +18dc : b226 lda (ind1+2) +18de : 08 php ;test stores do not alter flags +18df : 49c3 eor #$c3 +18e1 : 28 plp +18e2 : 9232 sta (indt+2) +18e4 : 08 php ;flags after load/store sequence +18e5 : 49c3 eor #$c3 +18e7 : c982 cmp #$82 ;test result + trap_ne +18e9 : d0fe > bne * ;failed not equal (non zero) + +18eb : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +18ec : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +18ee : cd1602 cmp fLDx+1 ;test flags + trap_ne +18f1 : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +18f3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +18f5 : 48 > pha ;use stack to load status +18f6 : 28 > plp + +18f7 : b228 lda (ind1+4) +18f9 : 08 php ;test stores do not alter flags +18fa : 49c3 eor #$c3 +18fc : 28 plp +18fd : 9234 sta (indt+4) +18ff : 08 php ;flags after load/store sequence +1900 : 49c3 eor #$c3 +1902 : c941 cmp #$41 ;test result + trap_ne +1904 : d0fe > bne * ;failed not equal (non zero) + +1906 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1907 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1909 : cd1702 cmp fLDx+2 ;test flags + trap_ne +190c : d0fe > bne * ;failed not equal (non zero) + + set_stat $ff + > load_flag $ff +190e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1910 : 48 > pha ;use stack to load status +1911 : 28 > plp + +1912 : b22a lda (ind1+6) +1914 : 08 php ;test stores do not alter flags +1915 : 49c3 eor #$c3 +1917 : 28 plp +1918 : 9236 sta (indt+6) +191a : 08 php ;flags after load/store sequence +191b : 49c3 eor #$c3 +191d : c900 cmp #0 ;test result + trap_ne +191f : d0fe > bne * ;failed not equal (non zero) + +1921 : 68 pla ;load status + eor_flag lo~fnz ;mask bits not altered +1922 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits + +1924 : cd1802 cmp fLDx+3 ;test flags + trap_ne +1927 : d0fe > bne * ;failed not equal (non zero) + +1929 : e099 cpx #$99 + trap_ne ;x altered during test +192b : d0fe > bne * ;failed not equal (non zero) + +192d : c066 cpy #$66 + trap_ne ;y altered during test +192f : d0fe > bne * ;failed not equal (non zero) + + +1931 : a003 ldy #3 ;testing store result +1933 : a200 ldx #0 +1935 : b90502 tstai2 lda abst,y +1938 : 49c3 eor #$c3 +193a : d91002 cmp abs1,y + trap_ne ;store to indirect data +193d : d0fe > bne * ;failed not equal (non zero) + +193f : 8a txa +1940 : 990502 sta abst,y ;clear +1943 : 88 dey +1944 : 10ef bpl tstai2 +1946 : ba tsx +1947 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +1949 : d0fe > bne * ;failed not equal (non zero) + + next_test +194b : ad0202 > lda test_case ;previous test +194e : c90d > cmp #test_num + > trap_ne ;test is out of sequence +1950 : d0fe > bne * ;failed not equal (non zero) + > +000e = >test_num = test_num + 1 +1952 : a90e > lda #test_num ;*** next tests' number +1954 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing STZ - zp / abs / zp,x / abs,x +1957 : a07b ldy #123 ;protect y +1959 : a204 ldx #4 ;precharge test area +195b : a907 lda #7 +195d : 950c tstz1 sta zpt,x +195f : 0a asl a +1960 : ca dex +1961 : 10fa bpl tstz1 +1963 : a204 ldx #4 + set_a $55,$ff + > load_flag $ff +1965 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1967 : 48 > pha ;use stack to load status +1968 : a955 > lda #$55 ;precharge accu +196a : 28 > plp + +196b : 640c stz zpt +196d : 640d stz zpt+1 +196f : 640e stz zpt+2 +1971 : 640f stz zpt+3 +1973 : 6410 stz zpt+4 + tst_a $55,$ff +1975 : 08 > php ;save flags +1976 : c955 > cmp #$55 ;test result + > trap_ne +1978 : d0fe > bne * ;failed not equal (non zero) + > +197a : 68 > pla ;load status +197b : 48 > pha + > cmp_flag $ff +197c : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +197e : d0fe > bne * ;failed not equal (non zero) + > +1980 : 28 > plp ;restore status + +1981 : b50c tstz2 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp +1983 : d0fe > bne * ;failed not equal (non zero) + +1985 : ca dex +1986 : 10f9 bpl tstz2 +1988 : a204 ldx #4 ;precharge test area +198a : a907 lda #7 +198c : 950c tstz3 sta zpt,x +198e : 0a asl a +198f : ca dex +1990 : 10fa bpl tstz3 +1992 : a204 ldx #4 + set_a $aa,0 + > load_flag 0 +1994 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1996 : 48 > pha ;use stack to load status +1997 : a9aa > lda #$aa ;precharge accu +1999 : 28 > plp + +199a : 640c stz zpt +199c : 640d stz zpt+1 +199e : 640e stz zpt+2 +19a0 : 640f stz zpt+3 +19a2 : 6410 stz zpt+4 + tst_a $aa,0 +19a4 : 08 > php ;save flags +19a5 : c9aa > cmp #$aa ;test result + > trap_ne +19a7 : d0fe > bne * ;failed not equal (non zero) + > +19a9 : 68 > pla ;load status +19aa : 48 > pha + > cmp_flag 0 +19ab : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +19ad : d0fe > bne * ;failed not equal (non zero) + > +19af : 28 > plp ;restore status + +19b0 : b50c tstz4 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp +19b2 : d0fe > bne * ;failed not equal (non zero) + +19b4 : ca dex +19b5 : 10f9 bpl tstz4 + +19b7 : a204 ldx #4 ;precharge test area +19b9 : a907 lda #7 +19bb : 9d0502 tstz5 sta abst,x +19be : 0a asl a +19bf : ca dex +19c0 : 10f9 bpl tstz5 +19c2 : a204 ldx #4 + set_a $55,$ff + > load_flag $ff +19c4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +19c6 : 48 > pha ;use stack to load status +19c7 : a955 > lda #$55 ;precharge accu +19c9 : 28 > plp + +19ca : 9c0502 stz abst +19cd : 9c0602 stz abst+1 +19d0 : 9c0702 stz abst+2 +19d3 : 9c0802 stz abst+3 +19d6 : 9c0902 stz abst+4 + tst_a $55,$ff +19d9 : 08 > php ;save flags +19da : c955 > cmp #$55 ;test result + > trap_ne +19dc : d0fe > bne * ;failed not equal (non zero) + > +19de : 68 > pla ;load status +19df : 48 > pha + > cmp_flag $ff +19e0 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +19e2 : d0fe > bne * ;failed not equal (non zero) + > +19e4 : 28 > plp ;restore status + +19e5 : bd0502 tstz6 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ abs +19e8 : d0fe > bne * ;failed not equal (non zero) + +19ea : ca dex +19eb : 10f8 bpl tstz6 +19ed : a204 ldx #4 ;precharge test area +19ef : a907 lda #7 +19f1 : 9d0502 tstz7 sta abst,x +19f4 : 0a asl a +19f5 : ca dex +19f6 : 10f9 bpl tstz7 +19f8 : a204 ldx #4 + set_a $aa,0 + > load_flag 0 +19fa : a900 > lda #0 ;allow test to change I-flag (no mask) + > +19fc : 48 > pha ;use stack to load status +19fd : a9aa > lda #$aa ;precharge accu +19ff : 28 > plp + +1a00 : 9c0502 stz abst +1a03 : 9c0602 stz abst+1 +1a06 : 9c0702 stz abst+2 +1a09 : 9c0802 stz abst+3 +1a0c : 9c0902 stz abst+4 + tst_a $aa,0 +1a0f : 08 > php ;save flags +1a10 : c9aa > cmp #$aa ;test result + > trap_ne +1a12 : d0fe > bne * ;failed not equal (non zero) + > +1a14 : 68 > pla ;load status +1a15 : 48 > pha + > cmp_flag 0 +1a16 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1a18 : d0fe > bne * ;failed not equal (non zero) + > +1a1a : 28 > plp ;restore status + +1a1b : bd0502 tstz8 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ abs +1a1e : d0fe > bne * ;failed not equal (non zero) + +1a20 : ca dex +1a21 : 10f8 bpl tstz8 + +1a23 : a204 ldx #4 ;precharge test area +1a25 : a907 lda #7 +1a27 : 950c tstz11 sta zpt,x +1a29 : 0a asl a +1a2a : ca dex +1a2b : 10fa bpl tstz11 +1a2d : a204 ldx #4 +1a2f : tstz15 + set_a $55,$ff + > load_flag $ff +1a2f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1a31 : 48 > pha ;use stack to load status +1a32 : a955 > lda #$55 ;precharge accu +1a34 : 28 > plp + +1a35 : 740c stz zpt,x + tst_a $55,$ff +1a37 : 08 > php ;save flags +1a38 : c955 > cmp #$55 ;test result + > trap_ne +1a3a : d0fe > bne * ;failed not equal (non zero) + > +1a3c : 68 > pla ;load status +1a3d : 48 > pha + > cmp_flag $ff +1a3e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1a40 : d0fe > bne * ;failed not equal (non zero) + > +1a42 : 28 > plp ;restore status + +1a43 : ca dex +1a44 : 10e9 bpl tstz15 +1a46 : a204 ldx #4 +1a48 : b50c tstz12 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp +1a4a : d0fe > bne * ;failed not equal (non zero) + +1a4c : ca dex +1a4d : 10f9 bpl tstz12 +1a4f : a204 ldx #4 ;precharge test area +1a51 : a907 lda #7 +1a53 : 950c tstz13 sta zpt,x +1a55 : 0a asl a +1a56 : ca dex +1a57 : 10fa bpl tstz13 +1a59 : a204 ldx #4 +1a5b : tstz16 + set_a $aa,0 + > load_flag 0 +1a5b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1a5d : 48 > pha ;use stack to load status +1a5e : a9aa > lda #$aa ;precharge accu +1a60 : 28 > plp + +1a61 : 740c stz zpt,x + tst_a $aa,0 +1a63 : 08 > php ;save flags +1a64 : c9aa > cmp #$aa ;test result + > trap_ne +1a66 : d0fe > bne * ;failed not equal (non zero) + > +1a68 : 68 > pla ;load status +1a69 : 48 > pha + > cmp_flag 0 +1a6a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1a6c : d0fe > bne * ;failed not equal (non zero) + > +1a6e : 28 > plp ;restore status + +1a6f : ca dex +1a70 : 10e9 bpl tstz16 +1a72 : a204 ldx #4 +1a74 : b50c tstz14 lda zpt,x ;verify zeros stored + trap_ne ;non zero after STZ zp +1a76 : d0fe > bne * ;failed not equal (non zero) + +1a78 : ca dex +1a79 : 10f9 bpl tstz14 + +1a7b : a204 ldx #4 ;precharge test area +1a7d : a907 lda #7 +1a7f : 9d0502 tstz21 sta abst,x +1a82 : 0a asl a +1a83 : ca dex +1a84 : 10f9 bpl tstz21 +1a86 : a204 ldx #4 +1a88 : tstz25 + set_a $55,$ff + > load_flag $ff +1a88 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1a8a : 48 > pha ;use stack to load status +1a8b : a955 > lda #$55 ;precharge accu +1a8d : 28 > plp + +1a8e : 9e0502 stz abst,x + tst_a $55,$ff +1a91 : 08 > php ;save flags +1a92 : c955 > cmp #$55 ;test result + > trap_ne +1a94 : d0fe > bne * ;failed not equal (non zero) + > +1a96 : 68 > pla ;load status +1a97 : 48 > pha + > cmp_flag $ff +1a98 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1a9a : d0fe > bne * ;failed not equal (non zero) + > +1a9c : 28 > plp ;restore status + +1a9d : ca dex +1a9e : 10e8 bpl tstz25 +1aa0 : a204 ldx #4 +1aa2 : bd0502 tstz22 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ zp +1aa5 : d0fe > bne * ;failed not equal (non zero) + +1aa7 : ca dex +1aa8 : 10f8 bpl tstz22 +1aaa : a204 ldx #4 ;precharge test area +1aac : a907 lda #7 +1aae : 9d0502 tstz23 sta abst,x +1ab1 : 0a asl a +1ab2 : ca dex +1ab3 : 10f9 bpl tstz23 +1ab5 : a204 ldx #4 +1ab7 : tstz26 + set_a $aa,0 + > load_flag 0 +1ab7 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1ab9 : 48 > pha ;use stack to load status +1aba : a9aa > lda #$aa ;precharge accu +1abc : 28 > plp + +1abd : 9e0502 stz abst,x + tst_a $aa,0 +1ac0 : 08 > php ;save flags +1ac1 : c9aa > cmp #$aa ;test result + > trap_ne +1ac3 : d0fe > bne * ;failed not equal (non zero) + > +1ac5 : 68 > pla ;load status +1ac6 : 48 > pha + > cmp_flag 0 +1ac7 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ac9 : d0fe > bne * ;failed not equal (non zero) + > +1acb : 28 > plp ;restore status + +1acc : ca dex +1acd : 10e8 bpl tstz26 +1acf : a204 ldx #4 +1ad1 : bd0502 tstz24 lda abst,x ;verify zeros stored + trap_ne ;non zero after STZ zp +1ad4 : d0fe > bne * ;failed not equal (non zero) + +1ad6 : ca dex +1ad7 : 10f8 bpl tstz24 + +1ad9 : c07b cpy #123 + trap_ne ;y altered during test +1adb : d0fe > bne * ;failed not equal (non zero) + +1add : ba tsx +1ade : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +1ae0 : d0fe > bne * ;failed not equal (non zero) + + next_test +1ae2 : ad0202 > lda test_case ;previous test +1ae5 : c90e > cmp #test_num + > trap_ne ;test is out of sequence +1ae7 : d0fe > bne * ;failed not equal (non zero) + > +000f = >test_num = test_num + 1 +1ae9 : a90f > lda #test_num ;*** next tests' number +1aeb : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing BIT - zp,x / abs,x / # +1aee : a042 ldy #$42 +1af0 : a203 ldx #3 + set_a $ff,0 + > load_flag 0 +1af2 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1af4 : 48 > pha ;use stack to load status +1af5 : a9ff > lda #$ff ;precharge accu +1af7 : 28 > plp + +1af8 : 3413 bit zp1,x ;00 - should set Z / clear NV + tst_a $ff,fz +1afa : 08 > php ;save flags +1afb : c9ff > cmp #$ff ;test result + > trap_ne +1afd : d0fe > bne * ;failed not equal (non zero) + > +1aff : 68 > pla ;load status +1b00 : 48 > pha + > cmp_flag fz +1b01 : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b03 : d0fe > bne * ;failed not equal (non zero) + > +1b05 : 28 > plp ;restore status + +1b06 : ca dex + set_a 1,0 + > load_flag 0 +1b07 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b09 : 48 > pha ;use stack to load status +1b0a : a901 > lda #1 ;precharge accu +1b0c : 28 > plp + +1b0d : 3413 bit zp1,x ;41 - should set V (M6) / clear NZ + tst_a 1,fv +1b0f : 08 > php ;save flags +1b10 : c901 > cmp #1 ;test result + > trap_ne +1b12 : d0fe > bne * ;failed not equal (non zero) + > +1b14 : 68 > pla ;load status +1b15 : 48 > pha + > cmp_flag fv +1b16 : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b18 : d0fe > bne * ;failed not equal (non zero) + > +1b1a : 28 > plp ;restore status + +1b1b : ca dex + set_a 1,0 + > load_flag 0 +1b1c : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b1e : 48 > pha ;use stack to load status +1b1f : a901 > lda #1 ;precharge accu +1b21 : 28 > plp + +1b22 : 3413 bit zp1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz +1b24 : 08 > php ;save flags +1b25 : c901 > cmp #1 ;test result + > trap_ne +1b27 : d0fe > bne * ;failed not equal (non zero) + > +1b29 : 68 > pla ;load status +1b2a : 48 > pha + > cmp_flag fnz +1b2b : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b2d : d0fe > bne * ;failed not equal (non zero) + > +1b2f : 28 > plp ;restore status + +1b30 : ca dex + set_a 1,0 + > load_flag 0 +1b31 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b33 : 48 > pha ;use stack to load status +1b34 : a901 > lda #1 ;precharge accu +1b36 : 28 > plp + +1b37 : 3413 bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv +1b39 : 08 > php ;save flags +1b3a : c901 > cmp #1 ;test result + > trap_ne +1b3c : d0fe > bne * ;failed not equal (non zero) + > +1b3e : 68 > pla ;load status +1b3f : 48 > pha + > cmp_flag fnv +1b40 : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b42 : d0fe > bne * ;failed not equal (non zero) + > +1b44 : 28 > plp ;restore status + + + set_a 1,$ff + > load_flag $ff +1b45 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1b47 : 48 > pha ;use stack to load status +1b48 : a901 > lda #1 ;precharge accu +1b4a : 28 > plp + +1b4b : 3413 bit zp1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz +1b4d : 08 > php ;save flags +1b4e : c901 > cmp #1 ;test result + > trap_ne +1b50 : d0fe > bne * ;failed not equal (non zero) + > +1b52 : 68 > pla ;load status +1b53 : 48 > pha + > cmp_flag ~fz +1b54 : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b56 : d0fe > bne * ;failed not equal (non zero) + > +1b58 : 28 > plp ;restore status + +1b59 : e8 inx + set_a 1,$ff + > load_flag $ff +1b5a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1b5c : 48 > pha ;use stack to load status +1b5d : a901 > lda #1 ;precharge accu +1b5f : 28 > plp + +1b60 : 3413 bit zp1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv +1b62 : 08 > php ;save flags +1b63 : c901 > cmp #1 ;test result + > trap_ne +1b65 : d0fe > bne * ;failed not equal (non zero) + > +1b67 : 68 > pla ;load status +1b68 : 48 > pha + > cmp_flag ~fv +1b69 : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b6b : d0fe > bne * ;failed not equal (non zero) + > +1b6d : 28 > plp ;restore status + +1b6e : e8 inx + set_a 1,$ff + > load_flag $ff +1b6f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1b71 : 48 > pha ;use stack to load status +1b72 : a901 > lda #1 ;precharge accu +1b74 : 28 > plp + +1b75 : 3413 bit zp1,x ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz +1b77 : 08 > php ;save flags +1b78 : c901 > cmp #1 ;test result + > trap_ne +1b7a : d0fe > bne * ;failed not equal (non zero) + > +1b7c : 68 > pla ;load status +1b7d : 48 > pha + > cmp_flag ~fnz +1b7e : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b80 : d0fe > bne * ;failed not equal (non zero) + > +1b82 : 28 > plp ;restore status + +1b83 : e8 inx + set_a $ff,$ff + > load_flag $ff +1b84 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1b86 : 48 > pha ;use stack to load status +1b87 : a9ff > lda #$ff ;precharge accu +1b89 : 28 > plp + +1b8a : 3413 bit zp1,x ;00 - should set Z / clear NV + tst_a $ff,~fnv +1b8c : 08 > php ;save flags +1b8d : c9ff > cmp #$ff ;test result + > trap_ne +1b8f : d0fe > bne * ;failed not equal (non zero) + > +1b91 : 68 > pla ;load status +1b92 : 48 > pha + > cmp_flag ~fnv +1b93 : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1b95 : d0fe > bne * ;failed not equal (non zero) + > +1b97 : 28 > plp ;restore status + + + set_a $ff,0 + > load_flag 0 +1b98 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1b9a : 48 > pha ;use stack to load status +1b9b : a9ff > lda #$ff ;precharge accu +1b9d : 28 > plp + +1b9e : 3c1002 bit abs1,x ;00 - should set Z / clear NV + tst_a $ff,fz +1ba1 : 08 > php ;save flags +1ba2 : c9ff > cmp #$ff ;test result + > trap_ne +1ba4 : d0fe > bne * ;failed not equal (non zero) + > +1ba6 : 68 > pla ;load status +1ba7 : 48 > pha + > cmp_flag fz +1ba8 : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1baa : d0fe > bne * ;failed not equal (non zero) + > +1bac : 28 > plp ;restore status + +1bad : ca dex + set_a 1,0 + > load_flag 0 +1bae : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1bb0 : 48 > pha ;use stack to load status +1bb1 : a901 > lda #1 ;precharge accu +1bb3 : 28 > plp + +1bb4 : 3c1002 bit abs1,x ;41 - should set V (M6) / clear NZ + tst_a 1,fv +1bb7 : 08 > php ;save flags +1bb8 : c901 > cmp #1 ;test result + > trap_ne +1bba : d0fe > bne * ;failed not equal (non zero) + > +1bbc : 68 > pla ;load status +1bbd : 48 > pha + > cmp_flag fv +1bbe : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bc0 : d0fe > bne * ;failed not equal (non zero) + > +1bc2 : 28 > plp ;restore status + +1bc3 : ca dex + set_a 1,0 + > load_flag 0 +1bc4 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1bc6 : 48 > pha ;use stack to load status +1bc7 : a901 > lda #1 ;precharge accu +1bc9 : 28 > plp + +1bca : 3c1002 bit abs1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,fnz +1bcd : 08 > php ;save flags +1bce : c901 > cmp #1 ;test result + > trap_ne +1bd0 : d0fe > bne * ;failed not equal (non zero) + > +1bd2 : 68 > pla ;load status +1bd3 : 48 > pha + > cmp_flag fnz +1bd4 : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bd6 : d0fe > bne * ;failed not equal (non zero) + > +1bd8 : 28 > plp ;restore status + +1bd9 : ca dex + set_a 1,0 + > load_flag 0 +1bda : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1bdc : 48 > pha ;use stack to load status +1bdd : a901 > lda #1 ;precharge accu +1bdf : 28 > plp + +1be0 : 3c1002 bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,fnv +1be3 : 08 > php ;save flags +1be4 : c901 > cmp #1 ;test result + > trap_ne +1be6 : d0fe > bne * ;failed not equal (non zero) + > +1be8 : 68 > pla ;load status +1be9 : 48 > pha + > cmp_flag fnv +1bea : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1bec : d0fe > bne * ;failed not equal (non zero) + > +1bee : 28 > plp ;restore status + + + set_a 1,$ff + > load_flag $ff +1bef : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1bf1 : 48 > pha ;use stack to load status +1bf2 : a901 > lda #1 ;precharge accu +1bf4 : 28 > plp + +1bf5 : 3c1002 bit abs1,x ;c3 - should set N (M7) & V (M6) / clear Z + tst_a 1,~fz +1bf8 : 08 > php ;save flags +1bf9 : c901 > cmp #1 ;test result + > trap_ne +1bfb : d0fe > bne * ;failed not equal (non zero) + > +1bfd : 68 > pla ;load status +1bfe : 48 > pha + > cmp_flag ~fz +1bff : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c01 : d0fe > bne * ;failed not equal (non zero) + > +1c03 : 28 > plp ;restore status + +1c04 : e8 inx + set_a 1,$ff + > load_flag $ff +1c05 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c07 : 48 > pha ;use stack to load status +1c08 : a901 > lda #1 ;precharge accu +1c0a : 28 > plp + +1c0b : 3c1002 bit abs1,x ;82 - should set N (M7) & Z / clear V + tst_a 1,~fv +1c0e : 08 > php ;save flags +1c0f : c901 > cmp #1 ;test result + > trap_ne +1c11 : d0fe > bne * ;failed not equal (non zero) + > +1c13 : 68 > pla ;load status +1c14 : 48 > pha + > cmp_flag ~fv +1c15 : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c17 : d0fe > bne * ;failed not equal (non zero) + > +1c19 : 28 > plp ;restore status + +1c1a : e8 inx + set_a 1,$ff + > load_flag $ff +1c1b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c1d : 48 > pha ;use stack to load status +1c1e : a901 > lda #1 ;precharge accu +1c20 : 28 > plp + +1c21 : 3c1002 bit abs1,x ;41 - should set V (M6) / clear NZ + tst_a 1,~fnz +1c24 : 08 > php ;save flags +1c25 : c901 > cmp #1 ;test result + > trap_ne +1c27 : d0fe > bne * ;failed not equal (non zero) + > +1c29 : 68 > pla ;load status +1c2a : 48 > pha + > cmp_flag ~fnz +1c2b : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c2d : d0fe > bne * ;failed not equal (non zero) + > +1c2f : 28 > plp ;restore status + +1c30 : e8 inx + set_a $ff,$ff + > load_flag $ff +1c31 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c33 : 48 > pha ;use stack to load status +1c34 : a9ff > lda #$ff ;precharge accu +1c36 : 28 > plp + +1c37 : 3c1002 bit abs1,x ;00 - should set Z / clear NV + tst_a $ff,~fnv +1c3a : 08 > php ;save flags +1c3b : c9ff > cmp #$ff ;test result + > trap_ne +1c3d : d0fe > bne * ;failed not equal (non zero) + > +1c3f : 68 > pla ;load status +1c40 : 48 > pha + > cmp_flag ~fnv +1c41 : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c43 : d0fe > bne * ;failed not equal (non zero) + > +1c45 : 28 > plp ;restore status + + + set_a $ff,0 + > load_flag 0 +1c46 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c48 : 48 > pha ;use stack to load status +1c49 : a9ff > lda #$ff ;precharge accu +1c4b : 28 > plp + +1c4c : 8900 bit #$00 ;00 - should set Z + tst_a $ff,fz +1c4e : 08 > php ;save flags +1c4f : c9ff > cmp #$ff ;test result + > trap_ne +1c51 : d0fe > bne * ;failed not equal (non zero) + > +1c53 : 68 > pla ;load status +1c54 : 48 > pha + > cmp_flag fz +1c55 : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c57 : d0fe > bne * ;failed not equal (non zero) + > +1c59 : 28 > plp ;restore status + +1c5a : ca dex + set_a 1,0 + > load_flag 0 +1c5b : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c5d : 48 > pha ;use stack to load status +1c5e : a901 > lda #1 ;precharge accu +1c60 : 28 > plp + +1c61 : 8941 bit #$41 ;41 - should clear Z + tst_a 1,0 +1c63 : 08 > php ;save flags +1c64 : c901 > cmp #1 ;test result + > trap_ne +1c66 : d0fe > bne * ;failed not equal (non zero) + > +1c68 : 68 > pla ;load status +1c69 : 48 > pha + > cmp_flag 0 +1c6a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c6c : d0fe > bne * ;failed not equal (non zero) + > +1c6e : 28 > plp ;restore status + + ; *** DEBUG INFO *** + ; if it fails the previous test and your BIT # has set the V flag + ; see http://forum.6502.org/viewtopic.php?f=2&t=2241&p=27243#p27239 + ; why it shouldn't alter N or V flags on a BIT # +1c6f : ca dex + set_a 1,0 + > load_flag 0 +1c70 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c72 : 48 > pha ;use stack to load status +1c73 : a901 > lda #1 ;precharge accu +1c75 : 28 > plp + +1c76 : 8982 bit #$82 ;82 - should set Z + tst_a 1,fz +1c78 : 08 > php ;save flags +1c79 : c901 > cmp #1 ;test result + > trap_ne +1c7b : d0fe > bne * ;failed not equal (non zero) + > +1c7d : 68 > pla ;load status +1c7e : 48 > pha + > cmp_flag fz +1c7f : c932 > cmp #(fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c81 : d0fe > bne * ;failed not equal (non zero) + > +1c83 : 28 > plp ;restore status + +1c84 : ca dex + set_a 1,0 + > load_flag 0 +1c85 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1c87 : 48 > pha ;use stack to load status +1c88 : a901 > lda #1 ;precharge accu +1c8a : 28 > plp + +1c8b : 89c3 bit #$c3 ;c3 - should clear Z + tst_a 1,0 +1c8d : 08 > php ;save flags +1c8e : c901 > cmp #1 ;test result + > trap_ne +1c90 : d0fe > bne * ;failed not equal (non zero) + > +1c92 : 68 > pla ;load status +1c93 : 48 > pha + > cmp_flag 0 +1c94 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1c96 : d0fe > bne * ;failed not equal (non zero) + > +1c98 : 28 > plp ;restore status + + + set_a 1,$ff + > load_flag $ff +1c99 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1c9b : 48 > pha ;use stack to load status +1c9c : a901 > lda #1 ;precharge accu +1c9e : 28 > plp + +1c9f : 89c3 bit #$c3 ;c3 - clear Z + tst_a 1,~fz +1ca1 : 08 > php ;save flags +1ca2 : c901 > cmp #1 ;test result + > trap_ne +1ca4 : d0fe > bne * ;failed not equal (non zero) + > +1ca6 : 68 > pla ;load status +1ca7 : 48 > pha + > cmp_flag ~fz +1ca8 : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1caa : d0fe > bne * ;failed not equal (non zero) + > +1cac : 28 > plp ;restore status + +1cad : e8 inx + set_a 1,$ff + > load_flag $ff +1cae : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1cb0 : 48 > pha ;use stack to load status +1cb1 : a901 > lda #1 ;precharge accu +1cb3 : 28 > plp + +1cb4 : 8982 bit #$82 ;82 - should set Z + tst_a 1,$ff +1cb6 : 08 > php ;save flags +1cb7 : c901 > cmp #1 ;test result + > trap_ne +1cb9 : d0fe > bne * ;failed not equal (non zero) + > +1cbb : 68 > pla ;load status +1cbc : 48 > pha + > cmp_flag $ff +1cbd : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cbf : d0fe > bne * ;failed not equal (non zero) + > +1cc1 : 28 > plp ;restore status + +1cc2 : e8 inx + set_a 1,$ff + > load_flag $ff +1cc3 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1cc5 : 48 > pha ;use stack to load status +1cc6 : a901 > lda #1 ;precharge accu +1cc8 : 28 > plp + +1cc9 : 8941 bit #$41 ;41 - should clear Z + tst_a 1,~fz +1ccb : 08 > php ;save flags +1ccc : c901 > cmp #1 ;test result + > trap_ne +1cce : d0fe > bne * ;failed not equal (non zero) + > +1cd0 : 68 > pla ;load status +1cd1 : 48 > pha + > cmp_flag ~fz +1cd2 : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1cd4 : d0fe > bne * ;failed not equal (non zero) + > +1cd6 : 28 > plp ;restore status + +1cd7 : e8 inx + set_a $ff,$ff + > load_flag $ff +1cd8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1cda : 48 > pha ;use stack to load status +1cdb : a9ff > lda #$ff ;precharge accu +1cdd : 28 > plp + +1cde : 8900 bit #$00 ;00 - should set Z + tst_a $ff,$ff +1ce0 : 08 > php ;save flags +1ce1 : c9ff > cmp #$ff ;test result + > trap_ne +1ce3 : d0fe > bne * ;failed not equal (non zero) + > +1ce5 : 68 > pla ;load status +1ce6 : 48 > pha + > cmp_flag $ff +1ce7 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ce9 : d0fe > bne * ;failed not equal (non zero) + > +1ceb : 28 > plp ;restore status + + +1cec : e003 cpx #3 + trap_ne ;x altered during test +1cee : d0fe > bne * ;failed not equal (non zero) + +1cf0 : c042 cpy #$42 + trap_ne ;y altered during test +1cf2 : d0fe > bne * ;failed not equal (non zero) + +1cf4 : ba tsx +1cf5 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +1cf7 : d0fe > bne * ;failed not equal (non zero) + + next_test +1cf9 : ad0202 > lda test_case ;previous test +1cfc : c90f > cmp #test_num + > trap_ne ;test is out of sequence +1cfe : d0fe > bne * ;failed not equal (non zero) + > +0010 = >test_num = test_num + 1 +1d00 : a910 > lda #test_num ;*** next tests' number +1d02 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing TRB, TSB - zp / abs + + trbt macro ;\1 = memory, \2 = flags + sty \1 + load_flag \2 + pha + lda zpt+1 + plp + trb \1 + php + cmp zpt+1 + trap_ne ;accu was changed + pla + pha + ora #fz ;mask Z + cmp_flag \2|fz + trap_ne ;flags changed except Z + pla + and #fz + cmp zpt+2 + trap_ne ;Z flag invalid + lda zpt+3 + cmp zpt + trap_ne ;altered bits in memory wrong + endm + + tsbt macro ;\1 = memory, \2 = flags + sty \1 + load_flag \2 + pha + lda zpt+1 + plp + tsb \1 + php + cmp zpt+1 + trap_ne ;accu was changed + pla + pha + ora #fz ;mask Z + cmp_flag \2|fz + trap_ne ;flags changed except Z + pla + and #fz + cmp zpt+2 + trap_ne ;Z flag invalid + lda zpt+4 + cmp zpt + trap_ne ;altered bits in memory wrong + endm + +1d05 : a2c0 ldx #$c0 +1d07 : a000 ldy #0 ;op1 - memory save + ; zpt ;op1 - memory modifiable +1d09 : 640d stz zpt+1 ;op2 - accu + ; zpt+2 ;and flags + ; zpt+3 ;memory after reset + ; zpt+4 ;memory after set + +1d0b : 98 tbt1 tya +1d0c : 250d and zpt+1 ;set Z by anding the 2 operands +1d0e : 08 php +1d0f : 68 pla +1d10 : 2902 and #fz ;mask Z +1d12 : 850e sta zpt+2 +1d14 : 98 tya ;reset op1 bits by op2 +1d15 : 49ff eor #$ff +1d17 : 050d ora zpt+1 +1d19 : 49ff eor #$ff +1d1b : 850f sta zpt+3 +1d1d : 98 tya ;set op1 bits by op2 +1d1e : 050d ora zpt+1 +1d20 : 8510 sta zpt+4 + + trbt zpt,$ff +1d22 : 840c > sty zpt + > load_flag $ff +1d24 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1d26 : 48 > pha +1d27 : a50d > lda zpt+1 +1d29 : 28 > plp +1d2a : 140c > trb zpt +1d2c : 08 > php +1d2d : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1d2f : d0fe > bne * ;failed not equal (non zero) + > +1d31 : 68 > pla +1d32 : 48 > pha +1d33 : 0902 > ora #fz ;mask Z + > cmp_flag $ff|fz +1d35 : c9ff > cmp #($ff|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1d37 : d0fe > bne * ;failed not equal (non zero) + > +1d39 : 68 > pla +1d3a : 2902 > and #fz +1d3c : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1d3e : d0fe > bne * ;failed not equal (non zero) + > +1d40 : a50f > lda zpt+3 +1d42 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1d44 : d0fe > bne * ;failed not equal (non zero) + > + + trbt abst,$ff +1d46 : 8c0502 > sty abst + > load_flag $ff +1d49 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1d4b : 48 > pha +1d4c : a50d > lda zpt+1 +1d4e : 28 > plp +1d4f : 1c0502 > trb abst +1d52 : 08 > php +1d53 : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1d55 : d0fe > bne * ;failed not equal (non zero) + > +1d57 : 68 > pla +1d58 : 48 > pha +1d59 : 0902 > ora #fz ;mask Z + > cmp_flag $ff|fz +1d5b : c9ff > cmp #($ff|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1d5d : d0fe > bne * ;failed not equal (non zero) + > +1d5f : 68 > pla +1d60 : 2902 > and #fz +1d62 : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1d64 : d0fe > bne * ;failed not equal (non zero) + > +1d66 : a50f > lda zpt+3 +1d68 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1d6a : d0fe > bne * ;failed not equal (non zero) + > + + trbt zpt,0 +1d6c : 840c > sty zpt + > load_flag 0 +1d6e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1d70 : 48 > pha +1d71 : a50d > lda zpt+1 +1d73 : 28 > plp +1d74 : 140c > trb zpt +1d76 : 08 > php +1d77 : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1d79 : d0fe > bne * ;failed not equal (non zero) + > +1d7b : 68 > pla +1d7c : 48 > pha +1d7d : 0902 > ora #fz ;mask Z + > cmp_flag 0|fz +1d7f : c932 > cmp #(0|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1d81 : d0fe > bne * ;failed not equal (non zero) + > +1d83 : 68 > pla +1d84 : 2902 > and #fz +1d86 : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1d88 : d0fe > bne * ;failed not equal (non zero) + > +1d8a : a50f > lda zpt+3 +1d8c : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1d8e : d0fe > bne * ;failed not equal (non zero) + > + + trbt abst,0 +1d90 : 8c0502 > sty abst + > load_flag 0 +1d93 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1d95 : 48 > pha +1d96 : a50d > lda zpt+1 +1d98 : 28 > plp +1d99 : 1c0502 > trb abst +1d9c : 08 > php +1d9d : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1d9f : d0fe > bne * ;failed not equal (non zero) + > +1da1 : 68 > pla +1da2 : 48 > pha +1da3 : 0902 > ora #fz ;mask Z + > cmp_flag 0|fz +1da5 : c932 > cmp #(0|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1da7 : d0fe > bne * ;failed not equal (non zero) + > +1da9 : 68 > pla +1daa : 2902 > and #fz +1dac : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1dae : d0fe > bne * ;failed not equal (non zero) + > +1db0 : a50f > lda zpt+3 +1db2 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1db4 : d0fe > bne * ;failed not equal (non zero) + > + + tsbt zpt,$ff +1db6 : 840c > sty zpt + > load_flag $ff +1db8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1dba : 48 > pha +1dbb : a50d > lda zpt+1 +1dbd : 28 > plp +1dbe : 040c > tsb zpt +1dc0 : 08 > php +1dc1 : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1dc3 : d0fe > bne * ;failed not equal (non zero) + > +1dc5 : 68 > pla +1dc6 : 48 > pha +1dc7 : 0902 > ora #fz ;mask Z + > cmp_flag $ff|fz +1dc9 : c9ff > cmp #($ff|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1dcb : d0fe > bne * ;failed not equal (non zero) + > +1dcd : 68 > pla +1dce : 2902 > and #fz +1dd0 : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1dd2 : d0fe > bne * ;failed not equal (non zero) + > +1dd4 : a510 > lda zpt+4 +1dd6 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1dd8 : d0fe > bne * ;failed not equal (non zero) + > + + tsbt abst,$ff +1dda : 8c0502 > sty abst + > load_flag $ff +1ddd : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1ddf : 48 > pha +1de0 : a50d > lda zpt+1 +1de2 : 28 > plp +1de3 : 0c0502 > tsb abst +1de6 : 08 > php +1de7 : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1de9 : d0fe > bne * ;failed not equal (non zero) + > +1deb : 68 > pla +1dec : 48 > pha +1ded : 0902 > ora #fz ;mask Z + > cmp_flag $ff|fz +1def : c9ff > cmp #($ff|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1df1 : d0fe > bne * ;failed not equal (non zero) + > +1df3 : 68 > pla +1df4 : 2902 > and #fz +1df6 : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1df8 : d0fe > bne * ;failed not equal (non zero) + > +1dfa : a510 > lda zpt+4 +1dfc : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1dfe : d0fe > bne * ;failed not equal (non zero) + > + + tsbt zpt,0 +1e00 : 840c > sty zpt + > load_flag 0 +1e02 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1e04 : 48 > pha +1e05 : a50d > lda zpt+1 +1e07 : 28 > plp +1e08 : 040c > tsb zpt +1e0a : 08 > php +1e0b : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1e0d : d0fe > bne * ;failed not equal (non zero) + > +1e0f : 68 > pla +1e10 : 48 > pha +1e11 : 0902 > ora #fz ;mask Z + > cmp_flag 0|fz +1e13 : c932 > cmp #(0|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1e15 : d0fe > bne * ;failed not equal (non zero) + > +1e17 : 68 > pla +1e18 : 2902 > and #fz +1e1a : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1e1c : d0fe > bne * ;failed not equal (non zero) + > +1e1e : a510 > lda zpt+4 +1e20 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1e22 : d0fe > bne * ;failed not equal (non zero) + > + + tsbt abst,0 +1e24 : 8c0502 > sty abst + > load_flag 0 +1e27 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1e29 : 48 > pha +1e2a : a50d > lda zpt+1 +1e2c : 28 > plp +1e2d : 0c0502 > tsb abst +1e30 : 08 > php +1e31 : c50d > cmp zpt+1 + > trap_ne ;accu was changed +1e33 : d0fe > bne * ;failed not equal (non zero) + > +1e35 : 68 > pla +1e36 : 48 > pha +1e37 : 0902 > ora #fz ;mask Z + > cmp_flag 0|fz +1e39 : c932 > cmp #(0|fz|fao)&m8 ;expected flags + always on bits + > + > trap_ne ;flags changed except Z +1e3b : d0fe > bne * ;failed not equal (non zero) + > +1e3d : 68 > pla +1e3e : 2902 > and #fz +1e40 : c50e > cmp zpt+2 + > trap_ne ;Z flag invalid +1e42 : d0fe > bne * ;failed not equal (non zero) + > +1e44 : a510 > lda zpt+4 +1e46 : c50c > cmp zpt + > trap_ne ;altered bits in memory wrong +1e48 : d0fe > bne * ;failed not equal (non zero) + > + + +1e4a : c8 iny ;iterate op1 +1e4b : d004 bne tbt3 +1e4d : e60d inc zpt+1 ;iterate op2 +1e4f : f003 beq tbt2 +1e51 : 4c0b1d tbt3 jmp tbt1 +1e54 : tbt2 +1e54 : e0c0 cpx #$c0 + trap_ne ;x altered during test +1e56 : d0fe > bne * ;failed not equal (non zero) + +1e58 : ba tsx +1e59 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +1e5b : d0fe > bne * ;failed not equal (non zero) + + next_test +1e5d : ad0202 > lda test_case ;previous test +1e60 : c910 > cmp #test_num + > trap_ne ;test is out of sequence +1e62 : d0fe > bne * ;failed not equal (non zero) + > +0011 = >test_num = test_num + 1 +1e64 : a911 > lda #test_num ;*** next tests' number +1e66 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + if rkwl_wdc_op = 1 + ; testing RMB, SMB - zp + rmbt macro ;\1 = bitnum + lda #$ff + sta zpt + set_a $a5,0 + rmb \1,zpt + tst_a $a5,0 + lda zpt + cmp #$ff-(1<<\1) + trap_ne ;wrong bits set or cleared + lda #1<<\1 + sta zpt + set_a $5a,$ff + rmb \1,zpt + tst_a $5a,$ff + lda zpt + trap_ne ;wrong bits set or cleared + endm + smbt macro ;\1 = bitnum + lda #$ff-(1<<\1) + sta zpt + set_a $a5,0 + smb \1,zpt + tst_a $a5,0 + lda zpt + cmp #$ff + trap_ne ;wrong bits set or cleared + lda #0 + sta zpt + set_a $5a,$ff + smb \1,zpt + tst_a $5a,$ff + lda zpt + cmp #1<<\1 + trap_ne ;wrong bits set or cleared + endm + +1e69 : a2ba ldx #$ba ;protect x & y +1e6b : a0d0 ldy #$d0 + rmbt 0 +1e6d : a9ff > lda #$ff +1e6f : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1e71 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1e73 : 48 > pha ;use stack to load status +1e74 : a9a5 > lda #$a5 ;precharge accu +1e76 : 28 > plp + > +1e77 : 070c > rmb 0,zpt + > tst_a $a5,0 +1e79 : 08 > php ;save flags +1e7a : c9a5 > cmp #$a5 ;test result + > trap_ne +1e7c : d0fe > bne * ;failed not equal (non zero) + > +1e7e : 68 > pla ;load status +1e7f : 48 > pha + > cmp_flag 0 +1e80 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1e82 : d0fe > bne * ;failed not equal (non zero) + > +1e84 : 28 > plp ;restore status + > +1e85 : a50c > lda zpt +1e87 : c9fe > cmp #$ff-(1<<0) + > trap_ne ;wrong bits set or cleared +1e89 : d0fe > bne * ;failed not equal (non zero) + > +1e8b : a901 > lda #1<<0 +1e8d : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1e8f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1e91 : 48 > pha ;use stack to load status +1e92 : a95a > lda #$5a ;precharge accu +1e94 : 28 > plp + > +1e95 : 070c > rmb 0,zpt + > tst_a $5a,$ff +1e97 : 08 > php ;save flags +1e98 : c95a > cmp #$5a ;test result + > trap_ne +1e9a : d0fe > bne * ;failed not equal (non zero) + > +1e9c : 68 > pla ;load status +1e9d : 48 > pha + > cmp_flag $ff +1e9e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ea0 : d0fe > bne * ;failed not equal (non zero) + > +1ea2 : 28 > plp ;restore status + > +1ea3 : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1ea5 : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 1 +1ea7 : a9ff > lda #$ff +1ea9 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1eab : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1ead : 48 > pha ;use stack to load status +1eae : a9a5 > lda #$a5 ;precharge accu +1eb0 : 28 > plp + > +1eb1 : 170c > rmb 1,zpt + > tst_a $a5,0 +1eb3 : 08 > php ;save flags +1eb4 : c9a5 > cmp #$a5 ;test result + > trap_ne +1eb6 : d0fe > bne * ;failed not equal (non zero) + > +1eb8 : 68 > pla ;load status +1eb9 : 48 > pha + > cmp_flag 0 +1eba : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ebc : d0fe > bne * ;failed not equal (non zero) + > +1ebe : 28 > plp ;restore status + > +1ebf : a50c > lda zpt +1ec1 : c9fd > cmp #$ff-(1<<1) + > trap_ne ;wrong bits set or cleared +1ec3 : d0fe > bne * ;failed not equal (non zero) + > +1ec5 : a902 > lda #1<<1 +1ec7 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1ec9 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1ecb : 48 > pha ;use stack to load status +1ecc : a95a > lda #$5a ;precharge accu +1ece : 28 > plp + > +1ecf : 170c > rmb 1,zpt + > tst_a $5a,$ff +1ed1 : 08 > php ;save flags +1ed2 : c95a > cmp #$5a ;test result + > trap_ne +1ed4 : d0fe > bne * ;failed not equal (non zero) + > +1ed6 : 68 > pla ;load status +1ed7 : 48 > pha + > cmp_flag $ff +1ed8 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1eda : d0fe > bne * ;failed not equal (non zero) + > +1edc : 28 > plp ;restore status + > +1edd : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1edf : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 2 +1ee1 : a9ff > lda #$ff +1ee3 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1ee5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1ee7 : 48 > pha ;use stack to load status +1ee8 : a9a5 > lda #$a5 ;precharge accu +1eea : 28 > plp + > +1eeb : 270c > rmb 2,zpt + > tst_a $a5,0 +1eed : 08 > php ;save flags +1eee : c9a5 > cmp #$a5 ;test result + > trap_ne +1ef0 : d0fe > bne * ;failed not equal (non zero) + > +1ef2 : 68 > pla ;load status +1ef3 : 48 > pha + > cmp_flag 0 +1ef4 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ef6 : d0fe > bne * ;failed not equal (non zero) + > +1ef8 : 28 > plp ;restore status + > +1ef9 : a50c > lda zpt +1efb : c9fb > cmp #$ff-(1<<2) + > trap_ne ;wrong bits set or cleared +1efd : d0fe > bne * ;failed not equal (non zero) + > +1eff : a904 > lda #1<<2 +1f01 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1f03 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f05 : 48 > pha ;use stack to load status +1f06 : a95a > lda #$5a ;precharge accu +1f08 : 28 > plp + > +1f09 : 270c > rmb 2,zpt + > tst_a $5a,$ff +1f0b : 08 > php ;save flags +1f0c : c95a > cmp #$5a ;test result + > trap_ne +1f0e : d0fe > bne * ;failed not equal (non zero) + > +1f10 : 68 > pla ;load status +1f11 : 48 > pha + > cmp_flag $ff +1f12 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f14 : d0fe > bne * ;failed not equal (non zero) + > +1f16 : 28 > plp ;restore status + > +1f17 : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1f19 : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 3 +1f1b : a9ff > lda #$ff +1f1d : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1f1f : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f21 : 48 > pha ;use stack to load status +1f22 : a9a5 > lda #$a5 ;precharge accu +1f24 : 28 > plp + > +1f25 : 370c > rmb 3,zpt + > tst_a $a5,0 +1f27 : 08 > php ;save flags +1f28 : c9a5 > cmp #$a5 ;test result + > trap_ne +1f2a : d0fe > bne * ;failed not equal (non zero) + > +1f2c : 68 > pla ;load status +1f2d : 48 > pha + > cmp_flag 0 +1f2e : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f30 : d0fe > bne * ;failed not equal (non zero) + > +1f32 : 28 > plp ;restore status + > +1f33 : a50c > lda zpt +1f35 : c9f7 > cmp #$ff-(1<<3) + > trap_ne ;wrong bits set or cleared +1f37 : d0fe > bne * ;failed not equal (non zero) + > +1f39 : a908 > lda #1<<3 +1f3b : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1f3d : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f3f : 48 > pha ;use stack to load status +1f40 : a95a > lda #$5a ;precharge accu +1f42 : 28 > plp + > +1f43 : 370c > rmb 3,zpt + > tst_a $5a,$ff +1f45 : 08 > php ;save flags +1f46 : c95a > cmp #$5a ;test result + > trap_ne +1f48 : d0fe > bne * ;failed not equal (non zero) + > +1f4a : 68 > pla ;load status +1f4b : 48 > pha + > cmp_flag $ff +1f4c : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f4e : d0fe > bne * ;failed not equal (non zero) + > +1f50 : 28 > plp ;restore status + > +1f51 : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1f53 : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 4 +1f55 : a9ff > lda #$ff +1f57 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1f59 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f5b : 48 > pha ;use stack to load status +1f5c : a9a5 > lda #$a5 ;precharge accu +1f5e : 28 > plp + > +1f5f : 470c > rmb 4,zpt + > tst_a $a5,0 +1f61 : 08 > php ;save flags +1f62 : c9a5 > cmp #$a5 ;test result + > trap_ne +1f64 : d0fe > bne * ;failed not equal (non zero) + > +1f66 : 68 > pla ;load status +1f67 : 48 > pha + > cmp_flag 0 +1f68 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f6a : d0fe > bne * ;failed not equal (non zero) + > +1f6c : 28 > plp ;restore status + > +1f6d : a50c > lda zpt +1f6f : c9ef > cmp #$ff-(1<<4) + > trap_ne ;wrong bits set or cleared +1f71 : d0fe > bne * ;failed not equal (non zero) + > +1f73 : a910 > lda #1<<4 +1f75 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1f77 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1f79 : 48 > pha ;use stack to load status +1f7a : a95a > lda #$5a ;precharge accu +1f7c : 28 > plp + > +1f7d : 470c > rmb 4,zpt + > tst_a $5a,$ff +1f7f : 08 > php ;save flags +1f80 : c95a > cmp #$5a ;test result + > trap_ne +1f82 : d0fe > bne * ;failed not equal (non zero) + > +1f84 : 68 > pla ;load status +1f85 : 48 > pha + > cmp_flag $ff +1f86 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1f88 : d0fe > bne * ;failed not equal (non zero) + > +1f8a : 28 > plp ;restore status + > +1f8b : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1f8d : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 5 +1f8f : a9ff > lda #$ff +1f91 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1f93 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1f95 : 48 > pha ;use stack to load status +1f96 : a9a5 > lda #$a5 ;precharge accu +1f98 : 28 > plp + > +1f99 : 570c > rmb 5,zpt + > tst_a $a5,0 +1f9b : 08 > php ;save flags +1f9c : c9a5 > cmp #$a5 ;test result + > trap_ne +1f9e : d0fe > bne * ;failed not equal (non zero) + > +1fa0 : 68 > pla ;load status +1fa1 : 48 > pha + > cmp_flag 0 +1fa2 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fa4 : d0fe > bne * ;failed not equal (non zero) + > +1fa6 : 28 > plp ;restore status + > +1fa7 : a50c > lda zpt +1fa9 : c9df > cmp #$ff-(1<<5) + > trap_ne ;wrong bits set or cleared +1fab : d0fe > bne * ;failed not equal (non zero) + > +1fad : a920 > lda #1<<5 +1faf : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1fb1 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1fb3 : 48 > pha ;use stack to load status +1fb4 : a95a > lda #$5a ;precharge accu +1fb6 : 28 > plp + > +1fb7 : 570c > rmb 5,zpt + > tst_a $5a,$ff +1fb9 : 08 > php ;save flags +1fba : c95a > cmp #$5a ;test result + > trap_ne +1fbc : d0fe > bne * ;failed not equal (non zero) + > +1fbe : 68 > pla ;load status +1fbf : 48 > pha + > cmp_flag $ff +1fc0 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fc2 : d0fe > bne * ;failed not equal (non zero) + > +1fc4 : 28 > plp ;restore status + > +1fc5 : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +1fc7 : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 6 +1fc9 : a9ff > lda #$ff +1fcb : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +1fcd : a900 > lda #0 ;allow test to change I-flag (no mask) + > +1fcf : 48 > pha ;use stack to load status +1fd0 : a9a5 > lda #$a5 ;precharge accu +1fd2 : 28 > plp + > +1fd3 : 670c > rmb 6,zpt + > tst_a $a5,0 +1fd5 : 08 > php ;save flags +1fd6 : c9a5 > cmp #$a5 ;test result + > trap_ne +1fd8 : d0fe > bne * ;failed not equal (non zero) + > +1fda : 68 > pla ;load status +1fdb : 48 > pha + > cmp_flag 0 +1fdc : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1fde : d0fe > bne * ;failed not equal (non zero) + > +1fe0 : 28 > plp ;restore status + > +1fe1 : a50c > lda zpt +1fe3 : c9bf > cmp #$ff-(1<<6) + > trap_ne ;wrong bits set or cleared +1fe5 : d0fe > bne * ;failed not equal (non zero) + > +1fe7 : a940 > lda #1<<6 +1fe9 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +1feb : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +1fed : 48 > pha ;use stack to load status +1fee : a95a > lda #$5a ;precharge accu +1ff0 : 28 > plp + > +1ff1 : 670c > rmb 6,zpt + > tst_a $5a,$ff +1ff3 : 08 > php ;save flags +1ff4 : c95a > cmp #$5a ;test result + > trap_ne +1ff6 : d0fe > bne * ;failed not equal (non zero) + > +1ff8 : 68 > pla ;load status +1ff9 : 48 > pha + > cmp_flag $ff +1ffa : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +1ffc : d0fe > bne * ;failed not equal (non zero) + > +1ffe : 28 > plp ;restore status + > +1fff : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +2001 : d0fe > bne * ;failed not equal (non zero) + > + + rmbt 7 +2003 : a9ff > lda #$ff +2005 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +2007 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2009 : 48 > pha ;use stack to load status +200a : a9a5 > lda #$a5 ;precharge accu +200c : 28 > plp + > +200d : 770c > rmb 7,zpt + > tst_a $a5,0 +200f : 08 > php ;save flags +2010 : c9a5 > cmp #$a5 ;test result + > trap_ne +2012 : d0fe > bne * ;failed not equal (non zero) + > +2014 : 68 > pla ;load status +2015 : 48 > pha + > cmp_flag 0 +2016 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2018 : d0fe > bne * ;failed not equal (non zero) + > +201a : 28 > plp ;restore status + > +201b : a50c > lda zpt +201d : c97f > cmp #$ff-(1<<7) + > trap_ne ;wrong bits set or cleared +201f : d0fe > bne * ;failed not equal (non zero) + > +2021 : a980 > lda #1<<7 +2023 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +2025 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2027 : 48 > pha ;use stack to load status +2028 : a95a > lda #$5a ;precharge accu +202a : 28 > plp + > +202b : 770c > rmb 7,zpt + > tst_a $5a,$ff +202d : 08 > php ;save flags +202e : c95a > cmp #$5a ;test result + > trap_ne +2030 : d0fe > bne * ;failed not equal (non zero) + > +2032 : 68 > pla ;load status +2033 : 48 > pha + > cmp_flag $ff +2034 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2036 : d0fe > bne * ;failed not equal (non zero) + > +2038 : 28 > plp ;restore status + > +2039 : a50c > lda zpt + > trap_ne ;wrong bits set or cleared +203b : d0fe > bne * ;failed not equal (non zero) + > + + smbt 0 +203d : a9fe > lda #$ff-(1<<0) +203f : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +2041 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2043 : 48 > pha ;use stack to load status +2044 : a9a5 > lda #$a5 ;precharge accu +2046 : 28 > plp + > +2047 : 870c > smb 0,zpt + > tst_a $a5,0 +2049 : 08 > php ;save flags +204a : c9a5 > cmp #$a5 ;test result + > trap_ne +204c : d0fe > bne * ;failed not equal (non zero) + > +204e : 68 > pla ;load status +204f : 48 > pha + > cmp_flag 0 +2050 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2052 : d0fe > bne * ;failed not equal (non zero) + > +2054 : 28 > plp ;restore status + > +2055 : a50c > lda zpt +2057 : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +2059 : d0fe > bne * ;failed not equal (non zero) + > +205b : a900 > lda #0 +205d : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +205f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2061 : 48 > pha ;use stack to load status +2062 : a95a > lda #$5a ;precharge accu +2064 : 28 > plp + > +2065 : 870c > smb 0,zpt + > tst_a $5a,$ff +2067 : 08 > php ;save flags +2068 : c95a > cmp #$5a ;test result + > trap_ne +206a : d0fe > bne * ;failed not equal (non zero) + > +206c : 68 > pla ;load status +206d : 48 > pha + > cmp_flag $ff +206e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2070 : d0fe > bne * ;failed not equal (non zero) + > +2072 : 28 > plp ;restore status + > +2073 : a50c > lda zpt +2075 : c901 > cmp #1<<0 + > trap_ne ;wrong bits set or cleared +2077 : d0fe > bne * ;failed not equal (non zero) + > + + smbt 1 +2079 : a9fd > lda #$ff-(1<<1) +207b : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +207d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +207f : 48 > pha ;use stack to load status +2080 : a9a5 > lda #$a5 ;precharge accu +2082 : 28 > plp + > +2083 : 970c > smb 1,zpt + > tst_a $a5,0 +2085 : 08 > php ;save flags +2086 : c9a5 > cmp #$a5 ;test result + > trap_ne +2088 : d0fe > bne * ;failed not equal (non zero) + > +208a : 68 > pla ;load status +208b : 48 > pha + > cmp_flag 0 +208c : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +208e : d0fe > bne * ;failed not equal (non zero) + > +2090 : 28 > plp ;restore status + > +2091 : a50c > lda zpt +2093 : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +2095 : d0fe > bne * ;failed not equal (non zero) + > +2097 : a900 > lda #0 +2099 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +209b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +209d : 48 > pha ;use stack to load status +209e : a95a > lda #$5a ;precharge accu +20a0 : 28 > plp + > +20a1 : 970c > smb 1,zpt + > tst_a $5a,$ff +20a3 : 08 > php ;save flags +20a4 : c95a > cmp #$5a ;test result + > trap_ne +20a6 : d0fe > bne * ;failed not equal (non zero) + > +20a8 : 68 > pla ;load status +20a9 : 48 > pha + > cmp_flag $ff +20aa : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20ac : d0fe > bne * ;failed not equal (non zero) + > +20ae : 28 > plp ;restore status + > +20af : a50c > lda zpt +20b1 : c902 > cmp #1<<1 + > trap_ne ;wrong bits set or cleared +20b3 : d0fe > bne * ;failed not equal (non zero) + > + + smbt 2 +20b5 : a9fb > lda #$ff-(1<<2) +20b7 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +20b9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +20bb : 48 > pha ;use stack to load status +20bc : a9a5 > lda #$a5 ;precharge accu +20be : 28 > plp + > +20bf : a70c > smb 2,zpt + > tst_a $a5,0 +20c1 : 08 > php ;save flags +20c2 : c9a5 > cmp #$a5 ;test result + > trap_ne +20c4 : d0fe > bne * ;failed not equal (non zero) + > +20c6 : 68 > pla ;load status +20c7 : 48 > pha + > cmp_flag 0 +20c8 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20ca : d0fe > bne * ;failed not equal (non zero) + > +20cc : 28 > plp ;restore status + > +20cd : a50c > lda zpt +20cf : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +20d1 : d0fe > bne * ;failed not equal (non zero) + > +20d3 : a900 > lda #0 +20d5 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +20d7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +20d9 : 48 > pha ;use stack to load status +20da : a95a > lda #$5a ;precharge accu +20dc : 28 > plp + > +20dd : a70c > smb 2,zpt + > tst_a $5a,$ff +20df : 08 > php ;save flags +20e0 : c95a > cmp #$5a ;test result + > trap_ne +20e2 : d0fe > bne * ;failed not equal (non zero) + > +20e4 : 68 > pla ;load status +20e5 : 48 > pha + > cmp_flag $ff +20e6 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +20e8 : d0fe > bne * ;failed not equal (non zero) + > +20ea : 28 > plp ;restore status + > +20eb : a50c > lda zpt +20ed : c904 > cmp #1<<2 + > trap_ne ;wrong bits set or cleared +20ef : d0fe > bne * ;failed not equal (non zero) + > + + smbt 3 +20f1 : a9f7 > lda #$ff-(1<<3) +20f3 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +20f5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +20f7 : 48 > pha ;use stack to load status +20f8 : a9a5 > lda #$a5 ;precharge accu +20fa : 28 > plp + > +20fb : b70c > smb 3,zpt + > tst_a $a5,0 +20fd : 08 > php ;save flags +20fe : c9a5 > cmp #$a5 ;test result + > trap_ne +2100 : d0fe > bne * ;failed not equal (non zero) + > +2102 : 68 > pla ;load status +2103 : 48 > pha + > cmp_flag 0 +2104 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2106 : d0fe > bne * ;failed not equal (non zero) + > +2108 : 28 > plp ;restore status + > +2109 : a50c > lda zpt +210b : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +210d : d0fe > bne * ;failed not equal (non zero) + > +210f : a900 > lda #0 +2111 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +2113 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2115 : 48 > pha ;use stack to load status +2116 : a95a > lda #$5a ;precharge accu +2118 : 28 > plp + > +2119 : b70c > smb 3,zpt + > tst_a $5a,$ff +211b : 08 > php ;save flags +211c : c95a > cmp #$5a ;test result + > trap_ne +211e : d0fe > bne * ;failed not equal (non zero) + > +2120 : 68 > pla ;load status +2121 : 48 > pha + > cmp_flag $ff +2122 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2124 : d0fe > bne * ;failed not equal (non zero) + > +2126 : 28 > plp ;restore status + > +2127 : a50c > lda zpt +2129 : c908 > cmp #1<<3 + > trap_ne ;wrong bits set or cleared +212b : d0fe > bne * ;failed not equal (non zero) + > + + smbt 4 +212d : a9ef > lda #$ff-(1<<4) +212f : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +2131 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2133 : 48 > pha ;use stack to load status +2134 : a9a5 > lda #$a5 ;precharge accu +2136 : 28 > plp + > +2137 : c70c > smb 4,zpt + > tst_a $a5,0 +2139 : 08 > php ;save flags +213a : c9a5 > cmp #$a5 ;test result + > trap_ne +213c : d0fe > bne * ;failed not equal (non zero) + > +213e : 68 > pla ;load status +213f : 48 > pha + > cmp_flag 0 +2140 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2142 : d0fe > bne * ;failed not equal (non zero) + > +2144 : 28 > plp ;restore status + > +2145 : a50c > lda zpt +2147 : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +2149 : d0fe > bne * ;failed not equal (non zero) + > +214b : a900 > lda #0 +214d : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +214f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2151 : 48 > pha ;use stack to load status +2152 : a95a > lda #$5a ;precharge accu +2154 : 28 > plp + > +2155 : c70c > smb 4,zpt + > tst_a $5a,$ff +2157 : 08 > php ;save flags +2158 : c95a > cmp #$5a ;test result + > trap_ne +215a : d0fe > bne * ;failed not equal (non zero) + > +215c : 68 > pla ;load status +215d : 48 > pha + > cmp_flag $ff +215e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2160 : d0fe > bne * ;failed not equal (non zero) + > +2162 : 28 > plp ;restore status + > +2163 : a50c > lda zpt +2165 : c910 > cmp #1<<4 + > trap_ne ;wrong bits set or cleared +2167 : d0fe > bne * ;failed not equal (non zero) + > + + smbt 5 +2169 : a9df > lda #$ff-(1<<5) +216b : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +216d : a900 > lda #0 ;allow test to change I-flag (no mask) + > +216f : 48 > pha ;use stack to load status +2170 : a9a5 > lda #$a5 ;precharge accu +2172 : 28 > plp + > +2173 : d70c > smb 5,zpt + > tst_a $a5,0 +2175 : 08 > php ;save flags +2176 : c9a5 > cmp #$a5 ;test result + > trap_ne +2178 : d0fe > bne * ;failed not equal (non zero) + > +217a : 68 > pla ;load status +217b : 48 > pha + > cmp_flag 0 +217c : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +217e : d0fe > bne * ;failed not equal (non zero) + > +2180 : 28 > plp ;restore status + > +2181 : a50c > lda zpt +2183 : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +2185 : d0fe > bne * ;failed not equal (non zero) + > +2187 : a900 > lda #0 +2189 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +218b : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +218d : 48 > pha ;use stack to load status +218e : a95a > lda #$5a ;precharge accu +2190 : 28 > plp + > +2191 : d70c > smb 5,zpt + > tst_a $5a,$ff +2193 : 08 > php ;save flags +2194 : c95a > cmp #$5a ;test result + > trap_ne +2196 : d0fe > bne * ;failed not equal (non zero) + > +2198 : 68 > pla ;load status +2199 : 48 > pha + > cmp_flag $ff +219a : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +219c : d0fe > bne * ;failed not equal (non zero) + > +219e : 28 > plp ;restore status + > +219f : a50c > lda zpt +21a1 : c920 > cmp #1<<5 + > trap_ne ;wrong bits set or cleared +21a3 : d0fe > bne * ;failed not equal (non zero) + > + + smbt 6 +21a5 : a9bf > lda #$ff-(1<<6) +21a7 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +21a9 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +21ab : 48 > pha ;use stack to load status +21ac : a9a5 > lda #$a5 ;precharge accu +21ae : 28 > plp + > +21af : e70c > smb 6,zpt + > tst_a $a5,0 +21b1 : 08 > php ;save flags +21b2 : c9a5 > cmp #$a5 ;test result + > trap_ne +21b4 : d0fe > bne * ;failed not equal (non zero) + > +21b6 : 68 > pla ;load status +21b7 : 48 > pha + > cmp_flag 0 +21b8 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21ba : d0fe > bne * ;failed not equal (non zero) + > +21bc : 28 > plp ;restore status + > +21bd : a50c > lda zpt +21bf : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +21c1 : d0fe > bne * ;failed not equal (non zero) + > +21c3 : a900 > lda #0 +21c5 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +21c7 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +21c9 : 48 > pha ;use stack to load status +21ca : a95a > lda #$5a ;precharge accu +21cc : 28 > plp + > +21cd : e70c > smb 6,zpt + > tst_a $5a,$ff +21cf : 08 > php ;save flags +21d0 : c95a > cmp #$5a ;test result + > trap_ne +21d2 : d0fe > bne * ;failed not equal (non zero) + > +21d4 : 68 > pla ;load status +21d5 : 48 > pha + > cmp_flag $ff +21d6 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21d8 : d0fe > bne * ;failed not equal (non zero) + > +21da : 28 > plp ;restore status + > +21db : a50c > lda zpt +21dd : c940 > cmp #1<<6 + > trap_ne ;wrong bits set or cleared +21df : d0fe > bne * ;failed not equal (non zero) + > + + smbt 7 +21e1 : a97f > lda #$ff-(1<<7) +21e3 : 850c > sta zpt + > set_a $a5,0 + > load_flag 0 +21e5 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +21e7 : 48 > pha ;use stack to load status +21e8 : a9a5 > lda #$a5 ;precharge accu +21ea : 28 > plp + > +21eb : f70c > smb 7,zpt + > tst_a $a5,0 +21ed : 08 > php ;save flags +21ee : c9a5 > cmp #$a5 ;test result + > trap_ne +21f0 : d0fe > bne * ;failed not equal (non zero) + > +21f2 : 68 > pla ;load status +21f3 : 48 > pha + > cmp_flag 0 +21f4 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits + > + > trap_ne +21f6 : d0fe > bne * ;failed not equal (non zero) + > +21f8 : 28 > plp ;restore status + > +21f9 : a50c > lda zpt +21fb : c9ff > cmp #$ff + > trap_ne ;wrong bits set or cleared +21fd : d0fe > bne * ;failed not equal (non zero) + > +21ff : a900 > lda #0 +2201 : 850c > sta zpt + > set_a $5a,$ff + > load_flag $ff +2203 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2205 : 48 > pha ;use stack to load status +2206 : a95a > lda #$5a ;precharge accu +2208 : 28 > plp + > +2209 : f70c > smb 7,zpt + > tst_a $5a,$ff +220b : 08 > php ;save flags +220c : c95a > cmp #$5a ;test result + > trap_ne +220e : d0fe > bne * ;failed not equal (non zero) + > +2210 : 68 > pla ;load status +2211 : 48 > pha + > cmp_flag $ff +2212 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2214 : d0fe > bne * ;failed not equal (non zero) + > +2216 : 28 > plp ;restore status + > +2217 : a50c > lda zpt +2219 : c980 > cmp #1<<7 + > trap_ne ;wrong bits set or cleared +221b : d0fe > bne * ;failed not equal (non zero) + > + +221d : e0ba cpx #$ba + trap_ne ;x altered during test +221f : d0fe > bne * ;failed not equal (non zero) + +2221 : c0d0 cpy #$d0 + trap_ne ;y altered during test +2223 : d0fe > bne * ;failed not equal (non zero) + +2225 : ba tsx +2226 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +2228 : d0fe > bne * ;failed not equal (non zero) + + next_test +222a : ad0202 > lda test_case ;previous test +222d : c911 > cmp #test_num + > trap_ne ;test is out of sequence +222f : d0fe > bne * ;failed not equal (non zero) + > +0012 = >test_num = test_num + 1 +2231 : a912 > lda #test_num ;*** next tests' number +2233 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + endif + + ; testing CMP - (zp) +2236 : a2de ldx #$de ;protect x & y +2238 : a0ad ldy #$ad + set_a $80,0 + > load_flag 0 +223a : a900 > lda #0 ;allow test to change I-flag (no mask) + > +223c : 48 > pha ;use stack to load status +223d : a980 > lda #$80 ;precharge accu +223f : 28 > plp + +2240 : d22c cmp (ind1+8) + tst_a $80,fc +2242 : 08 > php ;save flags +2243 : c980 > cmp #$80 ;test result + > trap_ne +2245 : d0fe > bne * ;failed not equal (non zero) + > +2247 : 68 > pla ;load status +2248 : 48 > pha + > cmp_flag fc +2249 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +224b : d0fe > bne * ;failed not equal (non zero) + > +224d : 28 > plp ;restore status + + set_a $7f,0 + > load_flag 0 +224e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2250 : 48 > pha ;use stack to load status +2251 : a97f > lda #$7f ;precharge accu +2253 : 28 > plp + +2254 : d22c cmp (ind1+8) + tst_a $7f,fzc +2256 : 08 > php ;save flags +2257 : c97f > cmp #$7f ;test result + > trap_ne +2259 : d0fe > bne * ;failed not equal (non zero) + > +225b : 68 > pla ;load status +225c : 48 > pha + > cmp_flag fzc +225d : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +225f : d0fe > bne * ;failed not equal (non zero) + > +2261 : 28 > plp ;restore status + + set_a $7e,0 + > load_flag 0 +2262 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2264 : 48 > pha ;use stack to load status +2265 : a97e > lda #$7e ;precharge accu +2267 : 28 > plp + +2268 : d22c cmp (ind1+8) + tst_a $7e,fn +226a : 08 > php ;save flags +226b : c97e > cmp #$7e ;test result + > trap_ne +226d : d0fe > bne * ;failed not equal (non zero) + > +226f : 68 > pla ;load status +2270 : 48 > pha + > cmp_flag fn +2271 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2273 : d0fe > bne * ;failed not equal (non zero) + > +2275 : 28 > plp ;restore status + + set_a $80,$ff + > load_flag $ff +2276 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2278 : 48 > pha ;use stack to load status +2279 : a980 > lda #$80 ;precharge accu +227b : 28 > plp + +227c : d22c cmp (ind1+8) + tst_a $80,~fnz +227e : 08 > php ;save flags +227f : c980 > cmp #$80 ;test result + > trap_ne +2281 : d0fe > bne * ;failed not equal (non zero) + > +2283 : 68 > pla ;load status +2284 : 48 > pha + > cmp_flag ~fnz +2285 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits + > + > trap_ne +2287 : d0fe > bne * ;failed not equal (non zero) + > +2289 : 28 > plp ;restore status + + set_a $7f,$ff + > load_flag $ff +228a : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +228c : 48 > pha ;use stack to load status +228d : a97f > lda #$7f ;precharge accu +228f : 28 > plp + +2290 : d22c cmp (ind1+8) + tst_a $7f,~fn +2292 : 08 > php ;save flags +2293 : c97f > cmp #$7f ;test result + > trap_ne +2295 : d0fe > bne * ;failed not equal (non zero) + > +2297 : 68 > pla ;load status +2298 : 48 > pha + > cmp_flag ~fn +2299 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits + > + > trap_ne +229b : d0fe > bne * ;failed not equal (non zero) + > +229d : 28 > plp ;restore status + + set_a $7e,$ff + > load_flag $ff +229e : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +22a0 : 48 > pha ;use stack to load status +22a1 : a97e > lda #$7e ;precharge accu +22a3 : 28 > plp + +22a4 : d22c cmp (ind1+8) + tst_a $7e,~fzc +22a6 : 08 > php ;save flags +22a7 : c97e > cmp #$7e ;test result + > trap_ne +22a9 : d0fe > bne * ;failed not equal (non zero) + > +22ab : 68 > pla ;load status +22ac : 48 > pha + > cmp_flag ~fzc +22ad : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits + > + > trap_ne +22af : d0fe > bne * ;failed not equal (non zero) + > +22b1 : 28 > plp ;restore status + +22b2 : e0de cpx #$de + trap_ne ;x altered during test +22b4 : d0fe > bne * ;failed not equal (non zero) + +22b6 : c0ad cpy #$ad + trap_ne ;y altered during test +22b8 : d0fe > bne * ;failed not equal (non zero) + +22ba : ba tsx +22bb : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +22bd : d0fe > bne * ;failed not equal (non zero) + + next_test +22bf : ad0202 > lda test_case ;previous test +22c2 : c912 > cmp #test_num + > trap_ne ;test is out of sequence +22c4 : d0fe > bne * ;failed not equal (non zero) + > +0013 = >test_num = test_num + 1 +22c6 : a913 > lda #test_num ;*** next tests' number +22c8 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; testing logical instructions - AND EOR ORA (zp) +22cb : a242 ldx #$42 ;protect x & y + +22cd : a000 ldy #0 ;AND +22cf : a53a lda indAN ;set indirect address +22d1 : 850c sta zpt +22d3 : a53b lda indAN+1 +22d5 : 850d sta zpt+1 +22d7 : tand1 + set_ay absANa,0 + > load_flag 0 +22d7 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +22d9 : 48 > pha ;use stack to load status +22da : b95302 > lda absANa,y ;precharge accu +22dd : 28 > plp + +22de : 320c and (zpt) + tst_ay absrlo,absflo,0 +22e0 : 08 > php ;save flags +22e1 : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +22e4 : d0fe > bne * ;failed not equal (non zero) + > +22e6 : 68 > pla ;load status + > eor_flag 0 +22e7 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +22e9 : d95f02 > cmp absflo,y ;test flags + > trap_ne +22ec : d0fe > bne * ;failed not equal (non zero) + > + +22ee : e60c inc zpt +22f0 : c8 iny +22f1 : c004 cpy #4 +22f3 : d0e2 bne tand1 +22f5 : 88 dey +22f6 : c60c dec zpt +22f8 : tand2 + set_ay absANa,$ff + > load_flag $ff +22f8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +22fa : 48 > pha ;use stack to load status +22fb : b95302 > lda absANa,y ;precharge accu +22fe : 28 > plp + +22ff : 320c and (zpt) + tst_ay absrlo,absflo,$ff-fnz +2301 : 08 > php ;save flags +2302 : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +2305 : d0fe > bne * ;failed not equal (non zero) + > +2307 : 68 > pla ;load status + > eor_flag $ff-fnz +2308 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +230a : d95f02 > cmp absflo,y ;test flags + > trap_ne +230d : d0fe > bne * ;failed not equal (non zero) + > + +230f : c60c dec zpt +2311 : 88 dey +2312 : 10e4 bpl tand2 + +2314 : a000 ldy #0 ;EOR +2316 : a542 lda indEO ;set indirect address +2318 : 850c sta zpt +231a : a543 lda indEO+1 +231c : 850d sta zpt+1 +231e : teor1 + set_ay absEOa,0 + > load_flag 0 +231e : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2320 : 48 > pha ;use stack to load status +2321 : b95702 > lda absEOa,y ;precharge accu +2324 : 28 > plp + +2325 : 520c eor (zpt) + tst_ay absrlo,absflo,0 +2327 : 08 > php ;save flags +2328 : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +232b : d0fe > bne * ;failed not equal (non zero) + > +232d : 68 > pla ;load status + > eor_flag 0 +232e : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2330 : d95f02 > cmp absflo,y ;test flags + > trap_ne +2333 : d0fe > bne * ;failed not equal (non zero) + > + +2335 : e60c inc zpt +2337 : c8 iny +2338 : c004 cpy #4 +233a : d0e2 bne teor1 +233c : 88 dey +233d : c60c dec zpt +233f : teor2 + set_ay absEOa,$ff + > load_flag $ff +233f : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2341 : 48 > pha ;use stack to load status +2342 : b95702 > lda absEOa,y ;precharge accu +2345 : 28 > plp + +2346 : 520c eor (zpt) + tst_ay absrlo,absflo,$ff-fnz +2348 : 08 > php ;save flags +2349 : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +234c : d0fe > bne * ;failed not equal (non zero) + > +234e : 68 > pla ;load status + > eor_flag $ff-fnz +234f : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2351 : d95f02 > cmp absflo,y ;test flags + > trap_ne +2354 : d0fe > bne * ;failed not equal (non zero) + > + +2356 : c60c dec zpt +2358 : 88 dey +2359 : 10e4 bpl teor2 + +235b : a000 ldy #0 ;ORA +235d : a54a lda indOR ;set indirect address +235f : 850c sta zpt +2361 : a54b lda indOR+1 +2363 : 850d sta zpt+1 +2365 : tora1 + set_ay absORa,0 + > load_flag 0 +2365 : a900 > lda #0 ;allow test to change I-flag (no mask) + > +2367 : 48 > pha ;use stack to load status +2368 : b94f02 > lda absORa,y ;precharge accu +236b : 28 > plp + +236c : 120c ora (zpt) + tst_ay absrlo,absflo,0 +236e : 08 > php ;save flags +236f : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +2372 : d0fe > bne * ;failed not equal (non zero) + > +2374 : 68 > pla ;load status + > eor_flag 0 +2375 : 4930 > eor #0|fao ;invert expected flags + always on bits + > +2377 : d95f02 > cmp absflo,y ;test flags + > trap_ne +237a : d0fe > bne * ;failed not equal (non zero) + > + +237c : e60c inc zpt +237e : c8 iny +237f : c004 cpy #4 +2381 : d0e2 bne tora1 +2383 : 88 dey +2384 : c60c dec zpt +2386 : tora2 + set_ay absORa,$ff + > load_flag $ff +2386 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +2388 : 48 > pha ;use stack to load status +2389 : b94f02 > lda absORa,y ;precharge accu +238c : 28 > plp + +238d : 120c ora (zpt) + tst_ay absrlo,absflo,$ff-fnz +238f : 08 > php ;save flags +2390 : d95b02 > cmp absrlo,y ;test result + > trap_ne ; +2393 : d0fe > bne * ;failed not equal (non zero) + > +2395 : 68 > pla ;load status + > eor_flag $ff-fnz +2396 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits + > +2398 : d95f02 > cmp absflo,y ;test flags + > trap_ne +239b : d0fe > bne * ;failed not equal (non zero) + > + +239d : c60c dec zpt +239f : 88 dey +23a0 : 10e4 bpl tora2 + +23a2 : e042 cpx #$42 + trap_ne ;x altered during test +23a4 : d0fe > bne * ;failed not equal (non zero) + +23a6 : ba tsx +23a7 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +23a9 : d0fe > bne * ;failed not equal (non zero) + + next_test +23ab : ad0202 > lda test_case ;previous test +23ae : c913 > cmp #test_num + > trap_ne ;test is out of sequence +23b0 : d0fe > bne * ;failed not equal (non zero) + > +0014 = >test_num = test_num + 1 +23b2 : a914 > lda #test_num ;*** next tests' number +23b4 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + if I_flag = 3 +23b7 : 58 cli + endif + + ; full binary add/subtract test - (zp) only + ; iterates through all combinations of operands and carry input + ; uses increments/decrements to predict result & result flags +23b8 : d8 cld +23b9 : a20e ldx #ad2 ;for indexed test +23bb : a0ff ldy #$ff ;max range +23bd : a900 lda #0 ;start with adding zeroes & no carry +23bf : 850c sta adfc ;carry in - for diag +23c1 : 850d sta ad1 ;operand 1 - accumulator +23c3 : 850e sta ad2 ;operand 2 - memory or immediate +23c5 : 8d0502 sta ada2 ;non zp +23c8 : 850f sta adrl ;expected result bits 0-7 +23ca : 8510 sta adrh ;expected result bit 8 (carry out) +23cc : a9ff lda #$ff ;complemented operand 2 for subtract +23ce : 8512 sta sb2 +23d0 : 8d0602 sta sba2 ;non zp +23d3 : a902 lda #2 ;expected Z-flag +23d5 : 8511 sta adrf +23d7 : 18 tadd clc ;test with carry clear +23d8 : 204e26 jsr chkadd +23db : e60c inc adfc ;now with carry +23dd : e60f inc adrl ;result +1 +23df : 08 php ;save N & Z from low result +23e0 : 08 php +23e1 : 68 pla ;accu holds expected flags +23e2 : 2982 and #$82 ;mask N & Z +23e4 : 28 plp +23e5 : d002 bne tadd1 +23e7 : e610 inc adrh ;result bit 8 - carry +23e9 : 0510 tadd1 ora adrh ;merge C to expected flags +23eb : 8511 sta adrf ;save expected flags except overflow +23ed : 38 sec ;test with carry set +23ee : 204e26 jsr chkadd +23f1 : c60c dec adfc ;same for operand +1 but no carry +23f3 : e60d inc ad1 +23f5 : d0e0 bne tadd ;iterate op1 +23f7 : a900 lda #0 ;preset result to op2 when op1 = 0 +23f9 : 8510 sta adrh +23fb : ee0502 inc ada2 +23fe : e60e inc ad2 +2400 : 08 php ;save NZ as operand 2 becomes the new result +2401 : 68 pla +2402 : 2982 and #$82 ;mask N00000Z0 +2404 : 8511 sta adrf ;no need to check carry as we are adding to 0 +2406 : c612 dec sb2 ;complement subtract operand 2 +2408 : ce0602 dec sba2 +240b : a50e lda ad2 +240d : 850f sta adrl +240f : d0c6 bne tadd ;iterate op2 + +2411 : e00e cpx #ad2 + trap_ne ;x altered during test +2413 : d0fe > bne * ;failed not equal (non zero) + +2415 : c0ff cpy #$ff + trap_ne ;y altered during test +2417 : d0fe > bne * ;failed not equal (non zero) + +2419 : ba tsx +241a : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +241c : d0fe > bne * ;failed not equal (non zero) + + next_test +241e : ad0202 > lda test_case ;previous test +2421 : c914 > cmp #test_num + > trap_ne ;test is out of sequence +2423 : d0fe > bne * ;failed not equal (non zero) + > +0015 = >test_num = test_num + 1 +2425 : a915 > lda #test_num ;*** next tests' number +2427 : 8d0202 > sta test_case + > ;check_ram ;uncomment to find altered RAM after each test + + + ; decimal add/subtract test + ; *** WARNING - tests documented behavior only! *** + ; only valid BCD operands are tested, the V flag is ignored + ; although V is declared as beeing valid on the 65C02 it has absolutely + ; no use in BCD math. No sign = no overflow! + ; iterates through all valid combinations of operands and carry input + ; uses increments/decrements to predict result & carry flag +242a : f8 sed +242b : a20e ldx #ad2 ;for indexed test +242d : a0ff ldy #$ff ;max range +242f : a999 lda #$99 ;start with adding 99 to 99 with carry +2431 : 850d sta ad1 ;operand 1 - accumulator +2433 : 850e sta ad2 ;operand 2 - memory or immediate +2435 : 8d0502 sta ada2 ;non zp +2438 : 850f sta adrl ;expected result bits 0-7 +243a : a901 lda #1 ;set carry in & out +243c : 850c sta adfc ;carry in - for diag +243e : 8510 sta adrh ;expected result bit 8 (carry out) +2440 : a981 lda #$81 ;set N & C (99 + 99 + C = 99 + C) +2442 : 8511 sta adrf +2444 : a900 lda #0 ;complemented operand 2 for subtract +2446 : 8512 sta sb2 +2448 : 8d0602 sta sba2 ;non zp +244b : 38 tdad sec ;test with carry set +244c : 20f724 jsr chkdad +244f : c60c dec adfc ;now with carry clear +2451 : a50f lda adrl ;decimal adjust result +2453 : d008 bne tdad1 ;skip clear carry & preset result 99 (9A-1) +2455 : c610 dec adrh +2457 : a999 lda #$99 +2459 : 850f sta adrl +245b : d012 bne tdad3 +245d : 290f tdad1 and #$f ;lower nibble mask +245f : d00c bne tdad2 ;no decimal adjust needed +2461 : c60f dec adrl ;decimal adjust (?0-6) +2463 : c60f dec adrl +2465 : c60f dec adrl +2467 : c60f dec adrl +2469 : c60f dec adrl +246b : c60f dec adrl +246d : c60f tdad2 dec adrl ;result -1 +246f : 08 tdad3 php ;save valid flags +2470 : 68 pla +2471 : 2982 and #$82 ;N-----Z- +2473 : 0510 ora adrh ;N-----ZC +2475 : 8511 sta adrf +2477 : 18 clc ;test with carry clear +2478 : 20f724 jsr chkdad +247b : e60c inc adfc ;same for operand -1 but with carry +247d : a50d lda ad1 ;decimal adjust operand 1 +247f : f015 beq tdad5 ;iterate operand 2 +2481 : 290f and #$f ;lower nibble mask +2483 : d00c bne tdad4 ;skip decimal adjust +2485 : c60d dec ad1 ;decimal adjust (?0-6) +2487 : c60d dec ad1 +2489 : c60d dec ad1 +248b : c60d dec ad1 +248d : c60d dec ad1 +248f : c60d dec ad1 +2491 : c60d tdad4 dec ad1 ;operand 1 -1 +2493 : 4c4b24 jmp tdad ;iterate op1 + +2496 : a999 tdad5 lda #$99 ;precharge op1 max +2498 : 850d sta ad1 +249a : a50e lda ad2 ;decimal adjust operand 2 +249c : f039 beq tdad7 ;end of iteration +249e : 290f and #$f ;lower nibble mask +24a0 : d018 bne tdad6 ;skip decimal adjust +24a2 : c60e dec ad2 ;decimal adjust (?0-6) +24a4 : c60e dec ad2 +24a6 : c60e dec ad2 +24a8 : c60e dec ad2 +24aa : c60e dec ad2 +24ac : c60e dec ad2 +24ae : e612 inc sb2 ;complemented decimal adjust for subtract (?9+6) +24b0 : e612 inc sb2 +24b2 : e612 inc sb2 +24b4 : e612 inc sb2 +24b6 : e612 inc sb2 +24b8 : e612 inc sb2 +24ba : c60e tdad6 dec ad2 ;operand 2 -1 +24bc : e612 inc sb2 ;complemented operand for subtract +24be : a512 lda sb2 +24c0 : 8d0602 sta sba2 ;copy as non zp operand +24c3 : a50e lda ad2 +24c5 : 8d0502 sta ada2 ;copy as non zp operand +24c8 : 850f sta adrl ;new result since op1+carry=00+carry +op2=op2 +24ca : 08 php ;save flags +24cb : 68 pla +24cc : 2982 and #$82 ;N-----Z- +24ce : 0901 ora #1 ;N-----ZC +24d0 : 8511 sta adrf +24d2 : e610 inc adrh ;result carry +24d4 : 4c4b24 jmp tdad ;iterate op2 + +24d7 : e00e tdad7 cpx #ad2 + trap_ne ;x altered during test +24d9 : d0fe > bne * ;failed not equal (non zero) + +24db : c0ff cpy #$ff + trap_ne ;y altered during test +24dd : d0fe > bne * ;failed not equal (non zero) + +24df : ba tsx +24e0 : e0ff cpx #$ff + trap_ne ;sp push/pop mismatch +24e2 : d0fe > bne * ;failed not equal (non zero) + +24e4 : d8 cld + +24e5 : ad0202 lda test_case +24e8 : c915 cmp #test_num + trap_ne ;previous test is out of sequence +24ea : d0fe > bne * ;failed not equal (non zero) + +24ec : a9f0 lda #$f0 ;mark opcode testing complete +24ee : 8d0202 sta test_case + + ; final RAM integrity test + ; verifies that none of the previous tests has altered RAM outside of the + ; designated write areas. + check_ram + > ;RAM check disabled - RAM size not set + + ; *** DEBUG INFO *** + ; to debug checksum errors uncomment check_ram in the next_test macro to + ; narrow down the responsible opcode. + ; may give false errors when monitor, OS or other background activity is + ; allowed during previous tests. + + + ; S U C C E S S ************************************************ + ; ------------- + success ;if you get here everything went well +24f1 : 4cf124 > jmp * ;test passed, no errors + + ; ------------- + ; S U C C E S S ************************************************ +24f4 : 4c0004 jmp start ;run again + + ; core subroutine of the decimal add/subtract test + ; *** WARNING - tests documented behavior only! *** + ; only valid BCD operands are tested, V flag is ignored + ; iterates through all valid combinations of operands and carry input + ; uses increments/decrements to predict result & carry flag +24f7 : chkdad + ; decimal ADC / SBC zp +24f7 : 08 php ;save carry for subtract +24f8 : a50d lda ad1 +24fa : 650e adc ad2 ;perform add +24fc : 08 php +24fd : c50f cmp adrl ;check result + trap_ne ;bad result +24ff : d0fe > bne * ;failed not equal (non zero) + +2501 : 68 pla ;check flags +2502 : 2983 and #$83 ;mask N-----ZC +2504 : c511 cmp adrf + trap_ne ;bad flags +2506 : d0fe > bne * ;failed not equal (non zero) + +2508 : 28 plp +2509 : 08 php ;save carry for next add +250a : a50d lda ad1 +250c : e512 sbc sb2 ;perform subtract +250e : 08 php +250f : c50f cmp adrl ;check result + trap_ne ;bad result +2511 : d0fe > bne * ;failed not equal (non zero) + +2513 : 68 pla ;check flags +2514 : 2983 and #$83 ;mask N-----ZC +2516 : c511 cmp adrf + trap_ne ;bad flags +2518 : d0fe > bne * ;failed not equal (non zero) + +251a : 28 plp + ; decimal ADC / SBC abs +251b : 08 php ;save carry for subtract +251c : a50d lda ad1 +251e : 6d0502 adc ada2 ;perform add +2521 : 08 php +2522 : c50f cmp adrl ;check result + trap_ne ;bad result +2524 : d0fe > bne * ;failed not equal (non zero) + +2526 : 68 pla ;check flags +2527 : 2983 and #$83 ;mask N-----ZC +2529 : c511 cmp adrf + trap_ne ;bad flags +252b : d0fe > bne * ;failed not equal (non zero) + +252d : 28 plp +252e : 08 php ;save carry for next add +252f : a50d lda ad1 +2531 : ed0602 sbc sba2 ;perform subtract +2534 : 08 php +2535 : c50f cmp adrl ;check result + trap_ne ;bad result +2537 : d0fe > bne * ;failed not equal (non zero) + +2539 : 68 pla ;check flags +253a : 2983 and #$83 ;mask N-----ZC +253c : c511 cmp adrf + trap_ne ;bad flags +253e : d0fe > bne * ;failed not equal (non zero) + +2540 : 28 plp + ; decimal ADC / SBC # +2541 : 08 php ;save carry for subtract +2542 : a50e lda ad2 +2544 : 8d0b02 sta ex_adci+1 ;set ADC # operand +2547 : a50d lda ad1 +2549 : 200a02 jsr ex_adci ;execute ADC # in RAM +254c : 08 php +254d : c50f cmp adrl ;check result + trap_ne ;bad result +254f : d0fe > bne * ;failed not equal (non zero) + +2551 : 68 pla ;check flags +2552 : 2983 and #$83 ;mask N-----ZC +2554 : c511 cmp adrf + trap_ne ;bad flags +2556 : d0fe > bne * ;failed not equal (non zero) + +2558 : 28 plp +2559 : 08 php ;save carry for next add +255a : a512 lda sb2 +255c : 8d0e02 sta ex_sbci+1 ;set SBC # operand +255f : a50d lda ad1 +2561 : 200d02 jsr ex_sbci ;execute SBC # in RAM +2564 : 08 php +2565 : c50f cmp adrl ;check result + trap_ne ;bad result +2567 : d0fe > bne * ;failed not equal (non zero) + +2569 : 68 pla ;check flags +256a : 2983 and #$83 ;mask N-----ZC +256c : c511 cmp adrf + trap_ne ;bad flags +256e : d0fe > bne * ;failed not equal (non zero) + +2570 : 28 plp + ; decimal ADC / SBC zp,x +2571 : 08 php ;save carry for subtract +2572 : a50d lda ad1 +2574 : 7500 adc 0,x ;perform add +2576 : 08 php +2577 : c50f cmp adrl ;check result + trap_ne ;bad result +2579 : d0fe > bne * ;failed not equal (non zero) + +257b : 68 pla ;check flags +257c : 2983 and #$83 ;mask N-----ZC +257e : c511 cmp adrf + trap_ne ;bad flags +2580 : d0fe > bne * ;failed not equal (non zero) + +2582 : 28 plp +2583 : 08 php ;save carry for next add +2584 : a50d lda ad1 +2586 : f504 sbc sb2-ad2,x ;perform subtract +2588 : 08 php +2589 : c50f cmp adrl ;check result + trap_ne ;bad result +258b : d0fe > bne * ;failed not equal (non zero) + +258d : 68 pla ;check flags +258e : 2983 and #$83 ;mask N-----ZC +2590 : c511 cmp adrf + trap_ne ;bad flags +2592 : d0fe > bne * ;failed not equal (non zero) + +2594 : 28 plp + ; decimal ADC / SBC abs,x +2595 : 08 php ;save carry for subtract +2596 : a50d lda ad1 +2598 : 7df701 adc ada2-ad2,x ;perform add +259b : 08 php +259c : c50f cmp adrl ;check result + trap_ne ;bad result +259e : d0fe > bne * ;failed not equal (non zero) + +25a0 : 68 pla ;check flags +25a1 : 2983 and #$83 ;mask N-----ZC +25a3 : c511 cmp adrf + trap_ne ;bad flags +25a5 : d0fe > bne * ;failed not equal (non zero) + +25a7 : 28 plp +25a8 : 08 php ;save carry for next add +25a9 : a50d lda ad1 +25ab : fdf801 sbc sba2-ad2,x ;perform subtract +25ae : 08 php +25af : c50f cmp adrl ;check result + trap_ne ;bad result +25b1 : d0fe > bne * ;failed not equal (non zero) + +25b3 : 68 pla ;check flags +25b4 : 2983 and #$83 ;mask N-----ZC +25b6 : c511 cmp adrf + trap_ne ;bad flags +25b8 : d0fe > bne * ;failed not equal (non zero) + +25ba : 28 plp + ; decimal ADC / SBC abs,y +25bb : 08 php ;save carry for subtract +25bc : a50d lda ad1 +25be : 790601 adc ada2-$ff,y ;perform add +25c1 : 08 php +25c2 : c50f cmp adrl ;check result + trap_ne ;bad result +25c4 : d0fe > bne * ;failed not equal (non zero) + +25c6 : 68 pla ;check flags +25c7 : 2983 and #$83 ;mask N-----ZC +25c9 : c511 cmp adrf + trap_ne ;bad flags +25cb : d0fe > bne * ;failed not equal (non zero) + +25cd : 28 plp +25ce : 08 php ;save carry for next add +25cf : a50d lda ad1 +25d1 : f90701 sbc sba2-$ff,y ;perform subtract +25d4 : 08 php +25d5 : c50f cmp adrl ;check result + trap_ne ;bad result +25d7 : d0fe > bne * ;failed not equal (non zero) + +25d9 : 68 pla ;check flags +25da : 2983 and #$83 ;mask N-----ZC +25dc : c511 cmp adrf + trap_ne ;bad flags +25de : d0fe > bne * ;failed not equal (non zero) + +25e0 : 28 plp + ; decimal ADC / SBC (zp,x) +25e1 : 08 php ;save carry for subtract +25e2 : a50d lda ad1 +25e4 : 6144 adc (lo adi2-ad2,x) ;perform add +25e6 : 08 php +25e7 : c50f cmp adrl ;check result + trap_ne ;bad result +25e9 : d0fe > bne * ;failed not equal (non zero) + +25eb : 68 pla ;check flags +25ec : 2983 and #$83 ;mask N-----ZC +25ee : c511 cmp adrf + trap_ne ;bad flags +25f0 : d0fe > bne * ;failed not equal (non zero) + +25f2 : 28 plp +25f3 : 08 php ;save carry for next add +25f4 : a50d lda ad1 +25f6 : e146 sbc (lo sbi2-ad2,x) ;perform subtract +25f8 : 08 php +25f9 : c50f cmp adrl ;check result + trap_ne ;bad result +25fb : d0fe > bne * ;failed not equal (non zero) + +25fd : 68 pla ;check flags +25fe : 2983 and #$83 ;mask N-----ZC +2600 : c511 cmp adrf + trap_ne ;bad flags +2602 : d0fe > bne * ;failed not equal (non zero) + +2604 : 28 plp + ; decimal ADC / SBC (abs),y +2605 : 08 php ;save carry for subtract +2606 : a50d lda ad1 +2608 : 7156 adc (adiy2),y ;perform add +260a : 08 php +260b : c50f cmp adrl ;check result + trap_ne ;bad result +260d : d0fe > bne * ;failed not equal (non zero) + +260f : 68 pla ;check flags +2610 : 2983 and #$83 ;mask N-----ZC +2612 : c511 cmp adrf + trap_ne ;bad flags +2614 : d0fe > bne * ;failed not equal (non zero) + +2616 : 28 plp +2617 : 08 php ;save carry for next add +2618 : a50d lda ad1 +261a : f158 sbc (sbiy2),y ;perform subtract +261c : 08 php +261d : c50f cmp adrl ;check result + trap_ne ;bad result +261f : d0fe > bne * ;failed not equal (non zero) + +2621 : 68 pla ;check flags +2622 : 2983 and #$83 ;mask N-----ZC +2624 : c511 cmp adrf + trap_ne ;bad flags +2626 : d0fe > bne * ;failed not equal (non zero) + +2628 : 28 plp + ; decimal ADC / SBC (zp) +2629 : 08 php ;save carry for subtract +262a : a50d lda ad1 +262c : 7252 adc (adi2) ;perform add +262e : 08 php +262f : c50f cmp adrl ;check result + trap_ne ;bad result +2631 : d0fe > bne * ;failed not equal (non zero) + +2633 : 68 pla ;check flags +2634 : 2983 and #$83 ;mask N-----ZC +2636 : c511 cmp adrf + trap_ne ;bad flags +2638 : d0fe > bne * ;failed not equal (non zero) + +263a : 28 plp +263b : 08 php ;save carry for next add +263c : a50d lda ad1 +263e : f254 sbc (sbi2) ;perform subtract +2640 : 08 php +2641 : c50f cmp adrl ;check result + trap_ne ;bad result +2643 : d0fe > bne * ;failed not equal (non zero) + +2645 : 68 pla ;check flags +2646 : 2983 and #$83 ;mask N-----ZC +2648 : c511 cmp adrf + trap_ne ;bad flags +264a : d0fe > bne * ;failed not equal (non zero) + +264c : 28 plp +264d : 60 rts + + ; core subroutine of the full binary add/subtract test + ; iterates through all combinations of operands and carry input + ; uses increments/decrements to predict result & result flags +264e : a511 chkadd lda adrf ;add V-flag if overflow +2650 : 2983 and #$83 ;keep N-----ZC / clear V +2652 : 48 pha +2653 : a50d lda ad1 ;test sign unequal between operands +2655 : 450e eor ad2 +2657 : 300a bmi ckad1 ;no overflow possible - operands have different sign +2659 : a50d lda ad1 ;test sign equal between operands and result +265b : 450f eor adrl +265d : 1004 bpl ckad1 ;no overflow occured - operand and result have same sign +265f : 68 pla +2660 : 0940 ora #$40 ;set V +2662 : 48 pha +2663 : 68 ckad1 pla +2664 : 8511 sta adrf ;save expected flags + ; binary ADC / SBC (zp) +2666 : 08 php ;save carry for subtract +2667 : a50d lda ad1 +2669 : 7252 adc (adi2) ;perform add +266b : 08 php +266c : c50f cmp adrl ;check result + trap_ne ;bad result +266e : d0fe > bne * ;failed not equal (non zero) + +2670 : 68 pla ;check flags +2671 : 29c3 and #$c3 ;mask NV----ZC +2673 : c511 cmp adrf + trap_ne ;bad flags +2675 : d0fe > bne * ;failed not equal (non zero) + +2677 : 28 plp +2678 : 08 php ;save carry for next add +2679 : a50d lda ad1 +267b : f254 sbc (sbi2) ;perform subtract +267d : 08 php +267e : c50f cmp adrl ;check result + trap_ne ;bad result +2680 : d0fe > bne * ;failed not equal (non zero) + +2682 : 68 pla ;check flags +2683 : 29c3 and #$c3 ;mask NV----ZC +2685 : c511 cmp adrf + trap_ne ;bad flags +2687 : d0fe > bne * ;failed not equal (non zero) + +2689 : 28 plp +268a : 60 rts + + ; target for the jump indirect test +268b : 9126 ji_adr dw test_ji +268d : 8216 dw ji_ret + +268f : 88 dey +2690 : 88 dey +2691 : test_ji +2691 : 08 php ;either SP or Y count will fail, if we do not hit +2692 : 88 dey +2693 : 88 dey +2694 : 88 dey +2695 : 28 plp + trap_cs ;flags loaded? +2696 : b0fe > bcs * ;failed carry set + + trap_vs +2698 : 70fe > bvs * ;failed overflow set + + trap_mi +269a : 30fe > bmi * ;failed minus (bit 7 set) + + trap_eq +269c : f0fe > beq * ;failed equal (zero) + +269e : c949 cmp #'I' ;registers loaded? + trap_ne +26a0 : d0fe > bne * ;failed not equal (non zero) + +26a2 : e04e cpx #'N' + trap_ne +26a4 : d0fe > bne * ;failed not equal (non zero) + +26a6 : c041 cpy #('D'-3) + trap_ne +26a8 : d0fe > bne * ;failed not equal (non zero) + +26aa : 48 pha ;save a,x +26ab : 8a txa +26ac : 48 pha +26ad : ba tsx +26ae : e0fd cpx #$fd ;check SP + trap_ne +26b0 : d0fe > bne * ;failed not equal (non zero) + +26b2 : 68 pla ;restore x +26b3 : aa tax + set_stat $ff + > load_flag $ff +26b4 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +26b6 : 48 > pha ;use stack to load status +26b7 : 28 > plp + +26b8 : 68 pla ;restore a +26b9 : e8 inx ;return registers with modifications +26ba : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 +26bc : 6cff02 jmp (ji_tab+2) +26bf : ea nop +26c0 : ea nop + trap ;runover protection +26c1 : 4cc126 > jmp * ;failed anyway + +26c4 : 4c0004 jmp start ;catastrophic error - cannot continue + + ; target for the jump indirect test +26c7 : 0e27 jxi_adr dw trap_ind +26c9 : 0e27 dw trap_ind +26cb : d526 dw test_jxi ;+4 +26cd : ce16 dw jxi_ret ;+6 +26cf : 0e27 dw trap_ind +26d1 : 0e27 dw trap_ind + +26d3 : 88 dey +26d4 : 88 dey +26d5 : test_jxi +26d5 : 08 php ;either SP or Y count will fail, if we do not hit +26d6 : 88 dey +26d7 : 88 dey +26d8 : 88 dey +26d9 : 28 plp + trap_cs ;flags loaded? +26da : b0fe > bcs * ;failed carry set + + trap_vs +26dc : 70fe > bvs * ;failed overflow set + + trap_mi +26de : 30fe > bmi * ;failed minus (bit 7 set) + + trap_eq +26e0 : f0fe > beq * ;failed equal (zero) + +26e2 : c958 cmp #'X' ;registers loaded? + trap_ne +26e4 : d0fe > bne * ;failed not equal (non zero) + +26e6 : e004 cpx #4 + trap_ne +26e8 : d0fe > bne * ;failed not equal (non zero) + +26ea : c046 cpy #('I'-3) + trap_ne +26ec : d0fe > bne * ;failed not equal (non zero) + +26ee : 48 pha ;save a,x +26ef : 8a txa +26f0 : 48 pha +26f1 : ba tsx +26f2 : e0fd cpx #$fd ;check SP + trap_ne +26f4 : d0fe > bne * ;failed not equal (non zero) + +26f6 : 68 pla ;restore x +26f7 : aa tax + set_stat $ff + > load_flag $ff +26f8 : a9ff > lda #$ff ;allow test to change I-flag (no mask) + > +26fa : 48 > pha ;use stack to load status +26fb : 28 > plp + +26fc : 68 pla ;restore a +26fd : e8 inx ;return registers with modifications +26fe : e8 inx +26ff : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 +2701 : 7cf902 jmp (jxi_tab,x) +2704 : ea nop +2705 : ea nop + trap ;runover protection +2706 : 4c0627 > jmp * ;failed anyway + +2709 : 4c0004 jmp start ;catastrophic error - cannot continue + + ; JMP (abs,x) with bad x +270c : ea nop +270d : ea nop +270e : trap_ind +270e : ea nop +270f : ea nop + trap ;near miss indexed indirect jump +2710 : 4c1027 > jmp * ;failed anyway + +2713 : 4c0004 jmp start ;catastrophic error - cannot continue + + ;trap in case of unexpected IRQ, NMI, BRK, RESET +2716 : nmi_trap + trap ;check stack for conditions at NMI +2716 : 4c1627 > jmp * ;failed anyway + +2719 : 4c0004 jmp start ;catastrophic error - cannot continue +271c : res_trap + trap ;unexpected RESET +271c : 4c1c27 > jmp * ;failed anyway + +271f : 4c0004 jmp start ;catastrophic error - cannot continue + +2722 : 88 dey +2723 : 88 dey +2724 : irq_trap ;BRK test or unextpected BRK or IRQ +2724 : 08 php ;either SP or Y count will fail, if we do not hit +2725 : 88 dey +2726 : 88 dey +2727 : 88 dey + ;next traps could be caused by unexpected BRK or IRQ + ;check stack for BREAK and originating location + ;possible jump/branch into weeds (uninitialized space) +2728 : c9bd cmp #$ff-'B' ;BRK pass 2 registers loaded? +272a : f042 beq break2 +272c : c942 cmp #'B' ;BRK pass 1 registers loaded? + trap_ne +272e : d0fe > bne * ;failed not equal (non zero) + +2730 : e052 cpx #'R' + trap_ne +2732 : d0fe > bne * ;failed not equal (non zero) + +2734 : c048 cpy #'K'-3 + trap_ne +2736 : d0fe > bne * ;failed not equal (non zero) + +2738 : 850a sta irq_a ;save registers during break test +273a : 860b stx irq_x +273c : ba tsx ;test break on stack +273d : bd0201 lda $102,x + cmp_flag 0 ;break test should have B=1 & unused=1 on stack +2740 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits + + trap_ne ;possible no break flag on stack +2742 : d0fe > bne * ;failed not equal (non zero) + +2744 : 68 pla + cmp_flag intdis ;should have added interrupt disable +2745 : c934 > cmp #(intdis |fao)&m8 ;expected flags + always on bits + + trap_ne +2747 : d0fe > bne * ;failed not equal (non zero) + +2749 : ba tsx +274a : e0fc cpx #$fc ;sp -3? (return addr, flags) + trap_ne +274c : d0fe > bne * ;failed not equal (non zero) + +274e : adff01 lda $1ff ;propper return on stack +2751 : c917 cmp #hi(brk_ret0) + trap_ne +2753 : d0fe > bne * ;failed not equal (non zero) + +2755 : adfe01 lda $1fe +2758 : c920 cmp #lo(brk_ret0) + trap_ne +275a : d0fe > bne * ;failed not equal (non zero) + + load_flag $ff +275c : a9ff > lda #$ff ;allow test to change I-flag (no mask) + +275e : 48 pha +275f : a60b ldx irq_x +2761 : e8 inx ;return registers with modifications +2762 : a50a lda irq_a +2764 : 49aa eor #$aa +2766 : 28 plp ;N=1, V=1, Z=1, C=1 but original flags should be restored +2767 : 40 rti + trap ;runover protection +2768 : 4c6827 > jmp * ;failed anyway + +276b : 4c0004 jmp start ;catastrophic error - cannot continue + +276e : break2 ;BRK pass 2 +276e : e0ad cpx #$ff-'R' + trap_ne +2770 : d0fe > bne * ;failed not equal (non zero) + +2772 : c0b1 cpy #$ff-'K'-3 + trap_ne +2774 : d0fe > bne * ;failed not equal (non zero) + +2776 : 850a sta irq_a ;save registers during break test +2778 : 860b stx irq_x +277a : ba tsx ;test break on stack +277b : bd0201 lda $102,x + cmp_flag $ff ;break test should have B=1 +277e : c9ff > cmp #($ff |fao)&m8 ;expected flags + always on bits + + trap_ne ;possibly no break flag on stack +2780 : d0fe > bne * ;failed not equal (non zero) + +2782 : 68 pla + cmp_flag $ff-decmode ;actual passed flags should have decmode cleared +2783 : c9f7 > cmp #($ff-decmode |fao)&m8 ;expected flags + always on bits + + trap_ne +2785 : d0fe > bne * ;failed not equal (non zero) + +2787 : ba tsx +2788 : e0fc cpx #$fc ;sp -3? (return addr, flags) + trap_ne +278a : d0fe > bne * ;failed not equal (non zero) + +278c : adff01 lda $1ff ;propper return on stack +278f : c917 cmp #hi(brk_ret1) + trap_ne +2791 : d0fe > bne * ;failed not equal (non zero) + +2793 : adfe01 lda $1fe +2796 : c946 cmp #lo(brk_ret1) + trap_ne +2798 : d0fe > bne * ;failed not equal (non zero) + + load_flag intdis +279a : a904 > lda #intdis ;allow test to change I-flag (no mask) + +279c : 48 pha +279d : a60b ldx irq_x +279f : e8 inx ;return registers with modifications +27a0 : a50a lda irq_a +27a2 : 49aa eor #$aa +27a4 : 28 plp ;N=0, V=0, Z=0, C=0 but original flags should be restored +27a5 : 40 rti + trap ;runover protection +27a6 : 4ca627 > jmp * ;failed anyway + +27a9 : 4c0004 jmp start ;catastrophic error - cannot continue + + if report = 1 + include "report.i65" + endif + + ;copy of data to initialize BSS segment + if load_data_direct != 1 + zp_init + zp1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR + zp7f_ db $7f ;test pattern for compare + ;logical zeropage operands + zpOR_ db 0,$1f,$71,$80 ;test pattern for OR + zpAN_ db $0f,$ff,$7f,$80 ;test pattern for AND + zpEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR + ;indirect addressing pointers + ind1_ dw abs1 ;indirect pointer to pattern in absolute memory + dw abs1+1 + dw abs1+2 + dw abs1+3 + dw abs7f + inw1_ dw abs1-$f8 ;indirect pointer for wrap-test pattern + indt_ dw abst ;indirect pointer to store area in absolute memory + dw abst+1 + dw abst+2 + dw abst+3 + inwt_ dw abst-$f8 ;indirect pointer for wrap-test store + indAN_ dw absAN ;indirect pointer to AND pattern in absolute memory + dw absAN+1 + dw absAN+2 + dw absAN+3 + indEO_ dw absEO ;indirect pointer to EOR pattern in absolute memory + dw absEO+1 + dw absEO+2 + dw absEO+3 + indOR_ dw absOR ;indirect pointer to OR pattern in absolute memory + dw absOR+1 + dw absOR+2 + dw absOR+3 + ;add/subtract indirect pointers + adi2_ dw ada2 ;indirect pointer to operand 2 in absolute memory + sbi2_ dw sba2 ;indirect pointer to complemented operand 2 (SBC) + adiy2_ dw ada2-$ff ;with offset for indirect indexed + sbiy2_ dw sba2-$ff + zp_end + if (zp_end - zp_init) != (zp_bss_end - zp_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and zeropage data + endif + data_init + ex_adc_ adc #0 ;execute immediate opcodes + rts + ex_sbc_ sbc #0 ;execute immediate opcodes + rts + abs1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR + abs7f_ db $7f ;test pattern for compare + ;loads + fLDx_ db fn,fn,0,fz ;expected flags for load + ;shifts + rASL_ ;expected result ASL & ROL -carry + rROL_ db $86,$04,$82,0 ; " + rROLc_ db $87,$05,$83,1 ;expected result ROL +carry + rLSR_ ;expected result LSR & ROR -carry + rROR_ db $61,$41,$20,0 ; " + rRORc_ db $e1,$c1,$a0,$80 ;expected result ROR +carry + fASL_ ;expected flags for shifts + fROL_ db fnc,fc,fn,fz ;no carry in + fROLc_ db fnc,fc,fn,0 ;carry in + fLSR_ + fROR_ db fc,0,fc,fz ;no carry in + fRORc_ db fnc,fn,fnc,fn ;carry in + ;increments (decrements) + rINC_ db $7f,$80,$ff,0,1 ;expected result for INC/DEC + fINC_ db 0,fn,fn,fz,0 ;expected flags for INC/DEC + ;logical memory operand + absOR_ db 0,$1f,$71,$80 ;test pattern for OR + absAN_ db $0f,$ff,$7f,$80 ;test pattern for AND + absEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR + ;logical accu operand + absORa_ db 0,$f1,$1f,0 ;test pattern for OR + absANa_ db $f0,$ff,$ff,$ff ;test pattern for AND + absEOa_ db $ff,$f0,$f0,$0f ;test pattern for EOR + ;logical results + absrlo_ db 0,$ff,$7f,$80 + absflo_ db fz,fn,0,fn + data_end + if (data_end - data_init) != (data_bss_end - data_bss) + ;force assembler error if size is different + ERROR ERROR ERROR ;mismatch between bss and data + endif + + vec_init + dw nmi_trap + dw res_trap + dw irq_trap + vec_bss equ $fffa + endif ;end of RAM init data + + ; code at end of image due to the need to add blank space as required + if ($ff & (ji_ret - * - 2)) < ($ff & (jxi_ret - * - 2)) + ; JMP (abs) when $xxff and $xx00 are from same page + ds lo(ji_ret - * - 2) + nop + nop + ji_px nop ;low address byte matched with ji_ret + nop + trap ;jmp indirect page cross bug + + ; JMP (abs,x) when $xxff and $xx00 are from same page + ds lo(jxi_ret - * - 2) + nop + nop + jxi_px nop ;low address byte matched with jxi_ret + nop + trap ;jmp indexed indirect page cross bug + else + ; JMP (abs,x) when $xxff and $xx00 are from same page +27ac : 00000000000000.. ds lo(jxi_ret - * - 2) +27cc : ea nop +27cd : ea nop +27ce : ea jxi_px nop ;low address byte matched with jxi_ret +27cf : ea nop + trap ;jmp indexed indirect page cross bug +27d0 : 4cd027 > jmp * ;failed anyway + + + ; JMP (abs) when $xxff and $xx00 are from same page +27d3 : 00000000000000.. ds lo(ji_ret - * - 2) +2880 : ea nop +2881 : ea nop +2882 : ea ji_px nop ;low address byte matched with ji_ret +2883 : ea nop + trap ;jmp indirect page cross bug +2884 : 4c8428 > jmp * ;failed anyway + + endif + + if (load_data_direct = 1) & (ROM_vectors = 1) +fffa = org $fffa ;vectors +fffa : 1627 dw nmi_trap +fffc : 1c27 dw res_trap +fffe : 2427 dw irq_trap + endif + +fffa = end start + +No errors in pass 2. +Wrote binary from address $0000 through $ffff. +Total size 65536 bytes. +Program start address is at $0400 (1024). + \ No newline at end of file diff --git a/src/test/kotlin/6502_functional_tests/license.txt b/src/test/kotlin/6502_functional_tests/license.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/license.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/test/kotlin/6502_functional_tests/readme.txt b/src/test/kotlin/6502_functional_tests/readme.txt new file mode 100644 index 0000000..a3e30cf --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/readme.txt @@ -0,0 +1,25 @@ +This is a set of functional tests for the 6502/65C02 type processors. + +The 6502_functional_test.a65 is an assembler sourcecode to test all valid +opcodes and addressing modes of the original NMOS 6502 cpu. + +The 65C02_extended_opcodes_test.a65c tests all additional opcodes of the +65C02 processor including undefined opcodes. + +The 6502_interrupt_test.a65 is a simple test to check the interrupt system +of both processors. A feedback register is required to inject IRQ and NMI +requests. + +Detailed information about how to configure, assemble and run the tests is +included in each source file. + +The tests have primarily been written to test my own ATMega16 6502 emulator +project. You can find it here: http://2m5.de/6502_Emu/index.htm + +A discussion about the tests can be found here: +http://forum.6502.org/viewtopic.php?f=2&t=2241 + +Good luck debugging your emulator, simulator, fpga core, discrete +logic implementation or whatever you have! + + diff --git a/src/test/kotlin/6502_functional_tests/report.i65 b/src/test/kotlin/6502_functional_tests/report.i65 new file mode 100644 index 0000000..8cf7a09 --- /dev/null +++ b/src/test/kotlin/6502_functional_tests/report.i65 @@ -0,0 +1,220 @@ +;**** report 6502 funtional test errors to standard I/O **** +; +;this include file is part of the 6502 functional tests +;it is used when you configure report = 1 in the tests +; +;to adopt the standard output vectors of your test environment +;you must modify the rchar and rget subroutines in this include +; +;I/O hardware may have to be initialized in report_init + +;print message macro - \1 = message location +rprt macro + ldx #0 + lda \1 +loop\? + jsr rchar + inx + lda \1,x + bne loop\? + endm + +;initialize I/O as required (example: configure & enable ACIA) +report_init + ;nothing to initialize + rprt rmsg_start + rts + +;show stack (with saved registers), zeropage and absolute memory workspace +;after an error was trapped in the test program +report_error +;save registers + php + pha + txa + pha + tya + pha + cld +;show stack with index to registers at error + rprt rmsg_stack + tsx + inx + lda #1 ;address high + jsr rhex + txa ;address low + jsr rhex +rstack jsr rspace + lda $100,x ;stack data + jsr rhex + inx + bne rstack + jsr rcrlf ;new line +;show zero page workspace + lda #0 + jsr rhex + lda #zpt + tax + jsr rhex +rzp jsr rspace + lda 0,x + jsr rhex + inx + cpx #zp_bss + bne rzp + jsr rcrlf +;show absolute workspace + lda #hi(data_segment) + jsr rhex + lda #lo(data_segment) + jsr rhex + ldx #0 +rabs jsr rspace + lda data_segment,x + jsr rhex + inx + cpx #(data_bss-data_segment) + bne rabs +;ask to continue + rprt rmsg_cont +rerr1 jsr rget + cmp #'S' + beq rskip + cmp #'C' + bne rerr1 +;restore registers + pla + tay + pla + tax + pla + plp + rts +;skip the current test +rskip lda #$f0 ;already end of tests? + cmp test_case + beq rerr1 ;skip is not available + ldx #$ff ;clear stack + txs + inc test_case ;next test + lda #lo(start) ;find begin of test + sta zpt + lda #hi(start) + sta zpt+1 +rskipl1 ldy #4 ;search pattern +rskipl2 lda (zpt),y ;next byte + cmp rmark,y + bne rskipnx ;no match + dey + bmi rskipf ;found pattern + cpy #1 ;skip immediate value + bne rskipl2 + dey + beq rskipl2 + +rskipnx inc zpt ;next RAM location + bne rskipl1 + inc zpt+1 + bne rskipl1 + +rskipf ldy #1 ;pattern found - check test number + lda (zpt),y ;test number + cmp #$f0 ;end of last test? + beq rskipe ;ask to rerun all + cmp test_case ;is next test? + bne rskipnx ;continue searching +rskipe jmp (zpt) ;start next test or rerun at end of tests + +rmark lda #0 ;begin of test search pattern + sta test_case + +;show test has ended, ask to repeat +report_success + if rep_int = 1 + rprt rmsg_priority + lda data_segment ;show interrupt sequence + jsr rhex + jsr rspace + lda data_segment+1 + jsr rhex + jsr rspace + lda data_segment+2 + jsr rhex + endif + rprt rmsg_success +rsuc1 jsr rget + cmp #'R' + bne rsuc1 + rts + +;input subroutine +;get a character from standard input +;adjust according to the needs in your test environment +rget ;get character in A +;rget1 +; lda $bff1 ;wait RDRF +; and #8 +; beq rget1 +;not a real ACIA - so RDRF is not checked +; lda $bff0 ;read acia rx reg + lda $f004 ;Kowalski simulator default +;the load can be replaced by a call to a kernal routine +; jsr $ffcf ;example: CHRIN for a C64 + cmp #'a' ;lower case + bcc rget1 + and #$5f ;convert to upper case +rget1 rts + +;output subroutines +rcrlf lda #10 + jsr rchar + lda #13 + bne rchar + +rspace lda #' ' + bne rchar + +rhex pha ;report hex byte in A + lsr a ;high nibble first + lsr a + lsr a + lsr a + jsr rnib + pla ;now low nibble + and #$f + +rnib clc ;report nibble in A + adc #'0' ;make printable 0-9 + cmp #'9'+1 + bcc rchar + adc #6 ;make printable A-F + +;send a character to standard output +;adjust according to the needs in your test environment +;register X needs to be preserved! +rchar ;report character in A +; pha ;wait TDRF +;rchar1 lda $bff1 +; and #$10 +; beq rchar1 +; pla +;not a real ACIA - so TDRF is not checked +; sta $bff0 ;write acia tx reg + sta $f001 ;Kowalski simulator default +;the store can be replaced by a call to a kernal routine +; jsr $ffd2 ;example: CHROUT for a C64 + rts + +rmsg_start + db 10,13,"Started testing",10,13,0 +rmsg_stack + db 10,13,"regs Y X A PS PCLPCH",10,13,0 +rmsg_cont + db 10,13,"press C to continue or S to skip current test",10,13,0 +rmsg_success + db 10,13,"All tests completed, press R to repeat",10,13,0 + if rep_int = 1 +rmsg_priority + db 10,13,"interrupt sequence (NMI IRQ BRK) ",0 + endif + \ No newline at end of file diff --git a/src/test/kotlin/6502testsuite/0start b/src/test/kotlin/6502testsuite/0start new file mode 100644 index 0000000..fb1cd21 Binary files /dev/null and b/src/test/kotlin/6502testsuite/0start differ diff --git a/src/test/kotlin/6502testsuite/_Test Suite 2.15.txt b/src/test/kotlin/6502testsuite/_Test Suite 2.15.txt new file mode 100644 index 0000000..b9ecc39 --- /dev/null +++ b/src/test/kotlin/6502testsuite/_Test Suite 2.15.txt @@ -0,0 +1,376 @@ +C64 Emulator Test Suite - Public Domain, no Copyright + +https://github.com/mattgodbolt/jsbeeb/blob/master/tests/suite/cbm-hackers-post.md + + +The purpose of the C64 Emulator Test Suite is +- to help C64 emulator authors improve the compatibility +- ensure that updated emulators have no new bugs in old code parts + +The suite are a few hundred C64 programs which check the details of the C64 they are running on. The suite runs automated and stops only if it has detected an error. That the suite doesn't stop on my C64-I/PAL proves that the suite has no bugs. That the same suite doesn't stop on an emulator proves that this particular emulator is compatible to my C64 regarding every tested detail. Of course, the emulator may still have bugs in parts which are not tested by the suite. There may also be a difference between your C64 and my C64. + +While the Test Suite is running, the Datasette should be disconnected. Needs about 80 min to complete. + +The source code has been developed with MACRO(SS)ASS+ by Wolfram Roemhild. The file TEMPLATE.ASM provides a starting point for adding new tests to the suite. + + +/////////////////////////////////////////////////////////////////////////////// +Program _START - some 6510 basic commands, just as an insurance + + +/////////////////////////////////////////////////////////////////////////////// +Programs LDAb to SBCb(EB) - 6510 command function + +addressing modes +----------------------------------- +n none (implied and accu) +b byte (immediate) +w word (absolute for JMP and JSR) +z zero page +zx zero page,x +zy zero page,y +a absolute +ax absolute,x +ay absolute,y +i indirect (JMP) +ix (indirect,x) +iy (indirect),y +r relative + +Display: +before data accu xreg yreg flags sp +after data accu xreg yreg flags sp +right data accu xreg yreg flags sp + +Either press STOP or any other key to continue. + +All 256 opcodes are tested except HLTn (02 12 22 32 42 52 62 72 92 B2 D2 F2). + +Indexed addressing modes count the index registers from 00 to FF. + +JMPi (xxFF) is tested. + +Single operand commands: 256 data combinations from 00 to FF multiplied by 256 flag combinations. + +Two operand commands: 256 data combinations 00/00, 00/11, ... FF/EE, FF/FF multiplied by 256 flag combinations. + +ANEb, LASay, SHAay, SHAiy, SHXay, SHYax and SHSay are executed only in the y border. These commands cause unpredictable results when a DMA comes between the command byte and the operand. + +SHAay, SHAiy, SHXay, SHYax and SHSay are tested on a data address xxFF only. When the hibyte of the indexed address needs adjustment, these commands will write to different locations, depending on the data written. + + +/////////////////////////////////////////////////////////////////////////////// +Programs TRAP* - 6510 IO traps, page boundaries and wrap arounds + + # code data zd zptr aspect tested +----------------------------------------------------------------------------- + 1 2800 29C0 F7 F7/F8 basic functionality + 2 2FFE 29C0 F7 F7/F8 4k boundary within 3 byte commands + 3 2FFF 29C0 F7 F7/F8 4k boundary within 2 and 3 byte commands + 4 D000 29C0 F7 F7/F8 IO traps for code fetch + 5 CFFE 29C0 F7 F7/F8 RAM/IO boundary within 3 byte commands + 6 CFFF 29C0 F7 F7/F8 RAM/IO boundary within 2 and 3 byte commands + 7 2800 D0C0 F7 F7/F8 IO traps for 16 bit data access + 8 2800 D000 F7 F7/F8 IO trap adjustment in ax, ay and iy addressing + 9 2800 29C0 02 F7/F8 wrap around in zx and zy addressing +10 2800 29C0 00 F7/F8 IO traps for 8 bit data access +11 2800 29C0 F7 02/03 wrap around in ix addressing +12 2800 29C0 F7 FF/00 wrap around and IO trap for pointer accesses +13 2800 0002 F7 F7/F8 64k wrap around in ax, ay and iy addressing +14 2800 0000 F7 F7/F8 64k wrap around plus IO trap +15 CFFF D0C6 00 FF/00 1-14 all together as a stress test +16 FFFE ---- -- --/-- 64k boundary within 3 byte commands +17 FFFF ---- -- --/-- 64k boundary within 2 and 3 byte commands + +In the programs TRAP16 and TRAP17, the locations of data, zerodata and zeroptr depend on the addressing mode. The CPU port at 00/01 is not able to hold all 256 bit combinations. + +The datasette may not be connected while TRAP16 and TRAP17 are running! + +Display: +after data accu xreg yreg flags +right data accu xreg yreg flags + +If all displayed values match, some other aspect is wrong, e.g. the stack pointer or data on stack. + +All 256 commands are tested except HLTn. Registers before: +data 1B (00 01 10 11) +accu C6 (11 00 01 10) +xreg B1 (10 11 00 01) +yreg 6C (01 10 11 00) +flags 00 +sptr not initialized, typically F8 + +The code length is 6 bytes maximum (SHSay). + +When the lowbyte of the data address is less than C0, SHAay, SHAiy, SHXay, SHYax and SHSay aren't tested. Those commands don't handle the address adjustment correctly. + +Relative jumps are tested in 4 combinations: offset 01 no jump, offset 01 jump, offset 80 no jump, offset 80 jump. For the offset 80, a RTS is written to the location at code - 7E. + + +/////////////////////////////////////////////////////////////////////////////// +Program BRANCHWRAP - Forward branches from FFxx to 00xx + +Backward branches from 00xx to FFxx were already tested in TRAP16 and TRAP17. + + +/////////////////////////////////////////////////////////////////////////////// +Program MMUFETCH - 6510 code fetching while memory configuration changes + +An example is the code sequence LDA #$37 : STA 1 : BRK in RAM at Axxx. Because STA 1 maps the Basic ROM, the BRK will never get executed. + +addr sequence +--------------------- +A4DF RAM-Basic-RAM +B828 RAM-Basic-RAM +EA77 RAM-Kernal-RAM +FD25 RAM-Kernal-RAM +D400 RAM-Charset-RAM +D000 RAM-IO-RAM + +The sequence IO-Charset-IO is not tested because I didn't find some appropriate code bytes in the Charset ROM at D000-D3FF. The SID registers at D4xx are write-only. + + +/////////////////////////////////////////////////////////////////////////////// +Program MMU - 6510 port at 00/01 bits 0-2 + +Display: +0/1=0-7 repeated 6 times: values stored in 0 and 1 +after 0 1 A000 E000 D000 IO +right 0 1 A000 E000 D000 IO + +address value meaning +---------------------------------------- +A000 94 read Basic, write RAM +A000 01 read/write RAM +E000 86 read Kernal, write RAM +E000 01 read/write RAM +D000/IO 3D/02 read Charset, write RAM +D000/IO 01/02 read/write RAM +D000/IO 00/03 read/write IO + + +/////////////////////////////////////////////////////////////////////////////// +Program CPUPORT - 6510 port at 00/01 bits 0-7 + +Display: +0/1=00/FF repeated 6 times: values stored in 0 and 1 +after 00 01 +right 00 01 + +The datasette may not be connected while CPUPORT is running! + +If both values match, the port behaves instable. On my C64, this will only happen when a datasette is connected. + + +/////////////////////////////////////////////////////////////////////////////// +Program CPUTIMING - 6510 timing whole commands + +Display: +xx command byte +clocks #measured +right #2 + +#1 #2 command or addressing mode +-------------------------------------- +2 2 n +2 2 b +3 3 Rz/Wz +5 5 Mz +4 8 Rzx/Rzy/Wzx/Wzy +6 10 Mzx/Mzy +4 4 Ra/Wa +6 6 Ma +4 8 Rax/Ray (same page) +5 9 Rax/Ray (different page) +5 9 Wax/Way +7 11 Max/May +6 8 Rix/Wix +8 10 Mix/Miy +5 7 Riy (same page) +6 8 Riy (different page) +6 8 Wiy +8 10 Miy +2 18 r+00 same page not taken +3 19 r+00 same page taken +3 19 r+7F same page taken +4 20 r+01 different page taken +4 20 r+7F different page taken +3 19 r-03 same page taken +3 19 r-80 same page taken +4 20 r-03 different page taken +4 20 r-80 different page taken +7 7 BRKn +3 3 PHAn/PHPn +4 4 PLAn/PLPn +3 3 JMPw +5 5 JMPi +6 6 JSRw +6 6 RTSn +6 6 RTIn + +#1 = command execution time without overhead +#2 = displayed value including overhead for measurement +R/W/M = Read/Write/Modify + + +/////////////////////////////////////////////////////////////////////////////// +Programs IRQ and NMI - CPU interrupts within commands + +Tested are all commands except HLTn. For a command of n cycles, a loop with the interrupt occurring before cycle 1..n is performed. Rax/Ray/Riy addressing is tested with both the same page and a different page. Branches are tested not taken, taken to the same page, and taken to a different page. + +Display: +stack
+right
+ +When an interrupt occurs 2 or more cycles before the current command ends, it is executed immediately after the command. Otherwise, the CPU executes the next command first before it calls the interrupt handler. + +The only exception to this rule are taken branches to the same page which last 3 cycles. Here, the interrupt must have occurred before clock 1 of the branch command; the normal rule says before clock 2. Branches to a different page or branches not taken are behaving normal. + +The 6510 will set the IFlag on NMI, too. 6502 untested. + +When an IRQ occurs while SEIn is executing, the IFlag on the stack will be set. + +When an NMI occurs before clock 4 of a BRKn command, the BRK is finished as a NMI. In this case, BFlag on the stack will not be cleared. + + +/////////////////////////////////////////////////////////////////////////////// +Programs CIA1TB123 and CIA2TB123 - CIA timer B 1-3 cycles after writing CRB + +The cycles 1-3 after STA DD0F cannot be measured with LDA DD06 because it takes 3 cycles to decode the LDAa. Executing the STA DD0F at DD03 lets the CPU read DD06 within one cycle. + +#1 #2 DD06 sequence 1/2/3 (4) +--------------------------------- +00 01 keep keep count count +00 10 keep load keep keep +00 11 keep load keep count +01 11 count load keep count +01 10 count load keep keep +01 00 count count keep keep + +#1, #2 = values written to DD0F + + +/////////////////////////////////////////////////////////////////////////////// +Programs CIA1PB6 to CIA2PB7 - CIA timer output to PB6 and PB7 + +Checks 128 combinations of CRA/B in One Shot mode: + old CRx bit 0 Start + CRx bit 1 PBxOut + CRx bit 2 PBxToggle + new CRx bit 0 Start + CRx bit 1 PBxOut + CRx bit 2 PBxToggle + CRx bit 4 Force Load + +The resulting PB6/7 bit is: + 0 if new PBxToggle is 0 + 1 if new PBxToggle is 1 + - (undetermined) if PBxOut is 0 + +Old values do not influence the result. Start and Force Load don't either. + +Next, the programs test if PBx is toggled to 0 on the first underflow and that neither writing CRx except bit 0 nor Timer Hi/Lo will set it back to 1. The only source which is able to reset the toggle line is a rising edge on the Start bit 0 of CRx. + +Another test verifies that the toggle line is independent from PBxOut and PBxToggle. Changing these two bits will have no effect on switching the toggle flip flop when the timer underflows. + +The last test checks for the correct timing in Pulse and Toggle Mode. + + +/////////////////////////////////////////////////////////////////////////////// +Program CIA1TAB - TA, TB, PB67 and ICR in cascaded mode + +Both latches are set to 2. TA counts system clocks, TB counts TA underflows (cascaded). PB6 is high for one cycle when TA underflows, PB7 is toggled when TB underflows. IMR is $02. + +TA 01 02 02 01 02 02 01 02 02 01 02 02 +TB 02 02 02 01 01 01 00 00 02 02 02 02 +PB 80 C0 80 80 C0 80 80 C0 00 00 40 00 +ICR 00 01 01 01 01 01 01 01 03 83 83 83 + +If one of the registers doesn't match this table, the program displays the wrong values with red color. + + +/////////////////////////////////////////////////////////////////////////////// +Program LOADTH - Load timer high byte + +Writing to the high byte of the latch may load the counter only when it is not running. + +writing counter load +------------------------ +high byte stopped yes +high byte running no +low byte stopped no +low byte running no + + +/////////////////////////////////////////////////////////////////////////////// +Program CNTO2 - Switches between CNT and o2 input + +When the timer input is switched from o2 to CNT or from CNT back to o2, there must be a two clock delay until the switch is recognized. + + +/////////////////////////////////////////////////////////////////////////////// +Program ICR01 - Reads ICR around an underflow + +Reads ICR when an underflow occurs and checks if the NMI is executed. + +time ICR NMI +-------------- +t-1 00 yes +t 01 no +t+1 81 yes + + +/////////////////////////////////////////////////////////////////////////////// +Program IMR - Interrupt mask register + +When a condition in the ICR is true, setting the corresponding bit in the IMR must also set the interrupt. Clearing the bit in the IMR may not clear the interrupt. Only reading the ICR may clear the interrupt. + + +/////////////////////////////////////////////////////////////////////////////// +Program FLIPOS - Flip one shot + +Sets and clears the one shot bit when an underflow occurs at t. Set must take effect at t-1, clear at t-2. + +time set clear +------------------ +t-2 stop count +t-1 stop stop +t count stop + + +/////////////////////////////////////////////////////////////////////////////// +Program ONESHOT - Checks for start bit cleared + +Reads CRA in one shot mode with an underflow at t. + +time CRA +--------- +t-1 $09 +t $08 + + +/////////////////////////////////////////////////////////////////////////////// +Program CNTDEF - CNT default + +CNT must be high by default. This is tested with timer B cascaded mode CRB = $61. + + + + + + +******************************************* +** U N D E R C O N S T R U C T I O N ** +******************************************* + + + +/////////////////////////////////////////////////////////////////////////////// +Programs CIA1TA to CIA2TB - CIA timers in sysclock mode + +PC64Win 2.15 bug: + before 05/02/01/00 + after xx + cr 11/19 + after xx +timer low doesn't match diff --git a/src/test/kotlin/6502testsuite/adca b/src/test/kotlin/6502testsuite/adca new file mode 100644 index 0000000..87bfdf6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/adca differ diff --git a/src/test/kotlin/6502testsuite/adcax b/src/test/kotlin/6502testsuite/adcax new file mode 100644 index 0000000..f28d921 Binary files /dev/null and b/src/test/kotlin/6502testsuite/adcax differ diff --git a/src/test/kotlin/6502testsuite/adcay b/src/test/kotlin/6502testsuite/adcay new file mode 100644 index 0000000..46a69cb Binary files /dev/null and b/src/test/kotlin/6502testsuite/adcay differ diff --git a/src/test/kotlin/6502testsuite/adcb b/src/test/kotlin/6502testsuite/adcb new file mode 100644 index 0000000..55169ef Binary files /dev/null and b/src/test/kotlin/6502testsuite/adcb differ diff --git a/src/test/kotlin/6502testsuite/adcix b/src/test/kotlin/6502testsuite/adcix new file mode 100644 index 0000000..252ea07 Binary files /dev/null and b/src/test/kotlin/6502testsuite/adcix differ diff --git a/src/test/kotlin/6502testsuite/adciy b/src/test/kotlin/6502testsuite/adciy new file mode 100644 index 0000000..faafc69 Binary files /dev/null and b/src/test/kotlin/6502testsuite/adciy differ diff --git a/src/test/kotlin/6502testsuite/adcz b/src/test/kotlin/6502testsuite/adcz new file mode 100644 index 0000000..356737d Binary files /dev/null and b/src/test/kotlin/6502testsuite/adcz differ diff --git a/src/test/kotlin/6502testsuite/adczx b/src/test/kotlin/6502testsuite/adczx new file mode 100644 index 0000000..036d83e Binary files /dev/null and b/src/test/kotlin/6502testsuite/adczx differ diff --git a/src/test/kotlin/6502testsuite/alrb b/src/test/kotlin/6502testsuite/alrb new file mode 100644 index 0000000..75da7c8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/alrb differ diff --git a/src/test/kotlin/6502testsuite/ancb b/src/test/kotlin/6502testsuite/ancb new file mode 100644 index 0000000..c0e1890 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ancb differ diff --git a/src/test/kotlin/6502testsuite/anda b/src/test/kotlin/6502testsuite/anda new file mode 100644 index 0000000..5ebc4cd Binary files /dev/null and b/src/test/kotlin/6502testsuite/anda differ diff --git a/src/test/kotlin/6502testsuite/andax b/src/test/kotlin/6502testsuite/andax new file mode 100644 index 0000000..ef004b7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/andax differ diff --git a/src/test/kotlin/6502testsuite/anday b/src/test/kotlin/6502testsuite/anday new file mode 100644 index 0000000..448381a Binary files /dev/null and b/src/test/kotlin/6502testsuite/anday differ diff --git a/src/test/kotlin/6502testsuite/andb b/src/test/kotlin/6502testsuite/andb new file mode 100644 index 0000000..1f4db42 Binary files /dev/null and b/src/test/kotlin/6502testsuite/andb differ diff --git a/src/test/kotlin/6502testsuite/andix b/src/test/kotlin/6502testsuite/andix new file mode 100644 index 0000000..50e632f Binary files /dev/null and b/src/test/kotlin/6502testsuite/andix differ diff --git a/src/test/kotlin/6502testsuite/andiy b/src/test/kotlin/6502testsuite/andiy new file mode 100644 index 0000000..770f86f Binary files /dev/null and b/src/test/kotlin/6502testsuite/andiy differ diff --git a/src/test/kotlin/6502testsuite/andz b/src/test/kotlin/6502testsuite/andz new file mode 100644 index 0000000..4e4db7b Binary files /dev/null and b/src/test/kotlin/6502testsuite/andz differ diff --git a/src/test/kotlin/6502testsuite/andzx b/src/test/kotlin/6502testsuite/andzx new file mode 100644 index 0000000..5a6de9e Binary files /dev/null and b/src/test/kotlin/6502testsuite/andzx differ diff --git a/src/test/kotlin/6502testsuite/aneb b/src/test/kotlin/6502testsuite/aneb new file mode 100644 index 0000000..c5e7e06 Binary files /dev/null and b/src/test/kotlin/6502testsuite/aneb differ diff --git a/src/test/kotlin/6502testsuite/arrb b/src/test/kotlin/6502testsuite/arrb new file mode 100644 index 0000000..af871ca Binary files /dev/null and b/src/test/kotlin/6502testsuite/arrb differ diff --git a/src/test/kotlin/6502testsuite/asla b/src/test/kotlin/6502testsuite/asla new file mode 100644 index 0000000..932a6d4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asla differ diff --git a/src/test/kotlin/6502testsuite/aslax b/src/test/kotlin/6502testsuite/aslax new file mode 100644 index 0000000..38bb78a Binary files /dev/null and b/src/test/kotlin/6502testsuite/aslax differ diff --git a/src/test/kotlin/6502testsuite/asln b/src/test/kotlin/6502testsuite/asln new file mode 100644 index 0000000..451a65a Binary files /dev/null and b/src/test/kotlin/6502testsuite/asln differ diff --git a/src/test/kotlin/6502testsuite/aslz b/src/test/kotlin/6502testsuite/aslz new file mode 100644 index 0000000..17eff5c Binary files /dev/null and b/src/test/kotlin/6502testsuite/aslz differ diff --git a/src/test/kotlin/6502testsuite/aslzx b/src/test/kotlin/6502testsuite/aslzx new file mode 100644 index 0000000..594fb68 Binary files /dev/null and b/src/test/kotlin/6502testsuite/aslzx differ diff --git a/src/test/kotlin/6502testsuite/asoa b/src/test/kotlin/6502testsuite/asoa new file mode 100644 index 0000000..299da9d Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoa differ diff --git a/src/test/kotlin/6502testsuite/asoax b/src/test/kotlin/6502testsuite/asoax new file mode 100644 index 0000000..205e6c1 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoax differ diff --git a/src/test/kotlin/6502testsuite/asoay b/src/test/kotlin/6502testsuite/asoay new file mode 100644 index 0000000..b6657bb Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoay differ diff --git a/src/test/kotlin/6502testsuite/asoix b/src/test/kotlin/6502testsuite/asoix new file mode 100644 index 0000000..9ff13a1 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoix differ diff --git a/src/test/kotlin/6502testsuite/asoiy b/src/test/kotlin/6502testsuite/asoiy new file mode 100644 index 0000000..389b578 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoiy differ diff --git a/src/test/kotlin/6502testsuite/asoz b/src/test/kotlin/6502testsuite/asoz new file mode 100644 index 0000000..3e06cc8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asoz differ diff --git a/src/test/kotlin/6502testsuite/asozx b/src/test/kotlin/6502testsuite/asozx new file mode 100644 index 0000000..8be8b08 Binary files /dev/null and b/src/test/kotlin/6502testsuite/asozx differ diff --git a/src/test/kotlin/6502testsuite/axsa b/src/test/kotlin/6502testsuite/axsa new file mode 100644 index 0000000..f53c23f Binary files /dev/null and b/src/test/kotlin/6502testsuite/axsa differ diff --git a/src/test/kotlin/6502testsuite/axsix b/src/test/kotlin/6502testsuite/axsix new file mode 100644 index 0000000..f285bc9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/axsix differ diff --git a/src/test/kotlin/6502testsuite/axsz b/src/test/kotlin/6502testsuite/axsz new file mode 100644 index 0000000..c1304fc Binary files /dev/null and b/src/test/kotlin/6502testsuite/axsz differ diff --git a/src/test/kotlin/6502testsuite/axszy b/src/test/kotlin/6502testsuite/axszy new file mode 100644 index 0000000..f886f0d Binary files /dev/null and b/src/test/kotlin/6502testsuite/axszy differ diff --git a/src/test/kotlin/6502testsuite/bccr b/src/test/kotlin/6502testsuite/bccr new file mode 100644 index 0000000..776e887 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bccr differ diff --git a/src/test/kotlin/6502testsuite/bcsr b/src/test/kotlin/6502testsuite/bcsr new file mode 100644 index 0000000..074baf2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bcsr differ diff --git a/src/test/kotlin/6502testsuite/beqr b/src/test/kotlin/6502testsuite/beqr new file mode 100644 index 0000000..b77ef95 Binary files /dev/null and b/src/test/kotlin/6502testsuite/beqr differ diff --git a/src/test/kotlin/6502testsuite/bita b/src/test/kotlin/6502testsuite/bita new file mode 100644 index 0000000..2800315 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bita differ diff --git a/src/test/kotlin/6502testsuite/bitz b/src/test/kotlin/6502testsuite/bitz new file mode 100644 index 0000000..439ca82 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bitz differ diff --git a/src/test/kotlin/6502testsuite/bmir b/src/test/kotlin/6502testsuite/bmir new file mode 100644 index 0000000..5ed96e4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bmir differ diff --git a/src/test/kotlin/6502testsuite/bner b/src/test/kotlin/6502testsuite/bner new file mode 100644 index 0000000..d14bfde Binary files /dev/null and b/src/test/kotlin/6502testsuite/bner differ diff --git a/src/test/kotlin/6502testsuite/bplr b/src/test/kotlin/6502testsuite/bplr new file mode 100644 index 0000000..26f074d Binary files /dev/null and b/src/test/kotlin/6502testsuite/bplr differ diff --git a/src/test/kotlin/6502testsuite/branchwrap b/src/test/kotlin/6502testsuite/branchwrap new file mode 100644 index 0000000..d7740b9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/branchwrap differ diff --git a/src/test/kotlin/6502testsuite/brkn b/src/test/kotlin/6502testsuite/brkn new file mode 100644 index 0000000..fc46111 Binary files /dev/null and b/src/test/kotlin/6502testsuite/brkn differ diff --git a/src/test/kotlin/6502testsuite/bvcr b/src/test/kotlin/6502testsuite/bvcr new file mode 100644 index 0000000..af935d6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bvcr differ diff --git a/src/test/kotlin/6502testsuite/bvsr b/src/test/kotlin/6502testsuite/bvsr new file mode 100644 index 0000000..45337d0 Binary files /dev/null and b/src/test/kotlin/6502testsuite/bvsr differ diff --git a/src/test/kotlin/6502testsuite/cia1pb6 b/src/test/kotlin/6502testsuite/cia1pb6 new file mode 100644 index 0000000..e8b683e Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1pb6 differ diff --git a/src/test/kotlin/6502testsuite/cia1pb7 b/src/test/kotlin/6502testsuite/cia1pb7 new file mode 100644 index 0000000..10920f7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1pb7 differ diff --git a/src/test/kotlin/6502testsuite/cia1ta b/src/test/kotlin/6502testsuite/cia1ta new file mode 100644 index 0000000..9f5ccfa Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1ta differ diff --git a/src/test/kotlin/6502testsuite/cia1tab b/src/test/kotlin/6502testsuite/cia1tab new file mode 100644 index 0000000..5d1aea7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1tab differ diff --git a/src/test/kotlin/6502testsuite/cia1tb b/src/test/kotlin/6502testsuite/cia1tb new file mode 100644 index 0000000..3802a1b Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1tb differ diff --git a/src/test/kotlin/6502testsuite/cia1tb123 b/src/test/kotlin/6502testsuite/cia1tb123 new file mode 100644 index 0000000..f7a90a2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia1tb123 differ diff --git a/src/test/kotlin/6502testsuite/cia2pb6 b/src/test/kotlin/6502testsuite/cia2pb6 new file mode 100644 index 0000000..fa0dc43 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia2pb6 differ diff --git a/src/test/kotlin/6502testsuite/cia2pb7 b/src/test/kotlin/6502testsuite/cia2pb7 new file mode 100644 index 0000000..118c51f Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia2pb7 differ diff --git a/src/test/kotlin/6502testsuite/cia2ta b/src/test/kotlin/6502testsuite/cia2ta new file mode 100644 index 0000000..59254a2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia2ta differ diff --git a/src/test/kotlin/6502testsuite/cia2tb b/src/test/kotlin/6502testsuite/cia2tb new file mode 100644 index 0000000..886daac Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia2tb differ diff --git a/src/test/kotlin/6502testsuite/cia2tb123 b/src/test/kotlin/6502testsuite/cia2tb123 new file mode 100644 index 0000000..f8b13c7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cia2tb123 differ diff --git a/src/test/kotlin/6502testsuite/clcn b/src/test/kotlin/6502testsuite/clcn new file mode 100644 index 0000000..a89106a Binary files /dev/null and b/src/test/kotlin/6502testsuite/clcn differ diff --git a/src/test/kotlin/6502testsuite/cldn b/src/test/kotlin/6502testsuite/cldn new file mode 100644 index 0000000..950696e Binary files /dev/null and b/src/test/kotlin/6502testsuite/cldn differ diff --git a/src/test/kotlin/6502testsuite/clin b/src/test/kotlin/6502testsuite/clin new file mode 100644 index 0000000..f5dd270 Binary files /dev/null and b/src/test/kotlin/6502testsuite/clin differ diff --git a/src/test/kotlin/6502testsuite/clvn b/src/test/kotlin/6502testsuite/clvn new file mode 100644 index 0000000..ec9bfb4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/clvn differ diff --git a/src/test/kotlin/6502testsuite/cmpa b/src/test/kotlin/6502testsuite/cmpa new file mode 100644 index 0000000..b515e08 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpa differ diff --git a/src/test/kotlin/6502testsuite/cmpax b/src/test/kotlin/6502testsuite/cmpax new file mode 100644 index 0000000..baa55f1 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpax differ diff --git a/src/test/kotlin/6502testsuite/cmpay b/src/test/kotlin/6502testsuite/cmpay new file mode 100644 index 0000000..f8351fc Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpay differ diff --git a/src/test/kotlin/6502testsuite/cmpb b/src/test/kotlin/6502testsuite/cmpb new file mode 100644 index 0000000..fbe1b91 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpb differ diff --git a/src/test/kotlin/6502testsuite/cmpix b/src/test/kotlin/6502testsuite/cmpix new file mode 100644 index 0000000..5e07d9d Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpix differ diff --git a/src/test/kotlin/6502testsuite/cmpiy b/src/test/kotlin/6502testsuite/cmpiy new file mode 100644 index 0000000..6926664 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpiy differ diff --git a/src/test/kotlin/6502testsuite/cmpz b/src/test/kotlin/6502testsuite/cmpz new file mode 100644 index 0000000..27f2ca3 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpz differ diff --git a/src/test/kotlin/6502testsuite/cmpzx b/src/test/kotlin/6502testsuite/cmpzx new file mode 100644 index 0000000..d332c16 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cmpzx differ diff --git a/src/test/kotlin/6502testsuite/cntdef b/src/test/kotlin/6502testsuite/cntdef new file mode 100644 index 0000000..b12f46c Binary files /dev/null and b/src/test/kotlin/6502testsuite/cntdef differ diff --git a/src/test/kotlin/6502testsuite/cnto2 b/src/test/kotlin/6502testsuite/cnto2 new file mode 100644 index 0000000..a7b0405 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cnto2 differ diff --git a/src/test/kotlin/6502testsuite/cpuport b/src/test/kotlin/6502testsuite/cpuport new file mode 100644 index 0000000..c3ac852 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpuport differ diff --git a/src/test/kotlin/6502testsuite/cputiming b/src/test/kotlin/6502testsuite/cputiming new file mode 100644 index 0000000..fc3114e Binary files /dev/null and b/src/test/kotlin/6502testsuite/cputiming differ diff --git a/src/test/kotlin/6502testsuite/cpxa b/src/test/kotlin/6502testsuite/cpxa new file mode 100644 index 0000000..bc36f18 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpxa differ diff --git a/src/test/kotlin/6502testsuite/cpxb b/src/test/kotlin/6502testsuite/cpxb new file mode 100644 index 0000000..97f8988 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpxb differ diff --git a/src/test/kotlin/6502testsuite/cpxz b/src/test/kotlin/6502testsuite/cpxz new file mode 100644 index 0000000..01ebf31 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpxz differ diff --git a/src/test/kotlin/6502testsuite/cpya b/src/test/kotlin/6502testsuite/cpya new file mode 100644 index 0000000..ab94484 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpya differ diff --git a/src/test/kotlin/6502testsuite/cpyb b/src/test/kotlin/6502testsuite/cpyb new file mode 100644 index 0000000..8247ec9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpyb differ diff --git a/src/test/kotlin/6502testsuite/cpyz b/src/test/kotlin/6502testsuite/cpyz new file mode 100644 index 0000000..81451bc Binary files /dev/null and b/src/test/kotlin/6502testsuite/cpyz differ diff --git a/src/test/kotlin/6502testsuite/dcma b/src/test/kotlin/6502testsuite/dcma new file mode 100644 index 0000000..9ed51d4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcma differ diff --git a/src/test/kotlin/6502testsuite/dcmax b/src/test/kotlin/6502testsuite/dcmax new file mode 100644 index 0000000..18ccbe8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmax differ diff --git a/src/test/kotlin/6502testsuite/dcmay b/src/test/kotlin/6502testsuite/dcmay new file mode 100644 index 0000000..01b27fb Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmay differ diff --git a/src/test/kotlin/6502testsuite/dcmix b/src/test/kotlin/6502testsuite/dcmix new file mode 100644 index 0000000..2f6de74 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmix differ diff --git a/src/test/kotlin/6502testsuite/dcmiy b/src/test/kotlin/6502testsuite/dcmiy new file mode 100644 index 0000000..4df4044 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmiy differ diff --git a/src/test/kotlin/6502testsuite/dcmz b/src/test/kotlin/6502testsuite/dcmz new file mode 100644 index 0000000..fa04f43 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmz differ diff --git a/src/test/kotlin/6502testsuite/dcmzx b/src/test/kotlin/6502testsuite/dcmzx new file mode 100644 index 0000000..c9e72b7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/dcmzx differ diff --git a/src/test/kotlin/6502testsuite/deca b/src/test/kotlin/6502testsuite/deca new file mode 100644 index 0000000..167ef54 Binary files /dev/null and b/src/test/kotlin/6502testsuite/deca differ diff --git a/src/test/kotlin/6502testsuite/decax b/src/test/kotlin/6502testsuite/decax new file mode 100644 index 0000000..69c31f9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/decax differ diff --git a/src/test/kotlin/6502testsuite/decz b/src/test/kotlin/6502testsuite/decz new file mode 100644 index 0000000..f7f3946 Binary files /dev/null and b/src/test/kotlin/6502testsuite/decz differ diff --git a/src/test/kotlin/6502testsuite/deczx b/src/test/kotlin/6502testsuite/deczx new file mode 100644 index 0000000..d8c0e76 Binary files /dev/null and b/src/test/kotlin/6502testsuite/deczx differ diff --git a/src/test/kotlin/6502testsuite/dexn b/src/test/kotlin/6502testsuite/dexn new file mode 100644 index 0000000..c02027a Binary files /dev/null and b/src/test/kotlin/6502testsuite/dexn differ diff --git a/src/test/kotlin/6502testsuite/deyn b/src/test/kotlin/6502testsuite/deyn new file mode 100644 index 0000000..8c9e068 Binary files /dev/null and b/src/test/kotlin/6502testsuite/deyn differ diff --git a/src/test/kotlin/6502testsuite/eora b/src/test/kotlin/6502testsuite/eora new file mode 100644 index 0000000..7473a9b Binary files /dev/null and b/src/test/kotlin/6502testsuite/eora differ diff --git a/src/test/kotlin/6502testsuite/eorax b/src/test/kotlin/6502testsuite/eorax new file mode 100644 index 0000000..584be50 Binary files /dev/null and b/src/test/kotlin/6502testsuite/eorax differ diff --git a/src/test/kotlin/6502testsuite/eoray b/src/test/kotlin/6502testsuite/eoray new file mode 100644 index 0000000..340b6a5 Binary files /dev/null and b/src/test/kotlin/6502testsuite/eoray differ diff --git a/src/test/kotlin/6502testsuite/eorb b/src/test/kotlin/6502testsuite/eorb new file mode 100644 index 0000000..3b17168 Binary files /dev/null and b/src/test/kotlin/6502testsuite/eorb differ diff --git a/src/test/kotlin/6502testsuite/eorix b/src/test/kotlin/6502testsuite/eorix new file mode 100644 index 0000000..06de6ff Binary files /dev/null and b/src/test/kotlin/6502testsuite/eorix differ diff --git a/src/test/kotlin/6502testsuite/eoriy b/src/test/kotlin/6502testsuite/eoriy new file mode 100644 index 0000000..194802b Binary files /dev/null and b/src/test/kotlin/6502testsuite/eoriy differ diff --git a/src/test/kotlin/6502testsuite/eorz b/src/test/kotlin/6502testsuite/eorz new file mode 100644 index 0000000..fa3e882 Binary files /dev/null and b/src/test/kotlin/6502testsuite/eorz differ diff --git a/src/test/kotlin/6502testsuite/eorzx b/src/test/kotlin/6502testsuite/eorzx new file mode 100644 index 0000000..c39e0eb Binary files /dev/null and b/src/test/kotlin/6502testsuite/eorzx differ diff --git a/src/test/kotlin/6502testsuite/finish b/src/test/kotlin/6502testsuite/finish new file mode 100644 index 0000000..52f6f45 Binary files /dev/null and b/src/test/kotlin/6502testsuite/finish differ diff --git a/src/test/kotlin/6502testsuite/flipos b/src/test/kotlin/6502testsuite/flipos new file mode 100644 index 0000000..431e490 Binary files /dev/null and b/src/test/kotlin/6502testsuite/flipos differ diff --git a/src/test/kotlin/6502testsuite/icr01 b/src/test/kotlin/6502testsuite/icr01 new file mode 100644 index 0000000..de8bd98 Binary files /dev/null and b/src/test/kotlin/6502testsuite/icr01 differ diff --git a/src/test/kotlin/6502testsuite/imr b/src/test/kotlin/6502testsuite/imr new file mode 100644 index 0000000..3fe057b Binary files /dev/null and b/src/test/kotlin/6502testsuite/imr differ diff --git a/src/test/kotlin/6502testsuite/inca b/src/test/kotlin/6502testsuite/inca new file mode 100644 index 0000000..bb031cb Binary files /dev/null and b/src/test/kotlin/6502testsuite/inca differ diff --git a/src/test/kotlin/6502testsuite/incax b/src/test/kotlin/6502testsuite/incax new file mode 100644 index 0000000..065ae31 Binary files /dev/null and b/src/test/kotlin/6502testsuite/incax differ diff --git a/src/test/kotlin/6502testsuite/incz b/src/test/kotlin/6502testsuite/incz new file mode 100644 index 0000000..b3b9bac Binary files /dev/null and b/src/test/kotlin/6502testsuite/incz differ diff --git a/src/test/kotlin/6502testsuite/inczx b/src/test/kotlin/6502testsuite/inczx new file mode 100644 index 0000000..019a469 Binary files /dev/null and b/src/test/kotlin/6502testsuite/inczx differ diff --git a/src/test/kotlin/6502testsuite/insa b/src/test/kotlin/6502testsuite/insa new file mode 100644 index 0000000..b117525 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insa differ diff --git a/src/test/kotlin/6502testsuite/insax b/src/test/kotlin/6502testsuite/insax new file mode 100644 index 0000000..e6b1cc3 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insax differ diff --git a/src/test/kotlin/6502testsuite/insay b/src/test/kotlin/6502testsuite/insay new file mode 100644 index 0000000..06a4b73 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insay differ diff --git a/src/test/kotlin/6502testsuite/insix b/src/test/kotlin/6502testsuite/insix new file mode 100644 index 0000000..85572f2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insix differ diff --git a/src/test/kotlin/6502testsuite/insiy b/src/test/kotlin/6502testsuite/insiy new file mode 100644 index 0000000..8f0af40 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insiy differ diff --git a/src/test/kotlin/6502testsuite/insz b/src/test/kotlin/6502testsuite/insz new file mode 100644 index 0000000..717dd27 Binary files /dev/null and b/src/test/kotlin/6502testsuite/insz differ diff --git a/src/test/kotlin/6502testsuite/inszx b/src/test/kotlin/6502testsuite/inszx new file mode 100644 index 0000000..fbc2057 Binary files /dev/null and b/src/test/kotlin/6502testsuite/inszx differ diff --git a/src/test/kotlin/6502testsuite/inxn b/src/test/kotlin/6502testsuite/inxn new file mode 100644 index 0000000..b18ba94 Binary files /dev/null and b/src/test/kotlin/6502testsuite/inxn differ diff --git a/src/test/kotlin/6502testsuite/inyn b/src/test/kotlin/6502testsuite/inyn new file mode 100644 index 0000000..5ceba8d Binary files /dev/null and b/src/test/kotlin/6502testsuite/inyn differ diff --git a/src/test/kotlin/6502testsuite/irq b/src/test/kotlin/6502testsuite/irq new file mode 100644 index 0000000..54be04f Binary files /dev/null and b/src/test/kotlin/6502testsuite/irq differ diff --git a/src/test/kotlin/6502testsuite/jmpi b/src/test/kotlin/6502testsuite/jmpi new file mode 100644 index 0000000..5c4f882 Binary files /dev/null and b/src/test/kotlin/6502testsuite/jmpi differ diff --git a/src/test/kotlin/6502testsuite/jmpw b/src/test/kotlin/6502testsuite/jmpw new file mode 100644 index 0000000..738249c Binary files /dev/null and b/src/test/kotlin/6502testsuite/jmpw differ diff --git a/src/test/kotlin/6502testsuite/jsrw b/src/test/kotlin/6502testsuite/jsrw new file mode 100644 index 0000000..a08772f Binary files /dev/null and b/src/test/kotlin/6502testsuite/jsrw differ diff --git a/src/test/kotlin/6502testsuite/lasay b/src/test/kotlin/6502testsuite/lasay new file mode 100644 index 0000000..6b85ce3 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lasay differ diff --git a/src/test/kotlin/6502testsuite/laxa b/src/test/kotlin/6502testsuite/laxa new file mode 100644 index 0000000..7693a0c Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxa differ diff --git a/src/test/kotlin/6502testsuite/laxay b/src/test/kotlin/6502testsuite/laxay new file mode 100644 index 0000000..1292c0d Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxay differ diff --git a/src/test/kotlin/6502testsuite/laxix b/src/test/kotlin/6502testsuite/laxix new file mode 100644 index 0000000..67d0388 Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxix differ diff --git a/src/test/kotlin/6502testsuite/laxiy b/src/test/kotlin/6502testsuite/laxiy new file mode 100644 index 0000000..1daac98 Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxiy differ diff --git a/src/test/kotlin/6502testsuite/laxz b/src/test/kotlin/6502testsuite/laxz new file mode 100644 index 0000000..9b24d20 Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxz differ diff --git a/src/test/kotlin/6502testsuite/laxzy b/src/test/kotlin/6502testsuite/laxzy new file mode 100644 index 0000000..a9de62c Binary files /dev/null and b/src/test/kotlin/6502testsuite/laxzy differ diff --git a/src/test/kotlin/6502testsuite/ldaa b/src/test/kotlin/6502testsuite/ldaa new file mode 100644 index 0000000..55be82f Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaa differ diff --git a/src/test/kotlin/6502testsuite/ldaax b/src/test/kotlin/6502testsuite/ldaax new file mode 100644 index 0000000..130c5c4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaax differ diff --git a/src/test/kotlin/6502testsuite/ldaay b/src/test/kotlin/6502testsuite/ldaay new file mode 100644 index 0000000..1cb9f6c Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaay differ diff --git a/src/test/kotlin/6502testsuite/ldab b/src/test/kotlin/6502testsuite/ldab new file mode 100644 index 0000000..103e9f6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldab differ diff --git a/src/test/kotlin/6502testsuite/ldaix b/src/test/kotlin/6502testsuite/ldaix new file mode 100644 index 0000000..31c5945 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaix differ diff --git a/src/test/kotlin/6502testsuite/ldaiy b/src/test/kotlin/6502testsuite/ldaiy new file mode 100644 index 0000000..6f7bd11 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaiy differ diff --git a/src/test/kotlin/6502testsuite/ldaz b/src/test/kotlin/6502testsuite/ldaz new file mode 100644 index 0000000..63ffdc7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldaz differ diff --git a/src/test/kotlin/6502testsuite/ldazx b/src/test/kotlin/6502testsuite/ldazx new file mode 100644 index 0000000..4739e4b Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldazx differ diff --git a/src/test/kotlin/6502testsuite/ldxa b/src/test/kotlin/6502testsuite/ldxa new file mode 100644 index 0000000..d2c8558 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldxa differ diff --git a/src/test/kotlin/6502testsuite/ldxay b/src/test/kotlin/6502testsuite/ldxay new file mode 100644 index 0000000..6d6267c Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldxay differ diff --git a/src/test/kotlin/6502testsuite/ldxb b/src/test/kotlin/6502testsuite/ldxb new file mode 100644 index 0000000..ccab216 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldxb differ diff --git a/src/test/kotlin/6502testsuite/ldxz b/src/test/kotlin/6502testsuite/ldxz new file mode 100644 index 0000000..792838e Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldxz differ diff --git a/src/test/kotlin/6502testsuite/ldxzy b/src/test/kotlin/6502testsuite/ldxzy new file mode 100644 index 0000000..727a70a Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldxzy differ diff --git a/src/test/kotlin/6502testsuite/ldya b/src/test/kotlin/6502testsuite/ldya new file mode 100644 index 0000000..fef0d4b Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldya differ diff --git a/src/test/kotlin/6502testsuite/ldyax b/src/test/kotlin/6502testsuite/ldyax new file mode 100644 index 0000000..57defb9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldyax differ diff --git a/src/test/kotlin/6502testsuite/ldyb b/src/test/kotlin/6502testsuite/ldyb new file mode 100644 index 0000000..1e011d2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldyb differ diff --git a/src/test/kotlin/6502testsuite/ldyz b/src/test/kotlin/6502testsuite/ldyz new file mode 100644 index 0000000..042fd24 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldyz differ diff --git a/src/test/kotlin/6502testsuite/ldyzx b/src/test/kotlin/6502testsuite/ldyzx new file mode 100644 index 0000000..4205dc7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/ldyzx differ diff --git a/src/test/kotlin/6502testsuite/loadth b/src/test/kotlin/6502testsuite/loadth new file mode 100644 index 0000000..9125b8e Binary files /dev/null and b/src/test/kotlin/6502testsuite/loadth differ diff --git a/src/test/kotlin/6502testsuite/lsea b/src/test/kotlin/6502testsuite/lsea new file mode 100644 index 0000000..8b33a4b Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsea differ diff --git a/src/test/kotlin/6502testsuite/lseax b/src/test/kotlin/6502testsuite/lseax new file mode 100644 index 0000000..2468fd7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lseax differ diff --git a/src/test/kotlin/6502testsuite/lseay b/src/test/kotlin/6502testsuite/lseay new file mode 100644 index 0000000..f7dfac2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lseay differ diff --git a/src/test/kotlin/6502testsuite/lseix b/src/test/kotlin/6502testsuite/lseix new file mode 100644 index 0000000..3d40ff6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lseix differ diff --git a/src/test/kotlin/6502testsuite/lseiy b/src/test/kotlin/6502testsuite/lseiy new file mode 100644 index 0000000..96764e2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lseiy differ diff --git a/src/test/kotlin/6502testsuite/lsez b/src/test/kotlin/6502testsuite/lsez new file mode 100644 index 0000000..d6f75b7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsez differ diff --git a/src/test/kotlin/6502testsuite/lsezx b/src/test/kotlin/6502testsuite/lsezx new file mode 100644 index 0000000..d5063d0 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsezx differ diff --git a/src/test/kotlin/6502testsuite/lsra b/src/test/kotlin/6502testsuite/lsra new file mode 100644 index 0000000..27151dd Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsra differ diff --git a/src/test/kotlin/6502testsuite/lsrax b/src/test/kotlin/6502testsuite/lsrax new file mode 100644 index 0000000..d87966c Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsrax differ diff --git a/src/test/kotlin/6502testsuite/lsrn b/src/test/kotlin/6502testsuite/lsrn new file mode 100644 index 0000000..48fbb50 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsrn differ diff --git a/src/test/kotlin/6502testsuite/lsrz b/src/test/kotlin/6502testsuite/lsrz new file mode 100644 index 0000000..4e3cbef Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsrz differ diff --git a/src/test/kotlin/6502testsuite/lsrzx b/src/test/kotlin/6502testsuite/lsrzx new file mode 100644 index 0000000..8e5c399 Binary files /dev/null and b/src/test/kotlin/6502testsuite/lsrzx differ diff --git a/src/test/kotlin/6502testsuite/lxab b/src/test/kotlin/6502testsuite/lxab new file mode 100644 index 0000000..24e950d Binary files /dev/null and b/src/test/kotlin/6502testsuite/lxab differ diff --git a/src/test/kotlin/6502testsuite/mmu b/src/test/kotlin/6502testsuite/mmu new file mode 100644 index 0000000..f1140ad Binary files /dev/null and b/src/test/kotlin/6502testsuite/mmu differ diff --git a/src/test/kotlin/6502testsuite/mmufetch b/src/test/kotlin/6502testsuite/mmufetch new file mode 100644 index 0000000..148940e Binary files /dev/null and b/src/test/kotlin/6502testsuite/mmufetch differ diff --git a/src/test/kotlin/6502testsuite/nmi b/src/test/kotlin/6502testsuite/nmi new file mode 100644 index 0000000..445bf26 Binary files /dev/null and b/src/test/kotlin/6502testsuite/nmi differ diff --git a/src/test/kotlin/6502testsuite/nopa b/src/test/kotlin/6502testsuite/nopa new file mode 100644 index 0000000..40784d9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopa differ diff --git a/src/test/kotlin/6502testsuite/nopax b/src/test/kotlin/6502testsuite/nopax new file mode 100644 index 0000000..8f70d15 Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopax differ diff --git a/src/test/kotlin/6502testsuite/nopb b/src/test/kotlin/6502testsuite/nopb new file mode 100644 index 0000000..0b6516e Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopb differ diff --git a/src/test/kotlin/6502testsuite/nopn b/src/test/kotlin/6502testsuite/nopn new file mode 100644 index 0000000..7d9264a Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopn differ diff --git a/src/test/kotlin/6502testsuite/nopz b/src/test/kotlin/6502testsuite/nopz new file mode 100644 index 0000000..30ab926 Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopz differ diff --git a/src/test/kotlin/6502testsuite/nopzx b/src/test/kotlin/6502testsuite/nopzx new file mode 100644 index 0000000..ec8770e Binary files /dev/null and b/src/test/kotlin/6502testsuite/nopzx differ diff --git a/src/test/kotlin/6502testsuite/oneshot b/src/test/kotlin/6502testsuite/oneshot new file mode 100644 index 0000000..eda87c0 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oneshot differ diff --git a/src/test/kotlin/6502testsuite/oraa b/src/test/kotlin/6502testsuite/oraa new file mode 100644 index 0000000..fe07787 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraa differ diff --git a/src/test/kotlin/6502testsuite/oraax b/src/test/kotlin/6502testsuite/oraax new file mode 100644 index 0000000..642f0a4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraax differ diff --git a/src/test/kotlin/6502testsuite/oraay b/src/test/kotlin/6502testsuite/oraay new file mode 100644 index 0000000..3a67e19 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraay differ diff --git a/src/test/kotlin/6502testsuite/orab b/src/test/kotlin/6502testsuite/orab new file mode 100644 index 0000000..39be6e8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/orab differ diff --git a/src/test/kotlin/6502testsuite/oraix b/src/test/kotlin/6502testsuite/oraix new file mode 100644 index 0000000..68d2fdf Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraix differ diff --git a/src/test/kotlin/6502testsuite/oraiy b/src/test/kotlin/6502testsuite/oraiy new file mode 100644 index 0000000..5c3fce3 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraiy differ diff --git a/src/test/kotlin/6502testsuite/oraz b/src/test/kotlin/6502testsuite/oraz new file mode 100644 index 0000000..23addc4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/oraz differ diff --git a/src/test/kotlin/6502testsuite/orazx b/src/test/kotlin/6502testsuite/orazx new file mode 100644 index 0000000..bca23a9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/orazx differ diff --git a/src/test/kotlin/6502testsuite/phan b/src/test/kotlin/6502testsuite/phan new file mode 100644 index 0000000..c0a0247 Binary files /dev/null and b/src/test/kotlin/6502testsuite/phan differ diff --git a/src/test/kotlin/6502testsuite/phpn b/src/test/kotlin/6502testsuite/phpn new file mode 100644 index 0000000..be4b987 Binary files /dev/null and b/src/test/kotlin/6502testsuite/phpn differ diff --git a/src/test/kotlin/6502testsuite/plan b/src/test/kotlin/6502testsuite/plan new file mode 100644 index 0000000..785291b Binary files /dev/null and b/src/test/kotlin/6502testsuite/plan differ diff --git a/src/test/kotlin/6502testsuite/plpn b/src/test/kotlin/6502testsuite/plpn new file mode 100644 index 0000000..9e179c6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/plpn differ diff --git a/src/test/kotlin/6502testsuite/rlaa b/src/test/kotlin/6502testsuite/rlaa new file mode 100644 index 0000000..6fe1d28 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaa differ diff --git a/src/test/kotlin/6502testsuite/rlaax b/src/test/kotlin/6502testsuite/rlaax new file mode 100644 index 0000000..712eaeb Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaax differ diff --git a/src/test/kotlin/6502testsuite/rlaay b/src/test/kotlin/6502testsuite/rlaay new file mode 100644 index 0000000..ce337cd Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaay differ diff --git a/src/test/kotlin/6502testsuite/rlaix b/src/test/kotlin/6502testsuite/rlaix new file mode 100644 index 0000000..f60672e Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaix differ diff --git a/src/test/kotlin/6502testsuite/rlaiy b/src/test/kotlin/6502testsuite/rlaiy new file mode 100644 index 0000000..2391a95 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaiy differ diff --git a/src/test/kotlin/6502testsuite/rlaz b/src/test/kotlin/6502testsuite/rlaz new file mode 100644 index 0000000..bdacdb1 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlaz differ diff --git a/src/test/kotlin/6502testsuite/rlazx b/src/test/kotlin/6502testsuite/rlazx new file mode 100644 index 0000000..24e2684 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rlazx differ diff --git a/src/test/kotlin/6502testsuite/rola b/src/test/kotlin/6502testsuite/rola new file mode 100644 index 0000000..f79f6b8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rola differ diff --git a/src/test/kotlin/6502testsuite/rolax b/src/test/kotlin/6502testsuite/rolax new file mode 100644 index 0000000..05a11e6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rolax differ diff --git a/src/test/kotlin/6502testsuite/roln b/src/test/kotlin/6502testsuite/roln new file mode 100644 index 0000000..b3c4684 Binary files /dev/null and b/src/test/kotlin/6502testsuite/roln differ diff --git a/src/test/kotlin/6502testsuite/rolz b/src/test/kotlin/6502testsuite/rolz new file mode 100644 index 0000000..d694c13 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rolz differ diff --git a/src/test/kotlin/6502testsuite/rolzx b/src/test/kotlin/6502testsuite/rolzx new file mode 100644 index 0000000..928beaf Binary files /dev/null and b/src/test/kotlin/6502testsuite/rolzx differ diff --git a/src/test/kotlin/6502testsuite/rora b/src/test/kotlin/6502testsuite/rora new file mode 100644 index 0000000..32d8fa4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rora differ diff --git a/src/test/kotlin/6502testsuite/rorax b/src/test/kotlin/6502testsuite/rorax new file mode 100644 index 0000000..e2438f6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rorax differ diff --git a/src/test/kotlin/6502testsuite/rorn b/src/test/kotlin/6502testsuite/rorn new file mode 100644 index 0000000..46a5435 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rorn differ diff --git a/src/test/kotlin/6502testsuite/rorz b/src/test/kotlin/6502testsuite/rorz new file mode 100644 index 0000000..31e907e Binary files /dev/null and b/src/test/kotlin/6502testsuite/rorz differ diff --git a/src/test/kotlin/6502testsuite/rorzx b/src/test/kotlin/6502testsuite/rorzx new file mode 100644 index 0000000..8e1294b Binary files /dev/null and b/src/test/kotlin/6502testsuite/rorzx differ diff --git a/src/test/kotlin/6502testsuite/rraa b/src/test/kotlin/6502testsuite/rraa new file mode 100644 index 0000000..fdbc3c7 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraa differ diff --git a/src/test/kotlin/6502testsuite/rraax b/src/test/kotlin/6502testsuite/rraax new file mode 100644 index 0000000..a3e8011 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraax differ diff --git a/src/test/kotlin/6502testsuite/rraay b/src/test/kotlin/6502testsuite/rraay new file mode 100644 index 0000000..d55640f Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraay differ diff --git a/src/test/kotlin/6502testsuite/rraix b/src/test/kotlin/6502testsuite/rraix new file mode 100644 index 0000000..cbdc97f Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraix differ diff --git a/src/test/kotlin/6502testsuite/rraiy b/src/test/kotlin/6502testsuite/rraiy new file mode 100644 index 0000000..82d7e4d Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraiy differ diff --git a/src/test/kotlin/6502testsuite/rraz b/src/test/kotlin/6502testsuite/rraz new file mode 100644 index 0000000..dd79bc2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rraz differ diff --git a/src/test/kotlin/6502testsuite/rrazx b/src/test/kotlin/6502testsuite/rrazx new file mode 100644 index 0000000..5328358 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rrazx differ diff --git a/src/test/kotlin/6502testsuite/rtin b/src/test/kotlin/6502testsuite/rtin new file mode 100644 index 0000000..d3b6322 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rtin differ diff --git a/src/test/kotlin/6502testsuite/rtsn b/src/test/kotlin/6502testsuite/rtsn new file mode 100644 index 0000000..1dadcf2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/rtsn differ diff --git a/src/test/kotlin/6502testsuite/sbca b/src/test/kotlin/6502testsuite/sbca new file mode 100644 index 0000000..5bb1e96 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbca differ diff --git a/src/test/kotlin/6502testsuite/sbcax b/src/test/kotlin/6502testsuite/sbcax new file mode 100644 index 0000000..b811793 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcax differ diff --git a/src/test/kotlin/6502testsuite/sbcay b/src/test/kotlin/6502testsuite/sbcay new file mode 100644 index 0000000..dda6c45 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcay differ diff --git a/src/test/kotlin/6502testsuite/sbcb b/src/test/kotlin/6502testsuite/sbcb new file mode 100644 index 0000000..806ecd8 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcb differ diff --git a/src/test/kotlin/6502testsuite/sbcb(eb) b/src/test/kotlin/6502testsuite/sbcb(eb) new file mode 100644 index 0000000..5b684dc Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcb(eb) differ diff --git a/src/test/kotlin/6502testsuite/sbcix b/src/test/kotlin/6502testsuite/sbcix new file mode 100644 index 0000000..88f0828 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcix differ diff --git a/src/test/kotlin/6502testsuite/sbciy b/src/test/kotlin/6502testsuite/sbciy new file mode 100644 index 0000000..b34ec55 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbciy differ diff --git a/src/test/kotlin/6502testsuite/sbcz b/src/test/kotlin/6502testsuite/sbcz new file mode 100644 index 0000000..4d446e4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbcz differ diff --git a/src/test/kotlin/6502testsuite/sbczx b/src/test/kotlin/6502testsuite/sbczx new file mode 100644 index 0000000..fde9acc Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbczx differ diff --git a/src/test/kotlin/6502testsuite/sbxb b/src/test/kotlin/6502testsuite/sbxb new file mode 100644 index 0000000..7c6a9b5 Binary files /dev/null and b/src/test/kotlin/6502testsuite/sbxb differ diff --git a/src/test/kotlin/6502testsuite/secn b/src/test/kotlin/6502testsuite/secn new file mode 100644 index 0000000..391795d Binary files /dev/null and b/src/test/kotlin/6502testsuite/secn differ diff --git a/src/test/kotlin/6502testsuite/sedn b/src/test/kotlin/6502testsuite/sedn new file mode 100644 index 0000000..a9f1e1f Binary files /dev/null and b/src/test/kotlin/6502testsuite/sedn differ diff --git a/src/test/kotlin/6502testsuite/sein b/src/test/kotlin/6502testsuite/sein new file mode 100644 index 0000000..e69ce7c Binary files /dev/null and b/src/test/kotlin/6502testsuite/sein differ diff --git a/src/test/kotlin/6502testsuite/shaay b/src/test/kotlin/6502testsuite/shaay new file mode 100644 index 0000000..df7b51c Binary files /dev/null and b/src/test/kotlin/6502testsuite/shaay differ diff --git a/src/test/kotlin/6502testsuite/shaiy b/src/test/kotlin/6502testsuite/shaiy new file mode 100644 index 0000000..5640d04 Binary files /dev/null and b/src/test/kotlin/6502testsuite/shaiy differ diff --git a/src/test/kotlin/6502testsuite/shsay b/src/test/kotlin/6502testsuite/shsay new file mode 100644 index 0000000..88ac4ce Binary files /dev/null and b/src/test/kotlin/6502testsuite/shsay differ diff --git a/src/test/kotlin/6502testsuite/shxay b/src/test/kotlin/6502testsuite/shxay new file mode 100644 index 0000000..0918d21 Binary files /dev/null and b/src/test/kotlin/6502testsuite/shxay differ diff --git a/src/test/kotlin/6502testsuite/shyax b/src/test/kotlin/6502testsuite/shyax new file mode 100644 index 0000000..74b4f84 Binary files /dev/null and b/src/test/kotlin/6502testsuite/shyax differ diff --git a/src/test/kotlin/6502testsuite/staa b/src/test/kotlin/6502testsuite/staa new file mode 100644 index 0000000..f7350ef Binary files /dev/null and b/src/test/kotlin/6502testsuite/staa differ diff --git a/src/test/kotlin/6502testsuite/staax b/src/test/kotlin/6502testsuite/staax new file mode 100644 index 0000000..96d3f80 Binary files /dev/null and b/src/test/kotlin/6502testsuite/staax differ diff --git a/src/test/kotlin/6502testsuite/staay b/src/test/kotlin/6502testsuite/staay new file mode 100644 index 0000000..6783682 Binary files /dev/null and b/src/test/kotlin/6502testsuite/staay differ diff --git a/src/test/kotlin/6502testsuite/staix b/src/test/kotlin/6502testsuite/staix new file mode 100644 index 0000000..9752dc6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/staix differ diff --git a/src/test/kotlin/6502testsuite/staiy b/src/test/kotlin/6502testsuite/staiy new file mode 100644 index 0000000..a70dfcf Binary files /dev/null and b/src/test/kotlin/6502testsuite/staiy differ diff --git a/src/test/kotlin/6502testsuite/staz b/src/test/kotlin/6502testsuite/staz new file mode 100644 index 0000000..f271def Binary files /dev/null and b/src/test/kotlin/6502testsuite/staz differ diff --git a/src/test/kotlin/6502testsuite/stazx b/src/test/kotlin/6502testsuite/stazx new file mode 100644 index 0000000..9bd9a77 Binary files /dev/null and b/src/test/kotlin/6502testsuite/stazx differ diff --git a/src/test/kotlin/6502testsuite/stxa b/src/test/kotlin/6502testsuite/stxa new file mode 100644 index 0000000..e11db6d Binary files /dev/null and b/src/test/kotlin/6502testsuite/stxa differ diff --git a/src/test/kotlin/6502testsuite/stxz b/src/test/kotlin/6502testsuite/stxz new file mode 100644 index 0000000..9bf1c92 Binary files /dev/null and b/src/test/kotlin/6502testsuite/stxz differ diff --git a/src/test/kotlin/6502testsuite/stxzy b/src/test/kotlin/6502testsuite/stxzy new file mode 100644 index 0000000..ff194a2 Binary files /dev/null and b/src/test/kotlin/6502testsuite/stxzy differ diff --git a/src/test/kotlin/6502testsuite/stya b/src/test/kotlin/6502testsuite/stya new file mode 100644 index 0000000..e520a62 Binary files /dev/null and b/src/test/kotlin/6502testsuite/stya differ diff --git a/src/test/kotlin/6502testsuite/styz b/src/test/kotlin/6502testsuite/styz new file mode 100644 index 0000000..12816e4 Binary files /dev/null and b/src/test/kotlin/6502testsuite/styz differ diff --git a/src/test/kotlin/6502testsuite/styzx b/src/test/kotlin/6502testsuite/styzx new file mode 100644 index 0000000..18e0b24 Binary files /dev/null and b/src/test/kotlin/6502testsuite/styzx differ diff --git a/src/test/kotlin/6502testsuite/taxn b/src/test/kotlin/6502testsuite/taxn new file mode 100644 index 0000000..ab0eaa0 Binary files /dev/null and b/src/test/kotlin/6502testsuite/taxn differ diff --git a/src/test/kotlin/6502testsuite/tayn b/src/test/kotlin/6502testsuite/tayn new file mode 100644 index 0000000..b1bff05 Binary files /dev/null and b/src/test/kotlin/6502testsuite/tayn differ diff --git a/src/test/kotlin/6502testsuite/trap1 b/src/test/kotlin/6502testsuite/trap1 new file mode 100644 index 0000000..69e1311 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap1 differ diff --git a/src/test/kotlin/6502testsuite/trap10 b/src/test/kotlin/6502testsuite/trap10 new file mode 100644 index 0000000..039c61e Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap10 differ diff --git a/src/test/kotlin/6502testsuite/trap11 b/src/test/kotlin/6502testsuite/trap11 new file mode 100644 index 0000000..2bab320 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap11 differ diff --git a/src/test/kotlin/6502testsuite/trap12 b/src/test/kotlin/6502testsuite/trap12 new file mode 100644 index 0000000..7407832 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap12 differ diff --git a/src/test/kotlin/6502testsuite/trap13 b/src/test/kotlin/6502testsuite/trap13 new file mode 100644 index 0000000..b7545c9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap13 differ diff --git a/src/test/kotlin/6502testsuite/trap14 b/src/test/kotlin/6502testsuite/trap14 new file mode 100644 index 0000000..1bb4876 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap14 differ diff --git a/src/test/kotlin/6502testsuite/trap15 b/src/test/kotlin/6502testsuite/trap15 new file mode 100644 index 0000000..f610d10 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap15 differ diff --git a/src/test/kotlin/6502testsuite/trap16 b/src/test/kotlin/6502testsuite/trap16 new file mode 100644 index 0000000..64165d0 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap16 differ diff --git a/src/test/kotlin/6502testsuite/trap17 b/src/test/kotlin/6502testsuite/trap17 new file mode 100644 index 0000000..f0fd40c Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap17 differ diff --git a/src/test/kotlin/6502testsuite/trap2 b/src/test/kotlin/6502testsuite/trap2 new file mode 100644 index 0000000..d0ed817 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap2 differ diff --git a/src/test/kotlin/6502testsuite/trap3 b/src/test/kotlin/6502testsuite/trap3 new file mode 100644 index 0000000..8b16ad9 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap3 differ diff --git a/src/test/kotlin/6502testsuite/trap4 b/src/test/kotlin/6502testsuite/trap4 new file mode 100644 index 0000000..124ac74 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap4 differ diff --git a/src/test/kotlin/6502testsuite/trap5 b/src/test/kotlin/6502testsuite/trap5 new file mode 100644 index 0000000..f8ab1f6 Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap5 differ diff --git a/src/test/kotlin/6502testsuite/trap6 b/src/test/kotlin/6502testsuite/trap6 new file mode 100644 index 0000000..0221dcd Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap6 differ diff --git a/src/test/kotlin/6502testsuite/trap7 b/src/test/kotlin/6502testsuite/trap7 new file mode 100644 index 0000000..f573c6f Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap7 differ diff --git a/src/test/kotlin/6502testsuite/trap8 b/src/test/kotlin/6502testsuite/trap8 new file mode 100644 index 0000000..b47e19b Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap8 differ diff --git a/src/test/kotlin/6502testsuite/trap9 b/src/test/kotlin/6502testsuite/trap9 new file mode 100644 index 0000000..68e8a7f Binary files /dev/null and b/src/test/kotlin/6502testsuite/trap9 differ diff --git a/src/test/kotlin/6502testsuite/tsxn b/src/test/kotlin/6502testsuite/tsxn new file mode 100644 index 0000000..d94b438 Binary files /dev/null and b/src/test/kotlin/6502testsuite/tsxn differ diff --git a/src/test/kotlin/6502testsuite/txan b/src/test/kotlin/6502testsuite/txan new file mode 100644 index 0000000..e9e137e Binary files /dev/null and b/src/test/kotlin/6502testsuite/txan differ diff --git a/src/test/kotlin/6502testsuite/txsn b/src/test/kotlin/6502testsuite/txsn new file mode 100644 index 0000000..dde0444 Binary files /dev/null and b/src/test/kotlin/6502testsuite/txsn differ diff --git a/src/test/kotlin/6502testsuite/tyan b/src/test/kotlin/6502testsuite/tyan new file mode 100644 index 0000000..44d844a Binary files /dev/null and b/src/test/kotlin/6502testsuite/tyan differ diff --git a/src/test/kotlin/C64KernalStubs.kt b/src/test/kotlin/C64KernalStubs.kt new file mode 100644 index 0000000..6370d53 --- /dev/null +++ b/src/test/kotlin/C64KernalStubs.kt @@ -0,0 +1,48 @@ +import net.razorvine.ksim65.Petscii +import net.razorvine.ksim65.components.Address +import net.razorvine.ksim65.components.Cpu6502 +import net.razorvine.ksim65.components.Ram + + +class C64KernalStubs(private val ram: Ram) { + + fun handleBreakpoint(cpu: Cpu6502, pc: Address) { + when(pc) { + 0xffd2 -> { + // CHROUT + ram[0x030c] = 0 + val char = Petscii.decodePetscii(listOf(cpu.A.toShort()), true).first() + if(char==13.toChar()) + println() + else if(char in ' '..'~') + print(char) + cpu.currentOpcode = 0x60 // rts to end the stub + } + 0xffe4 -> { + // GETIN + throw KernalInputRequired() +// print("[Input required:] ") +// val s = readLine() +// if(s.isNullOrEmpty()) +// cpu.A = 3 +// else +// cpu.A = Petscii.encodePetscii(s, true).first().toInt() +// cpu.currentOpcode = 0x60 // rts to end the stub + } + 0xe16f -> { + throw KernalLoadNextPart() + // LOAD/VERIFY +// val loc = ram[0xbb].toInt() or (ram[0xbc].toInt() shl 8) +// val len = ram[0xb7].toInt() +// val filename = Petscii.decodePetscii((loc until loc + len).map { ram[it] }.toList(), true).toLowerCase() +// ram.loadPrg("test/6502testsuite/$filename") +// cpu.popStackAddr() +// cpu.PC = 0x0816 // continue in next module + } + } + } +} + +internal class KernalLoadNextPart: Exception() +internal class KernalInputRequired: Exception() + diff --git a/src/test/kotlin/Test6502.kt b/src/test/kotlin/Test6502.kt new file mode 100644 index 0000000..29ac444 --- /dev/null +++ b/src/test/kotlin/Test6502.kt @@ -0,0 +1,323 @@ +import net.razorvine.ksim65.components.Cpu6502 +import org.junit.jupiter.api.TestInstance +import kotlin.test.* + + +/* + +Unit test suite adapted from Py65 https://github.com/mnaberez/py65 + +Copyright (c) 2008-2018, Mike Naberezny and contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +class Test6502 : TestCommon6502() { + // NMOS 6502 tests + + override fun createCpu() = Cpu6502(false) + + // ADC Indirect, Indexed (X) + + @Test + fun test_adc_ind_indexed_has_page_wrap_bug() { + mpu.A = 0x01 + mpu.X = 0xFF + // $0000 ADC ($80,X) + // $007f Vector to $BBBB (read if page wrapped) + // $017f Vector to $ABCD (read if no page wrap) + writeMem(memory, 0x0000, listOf(0x61, 0x80)) + writeMem(memory, 0x007f, listOf(0xBB, 0xBB)) + writeMem(memory, 0x017f, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x01 + memory[0xBBBB] = 0x02 + mpu.step() + assertEquals(0x03, mpu.A) + } + + // ADC Indexed, Indirect (Y) + + @Test + fun test_adc_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0x42 + mpu.Y = 0x02 + // $1000 ADC ($FF),Y + writeMem(memory, 0x1000, listOf(0x71, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x14 // read if no page wrap + memory[0x0012] = 0x42 // read if page wrapped + mpu.step() + assertEquals(0x84, mpu.A) + } + + // LDA Zero Page, X-Indexed + + @Test + fun test_lda_zp_x_indexed_page_wraps() { + mpu.A = 0x00 + mpu.X = 0xFF + // $0000 LDA $80,X + writeMem(memory, 0x0000, listOf(0xB5, 0x80)) + memory[0x007F] = 0x42 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x42, mpu.A) + } + + // AND Indexed, Indirect (Y) + + @Test + fun test_and_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0x42 + mpu.Y = 0x02 + // $1000 AND ($FF),Y + writeMem(memory, 0x1000, listOf(0x31, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x00 // read if no page wrap + memory[0x0012] = 0xFF // read if page wrapped + mpu.step() + assertEquals(0x42, mpu.A) + } + + // BRK + + @Test + fun test_brk_preserves_decimal_flag_when_it_is_set() { + mpu.Status.D = true + // $C000 BRK + memory[0xC000] = 0x00 + mpu.PC = 0xC000 + mpu.step() + assertTrue(mpu.Status.B) + assertTrue(mpu.Status.D) + } + + @Test + fun test_brk_preserves_decimal_flag_when_it_is_clear() { + // $C000 BRK + memory[0xC000] = 0x00 + mpu.PC = 0xC000 + mpu.step() + assertTrue(mpu.Status.B) + assertFalse(mpu.Status.D) + } + + // CMP Indirect, Indexed (X) + + @Test + fun test_cmp_ind_x_has_page_wrap_bug() { + mpu.A = 0x42 + mpu.X = 0xFF + // $0000 CMP ($80,X) + // $007f Vector to $BBBB (read if page wrapped) + // $017f Vector to $ABCD (read if no page wrap) + writeMem(memory, 0x0000, listOf(0xC1, 0x80)) + writeMem(memory, 0x007f, listOf(0xBB, 0xBB)) + writeMem(memory, 0x017f, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + memory[0xBBBB] = 0x42 + mpu.step() + assertTrue(mpu.Status.Z) + } + + // CMP Indexed, Indirect (Y) + + @Test + fun test_cmp_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0x42 + mpu.Y = 0x02 + // $1000 CMP ($FF),Y + writeMem(memory, 0x1000, listOf(0xd1, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x14 // read if no page wrap + memory[0x0012] = 0x42 // read if page wrapped + mpu.step() + assertTrue(mpu.Status.Z) + } + + // EOR Indirect, Indexed (X) + + @Test + fun test_eor_ind_x_has_page_wrap_bug() { + mpu.A = 0xAA + mpu.X = 0xFF + // $0000 EOR ($80,X) + // $007f Vector to $BBBB (read if page wrapped) + // $017f Vector to $ABCD (read if no page wrap) + writeMem(memory, 0x0000, listOf(0x41, 0x80)) + writeMem(memory, 0x007f, listOf(0xBB, 0xBB)) + writeMem(memory, 0x017f, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + memory[0xBBBB] = 0xFF + mpu.step() + assertEquals(0x55, mpu.A) + } + + // EOR Indexed, Indirect (Y) + + @Test + fun test_eor_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0xAA + mpu.Y = 0x02 + // $1000 EOR ($FF),Y + writeMem(memory, 0x1000, listOf(0x51, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x00 // read if no page wrap + memory[0x0012] = 0xFF // read if page wrapped + mpu.step() + assertEquals(0x55, mpu.A) + } + + // LDA Indirect, Indexed (X) + + @Test + fun test_lda_ind_indexed_x_has_page_wrap_bug() { + mpu.A = 0x00 + mpu.X = 0xff + // $0000 LDA ($80,X) + // $007f Vector to $BBBB (read if page wrapped) + // $017f Vector to $ABCD (read if no page wrap) + writeMem(memory, 0x0000, listOf(0xA1, 0x80)) + writeMem(memory, 0x007f, listOf(0xBB, 0xBB)) + writeMem(memory, 0x017f, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x42 + memory[0xBBBB] = 0xEF + mpu.step() + assertEquals(0xEF, mpu.A) + } + + // LDA Indexed, Indirect (Y) + + @Test + fun test_lda_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0x00 + mpu.Y = 0x02 + // $1000 LDA ($FF),Y + writeMem(memory, 0x1000, listOf(0xb1, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x14 // read if no page wrap + memory[0x0012] = 0x42 // read if page wrapped + mpu.step() + assertEquals(0x42, mpu.A) + } + + // LDA Zero Page, X-Indexed + + @Test + fun test_lda_zp_x_has_page_wrap_bug() { + mpu.A = 0x00 + mpu.X = 0xFF + // $0000 LDA $80,X + writeMem(memory, 0x0000, listOf(0xB5, 0x80)) + memory[0x007F] = 0x42 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x42, mpu.A) + } + + // JMP Indirect + + @Test + fun test_jmp_jumps_to_address_with_page_wrap_bug() { + memory[0x00ff] = 0 + // $0000 JMP ($00) + writeMem(memory, 0, listOf(0x6c, 0xff, 0x00)) + mpu.step() + assertEquals(0x6c00, mpu.PC) + assertEquals((5+Cpu6502.resetCycles).toLong(), mpu.totalCycles) + } + + // ORA Indexed, Indirect (Y) + + @Test + fun test_ora_indexed_ind_y_has_page_wrap_bug() { + mpu.PC = 0x1000 + mpu.A = 0x00 + mpu.Y = 0x02 + // $1000 ORA ($FF),Y + writeMem(memory, 0x1000, listOf(0x11, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x00 // read if no page wrap + memory[0x0012] = 0x42 // read if page wrapped + mpu.step() + assertEquals(0x42, mpu.A) + } + + // SBC Indexed, Indirect (Y) + + @Test + fun test_sbc_indexed_ind_y_has_page_wrap_bug() { + + mpu.PC = 0x1000 + mpu.Status.C = true + mpu.A = 0x42 + mpu.Y = 0x02 + // $1000 SBC ($FF),Y + writeMem(memory, 0x1000, listOf(0xf1, 0xff)) + // Vector + memory[0x00ff] = 0x10 // low byte + memory[0x0100] = 0x20 // high byte if no page wrap + memory[0x0000] = 0x00 // high byte if page wrapped + // Data + memory[0x2012] = 0x02 // read if no page wrap + memory[0x0012] = 0x03 // read if page wrapped + mpu.step() + assertEquals(0x3f, mpu.A) + } +} diff --git a/src/test/kotlin/Test6502CpuBasics.kt b/src/test/kotlin/Test6502CpuBasics.kt new file mode 100644 index 0000000..91fe9e2 --- /dev/null +++ b/src/test/kotlin/Test6502CpuBasics.kt @@ -0,0 +1,100 @@ +import net.razorvine.ksim65.components.Bus +import net.razorvine.ksim65.components.Cpu6502 +import net.razorvine.ksim65.components.Ram +import kotlin.test.* +import kotlin.system.measureNanoTime +import kotlin.test.assertEquals + + +class Test6502CpuBasics { + + @Test + fun testCpuFlagsAfterReset() { + val cpu = Cpu6502(true) + val bus = Bus() + bus.add(cpu) + cpu.reset() + assertEquals(0xfd, cpu.SP) + assertEquals(0xffff, cpu.PC) + assertEquals(0, cpu.totalCycles) + assertEquals(8, cpu.instrCycles) + assertEquals(0, cpu.A) + assertEquals(0, cpu.X) + assertEquals(0, cpu.Y) + assertEquals(0, cpu.currentOpcode) + assertEquals(Cpu6502.StatusRegister(C = false, Z = false, I = true, D = false, B = false, V = false, N = false), cpu.Status) + assertEquals(0b00100100, cpu.Status.asByte()) + } + + @Test + fun testCpuPerformance() { + val cpu = Cpu6502(true) + val ram = Ram(0x1000, 0x2000) + // load a simple program that loops a few instructions + for(b in listOf(0xa9, 0x63, 0xaa, 0x86, 0x22, 0x8e, 0x22, 0x22, 0x91, 0x22, 0x6d, 0x33, 0x33, 0xcd, 0x55, 0x55, 0xd0, 0xee, 0xf0, 0xec).withIndex()) { + ram[0x1000+b.index] = b.value.toShort() + } + + val bus = Bus() + bus.add(cpu) + bus.add(ram) + cpu.reset() + cpu.PC = 0x1000 + + // warmup + while(cpu.totalCycles<1000000) + cpu.clock() + + // timing + val cycles = 50000000 + val duration = measureNanoTime { + while (cpu.totalCycles < cycles) + cpu.clock() + } + val seconds = duration.toDouble() / 1e9 + val mhz = (cycles.toDouble() / seconds) / 1e6 + println("duration $seconds sec for $cycles = $mhz Mhz") + + } + + @Test + fun testBCD() { + val cpu = Cpu6502(true) + val bus = Bus() + bus.add(cpu) + val ram = Ram(0, 0xffff) + ram[Cpu6502.RESET_vector] = 0x00 + ram[Cpu6502.RESET_vector +1] = 0x10 + ram.load("src/test/kotlin/testfiles/bcdtest.bin", 0x1000) + bus.add(ram) + bus.reset() + + try { + while (true) { + bus.clock() + } + } catch(e: Cpu6502.InstructionError) { + // do nothing + } + + if(ram[0x0400] ==0.toShort()) { + println("BCD TEST: OK!") + } + else { + val code = ram[0x0400] + val v1 = ram[0x0401] + val v2 = ram[0x0402] + val predictedA = ram[0x00fc] + val actualA = ram[0x00fd] + val predictedF = ram[0x00fe] + val actualF = ram[0x00ff] + println("BCD TEST: FAIL!! code=${Cpu6502.hexB(code)} value1=${Cpu6502.hexB(v1)} value2=${Cpu6502.hexB(v2)}") + println(" predictedA=${Cpu6502.hexB(predictedA)}") + println(" actualA=${Cpu6502.hexB(actualA)}") + println(" predictedF=${predictedF.toString(2).padStart(8,'0')}") + println(" actualF=${actualF.toString(2).padStart(8,'0')}") + fail("BCD test failed") + } + } + +} diff --git a/src/test/kotlin/Test6502Functional.kt b/src/test/kotlin/Test6502Functional.kt new file mode 100644 index 0000000..d2cf106 --- /dev/null +++ b/src/test/kotlin/Test6502Functional.kt @@ -0,0 +1,43 @@ +import net.razorvine.ksim65.components.Bus +import net.razorvine.ksim65.components.Ram +import net.razorvine.ksim65.components.Cpu6502 +import java.lang.Exception +import kotlin.test.* + + +class Test6502Functional { + + private class SuccessfulTestResult: Exception() + + @Test + fun testFunctional() { + val cpu = Cpu6502(false) + val bus = Bus() + val ram = Ram(0, 0xffff) + ram.load("src/test/kotlin/6502_functional_tests/bin_files/6502_functional_test.bin", 0) + bus.add(cpu) + bus.add(ram) + cpu.reset() + cpu.PC = 0x0400 + cpu.breakpoint(0x3469) { _, _ -> + // reaching this address means successful test result + if(cpu.currentOpcode==0x4c) + throw SuccessfulTestResult() + } + + try { + while (cpu.totalCycles < 900000000) { + cpu.clock() + } + } catch (sx: SuccessfulTestResult) { + println("test successful") + return + } + + cpu.printState() + val d = cpu.disassemble(ram, cpu.PC-20, cpu.PC+20) + println(d.joinToString ("\n")) + fail("test failed") + } + +} diff --git a/src/test/kotlin/Test6502TestSuite.kt b/src/test/kotlin/Test6502TestSuite.kt new file mode 100644 index 0000000..22ad871 --- /dev/null +++ b/src/test/kotlin/Test6502TestSuite.kt @@ -0,0 +1,1391 @@ +import net.razorvine.ksim65.components.Bus +import net.razorvine.ksim65.components.Cpu6502 +import net.razorvine.ksim65.components.Ram +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.TestInstance +import kotlin.test.* + + +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +@Disabled("this test suite takes a long time") +class Test6502TestSuite { + + val cpu: Cpu6502 = Cpu6502(stopOnBrk = false) + val ram = Ram(0, 0xffff) + val bus = Bus() + val kernalStubs = C64KernalStubs(ram) + + init { + cpu.tracing = false + cpu.breakpoint(0xffd2) { cpu, pc -> kernalStubs.handleBreakpoint(cpu, pc) } + cpu.breakpoint(0xffe4) { cpu, pc -> kernalStubs.handleBreakpoint(cpu, pc) } + cpu.breakpoint(0xe16f) { cpu, pc -> kernalStubs.handleBreakpoint(cpu, pc) } + + // create the system bus and add device to it. + // note that the order is relevant w.r.t. where reads and writes are going. + ram[0x02] = 0 + ram[0xa002] = 0 + ram[0xa003] = 0x80 + ram[Cpu6502.IRQ_vector] = 0x48 + ram[Cpu6502.IRQ_vector + 1] = 0xff + ram[Cpu6502.RESET_vector] = 0x01 + ram[Cpu6502.RESET_vector + 1] = 0x08 + ram[0x01fe] = 0xff + ram[0x01ff] = 0x7f + ram[0x8000] = 2 + ram[0xa474] = 2 + + // setup the irq/brk routine + for(b in listOf(0x48, 0x8A, 0x48, 0x98, 0x48, 0xBA, 0xBD, 0x04, + 0x01, 0x29, 0x10, 0xF0, 0x03, 0x6C, 0x16, 0x03, + 0x6C, 0x14, 0x03).withIndex()) { + ram[0xff48+b.index] = b.value.toShort() + } + bus.add(cpu) + bus.add(ram) + } + + private fun runTest(testprogram: String) { + ram.loadPrg("test/6502testsuite/$testprogram") + bus.reset() + cpu.SP = 0xfd + cpu.Status.fromByte(0b00100100) + try { + while (cpu.totalCycles < 50000000L) { + bus.clock() + } + fail("test hangs") + } catch (e: Cpu6502.InstructionError) { + println(">>> INSTRUCTION ERROR: ${e.message}") + } catch (le: KernalLoadNextPart) { + return // test ok + } catch (ie: KernalInputRequired) { + fail("test failed") + } + fail("test failed") + } + + @Test + fun test0start() { + runTest("0start") + } + + @Test + fun testAdca() { + runTest("adca") + } + + @Test + fun testAdcax() { + runTest("adcax") + } + + @Test + fun testAdcay() { + runTest("adcay") + } + + @Test + fun testAdcb() { + runTest("adcb") + } + + @Test + fun testAdcix() { + runTest("adcix") + } + + @Test + fun testAdciy() { + runTest("adciy") + } + + @Test + fun testAdcz() { + runTest("adcz") + } + + @Test + fun testAdczx() { + runTest("adczx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAlrb() { + runTest("alrb") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAncb() { + runTest("ancb") + } + + @Test + fun testAnda() { + runTest("anda") + } + + @Test + fun testAndax() { + runTest("andax") + } + + @Test + fun testAnday() { + runTest("anday") + } + + @Test + fun testAndb() { + runTest("andb") + } + + @Test + fun testAndix() { + runTest("andix") + } + + @Test + fun testAndiy() { + runTest("andiy") + } + + @Test + fun testAndz() { + runTest("andz") + } + + @Test + fun testAndzx() { + runTest("andzx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAneb() { + runTest("aneb") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testArrb() { + runTest("arrb") + } + + @Test + fun testAsla() { + runTest("asla") + } + + @Test + fun testAslax() { + runTest("aslax") + } + + @Test + fun testAsln() { + runTest("asln") + } + + @Test + fun testAslz() { + runTest("aslz") + } + + @Test + fun testAslzx() { + runTest("aslzx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoa() { + runTest("asoa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoax() { + runTest("asoax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoay() { + runTest("asoay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoix() { + runTest("asoix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoiy() { + runTest("asoiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsoz() { + runTest("asoz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAsozx() { + runTest("asozx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAxsa() { + runTest("axsa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAxsix() { + runTest("axsix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAxsz() { + runTest("axsz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testAxszy() { + runTest("axszy") + } + + @Test + fun testBccr() { + runTest("bccr") + } + + @Test + fun testBcsr() { + runTest("bcsr") + } + + @Test + fun testBeqr() { + runTest("beqr") + } + + @Test + fun testBita() { + runTest("bita") + } + + @Test + fun testBitz() { + runTest("bitz") + } + + @Test + fun testBmir() { + runTest("bmir") + } + + @Test + fun testBner() { + runTest("bner") + } + + @Test + fun testBplr() { + runTest("bplr") + } + + @Test + fun testBranchwrap() { + runTest("branchwrap") + } + + @Test + fun testBrkn() { + runTest("brkn") + } + + @Test + fun testBvcr() { + runTest("bvcr") + } + + @Test + fun testBvsr() { + runTest("bvsr") + } + + @Test + @Disabled("c64 specific component") + fun testCia1pb6() { + runTest("cia1pb6") + } + + @Test + @Disabled("c64 specific component") + fun testCia1pb7() { + runTest("cia1pb7") + } + + @Test + @Disabled("c64 specific component") + fun testCia1ta() { + runTest("cia1ta") + } + + @Test + @Disabled("c64 specific component") + fun testCia1tab() { + runTest("cia1tab") + } + + @Test + @Disabled("c64 specific component") + fun testCia1tb() { + runTest("cia1tb") + } + + @Test + @Disabled("c64 specific component") + fun testCia1tb123() { + runTest("cia1tb123") + } + + @Test + @Disabled("c64 specific component") + fun testCia2pb6() { + runTest("cia2pb6") + } + + @Test + @Disabled("c64 specific component") + fun testCia2pb7() { + runTest("cia2pb7") + } + + @Test + @Disabled("c64 specific component") + fun testCia2ta() { + runTest("cia2ta") + } + + @Test + @Disabled("c64 specific component") + fun testCia2tb() { + runTest("cia2tb") + } + + @Test + @Disabled("c64 specific component") + fun testCia2tb123() { + runTest("cia2tb123") + } + + @Test + fun testClcn() { + runTest("clcn") + } + + @Test + fun testCldn() { + runTest("cldn") + } + + @Test + fun testClin() { + runTest("clin") + } + + @Test + fun testClvn() { + runTest("clvn") + } + + @Test + fun testCmpa() { + runTest("cmpa") + } + + @Test + fun testCmpax() { + runTest("cmpax") + } + + @Test + fun testCmpay() { + runTest("cmpay") + } + + @Test + fun testCmpb() { + runTest("cmpb") + } + + @Test + fun testCmpix() { + runTest("cmpix") + } + + @Test + fun testCmpiy() { + runTest("cmpiy") + } + + @Test + fun testCmpz() { + runTest("cmpz") + } + + @Test + fun testCmpzx() { + runTest("cmpzx") + } + + @Test + @Disabled("c64 6510 specific component") + fun testCntdef() { + runTest("cntdef") + } + + @Test + @Disabled("c64 6510 specific component") + fun testCnto2() { + runTest("cnto2") + } + + @Test + @Disabled("c64 6510 specific component") + fun testCpuport() { + runTest("cpuport") + } + + @Test + @Disabled("todo: get all cycle times right") + fun testCputiming() { + runTest("cputiming") + } + + @Test + fun testCpxa() { + runTest("cpxa") + } + + @Test + fun testCpxb() { + runTest("cpxb") + } + + @Test + fun testCpxz() { + runTest("cpxz") + } + + @Test + fun testCpya() { + runTest("cpya") + } + + @Test + fun testCpyb() { + runTest("cpyb") + } + + @Test + fun testCpyz() { + runTest("cpyz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcma() { + runTest("dcma") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmax() { + runTest("dcmax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmay() { + runTest("dcmay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmix() { + runTest("dcmix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmiy() { + runTest("dcmiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmz() { + runTest("dcmz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testDcmzx() { + runTest("dcmzx") + } + + @Test + fun testDeca() { + runTest("deca") + } + + @Test + fun testDecax() { + runTest("decax") + } + + @Test + fun testDecz() { + runTest("decz") + } + + @Test + fun testDeczx() { + runTest("deczx") + } + + @Test + fun testDexn() { + runTest("dexn") + } + + @Test + fun testDeyn() { + runTest("deyn") + } + + @Test + fun testEora() { + runTest("eora") + } + + @Test + fun testEorax() { + runTest("eorax") + } + + @Test + fun testEoray() { + runTest("eoray") + } + + @Test + fun testEorb() { + runTest("eorb") + } + + @Test + fun testEorix() { + runTest("eorix") + } + + @Test + fun testEoriy() { + runTest("eoriy") + } + + @Test + fun testEorz() { + runTest("eorz") + } + + @Test + fun testEorzx() { + runTest("eorzx") + } + + @Test + @Disabled("c64 specific component") + fun testFlipos() { + runTest("flipos") + } + + @Test + @Disabled("c64 specific component") + fun testIcr01() { + runTest("icr01") + } + + @Test + @Disabled("c64 specific component") + fun testImr() { + runTest("imr") + } + + @Test + fun testInca() { + runTest("inca") + } + + @Test + fun testIncax() { + runTest("incax") + } + + @Test + fun testIncz() { + runTest("incz") + } + + @Test + fun testInczx() { + runTest("inczx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsa() { + runTest("insa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsax() { + runTest("insax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsay() { + runTest("insay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsix() { + runTest("insix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsiy() { + runTest("insiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInsz() { + runTest("insz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testInszx() { + runTest("inszx") + } + + @Test + fun testInxn() { + runTest("inxn") + } + + @Test + fun testInyn() { + runTest("inyn") + } + + @Test + @Disabled("c64 specific component") + fun testIrq() { + runTest("irq") + } + + @Test + fun testJmpi() { + runTest("jmpi") + } + + @Test + fun testJmpw() { + runTest("jmpw") + } + + @Test + fun testJsrw() { + runTest("jsrw") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLasay() { + runTest("lasay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxa() { + runTest("laxa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxay() { + runTest("laxay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxix() { + runTest("laxix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxiy() { + runTest("laxiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxz() { + runTest("laxz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLaxzy() { + runTest("laxzy") + } + + @Test + fun testLdaa() { + runTest("ldaa") + } + + @Test + fun testLdaax() { + runTest("ldaax") + } + + @Test + fun testLdaay() { + runTest("ldaay") + } + + @Test + fun testLdab() { + runTest("ldab") + } + + @Test + fun testLdaix() { + runTest("ldaix") + } + + @Test + fun testLdaiy() { + runTest("ldaiy") + } + + @Test + fun testLdaz() { + runTest("ldaz") + } + + @Test + fun testLdazx() { + runTest("ldazx") + } + + @Test + fun testLdxa() { + runTest("ldxa") + } + + @Test + fun testLdxay() { + runTest("ldxay") + } + + @Test + fun testLdxb() { + runTest("ldxb") + } + + @Test + fun testLdxz() { + runTest("ldxz") + } + + @Test + fun testLdxzy() { + runTest("ldxzy") + } + + @Test + fun testLdya() { + runTest("ldya") + } + + @Test + fun testLdyax() { + runTest("ldyax") + } + + @Test + fun testLdyb() { + runTest("ldyb") + } + + @Test + fun testLdyz() { + runTest("ldyz") + } + + @Test + fun testLdyzx() { + runTest("ldyzx") + } + + @Test + @Disabled("c64 specific component") + fun testLoadth() { + runTest("loadth") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLsea() { + runTest("lsea") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLseax() { + runTest("lseax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLseay() { + runTest("lseay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLseix() { + runTest("lseix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLseiy() { + runTest("lseiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLsez() { + runTest("lsez") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLsezx() { + runTest("lsezx") + } + + @Test + fun testLsra() { + runTest("lsra") + } + + @Test + fun testLsrax() { + runTest("lsrax") + } + + @Test + fun testLsrn() { + runTest("lsrn") + } + + @Test + fun testLsrz() { + runTest("lsrz") + } + + @Test + fun testLsrzx() { + runTest("lsrzx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testLxab() { + runTest("lxab") + } + + @Test + @Disabled("c64 6510 specific component") + fun testMmu() { + runTest("mmu") + } + + @Test + @Disabled("c64 6510 specific component") + fun testMmufetch() { + runTest("mmufetch") + } + + @Test + @Disabled("c64 specific component") + fun testNmi() { + runTest("nmi") + } + + @Test + fun testNopa() { + runTest("nopa") + } + + @Test + fun testNopax() { + runTest("nopax") + } + + @Test + fun testNopb() { + runTest("nopb") + } + + @Test + fun testNopn() { + runTest("nopn") + } + + @Test + fun testNopz() { + runTest("nopz") + } + + @Test + fun testNopzx() { + runTest("nopzx") + } + + @Test + @Disabled("c64 specific component") + fun testOneshot() { + runTest("oneshot") + } + + @Test + fun testOraa() { + runTest("oraa") + } + + @Test + fun testOraax() { + runTest("oraax") + } + + @Test + fun testOraay() { + runTest("oraay") + } + + @Test + fun testOrab() { + runTest("orab") + } + + @Test + fun testOraix() { + runTest("oraix") + } + + @Test + fun testOraiy() { + runTest("oraiy") + } + + @Test + fun testOraz() { + runTest("oraz") + } + + @Test + fun testOrazx() { + runTest("orazx") + } + + @Test + fun testPhan() { + runTest("phan") + } + + @Test + fun testPhpn() { + runTest("phpn") + } + + @Test + fun testPlan() { + runTest("plan") + } + + @Test + fun testPlpn() { + runTest("plpn") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaa() { + runTest("rlaa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaax() { + runTest("rlaax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaay() { + runTest("rlaay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaix() { + runTest("rlaix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaiy() { + runTest("rlaiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlaz() { + runTest("rlaz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRlazx() { + runTest("rlazx") + } + + @Test + fun testRola() { + runTest("rola") + } + + @Test + fun testRolax() { + runTest("rolax") + } + + @Test + fun testRoln() { + runTest("roln") + } + + @Test + fun testRolz() { + runTest("rolz") + } + + @Test + fun testRolzx() { + runTest("rolzx") + } + + @Test + fun testRora() { + runTest("rora") + } + + @Test + fun testRorax() { + runTest("rorax") + } + + @Test + fun testRorn() { + runTest("rorn") + } + + @Test + fun testRorz() { + runTest("rorz") + } + + @Test + fun testRorzx() { + runTest("rorzx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraa() { + runTest("rraa") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraax() { + runTest("rraax") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraay() { + runTest("rraay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraix() { + runTest("rraix") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraiy() { + runTest("rraiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRraz() { + runTest("rraz") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testRrazx() { + runTest("rrazx") + } + + @Test + fun testRtin() { + runTest("rtin") + } + + @Test + fun testRtsn() { + runTest("rtsn") + } + + @Test + fun testSbca() { + runTest("sbca") + } + + @Test + fun testSbcax() { + runTest("sbcax") + } + + @Test + fun testSbcay() { + runTest("sbcay") + } + + @Test + fun testSbcb() { + runTest("sbcb") + } + + @Test + fun testSbcb_eb() { + runTest("sbcb(eb)") + } + + @Test + fun testSbcix() { + runTest("sbcix") + } + + @Test + fun testSbciy() { + runTest("sbciy") + } + + @Test + fun testSbcz() { + runTest("sbcz") + } + + @Test + fun testSbczx() { + runTest("sbczx") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testSbxb() { + runTest("sbxb") + } + + @Test + fun testSecn() { + runTest("secn") + } + + @Test + fun testSedn() { + runTest("sedn") + } + + @Test + fun testSein() { + runTest("sein") + } + + @Test + @Disabled("not yet implemented- illegal instruction sha/ahx") + fun testShaay() { + runTest("shaay") + } + + @Test + @Disabled("not yet implemented- illegal instruction sha/ahx") + fun testShaiy() { + runTest("shaiy") + } + + @Test + @Disabled("not yet implemented- illegal instruction shs/tas") + fun testShsay() { + runTest("shsay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testShxay() { + runTest("shxay") + } + + @Test + @Disabled("not yet implemented- illegal instruction") + fun testShyax() { + runTest("shyax") + } + + @Test + fun testStaa() { + runTest("staa") + } + + @Test + fun testStaax() { + runTest("staax") + } + + @Test + fun testStaay() { + runTest("staay") + } + + @Test + fun testStaix() { + runTest("staix") + } + + @Test + fun testStaiy() { + runTest("staiy") + } + + @Test + fun testStaz() { + runTest("staz") + } + + @Test + fun testStazx() { + runTest("stazx") + } + + @Test + fun testStxa() { + runTest("stxa") + } + + @Test + fun testStxz() { + runTest("stxz") + } + + @Test + fun testStxzy() { + runTest("stxzy") + } + + @Test + fun testStya() { + runTest("stya") + } + + @Test + fun testStyz() { + runTest("styz") + } + + @Test + fun testStyzx() { + runTest("styzx") + } + + @Test + fun testTaxn() { + runTest("taxn") + } + + @Test + fun testTayn() { + runTest("tayn") + } + + @Test + fun testTsxn() { + runTest("tsxn") + } + + @Test + fun testTxan() { + runTest("txan") + } + + @Test + fun testTxsn() { + runTest("txsn") + } + + @Test + fun testTyan() { + runTest("tyan") + } + +} diff --git a/src/test/kotlin/Test65C02.kt b/src/test/kotlin/Test65C02.kt new file mode 100644 index 0000000..4ad03ca --- /dev/null +++ b/src/test/kotlin/Test65C02.kt @@ -0,0 +1,1548 @@ +import net.razorvine.ksim65.components.Cpu65C02 +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.TestInstance +import kotlin.test.* + +/* + +Unit test suite adapted from Py65 https://github.com/mnaberez/py65 + +Copyright (c) 2008-2018, Mike Naberezny and contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +@Disabled("there is no 65C02 cpu implementation at this time") // TODO create a 65c02 cpu and enable this again +class Test65C02 : TestCommon6502() { + // CMOS 65C02 Tests + override fun createCpu() = Cpu65C02(false) + + // Reset + + @Test + fun test_reset_clears_decimal_flag() { + // W65C02S Datasheet, Apr 14 2009, Table 7-1 Operational Enhancements + // NMOS 6502 decimal flag = indetermine after reset, CMOS 65C02 = 0 + mpu.Status.D = true + mpu.reset() + assertFalse(mpu.Status.D) + } + + // ADC Zero Page, Indirect + + @Test + fun test_adc_bcd_off_zp_ind_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_ind_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Status.C = true + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_zp_ind_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_ind_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_ind_overflow_cleared_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_ind_overflow_cleared_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_ind_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_ind_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_ind_overflow_set_on_40_plus_40() { + mpu.A = 0x40 + // $0000 ADC ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x72, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // AND Zero Page, Indirect + + @Test + fun test_and_zp_ind_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + // $0000 AND ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x32, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_zp_ind_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + // $0000 AND ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x32, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xAA + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // BIT (Absolute, X-Indexed) + + @Test + fun test_bit_abs_x_copies_bit_7_of_memory_to_n_flag_when_0() { + mpu.Status.N = false + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0xFF + mpu.A = 0xFF + mpu.step() + assertTrue(mpu.Status.N) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_copies_bit_7_of_memory_to_n_flag_when_1() { + mpu.Status.N = true + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0xFF + mpu.step() + assertFalse(mpu.Status.N) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_copies_bit_6_of_memory_to_v_flag_when_0() { + mpu.Status.V = false + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0xFF + mpu.A = 0xFF + mpu.step() + assertTrue(mpu.Status.V) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_copies_bit_6_of_memory_to_v_flag_when_1() { + mpu.Status.V = true + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0xFF + mpu.step() + assertFalse(mpu.Status.V) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_stores_result_of_and_in_z_preserves_a_when_1() { + mpu.Status.Z = false + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0xFEED]) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_stores_result_of_and_nonzero_in_z_preserves_a() { + mpu.Status.Z = true + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0x01 + mpu.A = 0x01 + mpu.step() + assertFalse(mpu.Status.Z) // result of AND is non-zero + assertEquals(0x01, mpu.A) + assertEquals(0x01, memory[0xFEED]) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + @Test + fun test_bit_abs_x_stores_result_of_and_when_zero_in_z_preserves_a() { + mpu.Status.Z = false + mpu.X = 0x02 + // $0000 BIT $FEEB,X + writeMem(memory, 0x0000, listOf(0x3C, 0xEB, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) // result of AND is zero + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0xFEED]) + assertEquals(4, mpu.totalCycles) + assertEquals(0x0003, mpu.PC) + } + + // BIT (Immediate) + + @Test + fun test_bit_imm_does_not_affect_n_and_z_flags() { + mpu.Status.N = true + mpu.Status.V = true + // $0000 BIT #$FF + writeMem(memory, 0x0000, listOf(0x89, 0xff)) + mpu.A = 0x00 + mpu.step() + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertEquals(0x00, mpu.A) + assertEquals(2, mpu.totalCycles) + assertEquals(0x02, mpu.PC) + } + + @Test + fun test_bit_imm_stores_result_of_and_in_z_preserves_a_when_1() { + mpu.Status.Z = false + // $0000 BIT #$00 + writeMem(memory, 0x0000, listOf(0x89, 0x00)) + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) + assertEquals(0x01, mpu.A) + assertEquals(2, mpu.totalCycles) + assertEquals(0x02, mpu.PC) + } + + @Test + fun test_bit_imm_stores_result_of_and_when_nonzero_in_z_preserves_a() { + mpu.Status.Z = true + // $0000 BIT #$01 + writeMem(memory, 0x0000, listOf(0x89, 0x01)) + mpu.A = 0x01 + mpu.step() + assertFalse(mpu.Status.Z) // result of AND is non-zero + assertEquals(0x01, mpu.A) + assertEquals(2, mpu.totalCycles) + assertEquals(0x02, mpu.PC) + } + + @Test + fun test_bit_imm_stores_result_of_and_when_zero_in_z_preserves_a() { + mpu.Status.Z = false + // $0000 BIT #$00 + writeMem(memory, 0x0000, listOf(0x89, 0x00)) + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) // result of AND is zero + assertEquals(0x01, mpu.A) + assertEquals(2, mpu.totalCycles) + assertEquals(0x02, mpu.PC) + } + + // BIT (Zero Page, X-Indexed) + + @Test + fun test_bit_zp_x_copies_bit_7_of_memory_to_n_flag_when_0() { + mpu.Status.N = false + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0xFF + mpu.X = 0x03 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertTrue(mpu.Status.N) + } + + @Test + fun test_bit_zp_x_copies_bit_7_of_memory_to_n_flag_when_1() { + mpu.Status.N = true + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0x00 + mpu.X = 0x03 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertFalse(mpu.Status.N) + } + + @Test + fun test_bit_zp_x_copies_bit_6_of_memory_to_v_flag_when_0() { + mpu.Status.V = false + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0xFF + mpu.X = 0x03 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertTrue(mpu.Status.V) + } + + @Test + fun test_bit_zp_x_copies_bit_6_of_memory_to_v_flag_when_1() { + mpu.Status.V = true + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0x00 + mpu.X = 0x03 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertFalse(mpu.Status.V) + } + + @Test + fun test_bit_zp_x_stores_result_of_and_in_z_preserves_a_when_1() { + mpu.Status.Z = false + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0x00 + mpu.X = 0x03 + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0x0010 + mpu.X]) + } + + @Test + fun test_bit_zp_x_stores_result_of_and_when_nonzero_in_z_preserves_a() { + mpu.Status.Z = true + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0x01 + mpu.X = 0x03 + mpu.A = 0x01 + mpu.step() + assertFalse(mpu.Status.Z) // result of AND is non-zero + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertEquals(0x01, mpu.A) + assertEquals(0x01, memory[0x0010 + mpu.X]) + } + + @Test + fun test_bit_zp_x_stores_result_of_and_when_zero_in_z_preserves_a() { + mpu.Status.Z = false + // $0000 BIT $0010,X + writeMem(memory, 0x0000, listOf(0x34, 0x10)) + memory[0x0013] = 0x00 + mpu.X = 0x03 + mpu.A = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + assertTrue(mpu.Status.Z) // result of AND is zero + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0x0010 + mpu.X]) + } + + // BRK + + @Test + fun test_brk_clears_decimal_flag() { + mpu.Status.D = true + // $C000 BRK + memory[0xC000] = 0x00 + mpu.PC = 0xC000 + mpu.step() + assertTrue(mpu.Status.B) + assertFalse(mpu.Status.D) + } + + // CMP Zero Page, Indirect + + @Test + fun test_cmp_zpi_sets_z_flag_if_equal() { + mpu.A = 0x42 + // $0000 AND ($10) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xd2, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x42 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x42, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_cmp_zpi_resets_z_flag_if_unequal() { + mpu.A = 0x43 + // $0000 AND ($10) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xd2, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x42 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x43, mpu.A) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // EOR Zero Page, Indirect + + @Test + fun test_eor_zp_ind_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + // $0000 EOR ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x52, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_zp_ind_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + // $0000 EOR ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x52, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // INC Accumulator + + @Test + fun test_inc_acc_increments_accum() { + memory[0x0000] = 0x1A + mpu.A = 0x42 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x43, mpu.A) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_acc_increments_accum_rolls_over_and_sets_zero_flag() { + memory[0x0000] = 0x1A + mpu.A = 0xFF + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_acc_sets_negative_flag_when_incrementing_above_7F() { + memory[0x0000] = 0x1A + mpu.A = 0x7F + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + // JMP Indirect + + @Test + fun test_jmp_ind_does_not_have_page_wrap_bug() { + writeMem(memory, 0x10FF, listOf(0xCD, 0xAB)) + // $0000 JMP ($10FF) + writeMem(memory, 0, listOf(0x6c, 0xFF, 0x10)) + mpu.step() + assertEquals(0xABCD, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + // JMP Indirect Absolute X-Indexed + + @Test + fun test_jmp_iax_jumps_to_address() { + mpu.X = 2 + // $0000 JMP ($ABCD,X) + // $ABCF Vector to $1234 + writeMem(memory, 0x0000, listOf(0x7C, 0xCD, 0xAB)) + writeMem(memory, 0xABCF, listOf(0x34, 0x12)) + mpu.step() + assertEquals(0x1234, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + // LDA Zero Page, Indirect + + @Test + fun test_lda_zp_ind_loads_a_sets_n_flag() { + mpu.A = 0x00 + // $0000 LDA ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xB2, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_zp_ind_loads_a_sets_z_flag() { + mpu.A = 0x00 + // $0000 LDA ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xB2, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // ORA Zero Page, Indirect + + @Test + fun test_ora_zp_ind_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.Y = 0x12 // These should not affect the ORA + mpu.X = 0x34 + // $0000 ORA ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x12, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_zp_ind_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + // $0000 ORA ($0010) + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x12, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x82 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // PHX + + @Test + fun test_phx_pushes_x_and_updates_sp() { + mpu.X = 0xAB + // $0000 PHX + memory[0x0000] = 0xDA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.X) + assertEquals(0xAB, memory[0x01FF]) + assertEquals(0xFE, mpu.SP) + assertEquals(3, mpu.totalCycles) + } + + // PHY + + @Test + fun test_phy_pushes_y_and_updates_sp() { + mpu.Y = 0xAB + // $0000 PHY + memory[0x0000] = 0x5A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.Y) + assertEquals(0xAB, memory[0x01FF]) + assertEquals(0xFE, mpu.SP) + assertEquals(3, mpu.totalCycles) + } + + // PLX + + @Test + fun test_plx_pulls_top_byte_from_stack_into_x_and_updates_sp() { + // $0000 PLX + memory[0x0000] = 0xFA + memory[0x01FF] = 0xAB + mpu.SP = 0xFE + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.X) + assertEquals(0xFF, mpu.SP) + assertEquals(4, mpu.totalCycles) + } + + // PLY + + @Test + fun test_ply_pulls_top_byte_from_stack_into_y_and_updates_sp() { + // $0000 PLY + memory[0x0000] = 0x7A + memory[0x01FF] = 0xAB + mpu.SP = 0xFE + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.Y) + assertEquals(0xFF, mpu.SP) + assertEquals(4, mpu.totalCycles) + } + + // RMB0 + + @Test + fun test_rmb0_clears_bit_0_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB0 $43 + writeMem(memory, 0x0000, listOf(0x07, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11111110 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb0_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB0 $43 + writeMem(memory, 0x0000, listOf(0x07, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB1 + + @Test + fun test_rmb1_clears_bit_1_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB1 $43 + writeMem(memory, 0x0000, listOf(0x17, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11111101 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb1_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB1 $43 + writeMem(memory, 0x0000, listOf(0x17, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB2 + + @Test + fun test_rmb2_clears_bit_2_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB2 $43 + writeMem(memory, 0x0000, listOf(0x27, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11111011 + assertEquals(expected, memory[0x0043].toInt()) + + } + + @Test + fun test_rmb2_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB2 $43 + writeMem(memory, 0x0000, listOf(0x27, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB3 + + @Test + fun test_rmb3_clears_bit_3_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB3 $43 + writeMem(memory, 0x0000, listOf(0x37, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11110111 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb3_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB3 $43 + writeMem(memory, 0x0000, listOf(0x37, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB4 + + @Test + fun test_rmb4_clears_bit_4_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB4 $43 + writeMem(memory, 0x0000, listOf(0x47, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11101111 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb4_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB4 $43 + writeMem(memory, 0x0000, listOf(0x47, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB5 + + @Test + fun test_rmb5_clears_bit_5_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB5 $43 + writeMem(memory, 0x0000, listOf(0x57, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b11011111 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb5_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB5 $43 + writeMem(memory, 0x0000, listOf(0x57, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB6 + + @Test + fun test_rmb6_clears_bit_6_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB6 $43 + writeMem(memory, 0x0000, listOf(0x67, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b10111111 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_rmb6_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB6 $43 + writeMem(memory, 0x0000, listOf(0x67, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // RMB7 + + @Test + fun test_rmb7_clears_bit_7_without_affecting_other_bits() { + memory[0x0043] = 0b11111111 + // $0000 RMB7 $43 + writeMem(memory, 0x0000, listOf(0x77, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b01111111 + assertEquals(expected, memory[0x0043].toInt()) + + } + + @Test + fun test_rmb7_does_not_affect_status_register() { + memory[0x0043] = 0b11111111 + // $0000 RMB7 $43 + writeMem(memory, 0x0000, listOf(0x77, 0x43)) + val expected = 0b01010101 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // STA Zero Page, Indirect + + @Test + fun test_sta_zp_ind_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + // $0000 STA ($0010) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x92, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0xFF, memory[0xFEED]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_zp_ind_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + // $0000 STA ($0010) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x92, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, memory[0xFEED]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // SMB0 + + @Test + fun test_smb0_sets_bit_0_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB0 $43 + writeMem(memory, 0x0000, listOf(0x87, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00000001 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_smb0_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB0 $43 + writeMem(memory, 0x0000, listOf(0x87, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB1 + + @Test + fun test_smb1_sets_bit_1_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB1 $43 + writeMem(memory, 0x0000, listOf(0x97, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00000010 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_smb1_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB1 $43 + writeMem(memory, 0x0000, listOf(0x97, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB2 + + @Test + fun test_smb2_sets_bit_2_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB2 $43 + writeMem(memory, 0x0000, listOf(0xA7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00000100 + assertEquals(expected, memory[0x0043].toInt()) + + } + + @Test + fun test_smb2_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB2 $43 + writeMem(memory, 0x0000, listOf(0xA7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB3 + + @Test + fun test_smb3_sets_bit_3_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB3 $43 + writeMem(memory, 0x0000, listOf(0xB7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00001000 + assertEquals(expected, memory[0x0043].toInt()) + + } + + @Test + fun test_smb3_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB3 $43 + writeMem(memory, 0x0000, listOf(0xB7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB4 + + @Test + fun test_smb4_sets_bit_4_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB4 $43 + writeMem(memory, 0x0000, listOf(0xC7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00010000 + assertEquals(expected, memory[0x0043].toInt()) + + } + + @Test + fun test_smb4_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB4 $43 + writeMem(memory, 0x0000, listOf(0xC7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB5 + + @Test + fun test_smb5_sets_bit_5_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB5 $43 + writeMem(memory, 0x0000, listOf(0xD7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b00100000 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_smb5_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB5 $43 + writeMem(memory, 0x0000, listOf(0xD7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB6 + + @Test + fun test_smb6_sets_bit_6_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB6 $43 + writeMem(memory, 0x0000, listOf(0xE7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b01000000 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_smb6_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB6 $43 + writeMem(memory, 0x0000, listOf(0xE7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SMB7 + + @Test + fun test_smb7_sets_bit_7_without_affecting_other_bits() { + memory[0x0043] = 0b00000000 + // $0000 SMB7 $43 + writeMem(memory, 0x0000, listOf(0xF7, 0x43)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + val expected = 0b10000000 + assertEquals(expected, memory[0x0043].toInt()) + } + + @Test + fun test_smb7_does_not_affect_status_register() { + memory[0x0043] = 0b00000000 + // $0000 SMB7 $43 + writeMem(memory, 0x0000, listOf(0xF7, 0x43)) + val expected = 0b11001100 + mpu.Status.fromByte(expected) + mpu.step() + assertEquals(expected, mpu.Status.asByte().toInt()) + } + + // SBC Zero Page, Indirect + + @Test + fun test_sbc_zp_ind_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC ($10) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF2, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_ind_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC ($10) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF2, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_ind_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC ($10) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF2, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_ind_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC ($10) + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF2, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x02 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // STZ Zero Page + + @Test + fun test_stz_zp_stores_zero() { + memory[0x0032] = 0x88 + // #0000 STZ $32 + memory[0x0000] = 0x64 + memory[0x0001] = 0x32 + assertEquals(0x88, memory[0x0032]) + mpu.step() + assertEquals(0x00, memory[0x0032]) + assertEquals(0x0002, mpu.PC) + assertEquals(3, mpu.totalCycles) + } + + // STZ Zero Page, X-Indexed + + @Test + fun test_stz_zp_x_stores_zero() { + memory[0x0032] = 0x88 + // $0000 STZ $32,X + memory[0x0000] = 0x74 + memory[0x0001] = 0x32 + assertEquals(0x88, memory[0x0032]) + mpu.step() + assertEquals(0x00, memory[0x0032]) + assertEquals(0x0002, mpu.PC) + assertEquals(4, mpu.totalCycles) + } + + // STZ Absolute + + @Test + fun test_stz_abs_stores_zero() { + memory[0xFEED] = 0x88 + // $0000 STZ $FEED + writeMem(memory, 0x0000, listOf(0x9C, 0xED, 0xFE)) + assertEquals(0x88, memory[0xFEED]) + mpu.step() + assertEquals(0x00, memory[0xFEED]) + assertEquals(0x0003, mpu.PC) + assertEquals(4, mpu.totalCycles) + } + + // STZ Absolute, X-Indexed + + @Test + fun test_stz_abs_x_stores_zero() { + memory[0xFEED] = 0x88 + mpu.X = 0x0D + // $0000 STZ $FEE0,X + writeMem(memory, 0x0000, listOf(0x9E, 0xE0, 0xFE)) + assertEquals(0x88, memory[0xFEED]) + assertEquals(0x0D, mpu.X) + mpu.step() + assertEquals(0x00, memory[0xFEED]) + assertEquals(0x0003, mpu.PC) + assertEquals(5, mpu.totalCycles) + } + + // TSB Zero Page + + @Test + fun test_tsb_zp_ones() { + memory[0x00BB] = 0xE0 + // $0000 TSB $BD + writeMem(memory, 0x0000, listOf(0x04, 0xBB)) + mpu.A = 0x70 + assertEquals(0xE0, memory[0x00BB]) + mpu.step() + assertEquals(0xF0, memory[0x00BB]) + assertFalse(mpu.Status.Z) + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + } + + @Test + fun test_tsb_zp_zeros() { + memory[0x00BB] = 0x80 + // $0000 TSB $BD + writeMem(memory, 0x0000, listOf(0x04, 0xBB)) + mpu.A = 0x60 + assertEquals(0x80, memory[0x00BB]) + mpu.step() + assertEquals(0xE0, memory[0x00BB]) + assertTrue(mpu.Status.Z) + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + } + + // TSB Absolute + + @Test + fun test_tsb_abs_ones() { + memory[0xFEED] = 0xE0 + // $0000 TSB $FEED + writeMem(memory, 0x0000, listOf(0x0C, 0xED, 0xFE)) + mpu.A = 0x70 + assertEquals(0xE0, memory[0xFEED]) + mpu.step() + assertEquals(0xF0, memory[0xFEED]) + assertFalse(mpu.Status.Z) + assertEquals(0x0003, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + @Test + fun test_tsb_abs_zeros() { + memory[0xFEED] = 0x80 + // $0000 TSB $FEED + writeMem(memory, 0x0000, listOf(0x0C, 0xED, 0xFE)) + mpu.A = 0x60 + assertEquals(0x80, memory[0xFEED]) + mpu.step() + assertEquals(0xE0, memory[0xFEED]) + assertTrue(mpu.Status.Z) + assertEquals(0x0003, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + // TRB Zero Page + + @Test + fun test_trb_zp_ones() { + memory[0x00BB] = 0xE0 + // $0000 TRB $BD + writeMem(memory, 0x0000, listOf(0x14, 0xBB)) + mpu.A = 0x70 + assertEquals(0xE0, memory[0x00BB]) + mpu.step() + assertEquals(0x80, memory[0x00BB]) + assertFalse(mpu.Status.Z) + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + } + + @Test + fun test_trb_zp_zeros() { + memory[0x00BB] = 0x80 + // $0000 TRB $BD + writeMem(memory, 0x0000, listOf(0x14, 0xBB)) + mpu.A = 0x60 + assertEquals(0x80, memory[0x00BB]) + mpu.step() + assertEquals(0x80, memory[0x00BB]) + assertTrue(mpu.Status.Z) + assertEquals(0x0002, mpu.PC) + assertEquals(5, mpu.totalCycles) + } + + // TRB Absolute + + @Test + fun test_trb_abs_ones() { + memory[0xFEED] = 0xE0 + // $0000 TRB $FEED + writeMem(memory, 0x0000, listOf(0x1C, 0xED, 0xFE)) + mpu.A = 0x70 + assertEquals(0xE0, memory[0xFEED]) + mpu.step() + assertEquals(0x80, memory[0xFEED]) + assertFalse(mpu.Status.Z) + assertEquals(0x0003, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + @Test + fun test_trb_abs_zeros() { + memory[0xFEED] = 0x80 + // $0000 TRB $FEED + writeMem(memory, 0x0000, listOf(0x1C, 0xED, 0xFE)) + mpu.A = 0x60 + assertEquals(0x80, memory[0xFEED]) + mpu.step() + assertEquals(0x80, memory[0xFEED]) + assertTrue(mpu.Status.Z) + assertEquals(0x0003, mpu.PC) + assertEquals(6, mpu.totalCycles) + } + + @Test + fun test_dec_a_decreases_a() { + // $0000 DEC A + memory[0x0000] = 0x3a + mpu.A = 0x48 + mpu.step() + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + assertEquals(0x47, mpu.A) + } + + @Test + fun test_dec_a_sets_zero_flag() { + // $0000 DEC A + memory[0x0000] = 0x3a + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + assertEquals(0x00, mpu.A) + } + + @Test + fun test_dec_a_wraps_at_zero() { + // $0000 DEC A + memory[0x0000] = 0x3a + mpu.A = 0x00 + mpu.step() + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + assertEquals(0xFF, mpu.A) + } + + @Test + fun test_bra_forward() { + // $0000 BRA $10 + writeMem(memory, 0x0000, listOf(0x80, 0x10)) + mpu.step() + assertEquals(0x12, mpu.PC) + assertEquals(2, mpu.totalCycles) + } + + @Test + fun test_bra_backward() { + // $0240 BRA $F0 + writeMem(memory, 0x0000, listOf(0x80, 0xF0)) + mpu.PC = 0x0204 + mpu.step() + assertEquals(0x1F6, mpu.PC) + assertEquals(3, mpu.totalCycles) // Crossed boundry + } + + // WAI + + @Test + fun test_wai_sets_waiting() { + mpu as Cpu65C02 + assertFalse(mpu.waiting) + // $0240 WAI + memory[0x0204] = 0xcb + mpu.PC = 0x0204 + mpu.step() + assertTrue(mpu.waiting) + assertEquals(0x0205, mpu.PC) + assertEquals(3, mpu.totalCycles) + } +} diff --git a/src/test/kotlin/TestCommon6502.kt b/src/test/kotlin/TestCommon6502.kt new file mode 100644 index 0000000..5691a91 --- /dev/null +++ b/src/test/kotlin/TestCommon6502.kt @@ -0,0 +1,6257 @@ +import net.razorvine.ksim65.components.* +import org.junit.jupiter.api.TestInstance +import kotlin.test.* + +/* + +Unit test suite adapted from Py65 https://github.com/mnaberez/py65 + +Copyright (c) 2008-2018, Mike Naberezny and contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +abstract class TestCommon6502 { + // Tests common to 6502-based microprocessors + + val mpu: Cpu6502 + val memory = Ram(0, 0xffff) + val bus = Bus() + + abstract fun createCpu(): Cpu6502 + + init { + mpu = createCpu() + bus.add(mpu) + bus.add(memory) + memory.fill(0xaa) + memory[Cpu6502.RESET_vector] = 0 + memory[Cpu6502.RESET_vector + 1] = 0 + mpu.reset() + mpu.Status.I = false // allow interrupts again + } + + companion object { + // processor flags + const val fNEGATIVE = 128 + const val fOVERFLOW = 64 + const val fUNUSED = 32 + const val fBREAK = 16 + const val fDECIMAL = 8 + const val fINTERRUPT = 4 + const val fZERO = 2 + const val fCARRY = 1 + } + + // test helpers + fun writeMem(memory: MemMappedComponent, startAddress: Address, data: Iterable) { + var addr = startAddress + data.forEach { memory[addr++] = it } + } + + + // Reset + @Test + fun test_reset_sets_registers_to_initial_states() { + + mpu.reset() + assertEquals(0xFD, mpu.SP) + assertEquals(0, mpu.A) + assertEquals(0, mpu.X) + assertEquals(0, mpu.Y) + assertTrue(mpu.Status.I) // the other status flags are undefined after reset + } + + // ADC Absolute + + @Test + fun test_adc_bcd_off_absolute_carry_clear_in_accumulator_zeroes() { + mpu.A = 0 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + // assertEquals(0x10000, memory.size) + + memory[0xC000] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_absolute_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Status.C = true + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_absolute_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0xFE + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_absolute_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_absolute_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_absolute_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0xff + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_absolute_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_absolute_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0xff + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_absolute_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + // $0000 ADC $C000 + writeMem(memory, 0x0000, listOf(0x6D, 0x00, 0xC0)) + memory[0xC000] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Zero Page + + @Test + fun test_adc_bcd_off_zp_carry_clear_in_accumulator_zeroes() { + mpu.A = 0 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Status.C = true + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_zp_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0xff + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0xff + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_overflow_set_on_40_plus_40() { + mpu.A = 0x40 + mpu.Status.V = false + // $0000 ADC $00B0 + writeMem(memory, 0x0000, listOf(0x65, 0xB0)) + memory[0x00B0] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Immediate + + @Test + fun test_adc_bcd_off_immediate_carry_clear_in_accumulator_zeroes() { + mpu.A = 0 + // $0000 ADC #$00 + writeMem(memory, 0x0000, listOf(0x69, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_immediate_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Status.C = true + // $0000 ADC #$00 + writeMem(memory, 0x0000, listOf(0x69, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_immediate_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + // $0000 ADC #$FE + writeMem(memory, 0x0000, listOf(0x69, 0xFE)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_immediate_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + // $0000 ADC #$FF + writeMem(memory, 0x0000, listOf(0x69, 0xFF)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_immediate_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC #$01 + writeMem(memory, 0x000, listOf(0x69, 0x01)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_immediate_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC #$FF + writeMem(memory, 0x000, listOf(0x69, 0xff)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_immediate_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC #$01 + writeMem(memory, 0x000, listOf(0x69, 0x01)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_immediate_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC #$FF + writeMem(memory, 0x000, listOf(0x69, 0xff)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_immediate_overflow_set_on_40_plus_40() { + mpu.A = 0x40 + // $0000 ADC #$40 + writeMem(memory, 0x0000, listOf(0x69, 0x40)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_on_immediate_79_plus_00_carry_set() { + mpu.Status.D = true + mpu.Status.C = true + mpu.A = 0x79 + // $0000 ADC #$00 + writeMem(memory, 0x0000, listOf(0x69, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_on_immediate_6f_plus_00_carry_set() { + mpu.Status.D = true + mpu.Status.C = true + mpu.A = 0x6f + // $0000 ADC #$00 + writeMem(memory, 0x0000, listOf(0x69, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x76, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.V) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_on_immediate_9c_plus_9d() { + mpu.Status.D = true + mpu.Status.C = false + mpu.Status.N = true + mpu.A = 0x9c + // $0000 ADC #$9d + // $0002 ADC #$9d + writeMem(memory, 0x0000, listOf(0x69, 0x9d)) + writeMem(memory, 0x0002, listOf(0x69, 0x9d)) + mpu.step() + assertEquals(0x9f, mpu.A) + assertTrue(mpu.Status.C) + mpu.step() + assertEquals(0x0004, mpu.PC) + assertEquals(0x93, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.N) + } + + // ADC Absolute, X-Indexed + + @Test + fun test_adc_bcd_off_abs_x_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_x_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_abs_x_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0xFE + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_x_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + mpu.X = 0x03 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_x_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_x_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0xff + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_x_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_x_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0xff + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_x_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + mpu.X = 0x03 + // $0000 ADC $C000,X + writeMem(memory, 0x0000, listOf(0x7D, 0x00, 0xC0)) + memory[0xC000 + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Absolute, Y-Indexed + + @Test + fun test_adc_bcd_off_abs_y_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_y_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Y = 0x03 + mpu.Status.C = true + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_abs_y_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + mpu.Y = 0x03 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0xFE + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_y_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + mpu.Y = 0x03 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_abs_y_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_y_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_y_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_y_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_abs_y_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + mpu.Y = 0x03 + // $0000 ADC $C000,Y + writeMem(memory, 0x0000, listOf(0x79, 0x00, 0xC0)) + memory[0xC000 + mpu.Y] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Zero Page, X-Indexed + + @Test + fun test_adc_bcd_off_zp_x_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_x_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_zp_x_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_x_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_zp_x_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_x_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_x_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_x_overflow_set_no_carry_80_plus_ff() { + + mpu.Status.C = false + mpu.A = 0x80 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0xff + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_zp_x_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + mpu.X = 0x03 + // $0000 ADC $0010,X + writeMem(memory, 0x0000, listOf(0x75, 0x10)) + memory[0x0010 + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Indirect, Indexed (X) + + @Test + fun test_adc_bcd_off_ind_indexed_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_ind_indexed_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_ind_indexed_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_ind_indexed_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_ind_indexed_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_ind_indexed_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_ind_indexed_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_ind_indexed_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_ind_indexed_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + mpu.X = 0x03 + // $0000 ADC ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x61, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // ADC Indexed, Indirect (Y) + + @Test + fun test_adc_bcd_off_indexed_ind_carry_clear_in_accumulator_zeroes() { + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_indexed_ind_carry_set_in_accumulator_zero() { + mpu.A = 0 + mpu.Y = 0x03 + mpu.Status.C = true + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_adc_bcd_off_indexed_ind_carry_clear_in_no_carry_clear_out() { + mpu.A = 0x01 + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_indexed_ind_carry_clear_in_carry_set_out() { + mpu.A = 0x02 + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, mpu.A) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_adc_bcd_off_indexed_ind_overflow_clr_no_carry_01_plus_01() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.Y = 0x03 + // $0000 $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_indexed_ind_overflow_clr_no_carry_01_plus_ff() { + mpu.Status.C = false + mpu.A = 0x01 + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_indexed_ind_overflow_set_no_carry_7f_plus_01() { + mpu.Status.C = false + mpu.A = 0x7f + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_indexed_ind_overflow_set_no_carry_80_plus_ff() { + mpu.Status.C = false + mpu.A = 0x80 + mpu.Y = 0x03 + // $0000 $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x7f, mpu.A) + assertTrue(mpu.Status.V) + } + + @Test + fun test_adc_bcd_off_indexed_ind_overflow_set_on_40_plus_40() { + mpu.Status.V = false + mpu.A = 0x40 + mpu.Y = 0x03 + // $0000 ADC ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x71, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertTrue(mpu.Status.V) + assertFalse(mpu.Status.Z) + } + + // AND (Absolute) + + @Test + fun test_and_absolute_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + // $0000 AND $ABCD + writeMem(memory, 0x0000, listOf(0x2D, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_absolute_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + // $0000 AND $ABCD + writeMem(memory, 0x0000, listOf(0x2D, 0xCD, 0xAB)) + memory[0xABCD] = 0xAA + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND (Absolute) + + @Test + fun test_and_zp_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + // $0000 AND $0010 + writeMem(memory, 0x0000, listOf(0x25, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_zp_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + // $0000 AND $0010 + writeMem(memory, 0x0000, listOf(0x25, 0x10)) + memory[0x0010] = 0xAA + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND (Immediate) + + @Test + fun test_and_immediate_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + // $0000 AND #$00 + writeMem(memory, 0x0000, listOf(0x29, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_immediate_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + // $0000 AND #$AA + writeMem(memory, 0x0000, listOf(0x29, 0xAA)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND (Absolute, X-Indexed) + + @Test + fun test_and_abs_x_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND $ABCD,X + writeMem(memory, 0x0000, listOf(0x3d, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_abs_x_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND $ABCD,X + writeMem(memory, 0x0000, listOf(0x3d, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xAA + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND (Absolute, Y-Indexed) + + @Test + fun test_and_abs_y_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 AND $ABCD,X + writeMem(memory, 0x0000, listOf(0x39, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_abs_y_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 AND $ABCD,X + writeMem(memory, 0x0000, listOf(0x39, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xAA + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND Indirect, Indexed (X) + + @Test + fun test_and_ind_indexed_x_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x21, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_ind_indexed_x_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x21, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0xAA + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND Indexed, Indirect (Y) + + @Test + fun test_and_indexed_ind_y_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 AND ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x31, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_indexed_ind_y_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 AND ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x31, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xAA + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // AND Zero Page, X-Indexed + + @Test + fun test_and_zp_x_all_zeros_setting_zero_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND $0010,X + writeMem(memory, 0x0000, listOf(0x35, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_and_zp_x_all_zeros_and_ones_setting_negative_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 AND $0010,X + writeMem(memory, 0x0000, listOf(0x35, 0x10)) + memory[0x0010 + mpu.X] = 0xAA + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ASL Accumulator + + @Test + fun test_asl_accumulator_sets_z_flag() { + mpu.A = 0x00 + // $0000 ASL A + memory[0x0000] = 0x0A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_asl_accumulator_sets_n_flag() { + mpu.A = 0x40 + // $0000 ASL A + memory[0x0000] = 0x0A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_asl_accumulator_shifts_out_zero() { + mpu.A = 0x7F + // $0000 ASL A + memory[0x0000] = 0x0A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFE, mpu.A) + assertFalse(mpu.Status.C) + } + + @Test + fun test_asl_accumulator_shifts_out_one() { + mpu.A = 0xFF + // $0000 ASL A + memory[0x0000] = 0x0A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFE, mpu.A) + assertTrue(mpu.Status.C) + } + + @Test + fun test_asl_accumulator_80_sets_z_flag() { + mpu.A = 0x80 + mpu.Status.Z = false + // $0000 ASL A + memory[0x0000] = 0x0A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + // ASL Absolute + + @Test + fun test_asl_absolute_sets_z_flag() { + // $0000 ASL $ABCD + writeMem(memory, 0x0000, listOf(0x0E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_asl_absolute_sets_n_flag() { + // $0000 ASL $ABCD + writeMem(memory, 0x0000, listOf(0x0E, 0xCD, 0xAB)) + memory[0xABCD] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_asl_absolute_shifts_out_zero() { + mpu.A = 0xAA + // $0000 ASL $ABCD + writeMem(memory, 0x0000, listOf(0x0E, 0xCD, 0xAB)) + memory[0xABCD] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0xABCD]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_asl_absolute_shifts_out_one() { + mpu.A = 0xAA + // $0000 ASL $ABCD + writeMem(memory, 0x0000, listOf(0x0E, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0xABCD]) + assertTrue(mpu.Status.C) + } + + // ASL Zero Page + + @Test + fun test_asl_zp_sets_z_flag() { + // $0000 ASL $0010 + writeMem(memory, 0x0000, listOf(0x06, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_asl_zp_sets_n_flag() { + // $0000 ASL $0010 + writeMem(memory, 0x0000, listOf(0x06, 0x10)) + memory[0x0010] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_asl_zp_shifts_out_zero() { + mpu.A = 0xAA + // $0000 ASL $0010 + writeMem(memory, 0x0000, listOf(0x06, 0x10)) + memory[0x0010] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0x0010]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_asl_zp_shifts_out_one() { + mpu.A = 0xAA + // $0000 ASL $0010 + writeMem(memory, 0x0000, listOf(0x06, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0x0010]) + assertTrue(mpu.Status.C) + } + + // ASL Absolute, X-Indexed + + @Test + fun test_asl_abs_x_indexed_sets_z_flag() { + mpu.X = 0x03 + // $0000 ASL $ABCD,X + writeMem(memory, 0x0000, listOf(0x1E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_asl_abs_x_indexed_sets_n_flag() { + mpu.X = 0x03 + // $0000 ASL $ABCD,X + writeMem(memory, 0x0000, listOf(0x1E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_asl_abs_x_indexed_shifts_out_zero() { + mpu.A = 0xAA + mpu.X = 0x03 + // $0000 ASL $ABCD,X + writeMem(memory, 0x0000, listOf(0x1E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_asl_abs_x_indexed_shifts_out_one() { + mpu.A = 0xAA + mpu.X = 0x03 + // $0000 ASL $ABCD,X + writeMem(memory, 0x0000, listOf(0x1E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.C) + } + + // ASL Zero Page, X-Indexed + + @Test + fun test_asl_zp_x_indexed_sets_z_flag() { + mpu.X = 0x03 + // $0000 ASL $0010,X + writeMem(memory, 0x0000, listOf(0x16, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_asl_zp_x_indexed_sets_n_flag() { + mpu.X = 0x03 + // $0000 ASL $0010,X + writeMem(memory, 0x0000, listOf(0x16, 0x10)) + memory[0x0010 + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_asl_zp_x_indexed_shifts_out_zero() { + mpu.X = 0x03 + mpu.A = 0xAA + // $0000 ASL $0010,X + writeMem(memory, 0x0000, listOf(0x16, 0x10)) + memory[0x0010 + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_asl_zp_x_indexed_shifts_out_one() { + mpu.X = 0x03 + mpu.A = 0xAA + // $0000 ASL $0010,X + writeMem(memory, 0x0000, listOf(0x16, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xAA, mpu.A) + assertEquals(0xFE, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.C) + } + + // BCC + + @Test + fun test_bcc_carry_clear_branches_relative_forward() { + mpu.Status.C = false + // $0000 BCC +6 + writeMem(memory, 0x0000, listOf(0x90, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bcc_carry_clear_branches_relative_backward() { + mpu.Status.C = false + mpu.PC = 0x0050 + val rel = 256 + (-6) // two's complement of 6 + // $0000 BCC -6 + writeMem(memory, 0x0050, listOf(0x90, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bcc_carry_set_does_not_branch() { + mpu.Status.C = true + // $0000 BCC +6 + writeMem(memory, 0x0000, listOf(0x90, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BCS + + @Test + fun test_bcs_carry_set_branches_relative_forward() { + mpu.Status.C = true + // $0000 BCS +6 + writeMem(memory, 0x0000, listOf(0xB0, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bcs_carry_set_branches_relative_backward() { + mpu.Status.C = true + mpu.PC = 0x0050 + val rel = 256 + (-6) // two's complement of 6 + // $0000 BCS -6 + writeMem(memory, 0x0050, listOf(0xB0, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bcs_carry_clear_does_not_branch() { + mpu.Status.C = false + // $0000 BCS +6 + writeMem(memory, 0x0000, listOf(0xB0, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BEQ + + @Test + fun test_beq_zero_set_branches_relative_forward() { + mpu.Status.Z = true + // $0000 BEQ +6 + writeMem(memory, 0x0000, listOf(0xF0, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_beq_zero_set_branches_relative_backward() { + mpu.Status.Z = true + mpu.PC = 0x0050 + val rel = 256 + (-6) // two's complement of 6 + // $0000 BEQ -6 + writeMem(memory, 0x0050, listOf(0xF0, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_beq_zero_clear_does_not_branch() { + mpu.Status.Z = false + // $0000 BEQ +6 + writeMem(memory, 0x0000, listOf(0xF0, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BIT (Absolute) + + @Test + fun test_bit_abs_copies_bit_7_of_memory_to_n_flag_when_0() { + mpu.Status.N = false + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0xFF + mpu.A = 0xFF + mpu.step() + assertTrue(mpu.Status.N) + } + + @Test + fun test_bit_abs_copies_bit_7_of_memory_to_n_flag_when_1() { + mpu.Status.N = true + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0xFF + mpu.step() + assertFalse(mpu.Status.N) + } + + @Test + fun test_bit_abs_copies_bit_6_of_memory_to_v_flag_when_0() { + mpu.Status.V = false + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0xFF + mpu.A = 0xFF + mpu.step() + assertTrue(mpu.Status.V) + } + + @Test + fun test_bit_abs_copies_bit_6_of_memory_to_v_flag_when_1() { + mpu.Status.V = true + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0xFF + mpu.step() + assertFalse(mpu.Status.V) + } + + @Test + fun test_bit_abs_stores_result_of_and_in_z_preserves_a_when_1() { + mpu.Status.Z = false + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0xFEED]) + } + + @Test + fun test_bit_abs_stores_result_of_and_when_nonzero_in_z_preserves_a() { + mpu.Status.Z = true + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0x01 + mpu.A = 0x01 + mpu.step() + assertFalse(mpu.Status.Z) // result of AND is non-zero + assertEquals(0x01, mpu.A) + assertEquals(0x01, memory[0xFEED]) + } + + @Test + fun test_bit_abs_stores_result_of_and_when_zero_in_z_preserves_a() { + mpu.Status.Z = false + // $0000 BIT $FEED + writeMem(memory, 0x0000, listOf(0x2C, 0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.A = 0x01 + mpu.step() + assertTrue(mpu.Status.Z) // result of AND is zero + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0xFEED]) + } + + // BIT (Zero Page) + + @Test + fun test_bit_zp_copies_bit_7_of_memory_to_n_flag_when_0() { + mpu.Status.N = false + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0xFF + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertTrue(mpu.Status.N) + } + + @Test + fun test_bit_zp_copies_bit_7_of_memory_to_n_flag_when_1() { + mpu.Status.N = true + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0x00 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertFalse(mpu.Status.N) + } + + @Test + fun test_bit_zp_copies_bit_6_of_memory_to_v_flag_when_0() { + mpu.Status.V = false + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0xFF + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertTrue(mpu.Status.V) + } + + @Test + fun test_bit_zp_copies_bit_6_of_memory_to_v_flag_when_1() { + mpu.Status.V = true + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0x00 + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertFalse(mpu.Status.V) + } + + @Test + fun test_bit_zp_stores_result_of_and_in_z_preserves_a_when_1() { + mpu.Status.Z = false + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0x00 + mpu.A = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertTrue(mpu.Status.Z) + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0x0010]) + } + + @Test + fun test_bit_zp_stores_result_of_and_when_nonzero_in_z_preserves_a() { + mpu.Status.Z = true + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0x01 + mpu.A = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertFalse(mpu.Status.Z) // result of AND is non-zero + assertEquals(0x01, mpu.A) + assertEquals(0x01, memory[0x0010]) + } + + @Test + fun test_bit_zp_stores_result_of_and_when_zero_in_z_preserves_a() { + mpu.Status.Z = false + // $0000 BIT $0010 + writeMem(memory, 0x0000, listOf(0x24, 0x10)) + memory[0x0010] = 0x00 + mpu.A = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(3 + Cpu6502.resetCycles, mpu.totalCycles.toInt()) + assertTrue(mpu.Status.Z) // result of AND is zero + assertEquals(0x01, mpu.A) + assertEquals(0x00, memory[0x0010]) + } + + // BMI + + @Test + fun test_bmi_negative_set_branches_relative_forward() { + mpu.Status.N = true + // $0000 BMI +06 + writeMem(memory, 0x0000, listOf(0x30, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bmi_negative_set_branches_relative_backward() { + mpu.Status.N = true + mpu.PC = 0x0050 + // $0000 BMI -6 + val rel = 256 + (-6) // two's complement of 6 + writeMem(memory, 0x0050, listOf(0x30, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bmi_negative_clear_does_not_branch() { + mpu.Status.N = false + // $0000 BEQ +6 + writeMem(memory, 0x0000, listOf(0x30, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BNE + + @Test + fun test_bne_zero_clear_branches_relative_forward() { + mpu.Status.Z = false + // $0000 BNE +6 + writeMem(memory, 0x0000, listOf(0xD0, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bne_zero_clear_branches_relative_backward() { + mpu.Status.Z = false + mpu.PC = 0x0050 + // $0050 BNE -6 + val rel = 256 + (-6) // two's complement of 6 + writeMem(memory, 0x0050, listOf(0xD0, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bne_zero_set_does_not_branch() { + mpu.Status.Z = true + // $0000 BNE +6 + writeMem(memory, 0x0000, listOf(0xD0, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BPL + + @Test + fun test_bpl_negative_clear_branches_relative_forward() { + mpu.Status.N = false + // $0000 BPL +06 + writeMem(memory, 0x0000, listOf(0x10, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bpl_negative_clear_branches_relative_backward() { + mpu.Status.N = false + mpu.PC = 0x0050 + // $0050 BPL -6 + val rel = 256 + (-6) // two's complement of 6 + writeMem(memory, 0x0050, listOf(0x10, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bpl_negative_set_does_not_branch() { + mpu.Status.N = true + // $0000 BPL +6 + writeMem(memory, 0x0000, listOf(0x10, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BRK + + @Test + fun test_brk_pushes_pc_plus_2_and_status_then_sets_pc_to_irq_vector() { + writeMem(memory, 0xFFFE, listOf(0xCD, 0xAB)) + mpu.SP = 0xff + mpu.Status.I = false + // $C000 BRK + memory[0xC000] = 0x00 + mpu.PC = 0xC000 + mpu.step() + assertEquals(0xABCD, mpu.PC) + + assertEquals(0xFC, mpu.SP) + assertEquals(0xC0, memory[0x1FF]) // PCH + assertEquals(0x02, memory[0x1FE]) // PCL + assertEquals(fBREAK or fUNUSED, memory[0x1FD].toInt(), "Status on stack should have no I flag") + assertEquals(fBREAK or fUNUSED or fINTERRUPT, mpu.Status.asByte().toInt()) + } + + // BVC + + @Test + fun test_bvc_overflow_clear_branches_relative_forward() { + mpu.Status.V = false + // $0000 BVC +6 + writeMem(memory, 0x0000, listOf(0x50, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bvc_overflow_clear_branches_relative_backward() { + mpu.Status.V = false + mpu.PC = 0x0050 + val rel = 256 + (-6) // two's complement of 6 + // $0050 BVC -6 + writeMem(memory, 0x0050, listOf(0x50, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bvc_overflow_set_does_not_branch() { + mpu.Status.V = true + // $0000 BVC +6 + writeMem(memory, 0x0000, listOf(0x50, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // BVS + + @Test + fun test_bvs_overflow_set_branches_relative_forward() { + mpu.Status.V = true + // $0000 BVS +6 + writeMem(memory, 0x0000, listOf(0x70, 0x06)) + mpu.step() + assertEquals(0x0002 + 0x06, mpu.PC) + } + + @Test + fun test_bvs_overflow_set_branches_relative_backward() { + mpu.Status.V = true + mpu.PC = 0x0050 + val rel = 256 + (-6) // two's complement of 6 + // $0050 BVS -6 + writeMem(memory, 0x0050, listOf(0x70, rel.toShort())) + mpu.step() + assertEquals(0x0052 - 6, mpu.PC) + } + + @Test + fun test_bvs_overflow_clear_does_not_branch() { + mpu.Status.V = false + // $0000 BVS +6 + writeMem(memory, 0x0000, listOf(0x70, 0x06)) + mpu.step() + assertEquals(0x0002, mpu.PC) + } + + // CLC + + @Test + fun test_clc_clears_carry_flag() { + mpu.Status.C = true + // $0000 CLC + memory[0x0000] = 0x18 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertFalse(mpu.Status.C) + } + + // CLD + + @Test + fun test_cld_clears_decimal_flag() { + mpu.Status.D = true + // $0000 CLD + memory[0x0000] = 0xD8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertFalse(mpu.Status.D) + } + + // CLI + @Test + fun test_cli_clears_interrupt_mask_flag() { + mpu.Status.I = true + // $0000 CLI + memory[0x0000] = 0x58 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertFalse(mpu.Status.I) + } + + // CLV + @Test + fun test_clv_clears_overflow_flag() { + mpu.Status.V = true + // $0000 CLV + memory[0x0000] = 0xB8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertFalse(mpu.Status.V) + } + + // Compare instructions + + // See http://6502.org/tutorials/compare_instructions.html + // and http://www.6502.org/tutorials/compare_beyond.html + // Cheat sheet: + // - Comparison is actually subtraction "register - memory" + // - Z contains equality result (1 equal, 0 not equal) + // - C contains result of unsigned comparison (0 if A=m) + // - N holds MSB of subtraction result (*NOT* of signed subtraction) + // - V is not affected by comparison + // - D has no effect on comparison + + // CMP Immediate + @Test + fun test_cmp_imm_sets_zero_carry_clears_neg_flags_if_equal() { + // Comparison: A == m + // $0000 CMP #10 , A will be 10 + writeMem(memory, 0x0000, listOf(0xC9, 10)) + mpu.A = 10 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + @Test + fun test_cmp_imm_clears_zero_carry_takes_neg_if_less_unsigned() { + // Comparison: A < m (unsigned) + // $0000 CMP #10 , A will be 1 + writeMem(memory, 0x0000, listOf(0xC9, 10)) + mpu.A = 1 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertTrue(mpu.Status.N) // 0x01-0x0A=0xF7 + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + } + + @Test + fun test_cmp_imm_clears_zero_sets_carry_takes_neg_if_less_signed() { + // Comparison: A < #nn (signed), A negative + // $0000 CMP #1, A will be -1 (0xFF) + writeMem(memory, 0x0000, listOf(0xC9, 1)) + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertTrue(mpu.Status.N) // 0xFF-0x01=0xFE + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) // A>m unsigned + } + + @Test + fun test_cmp_imm_clears_zero_carry_takes_neg_if_less_signed_nega() { + // Comparison: A < m (signed), A and m both negative + // $0000 CMP #0xFF (-1), A will be -2 (0xFE) + writeMem(memory, 0x0000, listOf(0xC9, 0xFF)) + mpu.A = 0xFE + mpu.step() + assertEquals(0x0002, mpu.PC) + assertTrue(mpu.Status.N) // 0xFE-0xFF=0xFF + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) // A m (unsigned) + // $0000 CMP #1 , A will be 10 + writeMem(memory, 0x0000, listOf(0xC9, 1)) + mpu.A = 10 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertFalse(mpu.Status.N) // 0x0A-0x01 = 0x09 + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) // A>m unsigned + } + + @Test + fun test_cmp_imm_clears_zero_carry_takes_neg_if_more_signed() { + // Comparison: A > m (signed), memory negative + // $0000 CMP #$FF (-1), A will be 2 + writeMem(memory, 0x0000, listOf(0xC9, 0xFF)) + mpu.A = 2 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertFalse(mpu.Status.N) // 0x02-0xFF=0x01 + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) // A m (signed), A and m both negative + // $0000 CMP #$FE (-2), A will be -1 (0xFF) + writeMem(memory, 0x0000, listOf(0xC9, 0xFE)) + mpu.A = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertFalse(mpu.Status.N) // 0xFF-0xFE=0x01 + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) // A>m unsigned + } + + // CPX Immediate + + @Test + fun test_cpx_imm_sets_zero_carry_clears_neg_flags_if_equal() { + // Comparison: X == m + // $0000 CPX #$20 + writeMem(memory, 0x0000, listOf(0xE0, 0x20)) + mpu.X = 0x20 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // CPY Immediate + + @Test + fun test_cpy_imm_sets_zero_carry_clears_neg_flags_if_equal() { + // Comparison: Y == m + // $0000 CPY #$30 + writeMem(memory, 0x0000, listOf(0xC0, 0x30)) + mpu.Y = 0x30 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // DEC Absolute + @Test + fun test_dec_abs_decrements_memory() { + // $0000 DEC 0xABCD + writeMem(memory, 0x0000, listOf(0xCE, 0xCD, 0xAB)) + memory[0xABCD] = 0x10 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x0F, memory[0xABCD]) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dec_abs_below_00_rolls_over_and_sets_negative_flag() { + // $0000 DEC 0xABCD + writeMem(memory, 0x0000, listOf(0xCE, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_dec_abs_sets_zero_flag_when_decrementing_to_zero() { + // $0000 DEC 0xABCD + writeMem(memory, 0x0000, listOf(0xCE, 0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // DEC Zero Page + + @Test + fun test_dec_zp_decrements_memory() { + // $0000 DEC 0x0010 + writeMem(memory, 0x0000, listOf(0xC6, 0x10)) + memory[0x0010] = 0x10 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x0F, memory[0x0010]) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dec_zp_below_00_rolls_over_and_sets_negative_flag() { + // $0000 DEC 0x0010 + writeMem(memory, 0x0000, listOf(0xC6, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_dec_zp_sets_zero_flag_when_decrementing_to_zero() { + // $0000 DEC 0x0010 + writeMem(memory, 0x0000, listOf(0xC6, 0x10)) + memory[0x0010] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // DEC Absolute, X-Indexed + + @Test + fun test_dec_abs_x_decrements_memory() { + // $0000 DEC 0xABCD,X + writeMem(memory, 0x0000, listOf(0xDE, 0xCD, 0xAB)) + mpu.X = 0x03 + memory[0xABCD + mpu.X] = 0x10 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x0F, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dec_abs_x_below_00_rolls_over_and_sets_negative_flag() { + // $0000 DEC 0xABCD,X + writeMem(memory, 0x0000, listOf(0xDE, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_dec_abs_x_sets_zero_flag_when_decrementing_to_zero() { + // $0000 DEC 0xABCD,X + writeMem(memory, 0x0000, listOf(0xDE, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // DEC Zero Page, X-Indexed + + @Test + fun test_dec_zp_x_decrements_memory() { + // $0000 DEC 0x0010,X + writeMem(memory, 0x0000, listOf(0xD6, 0x10)) + mpu.X = 0x03 + memory[0x0010 + mpu.X] = 0x10 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x0F, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dec_zp_x_below_00_rolls_over_and_sets_negative_flag() { + // $0000 DEC 0x0010,X + writeMem(memory, 0x0000, listOf(0xD6, 0x10)) + mpu.X = 0x03 + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_dec_zp_x_sets_zero_flag_when_decrementing_to_zero() { + // $0000 DEC 0x0010,X + writeMem(memory, 0x0000, listOf(0xD6, 0x10)) + mpu.X = 0x03 + memory[0x0010 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // DEX + + @Test + fun test_dex_decrements_x() { + mpu.X = 0x10 + // $0000 DEX + memory[0x0000] = 0xCA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x0F, mpu.X) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dex_below_00_rolls_over_and_sets_negative_flag() { + mpu.X = 0x00 + // $0000 DEX + memory[0x0000] = 0xCA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFF, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dex_sets_zero_flag_when_decrementing_to_zero() { + mpu.X = 0x01 + // $0000 DEX + memory[0x0000] = 0xCA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // DEY + + @Test + fun test_dey_decrements_y() { + mpu.Y = 0x10 + // $0000 DEY + memory[0x0000] = 0x88 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x0F, mpu.Y) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_dey_below_00_rolls_over_and_sets_negative_flag() { + mpu.Y = 0x00 + // $0000 DEY + memory[0x0000] = 0x88 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFF, mpu.Y) + assertTrue(mpu.Status.N) + } + + @Test + fun test_dey_sets_zero_flag_when_decrementing_to_zero() { + mpu.Y = 0x01 + // $0000 DEY + memory[0x0000] = 0x88 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + } + + // EOR Absolute + + @Test + fun test_eor_absolute_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + writeMem(memory, 0x0000, listOf(0x4D, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_absolute_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + writeMem(memory, 0x0000, listOf(0x4D, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Zero Page + + @Test + fun test_eor_zp_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + writeMem(memory, 0x0000, listOf(0x45, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0x0010]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_zp_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + writeMem(memory, 0x0000, listOf(0x45, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0x0010]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Immediate + + @Test + fun test_eor_immediate_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + writeMem(memory, 0x0000, listOf(0x49, 0xFF)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_immediate_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + writeMem(memory, 0x0000, listOf(0x49, 0xFF)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Absolute, X-Indexed + + @Test + fun test_eor_abs_x_indexed_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x5D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_abs_x_indexed_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x5D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Absolute, Y-Indexed + + @Test + fun test_eor_abs_y_indexed_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + writeMem(memory, 0x0000, listOf(0x59, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.Y]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_abs_y_indexed_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + mpu.Y = 0x03 + writeMem(memory, 0x0000, listOf(0x59, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.Y]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Indirect, Indexed (X) + + @Test + fun test_eor_ind_indexed_x_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x41, 0x10)) // => EOR listOf($0010,X) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) // => Vector to $ABCD + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_ind_indexed_x_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x41, 0x10)) // => EOR listOf($0010,X) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) // => Vector to $ABCD + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Indexed, Indirect (Y) + + @Test + fun test_eor_indexed_ind_y_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + writeMem(memory, 0x0000, listOf(0x51, 0x10)) // => EOR listOf($0010),Y + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) // => Vector to $ABCD + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.Y]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_indexed_ind_y_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + mpu.Y = 0x03 + writeMem(memory, 0x0000, listOf(0x51, 0x10)) // => EOR listOf($0010),Y + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) // => Vector to $ABCD + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0xABCD + mpu.Y]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // EOR Zero Page, X-Indexed + + @Test + fun test_eor_zp_x_indexed_flips_bits_over_setting_z_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x55, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0xFF, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_eor_zp_x_indexed_flips_bits_over_setting_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x55, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, mpu.A) + assertEquals(0xFF, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // INC Absolute + + @Test + fun test_inc_abs_increments_memory() { + writeMem(memory, 0x0000, listOf(0xEE, 0xCD, 0xAB)) + memory[0xABCD] = 0x09 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x0A, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_abs_increments_memory_rolls_over_and_sets_zero_flag() { + writeMem(memory, 0x0000, listOf(0xEE, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_abs_sets_negative_flag_when_incrementing_above_7F() { + writeMem(memory, 0x0000, listOf(0xEE, 0xCD, 0xAB)) + memory[0xABCD] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + // INC Zero Page + + @Test + fun test_inc_zp_increments_memory() { + writeMem(memory, 0x0000, listOf(0xE6, 0x10)) + memory[0x0010] = 0x09 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x0A, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_zp_increments_memory_rolls_over_and_sets_zero_flag() { + writeMem(memory, 0x0000, listOf(0xE6, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_zp_sets_negative_flag_when_incrementing_above_7F() { + writeMem(memory, 0x0000, listOf(0xE6, 0x10)) + memory[0x0010] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + // INC Absolute, X-Indexed + + @Test + fun test_inc_abs_x_increments_memory() { + writeMem(memory, 0x0000, listOf(0xFE, 0xCD, 0xAB)) + mpu.X = 0x03 + memory[0xABCD + mpu.X] = 0x09 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x0A, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_abs_x_increments_memory_rolls_over_and_sets_zero_flag() { + writeMem(memory, 0x0000, listOf(0xFE, 0xCD, 0xAB)) + mpu.X = 0x03 + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_abs_x_sets_negative_flag_when_incrementing_above_7F() { + writeMem(memory, 0x0000, listOf(0xFE, 0xCD, 0xAB)) + mpu.X = 0x03 + memory[0xABCD + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + // INC Zero Page, X-Indexed + + @Test + fun test_inc_zp_x_increments_memory() { + writeMem(memory, 0x0000, listOf(0xF6, 0x10)) + mpu.X = 0x03 + memory[0x0010 + mpu.X] = 0x09 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x0A, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_zp_x_increments_memory_rolls_over_and_sets_zero_flag() { + writeMem(memory, 0x0000, listOf(0xF6, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inc_zp_x_sets_negative_flag_when_incrementing_above_7F() { + writeMem(memory, 0x0000, listOf(0xF6, 0x10)) + memory[0x0010 + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + // INX + + @Test + fun test_inx_increments_x() { + mpu.X = 0x09 + memory[0x0000] = 0xE8 // => INX + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x0A, mpu.X) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_inx_above_FF_rolls_over_and_sets_zero_flag() { + mpu.X = 0xFF + memory[0x0000] = 0xE8 // => INX + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_inx_sets_negative_flag_when_incrementing_above_7F() { + mpu.X = 0x7f + memory[0x0000] = 0xE8 // => INX + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + } + + // INY + + @Test + fun test_iny_increments_y() { + mpu.Y = 0x09 + memory[0x0000] = 0xC8 // => INY + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x0A, mpu.Y) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_iny_above_FF_rolls_over_and_sets_zero_flag() { + mpu.Y = 0xFF + memory[0x0000] = 0xC8 // => INY + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_iny_sets_negative_flag_when_incrementing_above_7F() { + mpu.Y = 0x7f + memory[0x0000] = 0xC8 // => INY + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + } + + // JMP Absolute + + @Test + fun test_jmp_abs_jumps_to_absolute_address() { + // $0000 JMP $ABCD + writeMem(memory, 0x0000, listOf(0x4C, 0xCD, 0xAB)) + mpu.step() + assertEquals(0xABCD, mpu.PC) + } + + // JMP Indirect + + @Test + fun test_jmp_ind_jumps_to_indirect_address() { + // $0000 JMP ($ABCD) + writeMem(memory, 0x0000, listOf(0x6C, 0x00, 0x02)) + writeMem(memory, 0x0200, listOf(0xCD, 0xAB)) + mpu.step() + assertEquals(0xABCD, mpu.PC) + } + + // JSR + + @Test + fun test_jsr_pushes_pc_plus_2_and_sets_pc() { + // $C000 JSR $FFD2 + mpu.SP = 0xFF + writeMem(memory, 0xC000, listOf(0x20, 0xD2, 0xFF)) + mpu.PC = 0xC000 + mpu.step() + assertEquals(0xFFD2, mpu.PC) + assertEquals(0xFD, mpu.SP) + assertEquals(0xC0, memory[0x01FF]) // PCH + assertEquals(0x02, memory[0x01FE]) // PCL+2 + } + + // LDA Absolute + + @Test + fun test_lda_absolute_loads_a_sets_n_flag() { + mpu.A = 0x00 + // $0000 LDA $ABCD + writeMem(memory, 0x0000, listOf(0xAD, 0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_absolute_loads_a_sets_z_flag() { + mpu.A = 0xFF + // $0000 LDA $ABCD + writeMem(memory, 0x0000, listOf(0xAD, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDA Zero Page + + @Test + fun test_lda_zp_loads_a_sets_n_flag() { + mpu.A = 0x00 + // $0000 LDA $0010 + writeMem(memory, 0x0000, listOf(0xA5, 0x10)) + memory[0x0010] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_zp_loads_a_sets_z_flag() { + mpu.A = 0xFF + // $0000 LDA $0010 + writeMem(memory, 0x0000, listOf(0xA5, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDA Immediate + + @Test + fun test_lda_immediate_loads_a_sets_n_flag() { + mpu.A = 0x00 + // $0000 LDA #$80 + writeMem(memory, 0x0000, listOf(0xA9, 0x80)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_immediate_loads_a_sets_z_flag() { + mpu.A = 0xFF + // $0000 LDA #$00 + writeMem(memory, 0x0000, listOf(0xA9, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDA Absolute, X-Indexed + + @Test + fun test_lda_abs_x_indexed_loads_a_sets_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 LDA $ABCD,X + writeMem(memory, 0x0000, listOf(0xBD, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_abs_x_indexed_loads_a_sets_z_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 LDA $ABCD,X + writeMem(memory, 0x0000, listOf(0xBD, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lda_abs_x_indexed_does_not_page_wrap() { + mpu.A = 0 + mpu.X = 0xFF + // $0000 LDA $0080,X + writeMem(memory, 0x0000, listOf(0xBD, 0x80, 0x00)) + memory[0x0080 + mpu.X] = 0x42 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x42, mpu.A) + } + + // LDA Absolute, Y-Indexed + + @Test + fun test_lda_abs_y_indexed_loads_a_sets_n_flag() { + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 LDA $ABCD,Y + writeMem(memory, 0x0000, listOf(0xB9, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_abs_y_indexed_loads_a_sets_z_flag() { + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 LDA $ABCD,Y + writeMem(memory, 0x0000, listOf(0xB9, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lda_abs_y_indexed_does_not_page_wrap() { + mpu.A = 0 + mpu.Y = 0xFF + // $0000 LDA $0080,X + writeMem(memory, 0x0000, listOf(0xB9, 0x80, 0x00)) + memory[0x0080 + mpu.Y] = 0x42 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x42, mpu.A) + } + + // LDA Indirect, Indexed (X) + + @Test + fun test_lda_ind_indexed_x_loads_a_sets_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 LDA ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xA1, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_ind_indexed_x_loads_a_sets_z_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 LDA ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xA1, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDA Indexed, Indirect (Y) + + @Test + fun test_lda_indexed_ind_y_loads_a_sets_n_flag() { + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 LDA ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xB1, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_indexed_ind_y_correct_index() { + mpu.A = 0x00 + mpu.Y = 0xf3 + // $0000 LDA ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xB1, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + } + + @Test + fun test_lda_indexed_ind_y_loads_a_sets_z_flag() { + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 LDA ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0xB1, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDA Zero Page, X-Indexed + + @Test + fun test_lda_zp_x_indexed_loads_a_sets_n_flag() { + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 LDA $10,X + writeMem(memory, 0x0000, listOf(0xB5, 0x10)) + memory[0x0010 + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_lda_zp_x_indexed_correct_index() { + mpu.A = 0x00 + mpu.X = 0xf3 + // $0000 LDA $10,X + writeMem(memory, 0x0000, listOf(0xB5, 0x10)) + memory[(0x0010 + mpu.X) and 255] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.A) + } + + @Test + fun test_lda_zp_x_indexed_loads_a_sets_z_flag() { + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 LDA $10,X + writeMem(memory, 0x0000, listOf(0xB5, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDX Absolute + + @Test + fun test_ldx_absolute_loads_x_sets_n_flag() { + mpu.X = 0x00 + // $0000 LDX $ABCD + writeMem(memory, 0x0000, listOf(0xAE, 0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldx_absolute_loads_x_sets_z_flag() { + mpu.X = 0xFF + // $0000 LDX $ABCD + writeMem(memory, 0x0000, listOf(0xAE, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDX Zero Page + + @Test + fun test_ldx_zp_loads_x_sets_n_flag() { + mpu.X = 0x00 + // $0000 LDX $0010 + writeMem(memory, 0x0000, listOf(0xA6, 0x10)) + memory[0x0010] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldx_zp_loads_x_sets_z_flag() { + mpu.X = 0xFF + // $0000 LDX $0010 + writeMem(memory, 0x0000, listOf(0xA6, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDX Immediate + + @Test + fun test_ldx_immediate_loads_x_sets_n_flag() { + mpu.X = 0x00 + // $0000 LDX #$80 + writeMem(memory, 0x0000, listOf(0xA2, 0x80)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldx_immediate_loads_x_sets_z_flag() { + mpu.X = 0xFF + // $0000 LDX #$00 + writeMem(memory, 0x0000, listOf(0xA2, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDX Absolute, Y-Indexed + + @Test + fun test_ldx_abs_y_indexed_loads_x_sets_n_flag() { + mpu.X = 0x00 + mpu.Y = 0x03 + // $0000 LDX $ABCD,Y + writeMem(memory, 0x0000, listOf(0xBE, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldx_abs_y_indexed_loads_x_sets_z_flag() { + mpu.X = 0xFF + mpu.Y = 0x03 + // $0000 LDX $ABCD,Y + writeMem(memory, 0x0000, listOf(0xBE, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDX Zero Page, Y-Indexed + + @Test + fun test_ldx_zp_y_indexed_loads_x_sets_n_flag() { + mpu.X = 0x00 + mpu.Y = 0x03 + // $0000 LDX $0010,Y + writeMem(memory, 0x0000, listOf(0xB6, 0x10)) + memory[0x0010 + mpu.Y] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldx_zp_y_indexed_loads_x_sets_z_flag() { + mpu.X = 0xFF + mpu.Y = 0x03 + // $0000 LDX $0010,Y + writeMem(memory, 0x0000, listOf(0xB6, 0x10)) + memory[0x0010 + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDY Absolute + + @Test + fun test_ldy_absolute_loads_y_sets_n_flag() { + mpu.Y = 0x00 + // $0000 LDY $ABCD + writeMem(memory, 0x0000, listOf(0xAC, 0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldy_absolute_loads_y_sets_z_flag() { + mpu.Y = 0xFF + // $0000 LDY $ABCD + writeMem(memory, 0x0000, listOf(0xAC, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDY Zero Page + + @Test + fun test_ldy_zp_loads_y_sets_n_flag() { + mpu.Y = 0x00 + // $0000 LDY $0010 + writeMem(memory, 0x0000, listOf(0xA4, 0x10)) + memory[0x0010] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldy_zp_loads_y_sets_z_flag() { + mpu.Y = 0xFF + // $0000 LDY $0010 + writeMem(memory, 0x0000, listOf(0xA4, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDY Immediate + + @Test + fun test_ldy_immediate_loads_y_sets_n_flag() { + mpu.Y = 0x00 + // $0000 LDY #$80 + writeMem(memory, 0x0000, listOf(0xA0, 0x80)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldy_immediate_loads_y_sets_z_flag() { + mpu.Y = 0xFF + // $0000 LDY #$00 + writeMem(memory, 0x0000, listOf(0xA0, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDY Absolute, X-Indexed + + @Test + fun test_ldy_abs_x_indexed_loads_x_sets_n_flag() { + mpu.Y = 0x00 + mpu.X = 0x03 + // $0000 LDY $ABCD,X + writeMem(memory, 0x0000, listOf(0xBC, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldy_abs_x_indexed_loads_x_sets_z_flag() { + mpu.Y = 0xFF + mpu.X = 0x03 + // $0000 LDY $ABCD,X + writeMem(memory, 0x0000, listOf(0xBC, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LDY Zero Page, X-Indexed + + @Test + fun test_ldy_zp_x_indexed_loads_x_sets_n_flag() { + mpu.Y = 0x00 + mpu.X = 0x03 + // $0000 LDY $0010,X + writeMem(memory, 0x0000, listOf(0xB4, 0x10)) + memory[0x0010 + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_ldy_zp_x_indexed_loads_x_sets_z_flag() { + mpu.Y = 0xFF + mpu.X = 0x03 + // $0000 LDY $0010,X + writeMem(memory, 0x0000, listOf(0xB4, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + // LSR Accumulator + + @Test + fun test_lsr_accumulator_rotates_in_zero_not_carry() { + mpu.Status.C = true + // $0000 LSR A + memory[0x0000] = (0x4A) + mpu.A = 0x00 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_accumulator_sets_carry_and_zero_flags_after_rotation() { + mpu.Status.C = false + // $0000 LSR A + memory[0x0000] = (0x4A) + mpu.A = 0x01 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_accumulator_rotates_bits_right() { + mpu.Status.C = true + // $0000 LSR A + memory[0x0000] = (0x4A) + mpu.A = 0x04 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x02, mpu.A) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // LSR Absolute + + @Test + fun test_lsr_absolute_rotates_in_zero_not_carry() { + mpu.Status.C = true + // $0000 LSR $ABCD + writeMem(memory, 0x0000, listOf(0x4E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_absolute_sets_carry_and_zero_flags_after_rotation() { + mpu.Status.C = false + // $0000 LSR $ABCD + writeMem(memory, 0x0000, listOf(0x4E, 0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_absolute_rotates_bits_right() { + mpu.Status.C = true + // $0000 LSR $ABCD + writeMem(memory, 0x0000, listOf(0x4E, 0xCD, 0xAB)) + memory[0xABCD] = 0x04 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x02, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // LSR Zero Page + + @Test + fun test_lsr_zp_rotates_in_zero_not_carry() { + mpu.Status.C = true + // $0000 LSR $0010 + writeMem(memory, 0x0000, listOf(0x46, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_zp_sets_carry_and_zero_flags_after_rotation() { + mpu.Status.C = false + // $0000 LSR $0010 + writeMem(memory, 0x0000, listOf(0x46, 0x10)) + memory[0x0010] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_zp_rotates_bits_right() { + mpu.Status.C = true + // $0000 LSR $0010 + writeMem(memory, 0x0000, listOf(0x46, 0x10)) + memory[0x0010] = 0x04 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // LSR Absolute, X-Indexed + + @Test + fun test_lsr_abs_x_indexed_rotates_in_zero_not_carry() { + mpu.Status.C = true + mpu.X = 0x03 + // $0000 LSR $ABCD,X + writeMem(memory, 0x0000, listOf(0x5E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_abs_x_indexed_sets_c_and_z_flags_after_rotation() { + mpu.Status.C = false + mpu.X = 0x03 + // $0000 LSR $ABCD,X + writeMem(memory, 0x0000, listOf(0x5E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_abs_x_indexed_rotates_bits_right() { + mpu.Status.C = true + // $0000 LSR $ABCD,X + writeMem(memory, 0x0000, listOf(0x5E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x04 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x02, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // LSR Zero Page, X-Indexed + + @Test + fun test_lsr_zp_x_indexed_rotates_in_zero_not_carry() { + mpu.Status.C = true + mpu.X = 0x03 + // $0000 LSR $0010,X + writeMem(memory, 0x0000, listOf(0x56, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_zp_x_indexed_sets_carry_and_zero_flags_after_rotation() { + mpu.Status.C = false + mpu.X = 0x03 + // $0000 LSR $0010,X + writeMem(memory, 0x0000, listOf(0x56, 0x10)) + memory[0x0010 + mpu.X] = 0x01 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + @Test + fun test_lsr_zp_x_indexed_rotates_bits_right() { + mpu.Status.C = true + mpu.X = 0x03 + // $0000 LSR $0010,X + writeMem(memory, 0x0000, listOf(0x56, 0x10)) + memory[0x0010 + mpu.X] = 0x04 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x02, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.C) + assertFalse(mpu.Status.N) + } + + // NOP + + @Test + fun test_nop_does_nothing() { + // $0000 NOP + memory[0x0000] = 0xEA + mpu.step() + assertEquals(0x0001, mpu.PC) + } + + // ORA Absolute + + @Test + fun test_ora_absolute_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + // $0000 ORA $ABCD + writeMem(memory, 0x0000, listOf(0x0D, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_absolute_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + // $0000 ORA $ABCD + writeMem(memory, 0x0000, listOf(0x0D, 0xCD, 0xAB)) + memory[0xABCD] = 0x82 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Zero Page + + @Test + fun test_ora_zp_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + // $0000 ORA $0010 + writeMem(memory, 0x0000, listOf(0x05, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_zp_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + // $0000 ORA $0010 + writeMem(memory, 0x0000, listOf(0x05, 0x10)) + memory[0x0010] = 0x82 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Immediate + + @Test + fun test_ora_immediate_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + // $0000 ORA #$00 + writeMem(memory, 0x0000, listOf(0x09, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_immediate_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + // $0000 ORA #$82 + writeMem(memory, 0x0000, listOf(0x09, 0x82)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Absolute, X + + @Test + fun test_ora_abs_x_indexed_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ORA $ABCD,X + writeMem(memory, 0x0000, listOf(0x1D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_abs_x_indexed_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + mpu.X = 0x03 + // $0000 ORA $ABCD,X + writeMem(memory, 0x0000, listOf(0x1D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x82 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Absolute, Y + + @Test + fun test_ora_abs_y_indexed_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 ORA $ABCD,Y + writeMem(memory, 0x0000, listOf(0x19, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_abs_y_indexed_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + mpu.Y = 0x03 + // $0000 ORA $ABCD,Y + writeMem(memory, 0x0000, listOf(0x19, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x82 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Indirect, Indexed (X) + + @Test + fun test_ora_ind_indexed_x_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ORA ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x01, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_ind_indexed_x_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + mpu.X = 0x03 + // $0000 ORA ($0010,X) + // $0013 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x01, 0x10)) + writeMem(memory, 0x0013, listOf(0xCD, 0xAB)) + memory[0xABCD] = 0x82 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Indexed, Indirect (Y) + + @Test + fun test_ora_indexed_ind_y_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 ORA ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x11, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_indexed_ind_y_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + mpu.Y = 0x03 + // $0000 ORA ($0010),Y + // $0010 Vector to $ABCD + writeMem(memory, 0x0000, listOf(0x11, 0x10)) + writeMem(memory, 0x0010, listOf(0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x82 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // ORA Zero Page, X + + @Test + fun test_ora_zp_x_indexed_zeroes_or_zeros_sets_z_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 ORA $0010,X + writeMem(memory, 0x0000, listOf(0x15, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_ora_zp_x_indexed_turns_bits_on_sets_n_flag() { + mpu.Status.N = false + mpu.A = 0x03 + mpu.X = 0x03 + // $0000 ORA $0010,X + writeMem(memory, 0x0000, listOf(0x15, 0x10)) + memory[0x0010 + mpu.X] = 0x82 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x83, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + // PHA + + @Test + fun test_pha_pushes_a_and_updates_sp() { + mpu.A = 0xAB + // $0000 PHA + memory[0x0000] = 0x48 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xFC, mpu.SP) + assertEquals(0xAB, memory[0x01FD]) + } + + // PHP + + @Test + fun test_php_pushes_processor_status_and_updates_sp() { + for (flags in 0 until 0x100) { + mpu.reset() + mpu.Status.fromByte(flags or fBREAK or fUNUSED) + // $0000 PHP + memory[0x0000] = 0x08 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFC, mpu.SP) + assertEquals((flags or fBREAK or fUNUSED), memory[0x1FD].toInt()) + } + } + + // PLA + + @Test + fun test_pla_pulls_top_byte_from_stack_into_a_and_updates_sp() { + // $0000 PLA + memory[0x0000] = 0x68 + memory[0x01FF] = 0xAB + mpu.SP = 0xFE + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xFF, mpu.SP) + } + + // PLP + + @Test + fun test_plp_pulls_top_byte_from_stack_into_flags_and_updates_sp() { + // $0000 PLP + memory[0x0000] = 0x28 + memory[0x01FF] = 0xBA // must have BREAK and UNUSED set + mpu.SP = 0xFE + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xBA, mpu.Status.asByte()) + assertEquals(0xFF, mpu.SP) + } + + // ROL Accumulator + + @Test + fun test_rol_accumulator_zero_and_carry_zero_sets_z_flag() { + mpu.A = 0x00 + mpu.Status.C = false + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_accumulator_80_and_carry_zero_sets_z_flag() { + mpu.A = 0x80 + mpu.Status.C = false + mpu.Status.Z = false + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_accumulator_zero_and_carry_one_clears_z_flag() { + mpu.A = 0x00 + mpu.Status.C = true + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x01, mpu.A) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_accumulator_sets_n_flag() { + mpu.A = 0x40 + mpu.Status.C = true + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x81, mpu.A) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_rol_accumulator_shifts_out_zero() { + mpu.A = 0x7F + mpu.Status.C = false + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFE, mpu.A) + assertFalse(mpu.Status.C) + } + + @Test + fun test_rol_accumulator_shifts_out_one() { + mpu.A = 0xFF + mpu.Status.C = false + // $0000 ROL A + memory[0x0000] = 0x2A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xFE, mpu.A) + assertTrue(mpu.Status.C) + } + + // ROL Absolute + + @Test + fun test_rol_absolute_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_absolute_80_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.Status.Z = false + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_absolute_zero_and_carry_one_clears_z_flag() { + mpu.A = 0x00 + mpu.Status.C = true + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_absolute_sets_n_flag() { + mpu.Status.C = true + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_rol_absolute_shifts_out_zero() { + mpu.Status.C = false + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFE, memory[0xABCD]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_rol_absolute_shifts_out_one() { + mpu.Status.C = false + // $0000 ROL $ABCD + writeMem(memory, 0x0000, listOf(0x2E, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFE, memory[0xABCD]) + assertTrue(mpu.Status.C) + } + + // ROL Zero Page + + @Test + fun test_rol_zp_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_80_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.Status.Z = false + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_zero_and_carry_one_clears_z_flag() { + mpu.A = 0x00 + mpu.Status.C = true + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_sets_n_flag() { + mpu.Status.C = true + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_rol_zp_shifts_out_zero() { + mpu.Status.C = false + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFE, memory[0x0010]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_rol_zp_shifts_out_one() { + mpu.Status.C = false + // $0000 ROL $0010 + writeMem(memory, 0x0000, listOf(0x26, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFE, memory[0x0010]) + assertTrue(mpu.Status.C) + } + + // ROL Absolute, X-Indexed + + @Test + fun test_rol_abs_x_indexed_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.X = 0x03 + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_abs_x_indexed_80_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.Status.Z = false + mpu.X = 0x03 + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_abs_x_indexed_zero_and_carry_one_clears_z_flag() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x01, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_abs_x_indexed_sets_n_flag() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_rol_abs_x_indexed_shifts_out_zero() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFE, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_rol_abs_x_indexed_shifts_out_one() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROL $ABCD,X + writeMem(memory, 0x0000, listOf(0x3E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFE, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.C) + } + + // ROL Zero Page, X-Indexed + + @Test + fun test_rol_zp_x_indexed_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + // $0000 ROL $0010,X + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_x_indexed_80_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + mpu.Status.Z = false + mpu.X = 0x03 + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + // $0000 ROL $0010,X + memory[0x0010 + mpu.X] = 0x80 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_x_indexed_zero_and_carry_one_clears_z_flag() { + mpu.X = 0x03 + mpu.Status.C = true + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + // $0000 ROL $0010,X + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x01, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_rol_zp_x_indexed_sets_n_flag() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROL $0010,X + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + memory[0x0010 + mpu.X] = 0x40 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.Z) + } + + @Test + fun test_rol_zp_x_indexed_shifts_out_zero() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROL $0010,X + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + memory[0x0010 + mpu.X] = 0x7F + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFE, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_rol_zp_x_indexed_shifts_out_one() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROL $0010,X + writeMem(memory, 0x0000, listOf(0x36, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFE, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.C) + } + + // ROR Accumulator + + @Test + fun test_ror_accumulator_zero_and_carry_zero_sets_z_flag() { + mpu.A = 0x00 + mpu.Status.C = false + // $0000 ROR A + memory[0x0000] = 0x6A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_ror_accumulator_zero_and_carry_one_rotates_in_sets_n_flags() { + mpu.A = 0x00 + mpu.Status.C = true + // $0000 ROR A + memory[0x0000] = 0x6A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_ror_accumulator_shifts_out_zero() { + mpu.A = 0x02 + mpu.Status.C = true + // $0000 ROR A + memory[0x0000] = 0x6A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x81, mpu.A) + assertFalse(mpu.Status.C) + } + + @Test + fun test_ror_accumulator_shifts_out_one() { + mpu.A = 0x03 + mpu.Status.C = true + // $0000 ROR A + memory[0x0000] = 0x6A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x81, mpu.A) + assertTrue(mpu.Status.C) + } + + // ROR Absolute + + @Test + fun test_ror_absolute_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + // $0000 ROR $ABCD + writeMem(memory, 0x0000, listOf(0x6E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_ror_absolute_zero_and_carry_one_rotates_in_sets_n_flags() { + mpu.Status.C = true + // $0000 ROR $ABCD + writeMem(memory, 0x0000, listOf(0x6E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_ror_absolute_shifts_out_zero() { + mpu.Status.C = true + // $0000 ROR $ABCD + writeMem(memory, 0x0000, listOf(0x6E, 0xCD, 0xAB)) + memory[0xABCD] = 0x02 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_ror_absolute_shifts_out_one() { + mpu.Status.C = true + // $0000 ROR $ABCD + writeMem(memory, 0x0000, listOf(0x6E, 0xCD, 0xAB)) + memory[0xABCD] = 0x03 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD]) + assertTrue(mpu.Status.C) + } + + // ROR Zero Page + + @Test + fun test_ror_zp_zero_and_carry_zero_sets_z_flag() { + mpu.Status.C = false + // $0000 ROR $0010 + writeMem(memory, 0x0000, listOf(0x66, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_ror_zp_zero_and_carry_one_rotates_in_sets_n_flags() { + mpu.Status.C = true + // $0000 ROR $0010 + writeMem(memory, 0x0000, listOf(0x66, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_ror_zp_zero_absolute_shifts_out_zero() { + mpu.Status.C = true + // $0000 ROR $0010 + writeMem(memory, 0x0000, listOf(0x66, 0x10)) + memory[0x0010] = 0x02 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_ror_zp_shifts_out_one() { + mpu.Status.C = true + // $0000 ROR $0010 + writeMem(memory, 0x0000, listOf(0x66, 0x10)) + memory[0x0010] = 0x03 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010]) + assertTrue(mpu.Status.C) + } + + // ROR Absolute, X-Indexed + + @Test + fun test_ror_abs_x_indexed_zero_and_carry_zero_sets_z_flag() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROR $ABCD,X + writeMem(memory, 0x0000, listOf(0x7E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_ror_abs_x_indexed_z_and_c_1_rotates_in_sets_n_flags() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $ABCD,X + writeMem(memory, 0x0000, listOf(0x7E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x80, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_ror_abs_x_indexed_shifts_out_zero() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $ABCD,X + writeMem(memory, 0x0000, listOf(0x7E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x02 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_ror_abs_x_indexed_shifts_out_one() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $ABCD,X + writeMem(memory, 0x0000, listOf(0x7E, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x03 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x81, memory[0xABCD + mpu.X]) + assertTrue(mpu.Status.C) + } + + // ROR Zero Page, X-Indexed + + @Test + fun test_ror_zp_x_indexed_zero_and_carry_zero_sets_z_flag() { + mpu.X = 0x03 + mpu.Status.C = false + // $0000 ROR $0010,X + writeMem(memory, 0x0000, listOf(0x76, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.Z) + assertFalse(mpu.Status.N) + } + + @Test + fun test_ror_zp_x_indexed_zero_and_carry_one_rotates_in_sets_n_flags() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $0010,X + writeMem(memory, 0x0000, listOf(0x76, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x80, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + } + + @Test + fun test_ror_zp_x_indexed_zero_absolute_shifts_out_zero() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $0010,X + writeMem(memory, 0x0000, listOf(0x76, 0x10)) + memory[0x0010 + mpu.X] = 0x02 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010 + mpu.X]) + assertFalse(mpu.Status.C) + } + + @Test + fun test_ror_zp_x_indexed_shifts_out_one() { + mpu.X = 0x03 + mpu.Status.C = true + // $0000 ROR $0010,X + writeMem(memory, 0x0000, listOf(0x76, 0x10)) + memory[0x0010 + mpu.X] = 0x03 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x81, memory[0x0010 + mpu.X]) + assertTrue(mpu.Status.C) + } + + // RTI + + @Test + fun test_rti_restores_status_and_pc_and_updates_sp() { + // $0000 RTI + memory[0x0000] = 0x40 + writeMem(memory, 0x01FD, listOf(0xFC, 0x03, 0xC0)) // Status, PCL, PCH + mpu.SP = 0xFC + mpu.step() + assertEquals(0xFF, mpu.SP) + assertEquals(0xFC, mpu.Status.asByte()) + assertEquals(0xC003, mpu.PC) + } + + @Test + fun test_rti_forces_break_and_unused_flags_high() { + // $0000 RTI + memory[0x0000] = 0x40 + writeMem(memory, 0x01FD, listOf(0x00, 0x03, 0xC0)) // Status, PCL, PCH + mpu.SP = 0xFC + mpu.step() + assertTrue(mpu.Status.B) + // assertEquals(fUNUSED, mpu.Status.asByte().toInt() and fUNUSED) + } + + // RTS + + @Test + fun test_rts_restores_pc_and_increments_then_updates_sp() { + // $0000 RTS + memory[0x0000] = 0x60 + writeMem(memory, 0x01FE, listOf(0x03, 0xC0)) // PCL, PCH + mpu.PC = 0x0000 + mpu.SP = 0xFD + mpu.step() + assertEquals(0xC004, mpu.PC) + assertEquals(0xFF, mpu.SP) + } + + @Test + fun test_rts_wraps_around_top_of_memory() { + // $1000 RTS + memory[0x1000] = 0x60 + writeMem(memory, 0x01FE, listOf(0xFF, 0xFF)) // PCL, PCH + mpu.PC = 0x1000 + mpu.SP = 0xFD + mpu.step() + assertEquals(0x0000, mpu.PC) + assertEquals(0xFF, mpu.SP) + } + + // SBC Absolute + + @Test + fun test_sbc_abs_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC $ABCD + writeMem(memory, 0x0000, listOf(0xED, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC $ABCD + writeMem(memory, 0x0000, listOf(0xED, 0xCD, 0xAB)) + memory[0xABCD] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC $ABCD + writeMem(memory, 0x0000, listOf(0xED, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC $ABCD + writeMem(memory, 0x0000, listOf(0xED, 0xCD, 0xAB)) + memory[0xABCD] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Zero Page + + @Test + fun test_sbc_zp_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC $10 + writeMem(memory, 0x0000, listOf(0xE5, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC $10 + writeMem(memory, 0x0000, listOf(0xE5, 0x10)) + memory[0x0010] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // => SBC $10 + writeMem(memory, 0x0000, listOf(0xE5, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // => SBC $10 + writeMem(memory, 0x0000, listOf(0xE5, 0x10)) + memory[0x0010] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Immediate + + @Test + fun test_sbc_imm_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC #$00 + writeMem(memory, 0x0000, listOf(0xE9, 0x00)) + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_imm_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC #$01 + writeMem(memory, 0x0000, listOf(0xE9, 0x01)) + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_imm_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC #$00 + writeMem(memory, 0x0000, listOf(0xE9, 0x00)) + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_imm_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC #$02 + writeMem(memory, 0x0000, listOf(0xE9, 0x02)) + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + @Test + fun test_sbc_bcd_on_immediate_0a_minus_00_carry_set() { + mpu.Status.D = true + mpu.Status.C = true + mpu.A = 0x0a + // $0000 SBC #$00 + writeMem(memory, 0x0000, listOf(0xe9, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x0a, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.V) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + @Test + fun test_sbc_bcd_on_immediate_9a_minus_00_carry_set() { + mpu.Status.D = true + mpu.Status.C = true + mpu.A = 0x9a + // $0000 SBC #$00 + writeMem(memory, 0x0000, listOf(0xe9, 0x00)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x9a, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.V) + } + + @Test + fun test_sbc_bcd_on_immediate_00_minus_01_carry_set() { + mpu.Status.D = true + mpu.Status.V = true + mpu.Status.Z = true + mpu.Status.C = true + mpu.Status.N = false + mpu.A = 0x00 + // => $0000 SBC #$00 + writeMem(memory, 0x0000, listOf(0xe9, 0x01)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x99, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.N) + assertFalse(mpu.Status.V) + assertFalse(mpu.Status.C) + } + + @Test + fun test_sbc_bcd_on_immediate_20_minus_0a_carry_unset() { + mpu.Status.D = true + mpu.Status.C = false + mpu.A = 0x20 + // $0000 SBC #$0a + writeMem(memory, 0x0000, listOf(0xe9, 0x0a)) + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x1f, mpu.A) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.V) + } + + // SBC Absolute, X-Indexed + + @Test + fun test_sbc_abs_x_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC $FEE0,X + writeMem(memory, 0x0000, listOf(0xFD, 0xE0, 0xFE)) + mpu.X = 0x0D + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_x_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC $FEE0,X + writeMem(memory, 0x0000, listOf(0xFD, 0xE0, 0xFE)) + mpu.X = 0x0D + memory[0xFEED] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_x_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC $FEE0,X + writeMem(memory, 0x0000, listOf(0xFD, 0xE0, 0xFE)) + mpu.X = 0x0D + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_x_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC $FEE0,X + writeMem(memory, 0x0000, listOf(0xFD, 0xE0, 0xFE)) + mpu.X = 0x0D + memory[0xFEED] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Absolute, Y-Indexed + + @Test + fun test_sbc_abs_y_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC $FEE0,Y + writeMem(memory, 0x0000, listOf(0xF9, 0xE0, 0xFE)) + mpu.Y = 0x0D + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_y_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC $FEE0,Y + writeMem(memory, 0x0000, listOf(0xF9, 0xE0, 0xFE)) + mpu.Y = 0x0D + memory[0xFEED] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_y_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC $FEE0,Y + writeMem(memory, 0x0000, listOf(0xF9, 0xE0, 0xFE)) + mpu.Y = 0x0D + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_abs_y_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC $FEE0,Y + writeMem(memory, 0x0000, listOf(0xF9, 0xE0, 0xFE)) + mpu.Y = 0x0D + memory[0xFEED] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Indirect, Indexed (X) + + @Test + fun test_sbc_ind_x_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC ($10,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xE1, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + mpu.X = 0x03 + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_x_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC ($10,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xE1, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + mpu.X = 0x03 + memory[0xFEED] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_x_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC ($10,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xE1, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + mpu.X = 0x03 + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_x_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC ($10,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xE1, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + mpu.X = 0x03 + memory[0xFEED] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Indexed, Indirect (Y) + + @Test + fun test_sbc_ind_y_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 SBC ($10),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF1, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_y_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC ($10),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF1, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_y_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC ($10),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF1, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_ind_y_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC ($10),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0xF1, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SBC Zero Page, X-Indexed + + @Test + fun test_sbc_zp_x_all_zeros_and_no_borrow_is_zero() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x00 + // $0000 SBC $10,X + writeMem(memory, 0x0000, listOf(0xF5, 0x10)) + mpu.X = 0x0D + memory[0x001D] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_x_downto_zero_no_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = true // borrow = 0 + mpu.A = 0x01 + // $0000 SBC $10,X + writeMem(memory, 0x0000, listOf(0xF5, 0x10)) + mpu.X = 0x0D + memory[0x001D] = 0x01 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_x_downto_zero_with_borrow_sets_z_clears_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x01 + // $0000 SBC $10,X + writeMem(memory, 0x0000, listOf(0xF5, 0x10)) + mpu.X = 0x0D + memory[0x001D] = 0x00 + mpu.step() + assertEquals(0x00, mpu.A) + assertFalse(mpu.Status.N) + assertTrue(mpu.Status.C) + assertTrue(mpu.Status.Z) + } + + @Test + fun test_sbc_zp_x_downto_four_with_borrow_clears_z_n() { + mpu.Status.D = false + mpu.Status.C = false // borrow = 1 + mpu.A = 0x07 + // $0000 SBC $10,X + writeMem(memory, 0x0000, listOf(0xF5, 0x10)) + mpu.X = 0x0D + memory[0x001D] = 0x02 + mpu.step() + assertEquals(0x04, mpu.A) + assertFalse(mpu.Status.N) + assertFalse(mpu.Status.Z) + assertTrue(mpu.Status.C) + } + + // SEC + + @Test + fun test_sec_sets_carry_flag() { + mpu.Status.C = false + // $0000 SEC + memory[0x0000] = 0x038 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertTrue(mpu.Status.C) + } + + // SED + + @Test + fun test_sed_sets_decimal_mode_flag() { + mpu.Status.D = false + // $0000 SED + memory[0x0000] = 0xF8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertTrue(mpu.Status.D) + } + + // SEI + + @Test + fun test_sei_sets_interrupt_disable_flag() { + mpu.Status.I = false + // $0000 SEI + memory[0x0000] = 0x78 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertTrue(mpu.Status.I) + } + + // STA Absolute + + @Test + fun test_sta_absolute_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + // $0000 STA $ABCD + writeMem(memory, 0x0000, listOf(0x8D, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_absolute_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + // $0000 STA $ABCD + writeMem(memory, 0x0000, listOf(0x8D, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Zero Page + + @Test + fun test_sta_zp_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + // $0000 STA $0010 + writeMem(memory, 0x0000, listOf(0x85, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_zp_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + // $0000 STA $0010 + writeMem(memory, 0x0000, listOf(0x85, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Absolute, X-Indexed + + @Test + fun test_sta_abs_x_indexed_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 STA $ABCD,X + writeMem(memory, 0x0000, listOf(0x9D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD + mpu.X]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_abs_x_indexed_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 STA $ABCD,X + writeMem(memory, 0x0000, listOf(0x9D, 0xCD, 0xAB)) + memory[0xABCD + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.X]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Absolute, Y-Indexed + + @Test + fun test_sta_abs_y_indexed_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 STA $ABCD,Y + writeMem(memory, 0x0000, listOf(0x99, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD + mpu.Y]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_abs_y_indexed_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 STA $ABCD,Y + writeMem(memory, 0x0000, listOf(0x99, 0xCD, 0xAB)) + memory[0xABCD + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD + mpu.Y]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Indirect, Indexed (X) + + @Test + fun test_sta_ind_indexed_x_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 STA ($0010,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x81, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + memory[0xFEED] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0xFEED]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_ind_indexed_x_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 STA ($0010,X) + // $0013 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x81, 0x10)) + writeMem(memory, 0x0013, listOf(0xED, 0xFE)) + memory[0xFEED] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0xFEED]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Indexed, Indirect (Y) + + @Test + fun test_sta_indexed_ind_y_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + mpu.Y = 0x03 + // $0000 STA ($0010),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x91, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0xFEED + mpu.Y]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_indexed_ind_y_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + mpu.Y = 0x03 + // $0000 STA ($0010),Y + // $0010 Vector to $FEED + writeMem(memory, 0x0000, listOf(0x91, 0x10)) + writeMem(memory, 0x0010, listOf(0xED, 0xFE)) + memory[0xFEED + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0xFEED + mpu.Y]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STA Zero Page, X-Indexed + + @Test + fun test_sta_zp_x_indexed_stores_a_leaves_a_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.A = 0xFF + mpu.X = 0x03 + // $0000 STA $0010,X + writeMem(memory, 0x0000, listOf(0x95, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010 + mpu.X]) + assertEquals(0xFF, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sta_zp_x_indexed_stores_a_leaves_a_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.A = 0x00 + mpu.X = 0x03 + // $0000 STA $0010,X + writeMem(memory, 0x0000, listOf(0x95, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertEquals(0x00, mpu.A) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STX Absolute + + @Test + fun test_stx_absolute_stores_x_leaves_x_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.X = 0xFF + // $0000 STX $ABCD + writeMem(memory, 0x0000, listOf(0x8E, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD]) + assertEquals(0xFF, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_stx_absolute_stores_x_leaves_x_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.X = 0x00 + // $0000 STX $ABCD + writeMem(memory, 0x0000, listOf(0x8E, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertEquals(0x00, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STX Zero Page + + @Test + fun test_stx_zp_stores_x_leaves_x_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.X = 0xFF + // $0000 STX $0010 + writeMem(memory, 0x0000, listOf(0x86, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010]) + assertEquals(0xFF, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_stx_zp_stores_x_leaves_x_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.X = 0x00 + // $0000 STX $0010 + writeMem(memory, 0x0000, listOf(0x86, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertEquals(0x00, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STX Zero Page, Y-Indexed + + @Test + fun test_stx_zp_y_indexed_stores_x_leaves_x_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.X = 0xFF + mpu.Y = 0x03 + // $0000 STX $0010,Y + writeMem(memory, 0x0000, listOf(0x96, 0x10)) + memory[0x0010 + mpu.Y] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010 + mpu.Y]) + assertEquals(0xFF, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_stx_zp_y_indexed_stores_x_leaves_x_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.X = 0x00 + mpu.Y = 0x03 + // $0000 STX $0010,Y + writeMem(memory, 0x0000, listOf(0x96, 0x10)) + memory[0x0010 + mpu.Y] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.Y]) + assertEquals(0x00, mpu.X) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STY Absolute + + @Test + fun test_sty_absolute_stores_y_leaves_y_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0xFF + // $0000 STY $ABCD + writeMem(memory, 0x0000, listOf(0x8C, 0xCD, 0xAB)) + memory[0xABCD] = 0x00 + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0xFF, memory[0xABCD]) + assertEquals(0xFF, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sty_absolute_stores_y_leaves_y_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0x00 + // $0000 STY $ABCD + writeMem(memory, 0x0000, listOf(0x8C, 0xCD, 0xAB)) + memory[0xABCD] = 0xFF + mpu.step() + assertEquals(0x0003, mpu.PC) + assertEquals(0x00, memory[0xABCD]) + assertEquals(0x00, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STY Zero Page + + @Test + fun test_sty_zp_stores_y_leaves_y_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0xFF + // $0000 STY $0010 + writeMem(memory, 0x0000, listOf(0x84, 0x10)) + memory[0x0010] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010]) + assertEquals(0xFF, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sty_zp_stores_y_leaves_y_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0x00 + // $0000 STY $0010 + writeMem(memory, 0x0000, listOf(0x84, 0x10)) + memory[0x0010] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010]) + assertEquals(0x00, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // STY Zero Page, X-Indexed + + @Test + fun test_sty_zp_x_indexed_stores_y_leaves_y_and_n_flag_unchanged() { + val flags = 0xFF and fNEGATIVE.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0xFF + mpu.X = 0x03 + // $0000 STY $0010,X + writeMem(memory, 0x0000, listOf(0x94, 0x10)) + memory[0x0010 + mpu.X] = 0x00 + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0xFF, memory[0x0010 + mpu.X]) + assertEquals(0xFF, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + @Test + fun test_sty_zp_x_indexed_stores_y_leaves_y_and_z_flag_unchanged() { + val flags = 0xFF and fZERO.inv() + mpu.Status.fromByte(flags) + mpu.Y = 0x00 + mpu.X = 0x03 + // $0000 STY $0010,X + writeMem(memory, 0x0000, listOf(0x94, 0x10)) + memory[0x0010 + mpu.X] = 0xFF + mpu.step() + assertEquals(0x0002, mpu.PC) + assertEquals(0x00, memory[0x0010 + mpu.X]) + assertEquals(0x00, mpu.Y) + assertEquals(flags, mpu.Status.asByte().toInt()) + } + + // TAX + + @Test + fun test_tax_transfers_accumulator_into_x() { + mpu.A = 0xAB + mpu.X = 0x00 + // $0000 TAX + memory[0x0000] = 0xAA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xAB, mpu.X) + } + + @Test + fun test_tax_sets_negative_flag() { + mpu.Status.N = false + mpu.A = 0x80 + mpu.X = 0x00 + // $0000 TAX + memory[0x0000] = 0xAA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + } + + @Test + fun test_tax_sets_zero_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.X = 0xFF + // $0000 TAX + memory[0x0000] = 0xAA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + } + + // TAY + + @Test + fun test_tay_transfers_accumulator_into_y() { + mpu.A = 0xAB + mpu.Y = 0x00 + // $0000 TAY + memory[0x0000] = 0xA8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xAB, mpu.Y) + } + + @Test + fun test_tay_sets_negative_flag() { + mpu.Status.N = false + mpu.A = 0x80 + mpu.Y = 0x00 + // $0000 TAY + memory[0x0000] = 0xA8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + } + + @Test + fun test_tay_sets_zero_flag() { + mpu.Status.Z = false + mpu.A = 0x00 + mpu.Y = 0xFF + // $0000 TAY + memory[0x0000] = 0xA8 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + } + + // TSX + + @Test + fun test_tsx_transfers_stack_pointer_into_x() { + mpu.SP = 0xAB + mpu.X = 0x00 + // $0000 TSX + memory[0x0000] = 0xBA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.SP) + assertEquals(0xAB, mpu.X) + } + + @Test + fun test_tsx_sets_negative_flag() { + mpu.Status.N = false + mpu.SP = 0x80 + mpu.X = 0x00 + // $0000 TSX + memory[0x0000] = 0xBA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.SP) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + } + + @Test + fun test_tsx_sets_zero_flag() { + mpu.Status.Z = false + mpu.SP = 0x00 + mpu.Y = 0xFF + // $0000 TSX + memory[0x0000] = 0xBA + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.SP) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + } + + // TXA + + @Test + fun test_txa_transfers_x_into_a() { + mpu.X = 0xAB + mpu.A = 0x00 + // $0000 TXA + memory[0x0000] = 0x8A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xAB, mpu.X) + } + + @Test + fun test_txa_sets_negative_flag() { + mpu.Status.N = false + mpu.X = 0x80 + mpu.A = 0x00 + // $0000 TXA + memory[0x0000] = 0x8A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertEquals(0x80, mpu.X) + assertTrue(mpu.Status.N) + } + + @Test + fun test_txa_sets_zero_flag() { + mpu.Status.Z = false + mpu.X = 0x00 + mpu.A = 0xFF + // $0000 TXA + memory[0x0000] = 0x8A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.A) + assertEquals(0x00, mpu.X) + assertTrue(mpu.Status.Z) + } + + // TXS + + @Test + fun test_txs_transfers_x_into_stack_pointer() { + mpu.X = 0xAB + // $0000 TXS + memory[0x0000] = 0x9A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.SP) + assertEquals(0xAB, mpu.X) + } + + @Test + fun test_txs_does_not_set_negative_flag() { + mpu.Status.N = false + mpu.X = 0x80 + // $0000 TXS + memory[0x0000] = 0x9A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.SP) + assertEquals(0x80, mpu.X) + assertFalse(mpu.Status.N) + } + + @Test + fun test_txs_does_not_set_zero_flag() { + mpu.Status.Z = false + mpu.X = 0x00 + // $0000 TXS + memory[0x0000] = 0x9A + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x00, mpu.SP) + assertEquals(0x00, mpu.X) + assertFalse(mpu.Status.Z) + } + + // TYA + + @Test + fun test_tya_transfers_y_into_a() { + mpu.Y = 0xAB + mpu.A = 0x00 + // $0000 TYA + memory[0x0000] = 0x98 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0xAB, mpu.A) + assertEquals(0xAB, mpu.Y) + } + + @Test + fun test_tya_sets_negative_flag() { + mpu.Status.N = false + mpu.Y = 0x80 + mpu.A = 0x00 + // $0000 TYA + memory[0x0000] = 0x98 + mpu.step() + assertEquals(0x0001, mpu.PC) + assertEquals(0x80, mpu.A) + assertEquals(0x80, mpu.Y) + assertTrue(mpu.Status.N) + } + + @Test + fun test_tya_sets_zero_flag() { + mpu.Status.Z = false + mpu.Y = 0x00 + mpu.A = 0xFF + // $0000 TYA + memory[0x0000] = 0x98 + mpu.step() + assertEquals(0x00, mpu.A) + assertEquals(0x00, mpu.Y) + assertTrue(mpu.Status.Z) + assertEquals(0x0001, mpu.PC) + } + + @Test + fun test_brk_interrupt() { + writeMem(memory, 0xFFFE, listOf(0x00, 0x04)) + + writeMem(memory, 0x0000, listOf(0xA9, 0x01, // LDA #$01 + 0x00, 0xEA, // BRK + skipped byte + 0xEA, 0xEA, // NOP, NOP + 0xA9, 0x03)) // LDA #$03 + + writeMem(memory, 0x0400, listOf(0xA9, 0x02, // LDA #$02 + 0x40)) // RTI + + mpu.step() // LDA #$01 + assertEquals(0x01, mpu.A) + assertEquals(0x0002, mpu.PC) + mpu.step() // BRK + assertEquals(0x0400, mpu.PC) + mpu.step() // LDA #$02 + assertEquals(0x02, mpu.A) + assertEquals(0x0402, mpu.PC) + mpu.step() // RTI + + assertEquals(0x0004, mpu.PC) + mpu.step() // A NOP + mpu.step() // The second NOP + + mpu.step() // LDA #$03 + assertEquals(0x03, mpu.A) + assertEquals(0x0008, mpu.PC) + } +} diff --git a/src/test/kotlin/TestDisassembler.kt b/src/test/kotlin/TestDisassembler.kt new file mode 100644 index 0000000..35e62f5 --- /dev/null +++ b/src/test/kotlin/TestDisassembler.kt @@ -0,0 +1,29 @@ +import net.razorvine.ksim65.components.Cpu6502 +import net.razorvine.ksim65.components.Ram +import java.io.File +import kotlin.test.* + + +class TestDisassembler { + + @Test + fun testDisassembleAllOpcodes() { + val cpu = Cpu6502(true) + val memory = Ram(0, 0xffff) + memory.load("src/test/kotlin/testfiles/disassem_instr_test.prg", 0x1000 - 2) + val result = cpu.disassemble(memory, 0x1000, 0x1221) + assertEquals(256, result.size) + assertEquals("\$1000 69 01 adc #\$01", result[0]) + + val reference = File("src/test/kotlin/testfiles/disassem_ref_output.txt").readLines() + assertEquals(256, reference.size) + for (line in result.zip(reference)) { + if (line.first != line.second) { + fail("disassembled instruction mismatch: '${line.first}', expected '${line.second}'") + } + } + } + +} + + diff --git a/src/test/kotlin/bcd_vice_sim.c b/src/test/kotlin/bcd_vice_sim.c new file mode 100644 index 0000000..4d8cfab --- /dev/null +++ b/src/test/kotlin/bcd_vice_sim.c @@ -0,0 +1,160 @@ +#include + +static int flag_Z; +static int flag_C; +static int flag_N; +static int flag_V; + +unsigned int ADC(unsigned int A, unsigned int value, unsigned int bcd_mode) +{ + unsigned int tmp_value; + unsigned int tmp; + + tmp_value = (value); + + if (bcd_mode) { + tmp = (A & 0xf) + (tmp_value & 0xf) + flag_C; + if (tmp > 0x9) { + tmp += 0x6; + } + if (tmp <= 0x0f) { + tmp = (tmp & 0xf) + (A & 0xf0) + (tmp_value & 0xf0); + } else { + tmp = (tmp & 0xf) + (A & 0xf0) + (tmp_value & 0xf0) + 0x10; + } + flag_Z = !((A + tmp_value + flag_C) & 0xff); + flag_N = tmp & 0x80; + flag_V = ((A ^ tmp) & 0x80) && !((A ^ tmp_value) & 0x80); + if ((tmp & 0x1f0) > 0x90) { + tmp += 0x60; + } + flag_C = (tmp & 0xff0) > 0xf0; + } else { + tmp = tmp_value + A + flag_C; + flag_Z = (tmp&0xff)==0; + flag_N = (tmp&0x80)!=0; + flag_V = !((A ^ tmp_value) & 0x80) && ((A ^ tmp) & 0x80); + flag_C = tmp > 0xff; + } + return tmp & 0xff; +} + +unsigned int SBC(unsigned int A, unsigned int value, unsigned int bcd_mode) +{ + unsigned int src, tmp; + src = (unsigned int)(value); + tmp = A - src - (flag_C ? 0 : 1); + + if (bcd_mode) { + unsigned int tmp_a; + tmp_a = (A & 0xf) - (src & 0xf) - (flag_C ? 0 : 1); + if (tmp_a & 0x10) { + tmp_a = ((tmp_a - 6) & 0xf) | ((A & 0xf0) - (src & 0xf0) - 0x10); + } else { + tmp_a = (tmp_a & 0xf) | ((A & 0xf0) - (src & 0xf0)); + } + if (tmp_a & 0x100) { + tmp_a -= 0x60; + } + flag_C = tmp < 0x100; + flag_Z = (tmp&0xff)==0; + flag_N = (tmp&0x80)!=0; + flag_V = ((A ^ tmp) & 0x80) && ((A ^ src) & 0x80); + return tmp_a && 255; + } else { + flag_Z = (tmp&0xff)==0; + flag_N = (tmp&0x80)!=0; + flag_C = tmp < 0x100; + flag_V = ((A ^ tmp) & 0x80) && ((A ^ src) & 0x80); + return tmp && 255; + } +} + + +void print_result(int result) { + printf(" %02x", result); + printf(" N=%d", flag_N? 1:0); + printf(" V=%d", flag_V? 1:0); + printf(" Z=%d", flag_Z? 1:0); + printf(" C=%d", flag_C? 1:0); + printf("\n"); +} + +int main(char* argv) { + flag_C = flag_N = flag_V = flag_Z = 0; + + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 0; + printf("adc,normal,carry0: %02x + %02x = ", A, v); + unsigned int result = ADC(A, v, 0); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 1; + printf("adc,normal,carry1: %02x + %02x = ", A, v); + unsigned int result = ADC(A, v, 0); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 0; + printf("adc,bcd,carry0: %02x + %02x = ", A, v); + unsigned int result = ADC(A, v, 1); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 1; + printf("adc,bcd,carry1: %02x + %02x = ", A, v); + unsigned int result = ADC(A, v, 1); + print_result(result); + } + } + + + + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 0; + printf("sbc,normal,carry0: %02x - %02x = ", A, v); + unsigned int result = SBC(A, v, 0); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 1; + printf("sbc,normal,carry1: %02x - %02x = ", A, v); + unsigned int result = SBC(A, v, 0); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 0; + printf("sbc,bcd,carry0: %02x - %02x = ", A, v); + unsigned int result = SBC(A, v, 1); + print_result(result); + } + } + printf("\n"); + for(unsigned int A=0; A<256; ++A) { + for(unsigned int v=0; v<256; ++v) { + flag_C = 1; + printf("sbc,bcd,carry1: %02x - %02x = ", A, v); + unsigned int result = SBC(A, v, 1); + print_result(result); + } + } +} + diff --git a/src/test/kotlin/testfiles/bcdtest.bin b/src/test/kotlin/testfiles/bcdtest.bin new file mode 100644 index 0000000..85d2f8e Binary files /dev/null and b/src/test/kotlin/testfiles/bcdtest.bin differ diff --git a/src/test/kotlin/testfiles/disassem_instr_test.prg b/src/test/kotlin/testfiles/disassem_instr_test.prg new file mode 100644 index 0000000..c260fcc Binary files /dev/null and b/src/test/kotlin/testfiles/disassem_instr_test.prg differ diff --git a/src/test/kotlin/testfiles/disassem_ref_output.txt b/src/test/kotlin/testfiles/disassem_ref_output.txt new file mode 100644 index 0000000..826e46b --- /dev/null +++ b/src/test/kotlin/testfiles/disassem_ref_output.txt @@ -0,0 +1,256 @@ +$1000 69 01 adc #$01 +$1002 65 02 adc $02 +$1004 75 03 adc $03,x +$1006 6d 05 04 adc $0405 +$1009 7d 07 06 adc $0607,x +$100c 79 09 08 adc $0809,y +$100f 61 0a adc ($0a,x) +$1011 71 0b adc ($0b),y +$1013 29 0c and #$0c +$1015 25 0d and $0d +$1017 35 0e and $0e,x +$1019 2d 10 0f and $0f10 +$101c 3d 12 11 and $1112,x +$101f 39 14 13 and $1314,y +$1022 21 15 and ($15,x) +$1024 31 16 and ($16),y +$1026 0a asl a +$1027 06 17 asl $17 +$1029 16 18 asl $18,x +$102b 0e 1a 19 asl $191a +$102e 1e 1c 1b asl $1b1c,x +$1031 90 1d bcc $1050 +$1033 b0 1e bcs $1053 +$1035 f0 1f beq $1056 +$1037 24 20 bit $20 +$1039 2c 22 21 bit $2122 +$103c 30 23 bmi $1061 +$103e d0 24 bne $1064 +$1040 10 25 bpl $1067 +$1042 00 brk +$1043 50 26 bvc $106b +$1045 70 27 bvs $106e +$1047 18 clc +$1048 d8 cld +$1049 58 cli +$104a b8 clv +$104b c9 28 cmp #$28 +$104d c5 29 cmp $29 +$104f d5 2a cmp $2a,x +$1051 cd 2c 2b cmp $2b2c +$1054 dd 2e 2d cmp $2d2e,x +$1057 d9 30 2f cmp $2f30,y +$105a c1 31 cmp ($31,x) +$105c d1 32 cmp ($32),y +$105e e0 33 cpx #$33 +$1060 e4 34 cpx $34 +$1062 ec 36 35 cpx $3536 +$1065 c0 37 cpy #$37 +$1067 c4 38 cpy $38 +$1069 cc 3a 39 cpy $393a +$106c c6 3b dec $3b +$106e d6 3c dec $3c,x +$1070 ce 3e 3d dec $3d3e +$1073 de 40 3f dec $3f40,x +$1076 ca dex +$1077 88 dey +$1078 49 41 eor #$41 +$107a 45 42 eor $42 +$107c 55 43 eor $43,x +$107e 4d 45 44 eor $4445 +$1081 5d 47 46 eor $4647,x +$1084 59 49 48 eor $4849,y +$1087 41 4a eor ($4a,x) +$1089 51 4b eor ($4b),y +$108b e6 4c inc $4c +$108d f6 4d inc $4d,x +$108f ee 4f 4e inc $4e4f +$1092 fe 51 50 inc $5051,x +$1095 e8 inx +$1096 c8 iny +$1097 4c 53 52 jmp $5253 +$109a 6c 55 54 jmp ($5455) +$109d 20 57 56 jsr $5657 +$10a0 a9 58 lda #$58 +$10a2 a5 59 lda $59 +$10a4 b5 5a lda $5a,x +$10a6 ad 5c 5b lda $5b5c +$10a9 bd 5e 5d lda $5d5e,x +$10ac b9 60 5f lda $5f60,y +$10af a1 61 lda ($61,x) +$10b1 b1 62 lda ($62),y +$10b3 a2 63 ldx #$63 +$10b5 a6 64 ldx $64 +$10b7 b6 65 ldx $65,y +$10b9 ae 67 66 ldx $6667 +$10bc be 69 68 ldx $6869,y +$10bf a0 6a ldy #$6a +$10c1 a4 6b ldy $6b +$10c3 b4 6c ldy $6c,x +$10c5 ac 6e 6d ldy $6d6e +$10c8 bc 70 6f ldy $6f70,x +$10cb 4a lsr a +$10cc 46 71 lsr $71 +$10ce 56 72 lsr $72,x +$10d0 4e 74 73 lsr $7374 +$10d3 5e 76 75 lsr $7576,x +$10d6 ea nop +$10d7 09 77 ora #$77 +$10d9 05 78 ora $78 +$10db 15 79 ora $79,x +$10dd 0d 7b 7a ora $7a7b +$10e0 1d 7d 7c ora $7c7d,x +$10e3 19 7f 7e ora $7e7f,y +$10e6 01 80 ora ($80,x) +$10e8 11 81 ora ($81),y +$10ea 48 pha +$10eb 08 php +$10ec 68 pla +$10ed 28 plp +$10ee 2a rol a +$10ef 26 82 rol $82 +$10f1 36 83 rol $83,x +$10f3 2e 85 84 rol $8485 +$10f6 3e 87 86 rol $8687,x +$10f9 6a ror a +$10fa 66 88 ror $88 +$10fc 76 89 ror $89,x +$10fe 6e 8b 8a ror $8a8b +$1101 7e 8d 8c ror $8c8d,x +$1104 40 rti +$1105 60 rts +$1106 e9 8e sbc #$8e +$1108 e5 8f sbc $8f +$110a f5 90 sbc $90,x +$110c ed 92 91 sbc $9192 +$110f fd 94 93 sbc $9394,x +$1112 f9 96 95 sbc $9596,y +$1115 e1 97 sbc ($97,x) +$1117 f1 98 sbc ($98),y +$1119 38 sec +$111a f8 sed +$111b 78 sei +$111c 85 99 sta $99 +$111e 95 9a sta $9a,x +$1120 8d 9c 9b sta $9b9c +$1123 9d 9e 9d sta $9d9e,x +$1126 99 a0 9f sta $9fa0,y +$1129 81 a1 sta ($a1,x) +$112b 91 a2 sta ($a2),y +$112d 86 a3 stx $a3 +$112f 96 a4 stx $a4,y +$1131 8e a6 a5 stx $a5a6 +$1134 84 a7 sty $a7 +$1136 94 a8 sty $a8,x +$1138 8c aa a9 sty $a9aa +$113b aa tax +$113c a8 tay +$113d ba tsx +$113e 8a txa +$113f 9a txs +$1140 98 tya +$1141 02 ??? +$1142 12 ??? +$1143 22 ??? +$1144 32 ??? +$1145 42 ??? +$1146 52 ??? +$1147 62 ??? +$1148 72 ??? +$1149 92 ??? +$114a b2 ??? +$114b d2 ??? +$114c f2 ??? +$114d 7a nop +$114e 5a nop +$114f 1a nop +$1150 3a nop +$1151 da nop +$1152 fa nop +$1153 80 00 nop #$00 +$1155 82 00 nop #$00 +$1157 89 00 nop #$00 +$1159 c2 00 nop #$00 +$115b e2 00 nop #$00 +$115d 04 00 nop $00 +$115f 64 00 nop $00 +$1161 44 00 nop $00 +$1163 0c 00 00 nop $0000 +$1166 14 00 nop $00,x +$1168 34 00 nop $00,x +$116a 54 00 nop $00,x +$116c 74 00 nop $00,x +$116e d4 00 nop $00,x +$1170 f4 00 nop $00,x +$1172 1c 00 00 nop $0000,x +$1175 3c 00 00 nop $0000,x +$1178 5c 00 00 nop $0000,x +$117b 7c 00 00 nop $0000,x +$117e dc 00 00 nop $0000,x +$1181 fc 00 00 nop $0000,x +$1184 ab 00 lax #$00 +$1186 a7 00 lax $00 +$1188 b7 00 lax $00,y +$118a af 00 00 lax $0000 +$118d bf 00 00 lax $0000,y +$1190 a3 00 lax ($00,x) +$1192 b3 00 lax ($00),y +$1194 87 00 sax $00 +$1196 97 00 sax $00,y +$1198 8f 00 00 sax $0000 +$119b 83 00 sax ($00,x) +$119d eb 00 sbc #$00 +$119f c7 00 dcp $00 +$11a1 d7 00 dcp $00,x +$11a3 cf 00 00 dcp $0000 +$11a6 df 00 00 dcp $0000,x +$11a9 db 00 00 dcp $0000,y +$11ac c3 00 dcp ($00,x) +$11ae d3 00 dcp ($00),y +$11b0 e7 00 isc $00 +$11b2 f7 00 isc $00,x +$11b4 ef 00 00 isc $0000 +$11b7 ff 00 00 isc $0000,x +$11ba fb 00 00 isc $0000,y +$11bd e3 00 isc ($00,x) +$11bf f3 00 isc ($00),y +$11c1 27 00 rla $00 +$11c3 37 00 rla $00,x +$11c5 2f 00 00 rla $0000 +$11c8 3f 00 00 rla $0000,x +$11cb 3b 00 00 rla $0000,y +$11ce 23 00 rla ($00,x) +$11d0 33 00 rla ($00),y +$11d2 67 00 rra $00 +$11d4 77 00 rra $00,x +$11d6 6f 00 00 rra $0000 +$11d9 7f 00 00 rra $0000,x +$11dc 7b 00 00 rra $0000,y +$11df 63 00 rra ($00,x) +$11e1 73 00 rra ($00),y +$11e3 07 00 slo $00 +$11e5 17 00 slo $00,x +$11e7 0f 00 00 slo $0000 +$11ea 1f 00 00 slo $0000,x +$11ed 1b 00 00 slo $0000,y +$11f0 03 00 slo ($00,x) +$11f2 13 00 slo ($00),y +$11f4 47 00 sre $00 +$11f6 57 00 sre $00,x +$11f8 4f 00 00 sre $0000 +$11fb 5f 00 00 sre $0000,x +$11fe 5b 00 00 sre $0000,y +$1201 43 00 sre ($00,x) +$1203 53 00 sre ($00),y +$1205 0b 00 anc #$00 +$1207 2b 00 anc #$00 +$1209 4b 00 alr #$00 +$120b 6b 00 arr #$00 +$120d 8b 00 xaa #$00 +$120f 93 00 ahx ($00),y +$1211 9f 00 00 ahx $0000,y +$1214 9b 00 00 tas $0000,y +$1217 9e 00 00 shx $0000,y +$121a 9c 00 00 shy $0000,x +$121d bb 00 00 las $0000,y +$1220 cb 00 axs #$00 diff --git a/src/test/kotlin/testfiles/ram.bin b/src/test/kotlin/testfiles/ram.bin new file mode 100644 index 0000000..3dc0bb7 Binary files /dev/null and b/src/test/kotlin/testfiles/ram.bin differ