Repository: marioballano/emudore
Branch: master
Commit: 5d98f4447409
Files: 42
Total size: 1013.4 KB
Directory structure:
gitextract_1yla08f4/
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── README.md
├── assets/
│ ├── bas/
│ │ ├── 10print.bas
│ │ ├── bitmap.bas
│ │ ├── bouncing.bas
│ │ └── lowercase.bas
│ ├── prg/
│ │ └── monopole.prg
│ ├── roms/
│ │ └── README.md
│ └── tests/
│ ├── 6502_functional_test.a65
│ ├── 6502_functional_test.lst
│ └── README.md
├── cmake/
│ ├── FindSDL2.cmake
│ ├── FindSDL2_image.cmake
│ ├── FindSDL2_net.cmake
│ ├── FindSDL2_ttf.cmake
│ └── README.md
├── doc/
│ ├── .gitignore
│ └── doxygen.conf
├── res/
│ └── emudore.rc
└── src/
├── c64.cpp
├── c64.h
├── cia1.cpp
├── cia1.h
├── cia2.cpp
├── cia2.h
├── cpu.cpp
├── cpu.h
├── debugger.cpp
├── debugger.h
├── io.cpp
├── io.h
├── loader.cpp
├── loader.h
├── main.cpp
├── memory.cpp
├── memory.h
├── sid.h
├── util.h
├── vic.cpp
└── vic.h
================================================
FILE CONTENTS
================================================
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required (VERSION 2.8)
project(emudore)
set(SRC_FILES "src/c64.cpp"
"src/cpu.cpp"
"src/memory.cpp"
"src/cia1.cpp"
"src/cia2.cpp"
"src/vic.cpp"
"src/io.cpp"
"src/loader.cpp"
"src/main.cpp")
# GCC and Clang
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
# C++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
# r2 debugging support, for now only available on Linux
# and OSX Debug builds, if you want it enabled on release
# mode just remove the second part of the expression
if(CMAKE_BUILD_TYPE MATCHES "Debug" AND
(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin"))
add_definitions(-DDEBUGGER_SUPPORT)
set(SRC_FILES ${SRC_FILES} "src/debugger.cpp")
endif()
# MSVC, using pre-built binaries downloaded from:
# https://www.libsdl.org/download-2.0.php
if (MSVC)
set(SDL2_PATH "C:\\SDL2")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
add_executable (emudore ${SRC_FILES} res/emudore.rc)
set_target_properties(emudore PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS")
set_target_properties(emudore PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
else()
add_executable (emudore ${SRC_FILES})
endif()
# JavaScript and WebAssembly builds with emscripten
if(CMAKE_SYSTEM_NAME MATCHES "Emscripten")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -s USE_SDL=2 -s DISABLE_EXCEPTION_CATCHING=0 --preload-file assets/roms/")
if(WASM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
endif()
endif()
# SDL2
# Cmake 2.8 does not provide scripts to find SDL2, adding
# them to the cmake module path and here for convenience
if(NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})
endif()
# link
target_link_libraries(emudore ${SDL2_LIBRARY})
# copy assets to build directory
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets/ ${CMAKE_BINARY_DIR}/assets/)
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
release:
rm -rf build/*
cd build;cmake -DCMAKE_BUILD_TYPE=Release ..
cd build;make
debug:
rm -rf build/*
cd build;cmake -DCMAKE_BUILD_TYPE=Debug ..
cd build;make
js:
rm -rf build/*
cd build;cmake -DCMAKE_TOOLCHAIN_FILE=~/emsdk/emscripten/incoming/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release ..
cd build;make
wasm:
rm -rf build/*
cd build;cmake -DCMAKE_TOOLCHAIN_FILE=~/emsdk/emscripten/incoming/cmake/Modules/Platform/Emscripten.cmake -DWASM=1 -DCMAKE_BUILD_TYPE=Release ..
cd build;make
================================================
FILE: README.md
================================================
# emudore, a Commodore 64 emulator

# What's this?
emudore is a [Commodore 64 emulator](https://en.wikipedia.org/wiki/Commodore_64),
fully written from the scratch and built on the top of the following technologies:
* [C++11](https://en.wikipedia.org/wiki/C%2B%2B11)
* [SDL2](https://www.libsdl.org/download-2.0.php)
emudore builds and runs on Linux, Windows (Visual Studio), OSX and even runs in
your browser thanks to Emscriptem, it should theoretically work on any platform
supported by SDL2 provided a C++11 compiler is available.
# JavaScript and WebAssembly builds
If you wish to play a bit around without having to go through the hassle of
compiling it you can try the web build:
* [emudore (boot into CBM BASIC)](http://marioballano.github.io/emudorejs/)
* [emudore (load Monopole PRG)](http://marioballano.github.io/emudorejs/?load=samples/monopole.prg)
A [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly) build of emudore is also available,
please note that a browser with WebAssembly support is required to run these demos:
* [emudore (boot into CBM BASIC)](http://marioballano.github.io/emudorewa/)
* [emudore (load Monopole PRG)](http://marioballano.github.io/emudorewa/?load=samples/monopole.prg)
# Why am I writing another C64 emulator?
Long story short: to learn a bit more about computer architecture, graphics,
C++, etc.. while having some fun!
The Commodore 64 is regarded as one of the most epic 8-bit computers, it was actually
the first computer I ever laid hands on - thanks to my dad :) - and it seemed like a
sound choice to write an emulator for.
# Does this even work?
Well, yeah, mostly...
The BASIC ROM runs just fine, and most simple programs run without issues, however, many
of the more advanced games written in ML do not yet play well due to unimplemented hardware
features, writing an emulator is a tough task and after all my goal wasn't to write a full
perfect emulator but to learn in the process of making a simple one, here follow some facts
you might be interested in knowing about emudore's implementation:
**emulation is instruction-exact**
That's right, on every emulation cycle a single instruction is fetched and interpreted,
the number of CPU cycles the instruction has taken to execute is used to synchronize the
rest of the chips in a C64 board.
Unfortunately, this is not the best approach, other emulators are able to execute a single
instruction over multiple iterations of their emulation loop and mimic more accurately
the behaviour of the real hardware, however, this is an easier approach to implement
and does not impede the emulation from being relatively accurate.
**illegal opcodes not supported yet**
As many other architectures the MOS 6510 features a number of undocumented opcodes,
most of these are thought to be unintended and usually perform a mix of other opcodes
operations:
[NMOS 6510 Unintended Opcodes - PDF](http://csdb.dk/getinternalfile.php/135165/NoMoreSecrets-NMOS6510UnintendedOpcodes-20142412.pdf)
Nevertheless, some of these unintended opcodes have proven to be useful and are often
used in games and demos, emudore will need to support these in the future if we ever
intend to emulate serious games and demos.
**single-threaded**
emudore has been written as a single-threaded program, everything (including graphics) is
handled within the same thread, again, this approach has possibly some drawbacks, especially
in terms of performance, but it greatly simplifies the architecture: things like
synchronization of the mainboard chips become easier to implement.
**hardware acceleration and vertical refresh sync**
The screen is refreshed once at the end of every frame, when the video raster reaches the
last visible scanline, this way we're not constantly writing to the host video memory.
Also, to speed things up a bit I implemented hardware acceleration, we use an accelerated
renderer and streaming textures, unfortunately, we need to keep the rendered video frame
within emudore's memory and upload the texture to the GPU on every frame, direct pixel-access
is not doable straight on the GPU memory.
I also implemented vertical refresh synchronization, at the end of every frame we check
whether we are ahead of time compared to a real C64 computer, if that's the case we sleep
for a bit and wake up at the point a real C64 would have finished rendering the frame, this
effectively locks the screen refresh down to ~50Hz (PAL).
There are two main benefits of implementing vsync: it helps with performance since GPU
operations are costly and after all we don't want to run at the limit of fps our GPU can
handle; also, and more importantly, by doing this we emulate the speed of the real C64
computer synce the CPU and other chips are synchronized and run within the same thread, if
we are on a fast computer visual effects won't look accelerated and games become playable :)
**VIC-II chip**
The vic-ii is a relatively complex chip, my implementation is not yet complete whatsoever,
and certain features are more than likely still buggy, for now four out of the five official
graphic modes are supported:
* standard character mode
* multicolor character mode
* standard bitmap mode
* multicolor bitmap mode
Smooth scrolling, sprites and raster interrupts have also been implemented and badlines
are also emulated.
Some things that are left to implement include: sprite double height/width mode, sprite
collision interrupts, etc.
A simple approach was taken to emulate the raster beam drawing, pixels drawn to the
screen surface are computed at the end of each scan line, this might result in
certain graphic effects being badly emulated, bear in mind that timing is of the essence
in the c64, well-versed programmers master and exploit it to put together amazing
effects that otherwise wouldn't be feasible.
**beware**
Due to some of the aforementioned facts, expect things to fail, don't even dream
the emulation is going to be pixel-exact, certain effects are likely to get badly
emulated, specially if you're running things like a demo.
# Are you bleedin' serious radare2 is supported?
Indeed, for now it's only suppported on Linux and OSX (debug) builds, you can grab
a fresh copy of radare from [github](https://github.com/radare/radare2)
Then fire the emulator up and connect with radare:
r2 -w -a 6502 rap://localhost:9999//
For now radare can just read and modify memory, further support might be coming
down the line once [this feature](https://github.com/radare/radare2/issues/4173)
gets implemented in radare.
Some pictures of radare in action:


I hope this feature will come in useful to retrodev reverse engineers :)
# So now .. what?
There are many features of the currently emulated chips that I haven't implemented
yet, time permitting my plan is to keep working and learning about other aspects of
the C64 technology, also, at some stage I'd love to get the time to work on:
* Sound support: [SID](https://en.wikipedia.org/wiki/MOS_Technology_SID)
* Floppy drive support: [VIC-1541](https://en.wikipedia.org/wiki/Commodore_1541)
# Alright, enough of your jibba-jabba, how do I run this?
If you are running a Linux Debian-based distro:
sudo apt-get install g++ cmake libsdl2-dev
Then simply compile and run:
make release
cd build
./emudore
# What C64 programs can I load into this?
For the time being emudore can load PRGs, you can test:
./emudore assets/prg/monopole.prg
emudore can also type BASIC listings for you (special keys not supported yet):
./emudore assets/bas/10print.bas
(then type RUN at the emulator window)
# Got some more screenshots?
Sure..
  
  
# References
If you are interested in computer archeology, and particularly in the C64, among
others, the following resources came in handy to develop (and get inspiration) while
developing emudore:
* [The C64 Wiki](http://www.c64-wiki.com/)
* [Programming the Commodore 64: The Definitive Guide](http://www.amazon.co.uk/Programming-Commodore-64-Definitive-Guide/dp/0874550815/)
* [Commodore: A Company on the Edge (book)](http://www.amazon.co.uk/Commodore-Company-Edge-Brian-Bagnall/dp/0973864966/)
* [The Ultimate Commodore 64 Talk](https://www.youtube.com/watch?v=ZsRRCnque2E)
* [Behind the scenes of a C64 demo](https://www.youtube.com/watch?v=So-m4NUzKLw)
* [Dustlayer's blog](http://dustlayer.com/blog/)
* [The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64](http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt)
# Forks
Some people have forked emudore and experimented with it, some notable forks include:
* [Chris Frantz's C64 and NES emulator](https://github.com/cfrantz/emudore)
* [Scott Hutter's bare metal x86-64 emulator](https://github.com/xlar54/emudore64)
# License
I don't think anybody will ever dare to use this for an actual useful purpose, but just in case,
the project is licensed under the [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0)
================================================
FILE: assets/bas/10print.bas
================================================
REM source: http://10print.org/
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
================================================
FILE: assets/bas/bitmap.bas
================================================
10 POKE 53272,PEEK(53272)OR8:POKE 53265,PEEK(53265)OR32
20 FORI=8192TO16191 STEP 8
30 POKEI,240:POKEI+1,240:POKEI+2,240:POKEI+3,240
40 POKEI+4,15:POKEI+5,15:POKEI+6,15:POKEI+7,15
50 NEXT
60 FORI=1024TO2034:POKEI,251:NEXT
70 GOTO 70
================================================
FILE: assets/bas/bouncing.bas
================================================
REM source: http://www.lemon64.com/manual/
NEW
10 POKE 53281,1: PRINT"*"
20 POKE 53280,7: POKE 53281,6
30 X = 1 : Y = 1
40 DX = 1 : DY = 1
50 POKE 1024 + X + 40 * Y, 81
60 FOR T = 1 TO 10 : NEXT
70 POKE 1024 + X + 40 * Y, 32
80 X = X + DX
90 IF X <= 0 OR X >= 39 THEN DX = -DX
100 Y = Y + DY
110 IF Y <= 0 OR Y >= 24 THEN DY = -DY
120 GOTO 50
================================================
FILE: assets/bas/lowercase.bas
================================================
REM SWITCH TO LOWERCASE MODE
POKE 53272,23
================================================
FILE: assets/roms/README.md
================================================
The following files have been downloaded from:
ftp://www.zimmers.net/pub/cbm/firmware/computers/c64/
Please, bear in mind that these files might be subject to other licenses
than emudore's
# kernal.901227-03.bin
This 8-kilobyte 2364 ROM is the third and essentially last revision of
the Commodore 64 KERNAL. It is the most widely spread version.
# basic.901226-01.bin
Commodore 64 BASIC V2. The first and essentially only revision, located at
$A000-$BFFF. In the 64GS system firmware, the 30 unused bytes at $BF53-$BF70
are filled with $00 instead of $AA. In the Commodore 65 firmware, these bytes
are filled with $FF.
# characters.901225-01.bin
The character generator ROM.
================================================
FILE: assets/tests/6502_functional_test.a65
================================================
;
; 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 21-oct-2015
; 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
; 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 = 0
;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
set_stat 0
lda #'B'
ldx #'R'
ldy #'K' ;N=0, V=0, Z=0, C=0
brk
else
lda #hi brk_ret ;emulated break
pha
lda #lo brk_ret
pha
lda #fao ;set break & unused on stack
pha
set_stat intdis
lda #'B'
ldx #'R'
ldy #'K' ;N=0, V=0, Z=0, C=0
jmp irq_trap
endif
dey ;should not be executed
brk_ret ;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?
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
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
; 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
;trap in case of unexpected IRQ, NMI, BRK, RESET - BRK test target
nmi_trap
trap ;check stack for conditions at NMI
res_trap
trap ;unexpected RESET
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 4 traps could be caused by unexpected BRK or IRQ
;check stack for BREAK and originating location
;possible jump/branch into weeds (uninitialized space)
cmp #'B' ;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
trap_ne ; - no break flag on stack
pla
cmp #fai ;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_ret)
trap_ne
lda $1fe
cmp #lo(brk_ret)
trap_ne
set_stat $ff
ldx irq_x
inx ;return registers with modifications
lda irq_a
eor #$aa ;N=1, V=1, Z=0, C=1 but original flags should be restored
rti
trap ;runover protection
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
================================================
FILE: assets/tests/6502_functional_test.lst
================================================
AS65 Assembler for R6502 [1.42]. Copyright 1994-2007, Frank A. Kingswood Page 1
---------------------------------------------------- 6502_functional_test.a65 ----------------------------------------------------
6010 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 21-oct-2015
; 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
; 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
0000 = load_data_direct = 0
;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
000a = org zero_page
;break test interrupt save
000a = irq_a ds 1 ;a register
000b = 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 = adfc ds 1 ;carry flag before op
000d = ad1 ds 1 ;operand 1 - accumulator
000e = ad2 ds 1 ;operand 2 - memory / immediate
000f = adrl ds 1 ;expected result bits 0-7
0010 = adrh ds 1 ;expected result bit 8 (carry)
0011 = adrf ds 1 ;expected flags NV0000ZC (only binary mode)
0012 = sb2 ds 1 ;operand 2 complemented for subtract
0013 = zp_bss
0013 = zp1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
0017 = zp7f db $7f ;test pattern for compare
;logical zeropage operands
0018 = zpOR db 0,$1f,$71,$80 ;test pattern for OR
001c = zpAN db $0f,$ff,$7f,$80 ;test pattern for AND
0020 = zpEO db $ff,$0f,$8f,$8f ;test pattern for EOR
;indirect addressing pointers
0024 = ind1 dw abs1 ;indirect pointer to pattern in absolute memory
0026 = dw abs1+1
0028 = dw abs1+2
002a = dw abs1+3
002c = dw abs7f
002e = inw1 dw abs1-$f8 ;indirect pointer for wrap-test pattern
0030 = indt dw abst ;indirect pointer to store area in absolute memory
0032 = dw abst+1
0034 = dw abst+2
0036 = dw abst+3
0038 = inwt dw abst-$f8 ;indirect pointer for wrap-test store
003a = indAN dw absAN ;indirect pointer to AND pattern in absolute memory
003c = dw absAN+1
003e = dw absAN+2
0040 = dw absAN+3
0042 = indEO dw absEO ;indirect pointer to EOR pattern in absolute memory
0044 = dw absEO+1
0046 = dw absEO+2
0048 = dw absEO+3
004a = indOR dw absOR ;indirect pointer to OR pattern in absolute memory
004c = dw absOR+1
004e = dw absOR+2
0050 = dw absOR+3
;add/subtract indirect pointers
0052 = adi2 dw ada2 ;indirect pointer to operand 2 in absolute memory
0054 = sbi2 dw sba2 ;indirect pointer to complemented operand 2 (SBC)
0056 = adiy2 dw ada2-$ff ;with offset for indirect indexed
0058 = sbiy2 dw sba2-$ff
005a = zp_bss_end
0200 = org data_segment
0200 = test_case ds 1 ;current test number
0201 = 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 = ada2 ds 1 ;operand 2
0204 = sba2 ds 1 ;operand 2 complemented for subtract
0205 = ds 3 ;fill remaining bytes
0208 = 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
0208 = ex_andi ds 3
020b = ex_eori ds 3
020e = ex_orai ds 3
0211 = ex_adci ds 3
0214 = ex_sbci ds 3
endif
0217 = abs1 db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
021b = abs7f db $7f ;test pattern for compare
;loads
021c = fLDx db fn,fn,0,fz ;expected flags for load
;shifts
0220 = rASL ;expected result ASL & ROL -carry
0220 = rROL db $86,$04,$82,0 ; "
0224 = rROLc db $87,$05,$83,1 ;expected result ROL +carry
0228 = rLSR ;expected result LSR & ROR -carry
0228 = rROR db $61,$41,$20,0 ; "
022c = rRORc db $e1,$c1,$a0,$80 ;expected result ROR +carry
0230 = fASL ;expected flags for shifts
0230 = fROL db fnc,fc,fn,fz ;no carry in
0234 = fROLc db fnc,fc,fn,0 ;carry in
0238 = fLSR
0238 = fROR db fc,0,fc,fz ;no carry in
023c = fRORc db fnc,fn,fnc,fn ;carry in
;increments (decrements)
0240 = rINC db $7f,$80,$ff,0,1 ;expected result for INC/DEC
0245 = fINC db 0,fn,fn,fz,0 ;expected flags for INC/DEC
;logical memory operand
024a = absOR db 0,$1f,$71,$80 ;test pattern for OR
024e = absAN db $0f,$ff,$7f,$80 ;test pattern for AND
0252 = absEO db $ff,$0f,$8f,$8f ;test pattern for EOR
;logical accu operand
0256 = absORa db 0,$f1,$1f,0 ;test pattern for OR
025a = absANa db $f0,$ff,$ff,$ff ;test pattern for AND
025e = absEOa db $ff,$f0,$f0,$0f ;test pattern for EOR
;logical results
0262 = absrlo db 0,$ff,$7f,$80
0266 = 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
0438 : a246 ldx #zp_end-zp_init-1
043a : bddc37 ld_zp lda zp_init,x
043d : 9513 sta zp_bss,x
043f : ca dex
0440 : 10f8 bpl ld_zp
0442 : a261 ldx #data_end-data_init-1
0444 : bd2338 ld_data lda data_init,x
0447 : 9d0802 sta data_bss,x
044a : ca dex
044b : 10f7 bpl ld_data
if ROM_vectors = 1
044d : a205 ldx #5
044f : bd8538 ld_vect lda vec_init,x
0452 : 9dfaff sta vec_bss,x
0455 : ca dex
0456 : 10f7 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
0458 : ad0002 > lda test_case ;previous test
045b : c900 > cmp #test_num
> trap_ne ;test is out of sequence
045d : d0fe > bne * ;failed not equal (non zero)
>
0001 = >test_num = test_num + 1
045f : a901 > lda #test_num ;*** next tests' number
0461 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
if disable_selfmod = 0
;testing relative addressing with BEQ
0464 : a0fe ldy #$fe ;testing maximum range, not -1/-2 (invalid/self adr)
0466 : range_loop
0466 : 88 dey ;next relative address
0467 : 98 tya
0468 : aa tax ;precharge count to end of loop
0469 : 1008 bpl range_fw ;calculate relative address
046b : 18 clc ;avoid branch self or to relative address of branch
046c : 6902 adc #2
046e : ea nop ;offset landing zone - tolerate +/-5 offset to branch
046f : ea nop
0470 : ea nop
0471 : ea nop
0472 : ea nop
0473 : range_fw
0473 : ea nop
0474 : ea nop
0475 : ea nop
0476 : ea nop
0477 : ea nop
0478 : 497f eor #$7f ;complement except sign
047a : 8d0605 sta range_adr ;load into test target
047d : a900 lda #0 ;should set zero flag in status register
047f : 4c0505 jmp range_op
0482 : ca dex ; offset landing zone - backward branch too far
0483 : ca dex
0484 : ca dex
0485 : ca dex
0486 : ca dex
;relative address target field with branch under test in the middle
0487 : ca dex ;-128 - max backward
0488 : ca dex
0489 : ca dex
048a : ca dex
048b : ca dex
048c : ca dex
048d : ca dex
048e : ca dex
048f : ca dex ;-120
0490 : ca dex
0491 : ca dex
0492 : ca dex
0493 : ca dex
0494 : ca dex
0495 : ca dex
0496 : ca dex
0497 : ca dex
0498 : ca dex
0499 : ca dex ;-110
049a : ca dex
049b : ca dex
049c : ca dex
049d : ca dex
049e : ca dex
049f : ca dex
04a0 : ca dex
04a1 : ca dex
04a2 : ca dex
04a3 : ca dex ;-100
04a4 : ca dex
04a5 : ca dex
04a6 : ca dex
04a7 : ca dex
04a8 : ca dex
04a9 : ca dex
04aa : ca dex
04ab : ca dex
04ac : ca dex
04ad : ca dex ;-90
04ae : ca dex
04af : ca dex
04b0 : ca dex
04b1 : ca dex
04b2 : ca dex
04b3 : ca dex
04b4 : ca dex
04b5 : ca dex
04b6 : ca dex
04b7 : ca dex ;-80
04b8 : ca dex
04b9 : ca dex
04ba : ca dex
04bb : ca dex
04bc : ca dex
04bd : ca dex
04be : ca dex
04bf : ca dex
04c0 : ca dex
04c1 : ca dex ;-70
04c2 : ca dex
04c3 : ca dex
04c4 : ca dex
04c5 : ca dex
04c6 : ca dex
04c7 : ca dex
04c8 : ca dex
04c9 : ca dex
04ca : ca dex
04cb : ca dex ;-60
04cc : ca dex
04cd : ca dex
04ce : ca dex
04cf : ca dex
04d0 : ca dex
04d1 : ca dex
04d2 : ca dex
04d3 : ca dex
04d4 : ca dex
04d5 : ca dex ;-50
04d6 : ca dex
04d7 : ca dex
04d8 : ca dex
04d9 : ca dex
04da : ca dex
04db : ca dex
04dc : ca dex
04dd : ca dex
04de : ca dex
04df : ca dex ;-40
04e0 : ca dex
04e1 : ca dex
04e2 : ca dex
04e3 : ca dex
04e4 : ca dex
04e5 : ca dex
04e6 : ca dex
04e7 : ca dex
04e8 : ca dex
04e9 : ca dex ;-30
04ea : ca dex
04eb : ca dex
04ec : ca dex
04ed : ca dex
04ee : ca dex
04ef : ca dex
04f0 : ca dex
04f1 : ca dex
04f2 : ca dex
04f3 : ca dex ;-20
04f4 : ca dex
04f5 : ca dex
04f6 : ca dex
04f7 : ca dex
04f8 : ca dex
04f9 : ca dex
04fa : ca dex
04fb : ca dex
04fc : ca dex
04fd : ca dex ;-10
04fe : ca dex
04ff : ca dex
0500 : ca dex
0501 : ca dex
0502 : ca dex
0503 : ca dex
0504 : ca dex ;-3
0505 : range_op ;test target with zero flag=0, z=1 if previous dex
0506 = range_adr = *+1 ;modifiable relative address
0505 : f03e beq *+64 ;+64 if called without modification
0507 : ca dex ;+0
0508 : ca dex
0509 : ca dex
050a : ca dex
050b : ca dex
050c : ca dex
050d : ca dex
050e : ca dex
050f : ca dex
0510 : ca dex
0511 : ca dex ;+10
0512 : ca dex
0513 : ca dex
0514 : ca dex
0515 : ca dex
0516 : ca dex
0517 : ca dex
0518 : ca dex
0519 : ca dex
051a : ca dex
051b : ca dex ;+20
051c : ca dex
051d : ca dex
051e : ca dex
051f : ca dex
0520 : ca dex
0521 : ca dex
0522 : ca dex
0523 : ca dex
0524 : ca dex
0525 : ca dex ;+30
0526 : ca dex
0527 : ca dex
0528 : ca dex
0529 : ca dex
052a : ca dex
052b : ca dex
052c : ca dex
052d : ca dex
052e : ca dex
052f : ca dex ;+40
0530 : ca dex
0531 : ca dex
0532 : ca dex
0533 : ca dex
0534 : ca dex
0535 : ca dex
0536 : ca dex
0537 : ca dex
0538 : ca dex
0539 : ca dex ;+50
053a : ca dex
053b : ca dex
053c : ca dex
053d : ca dex
053e : ca dex
053f : ca dex
0540 : ca dex
0541 : ca dex
0542 : ca dex
0543 : ca dex ;+60
0544 : ca dex
0545 : ca dex
0546 : ca dex
0547 : ca dex
0548 : ca dex
0549 : ca dex
054a : ca dex
054b : ca dex
054c : ca dex
054d : ca dex ;+70
054e : ca dex
054f : ca dex
0550 : ca dex
0551 : ca dex
0552 : ca dex
0553 : ca dex
0554 : ca dex
0555 : ca dex
0556 : ca dex
0557 : ca dex ;+80
0558 : ca dex
0559 : ca dex
055a : ca dex
055b : ca dex
055c : ca dex
055d : ca dex
055e : ca dex
055f : ca dex
0560 : ca dex
0561 : ca dex ;+90
0562 : ca dex
0563 : ca dex
0564 : ca dex
0565 : ca dex
0566 : ca dex
0567 : ca dex
0568 : ca dex
0569 : ca dex
056a : ca dex
056b : ca dex ;+100
056c : ca dex
056d : ca dex
056e : ca dex
056f : ca dex
0570 : ca dex
0571 : ca dex
0572 : ca dex
0573 : ca dex
0574 : ca dex
0575 : ca dex ;+110
0576 : ca dex
0577 : ca dex
0578 : ca dex
0579 : ca dex
057a : ca dex
057b : ca dex
057c : ca dex
057d : ca dex
057e : ca dex
057f : ca dex ;+120
0580 : ca dex
0581 : ca dex
0582 : ca dex
0583 : ca dex
0584 : ca dex
0585 : ca dex
0586 : ea nop ;offset landing zone - forward branch too far
0587 : ea nop
0588 : ea nop
0589 : ea nop
058a : ea nop
058b : f008 beq range_ok ;+127 - max forward
trap ; bad range
058d : 4c8d05 > jmp * ;failed anyway
0590 : ea nop ;offset landing zone - tolerate +/-5 offset to branch
0591 : ea nop
0592 : ea nop
0593 : ea nop
0594 : ea nop
0595 : range_ok
0595 : ea nop
0596 : ea nop
0597 : ea nop
0598 : ea nop
0599 : ea nop
059a : c000 cpy #0
059c : f003 beq range_end
059e : 4c6604 jmp range_loop
05a1 : range_end ;range test successful
endif
next_test
05a1 : ad0002 > lda test_case ;previous test
05a4 : c901 > cmp #test_num
> trap_ne ;test is out of sequence
05a6 : d0fe > bne * ;failed not equal (non zero)
>
0002 = >test_num = test_num + 1
05a8 : a902 > lda #test_num ;*** next tests' number
05aa : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
;partial test BNE & CMP, CPX, CPY immediate
05ad : c001 cpy #1 ;testing BNE true
05af : d003 bne test_bne
trap
05b1 : 4cb105 > jmp * ;failed anyway
05b4 : test_bne
05b4 : a900 lda #0
05b6 : c900 cmp #0 ;test compare immediate
trap_ne
05b8 : d0fe > bne * ;failed not equal (non zero)
trap_cc
05ba : 90fe > bcc * ;failed carry clear
trap_mi
05bc : 30fe > bmi * ;failed minus (bit 7 set)
05be : c901 cmp #1
trap_eq
05c0 : f0fe > beq * ;failed equal (zero)
trap_cs
05c2 : b0fe > bcs * ;failed carry set
trap_pl
05c4 : 10fe > bpl * ;failed plus (bit 7 clear)
05c6 : aa tax
05c7 : e000 cpx #0 ;test compare x immediate
trap_ne
05c9 : d0fe > bne * ;failed not equal (non zero)
trap_cc
05cb : 90fe > bcc * ;failed carry clear
trap_mi
05cd : 30fe > bmi * ;failed minus (bit 7 set)
05cf : e001 cpx #1
trap_eq
05d1 : f0fe > beq * ;failed equal (zero)
trap_cs
05d3 : b0fe > bcs * ;failed carry set
trap_pl
05d5 : 10fe > bpl * ;failed plus (bit 7 clear)
05d7 : a8 tay
05d8 : c000 cpy #0 ;test compare y immediate
trap_ne
05da : d0fe > bne * ;failed not equal (non zero)
trap_cc
05dc : 90fe > bcc * ;failed carry clear
trap_mi
05de : 30fe > bmi * ;failed minus (bit 7 set)
05e0 : c001 cpy #1
trap_eq
05e2 : f0fe > beq * ;failed equal (zero)
trap_cs
05e4 : b0fe > bcs * ;failed carry set
trap_pl
05e6 : 10fe > bpl * ;failed plus (bit 7 clear)
next_test
05e8 : ad0002 > lda test_case ;previous test
05eb : c902 > cmp #test_num
> trap_ne ;test is out of sequence
05ed : d0fe > bne * ;failed not equal (non zero)
>
0003 = >test_num = test_num + 1
05ef : a903 > lda #test_num ;*** next tests' number
05f1 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
;testing stack operations PHA PHP PLA PLP
05f4 : a2ff ldx #$ff ;initialize stack
05f6 : 9a txs
05f7 : a955 lda #$55
05f9 : 48 pha
05fa : a9aa lda #$aa
05fc : 48 pha
05fd : cdfe01 cmp $1fe ;on stack ?
trap_ne
0600 : d0fe > bne * ;failed not equal (non zero)
0602 : ba tsx
0603 : 8a txa ;overwrite accu
0604 : c9fd cmp #$fd ;sp decremented?
trap_ne
0606 : d0fe > bne * ;failed not equal (non zero)
0608 : 68 pla
0609 : c9aa cmp #$aa ;successful retreived from stack?
trap_ne
060b : d0fe > bne * ;failed not equal (non zero)
060d : 68 pla
060e : c955 cmp #$55
trap_ne
0610 : d0fe > bne * ;failed not equal (non zero)
0612 : cdff01 cmp $1ff ;remains on stack?
trap_ne
0615 : d0fe > bne * ;failed not equal (non zero)
0617 : ba tsx
0618 : e0ff cpx #$ff ;sp incremented?
trap_ne
061a : d0fe > bne * ;failed not equal (non zero)
next_test
061c : ad0002 > lda test_case ;previous test
061f : c903 > cmp #test_num
> trap_ne ;test is out of sequence
0621 : d0fe > bne * ;failed not equal (non zero)
>
0004 = >test_num = test_num + 1
0623 : a904 > lda #test_num ;*** next tests' number
0625 : 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
0628 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
062a : 48 > pha ;use stack to load status
062b : 28 > plp
062c : 101a bpl nbr1 ;branches should not be taken
062e : 501b bvc nbr2
0630 : 901c bcc nbr3
0632 : d01d bne nbr4
0634 : 3003 bmi br1 ;branches should be taken
trap
0636 : 4c3606 > jmp * ;failed anyway
0639 : 7003 br1 bvs br2
trap
063b : 4c3b06 > jmp * ;failed anyway
063e : b003 br2 bcs br3
trap
0640 : 4c4006 > jmp * ;failed anyway
0643 : f00f br3 beq br4
trap
0645 : 4c4506 > jmp * ;failed anyway
0648 : nbr1
trap ;previous bpl taken
0648 : 4c4806 > jmp * ;failed anyway
064b : nbr2
trap ;previous bvc taken
064b : 4c4b06 > jmp * ;failed anyway
064e : nbr3
trap ;previous bcc taken
064e : 4c4e06 > jmp * ;failed anyway
0651 : nbr4
trap ;previous bne taken
0651 : 4c5106 > jmp * ;failed anyway
0654 : 08 br4 php
0655 : ba tsx
0656 : e0fe cpx #$fe ;sp after php?
trap_ne
0658 : d0fe > bne * ;failed not equal (non zero)
065a : 68 pla
cmp_flag $ff ;returned all flags on?
065b : c9ff > cmp #($ff |fao)&m8 ;expected flags + always on bits
trap_ne
065d : d0fe > bne * ;failed not equal (non zero)
065f : ba tsx
0660 : e0ff cpx #$ff ;sp after php?
trap_ne
0662 : d0fe > bne * ;failed not equal (non zero)
set_stat 0 ;all off
> load_flag 0
0664 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0666 : 48 > pha ;use stack to load status
0667 : 28 > plp
0668 : 301a bmi nbr11 ;branches should not be taken
066a : 701b bvs nbr12
066c : b01c bcs nbr13
066e : f01d beq nbr14
0670 : 1003 bpl br11 ;branches should be taken
trap
0672 : 4c7206 > jmp * ;failed anyway
0675 : 5003 br11 bvc br12
trap
0677 : 4c7706 > jmp * ;failed anyway
067a : 9003 br12 bcc br13
trap
067c : 4c7c06 > jmp * ;failed anyway
067f : d00f br13 bne br14
trap
0681 : 4c8106 > jmp * ;failed anyway
0684 : nbr11
trap ;previous bmi taken
0684 : 4c8406 > jmp * ;failed anyway
0687 : nbr12
trap ;previous bvs taken
0687 : 4c8706 > jmp * ;failed anyway
068a : nbr13
trap ;previous bcs taken
068a : 4c8a06 > jmp * ;failed anyway
068d : nbr14
trap ;previous beq taken
068d : 4c8d06 > jmp * ;failed anyway
0690 : 08 br14 php
0691 : 68 pla
cmp_flag 0 ;flags off except break (pushed by sw) + reserved?
0692 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits
trap_ne
0694 : d0fe > bne * ;failed not equal (non zero)
;crosscheck flags
set_stat zero
> load_flag zero
0696 : a902 > lda #zero ;allow test to change I-flag (no mask)
>
0698 : 48 > pha ;use stack to load status
0699 : 28 > plp
069a : d002 bne brzs1
069c : f003 beq brzs2
069e : brzs1
trap ;branch zero/non zero
069e : 4c9e06 > jmp * ;failed anyway
06a1 : b002 brzs2 bcs brzs3
06a3 : 9003 bcc brzs4
06a5 : brzs3
trap ;branch carry/no carry
06a5 : 4ca506 > jmp * ;failed anyway
06a8 : 3002 brzs4 bmi brzs5
06aa : 1003 bpl brzs6
06ac : brzs5
trap ;branch minus/plus
06ac : 4cac06 > jmp * ;failed anyway
06af : 7002 brzs6 bvs brzs7
06b1 : 5003 bvc brzs8
06b3 : brzs7
trap ;branch overflow/no overflow
06b3 : 4cb306 > jmp * ;failed anyway
06b6 : brzs8
set_stat carry
> load_flag carry
06b6 : a901 > lda #carry ;allow test to change I-flag (no mask)
>
06b8 : 48 > pha ;use stack to load status
06b9 : 28 > plp
06ba : f002 beq brcs1
06bc : d003 bne brcs2
06be : brcs1
trap ;branch zero/non zero
06be : 4cbe06 > jmp * ;failed anyway
06c1 : 9002 brcs2 bcc brcs3
06c3 : b003 bcs brcs4
06c5 : brcs3
trap ;branch carry/no carry
06c5 : 4cc506 > jmp * ;failed anyway
06c8 : 3002 brcs4 bmi brcs5
06ca : 1003 bpl brcs6
06cc : brcs5
trap ;branch minus/plus
06cc : 4ccc06 > jmp * ;failed anyway
06cf : 7002 brcs6 bvs brcs7
06d1 : 5003 bvc brcs8
06d3 : brcs7
trap ;branch overflow/no overflow
06d3 : 4cd306 > jmp * ;failed anyway
06d6 : brcs8
set_stat minus
> load_flag minus
06d6 : a980 > lda #minus ;allow test to change I-flag (no mask)
>
06d8 : 48 > pha ;use stack to load status
06d9 : 28 > plp
06da : f002 beq brmi1
06dc : d003 bne brmi2
06de : brmi1
trap ;branch zero/non zero
06de : 4cde06 > jmp * ;failed anyway
06e1 : b002 brmi2 bcs brmi3
06e3 : 9003 bcc brmi4
06e5 : brmi3
trap ;branch carry/no carry
06e5 : 4ce506 > jmp * ;failed anyway
06e8 : 1002 brmi4 bpl brmi5
06ea : 3003 bmi brmi6
06ec : brmi5
trap ;branch minus/plus
06ec : 4cec06 > jmp * ;failed anyway
06ef : 7002 brmi6 bvs brmi7
06f1 : 5003 bvc brmi8
06f3 : brmi7
trap ;branch overflow/no overflow
06f3 : 4cf306 > jmp * ;failed anyway
06f6 : brmi8
set_stat overfl
> load_flag overfl
06f6 : a940 > lda #overfl ;allow test to change I-flag (no mask)
>
06f8 : 48 > pha ;use stack to load status
06f9 : 28 > plp
06fa : f002 beq brvs1
06fc : d003 bne brvs2
06fe : brvs1
trap ;branch zero/non zero
06fe : 4cfe06 > jmp * ;failed anyway
0701 : b002 brvs2 bcs brvs3
0703 : 9003 bcc brvs4
0705 : brvs3
trap ;branch carry/no carry
0705 : 4c0507 > jmp * ;failed anyway
0708 : 3002 brvs4 bmi brvs5
070a : 1003 bpl brvs6
070c : brvs5
trap ;branch minus/plus
070c : 4c0c07 > jmp * ;failed anyway
070f : 5002 brvs6 bvc brvs7
0711 : 7003 bvs brvs8
0713 : brvs7
trap ;branch overflow/no overflow
0713 : 4c1307 > jmp * ;failed anyway
0716 : brvs8
set_stat $ff-zero
> load_flag $ff-zero
0716 : a9fd > lda #$ff-zero ;allow test to change I-flag (no mask)
>
0718 : 48 > pha ;use stack to load status
0719 : 28 > plp
071a : f002 beq brzc1
071c : d003 bne brzc2
071e : brzc1
trap ;branch zero/non zero
071e : 4c1e07 > jmp * ;failed anyway
0721 : 9002 brzc2 bcc brzc3
0723 : b003 bcs brzc4
0725 : brzc3
trap ;branch carry/no carry
0725 : 4c2507 > jmp * ;failed anyway
0728 : 1002 brzc4 bpl brzc5
072a : 3003 bmi brzc6
072c : brzc5
trap ;branch minus/plus
072c : 4c2c07 > jmp * ;failed anyway
072f : 5002 brzc6 bvc brzc7
0731 : 7003 bvs brzc8
0733 : brzc7
trap ;branch overflow/no overflow
0733 : 4c3307 > jmp * ;failed anyway
0736 : brzc8
set_stat $ff-carry
> load_flag $ff-carry
0736 : a9fe > lda #$ff-carry ;allow test to change I-flag (no mask)
>
0738 : 48 > pha ;use stack to load status
0739 : 28 > plp
073a : d002 bne brcc1
073c : f003 beq brcc2
073e : brcc1
trap ;branch zero/non zero
073e : 4c3e07 > jmp * ;failed anyway
0741 : b002 brcc2 bcs brcc3
0743 : 9003 bcc brcc4
0745 : brcc3
trap ;branch carry/no carry
0745 : 4c4507 > jmp * ;failed anyway
0748 : 1002 brcc4 bpl brcc5
074a : 3003 bmi brcc6
074c : brcc5
trap ;branch minus/plus
074c : 4c4c07 > jmp * ;failed anyway
074f : 5002 brcc6 bvc brcc7
0751 : 7003 bvs brcc8
0753 : brcc7
trap ;branch overflow/no overflow
0753 : 4c5307 > jmp * ;failed anyway
0756 : brcc8
set_stat $ff-minus
> load_flag $ff-minus
0756 : a97f > lda #$ff-minus ;allow test to change I-flag (no mask)
>
0758 : 48 > pha ;use stack to load status
0759 : 28 > plp
075a : d002 bne brpl1
075c : f003 beq brpl2
075e : brpl1
trap ;branch zero/non zero
075e : 4c5e07 > jmp * ;failed anyway
0761 : 9002 brpl2 bcc brpl3
0763 : b003 bcs brpl4
0765 : brpl3
trap ;branch carry/no carry
0765 : 4c6507 > jmp * ;failed anyway
0768 : 3002 brpl4 bmi brpl5
076a : 1003 bpl brpl6
076c : brpl5
trap ;branch minus/plus
076c : 4c6c07 > jmp * ;failed anyway
076f : 5002 brpl6 bvc brpl7
0771 : 7003 bvs brpl8
0773 : brpl7
trap ;branch overflow/no overflow
0773 : 4c7307 > jmp * ;failed anyway
0776 : brpl8
set_stat $ff-overfl
> load_flag $ff-overfl
0776 : a9bf > lda #$ff-overfl ;allow test to change I-flag (no mask)
>
0778 : 48 > pha ;use stack to load status
0779 : 28 > plp
077a : d002 bne brvc1
077c : f003 beq brvc2
077e : brvc1
trap ;branch zero/non zero
077e : 4c7e07 > jmp * ;failed anyway
0781 : 9002 brvc2 bcc brvc3
0783 : b003 bcs brvc4
0785 : brvc3
trap ;branch carry/no carry
0785 : 4c8507 > jmp * ;failed anyway
0788 : 1002 brvc4 bpl brvc5
078a : 3003 bmi brvc6
078c : brvc5
trap ;branch minus/plus
078c : 4c8c07 > jmp * ;failed anyway
078f : 7002 brvc6 bvs brvc7
0791 : 5003 bvc brvc8
0793 : brvc7
trap ;branch overflow/no overflow
0793 : 4c9307 > jmp * ;failed anyway
0796 : brvc8
next_test
0796 : ad0002 > lda test_case ;previous test
0799 : c904 > cmp #test_num
> trap_ne ;test is out of sequence
079b : d0fe > bne * ;failed not equal (non zero)
>
0005 = >test_num = test_num + 1
079d : a905 > lda #test_num ;*** next tests' number
079f : 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
07a2 : a255 ldx #$55 ;x & y protected
07a4 : a0aa ldy #$aa
set_a 1,$ff ;push
> load_flag $ff
07a6 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
07a8 : 48 > pha ;use stack to load status
07a9 : a901 > lda #1 ;precharge accu
07ab : 28 > plp
07ac : 48 pha
tst_a 1,$ff
07ad : 08 > php ;save flags
07ae : c901 > cmp #1 ;test result
> trap_ne
07b0 : d0fe > bne * ;failed not equal (non zero)
>
07b2 : 68 > pla ;load status
07b3 : 48 > pha
> cmp_flag $ff
07b4 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
07b6 : d0fe > bne * ;failed not equal (non zero)
>
07b8 : 28 > plp ;restore status
set_a 0,0
> load_flag 0
07b9 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
07bb : 48 > pha ;use stack to load status
07bc : a900 > lda #0 ;precharge accu
07be : 28 > plp
07bf : 48 pha
tst_a 0,0
07c0 : 08 > php ;save flags
07c1 : c900 > cmp #0 ;test result
> trap_ne
07c3 : d0fe > bne * ;failed not equal (non zero)
>
07c5 : 68 > pla ;load status
07c6 : 48 > pha
> cmp_flag 0
07c7 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
07c9 : d0fe > bne * ;failed not equal (non zero)
>
07cb : 28 > plp ;restore status
set_a $ff,$ff
> load_flag $ff
07cc : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
07ce : 48 > pha ;use stack to load status
07cf : a9ff > lda #$ff ;precharge accu
07d1 : 28 > plp
07d2 : 48 pha
tst_a $ff,$ff
07d3 : 08 > php ;save flags
07d4 : c9ff > cmp #$ff ;test result
> trap_ne
07d6 : d0fe > bne * ;failed not equal (non zero)
>
07d8 : 68 > pla ;load status
07d9 : 48 > pha
> cmp_flag $ff
07da : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
07dc : d0fe > bne * ;failed not equal (non zero)
>
07de : 28 > plp ;restore status
set_a 1,0
> load_flag 0
07df : a900 > lda #0 ;allow test to change I-flag (no mask)
>
07e1 : 48 > pha ;use stack to load status
07e2 : a901 > lda #1 ;precharge accu
07e4 : 28 > plp
07e5 : 48 pha
tst_a 1,0
07e6 : 08 > php ;save flags
07e7 : c901 > cmp #1 ;test result
> trap_ne
07e9 : d0fe > bne * ;failed not equal (non zero)
>
07eb : 68 > pla ;load status
07ec : 48 > pha
> cmp_flag 0
07ed : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
07ef : d0fe > bne * ;failed not equal (non zero)
>
07f1 : 28 > plp ;restore status
set_a 0,$ff
> load_flag $ff
07f2 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
07f4 : 48 > pha ;use stack to load status
07f5 : a900 > lda #0 ;precharge accu
07f7 : 28 > plp
07f8 : 48 pha
tst_a 0,$ff
07f9 : 08 > php ;save flags
07fa : c900 > cmp #0 ;test result
> trap_ne
07fc : d0fe > bne * ;failed not equal (non zero)
>
07fe : 68 > pla ;load status
07ff : 48 > pha
> cmp_flag $ff
0800 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0802 : d0fe > bne * ;failed not equal (non zero)
>
0804 : 28 > plp ;restore status
set_a $ff,0
> load_flag 0
0805 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0807 : 48 > pha ;use stack to load status
0808 : a9ff > lda #$ff ;precharge accu
080a : 28 > plp
080b : 48 pha
tst_a $ff,0
080c : 08 > php ;save flags
080d : c9ff > cmp #$ff ;test result
> trap_ne
080f : d0fe > bne * ;failed not equal (non zero)
>
0811 : 68 > pla ;load status
0812 : 48 > pha
> cmp_flag 0
0813 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0815 : d0fe > bne * ;failed not equal (non zero)
>
0817 : 28 > plp ;restore status
set_a 0,$ff ;pull
> load_flag $ff
0818 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
081a : 48 > pha ;use stack to load status
081b : a900 > lda #0 ;precharge accu
081d : 28 > plp
081e : 68 pla
tst_a $ff,$ff-zero
081f : 08 > php ;save flags
0820 : c9ff > cmp #$ff ;test result
> trap_ne
0822 : d0fe > bne * ;failed not equal (non zero)
>
0824 : 68 > pla ;load status
0825 : 48 > pha
> cmp_flag $ff-zero
0826 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0828 : d0fe > bne * ;failed not equal (non zero)
>
082a : 28 > plp ;restore status
set_a $ff,0
> load_flag 0
082b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
082d : 48 > pha ;use stack to load status
082e : a9ff > lda #$ff ;precharge accu
0830 : 28 > plp
0831 : 68 pla
tst_a 0,zero
0832 : 08 > php ;save flags
0833 : c900 > cmp #0 ;test result
> trap_ne
0835 : d0fe > bne * ;failed not equal (non zero)
>
0837 : 68 > pla ;load status
0838 : 48 > pha
> cmp_flag zero
0839 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
083b : d0fe > bne * ;failed not equal (non zero)
>
083d : 28 > plp ;restore status
set_a $fe,$ff
> load_flag $ff
083e : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0840 : 48 > pha ;use stack to load status
0841 : a9fe > lda #$fe ;precharge accu
0843 : 28 > plp
0844 : 68 pla
tst_a 1,$ff-zero-minus
0845 : 08 > php ;save flags
0846 : c901 > cmp #1 ;test result
> trap_ne
0848 : d0fe > bne * ;failed not equal (non zero)
>
084a : 68 > pla ;load status
084b : 48 > pha
> cmp_flag $ff-zero-minus
084c : c97d > cmp #($ff-zero-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
084e : d0fe > bne * ;failed not equal (non zero)
>
0850 : 28 > plp ;restore status
set_a 0,0
> load_flag 0
0851 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0853 : 48 > pha ;use stack to load status
0854 : a900 > lda #0 ;precharge accu
0856 : 28 > plp
0857 : 68 pla
tst_a $ff,minus
0858 : 08 > php ;save flags
0859 : c9ff > cmp #$ff ;test result
> trap_ne
085b : d0fe > bne * ;failed not equal (non zero)
>
085d : 68 > pla ;load status
085e : 48 > pha
> cmp_flag minus
085f : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0861 : d0fe > bne * ;failed not equal (non zero)
>
0863 : 28 > plp ;restore status
set_a $ff,$ff
> load_flag $ff
0864 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0866 : 48 > pha ;use stack to load status
0867 : a9ff > lda #$ff ;precharge accu
0869 : 28 > plp
086a : 68 pla
tst_a 0,$ff-minus
086b : 08 > php ;save flags
086c : c900 > cmp #0 ;test result
> trap_ne
086e : d0fe > bne * ;failed not equal (non zero)
>
0870 : 68 > pla ;load status
0871 : 48 > pha
> cmp_flag $ff-minus
0872 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0874 : d0fe > bne * ;failed not equal (non zero)
>
0876 : 28 > plp ;restore status
set_a $fe,0
> load_flag 0
0877 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0879 : 48 > pha ;use stack to load status
087a : a9fe > lda #$fe ;precharge accu
087c : 28 > plp
087d : 68 pla
tst_a 1,0
087e : 08 > php ;save flags
087f : c901 > cmp #1 ;test result
> trap_ne
0881 : d0fe > bne * ;failed not equal (non zero)
>
0883 : 68 > pla ;load status
0884 : 48 > pha
> cmp_flag 0
0885 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0887 : d0fe > bne * ;failed not equal (non zero)
>
0889 : 28 > plp ;restore status
088a : e055 cpx #$55 ;x & y unchanged?
trap_ne
088c : d0fe > bne * ;failed not equal (non zero)
088e : c0aa cpy #$aa
trap_ne
0890 : d0fe > bne * ;failed not equal (non zero)
next_test
0892 : ad0002 > lda test_case ;previous test
0895 : c905 > cmp #test_num
> trap_ne ;test is out of sequence
0897 : d0fe > bne * ;failed not equal (non zero)
>
0006 = >test_num = test_num + 1
0899 : a906 > lda #test_num ;*** next tests' number
089b : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; partial pretest EOR #
set_a $3c,0
> load_flag 0
089e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
08a0 : 48 > pha ;use stack to load status
08a1 : a93c > lda #$3c ;precharge accu
08a3 : 28 > plp
08a4 : 49c3 eor #$c3
tst_a $ff,fn
08a6 : 08 > php ;save flags
08a7 : c9ff > cmp #$ff ;test result
> trap_ne
08a9 : d0fe > bne * ;failed not equal (non zero)
>
08ab : 68 > pla ;load status
08ac : 48 > pha
> cmp_flag fn
08ad : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
08af : d0fe > bne * ;failed not equal (non zero)
>
08b1 : 28 > plp ;restore status
set_a $c3,0
> load_flag 0
08b2 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
08b4 : 48 > pha ;use stack to load status
08b5 : a9c3 > lda #$c3 ;precharge accu
08b7 : 28 > plp
08b8 : 49c3 eor #$c3
tst_a 0,fz
08ba : 08 > php ;save flags
08bb : c900 > cmp #0 ;test result
> trap_ne
08bd : d0fe > bne * ;failed not equal (non zero)
>
08bf : 68 > pla ;load status
08c0 : 48 > pha
> cmp_flag fz
08c1 : c932 > cmp #(fz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
08c3 : d0fe > bne * ;failed not equal (non zero)
>
08c5 : 28 > plp ;restore status
next_test
08c6 : ad0002 > lda test_case ;previous test
08c9 : c906 > cmp #test_num
> trap_ne ;test is out of sequence
08cb : d0fe > bne * ;failed not equal (non zero)
>
0007 = >test_num = test_num + 1
08cd : a907 > lda #test_num ;*** next tests' number
08cf : 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
08d2 : a224 ldx #$24
08d4 : a042 ldy #$42
set_a $18,0
> load_flag 0
08d6 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
08d8 : 48 > pha ;use stack to load status
08d9 : a918 > lda #$18 ;precharge accu
08db : 28 > plp
08dc : ea nop
tst_a $18,0
08dd : 08 > php ;save flags
08de : c918 > cmp #$18 ;test result
> trap_ne
08e0 : d0fe > bne * ;failed not equal (non zero)
>
08e2 : 68 > pla ;load status
08e3 : 48 > pha
> cmp_flag 0
08e4 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
08e6 : d0fe > bne * ;failed not equal (non zero)
>
08e8 : 28 > plp ;restore status
08e9 : e024 cpx #$24
trap_ne
08eb : d0fe > bne * ;failed not equal (non zero)
08ed : c042 cpy #$42
trap_ne
08ef : d0fe > bne * ;failed not equal (non zero)
08f1 : a2db ldx #$db
08f3 : a0bd ldy #$bd
set_a $e7,$ff
> load_flag $ff
08f5 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
08f7 : 48 > pha ;use stack to load status
08f8 : a9e7 > lda #$e7 ;precharge accu
08fa : 28 > plp
08fb : ea nop
tst_a $e7,$ff
08fc : 08 > php ;save flags
08fd : c9e7 > cmp #$e7 ;test result
> trap_ne
08ff : d0fe > bne * ;failed not equal (non zero)
>
0901 : 68 > pla ;load status
0902 : 48 > pha
> cmp_flag $ff
0903 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0905 : d0fe > bne * ;failed not equal (non zero)
>
0907 : 28 > plp ;restore status
0908 : e0db cpx #$db
trap_ne
090a : d0fe > bne * ;failed not equal (non zero)
090c : c0bd cpy #$bd
trap_ne
090e : d0fe > bne * ;failed not equal (non zero)
next_test
0910 : ad0002 > lda test_case ;previous test
0913 : c907 > cmp #test_num
> trap_ne ;test is out of sequence
0915 : d0fe > bne * ;failed not equal (non zero)
>
0008 = >test_num = test_num + 1
0917 : a908 > lda #test_num ;*** next tests' number
0919 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; jump absolute
set_stat $0
> load_flag $0
091c : a900 > lda #$0 ;allow test to change I-flag (no mask)
>
091e : 48 > pha ;use stack to load status
091f : 28 > plp
0920 : a946 lda #'F'
0922 : a241 ldx #'A'
0924 : a052 ldy #'R' ;N=0, V=0, Z=0, C=0
0926 : 4ce936 jmp test_far
0929 : ea nop
092a : ea nop
trap_ne ;runover protection
092b : d0fe > bne * ;failed not equal (non zero)
092d : e8 inx
092e : e8 inx
092f : far_ret
trap_eq ;returned flags OK?
092f : f0fe > beq * ;failed equal (zero)
trap_pl
0931 : 10fe > bpl * ;failed plus (bit 7 clear)
trap_cc
0933 : 90fe > bcc * ;failed carry clear
trap_vc
0935 : 50fe > bvc * ;failed overflow clear
0937 : c9ec cmp #('F'^$aa) ;returned registers OK?
trap_ne
0939 : d0fe > bne * ;failed not equal (non zero)
093b : e042 cpx #('A'+1)
trap_ne
093d : d0fe > bne * ;failed not equal (non zero)
093f : c04f cpy #('R'-3)
trap_ne
0941 : d0fe > bne * ;failed not equal (non zero)
0943 : ca dex
0944 : c8 iny
0945 : c8 iny
0946 : c8 iny
0947 : 49aa eor #$aa ;N=0, V=1, Z=0, C=1
0949 : 4c5209 jmp test_near
094c : ea nop
094d : ea nop
trap_ne ;runover protection
094e : d0fe > bne * ;failed not equal (non zero)
0950 : e8 inx
0951 : e8 inx
0952 : test_near
trap_eq ;passed flags OK?
0952 : f0fe > beq * ;failed equal (zero)
trap_mi
0954 : 30fe > bmi * ;failed minus (bit 7 set)
trap_cc
0956 : 90fe > bcc * ;failed carry clear
trap_vc
0958 : 50fe > bvc * ;failed overflow clear
095a : c946 cmp #'F' ;passed registers OK?
trap_ne
095c : d0fe > bne * ;failed not equal (non zero)
095e : e041 cpx #'A'
trap_ne
0960 : d0fe > bne * ;failed not equal (non zero)
0962 : c052 cpy #'R'
trap_ne
0964 : d0fe > bne * ;failed not equal (non zero)
next_test
0966 : ad0002 > lda test_case ;previous test
0969 : c908 > cmp #test_num
> trap_ne ;test is out of sequence
096b : d0fe > bne * ;failed not equal (non zero)
>
0009 = >test_num = test_num + 1
096d : a909 > lda #test_num ;*** next tests' number
096f : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; jump indirect
set_stat 0
> load_flag 0
0972 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0974 : 48 > pha ;use stack to load status
0975 : 28 > plp
0976 : a949 lda #'I'
0978 : a24e ldx #'N'
097a : a044 ldy #'D' ;N=0, V=0, Z=0, C=0
097c : 6c1837 jmp (ptr_tst_ind)
097f : ea nop
trap_ne ;runover protection
0980 : d0fe > bne * ;failed not equal (non zero)
0982 : 88 dey
0983 : 88 dey
0984 : ind_ret
0984 : 08 php ;either SP or Y count will fail, if we do not hit
0985 : 88 dey
0986 : 88 dey
0987 : 88 dey
0988 : 28 plp
trap_eq ;returned flags OK?
0989 : f0fe > beq * ;failed equal (zero)
trap_pl
098b : 10fe > bpl * ;failed plus (bit 7 clear)
trap_cc
098d : 90fe > bcc * ;failed carry clear
trap_vc
098f : 50fe > bvc * ;failed overflow clear
0991 : c9e3 cmp #('I'^$aa) ;returned registers OK?
trap_ne
0993 : d0fe > bne * ;failed not equal (non zero)
0995 : e04f cpx #('N'+1)
trap_ne
0997 : d0fe > bne * ;failed not equal (non zero)
0999 : c03e cpy #('D'-6)
trap_ne
099b : d0fe > bne * ;failed not equal (non zero)
099d : ba tsx ;SP check
099e : e0ff cpx #$ff
trap_ne
09a0 : d0fe > bne * ;failed not equal (non zero)
next_test
09a2 : ad0002 > lda test_case ;previous test
09a5 : c909 > cmp #test_num
> trap_ne ;test is out of sequence
09a7 : d0fe > bne * ;failed not equal (non zero)
>
000a = >test_num = test_num + 1
09a9 : a90a > lda #test_num ;*** next tests' number
09ab : 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
09ae : a900 > lda #0 ;allow test to change I-flag (no mask)
>
09b0 : 48 > pha ;use stack to load status
09b1 : 28 > plp
09b2 : a94a lda #'J'
09b4 : a253 ldx #'S'
09b6 : a052 ldy #'R' ;N=0, V=0, Z=0, C=0
09b8 : 205437 jsr test_jsr
09ba = jsr_ret = *-1 ;last address of jsr = return address
09bb : 08 php ;either SP or Y count will fail, if we do not hit
09bc : 88 dey
09bd : 88 dey
09be : 88 dey
09bf : 28 plp
trap_eq ;returned flags OK?
09c0 : f0fe > beq * ;failed equal (zero)
trap_pl
09c2 : 10fe > bpl * ;failed plus (bit 7 clear)
trap_cc
09c4 : 90fe > bcc * ;failed carry clear
trap_vc
09c6 : 50fe > bvc * ;failed overflow clear
09c8 : c9e0 cmp #('J'^$aa) ;returned registers OK?
trap_ne
09ca : d0fe > bne * ;failed not equal (non zero)
09cc : e054 cpx #('S'+1)
trap_ne
09ce : d0fe > bne * ;failed not equal (non zero)
09d0 : c04c cpy #('R'-6)
trap_ne
09d2 : d0fe > bne * ;failed not equal (non zero)
09d4 : ba tsx ;sp?
09d5 : e0ff cpx #$ff
trap_ne
09d7 : d0fe > bne * ;failed not equal (non zero)
next_test
09d9 : ad0002 > lda test_case ;previous test
09dc : c90a > cmp #test_num
> trap_ne ;test is out of sequence
09de : d0fe > bne * ;failed not equal (non zero)
>
000b = >test_num = test_num + 1
09e0 : a90b > lda #test_num ;*** next tests' number
09e2 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; break & return from interrupt
if ROM_vectors = 1
set_stat 0
> load_flag 0
09e5 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
09e7 : 48 > pha ;use stack to load status
09e8 : 28 > plp
09e9 : a942 lda #'B'
09eb : a252 ldx #'R'
09ed : a04b ldy #'K' ;N=0, V=0, Z=0, C=0
09ef : 00 brk
else
lda #hi brk_ret ;emulated break
pha
lda #lo brk_ret
pha
lda #fao ;set break & unused on stack
pha
set_stat intdis
lda #'B'
ldx #'R'
ldy #'K' ;N=0, V=0, Z=0, C=0
jmp irq_trap
endif
09f0 : 88 dey ;should not be executed
09f1 : brk_ret ;address of break return
09f1 : 08 php ;either SP or Y count will fail, if we do not hit
09f2 : 88 dey
09f3 : 88 dey
09f4 : 88 dey
09f5 : c9e8 cmp #('B'^$aa) ;returned registers OK?
trap_ne
09f7 : d0fe > bne * ;failed not equal (non zero)
09f9 : e053 cpx #('R'+1)
trap_ne
09fb : d0fe > bne * ;failed not equal (non zero)
09fd : c045 cpy #('K'-6)
trap_ne
09ff : d0fe > bne * ;failed not equal (non zero)
0a01 : 68 pla ;returned flags OK (unchanged)?
cmp_flag 0
0a02 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
trap_ne
0a04 : d0fe > bne * ;failed not equal (non zero)
0a06 : ba tsx ;sp?
0a07 : e0ff cpx #$ff
trap_ne
0a09 : d0fe > bne * ;failed not equal (non zero)
next_test
0a0b : ad0002 > lda test_case ;previous test
0a0e : c90b > cmp #test_num
> trap_ne ;test is out of sequence
0a10 : d0fe > bne * ;failed not equal (non zero)
>
000c = >test_num = test_num + 1
0a12 : a90c > lda #test_num ;*** next tests' number
0a14 : 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
0a17 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0a19 : 48 > pha ;use stack to load status
0a1a : 28 > plp
0a1b : 18 clc
tst_stat $ff-carry
0a1c : 08 > php ;save status
0a1d : 68 > pla ;use stack to retrieve status
0a1e : 48 > pha
> cmp_flag $ff-carry
0a1f : c9fe > cmp #($ff-carry|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a21 : d0fe > bne * ;failed not equal (non zero)
>
0a23 : 28 > plp ;restore status
0a24 : 38 sec
tst_stat $ff
0a25 : 08 > php ;save status
0a26 : 68 > pla ;use stack to retrieve status
0a27 : 48 > pha
> cmp_flag $ff
0a28 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a2a : d0fe > bne * ;failed not equal (non zero)
>
0a2c : 28 > plp ;restore status
if I_flag = 3
0a2d : 58 cli
tst_stat $ff-intdis
0a2e : 08 > php ;save status
0a2f : 68 > pla ;use stack to retrieve status
0a30 : 48 > pha
> cmp_flag $ff-intdis
0a31 : c9fb > cmp #($ff-intdis|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a33 : d0fe > bne * ;failed not equal (non zero)
>
0a35 : 28 > plp ;restore status
0a36 : 78 sei
tst_stat $ff
0a37 : 08 > php ;save status
0a38 : 68 > pla ;use stack to retrieve status
0a39 : 48 > pha
> cmp_flag $ff
0a3a : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a3c : d0fe > bne * ;failed not equal (non zero)
>
0a3e : 28 > plp ;restore status
endif
0a3f : d8 cld
tst_stat $ff-decmode
0a40 : 08 > php ;save status
0a41 : 68 > pla ;use stack to retrieve status
0a42 : 48 > pha
> cmp_flag $ff-decmode
0a43 : c9f7 > cmp #($ff-decmode|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a45 : d0fe > bne * ;failed not equal (non zero)
>
0a47 : 28 > plp ;restore status
0a48 : f8 sed
tst_stat $ff
0a49 : 08 > php ;save status
0a4a : 68 > pla ;use stack to retrieve status
0a4b : 48 > pha
> cmp_flag $ff
0a4c : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a4e : d0fe > bne * ;failed not equal (non zero)
>
0a50 : 28 > plp ;restore status
0a51 : b8 clv
tst_stat $ff-overfl
0a52 : 08 > php ;save status
0a53 : 68 > pla ;use stack to retrieve status
0a54 : 48 > pha
> cmp_flag $ff-overfl
0a55 : c9bf > cmp #($ff-overfl|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a57 : d0fe > bne * ;failed not equal (non zero)
>
0a59 : 28 > plp ;restore status
set_stat 0
> load_flag 0
0a5a : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0a5c : 48 > pha ;use stack to load status
0a5d : 28 > plp
tst_stat 0
0a5e : 08 > php ;save status
0a5f : 68 > pla ;use stack to retrieve status
0a60 : 48 > pha
> cmp_flag 0
0a61 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a63 : d0fe > bne * ;failed not equal (non zero)
>
0a65 : 28 > plp ;restore status
0a66 : 38 sec
tst_stat carry
0a67 : 08 > php ;save status
0a68 : 68 > pla ;use stack to retrieve status
0a69 : 48 > pha
> cmp_flag carry
0a6a : c931 > cmp #(carry|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a6c : d0fe > bne * ;failed not equal (non zero)
>
0a6e : 28 > plp ;restore status
0a6f : 18 clc
tst_stat 0
0a70 : 08 > php ;save status
0a71 : 68 > pla ;use stack to retrieve status
0a72 : 48 > pha
> cmp_flag 0
0a73 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a75 : d0fe > bne * ;failed not equal (non zero)
>
0a77 : 28 > plp ;restore status
if I_flag = 3
0a78 : 78 sei
tst_stat intdis
0a79 : 08 > php ;save status
0a7a : 68 > pla ;use stack to retrieve status
0a7b : 48 > pha
> cmp_flag intdis
0a7c : c934 > cmp #(intdis|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a7e : d0fe > bne * ;failed not equal (non zero)
>
0a80 : 28 > plp ;restore status
0a81 : 58 cli
tst_stat 0
0a82 : 08 > php ;save status
0a83 : 68 > pla ;use stack to retrieve 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
endif
0a8a : f8 sed
tst_stat decmode
0a8b : 08 > php ;save status
0a8c : 68 > pla ;use stack to retrieve status
0a8d : 48 > pha
> cmp_flag decmode
0a8e : c938 > cmp #(decmode|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a90 : d0fe > bne * ;failed not equal (non zero)
>
0a92 : 28 > plp ;restore status
0a93 : d8 cld
tst_stat 0
0a94 : 08 > php ;save status
0a95 : 68 > pla ;use stack to retrieve status
0a96 : 48 > pha
> cmp_flag 0
0a97 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits
>
> trap_ne
0a99 : d0fe > bne * ;failed not equal (non zero)
>
0a9b : 28 > plp ;restore status
set_stat overfl
> load_flag overfl
0a9c : a940 > lda #overfl ;allow test to change I-flag (no mask)
>
0a9e : 48 > pha ;use stack to load status
0a9f : 28 > plp
tst_stat overfl
0aa0 : 08 > php ;save status
0aa1 : 68 > pla ;use stack to retrieve status
0aa2 : 48 > pha
> cmp_flag overfl
0aa3 : c970 > cmp #(overfl|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0aa5 : d0fe > bne * ;failed not equal (non zero)
>
0aa7 : 28 > plp ;restore status
0aa8 : b8 clv
tst_stat 0
0aa9 : 08 > php ;save status
0aaa : 68 > pla ;use stack to retrieve status
0aab : 48 > pha
> cmp_flag 0
0aac : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0aae : d0fe > bne * ;failed not equal (non zero)
>
0ab0 : 28 > plp ;restore status
next_test
0ab1 : ad0002 > lda test_case ;previous test
0ab4 : c90c > cmp #test_num
> trap_ne ;test is out of sequence
0ab6 : d0fe > bne * ;failed not equal (non zero)
>
000d = >test_num = test_num + 1
0ab8 : a90d > lda #test_num ;*** next tests' number
0aba : 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
0abd : a2fe ldx #$fe
set_stat $ff
> load_flag $ff
0abf : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0ac1 : 48 > pha ;use stack to load status
0ac2 : 28 > plp
0ac3 : e8 inx ;ff
tst_x $ff,$ff-zero
0ac4 : 08 > php ;save flags
0ac5 : e0ff > cpx #$ff ;test result
> trap_ne
0ac7 : d0fe > bne * ;failed not equal (non zero)
>
0ac9 : 68 > pla ;load status
0aca : 48 > pha
> cmp_flag $ff-zero
0acb : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0acd : d0fe > bne * ;failed not equal (non zero)
>
0acf : 28 > plp ;restore status
0ad0 : e8 inx ;00
tst_x 0,$ff-minus
0ad1 : 08 > php ;save flags
0ad2 : e000 > cpx #0 ;test result
> trap_ne
0ad4 : d0fe > bne * ;failed not equal (non zero)
>
0ad6 : 68 > pla ;load status
0ad7 : 48 > pha
> cmp_flag $ff-minus
0ad8 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0ada : d0fe > bne * ;failed not equal (non zero)
>
0adc : 28 > plp ;restore status
0add : e8 inx ;01
tst_x 1,$ff-minus-zero
0ade : 08 > php ;save flags
0adf : e001 > cpx #1 ;test result
> trap_ne
0ae1 : d0fe > bne * ;failed not equal (non zero)
>
0ae3 : 68 > pla ;load status
0ae4 : 48 > pha
> cmp_flag $ff-minus-zero
0ae5 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0ae7 : d0fe > bne * ;failed not equal (non zero)
>
0ae9 : 28 > plp ;restore status
0aea : ca dex ;00
tst_x 0,$ff-minus
0aeb : 08 > php ;save flags
0aec : e000 > cpx #0 ;test result
> trap_ne
0aee : d0fe > bne * ;failed not equal (non zero)
>
0af0 : 68 > pla ;load status
0af1 : 48 > pha
> cmp_flag $ff-minus
0af2 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0af4 : d0fe > bne * ;failed not equal (non zero)
>
0af6 : 28 > plp ;restore status
0af7 : ca dex ;ff
tst_x $ff,$ff-zero
0af8 : 08 > php ;save flags
0af9 : e0ff > cpx #$ff ;test result
> trap_ne
0afb : d0fe > bne * ;failed not equal (non zero)
>
0afd : 68 > pla ;load status
0afe : 48 > pha
> cmp_flag $ff-zero
0aff : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b01 : d0fe > bne * ;failed not equal (non zero)
>
0b03 : 28 > plp ;restore status
0b04 : ca dex ;fe
set_stat 0
> load_flag 0
0b05 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0b07 : 48 > pha ;use stack to load status
0b08 : 28 > plp
0b09 : e8 inx ;ff
tst_x $ff,minus
0b0a : 08 > php ;save flags
0b0b : e0ff > cpx #$ff ;test result
> trap_ne
0b0d : d0fe > bne * ;failed not equal (non zero)
>
0b0f : 68 > pla ;load status
0b10 : 48 > pha
> cmp_flag minus
0b11 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b13 : d0fe > bne * ;failed not equal (non zero)
>
0b15 : 28 > plp ;restore status
0b16 : e8 inx ;00
tst_x 0,zero
0b17 : 08 > php ;save flags
0b18 : e000 > cpx #0 ;test result
> trap_ne
0b1a : d0fe > bne * ;failed not equal (non zero)
>
0b1c : 68 > pla ;load status
0b1d : 48 > pha
> cmp_flag zero
0b1e : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b20 : d0fe > bne * ;failed not equal (non zero)
>
0b22 : 28 > plp ;restore status
0b23 : e8 inx ;01
tst_x 1,0
0b24 : 08 > php ;save flags
0b25 : e001 > cpx #1 ;test result
> trap_ne
0b27 : d0fe > bne * ;failed not equal (non zero)
>
0b29 : 68 > pla ;load status
0b2a : 48 > pha
> cmp_flag 0
0b2b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b2d : d0fe > bne * ;failed not equal (non zero)
>
0b2f : 28 > plp ;restore status
0b30 : ca dex ;00
tst_x 0,zero
0b31 : 08 > php ;save flags
0b32 : e000 > cpx #0 ;test result
> trap_ne
0b34 : d0fe > bne * ;failed not equal (non zero)
>
0b36 : 68 > pla ;load status
0b37 : 48 > pha
> cmp_flag zero
0b38 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b3a : d0fe > bne * ;failed not equal (non zero)
>
0b3c : 28 > plp ;restore status
0b3d : ca dex ;ff
tst_x $ff,minus
0b3e : 08 > php ;save flags
0b3f : e0ff > cpx #$ff ;test result
> trap_ne
0b41 : d0fe > bne * ;failed not equal (non zero)
>
0b43 : 68 > pla ;load status
0b44 : 48 > pha
> cmp_flag minus
0b45 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b47 : d0fe > bne * ;failed not equal (non zero)
>
0b49 : 28 > plp ;restore status
0b4a : a0fe ldy #$fe
set_stat $ff
> load_flag $ff
0b4c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0b4e : 48 > pha ;use stack to load status
0b4f : 28 > plp
0b50 : c8 iny ;ff
tst_y $ff,$ff-zero
0b51 : 08 > php ;save flags
0b52 : c0ff > cpy #$ff ;test result
> trap_ne
0b54 : d0fe > bne * ;failed not equal (non zero)
>
0b56 : 68 > pla ;load status
0b57 : 48 > pha
> cmp_flag $ff-zero
0b58 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b5a : d0fe > bne * ;failed not equal (non zero)
>
0b5c : 28 > plp ;restore status
0b5d : c8 iny ;00
tst_y 0,$ff-minus
0b5e : 08 > php ;save flags
0b5f : c000 > cpy #0 ;test result
> trap_ne
0b61 : d0fe > bne * ;failed not equal (non zero)
>
0b63 : 68 > pla ;load status
0b64 : 48 > pha
> cmp_flag $ff-minus
0b65 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b67 : d0fe > bne * ;failed not equal (non zero)
>
0b69 : 28 > plp ;restore status
0b6a : c8 iny ;01
tst_y 1,$ff-minus-zero
0b6b : 08 > php ;save flags
0b6c : c001 > cpy #1 ;test result
> trap_ne
0b6e : d0fe > bne * ;failed not equal (non zero)
>
0b70 : 68 > pla ;load status
0b71 : 48 > pha
> cmp_flag $ff-minus-zero
0b72 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b74 : d0fe > bne * ;failed not equal (non zero)
>
0b76 : 28 > plp ;restore status
0b77 : 88 dey ;00
tst_y 0,$ff-minus
0b78 : 08 > php ;save flags
0b79 : c000 > cpy #0 ;test result
> trap_ne
0b7b : d0fe > bne * ;failed not equal (non zero)
>
0b7d : 68 > pla ;load status
0b7e : 48 > pha
> cmp_flag $ff-minus
0b7f : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b81 : d0fe > bne * ;failed not equal (non zero)
>
0b83 : 28 > plp ;restore status
0b84 : 88 dey ;ff
tst_y $ff,$ff-zero
0b85 : 08 > php ;save flags
0b86 : c0ff > cpy #$ff ;test result
> trap_ne
0b88 : d0fe > bne * ;failed not equal (non zero)
>
0b8a : 68 > pla ;load status
0b8b : 48 > pha
> cmp_flag $ff-zero
0b8c : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0b8e : d0fe > bne * ;failed not equal (non zero)
>
0b90 : 28 > plp ;restore status
0b91 : 88 dey ;fe
set_stat 0
> load_flag 0
0b92 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0b94 : 48 > pha ;use stack to load status
0b95 : 28 > plp
0b96 : c8 iny ;ff
tst_y $ff,0+minus
0b97 : 08 > php ;save flags
0b98 : c0ff > cpy #$ff ;test result
> trap_ne
0b9a : d0fe > bne * ;failed not equal (non zero)
>
0b9c : 68 > pla ;load status
0b9d : 48 > pha
> cmp_flag 0+minus
0b9e : c9b0 > cmp #(0+minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0ba0 : d0fe > bne * ;failed not equal (non zero)
>
0ba2 : 28 > plp ;restore status
0ba3 : c8 iny ;00
tst_y 0,zero
0ba4 : 08 > php ;save flags
0ba5 : c000 > cpy #0 ;test result
> trap_ne
0ba7 : d0fe > bne * ;failed not equal (non zero)
>
0ba9 : 68 > pla ;load status
0baa : 48 > pha
> cmp_flag zero
0bab : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0bad : d0fe > bne * ;failed not equal (non zero)
>
0baf : 28 > plp ;restore status
0bb0 : c8 iny ;01
tst_y 1,0
0bb1 : 08 > php ;save flags
0bb2 : c001 > cpy #1 ;test result
> trap_ne
0bb4 : d0fe > bne * ;failed not equal (non zero)
>
0bb6 : 68 > pla ;load status
0bb7 : 48 > pha
> cmp_flag 0
0bb8 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0bba : d0fe > bne * ;failed not equal (non zero)
>
0bbc : 28 > plp ;restore status
0bbd : 88 dey ;00
tst_y 0,zero
0bbe : 08 > php ;save flags
0bbf : c000 > cpy #0 ;test result
> trap_ne
0bc1 : d0fe > bne * ;failed not equal (non zero)
>
0bc3 : 68 > pla ;load status
0bc4 : 48 > pha
> cmp_flag zero
0bc5 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0bc7 : d0fe > bne * ;failed not equal (non zero)
>
0bc9 : 28 > plp ;restore status
0bca : 88 dey ;ff
tst_y $ff,minus
0bcb : 08 > php ;save flags
0bcc : c0ff > cpy #$ff ;test result
> trap_ne
0bce : d0fe > bne * ;failed not equal (non zero)
>
0bd0 : 68 > pla ;load status
0bd1 : 48 > pha
> cmp_flag minus
0bd2 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0bd4 : d0fe > bne * ;failed not equal (non zero)
>
0bd6 : 28 > plp ;restore status
0bd7 : a2ff ldx #$ff
set_stat $ff
> load_flag $ff
0bd9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0bdb : 48 > pha ;use stack to load status
0bdc : 28 > plp
0bdd : 8a txa
tst_a $ff,$ff-zero
0bde : 08 > php ;save flags
0bdf : c9ff > cmp #$ff ;test result
> trap_ne
0be1 : d0fe > bne * ;failed not equal (non zero)
>
0be3 : 68 > pla ;load status
0be4 : 48 > pha
> cmp_flag $ff-zero
0be5 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0be7 : d0fe > bne * ;failed not equal (non zero)
>
0be9 : 28 > plp ;restore status
0bea : 08 php
0beb : e8 inx ;00
0bec : 28 plp
0bed : 8a txa
tst_a 0,$ff-minus
0bee : 08 > php ;save flags
0bef : c900 > cmp #0 ;test result
> trap_ne
0bf1 : d0fe > bne * ;failed not equal (non zero)
>
0bf3 : 68 > pla ;load status
0bf4 : 48 > pha
> cmp_flag $ff-minus
0bf5 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0bf7 : d0fe > bne * ;failed not equal (non zero)
>
0bf9 : 28 > plp ;restore status
0bfa : 08 php
0bfb : e8 inx ;01
0bfc : 28 plp
0bfd : 8a txa
tst_a 1,$ff-minus-zero
0bfe : 08 > php ;save flags
0bff : c901 > cmp #1 ;test result
> trap_ne
0c01 : d0fe > bne * ;failed not equal (non zero)
>
0c03 : 68 > pla ;load status
0c04 : 48 > pha
> cmp_flag $ff-minus-zero
0c05 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c07 : d0fe > bne * ;failed not equal (non zero)
>
0c09 : 28 > plp ;restore status
set_stat 0
> load_flag 0
0c0a : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0c0c : 48 > pha ;use stack to load status
0c0d : 28 > plp
0c0e : 8a txa
tst_a 1,0
0c0f : 08 > php ;save flags
0c10 : c901 > cmp #1 ;test result
> trap_ne
0c12 : d0fe > bne * ;failed not equal (non zero)
>
0c14 : 68 > pla ;load status
0c15 : 48 > pha
> cmp_flag 0
0c16 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c18 : d0fe > bne * ;failed not equal (non zero)
>
0c1a : 28 > plp ;restore status
0c1b : 08 php
0c1c : ca dex ;00
0c1d : 28 plp
0c1e : 8a txa
tst_a 0,zero
0c1f : 08 > php ;save flags
0c20 : c900 > cmp #0 ;test result
> trap_ne
0c22 : d0fe > bne * ;failed not equal (non zero)
>
0c24 : 68 > pla ;load status
0c25 : 48 > pha
> cmp_flag zero
0c26 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c28 : d0fe > bne * ;failed not equal (non zero)
>
0c2a : 28 > plp ;restore status
0c2b : 08 php
0c2c : ca dex ;ff
0c2d : 28 plp
0c2e : 8a txa
tst_a $ff,minus
0c2f : 08 > php ;save flags
0c30 : c9ff > cmp #$ff ;test result
> trap_ne
0c32 : d0fe > bne * ;failed not equal (non zero)
>
0c34 : 68 > pla ;load status
0c35 : 48 > pha
> cmp_flag minus
0c36 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c38 : d0fe > bne * ;failed not equal (non zero)
>
0c3a : 28 > plp ;restore status
0c3b : a0ff ldy #$ff
set_stat $ff
> load_flag $ff
0c3d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0c3f : 48 > pha ;use stack to load status
0c40 : 28 > plp
0c41 : 98 tya
tst_a $ff,$ff-zero
0c42 : 08 > php ;save flags
0c43 : c9ff > cmp #$ff ;test result
> trap_ne
0c45 : d0fe > bne * ;failed not equal (non zero)
>
0c47 : 68 > pla ;load status
0c48 : 48 > pha
> cmp_flag $ff-zero
0c49 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c4b : d0fe > bne * ;failed not equal (non zero)
>
0c4d : 28 > plp ;restore status
0c4e : 08 php
0c4f : c8 iny ;00
0c50 : 28 plp
0c51 : 98 tya
tst_a 0,$ff-minus
0c52 : 08 > php ;save flags
0c53 : c900 > cmp #0 ;test result
> trap_ne
0c55 : d0fe > bne * ;failed not equal (non zero)
>
0c57 : 68 > pla ;load status
0c58 : 48 > pha
> cmp_flag $ff-minus
0c59 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c5b : d0fe > bne * ;failed not equal (non zero)
>
0c5d : 28 > plp ;restore status
0c5e : 08 php
0c5f : c8 iny ;01
0c60 : 28 plp
0c61 : 98 tya
tst_a 1,$ff-minus-zero
0c62 : 08 > php ;save flags
0c63 : c901 > cmp #1 ;test result
> trap_ne
0c65 : d0fe > bne * ;failed not equal (non zero)
>
0c67 : 68 > pla ;load status
0c68 : 48 > pha
> cmp_flag $ff-minus-zero
0c69 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c6b : d0fe > bne * ;failed not equal (non zero)
>
0c6d : 28 > plp ;restore status
set_stat 0
> load_flag 0
0c6e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0c70 : 48 > pha ;use stack to load status
0c71 : 28 > plp
0c72 : 98 tya
tst_a 1,0
0c73 : 08 > php ;save flags
0c74 : c901 > cmp #1 ;test result
> trap_ne
0c76 : d0fe > bne * ;failed not equal (non zero)
>
0c78 : 68 > pla ;load status
0c79 : 48 > pha
> cmp_flag 0
0c7a : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c7c : d0fe > bne * ;failed not equal (non zero)
>
0c7e : 28 > plp ;restore status
0c7f : 08 php
0c80 : 88 dey ;00
0c81 : 28 plp
0c82 : 98 tya
tst_a 0,zero
0c83 : 08 > php ;save flags
0c84 : c900 > cmp #0 ;test result
> trap_ne
0c86 : d0fe > bne * ;failed not equal (non zero)
>
0c88 : 68 > pla ;load status
0c89 : 48 > pha
> cmp_flag zero
0c8a : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c8c : d0fe > bne * ;failed not equal (non zero)
>
0c8e : 28 > plp ;restore status
0c8f : 08 php
0c90 : 88 dey ;ff
0c91 : 28 plp
0c92 : 98 tya
tst_a $ff,minus
0c93 : 08 > php ;save flags
0c94 : c9ff > cmp #$ff ;test result
> trap_ne
0c96 : d0fe > bne * ;failed not equal (non zero)
>
0c98 : 68 > pla ;load status
0c99 : 48 > pha
> cmp_flag minus
0c9a : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0c9c : d0fe > bne * ;failed not equal (non zero)
>
0c9e : 28 > plp ;restore status
load_flag $ff
0c9f : a9ff > lda #$ff ;allow test to change I-flag (no mask)
0ca1 : 48 pha
0ca2 : a2ff ldx #$ff ;ff
0ca4 : 8a txa
0ca5 : 28 plp
0ca6 : a8 tay
tst_y $ff,$ff-zero
0ca7 : 08 > php ;save flags
0ca8 : c0ff > cpy #$ff ;test result
> trap_ne
0caa : d0fe > bne * ;failed not equal (non zero)
>
0cac : 68 > pla ;load status
0cad : 48 > pha
> cmp_flag $ff-zero
0cae : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0cb0 : d0fe > bne * ;failed not equal (non zero)
>
0cb2 : 28 > plp ;restore status
0cb3 : 08 php
0cb4 : e8 inx ;00
0cb5 : 8a txa
0cb6 : 28 plp
0cb7 : a8 tay
tst_y 0,$ff-minus
0cb8 : 08 > php ;save flags
0cb9 : c000 > cpy #0 ;test result
> trap_ne
0cbb : d0fe > bne * ;failed not equal (non zero)
>
0cbd : 68 > pla ;load status
0cbe : 48 > pha
> cmp_flag $ff-minus
0cbf : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0cc1 : d0fe > bne * ;failed not equal (non zero)
>
0cc3 : 28 > plp ;restore status
0cc4 : 08 php
0cc5 : e8 inx ;01
0cc6 : 8a txa
0cc7 : 28 plp
0cc8 : a8 tay
tst_y 1,$ff-minus-zero
0cc9 : 08 > php ;save flags
0cca : c001 > cpy #1 ;test result
> trap_ne
0ccc : d0fe > bne * ;failed not equal (non zero)
>
0cce : 68 > pla ;load status
0ccf : 48 > pha
> cmp_flag $ff-minus-zero
0cd0 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0cd2 : d0fe > bne * ;failed not equal (non zero)
>
0cd4 : 28 > plp ;restore status
load_flag 0
0cd5 : a900 > lda #0 ;allow test to change I-flag (no mask)
0cd7 : 48 pha
0cd8 : a900 lda #0
0cda : 8a txa
0cdb : 28 plp
0cdc : a8 tay
tst_y 1,0
0cdd : 08 > php ;save flags
0cde : c001 > cpy #1 ;test result
> trap_ne
0ce0 : d0fe > bne * ;failed not equal (non zero)
>
0ce2 : 68 > pla ;load status
0ce3 : 48 > pha
> cmp_flag 0
0ce4 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0ce6 : d0fe > bne * ;failed not equal (non zero)
>
0ce8 : 28 > plp ;restore status
0ce9 : 08 php
0cea : ca dex ;00
0ceb : 8a txa
0cec : 28 plp
0ced : a8 tay
tst_y 0,zero
0cee : 08 > php ;save flags
0cef : c000 > cpy #0 ;test result
> trap_ne
0cf1 : d0fe > bne * ;failed not equal (non zero)
>
0cf3 : 68 > pla ;load status
0cf4 : 48 > pha
> cmp_flag zero
0cf5 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0cf7 : d0fe > bne * ;failed not equal (non zero)
>
0cf9 : 28 > plp ;restore status
0cfa : 08 php
0cfb : ca dex ;ff
0cfc : 8a txa
0cfd : 28 plp
0cfe : a8 tay
tst_y $ff,minus
0cff : 08 > php ;save flags
0d00 : c0ff > cpy #$ff ;test result
> trap_ne
0d02 : d0fe > bne * ;failed not equal (non zero)
>
0d04 : 68 > pla ;load status
0d05 : 48 > pha
> cmp_flag minus
0d06 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d08 : d0fe > bne * ;failed not equal (non zero)
>
0d0a : 28 > plp ;restore status
load_flag $ff
0d0b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
0d0d : 48 pha
0d0e : a0ff ldy #$ff ;ff
0d10 : 98 tya
0d11 : 28 plp
0d12 : aa tax
tst_x $ff,$ff-zero
0d13 : 08 > php ;save flags
0d14 : e0ff > cpx #$ff ;test result
> trap_ne
0d16 : d0fe > bne * ;failed not equal (non zero)
>
0d18 : 68 > pla ;load status
0d19 : 48 > pha
> cmp_flag $ff-zero
0d1a : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d1c : d0fe > bne * ;failed not equal (non zero)
>
0d1e : 28 > plp ;restore status
0d1f : 08 php
0d20 : c8 iny ;00
0d21 : 98 tya
0d22 : 28 plp
0d23 : aa tax
tst_x 0,$ff-minus
0d24 : 08 > php ;save flags
0d25 : e000 > cpx #0 ;test result
> trap_ne
0d27 : d0fe > bne * ;failed not equal (non zero)
>
0d29 : 68 > pla ;load status
0d2a : 48 > pha
> cmp_flag $ff-minus
0d2b : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d2d : d0fe > bne * ;failed not equal (non zero)
>
0d2f : 28 > plp ;restore status
0d30 : 08 php
0d31 : c8 iny ;01
0d32 : 98 tya
0d33 : 28 plp
0d34 : aa tax
tst_x 1,$ff-minus-zero
0d35 : 08 > php ;save flags
0d36 : e001 > cpx #1 ;test result
> trap_ne
0d38 : d0fe > bne * ;failed not equal (non zero)
>
0d3a : 68 > pla ;load status
0d3b : 48 > pha
> cmp_flag $ff-minus-zero
0d3c : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d3e : d0fe > bne * ;failed not equal (non zero)
>
0d40 : 28 > plp ;restore status
load_flag 0
0d41 : a900 > lda #0 ;allow test to change I-flag (no mask)
0d43 : 48 pha
0d44 : a900 lda #0 ;preset status
0d46 : 98 tya
0d47 : 28 plp
0d48 : aa tax
tst_x 1,0
0d49 : 08 > php ;save flags
0d4a : e001 > cpx #1 ;test result
> trap_ne
0d4c : d0fe > bne * ;failed not equal (non zero)
>
0d4e : 68 > pla ;load status
0d4f : 48 > pha
> cmp_flag 0
0d50 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d52 : d0fe > bne * ;failed not equal (non zero)
>
0d54 : 28 > plp ;restore status
0d55 : 08 php
0d56 : 88 dey ;00
0d57 : 98 tya
0d58 : 28 plp
0d59 : aa tax
tst_x 0,zero
0d5a : 08 > php ;save flags
0d5b : e000 > cpx #0 ;test result
> trap_ne
0d5d : d0fe > bne * ;failed not equal (non zero)
>
0d5f : 68 > pla ;load status
0d60 : 48 > pha
> cmp_flag zero
0d61 : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d63 : d0fe > bne * ;failed not equal (non zero)
>
0d65 : 28 > plp ;restore status
0d66 : 08 php
0d67 : 88 dey ;ff
0d68 : 98 tya
0d69 : 28 plp
0d6a : aa tax
tst_x $ff,minus
0d6b : 08 > php ;save flags
0d6c : e0ff > cpx #$ff ;test result
> trap_ne
0d6e : d0fe > bne * ;failed not equal (non zero)
>
0d70 : 68 > pla ;load status
0d71 : 48 > pha
> cmp_flag minus
0d72 : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
>
> trap_ne
0d74 : d0fe > bne * ;failed not equal (non zero)
>
0d76 : 28 > plp ;restore status
next_test
0d77 : ad0002 > lda test_case ;previous test
0d7a : c90d > cmp #test_num
> trap_ne ;test is out of sequence
0d7c : d0fe > bne * ;failed not equal (non zero)
>
000e = >test_num = test_num + 1
0d7e : a90e > lda #test_num ;*** next tests' number
0d80 : 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.
0d83 : a201 ldx #1 ;01
set_stat $ff
> load_flag $ff
0d85 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0d87 : 48 > pha ;use stack to load status
0d88 : 28 > plp
0d89 : 9a txs
0d8a : 08 php
0d8b : ad0101 lda $101
cmp_flag $ff
0d8e : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
trap_ne
0d90 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
0d92 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0d94 : 48 > pha ;use stack to load status
0d95 : 28 > plp
0d96 : 9a txs
0d97 : 08 php
0d98 : ad0101 lda $101
cmp_flag 0
0d9b : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
trap_ne
0d9d : d0fe > bne * ;failed not equal (non zero)
0d9f : ca dex ;00
set_stat $ff
> load_flag $ff
0da0 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0da2 : 48 > pha ;use stack to load status
0da3 : 28 > plp
0da4 : 9a txs
0da5 : 08 php
0da6 : ad0001 lda $100
cmp_flag $ff
0da9 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
trap_ne
0dab : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
0dad : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0daf : 48 > pha ;use stack to load status
0db0 : 28 > plp
0db1 : 9a txs
0db2 : 08 php
0db3 : ad0001 lda $100
cmp_flag 0
0db6 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
trap_ne
0db8 : d0fe > bne * ;failed not equal (non zero)
0dba : ca dex ;ff
set_stat $ff
> load_flag $ff
0dbb : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0dbd : 48 > pha ;use stack to load status
0dbe : 28 > plp
0dbf : 9a txs
0dc0 : 08 php
0dc1 : adff01 lda $1ff
cmp_flag $ff
0dc4 : c9ff > cmp #($ff|fao)&m8 ;expected flags + always on bits
trap_ne
0dc6 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
0dc8 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0dca : 48 > pha ;use stack to load status
0dcb : 28 > plp
0dcc : 9a txs
0dcd : 08 php
0dce : adff01 lda $1ff
cmp_flag 0
0dd1 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
0dd3 : a201 ldx #1
0dd5 : 9a txs ;sp=01
set_stat $ff
> load_flag $ff
0dd6 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0dd8 : 48 > pha ;use stack to load status
0dd9 : 28 > plp
0dda : ba tsx ;clears Z, N
0ddb : 08 php ;sp=00
0ddc : e001 cpx #1
trap_ne
0dde : d0fe > bne * ;failed not equal (non zero)
0de0 : ad0101 lda $101
cmp_flag $ff-minus-zero
0de3 : c97d > cmp #($ff-minus-zero|fao)&m8 ;expected flags + always on bits
trap_ne
0de5 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
0de7 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0de9 : 48 > pha ;use stack to load status
0dea : 28 > plp
0deb : ba tsx ;clears N, sets Z
0dec : 08 php ;sp=ff
0ded : e000 cpx #0
trap_ne
0def : d0fe > bne * ;failed not equal (non zero)
0df1 : ad0001 lda $100
cmp_flag $ff-minus
0df4 : c97f > cmp #($ff-minus|fao)&m8 ;expected flags + always on bits
trap_ne
0df6 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
0df8 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0dfa : 48 > pha ;use stack to load status
0dfb : 28 > plp
0dfc : ba tsx ;clears N, sets Z
0dfd : 08 php ;sp=fe
0dfe : e0ff cpx #$ff
trap_ne
0e00 : d0fe > bne * ;failed not equal (non zero)
0e02 : adff01 lda $1ff
cmp_flag $ff-zero
0e05 : c9fd > cmp #($ff-zero|fao)&m8 ;expected flags + always on bits
trap_ne
0e07 : d0fe > bne * ;failed not equal (non zero)
0e09 : a201 ldx #1
0e0b : 9a txs ;sp=01
set_stat 0
> load_flag 0
0e0c : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0e0e : 48 > pha ;use stack to load status
0e0f : 28 > plp
0e10 : ba tsx ;clears Z, N
0e11 : 08 php ;sp=00
0e12 : e001 cpx #1
trap_ne
0e14 : d0fe > bne * ;failed not equal (non zero)
0e16 : ad0101 lda $101
cmp_flag 0
0e19 : c930 > cmp #(0|fao)&m8 ;expected flags + always on bits
trap_ne
0e1b : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
0e1d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0e1f : 48 > pha ;use stack to load status
0e20 : 28 > plp
0e21 : ba tsx ;clears N, sets Z
0e22 : 08 php ;sp=ff
0e23 : e000 cpx #0
trap_ne
0e25 : d0fe > bne * ;failed not equal (non zero)
0e27 : ad0001 lda $100
cmp_flag zero
0e2a : c932 > cmp #(zero|fao)&m8 ;expected flags + always on bits
trap_ne
0e2c : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
0e2e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0e30 : 48 > pha ;use stack to load status
0e31 : 28 > plp
0e32 : ba tsx ;clears N, sets Z
0e33 : 08 php ;sp=fe
0e34 : e0ff cpx #$ff
trap_ne
0e36 : d0fe > bne * ;failed not equal (non zero)
0e38 : adff01 lda $1ff
cmp_flag minus
0e3b : c9b0 > cmp #(minus|fao)&m8 ;expected flags + always on bits
trap_ne
0e3d : d0fe > bne * ;failed not equal (non zero)
0e3f : 68 pla ;sp=ff
next_test
0e40 : ad0002 > lda test_case ;previous test
0e43 : c90e > cmp #test_num
> trap_ne ;test is out of sequence
0e45 : d0fe > bne * ;failed not equal (non zero)
>
000f = >test_num = test_num + 1
0e47 : a90f > lda #test_num ;*** next tests' number
0e49 : 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
0e4c : a003 ldy #3
0e4e : tldx
set_stat 0
> load_flag 0
0e4e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0e50 : 48 > pha ;use stack to load status
0e51 : 28 > plp
0e52 : b613 ldx zp1,y
0e54 : 08 php ;test stores do not alter flags
0e55 : 8a txa
0e56 : 49c3 eor #$c3
0e58 : 28 plp
0e59 : 990302 sta abst,y
0e5c : 08 php ;flags after load/store sequence
0e5d : 49c3 eor #$c3
0e5f : d91702 cmp abs1,y ;test result
trap_ne
0e62 : d0fe > bne * ;failed not equal (non zero)
0e64 : 68 pla ;load status
eor_flag 0
0e65 : 4930 > eor #0|fao ;invert expected flags + always on bits
0e67 : d91c02 cmp fLDx,y ;test flags
trap_ne
0e6a : d0fe > bne * ;failed not equal (non zero)
0e6c : 88 dey
0e6d : 10df bpl tldx
0e6f : a003 ldy #3
0e71 : tldx1
set_stat $ff
> load_flag $ff
0e71 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0e73 : 48 > pha ;use stack to load status
0e74 : 28 > plp
0e75 : b613 ldx zp1,y
0e77 : 08 php ;test stores do not alter flags
0e78 : 8a txa
0e79 : 49c3 eor #$c3
0e7b : 28 plp
0e7c : 990302 sta abst,y
0e7f : 08 php ;flags after load/store sequence
0e80 : 49c3 eor #$c3
0e82 : d91702 cmp abs1,y ;test result
trap_ne
0e85 : d0fe > bne * ;failed not equal (non zero)
0e87 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
0e88 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
0e8a : d91c02 cmp fLDx,y ;test flags
trap_ne
0e8d : d0fe > bne * ;failed not equal (non zero)
0e8f : 88 dey
0e90 : 10df bpl tldx1
0e92 : a003 ldy #3
0e94 : tldx2
set_stat 0
> load_flag 0
0e94 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0e96 : 48 > pha ;use stack to load status
0e97 : 28 > plp
0e98 : be1702 ldx abs1,y
0e9b : 08 php ;test stores do not alter flags
0e9c : 8a txa
0e9d : 49c3 eor #$c3
0e9f : aa tax
0ea0 : 28 plp
0ea1 : 960c stx zpt,y
0ea3 : 08 php ;flags after load/store sequence
0ea4 : 49c3 eor #$c3
0ea6 : d91300 cmp zp1,y ;test result
trap_ne
0ea9 : d0fe > bne * ;failed not equal (non zero)
0eab : 68 pla ;load status
eor_flag 0
0eac : 4930 > eor #0|fao ;invert expected flags + always on bits
0eae : d91c02 cmp fLDx,y ;test flags
trap_ne
0eb1 : d0fe > bne * ;failed not equal (non zero)
0eb3 : 88 dey
0eb4 : 10de bpl tldx2
0eb6 : a003 ldy #3
0eb8 : tldx3
set_stat $ff
> load_flag $ff
0eb8 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0eba : 48 > pha ;use stack to load status
0ebb : 28 > plp
0ebc : be1702 ldx abs1,y
0ebf : 08 php ;test stores do not alter flags
0ec0 : 8a txa
0ec1 : 49c3 eor #$c3
0ec3 : aa tax
0ec4 : 28 plp
0ec5 : 960c stx zpt,y
0ec7 : 08 php ;flags after load/store sequence
0ec8 : 49c3 eor #$c3
0eca : d91300 cmp zp1,y ;test result
trap_ne
0ecd : d0fe > bne * ;failed not equal (non zero)
0ecf : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
0ed0 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
0ed2 : d91c02 cmp fLDx,y ;test flags
trap_ne
0ed5 : d0fe > bne * ;failed not equal (non zero)
0ed7 : 88 dey
0ed8 : 10de bpl tldx3
0eda : a003 ldy #3 ;testing store result
0edc : a200 ldx #0
0ede : b90c00 tstx lda zpt,y
0ee1 : 49c3 eor #$c3
0ee3 : d91300 cmp zp1,y
trap_ne ;store to zp data
0ee6 : d0fe > bne * ;failed not equal (non zero)
0ee8 : 960c stx zpt,y ;clear
0eea : b90302 lda abst,y
0eed : 49c3 eor #$c3
0eef : d91702 cmp abs1,y
trap_ne ;store to abs data
0ef2 : d0fe > bne * ;failed not equal (non zero)
0ef4 : 8a txa
0ef5 : 990302 sta abst,y ;clear
0ef8 : 88 dey
0ef9 : 10e3 bpl tstx
next_test
0efb : ad0002 > lda test_case ;previous test
0efe : c90f > cmp #test_num
> trap_ne ;test is out of sequence
0f00 : d0fe > bne * ;failed not equal (non zero)
>
0010 = >test_num = test_num + 1
0f02 : a910 > lda #test_num ;*** next tests' number
0f04 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; indexed wraparound test (only zp should wrap)
0f07 : a0fd ldy #3+$fa
0f09 : b619 tldx4 ldx zp1-$fa&$ff,y ;wrap on indexed zp
0f0b : 8a txa
0f0c : 990901 sta abst-$fa,y ;no STX abs,y!
0f0f : 88 dey
0f10 : c0fa cpy #$fa
0f12 : b0f5 bcs tldx4
0f14 : a0fd ldy #3+$fa
0f16 : be1d01 tldx5 ldx abs1-$fa,y ;no wrap on indexed abs
0f19 : 9612 stx zpt-$fa&$ff,y
0f1b : 88 dey
0f1c : c0fa cpy #$fa
0f1e : b0f6 bcs tldx5
0f20 : a003 ldy #3 ;testing wraparound result
0f22 : a200 ldx #0
0f24 : b90c00 tstx1 lda zpt,y
0f27 : d91300 cmp zp1,y
trap_ne ;store to zp data
0f2a : d0fe > bne * ;failed not equal (non zero)
0f2c : 960c stx zpt,y ;clear
0f2e : b90302 lda abst,y
0f31 : d91702 cmp abs1,y
trap_ne ;store to abs data
0f34 : d0fe > bne * ;failed not equal (non zero)
0f36 : 8a txa
0f37 : 990302 sta abst,y ;clear
0f3a : 88 dey
0f3b : 10e7 bpl tstx1
next_test
0f3d : ad0002 > lda test_case ;previous test
0f40 : c910 > cmp #test_num
> trap_ne ;test is out of sequence
0f42 : d0fe > bne * ;failed not equal (non zero)
>
0011 = >test_num = test_num + 1
0f44 : a911 > lda #test_num ;*** next tests' number
0f46 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; LDY / STY - zp,x / abs,x
0f49 : a203 ldx #3
0f4b : tldy
set_stat 0
> load_flag 0
0f4b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0f4d : 48 > pha ;use stack to load status
0f4e : 28 > plp
0f4f : b413 ldy zp1,x
0f51 : 08 php ;test stores do not alter flags
0f52 : 98 tya
0f53 : 49c3 eor #$c3
0f55 : 28 plp
0f56 : 9d0302 sta abst,x
0f59 : 08 php ;flags after load/store sequence
0f5a : 49c3 eor #$c3
0f5c : dd1702 cmp abs1,x ;test result
trap_ne
0f5f : d0fe > bne * ;failed not equal (non zero)
0f61 : 68 pla ;load status
eor_flag 0
0f62 : 4930 > eor #0|fao ;invert expected flags + always on bits
0f64 : dd1c02 cmp fLDx,x ;test flags
trap_ne
0f67 : d0fe > bne * ;failed not equal (non zero)
0f69 : ca dex
0f6a : 10df bpl tldy
0f6c : a203 ldx #3
0f6e : tldy1
set_stat $ff
> load_flag $ff
0f6e : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0f70 : 48 > pha ;use stack to load status
0f71 : 28 > plp
0f72 : b413 ldy zp1,x
0f74 : 08 php ;test stores do not alter flags
0f75 : 98 tya
0f76 : 49c3 eor #$c3
0f78 : 28 plp
0f79 : 9d0302 sta abst,x
0f7c : 08 php ;flags after load/store sequence
0f7d : 49c3 eor #$c3
0f7f : dd1702 cmp abs1,x ;test result
trap_ne
0f82 : d0fe > bne * ;failed not equal (non zero)
0f84 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
0f85 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
0f87 : dd1c02 cmp fLDx,x ;test flags
trap_ne
0f8a : d0fe > bne * ;failed not equal (non zero)
0f8c : ca dex
0f8d : 10df bpl tldy1
0f8f : a203 ldx #3
0f91 : tldy2
set_stat 0
> load_flag 0
0f91 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
0f93 : 48 > pha ;use stack to load status
0f94 : 28 > plp
0f95 : bc1702 ldy abs1,x
0f98 : 08 php ;test stores do not alter flags
0f99 : 98 tya
0f9a : 49c3 eor #$c3
0f9c : a8 tay
0f9d : 28 plp
0f9e : 940c sty zpt,x
0fa0 : 08 php ;flags after load/store sequence
0fa1 : 49c3 eor #$c3
0fa3 : d513 cmp zp1,x ;test result
trap_ne
0fa5 : d0fe > bne * ;failed not equal (non zero)
0fa7 : 68 pla ;load status
eor_flag 0
0fa8 : 4930 > eor #0|fao ;invert expected flags + always on bits
0faa : dd1c02 cmp fLDx,x ;test flags
trap_ne
0fad : d0fe > bne * ;failed not equal (non zero)
0faf : ca dex
0fb0 : 10df bpl tldy2
0fb2 : a203 ldx #3
0fb4 : tldy3
set_stat $ff
> load_flag $ff
0fb4 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
0fb6 : 48 > pha ;use stack to load status
0fb7 : 28 > plp
0fb8 : bc1702 ldy abs1,x
0fbb : 08 php ;test stores do not alter flags
0fbc : 98 tya
0fbd : 49c3 eor #$c3
0fbf : a8 tay
0fc0 : 28 plp
0fc1 : 940c sty zpt,x
0fc3 : 08 php ;flags after load/store sequence
0fc4 : 49c3 eor #$c3
0fc6 : d513 cmp zp1,x ;test result
trap_ne
0fc8 : d0fe > bne * ;failed not equal (non zero)
0fca : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
0fcb : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
0fcd : dd1c02 cmp fLDx,x ;test flags
trap_ne
0fd0 : d0fe > bne * ;failed not equal (non zero)
0fd2 : ca dex
0fd3 : 10df bpl tldy3
0fd5 : a203 ldx #3 ;testing store result
0fd7 : a000 ldy #0
0fd9 : b50c tsty lda zpt,x
0fdb : 49c3 eor #$c3
0fdd : d513 cmp zp1,x
trap_ne ;store to zp,x data
0fdf : d0fe > bne * ;failed not equal (non zero)
0fe1 : 940c sty zpt,x ;clear
0fe3 : bd0302 lda abst,x
0fe6 : 49c3 eor #$c3
0fe8 : dd1702 cmp abs1,x
trap_ne ;store to abs,x data
0feb : d0fe > bne * ;failed not equal (non zero)
0fed : 8a txa
0fee : 9d0302 sta abst,x ;clear
0ff1 : ca dex
0ff2 : 10e5 bpl tsty
next_test
0ff4 : ad0002 > lda test_case ;previous test
0ff7 : c911 > cmp #test_num
> trap_ne ;test is out of sequence
0ff9 : d0fe > bne * ;failed not equal (non zero)
>
0012 = >test_num = test_num + 1
0ffb : a912 > lda #test_num ;*** next tests' number
0ffd : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; indexed wraparound test (only zp should wrap)
1000 : a2fd ldx #3+$fa
1002 : b419 tldy4 ldy zp1-$fa&$ff,x ;wrap on indexed zp
1004 : 98 tya
1005 : 9d0901 sta abst-$fa,x ;no STX abs,x!
1008 : ca dex
1009 : e0fa cpx #$fa
100b : b0f5 bcs tldy4
100d : a2fd ldx #3+$fa
100f : bc1d01 tldy5 ldy abs1-$fa,x ;no wrap on indexed abs
1012 : 9412 sty zpt-$fa&$ff,x
1014 : ca dex
1015 : e0fa cpx #$fa
1017 : b0f6 bcs tldy5
1019 : a203 ldx #3 ;testing wraparound result
101b : a000 ldy #0
101d : b50c tsty1 lda zpt,x
101f : d513 cmp zp1,x
trap_ne ;store to zp,x data
1021 : d0fe > bne * ;failed not equal (non zero)
1023 : 940c sty zpt,x ;clear
1025 : bd0302 lda abst,x
1028 : dd1702 cmp abs1,x
trap_ne ;store to abs,x data
102b : d0fe > bne * ;failed not equal (non zero)
102d : 8a txa
102e : 9d0302 sta abst,x ;clear
1031 : ca dex
1032 : 10e9 bpl tsty1
next_test
1034 : ad0002 > lda test_case ;previous test
1037 : c912 > cmp #test_num
> trap_ne ;test is out of sequence
1039 : d0fe > bne * ;failed not equal (non zero)
>
0013 = >test_num = test_num + 1
103b : a913 > lda #test_num ;*** next tests' number
103d : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; LDX / STX - zp / abs / #
set_stat 0
> load_flag 0
1040 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1042 : 48 > pha ;use stack to load status
1043 : 28 > plp
1044 : a613 ldx zp1
1046 : 08 php ;test stores do not alter flags
1047 : 8a txa
1048 : 49c3 eor #$c3
104a : aa tax
104b : 28 plp
104c : 8e0302 stx abst
104f : 08 php ;flags after load/store sequence
1050 : 49c3 eor #$c3
1052 : aa tax
1053 : e0c3 cpx #$c3 ;test result
trap_ne
1055 : d0fe > bne * ;failed not equal (non zero)
1057 : 68 pla ;load status
eor_flag 0
1058 : 4930 > eor #0|fao ;invert expected flags + always on bits
105a : cd1c02 cmp fLDx ;test flags
trap_ne
105d : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
105f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1061 : 48 > pha ;use stack to load status
1062 : 28 > plp
1063 : a614 ldx zp1+1
1065 : 08 php ;test stores do not alter flags
1066 : 8a txa
1067 : 49c3 eor #$c3
1069 : aa tax
106a : 28 plp
106b : 8e0402 stx abst+1
106e : 08 php ;flags after load/store sequence
106f : 49c3 eor #$c3
1071 : aa tax
1072 : e082 cpx #$82 ;test result
trap_ne
1074 : d0fe > bne * ;failed not equal (non zero)
1076 : 68 pla ;load status
eor_flag 0
1077 : 4930 > eor #0|fao ;invert expected flags + always on bits
1079 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
107c : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
107e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1080 : 48 > pha ;use stack to load status
1081 : 28 > plp
1082 : a615 ldx zp1+2
1084 : 08 php ;test stores do not alter flags
1085 : 8a txa
1086 : 49c3 eor #$c3
1088 : aa tax
1089 : 28 plp
108a : 8e0502 stx abst+2
108d : 08 php ;flags after load/store sequence
108e : 49c3 eor #$c3
1090 : aa tax
1091 : e041 cpx #$41 ;test result
trap_ne
1093 : d0fe > bne * ;failed not equal (non zero)
1095 : 68 pla ;load status
eor_flag 0
1096 : 4930 > eor #0|fao ;invert expected flags + always on bits
1098 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
109b : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
109d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
109f : 48 > pha ;use stack to load status
10a0 : 28 > plp
10a1 : a616 ldx zp1+3
10a3 : 08 php ;test stores do not alter flags
10a4 : 8a txa
10a5 : 49c3 eor #$c3
10a7 : aa tax
10a8 : 28 plp
10a9 : 8e0602 stx abst+3
10ac : 08 php ;flags after load/store sequence
10ad : 49c3 eor #$c3
10af : aa tax
10b0 : e000 cpx #0 ;test result
trap_ne
10b2 : d0fe > bne * ;failed not equal (non zero)
10b4 : 68 pla ;load status
eor_flag 0
10b5 : 4930 > eor #0|fao ;invert expected flags + always on bits
10b7 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
10ba : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
10bc : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
10be : 48 > pha ;use stack to load status
10bf : 28 > plp
10c0 : a613 ldx zp1
10c2 : 08 php ;test stores do not alter flags
10c3 : 8a txa
10c4 : 49c3 eor #$c3
10c6 : aa tax
10c7 : 28 plp
10c8 : 8e0302 stx abst
10cb : 08 php ;flags after load/store sequence
10cc : 49c3 eor #$c3
10ce : aa tax
10cf : e0c3 cpx #$c3 ;test result
trap_ne ;
10d1 : d0fe > bne * ;failed not equal (non zero)
10d3 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
10d4 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
10d6 : cd1c02 cmp fLDx ;test flags
trap_ne
10d9 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
10db : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
10dd : 48 > pha ;use stack to load status
10de : 28 > plp
10df : a614 ldx zp1+1
10e1 : 08 php ;test stores do not alter flags
10e2 : 8a txa
10e3 : 49c3 eor #$c3
10e5 : aa tax
10e6 : 28 plp
10e7 : 8e0402 stx abst+1
10ea : 08 php ;flags after load/store sequence
10eb : 49c3 eor #$c3
10ed : aa tax
10ee : e082 cpx #$82 ;test result
trap_ne
10f0 : d0fe > bne * ;failed not equal (non zero)
10f2 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
10f3 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
10f5 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
10f8 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
10fa : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
10fc : 48 > pha ;use stack to load status
10fd : 28 > plp
10fe : a615 ldx zp1+2
1100 : 08 php ;test stores do not alter flags
1101 : 8a txa
1102 : 49c3 eor #$c3
1104 : aa tax
1105 : 28 plp
1106 : 8e0502 stx abst+2
1109 : 08 php ;flags after load/store sequence
110a : 49c3 eor #$c3
110c : aa tax
110d : e041 cpx #$41 ;test result
trap_ne ;
110f : d0fe > bne * ;failed not equal (non zero)
1111 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1112 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1114 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1117 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1119 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
111b : 48 > pha ;use stack to load status
111c : 28 > plp
111d : a616 ldx zp1+3
111f : 08 php ;test stores do not alter flags
1120 : 8a txa
1121 : 49c3 eor #$c3
1123 : aa tax
1124 : 28 plp
1125 : 8e0602 stx abst+3
1128 : 08 php ;flags after load/store sequence
1129 : 49c3 eor #$c3
112b : aa tax
112c : e000 cpx #0 ;test result
trap_ne
112e : d0fe > bne * ;failed not equal (non zero)
1130 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1131 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1133 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1136 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1138 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
113a : 48 > pha ;use stack to load status
113b : 28 > plp
113c : ae1702 ldx abs1
113f : 08 php ;test stores do not alter flags
1140 : 8a txa
1141 : 49c3 eor #$c3
1143 : aa tax
1144 : 28 plp
1145 : 860c stx zpt
1147 : 08 php ;flags after load/store sequence
1148 : 49c3 eor #$c3
114a : c513 cmp zp1 ;test result
trap_ne
114c : d0fe > bne * ;failed not equal (non zero)
114e : 68 pla ;load status
eor_flag 0
114f : 4930 > eor #0|fao ;invert expected flags + always on bits
1151 : cd1c02 cmp fLDx ;test flags
trap_ne
1154 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1156 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1158 : 48 > pha ;use stack to load status
1159 : 28 > plp
115a : ae1802 ldx abs1+1
115d : 08 php ;test stores do not alter flags
115e : 8a txa
115f : 49c3 eor #$c3
1161 : aa tax
1162 : 28 plp
1163 : 860d stx zpt+1
1165 : 08 php ;flags after load/store sequence
1166 : 49c3 eor #$c3
1168 : c514 cmp zp1+1 ;test result
trap_ne
116a : d0fe > bne * ;failed not equal (non zero)
116c : 68 pla ;load status
eor_flag 0
116d : 4930 > eor #0|fao ;invert expected flags + always on bits
116f : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1172 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1174 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1176 : 48 > pha ;use stack to load status
1177 : 28 > plp
1178 : ae1902 ldx abs1+2
117b : 08 php ;test stores do not alter flags
117c : 8a txa
117d : 49c3 eor #$c3
117f : aa tax
1180 : 28 plp
1181 : 860e stx zpt+2
1183 : 08 php ;flags after load/store sequence
1184 : 49c3 eor #$c3
1186 : c515 cmp zp1+2 ;test result
trap_ne
1188 : d0fe > bne * ;failed not equal (non zero)
118a : 68 pla ;load status
eor_flag 0
118b : 4930 > eor #0|fao ;invert expected flags + always on bits
118d : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1190 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1192 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1194 : 48 > pha ;use stack to load status
1195 : 28 > plp
1196 : ae1a02 ldx abs1+3
1199 : 08 php ;test stores do not alter flags
119a : 8a txa
119b : 49c3 eor #$c3
119d : aa tax
119e : 28 plp
119f : 860f stx zpt+3
11a1 : 08 php ;flags after load/store sequence
11a2 : 49c3 eor #$c3
11a4 : c516 cmp zp1+3 ;test result
trap_ne
11a6 : d0fe > bne * ;failed not equal (non zero)
11a8 : 68 pla ;load status
eor_flag 0
11a9 : 4930 > eor #0|fao ;invert expected flags + always on bits
11ab : cd1f02 cmp fLDx+3 ;test flags
trap_ne
11ae : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
11b0 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
11b2 : 48 > pha ;use stack to load status
11b3 : 28 > plp
11b4 : ae1702 ldx abs1
11b7 : 08 php ;test stores do not alter flags
11b8 : 8a txa
11b9 : 49c3 eor #$c3
11bb : aa tax
11bc : 28 plp
11bd : 860c stx zpt
11bf : 08 php ;flags after load/store sequence
11c0 : 49c3 eor #$c3
11c2 : aa tax
11c3 : e413 cpx zp1 ;test result
trap_ne
11c5 : d0fe > bne * ;failed not equal (non zero)
11c7 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
11c8 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
11ca : cd1c02 cmp fLDx ;test flags
trap_ne
11cd : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
11cf : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
11d1 : 48 > pha ;use stack to load status
11d2 : 28 > plp
11d3 : ae1802 ldx abs1+1
11d6 : 08 php ;test stores do not alter flags
11d7 : 8a txa
11d8 : 49c3 eor #$c3
11da : aa tax
11db : 28 plp
11dc : 860d stx zpt+1
11de : 08 php ;flags after load/store sequence
11df : 49c3 eor #$c3
11e1 : aa tax
11e2 : e414 cpx zp1+1 ;test result
trap_ne
11e4 : d0fe > bne * ;failed not equal (non zero)
11e6 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
11e7 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
11e9 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
11ec : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
11ee : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
11f0 : 48 > pha ;use stack to load status
11f1 : 28 > plp
11f2 : ae1902 ldx abs1+2
11f5 : 08 php ;test stores do not alter flags
11f6 : 8a txa
11f7 : 49c3 eor #$c3
11f9 : aa tax
11fa : 28 plp
11fb : 860e stx zpt+2
11fd : 08 php ;flags after load/store sequence
11fe : 49c3 eor #$c3
1200 : aa tax
1201 : e415 cpx zp1+2 ;test result
trap_ne
1203 : d0fe > bne * ;failed not equal (non zero)
1205 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1206 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1208 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
120b : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
120d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
120f : 48 > pha ;use stack to load status
1210 : 28 > plp
1211 : ae1a02 ldx abs1+3
1214 : 08 php ;test stores do not alter flags
1215 : 8a txa
1216 : 49c3 eor #$c3
1218 : aa tax
1219 : 28 plp
121a : 860f stx zpt+3
121c : 08 php ;flags after load/store sequence
121d : 49c3 eor #$c3
121f : aa tax
1220 : e416 cpx zp1+3 ;test result
trap_ne
1222 : d0fe > bne * ;failed not equal (non zero)
1224 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1225 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1227 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
122a : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
122c : a900 > lda #0 ;allow test to change I-flag (no mask)
>
122e : 48 > pha ;use stack to load status
122f : 28 > plp
1230 : a2c3 ldx #$c3
1232 : 08 php
1233 : ec1702 cpx abs1 ;test result
trap_ne
1236 : d0fe > bne * ;failed not equal (non zero)
1238 : 68 pla ;load status
eor_flag 0
1239 : 4930 > eor #0|fao ;invert expected flags + always on bits
123b : cd1c02 cmp fLDx ;test flags
trap_ne
123e : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1240 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1242 : 48 > pha ;use stack to load status
1243 : 28 > plp
1244 : a282 ldx #$82
1246 : 08 php
1247 : ec1802 cpx abs1+1 ;test result
trap_ne
124a : d0fe > bne * ;failed not equal (non zero)
124c : 68 pla ;load status
eor_flag 0
124d : 4930 > eor #0|fao ;invert expected flags + always on bits
124f : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1252 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1254 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1256 : 48 > pha ;use stack to load status
1257 : 28 > plp
1258 : a241 ldx #$41
125a : 08 php
125b : ec1902 cpx abs1+2 ;test result
trap_ne
125e : d0fe > bne * ;failed not equal (non zero)
1260 : 68 pla ;load status
eor_flag 0
1261 : 4930 > eor #0|fao ;invert expected flags + always on bits
1263 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1266 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1268 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
126a : 48 > pha ;use stack to load status
126b : 28 > plp
126c : a200 ldx #0
126e : 08 php
126f : ec1a02 cpx abs1+3 ;test result
trap_ne
1272 : d0fe > bne * ;failed not equal (non zero)
1274 : 68 pla ;load status
eor_flag 0
1275 : 4930 > eor #0|fao ;invert expected flags + always on bits
1277 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
127a : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
127c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
127e : 48 > pha ;use stack to load status
127f : 28 > plp
1280 : a2c3 ldx #$c3
1282 : 08 php
1283 : ec1702 cpx abs1 ;test result
trap_ne
1286 : d0fe > bne * ;failed not equal (non zero)
1288 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1289 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
128b : cd1c02 cmp fLDx ;test flags
trap_ne
128e : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1290 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1292 : 48 > pha ;use stack to load status
1293 : 28 > plp
1294 : a282 ldx #$82
1296 : 08 php
1297 : ec1802 cpx abs1+1 ;test result
trap_ne
129a : d0fe > bne * ;failed not equal (non zero)
129c : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
129d : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
129f : cd1d02 cmp fLDx+1 ;test flags
trap_ne
12a2 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
12a4 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
12a6 : 48 > pha ;use stack to load status
12a7 : 28 > plp
12a8 : a241 ldx #$41
12aa : 08 php
12ab : ec1902 cpx abs1+2 ;test result
trap_ne
12ae : d0fe > bne * ;failed not equal (non zero)
12b0 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
12b1 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
12b3 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
12b6 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
12b8 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
12ba : 48 > pha ;use stack to load status
12bb : 28 > plp
12bc : a200 ldx #0
12be : 08 php
12bf : ec1a02 cpx abs1+3 ;test result
trap_ne
12c2 : d0fe > bne * ;failed not equal (non zero)
12c4 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
12c5 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
12c7 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
12ca : d0fe > bne * ;failed not equal (non zero)
12cc : a200 ldx #0
12ce : a50c lda zpt
12d0 : 49c3 eor #$c3
12d2 : c513 cmp zp1
trap_ne ;store to zp data
12d4 : d0fe > bne * ;failed not equal (non zero)
12d6 : 860c stx zpt ;clear
12d8 : ad0302 lda abst
12db : 49c3 eor #$c3
12dd : cd1702 cmp abs1
trap_ne ;store to abs data
12e0 : d0fe > bne * ;failed not equal (non zero)
12e2 : 8e0302 stx abst ;clear
12e5 : a50d lda zpt+1
12e7 : 49c3 eor #$c3
12e9 : c514 cmp zp1+1
trap_ne ;store to zp data
12eb : d0fe > bne * ;failed not equal (non zero)
12ed : 860d stx zpt+1 ;clear
12ef : ad0402 lda abst+1
12f2 : 49c3 eor #$c3
12f4 : cd1802 cmp abs1+1
trap_ne ;store to abs data
12f7 : d0fe > bne * ;failed not equal (non zero)
12f9 : 8e0402 stx abst+1 ;clear
12fc : a50e lda zpt+2
12fe : 49c3 eor #$c3
1300 : c515 cmp zp1+2
trap_ne ;store to zp data
1302 : d0fe > bne * ;failed not equal (non zero)
1304 : 860e stx zpt+2 ;clear
1306 : ad0502 lda abst+2
1309 : 49c3 eor #$c3
130b : cd1902 cmp abs1+2
trap_ne ;store to abs data
130e : d0fe > bne * ;failed not equal (non zero)
1310 : 8e0502 stx abst+2 ;clear
1313 : a50f lda zpt+3
1315 : 49c3 eor #$c3
1317 : c516 cmp zp1+3
trap_ne ;store to zp data
1319 : d0fe > bne * ;failed not equal (non zero)
131b : 860f stx zpt+3 ;clear
131d : ad0602 lda abst+3
1320 : 49c3 eor #$c3
1322 : cd1a02 cmp abs1+3
trap_ne ;store to abs data
1325 : d0fe > bne * ;failed not equal (non zero)
1327 : 8e0602 stx abst+3 ;clear
next_test
132a : ad0002 > lda test_case ;previous test
132d : c913 > cmp #test_num
> trap_ne ;test is out of sequence
132f : d0fe > bne * ;failed not equal (non zero)
>
0014 = >test_num = test_num + 1
1331 : a914 > lda #test_num ;*** next tests' number
1333 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; LDY / STY - zp / abs / #
set_stat 0
> load_flag 0
1336 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1338 : 48 > pha ;use stack to load status
1339 : 28 > plp
133a : a413 ldy zp1
133c : 08 php ;test stores do not alter flags
133d : 98 tya
133e : 49c3 eor #$c3
1340 : a8 tay
1341 : 28 plp
1342 : 8c0302 sty abst
1345 : 08 php ;flags after load/store sequence
1346 : 49c3 eor #$c3
1348 : a8 tay
1349 : c0c3 cpy #$c3 ;test result
trap_ne
134b : d0fe > bne * ;failed not equal (non zero)
134d : 68 pla ;load status
eor_flag 0
134e : 4930 > eor #0|fao ;invert expected flags + always on bits
1350 : cd1c02 cmp fLDx ;test flags
trap_ne
1353 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1355 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1357 : 48 > pha ;use stack to load status
1358 : 28 > plp
1359 : a414 ldy zp1+1
135b : 08 php ;test stores do not alter flags
135c : 98 tya
135d : 49c3 eor #$c3
135f : a8 tay
1360 : 28 plp
1361 : 8c0402 sty abst+1
1364 : 08 php ;flags after load/store sequence
1365 : 49c3 eor #$c3
1367 : a8 tay
1368 : c082 cpy #$82 ;test result
trap_ne
136a : d0fe > bne * ;failed not equal (non zero)
136c : 68 pla ;load status
eor_flag 0
136d : 4930 > eor #0|fao ;invert expected flags + always on bits
136f : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1372 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1374 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1376 : 48 > pha ;use stack to load status
1377 : 28 > plp
1378 : a415 ldy zp1+2
137a : 08 php ;test stores do not alter flags
137b : 98 tya
137c : 49c3 eor #$c3
137e : a8 tay
137f : 28 plp
1380 : 8c0502 sty abst+2
1383 : 08 php ;flags after load/store sequence
1384 : 49c3 eor #$c3
1386 : a8 tay
1387 : c041 cpy #$41 ;test result
trap_ne
1389 : d0fe > bne * ;failed not equal (non zero)
138b : 68 pla ;load status
eor_flag 0
138c : 4930 > eor #0|fao ;invert expected flags + always on bits
138e : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1391 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1393 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1395 : 48 > pha ;use stack to load status
1396 : 28 > plp
1397 : a416 ldy zp1+3
1399 : 08 php ;test stores do not alter flags
139a : 98 tya
139b : 49c3 eor #$c3
139d : a8 tay
139e : 28 plp
139f : 8c0602 sty abst+3
13a2 : 08 php ;flags after load/store sequence
13a3 : 49c3 eor #$c3
13a5 : a8 tay
13a6 : c000 cpy #0 ;test result
trap_ne
13a8 : d0fe > bne * ;failed not equal (non zero)
13aa : 68 pla ;load status
eor_flag 0
13ab : 4930 > eor #0|fao ;invert expected flags + always on bits
13ad : cd1f02 cmp fLDx+3 ;test flags
trap_ne
13b0 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
13b2 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
13b4 : 48 > pha ;use stack to load status
13b5 : 28 > plp
13b6 : a413 ldy zp1
13b8 : 08 php ;test stores do not alter flags
13b9 : 98 tya
13ba : 49c3 eor #$c3
13bc : a8 tay
13bd : 28 plp
13be : 8c0302 sty abst
13c1 : 08 php ;flags after load/store sequence
13c2 : 49c3 eor #$c3
13c4 : a8 tay
13c5 : c0c3 cpy #$c3 ;test result
trap_ne
13c7 : d0fe > bne * ;failed not equal (non zero)
13c9 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
13ca : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
13cc : cd1c02 cmp fLDx ;test flags
trap_ne
13cf : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
13d1 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
13d3 : 48 > pha ;use stack to load status
13d4 : 28 > plp
13d5 : a414 ldy zp1+1
13d7 : 08 php ;test stores do not alter flags
13d8 : 98 tya
13d9 : 49c3 eor #$c3
13db : a8 tay
13dc : 28 plp
13dd : 8c0402 sty abst+1
13e0 : 08 php ;flags after load/store sequence
13e1 : 49c3 eor #$c3
13e3 : a8 tay
13e4 : c082 cpy #$82 ;test result
trap_ne
13e6 : d0fe > bne * ;failed not equal (non zero)
13e8 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
13e9 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
13eb : cd1d02 cmp fLDx+1 ;test flags
trap_ne
13ee : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
13f0 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
13f2 : 48 > pha ;use stack to load status
13f3 : 28 > plp
13f4 : a415 ldy zp1+2
13f6 : 08 php ;test stores do not alter flags
13f7 : 98 tya
13f8 : 49c3 eor #$c3
13fa : a8 tay
13fb : 28 plp
13fc : 8c0502 sty abst+2
13ff : 08 php ;flags after load/store sequence
1400 : 49c3 eor #$c3
1402 : a8 tay
1403 : c041 cpy #$41 ;test result
trap_ne
1405 : d0fe > bne * ;failed not equal (non zero)
1407 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1408 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
140a : cd1e02 cmp fLDx+2 ;test flags
trap_ne
140d : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
140f : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1411 : 48 > pha ;use stack to load status
1412 : 28 > plp
1413 : a416 ldy zp1+3
1415 : 08 php ;test stores do not alter flags
1416 : 98 tya
1417 : 49c3 eor #$c3
1419 : a8 tay
141a : 28 plp
141b : 8c0602 sty abst+3
141e : 08 php ;flags after load/store sequence
141f : 49c3 eor #$c3
1421 : a8 tay
1422 : c000 cpy #0 ;test result
trap_ne
1424 : d0fe > bne * ;failed not equal (non zero)
1426 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1427 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1429 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
142c : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
142e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1430 : 48 > pha ;use stack to load status
1431 : 28 > plp
1432 : ac1702 ldy abs1
1435 : 08 php ;test stores do not alter flags
1436 : 98 tya
1437 : 49c3 eor #$c3
1439 : a8 tay
143a : 28 plp
143b : 840c sty zpt
143d : 08 php ;flags after load/store sequence
143e : 49c3 eor #$c3
1440 : a8 tay
1441 : c413 cpy zp1 ;test result
trap_ne
1443 : d0fe > bne * ;failed not equal (non zero)
1445 : 68 pla ;load status
eor_flag 0
1446 : 4930 > eor #0|fao ;invert expected flags + always on bits
1448 : cd1c02 cmp fLDx ;test flags
trap_ne
144b : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
144d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
144f : 48 > pha ;use stack to load status
1450 : 28 > plp
1451 : ac1802 ldy abs1+1
1454 : 08 php ;test stores do not alter flags
1455 : 98 tya
1456 : 49c3 eor #$c3
1458 : a8 tay
1459 : 28 plp
145a : 840d sty zpt+1
145c : 08 php ;flags after load/store sequence
145d : 49c3 eor #$c3
145f : a8 tay
1460 : c414 cpy zp1+1 ;test result
trap_ne
1462 : d0fe > bne * ;failed not equal (non zero)
1464 : 68 pla ;load status
eor_flag 0
1465 : 4930 > eor #0|fao ;invert expected flags + always on bits
1467 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
146a : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
146c : a900 > lda #0 ;allow test to change I-flag (no mask)
>
146e : 48 > pha ;use stack to load status
146f : 28 > plp
1470 : ac1902 ldy abs1+2
1473 : 08 php ;test stores do not alter flags
1474 : 98 tya
1475 : 49c3 eor #$c3
1477 : a8 tay
1478 : 28 plp
1479 : 840e sty zpt+2
147b : 08 php ;flags after load/store sequence
147c : 49c3 eor #$c3
147e : a8 tay
147f : c415 cpy zp1+2 ;test result
trap_ne
1481 : d0fe > bne * ;failed not equal (non zero)
1483 : 68 pla ;load status
eor_flag 0
1484 : 4930 > eor #0|fao ;invert expected flags + always on bits
1486 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1489 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
148b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
148d : 48 > pha ;use stack to load status
148e : 28 > plp
148f : ac1a02 ldy abs1+3
1492 : 08 php ;test stores do not alter flags
1493 : 98 tya
1494 : 49c3 eor #$c3
1496 : a8 tay
1497 : 28 plp
1498 : 840f sty zpt+3
149a : 08 php ;flags after load/store sequence
149b : 49c3 eor #$c3
149d : a8 tay
149e : c416 cpy zp1+3 ;test result
trap_ne
14a0 : d0fe > bne * ;failed not equal (non zero)
14a2 : 68 pla ;load status
eor_flag 0
14a3 : 4930 > eor #0|fao ;invert expected flags + always on bits
14a5 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
14a8 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
14aa : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
14ac : 48 > pha ;use stack to load status
14ad : 28 > plp
14ae : ac1702 ldy abs1
14b1 : 08 php ;test stores do not alter flags
14b2 : 98 tya
14b3 : 49c3 eor #$c3
14b5 : a8 tay
14b6 : 28 plp
14b7 : 840c sty zpt
14b9 : 08 php ;flags after load/store sequence
14ba : 49c3 eor #$c3
14bc : a8 tay
14bd : c513 cmp zp1 ;test result
trap_ne
14bf : d0fe > bne * ;failed not equal (non zero)
14c1 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
14c2 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
14c4 : cd1c02 cmp fLDx ;test flags
trap_ne
14c7 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
14c9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
14cb : 48 > pha ;use stack to load status
14cc : 28 > plp
14cd : ac1802 ldy abs1+1
14d0 : 08 php ;test stores do not alter flags
14d1 : 98 tya
14d2 : 49c3 eor #$c3
14d4 : a8 tay
14d5 : 28 plp
14d6 : 840d sty zpt+1
14d8 : 08 php ;flags after load/store sequence
14d9 : 49c3 eor #$c3
14db : a8 tay
14dc : c514 cmp zp1+1 ;test result
trap_ne
14de : d0fe > bne * ;failed not equal (non zero)
14e0 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
14e1 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
14e3 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
14e6 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
14e8 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
14ea : 48 > pha ;use stack to load status
14eb : 28 > plp
14ec : ac1902 ldy abs1+2
14ef : 08 php ;test stores do not alter flags
14f0 : 98 tya
14f1 : 49c3 eor #$c3
14f3 : a8 tay
14f4 : 28 plp
14f5 : 840e sty zpt+2
14f7 : 08 php ;flags after load/store sequence
14f8 : 49c3 eor #$c3
14fa : a8 tay
14fb : c515 cmp zp1+2 ;test result
trap_ne
14fd : d0fe > bne * ;failed not equal (non zero)
14ff : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1500 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1502 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1505 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1507 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1509 : 48 > pha ;use stack to load status
150a : 28 > plp
150b : ac1a02 ldy abs1+3
150e : 08 php ;test stores do not alter flags
150f : 98 tya
1510 : 49c3 eor #$c3
1512 : a8 tay
1513 : 28 plp
1514 : 840f sty zpt+3
1516 : 08 php ;flags after load/store sequence
1517 : 49c3 eor #$c3
1519 : a8 tay
151a : c516 cmp zp1+3 ;test result
trap_ne
151c : d0fe > bne * ;failed not equal (non zero)
151e : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
151f : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1521 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1524 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1526 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1528 : 48 > pha ;use stack to load status
1529 : 28 > plp
152a : a0c3 ldy #$c3
152c : 08 php
152d : cc1702 cpy abs1 ;test result
trap_ne
1530 : d0fe > bne * ;failed not equal (non zero)
1532 : 68 pla ;load status
eor_flag 0
1533 : 4930 > eor #0|fao ;invert expected flags + always on bits
1535 : cd1c02 cmp fLDx ;test flags
trap_ne
1538 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
153a : a900 > lda #0 ;allow test to change I-flag (no mask)
>
153c : 48 > pha ;use stack to load status
153d : 28 > plp
153e : a082 ldy #$82
1540 : 08 php
1541 : cc1802 cpy abs1+1 ;test result
trap_ne
1544 : d0fe > bne * ;failed not equal (non zero)
1546 : 68 pla ;load status
eor_flag 0
1547 : 4930 > eor #0|fao ;invert expected flags + always on bits
1549 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
154c : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
154e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1550 : 48 > pha ;use stack to load status
1551 : 28 > plp
1552 : a041 ldy #$41
1554 : 08 php
1555 : cc1902 cpy abs1+2 ;test result
trap_ne
1558 : d0fe > bne * ;failed not equal (non zero)
155a : 68 pla ;load status
eor_flag 0
155b : 4930 > eor #0|fao ;invert expected flags + always on bits
155d : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1560 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1562 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1564 : 48 > pha ;use stack to load status
1565 : 28 > plp
1566 : a000 ldy #0
1568 : 08 php
1569 : cc1a02 cpy abs1+3 ;test result
trap_ne
156c : d0fe > bne * ;failed not equal (non zero)
156e : 68 pla ;load status
eor_flag 0
156f : 4930 > eor #0|fao ;invert expected flags + always on bits
1571 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1574 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1576 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1578 : 48 > pha ;use stack to load status
1579 : 28 > plp
157a : a0c3 ldy #$c3
157c : 08 php
157d : cc1702 cpy abs1 ;test result
trap_ne
1580 : d0fe > bne * ;failed not equal (non zero)
1582 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1583 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1585 : cd1c02 cmp fLDx ;test flags
trap_ne
1588 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
158a : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
158c : 48 > pha ;use stack to load status
158d : 28 > plp
158e : a082 ldy #$82
1590 : 08 php
1591 : cc1802 cpy abs1+1 ;test result
trap_ne
1594 : d0fe > bne * ;failed not equal (non zero)
1596 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1597 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1599 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
159c : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
159e : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
15a0 : 48 > pha ;use stack to load status
15a1 : 28 > plp
15a2 : a041 ldy #$41
15a4 : 08 php
15a5 : cc1902 cpy abs1+2 ;test result
trap_ne
15a8 : d0fe > bne * ;failed not equal (non zero)
15aa : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
15ab : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
15ad : cd1e02 cmp fLDx+2 ;test flags
trap_ne
15b0 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
15b2 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
15b4 : 48 > pha ;use stack to load status
15b5 : 28 > plp
15b6 : a000 ldy #0
15b8 : 08 php
15b9 : cc1a02 cpy abs1+3 ;test result
trap_ne
15bc : d0fe > bne * ;failed not equal (non zero)
15be : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
15bf : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
15c1 : cd1f02 cmp fLDx+3 ;test flags
trap_ne
15c4 : d0fe > bne * ;failed not equal (non zero)
15c6 : a000 ldy #0
15c8 : a50c lda zpt
15ca : 49c3 eor #$c3
15cc : c513 cmp zp1
trap_ne ;store to zp data
15ce : d0fe > bne * ;failed not equal (non zero)
15d0 : 840c sty zpt ;clear
15d2 : ad0302 lda abst
15d5 : 49c3 eor #$c3
15d7 : cd1702 cmp abs1
trap_ne ;store to abs data
15da : d0fe > bne * ;failed not equal (non zero)
15dc : 8c0302 sty abst ;clear
15df : a50d lda zpt+1
15e1 : 49c3 eor #$c3
15e3 : c514 cmp zp1+1
trap_ne ;store to zp+1 data
15e5 : d0fe > bne * ;failed not equal (non zero)
15e7 : 840d sty zpt+1 ;clear
15e9 : ad0402 lda abst+1
15ec : 49c3 eor #$c3
15ee : cd1802 cmp abs1+1
trap_ne ;store to abs+1 data
15f1 : d0fe > bne * ;failed not equal (non zero)
15f3 : 8c0402 sty abst+1 ;clear
15f6 : a50e lda zpt+2
15f8 : 49c3 eor #$c3
15fa : c515 cmp zp1+2
trap_ne ;store to zp+2 data
15fc : d0fe > bne * ;failed not equal (non zero)
15fe : 840e sty zpt+2 ;clear
1600 : ad0502 lda abst+2
1603 : 49c3 eor #$c3
1605 : cd1902 cmp abs1+2
trap_ne ;store to abs+2 data
1608 : d0fe > bne * ;failed not equal (non zero)
160a : 8c0502 sty abst+2 ;clear
160d : a50f lda zpt+3
160f : 49c3 eor #$c3
1611 : c516 cmp zp1+3
trap_ne ;store to zp+3 data
1613 : d0fe > bne * ;failed not equal (non zero)
1615 : 840f sty zpt+3 ;clear
1617 : ad0602 lda abst+3
161a : 49c3 eor #$c3
161c : cd1a02 cmp abs1+3
trap_ne ;store to abs+3 data
161f : d0fe > bne * ;failed not equal (non zero)
1621 : 8c0602 sty abst+3 ;clear
next_test
1624 : ad0002 > lda test_case ;previous test
1627 : c914 > cmp #test_num
> trap_ne ;test is out of sequence
1629 : d0fe > bne * ;failed not equal (non zero)
>
0015 = >test_num = test_num + 1
162b : a915 > lda #test_num ;*** next tests' number
162d : 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
1630 : a203 ldx #3
1632 : tldax
set_stat 0
> load_flag 0
1632 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1634 : 48 > pha ;use stack to load status
1635 : 28 > plp
1636 : b513 lda zp1,x
1638 : 08 php ;test stores do not alter flags
1639 : 49c3 eor #$c3
163b : 28 plp
163c : 9d0302 sta abst,x
163f : 08 php ;flags after load/store sequence
1640 : 49c3 eor #$c3
1642 : dd1702 cmp abs1,x ;test result
trap_ne
1645 : d0fe > bne * ;failed not equal (non zero)
1647 : 68 pla ;load status
eor_flag 0
1648 : 4930 > eor #0|fao ;invert expected flags + always on bits
164a : dd1c02 cmp fLDx,x ;test flags
trap_ne
164d : d0fe > bne * ;failed not equal (non zero)
164f : ca dex
1650 : 10e0 bpl tldax
1652 : a203 ldx #3
1654 : tldax1
set_stat $ff
> load_flag $ff
1654 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1656 : 48 > pha ;use stack to load status
1657 : 28 > plp
1658 : b513 lda zp1,x
165a : 08 php ;test stores do not alter flags
165b : 49c3 eor #$c3
165d : 28 plp
165e : 9d0302 sta abst,x
1661 : 08 php ;flags after load/store sequence
1662 : 49c3 eor #$c3
1664 : dd1702 cmp abs1,x ;test result
trap_ne
1667 : d0fe > bne * ;failed not equal (non zero)
1669 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
166a : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
166c : dd1c02 cmp fLDx,x ;test flags
trap_ne
166f : d0fe > bne * ;failed not equal (non zero)
1671 : ca dex
1672 : 10e0 bpl tldax1
1674 : a203 ldx #3
1676 : tldax2
set_stat 0
> load_flag 0
1676 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1678 : 48 > pha ;use stack to load status
1679 : 28 > plp
167a : bd1702 lda abs1,x
167d : 08 php ;test stores do not alter flags
167e : 49c3 eor #$c3
1680 : 28 plp
1681 : 950c sta zpt,x
1683 : 08 php ;flags after load/store sequence
1684 : 49c3 eor #$c3
1686 : d513 cmp zp1,x ;test result
trap_ne
1688 : d0fe > bne * ;failed not equal (non zero)
168a : 68 pla ;load status
eor_flag 0
168b : 4930 > eor #0|fao ;invert expected flags + always on bits
168d : dd1c02 cmp fLDx,x ;test flags
trap_ne
1690 : d0fe > bne * ;failed not equal (non zero)
1692 : ca dex
1693 : 10e1 bpl tldax2
1695 : a203 ldx #3
1697 : tldax3
set_stat $ff
> load_flag $ff
1697 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1699 : 48 > pha ;use stack to load status
169a : 28 > plp
169b : bd1702 lda abs1,x
169e : 08 php ;test stores do not alter flags
169f : 49c3 eor #$c3
16a1 : 28 plp
16a2 : 950c sta zpt,x
16a4 : 08 php ;flags after load/store sequence
16a5 : 49c3 eor #$c3
16a7 : d513 cmp zp1,x ;test result
trap_ne
16a9 : d0fe > bne * ;failed not equal (non zero)
16ab : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
16ac : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
16ae : dd1c02 cmp fLDx,x ;test flags
trap_ne
16b1 : d0fe > bne * ;failed not equal (non zero)
16b3 : ca dex
16b4 : 10e1 bpl tldax3
16b6 : a203 ldx #3 ;testing store result
16b8 : a000 ldy #0
16ba : b50c tstax lda zpt,x
16bc : 49c3 eor #$c3
16be : d513 cmp zp1,x
trap_ne ;store to zp,x data
16c0 : d0fe > bne * ;failed not equal (non zero)
16c2 : 940c sty zpt,x ;clear
16c4 : bd0302 lda abst,x
16c7 : 49c3 eor #$c3
16c9 : dd1702 cmp abs1,x
trap_ne ;store to abs,x data
16cc : d0fe > bne * ;failed not equal (non zero)
16ce : 8a txa
16cf : 9d0302 sta abst,x ;clear
16d2 : ca dex
16d3 : 10e5 bpl tstax
next_test
16d5 : ad0002 > lda test_case ;previous test
16d8 : c915 > cmp #test_num
> trap_ne ;test is out of sequence
16da : d0fe > bne * ;failed not equal (non zero)
>
0016 = >test_num = test_num + 1
16dc : a916 > lda #test_num ;*** next tests' number
16de : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; LDA / STA - (zp),y / abs,y / (zp,x)
16e1 : a003 ldy #3
16e3 : tlday
set_stat 0
> load_flag 0
16e3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
16e5 : 48 > pha ;use stack to load status
16e6 : 28 > plp
16e7 : b124 lda (ind1),y
16e9 : 08 php ;test stores do not alter flags
16ea : 49c3 eor #$c3
16ec : 28 plp
16ed : 990302 sta abst,y
16f0 : 08 php ;flags after load/store sequence
16f1 : 49c3 eor #$c3
16f3 : d91702 cmp abs1,y ;test result
trap_ne
16f6 : d0fe > bne * ;failed not equal (non zero)
16f8 : 68 pla ;load status
eor_flag 0
16f9 : 4930 > eor #0|fao ;invert expected flags + always on bits
16fb : d91c02 cmp fLDx,y ;test flags
trap_ne
16fe : d0fe > bne * ;failed not equal (non zero)
1700 : 88 dey
1701 : 10e0 bpl tlday
1703 : a003 ldy #3
1705 : tlday1
set_stat $ff
> load_flag $ff
1705 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1707 : 48 > pha ;use stack to load status
1708 : 28 > plp
1709 : b124 lda (ind1),y
170b : 08 php ;test stores do not alter flags
170c : 49c3 eor #$c3
170e : 28 plp
170f : 990302 sta abst,y
1712 : 08 php ;flags after load/store sequence
1713 : 49c3 eor #$c3
1715 : d91702 cmp abs1,y ;test result
trap_ne
1718 : d0fe > bne * ;failed not equal (non zero)
171a : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
171b : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
171d : d91c02 cmp fLDx,y ;test flags
trap_ne
1720 : d0fe > bne * ;failed not equal (non zero)
1722 : 88 dey
1723 : 10e0 bpl tlday1
1725 : a003 ldy #3 ;testing store result
1727 : a200 ldx #0
1729 : b90302 tstay lda abst,y
172c : 49c3 eor #$c3
172e : d91702 cmp abs1,y
trap_ne ;store to abs data
1731 : d0fe > bne * ;failed not equal (non zero)
1733 : 8a txa
1734 : 990302 sta abst,y ;clear
1737 : 88 dey
1738 : 10ef bpl tstay
173a : a003 ldy #3
173c : tlday2
set_stat 0
> load_flag 0
173c : a900 > lda #0 ;allow test to change I-flag (no mask)
>
173e : 48 > pha ;use stack to load status
173f : 28 > plp
1740 : b91702 lda abs1,y
1743 : 08 php ;test stores do not alter flags
1744 : 49c3 eor #$c3
1746 : 28 plp
1747 : 9130 sta (indt),y
1749 : 08 php ;flags after load/store sequence
174a : 49c3 eor #$c3
174c : d124 cmp (ind1),y ;test result
trap_ne
174e : d0fe > bne * ;failed not equal (non zero)
1750 : 68 pla ;load status
eor_flag 0
1751 : 4930 > eor #0|fao ;invert expected flags + always on bits
1753 : d91c02 cmp fLDx,y ;test flags
trap_ne
1756 : d0fe > bne * ;failed not equal (non zero)
1758 : 88 dey
1759 : 10e1 bpl tlday2
175b : a003 ldy #3
175d : tlday3
set_stat $ff
> load_flag $ff
175d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
175f : 48 > pha ;use stack to load status
1760 : 28 > plp
1761 : b91702 lda abs1,y
1764 : 08 php ;test stores do not alter flags
1765 : 49c3 eor #$c3
1767 : 28 plp
1768 : 9130 sta (indt),y
176a : 08 php ;flags after load/store sequence
176b : 49c3 eor #$c3
176d : d124 cmp (ind1),y ;test result
trap_ne
176f : d0fe > bne * ;failed not equal (non zero)
1771 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1772 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1774 : d91c02 cmp fLDx,y ;test flags
trap_ne
1777 : d0fe > bne * ;failed not equal (non zero)
1779 : 88 dey
177a : 10e1 bpl tlday3
177c : a003 ldy #3 ;testing store result
177e : a200 ldx #0
1780 : b90302 tstay1 lda abst,y
1783 : 49c3 eor #$c3
1785 : d91702 cmp abs1,y
trap_ne ;store to abs data
1788 : d0fe > bne * ;failed not equal (non zero)
178a : 8a txa
178b : 990302 sta abst,y ;clear
178e : 88 dey
178f : 10ef bpl tstay1
1791 : a206 ldx #6
1793 : a003 ldy #3
1795 : tldax4
set_stat 0
> load_flag 0
1795 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1797 : 48 > pha ;use stack to load status
1798 : 28 > plp
1799 : a124 lda (ind1,x)
179b : 08 php ;test stores do not alter flags
179c : 49c3 eor #$c3
179e : 28 plp
179f : 8130 sta (indt,x)
17a1 : 08 php ;flags after load/store sequence
17a2 : 49c3 eor #$c3
17a4 : d91702 cmp abs1,y ;test result
trap_ne
17a7 : d0fe > bne * ;failed not equal (non zero)
17a9 : 68 pla ;load status
eor_flag 0
17aa : 4930 > eor #0|fao ;invert expected flags + always on bits
17ac : d91c02 cmp fLDx,y ;test flags
trap_ne
17af : d0fe > bne * ;failed not equal (non zero)
17b1 : ca dex
17b2 : ca dex
17b3 : 88 dey
17b4 : 10df bpl tldax4
17b6 : a206 ldx #6
17b8 : a003 ldy #3
17ba : tldax5
set_stat $ff
> load_flag $ff
17ba : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
17bc : 48 > pha ;use stack to load status
17bd : 28 > plp
17be : a124 lda (ind1,x)
17c0 : 08 php ;test stores do not alter flags
17c1 : 49c3 eor #$c3
17c3 : 28 plp
17c4 : 8130 sta (indt,x)
17c6 : 08 php ;flags after load/store sequence
17c7 : 49c3 eor #$c3
17c9 : d91702 cmp abs1,y ;test result
trap_ne
17cc : d0fe > bne * ;failed not equal (non zero)
17ce : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
17cf : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
17d1 : d91c02 cmp fLDx,y ;test flags
trap_ne
17d4 : d0fe > bne * ;failed not equal (non zero)
17d6 : ca dex
17d7 : ca dex
17d8 : 88 dey
17d9 : 10df bpl tldax5
17db : a003 ldy #3 ;testing store result
17dd : a200 ldx #0
17df : b90302 tstay2 lda abst,y
17e2 : 49c3 eor #$c3
17e4 : d91702 cmp abs1,y
trap_ne ;store to abs data
17e7 : d0fe > bne * ;failed not equal (non zero)
17e9 : 8a txa
17ea : 990302 sta abst,y ;clear
17ed : 88 dey
17ee : 10ef bpl tstay2
next_test
17f0 : ad0002 > lda test_case ;previous test
17f3 : c916 > cmp #test_num
> trap_ne ;test is out of sequence
17f5 : d0fe > bne * ;failed not equal (non zero)
>
0017 = >test_num = test_num + 1
17f7 : a917 > lda #test_num ;*** next tests' number
17f9 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; indexed wraparound test (only zp should wrap)
17fc : a2fd ldx #3+$fa
17fe : b519 tldax6 lda zp1-$fa&$ff,x ;wrap on indexed zp
1800 : 9d0901 sta abst-$fa,x ;no STX abs,x!
1803 : ca dex
1804 : e0fa cpx #$fa
1806 : b0f6 bcs tldax6
1808 : a2fd ldx #3+$fa
180a : bd1d01 tldax7 lda abs1-$fa,x ;no wrap on indexed abs
180d : 9512 sta zpt-$fa&$ff,x
180f : ca dex
1810 : e0fa cpx #$fa
1812 : b0f6 bcs tldax7
1814 : a203 ldx #3 ;testing wraparound result
1816 : a000 ldy #0
1818 : b50c tstax1 lda zpt,x
181a : d513 cmp zp1,x
trap_ne ;store to zp,x data
181c : d0fe > bne * ;failed not equal (non zero)
181e : 940c sty zpt,x ;clear
1820 : bd0302 lda abst,x
1823 : dd1702 cmp abs1,x
trap_ne ;store to abs,x data
1826 : d0fe > bne * ;failed not equal (non zero)
1828 : 8a txa
1829 : 9d0302 sta abst,x ;clear
182c : ca dex
182d : 10e9 bpl tstax1
182f : a0fb ldy #3+$f8
1831 : a2fe ldx #6+$f8
1833 : a12c tlday4 lda (ind1-$f8&$ff,x) ;wrap on indexed zp indirect
1835 : 990b01 sta abst-$f8,y
1838 : ca dex
1839 : ca dex
183a : 88 dey
183b : c0f8 cpy #$f8
183d : b0f4 bcs tlday4
183f : a003 ldy #3 ;testing wraparound result
1841 : a200 ldx #0
1843 : b90302 tstay4 lda abst,y
1846 : d91702 cmp abs1,y
trap_ne ;store to abs data
1849 : d0fe > bne * ;failed not equal (non zero)
184b : 8a txa
184c : 990302 sta abst,y ;clear
184f : 88 dey
1850 : 10f1 bpl tstay4
1852 : a0fb ldy #3+$f8
1854 : b91f01 tlday5 lda abs1-$f8,y ;no wrap on indexed abs
1857 : 9138 sta (inwt),y
1859 : 88 dey
185a : c0f8 cpy #$f8
185c : b0f6 bcs tlday5
185e : a003 ldy #3 ;testing wraparound result
1860 : a200 ldx #0
1862 : b90302 tstay5 lda abst,y
1865 : d91702 cmp abs1,y
trap_ne ;store to abs data
1868 : d0fe > bne * ;failed not equal (non zero)
186a : 8a txa
186b : 990302 sta abst,y ;clear
186e : 88 dey
186f : 10f1 bpl tstay5
1871 : a0fb ldy #3+$f8
1873 : a2fe ldx #6+$f8
1875 : b12e tlday6 lda (inw1),y ;no wrap on zp indirect indexed
1877 : 8138 sta (indt-$f8&$ff,x)
1879 : ca dex
187a : ca dex
187b : 88 dey
187c : c0f8 cpy #$f8
187e : b0f5 bcs tlday6
1880 : a003 ldy #3 ;testing wraparound result
1882 : a200 ldx #0
1884 : b90302 tstay6 lda abst,y
1887 : d91702 cmp abs1,y
trap_ne ;store to abs data
188a : d0fe > bne * ;failed not equal (non zero)
188c : 8a txa
188d : 990302 sta abst,y ;clear
1890 : 88 dey
1891 : 10f1 bpl tstay6
next_test
1893 : ad0002 > lda test_case ;previous test
1896 : c917 > cmp #test_num
> trap_ne ;test is out of sequence
1898 : d0fe > bne * ;failed not equal (non zero)
>
0018 = >test_num = test_num + 1
189a : a918 > lda #test_num ;*** next tests' number
189c : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; LDA / STA - zp / abs / #
set_stat 0
> load_flag 0
189f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
18a1 : 48 > pha ;use stack to load status
18a2 : 28 > plp
18a3 : a513 lda zp1
18a5 : 08 php ;test stores do not alter flags
18a6 : 49c3 eor #$c3
18a8 : 28 plp
18a9 : 8d0302 sta abst
18ac : 08 php ;flags after load/store sequence
18ad : 49c3 eor #$c3
18af : c9c3 cmp #$c3 ;test result
trap_ne
18b1 : d0fe > bne * ;failed not equal (non zero)
18b3 : 68 pla ;load status
eor_flag 0
18b4 : 4930 > eor #0|fao ;invert expected flags + always on bits
18b6 : cd1c02 cmp fLDx ;test flags
trap_ne
18b9 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
18bb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
18bd : 48 > pha ;use stack to load status
18be : 28 > plp
18bf : a514 lda zp1+1
18c1 : 08 php ;test stores do not alter flags
18c2 : 49c3 eor #$c3
18c4 : 28 plp
18c5 : 8d0402 sta abst+1
18c8 : 08 php ;flags after load/store sequence
18c9 : 49c3 eor #$c3
18cb : c982 cmp #$82 ;test result
trap_ne
18cd : d0fe > bne * ;failed not equal (non zero)
18cf : 68 pla ;load status
eor_flag 0
18d0 : 4930 > eor #0|fao ;invert expected flags + always on bits
18d2 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
18d5 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
18d7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
18d9 : 48 > pha ;use stack to load status
18da : 28 > plp
18db : a515 lda zp1+2
18dd : 08 php ;test stores do not alter flags
18de : 49c3 eor #$c3
18e0 : 28 plp
18e1 : 8d0502 sta abst+2
18e4 : 08 php ;flags after load/store sequence
18e5 : 49c3 eor #$c3
18e7 : c941 cmp #$41 ;test result
trap_ne
18e9 : d0fe > bne * ;failed not equal (non zero)
18eb : 68 pla ;load status
eor_flag 0
18ec : 4930 > eor #0|fao ;invert expected flags + always on bits
18ee : cd1e02 cmp fLDx+2 ;test flags
trap_ne
18f1 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
18f3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
18f5 : 48 > pha ;use stack to load status
18f6 : 28 > plp
18f7 : a516 lda zp1+3
18f9 : 08 php ;test stores do not alter flags
18fa : 49c3 eor #$c3
18fc : 28 plp
18fd : 8d0602 sta abst+3
1900 : 08 php ;flags after load/store sequence
1901 : 49c3 eor #$c3
1903 : c900 cmp #0 ;test result
trap_ne
1905 : d0fe > bne * ;failed not equal (non zero)
1907 : 68 pla ;load status
eor_flag 0
1908 : 4930 > eor #0|fao ;invert expected flags + always on bits
190a : cd1f02 cmp fLDx+3 ;test flags
trap_ne
190d : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
190f : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1911 : 48 > pha ;use stack to load status
1912 : 28 > plp
1913 : a513 lda zp1
1915 : 08 php ;test stores do not alter flags
1916 : 49c3 eor #$c3
1918 : 28 plp
1919 : 8d0302 sta abst
191c : 08 php ;flags after load/store sequence
191d : 49c3 eor #$c3
191f : c9c3 cmp #$c3 ;test result
trap_ne
1921 : d0fe > bne * ;failed not equal (non zero)
1923 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1924 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1926 : cd1c02 cmp fLDx ;test flags
trap_ne
1929 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
192b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
192d : 48 > pha ;use stack to load status
192e : 28 > plp
192f : a514 lda zp1+1
1931 : 08 php ;test stores do not alter flags
1932 : 49c3 eor #$c3
1934 : 28 plp
1935 : 8d0402 sta abst+1
1938 : 08 php ;flags after load/store sequence
1939 : 49c3 eor #$c3
193b : c982 cmp #$82 ;test result
trap_ne
193d : d0fe > bne * ;failed not equal (non zero)
193f : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1940 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1942 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1945 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1947 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1949 : 48 > pha ;use stack to load status
194a : 28 > plp
194b : a515 lda zp1+2
194d : 08 php ;test stores do not alter flags
194e : 49c3 eor #$c3
1950 : 28 plp
1951 : 8d0502 sta abst+2
1954 : 08 php ;flags after load/store sequence
1955 : 49c3 eor #$c3
1957 : c941 cmp #$41 ;test result
trap_ne
1959 : d0fe > bne * ;failed not equal (non zero)
195b : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
195c : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
195e : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1961 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1963 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1965 : 48 > pha ;use stack to load status
1966 : 28 > plp
1967 : a516 lda zp1+3
1969 : 08 php ;test stores do not alter flags
196a : 49c3 eor #$c3
196c : 28 plp
196d : 8d0602 sta abst+3
1970 : 08 php ;flags after load/store sequence
1971 : 49c3 eor #$c3
1973 : c900 cmp #0 ;test result
trap_ne
1975 : d0fe > bne * ;failed not equal (non zero)
1977 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1978 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
197a : cd1f02 cmp fLDx+3 ;test flags
trap_ne
197d : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
197f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1981 : 48 > pha ;use stack to load status
1982 : 28 > plp
1983 : ad1702 lda abs1
1986 : 08 php ;test stores do not alter flags
1987 : 49c3 eor #$c3
1989 : 28 plp
198a : 850c sta zpt
198c : 08 php ;flags after load/store sequence
198d : 49c3 eor #$c3
198f : c513 cmp zp1 ;test result
trap_ne
1991 : d0fe > bne * ;failed not equal (non zero)
1993 : 68 pla ;load status
eor_flag 0
1994 : 4930 > eor #0|fao ;invert expected flags + always on bits
1996 : cd1c02 cmp fLDx ;test flags
trap_ne
1999 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
199b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
199d : 48 > pha ;use stack to load status
199e : 28 > plp
199f : ad1802 lda abs1+1
19a2 : 08 php ;test stores do not alter flags
19a3 : 49c3 eor #$c3
19a5 : 28 plp
19a6 : 850d sta zpt+1
19a8 : 08 php ;flags after load/store sequence
19a9 : 49c3 eor #$c3
19ab : c514 cmp zp1+1 ;test result
trap_ne
19ad : d0fe > bne * ;failed not equal (non zero)
19af : 68 pla ;load status
eor_flag 0
19b0 : 4930 > eor #0|fao ;invert expected flags + always on bits
19b2 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
19b5 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
19b7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
19b9 : 48 > pha ;use stack to load status
19ba : 28 > plp
19bb : ad1902 lda abs1+2
19be : 08 php ;test stores do not alter flags
19bf : 49c3 eor #$c3
19c1 : 28 plp
19c2 : 850e sta zpt+2
19c4 : 08 php ;flags after load/store sequence
19c5 : 49c3 eor #$c3
19c7 : c515 cmp zp1+2 ;test result
trap_ne
19c9 : d0fe > bne * ;failed not equal (non zero)
19cb : 68 pla ;load status
eor_flag 0
19cc : 4930 > eor #0|fao ;invert expected flags + always on bits
19ce : cd1e02 cmp fLDx+2 ;test flags
trap_ne
19d1 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
19d3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
19d5 : 48 > pha ;use stack to load status
19d6 : 28 > plp
19d7 : ad1a02 lda abs1+3
19da : 08 php ;test stores do not alter flags
19db : 49c3 eor #$c3
19dd : 28 plp
19de : 850f sta zpt+3
19e0 : 08 php ;flags after load/store sequence
19e1 : 49c3 eor #$c3
19e3 : c516 cmp zp1+3 ;test result
trap_ne
19e5 : d0fe > bne * ;failed not equal (non zero)
19e7 : 68 pla ;load status
eor_flag 0
19e8 : 4930 > eor #0|fao ;invert expected flags + always on bits
19ea : cd1f02 cmp fLDx+3 ;test flags
trap_ne
19ed : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
19ef : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
19f1 : 48 > pha ;use stack to load status
19f2 : 28 > plp
19f3 : ad1702 lda abs1
19f6 : 08 php ;test stores do not alter flags
19f7 : 49c3 eor #$c3
19f9 : 28 plp
19fa : 850c sta zpt
19fc : 08 php ;flags after load/store sequence
19fd : 49c3 eor #$c3
19ff : c513 cmp zp1 ;test result
trap_ne
1a01 : d0fe > bne * ;failed not equal (non zero)
1a03 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1a04 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1a06 : cd1c02 cmp fLDx ;test flags
trap_ne
1a09 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1a0b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1a0d : 48 > pha ;use stack to load status
1a0e : 28 > plp
1a0f : ad1802 lda abs1+1
1a12 : 08 php ;test stores do not alter flags
1a13 : 49c3 eor #$c3
1a15 : 28 plp
1a16 : 850d sta zpt+1
1a18 : 08 php ;flags after load/store sequence
1a19 : 49c3 eor #$c3
1a1b : c514 cmp zp1+1 ;test result
trap_ne
1a1d : d0fe > bne * ;failed not equal (non zero)
1a1f : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1a20 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1a22 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1a25 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1a27 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1a29 : 48 > pha ;use stack to load status
1a2a : 28 > plp
1a2b : ad1902 lda abs1+2
1a2e : 08 php ;test stores do not alter flags
1a2f : 49c3 eor #$c3
1a31 : 28 plp
1a32 : 850e sta zpt+2
1a34 : 08 php ;flags after load/store sequence
1a35 : 49c3 eor #$c3
1a37 : c515 cmp zp1+2 ;test result
trap_ne
1a39 : d0fe > bne * ;failed not equal (non zero)
1a3b : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1a3c : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1a3e : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1a41 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1a43 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1a45 : 48 > pha ;use stack to load status
1a46 : 28 > plp
1a47 : ad1a02 lda abs1+3
1a4a : 08 php ;test stores do not alter flags
1a4b : 49c3 eor #$c3
1a4d : 28 plp
1a4e : 850f sta zpt+3
1a50 : 08 php ;flags after load/store sequence
1a51 : 49c3 eor #$c3
1a53 : c516 cmp zp1+3 ;test result
trap_ne
1a55 : d0fe > bne * ;failed not equal (non zero)
1a57 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1a58 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1a5a : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1a5d : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1a5f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1a61 : 48 > pha ;use stack to load status
1a62 : 28 > plp
1a63 : a9c3 lda #$c3
1a65 : 08 php
1a66 : cd1702 cmp abs1 ;test result
trap_ne
1a69 : d0fe > bne * ;failed not equal (non zero)
1a6b : 68 pla ;load status
eor_flag 0
1a6c : 4930 > eor #0|fao ;invert expected flags + always on bits
1a6e : cd1c02 cmp fLDx ;test flags
trap_ne
1a71 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1a73 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1a75 : 48 > pha ;use stack to load status
1a76 : 28 > plp
1a77 : a982 lda #$82
1a79 : 08 php
1a7a : cd1802 cmp abs1+1 ;test result
trap_ne
1a7d : d0fe > bne * ;failed not equal (non zero)
1a7f : 68 pla ;load status
eor_flag 0
1a80 : 4930 > eor #0|fao ;invert expected flags + always on bits
1a82 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1a85 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1a87 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1a89 : 48 > pha ;use stack to load status
1a8a : 28 > plp
1a8b : a941 lda #$41
1a8d : 08 php
1a8e : cd1902 cmp abs1+2 ;test result
trap_ne
1a91 : d0fe > bne * ;failed not equal (non zero)
1a93 : 68 pla ;load status
eor_flag 0
1a94 : 4930 > eor #0|fao ;invert expected flags + always on bits
1a96 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1a99 : d0fe > bne * ;failed not equal (non zero)
set_stat 0
> load_flag 0
1a9b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1a9d : 48 > pha ;use stack to load status
1a9e : 28 > plp
1a9f : a900 lda #0
1aa1 : 08 php
1aa2 : cd1a02 cmp abs1+3 ;test result
trap_ne
1aa5 : d0fe > bne * ;failed not equal (non zero)
1aa7 : 68 pla ;load status
eor_flag 0
1aa8 : 4930 > eor #0|fao ;invert expected flags + always on bits
1aaa : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1aad : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1aaf : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1ab1 : 48 > pha ;use stack to load status
1ab2 : 28 > plp
1ab3 : a9c3 lda #$c3
1ab5 : 08 php
1ab6 : cd1702 cmp abs1 ;test result
trap_ne
1ab9 : d0fe > bne * ;failed not equal (non zero)
1abb : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1abc : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1abe : cd1c02 cmp fLDx ;test flags
trap_ne
1ac1 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1ac3 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1ac5 : 48 > pha ;use stack to load status
1ac6 : 28 > plp
1ac7 : a982 lda #$82
1ac9 : 08 php
1aca : cd1802 cmp abs1+1 ;test result
trap_ne
1acd : d0fe > bne * ;failed not equal (non zero)
1acf : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1ad0 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1ad2 : cd1d02 cmp fLDx+1 ;test flags
trap_ne
1ad5 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1ad7 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1ad9 : 48 > pha ;use stack to load status
1ada : 28 > plp
1adb : a941 lda #$41
1add : 08 php
1ade : cd1902 cmp abs1+2 ;test result
trap_ne
1ae1 : d0fe > bne * ;failed not equal (non zero)
1ae3 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1ae4 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1ae6 : cd1e02 cmp fLDx+2 ;test flags
trap_ne
1ae9 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
1aeb : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1aed : 48 > pha ;use stack to load status
1aee : 28 > plp
1aef : a900 lda #0
1af1 : 08 php
1af2 : cd1a02 cmp abs1+3 ;test result
trap_ne
1af5 : d0fe > bne * ;failed not equal (non zero)
1af7 : 68 pla ;load status
eor_flag lo~fnz ;mask bits not altered
1af8 : 497d > eor #lo~fnz |fao ;invert expected flags + always on bits
1afa : cd1f02 cmp fLDx+3 ;test flags
trap_ne
1afd : d0fe > bne * ;failed not equal (non zero)
1aff : a200 ldx #0
1b01 : a50c lda zpt
1b03 : 49c3 eor #$c3
1b05 : c513 cmp zp1
trap_ne ;store to zp data
1b07 : d0fe > bne * ;failed not equal (non zero)
1b09 : 860c stx zpt ;clear
1b0b : ad0302 lda abst
1b0e : 49c3 eor #$c3
1b10 : cd1702 cmp abs1
trap_ne ;store to abs data
1b13 : d0fe > bne * ;failed not equal (non zero)
1b15 : 8e0302 stx abst ;clear
1b18 : a50d lda zpt+1
1b1a : 49c3 eor #$c3
1b1c : c514 cmp zp1+1
trap_ne ;store to zp data
1b1e : d0fe > bne * ;failed not equal (non zero)
1b20 : 860d stx zpt+1 ;clear
1b22 : ad0402 lda abst+1
1b25 : 49c3 eor #$c3
1b27 : cd1802 cmp abs1+1
trap_ne ;store to abs data
1b2a : d0fe > bne * ;failed not equal (non zero)
1b2c : 8e0402 stx abst+1 ;clear
1b2f : a50e lda zpt+2
1b31 : 49c3 eor #$c3
1b33 : c515 cmp zp1+2
trap_ne ;store to zp data
1b35 : d0fe > bne * ;failed not equal (non zero)
1b37 : 860e stx zpt+2 ;clear
1b39 : ad0502 lda abst+2
1b3c : 49c3 eor #$c3
1b3e : cd1902 cmp abs1+2
trap_ne ;store to abs data
1b41 : d0fe > bne * ;failed not equal (non zero)
1b43 : 8e0502 stx abst+2 ;clear
1b46 : a50f lda zpt+3
1b48 : 49c3 eor #$c3
1b4a : c516 cmp zp1+3
trap_ne ;store to zp data
1b4c : d0fe > bne * ;failed not equal (non zero)
1b4e : 860f stx zpt+3 ;clear
1b50 : ad0602 lda abst+3
1b53 : 49c3 eor #$c3
1b55 : cd1a02 cmp abs1+3
trap_ne ;store to abs data
1b58 : d0fe > bne * ;failed not equal (non zero)
1b5a : 8e0602 stx abst+3 ;clear
next_test
1b5d : ad0002 > lda test_case ;previous test
1b60 : c918 > cmp #test_num
> trap_ne ;test is out of sequence
1b62 : d0fe > bne * ;failed not equal (non zero)
>
0019 = >test_num = test_num + 1
1b64 : a919 > lda #test_num ;*** next tests' number
1b66 : 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
1b69 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1b6b : 48 > pha ;use stack to load status
1b6c : a9ff > lda #$ff ;precharge accu
1b6e : 28 > plp
1b6f : 2416 bit zp1+3 ;00 - should set Z / clear NV
tst_a $ff,fz
1b71 : 08 > php ;save flags
1b72 : c9ff > cmp #$ff ;test result
> trap_ne
1b74 : d0fe > bne * ;failed not equal (non zero)
>
1b76 : 68 > pla ;load status
1b77 : 48 > pha
> cmp_flag fz
1b78 : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits
>
> trap_ne
1b7a : d0fe > bne * ;failed not equal (non zero)
>
1b7c : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1b7d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1b7f : 48 > pha ;use stack to load status
1b80 : a901 > lda #1 ;precharge accu
1b82 : 28 > plp
1b83 : 2415 bit zp1+2 ;41 - should set V (M6) / clear NZ
tst_a 1,fv
1b85 : 08 > php ;save flags
1b86 : c901 > cmp #1 ;test result
> trap_ne
1b88 : d0fe > bne * ;failed not equal (non zero)
>
1b8a : 68 > pla ;load status
1b8b : 48 > pha
> cmp_flag fv
1b8c : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1b8e : d0fe > bne * ;failed not equal (non zero)
>
1b90 : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1b91 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1b93 : 48 > pha ;use stack to load status
1b94 : a901 > lda #1 ;precharge accu
1b96 : 28 > plp
1b97 : 2414 bit zp1+1 ;82 - should set N (M7) & Z / clear V
tst_a 1,fnz
1b99 : 08 > php ;save flags
1b9a : c901 > cmp #1 ;test result
> trap_ne
1b9c : d0fe > bne * ;failed not equal (non zero)
>
1b9e : 68 > pla ;load status
1b9f : 48 > pha
> cmp_flag fnz
1ba0 : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1ba2 : d0fe > bne * ;failed not equal (non zero)
>
1ba4 : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1ba5 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1ba7 : 48 > pha ;use stack to load status
1ba8 : a901 > lda #1 ;precharge accu
1baa : 28 > plp
1bab : 2413 bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z
tst_a 1,fnv
1bad : 08 > php ;save flags
1bae : c901 > cmp #1 ;test result
> trap_ne
1bb0 : d0fe > bne * ;failed not equal (non zero)
>
1bb2 : 68 > pla ;load status
1bb3 : 48 > pha
> cmp_flag fnv
1bb4 : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1bb6 : d0fe > bne * ;failed not equal (non zero)
>
1bb8 : 28 > plp ;restore status
set_a $ff,$ff
> load_flag $ff
1bb9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1bbb : 48 > pha ;use stack to load status
1bbc : a9ff > lda #$ff ;precharge accu
1bbe : 28 > plp
1bbf : 2416 bit zp1+3 ;00 - should set Z / clear NV
tst_a $ff,~fnv
1bc1 : 08 > php ;save flags
1bc2 : c9ff > cmp #$ff ;test result
> trap_ne
1bc4 : d0fe > bne * ;failed not equal (non zero)
>
1bc6 : 68 > pla ;load status
1bc7 : 48 > pha
> cmp_flag ~fnv
1bc8 : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits
>
> trap_ne
1bca : d0fe > bne * ;failed not equal (non zero)
>
1bcc : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1bcd : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1bcf : 48 > pha ;use stack to load status
1bd0 : a901 > lda #1 ;precharge accu
1bd2 : 28 > plp
1bd3 : 2415 bit zp1+2 ;41 - should set V (M6) / clear NZ
tst_a 1,~fnz
1bd5 : 08 > php ;save flags
1bd6 : c901 > cmp #1 ;test result
> trap_ne
1bd8 : d0fe > bne * ;failed not equal (non zero)
>
1bda : 68 > pla ;load status
1bdb : 48 > pha
> cmp_flag ~fnz
1bdc : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1bde : d0fe > bne * ;failed not equal (non zero)
>
1be0 : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1be1 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1be3 : 48 > pha ;use stack to load status
1be4 : a901 > lda #1 ;precharge accu
1be6 : 28 > plp
1be7 : 2414 bit zp1+1 ;82 - should set N (M7) & Z / clear V
tst_a 1,~fv
1be9 : 08 > php ;save flags
1bea : c901 > cmp #1 ;test result
> trap_ne
1bec : d0fe > bne * ;failed not equal (non zero)
>
1bee : 68 > pla ;load status
1bef : 48 > pha
> cmp_flag ~fv
1bf0 : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1bf2 : d0fe > bne * ;failed not equal (non zero)
>
1bf4 : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1bf5 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1bf7 : 48 > pha ;use stack to load status
1bf8 : a901 > lda #1 ;precharge accu
1bfa : 28 > plp
1bfb : 2413 bit zp1 ;c3 - should set N (M7) & V (M6) / clear Z
tst_a 1,~fz
1bfd : 08 > php ;save flags
1bfe : c901 > cmp #1 ;test result
> trap_ne
1c00 : d0fe > bne * ;failed not equal (non zero)
>
1c02 : 68 > pla ;load status
1c03 : 48 > pha
> cmp_flag ~fz
1c04 : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c06 : d0fe > bne * ;failed not equal (non zero)
>
1c08 : 28 > plp ;restore status
set_a $ff,0
> load_flag 0
1c09 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1c0b : 48 > pha ;use stack to load status
1c0c : a9ff > lda #$ff ;precharge accu
1c0e : 28 > plp
1c0f : 2c1a02 bit abs1+3 ;00 - should set Z / clear NV
tst_a $ff,fz
1c12 : 08 > php ;save flags
1c13 : c9ff > cmp #$ff ;test result
> trap_ne
1c15 : d0fe > bne * ;failed not equal (non zero)
>
1c17 : 68 > pla ;load status
1c18 : 48 > pha
> cmp_flag fz
1c19 : c932 > cmp #(fz |fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c1b : d0fe > bne * ;failed not equal (non zero)
>
1c1d : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1c1e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1c20 : 48 > pha ;use stack to load status
1c21 : a901 > lda #1 ;precharge accu
1c23 : 28 > plp
1c24 : 2c1902 bit abs1+2 ;41 - should set V (M6) / clear NZ
tst_a 1,fv
1c27 : 08 > php ;save flags
1c28 : c901 > cmp #1 ;test result
> trap_ne
1c2a : d0fe > bne * ;failed not equal (non zero)
>
1c2c : 68 > pla ;load status
1c2d : 48 > pha
> cmp_flag fv
1c2e : c970 > cmp #(fv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c30 : d0fe > bne * ;failed not equal (non zero)
>
1c32 : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1c33 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1c35 : 48 > pha ;use stack to load status
1c36 : a901 > lda #1 ;precharge accu
1c38 : 28 > plp
1c39 : 2c1802 bit abs1+1 ;82 - should set N (M7) & Z / clear V
tst_a 1,fnz
1c3c : 08 > php ;save flags
1c3d : c901 > cmp #1 ;test result
> trap_ne
1c3f : d0fe > bne * ;failed not equal (non zero)
>
1c41 : 68 > pla ;load status
1c42 : 48 > pha
> cmp_flag fnz
1c43 : c9b2 > cmp #(fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c45 : d0fe > bne * ;failed not equal (non zero)
>
1c47 : 28 > plp ;restore status
set_a 1,0
> load_flag 0
1c48 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1c4a : 48 > pha ;use stack to load status
1c4b : a901 > lda #1 ;precharge accu
1c4d : 28 > plp
1c4e : 2c1702 bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z
tst_a 1,fnv
1c51 : 08 > php ;save flags
1c52 : c901 > cmp #1 ;test result
> trap_ne
1c54 : d0fe > bne * ;failed not equal (non zero)
>
1c56 : 68 > pla ;load status
1c57 : 48 > pha
> cmp_flag fnv
1c58 : c9f0 > cmp #(fnv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c5a : d0fe > bne * ;failed not equal (non zero)
>
1c5c : 28 > plp ;restore status
set_a $ff,$ff
> load_flag $ff
1c5d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1c5f : 48 > pha ;use stack to load status
1c60 : a9ff > lda #$ff ;precharge accu
1c62 : 28 > plp
1c63 : 2c1a02 bit abs1+3 ;00 - should set Z / clear NV
tst_a $ff,~fnv
1c66 : 08 > php ;save flags
1c67 : c9ff > cmp #$ff ;test result
> trap_ne
1c69 : d0fe > bne * ;failed not equal (non zero)
>
1c6b : 68 > pla ;load status
1c6c : 48 > pha
> cmp_flag ~fnv
1c6d : c93f > cmp #(~fnv |fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c6f : d0fe > bne * ;failed not equal (non zero)
>
1c71 : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1c72 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1c74 : 48 > pha ;use stack to load status
1c75 : a901 > lda #1 ;precharge accu
1c77 : 28 > plp
1c78 : 2c1902 bit abs1+2 ;41 - should set V (M6) / clear NZ
tst_a 1,~fnz
1c7b : 08 > php ;save flags
1c7c : c901 > cmp #1 ;test result
> trap_ne
1c7e : d0fe > bne * ;failed not equal (non zero)
>
1c80 : 68 > pla ;load status
1c81 : 48 > pha
> cmp_flag ~fnz
1c82 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c84 : d0fe > bne * ;failed not equal (non zero)
>
1c86 : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1c87 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1c89 : 48 > pha ;use stack to load status
1c8a : a901 > lda #1 ;precharge accu
1c8c : 28 > plp
1c8d : 2c1802 bit abs1+1 ;82 - should set N (M7) & Z / clear V
tst_a 1,~fv
1c90 : 08 > php ;save flags
1c91 : c901 > cmp #1 ;test result
> trap_ne
1c93 : d0fe > bne * ;failed not equal (non zero)
>
1c95 : 68 > pla ;load status
1c96 : 48 > pha
> cmp_flag ~fv
1c97 : c9bf > cmp #(~fv|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1c99 : d0fe > bne * ;failed not equal (non zero)
>
1c9b : 28 > plp ;restore status
set_a 1,$ff
> load_flag $ff
1c9c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1c9e : 48 > pha ;use stack to load status
1c9f : a901 > lda #1 ;precharge accu
1ca1 : 28 > plp
1ca2 : 2c1702 bit abs1 ;c3 - should set N (M7) & V (M6) / clear Z
tst_a 1,~fz
1ca5 : 08 > php ;save flags
1ca6 : c901 > cmp #1 ;test result
> trap_ne
1ca8 : d0fe > bne * ;failed not equal (non zero)
>
1caa : 68 > pla ;load status
1cab : 48 > pha
> cmp_flag ~fz
1cac : c9fd > cmp #(~fz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1cae : d0fe > bne * ;failed not equal (non zero)
>
1cb0 : 28 > plp ;restore status
next_test
1cb1 : ad0002 > lda test_case ;previous test
1cb4 : c919 > cmp #test_num
> trap_ne ;test is out of sequence
1cb6 : d0fe > bne * ;failed not equal (non zero)
>
001a = >test_num = test_num + 1
1cb8 : a91a > lda #test_num ;*** next tests' number
1cba : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; CPX - zp / abs / #
set_x $80,0
> load_flag 0
1cbd : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1cbf : 48 > pha ;use stack to load status
1cc0 : a280 > ldx #$80 ;precharge index x
1cc2 : 28 > plp
1cc3 : e417 cpx zp7f
tst_stat fc
1cc5 : 08 > php ;save status
1cc6 : 68 > pla ;use stack to retrieve status
1cc7 : 48 > pha
> cmp_flag fc
1cc8 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1cca : d0fe > bne * ;failed not equal (non zero)
>
1ccc : 28 > plp ;restore status
1ccd : ca dex
1cce : e417 cpx zp7f
tst_stat fzc
1cd0 : 08 > php ;save status
1cd1 : 68 > pla ;use stack to retrieve status
1cd2 : 48 > pha
> cmp_flag fzc
1cd3 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1cd5 : d0fe > bne * ;failed not equal (non zero)
>
1cd7 : 28 > plp ;restore status
1cd8 : ca dex
1cd9 : e417 cpx zp7f
tst_x $7e,fn
1cdb : 08 > php ;save flags
1cdc : e07e > cpx #$7e ;test result
> trap_ne
1cde : d0fe > bne * ;failed not equal (non zero)
>
1ce0 : 68 > pla ;load status
1ce1 : 48 > pha
> cmp_flag fn
1ce2 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1ce4 : d0fe > bne * ;failed not equal (non zero)
>
1ce6 : 28 > plp ;restore status
set_x $80,$ff
> load_flag $ff
1ce7 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1ce9 : 48 > pha ;use stack to load status
1cea : a280 > ldx #$80 ;precharge index x
1cec : 28 > plp
1ced : e417 cpx zp7f
tst_stat ~fnz
1cef : 08 > php ;save status
1cf0 : 68 > pla ;use stack to retrieve status
1cf1 : 48 > pha
> cmp_flag ~fnz
1cf2 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1cf4 : d0fe > bne * ;failed not equal (non zero)
>
1cf6 : 28 > plp ;restore status
1cf7 : ca dex
1cf8 : e417 cpx zp7f
tst_stat ~fn
1cfa : 08 > php ;save status
1cfb : 68 > pla ;use stack to retrieve status
1cfc : 48 > pha
> cmp_flag ~fn
1cfd : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1cff : d0fe > bne * ;failed not equal (non zero)
>
1d01 : 28 > plp ;restore status
1d02 : ca dex
1d03 : e417 cpx zp7f
tst_x $7e,~fzc
1d05 : 08 > php ;save flags
1d06 : e07e > cpx #$7e ;test result
> trap_ne
1d08 : d0fe > bne * ;failed not equal (non zero)
>
1d0a : 68 > pla ;load status
1d0b : 48 > pha
> cmp_flag ~fzc
1d0c : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d0e : d0fe > bne * ;failed not equal (non zero)
>
1d10 : 28 > plp ;restore status
set_x $80,0
> load_flag 0
1d11 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1d13 : 48 > pha ;use stack to load status
1d14 : a280 > ldx #$80 ;precharge index x
1d16 : 28 > plp
1d17 : ec1b02 cpx abs7f
tst_stat fc
1d1a : 08 > php ;save status
1d1b : 68 > pla ;use stack to retrieve status
1d1c : 48 > pha
> cmp_flag fc
1d1d : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d1f : d0fe > bne * ;failed not equal (non zero)
>
1d21 : 28 > plp ;restore status
1d22 : ca dex
1d23 : ec1b02 cpx abs7f
tst_stat fzc
1d26 : 08 > php ;save status
1d27 : 68 > pla ;use stack to retrieve status
1d28 : 48 > pha
> cmp_flag fzc
1d29 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d2b : d0fe > bne * ;failed not equal (non zero)
>
1d2d : 28 > plp ;restore status
1d2e : ca dex
1d2f : ec1b02 cpx abs7f
tst_x $7e,fn
1d32 : 08 > php ;save flags
1d33 : e07e > cpx #$7e ;test result
> trap_ne
1d35 : d0fe > bne * ;failed not equal (non zero)
>
1d37 : 68 > pla ;load status
1d38 : 48 > pha
> cmp_flag fn
1d39 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d3b : d0fe > bne * ;failed not equal (non zero)
>
1d3d : 28 > plp ;restore status
set_x $80,$ff
> load_flag $ff
1d3e : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1d40 : 48 > pha ;use stack to load status
1d41 : a280 > ldx #$80 ;precharge index x
1d43 : 28 > plp
1d44 : ec1b02 cpx abs7f
tst_stat ~fnz
1d47 : 08 > php ;save status
1d48 : 68 > pla ;use stack to retrieve status
1d49 : 48 > pha
> cmp_flag ~fnz
1d4a : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d4c : d0fe > bne * ;failed not equal (non zero)
>
1d4e : 28 > plp ;restore status
1d4f : ca dex
1d50 : ec1b02 cpx abs7f
tst_stat ~fn
1d53 : 08 > php ;save status
1d54 : 68 > pla ;use stack to retrieve status
1d55 : 48 > pha
> cmp_flag ~fn
1d56 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d58 : d0fe > bne * ;failed not equal (non zero)
>
1d5a : 28 > plp ;restore status
1d5b : ca dex
1d5c : ec1b02 cpx abs7f
tst_x $7e,~fzc
1d5f : 08 > php ;save flags
1d60 : e07e > cpx #$7e ;test result
> trap_ne
1d62 : d0fe > bne * ;failed not equal (non zero)
>
1d64 : 68 > pla ;load status
1d65 : 48 > pha
> cmp_flag ~fzc
1d66 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d68 : d0fe > bne * ;failed not equal (non zero)
>
1d6a : 28 > plp ;restore status
set_x $80,0
> load_flag 0
1d6b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1d6d : 48 > pha ;use stack to load status
1d6e : a280 > ldx #$80 ;precharge index x
1d70 : 28 > plp
1d71 : e07f cpx #$7f
tst_stat fc
1d73 : 08 > php ;save status
1d74 : 68 > pla ;use stack to retrieve status
1d75 : 48 > pha
> cmp_flag fc
1d76 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d78 : d0fe > bne * ;failed not equal (non zero)
>
1d7a : 28 > plp ;restore status
1d7b : ca dex
1d7c : e07f cpx #$7f
tst_stat fzc
1d7e : 08 > php ;save status
1d7f : 68 > pla ;use stack to retrieve status
1d80 : 48 > pha
> cmp_flag fzc
1d81 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d83 : d0fe > bne * ;failed not equal (non zero)
>
1d85 : 28 > plp ;restore status
1d86 : ca dex
1d87 : e07f cpx #$7f
tst_x $7e,fn
1d89 : 08 > php ;save flags
1d8a : e07e > cpx #$7e ;test result
> trap_ne
1d8c : d0fe > bne * ;failed not equal (non zero)
>
1d8e : 68 > pla ;load status
1d8f : 48 > pha
> cmp_flag fn
1d90 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1d92 : d0fe > bne * ;failed not equal (non zero)
>
1d94 : 28 > plp ;restore status
set_x $80,$ff
> load_flag $ff
1d95 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1d97 : 48 > pha ;use stack to load status
1d98 : a280 > ldx #$80 ;precharge index x
1d9a : 28 > plp
1d9b : e07f cpx #$7f
tst_stat ~fnz
1d9d : 08 > php ;save status
1d9e : 68 > pla ;use stack to retrieve status
1d9f : 48 > pha
> cmp_flag ~fnz
1da0 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1da2 : d0fe > bne * ;failed not equal (non zero)
>
1da4 : 28 > plp ;restore status
1da5 : ca dex
1da6 : e07f cpx #$7f
tst_stat ~fn
1da8 : 08 > php ;save status
1da9 : 68 > pla ;use stack to retrieve status
1daa : 48 > pha
> cmp_flag ~fn
1dab : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1dad : d0fe > bne * ;failed not equal (non zero)
>
1daf : 28 > plp ;restore status
1db0 : ca dex
1db1 : e07f cpx #$7f
tst_x $7e,~fzc
1db3 : 08 > php ;save flags
1db4 : e07e > cpx #$7e ;test result
> trap_ne
1db6 : d0fe > bne * ;failed not equal (non zero)
>
1db8 : 68 > pla ;load status
1db9 : 48 > pha
> cmp_flag ~fzc
1dba : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1dbc : d0fe > bne * ;failed not equal (non zero)
>
1dbe : 28 > plp ;restore status
next_test
1dbf : ad0002 > lda test_case ;previous test
1dc2 : c91a > cmp #test_num
> trap_ne ;test is out of sequence
1dc4 : d0fe > bne * ;failed not equal (non zero)
>
001b = >test_num = test_num + 1
1dc6 : a91b > lda #test_num ;*** next tests' number
1dc8 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; CPY - zp / abs / #
set_y $80,0
> load_flag 0
1dcb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1dcd : 48 > pha ;use stack to load status
1dce : a080 > ldy #$80 ;precharge index y
1dd0 : 28 > plp
1dd1 : c417 cpy zp7f
tst_stat fc
1dd3 : 08 > php ;save status
1dd4 : 68 > pla ;use stack to retrieve status
1dd5 : 48 > pha
> cmp_flag fc
1dd6 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1dd8 : d0fe > bne * ;failed not equal (non zero)
>
1dda : 28 > plp ;restore status
1ddb : 88 dey
1ddc : c417 cpy zp7f
tst_stat fzc
1dde : 08 > php ;save status
1ddf : 68 > pla ;use stack to retrieve status
1de0 : 48 > pha
> cmp_flag fzc
1de1 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1de3 : d0fe > bne * ;failed not equal (non zero)
>
1de5 : 28 > plp ;restore status
1de6 : 88 dey
1de7 : c417 cpy zp7f
tst_y $7e,fn
1de9 : 08 > php ;save flags
1dea : c07e > cpy #$7e ;test result
> trap_ne
1dec : d0fe > bne * ;failed not equal (non zero)
>
1dee : 68 > pla ;load status
1def : 48 > pha
> cmp_flag fn
1df0 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1df2 : d0fe > bne * ;failed not equal (non zero)
>
1df4 : 28 > plp ;restore status
set_y $80,$ff
> load_flag $ff
1df5 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1df7 : 48 > pha ;use stack to load status
1df8 : a080 > ldy #$80 ;precharge index y
1dfa : 28 > plp
1dfb : c417 cpy zp7f
tst_stat ~fnz
1dfd : 08 > php ;save status
1dfe : 68 > pla ;use stack to retrieve status
1dff : 48 > pha
> cmp_flag ~fnz
1e00 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e02 : d0fe > bne * ;failed not equal (non zero)
>
1e04 : 28 > plp ;restore status
1e05 : 88 dey
1e06 : c417 cpy zp7f
tst_stat ~fn
1e08 : 08 > php ;save status
1e09 : 68 > pla ;use stack to retrieve status
1e0a : 48 > pha
> cmp_flag ~fn
1e0b : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e0d : d0fe > bne * ;failed not equal (non zero)
>
1e0f : 28 > plp ;restore status
1e10 : 88 dey
1e11 : c417 cpy zp7f
tst_y $7e,~fzc
1e13 : 08 > php ;save flags
1e14 : c07e > cpy #$7e ;test result
> trap_ne
1e16 : d0fe > bne * ;failed not equal (non zero)
>
1e18 : 68 > pla ;load status
1e19 : 48 > pha
> cmp_flag ~fzc
1e1a : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e1c : d0fe > bne * ;failed not equal (non zero)
>
1e1e : 28 > plp ;restore status
set_y $80,0
> load_flag 0
1e1f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1e21 : 48 > pha ;use stack to load status
1e22 : a080 > ldy #$80 ;precharge index y
1e24 : 28 > plp
1e25 : cc1b02 cpy abs7f
tst_stat fc
1e28 : 08 > php ;save status
1e29 : 68 > pla ;use stack to retrieve status
1e2a : 48 > pha
> cmp_flag fc
1e2b : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e2d : d0fe > bne * ;failed not equal (non zero)
>
1e2f : 28 > plp ;restore status
1e30 : 88 dey
1e31 : cc1b02 cpy abs7f
tst_stat fzc
1e34 : 08 > php ;save status
1e35 : 68 > pla ;use stack to retrieve status
1e36 : 48 > pha
> cmp_flag fzc
1e37 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e39 : d0fe > bne * ;failed not equal (non zero)
>
1e3b : 28 > plp ;restore status
1e3c : 88 dey
1e3d : cc1b02 cpy abs7f
tst_y $7e,fn
1e40 : 08 > php ;save flags
1e41 : c07e > cpy #$7e ;test result
> trap_ne
1e43 : d0fe > bne * ;failed not equal (non zero)
>
1e45 : 68 > pla ;load status
1e46 : 48 > pha
> cmp_flag fn
1e47 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e49 : d0fe > bne * ;failed not equal (non zero)
>
1e4b : 28 > plp ;restore status
set_y $80,$ff
> load_flag $ff
1e4c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1e4e : 48 > pha ;use stack to load status
1e4f : a080 > ldy #$80 ;precharge index y
1e51 : 28 > plp
1e52 : cc1b02 cpy abs7f
tst_stat ~fnz
1e55 : 08 > php ;save status
1e56 : 68 > pla ;use stack to retrieve status
1e57 : 48 > pha
> cmp_flag ~fnz
1e58 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e5a : d0fe > bne * ;failed not equal (non zero)
>
1e5c : 28 > plp ;restore status
1e5d : 88 dey
1e5e : cc1b02 cpy abs7f
tst_stat ~fn
1e61 : 08 > php ;save status
1e62 : 68 > pla ;use stack to retrieve status
1e63 : 48 > pha
> cmp_flag ~fn
1e64 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e66 : d0fe > bne * ;failed not equal (non zero)
>
1e68 : 28 > plp ;restore status
1e69 : 88 dey
1e6a : cc1b02 cpy abs7f
tst_y $7e,~fzc
1e6d : 08 > php ;save flags
1e6e : c07e > cpy #$7e ;test result
> trap_ne
1e70 : d0fe > bne * ;failed not equal (non zero)
>
1e72 : 68 > pla ;load status
1e73 : 48 > pha
> cmp_flag ~fzc
1e74 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e76 : d0fe > bne * ;failed not equal (non zero)
>
1e78 : 28 > plp ;restore status
set_y $80,0
> load_flag 0
1e79 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1e7b : 48 > pha ;use stack to load status
1e7c : a080 > ldy #$80 ;precharge index y
1e7e : 28 > plp
1e7f : c07f cpy #$7f
tst_stat fc
1e81 : 08 > php ;save status
1e82 : 68 > pla ;use stack to retrieve status
1e83 : 48 > pha
> cmp_flag fc
1e84 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e86 : d0fe > bne * ;failed not equal (non zero)
>
1e88 : 28 > plp ;restore status
1e89 : 88 dey
1e8a : c07f cpy #$7f
tst_stat fzc
1e8c : 08 > php ;save status
1e8d : 68 > pla ;use stack to retrieve status
1e8e : 48 > pha
> cmp_flag fzc
1e8f : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1e91 : d0fe > bne * ;failed not equal (non zero)
>
1e93 : 28 > plp ;restore status
1e94 : 88 dey
1e95 : c07f cpy #$7f
tst_y $7e,fn
1e97 : 08 > php ;save flags
1e98 : c07e > cpy #$7e ;test result
> trap_ne
1e9a : d0fe > bne * ;failed not equal (non zero)
>
1e9c : 68 > pla ;load status
1e9d : 48 > pha
> cmp_flag fn
1e9e : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1ea0 : d0fe > bne * ;failed not equal (non zero)
>
1ea2 : 28 > plp ;restore status
set_y $80,$ff
> load_flag $ff
1ea3 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1ea5 : 48 > pha ;use stack to load status
1ea6 : a080 > ldy #$80 ;precharge index y
1ea8 : 28 > plp
1ea9 : c07f cpy #$7f
tst_stat ~fnz
1eab : 08 > php ;save status
1eac : 68 > pla ;use stack to retrieve status
1ead : 48 > pha
> cmp_flag ~fnz
1eae : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1eb0 : d0fe > bne * ;failed not equal (non zero)
>
1eb2 : 28 > plp ;restore status
1eb3 : 88 dey
1eb4 : c07f cpy #$7f
tst_stat ~fn
1eb6 : 08 > php ;save status
1eb7 : 68 > pla ;use stack to retrieve status
1eb8 : 48 > pha
> cmp_flag ~fn
1eb9 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1ebb : d0fe > bne * ;failed not equal (non zero)
>
1ebd : 28 > plp ;restore status
1ebe : 88 dey
1ebf : c07f cpy #$7f
tst_y $7e,~fzc
1ec1 : 08 > php ;save flags
1ec2 : c07e > cpy #$7e ;test result
> trap_ne
1ec4 : d0fe > bne * ;failed not equal (non zero)
>
1ec6 : 68 > pla ;load status
1ec7 : 48 > pha
> cmp_flag ~fzc
1ec8 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1eca : d0fe > bne * ;failed not equal (non zero)
>
1ecc : 28 > plp ;restore status
next_test
1ecd : ad0002 > lda test_case ;previous test
1ed0 : c91b > cmp #test_num
> trap_ne ;test is out of sequence
1ed2 : d0fe > bne * ;failed not equal (non zero)
>
001c = >test_num = test_num + 1
1ed4 : a91c > lda #test_num ;*** next tests' number
1ed6 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; CMP - zp / abs / #
set_a $80,0
> load_flag 0
1ed9 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1edb : 48 > pha ;use stack to load status
1edc : a980 > lda #$80 ;precharge accu
1ede : 28 > plp
1edf : c517 cmp zp7f
tst_a $80,fc
1ee1 : 08 > php ;save flags
1ee2 : c980 > cmp #$80 ;test result
> trap_ne
1ee4 : d0fe > bne * ;failed not equal (non zero)
>
1ee6 : 68 > pla ;load status
1ee7 : 48 > pha
> cmp_flag fc
1ee8 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1eea : d0fe > bne * ;failed not equal (non zero)
>
1eec : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
1eed : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1eef : 48 > pha ;use stack to load status
1ef0 : a97f > lda #$7f ;precharge accu
1ef2 : 28 > plp
1ef3 : c517 cmp zp7f
tst_a $7f,fzc
1ef5 : 08 > php ;save flags
1ef6 : c97f > cmp #$7f ;test result
> trap_ne
1ef8 : d0fe > bne * ;failed not equal (non zero)
>
1efa : 68 > pla ;load status
1efb : 48 > pha
> cmp_flag fzc
1efc : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1efe : d0fe > bne * ;failed not equal (non zero)
>
1f00 : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
1f01 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1f03 : 48 > pha ;use stack to load status
1f04 : a97e > lda #$7e ;precharge accu
1f06 : 28 > plp
1f07 : c517 cmp zp7f
tst_a $7e,fn
1f09 : 08 > php ;save flags
1f0a : c97e > cmp #$7e ;test result
> trap_ne
1f0c : d0fe > bne * ;failed not equal (non zero)
>
1f0e : 68 > pla ;load status
1f0f : 48 > pha
> cmp_flag fn
1f10 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f12 : d0fe > bne * ;failed not equal (non zero)
>
1f14 : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
1f15 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1f17 : 48 > pha ;use stack to load status
1f18 : a980 > lda #$80 ;precharge accu
1f1a : 28 > plp
1f1b : c517 cmp zp7f
tst_a $80,~fnz
1f1d : 08 > php ;save flags
1f1e : c980 > cmp #$80 ;test result
> trap_ne
1f20 : d0fe > bne * ;failed not equal (non zero)
>
1f22 : 68 > pla ;load status
1f23 : 48 > pha
> cmp_flag ~fnz
1f24 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f26 : d0fe > bne * ;failed not equal (non zero)
>
1f28 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
1f29 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1f2b : 48 > pha ;use stack to load status
1f2c : a97f > lda #$7f ;precharge accu
1f2e : 28 > plp
1f2f : c517 cmp zp7f
tst_a $7f,~fn
1f31 : 08 > php ;save flags
1f32 : c97f > cmp #$7f ;test result
> trap_ne
1f34 : d0fe > bne * ;failed not equal (non zero)
>
1f36 : 68 > pla ;load status
1f37 : 48 > pha
> cmp_flag ~fn
1f38 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f3a : d0fe > bne * ;failed not equal (non zero)
>
1f3c : 28 > plp ;restore status
set_a $7e,$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 : a97e > lda #$7e ;precharge accu
1f42 : 28 > plp
1f43 : c517 cmp zp7f
tst_a $7e,~fzc
1f45 : 08 > php ;save flags
1f46 : c97e > cmp #$7e ;test result
> trap_ne
1f48 : d0fe > bne * ;failed not equal (non zero)
>
1f4a : 68 > pla ;load status
1f4b : 48 > pha
> cmp_flag ~fzc
1f4c : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f4e : d0fe > bne * ;failed not equal (non zero)
>
1f50 : 28 > plp ;restore status
set_a $80,0
> load_flag 0
1f51 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1f53 : 48 > pha ;use stack to load status
1f54 : a980 > lda #$80 ;precharge accu
1f56 : 28 > plp
1f57 : cd1b02 cmp abs7f
tst_a $80,fc
1f5a : 08 > php ;save flags
1f5b : c980 > cmp #$80 ;test result
> trap_ne
1f5d : d0fe > bne * ;failed not equal (non zero)
>
1f5f : 68 > pla ;load status
1f60 : 48 > pha
> cmp_flag fc
1f61 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f63 : d0fe > bne * ;failed not equal (non zero)
>
1f65 : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
1f66 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1f68 : 48 > pha ;use stack to load status
1f69 : a97f > lda #$7f ;precharge accu
1f6b : 28 > plp
1f6c : cd1b02 cmp abs7f
tst_a $7f,fzc
1f6f : 08 > php ;save flags
1f70 : c97f > cmp #$7f ;test result
> trap_ne
1f72 : d0fe > bne * ;failed not equal (non zero)
>
1f74 : 68 > pla ;load status
1f75 : 48 > pha
> cmp_flag fzc
1f76 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f78 : d0fe > bne * ;failed not equal (non zero)
>
1f7a : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
1f7b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1f7d : 48 > pha ;use stack to load status
1f7e : a97e > lda #$7e ;precharge accu
1f80 : 28 > plp
1f81 : cd1b02 cmp abs7f
tst_a $7e,fn
1f84 : 08 > php ;save flags
1f85 : c97e > cmp #$7e ;test result
> trap_ne
1f87 : d0fe > bne * ;failed not equal (non zero)
>
1f89 : 68 > pla ;load status
1f8a : 48 > pha
> cmp_flag fn
1f8b : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1f8d : d0fe > bne * ;failed not equal (non zero)
>
1f8f : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
1f90 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1f92 : 48 > pha ;use stack to load status
1f93 : a980 > lda #$80 ;precharge accu
1f95 : 28 > plp
1f96 : cd1b02 cmp abs7f
tst_a $80,~fnz
1f99 : 08 > php ;save flags
1f9a : c980 > cmp #$80 ;test result
> trap_ne
1f9c : d0fe > bne * ;failed not equal (non zero)
>
1f9e : 68 > pla ;load status
1f9f : 48 > pha
> cmp_flag ~fnz
1fa0 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1fa2 : d0fe > bne * ;failed not equal (non zero)
>
1fa4 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
1fa5 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1fa7 : 48 > pha ;use stack to load status
1fa8 : a97f > lda #$7f ;precharge accu
1faa : 28 > plp
1fab : cd1b02 cmp abs7f
tst_a $7f,~fn
1fae : 08 > php ;save flags
1faf : c97f > cmp #$7f ;test result
> trap_ne
1fb1 : d0fe > bne * ;failed not equal (non zero)
>
1fb3 : 68 > pla ;load status
1fb4 : 48 > pha
> cmp_flag ~fn
1fb5 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1fb7 : d0fe > bne * ;failed not equal (non zero)
>
1fb9 : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
1fba : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
1fbc : 48 > pha ;use stack to load status
1fbd : a97e > lda #$7e ;precharge accu
1fbf : 28 > plp
1fc0 : cd1b02 cmp abs7f
tst_a $7e,~fzc
1fc3 : 08 > php ;save flags
1fc4 : c97e > cmp #$7e ;test result
> trap_ne
1fc6 : d0fe > bne * ;failed not equal (non zero)
>
1fc8 : 68 > pla ;load status
1fc9 : 48 > pha
> cmp_flag ~fzc
1fca : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1fcc : d0fe > bne * ;failed not equal (non zero)
>
1fce : 28 > plp ;restore status
set_a $80,0
> load_flag 0
1fcf : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1fd1 : 48 > pha ;use stack to load status
1fd2 : a980 > lda #$80 ;precharge accu
1fd4 : 28 > plp
1fd5 : c97f cmp #$7f
tst_a $80,fc
1fd7 : 08 > php ;save flags
1fd8 : c980 > cmp #$80 ;test result
> trap_ne
1fda : d0fe > bne * ;failed not equal (non zero)
>
1fdc : 68 > pla ;load status
1fdd : 48 > pha
> cmp_flag fc
1fde : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1fe0 : d0fe > bne * ;failed not equal (non zero)
>
1fe2 : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
1fe3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1fe5 : 48 > pha ;use stack to load status
1fe6 : a97f > lda #$7f ;precharge accu
1fe8 : 28 > plp
1fe9 : c97f cmp #$7f
tst_a $7f,fzc
1feb : 08 > php ;save flags
1fec : c97f > cmp #$7f ;test result
> trap_ne
1fee : d0fe > bne * ;failed not equal (non zero)
>
1ff0 : 68 > pla ;load status
1ff1 : 48 > pha
> cmp_flag fzc
1ff2 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
1ff4 : d0fe > bne * ;failed not equal (non zero)
>
1ff6 : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
1ff7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
1ff9 : 48 > pha ;use stack to load status
1ffa : a97e > lda #$7e ;precharge accu
1ffc : 28 > plp
1ffd : c97f cmp #$7f
tst_a $7e,fn
1fff : 08 > php ;save flags
2000 : c97e > cmp #$7e ;test result
> trap_ne
2002 : d0fe > bne * ;failed not equal (non zero)
>
2004 : 68 > pla ;load status
2005 : 48 > pha
> cmp_flag fn
2006 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2008 : d0fe > bne * ;failed not equal (non zero)
>
200a : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
200b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
200d : 48 > pha ;use stack to load status
200e : a980 > lda #$80 ;precharge accu
2010 : 28 > plp
2011 : c97f cmp #$7f
tst_a $80,~fnz
2013 : 08 > php ;save flags
2014 : c980 > cmp #$80 ;test result
> trap_ne
2016 : d0fe > bne * ;failed not equal (non zero)
>
2018 : 68 > pla ;load status
2019 : 48 > pha
> cmp_flag ~fnz
201a : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
201c : d0fe > bne * ;failed not equal (non zero)
>
201e : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
201f : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2021 : 48 > pha ;use stack to load status
2022 : a97f > lda #$7f ;precharge accu
2024 : 28 > plp
2025 : c97f cmp #$7f
tst_a $7f,~fn
2027 : 08 > php ;save flags
2028 : c97f > cmp #$7f ;test result
> trap_ne
202a : d0fe > bne * ;failed not equal (non zero)
>
202c : 68 > pla ;load status
202d : 48 > pha
> cmp_flag ~fn
202e : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2030 : d0fe > bne * ;failed not equal (non zero)
>
2032 : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
2033 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2035 : 48 > pha ;use stack to load status
2036 : a97e > lda #$7e ;precharge accu
2038 : 28 > plp
2039 : c97f cmp #$7f
tst_a $7e,~fzc
203b : 08 > php ;save flags
203c : c97e > cmp #$7e ;test result
> trap_ne
203e : d0fe > bne * ;failed not equal (non zero)
>
2040 : 68 > pla ;load status
2041 : 48 > pha
> cmp_flag ~fzc
2042 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2044 : d0fe > bne * ;failed not equal (non zero)
>
2046 : 28 > plp ;restore status
2047 : a204 ldx #4 ;with indexing by X
set_a $80,0
> load_flag 0
2049 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
204b : 48 > pha ;use stack to load status
204c : a980 > lda #$80 ;precharge accu
204e : 28 > plp
204f : d513 cmp zp1,x
tst_a $80,fc
2051 : 08 > php ;save flags
2052 : c980 > cmp #$80 ;test result
> trap_ne
2054 : d0fe > bne * ;failed not equal (non zero)
>
2056 : 68 > pla ;load status
2057 : 48 > pha
> cmp_flag fc
2058 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
205a : d0fe > bne * ;failed not equal (non zero)
>
205c : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
205d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
205f : 48 > pha ;use stack to load status
2060 : a97f > lda #$7f ;precharge accu
2062 : 28 > plp
2063 : d513 cmp zp1,x
tst_a $7f,fzc
2065 : 08 > php ;save flags
2066 : c97f > cmp #$7f ;test result
> trap_ne
2068 : d0fe > bne * ;failed not equal (non zero)
>
206a : 68 > pla ;load status
206b : 48 > pha
> cmp_flag fzc
206c : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
206e : d0fe > bne * ;failed not equal (non zero)
>
2070 : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
2071 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2073 : 48 > pha ;use stack to load status
2074 : a97e > lda #$7e ;precharge accu
2076 : 28 > plp
2077 : d513 cmp zp1,x
tst_a $7e,fn
2079 : 08 > php ;save flags
207a : c97e > cmp #$7e ;test result
> trap_ne
207c : d0fe > bne * ;failed not equal (non zero)
>
207e : 68 > pla ;load status
207f : 48 > pha
> cmp_flag fn
2080 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2082 : d0fe > bne * ;failed not equal (non zero)
>
2084 : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
2085 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2087 : 48 > pha ;use stack to load status
2088 : a980 > lda #$80 ;precharge accu
208a : 28 > plp
208b : d513 cmp zp1,x
tst_a $80,~fnz
208d : 08 > php ;save flags
208e : c980 > cmp #$80 ;test result
> trap_ne
2090 : d0fe > bne * ;failed not equal (non zero)
>
2092 : 68 > pla ;load status
2093 : 48 > pha
> cmp_flag ~fnz
2094 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2096 : d0fe > bne * ;failed not equal (non zero)
>
2098 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
2099 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
209b : 48 > pha ;use stack to load status
209c : a97f > lda #$7f ;precharge accu
209e : 28 > plp
209f : d513 cmp zp1,x
tst_a $7f,~fn
20a1 : 08 > php ;save flags
20a2 : c97f > cmp #$7f ;test result
> trap_ne
20a4 : d0fe > bne * ;failed not equal (non zero)
>
20a6 : 68 > pla ;load status
20a7 : 48 > pha
> cmp_flag ~fn
20a8 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
20aa : d0fe > bne * ;failed not equal (non zero)
>
20ac : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
20ad : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
20af : 48 > pha ;use stack to load status
20b0 : a97e > lda #$7e ;precharge accu
20b2 : 28 > plp
20b3 : d513 cmp zp1,x
tst_a $7e,~fzc
20b5 : 08 > php ;save flags
20b6 : c97e > cmp #$7e ;test result
> trap_ne
20b8 : d0fe > bne * ;failed not equal (non zero)
>
20ba : 68 > pla ;load status
20bb : 48 > pha
> cmp_flag ~fzc
20bc : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
20be : d0fe > bne * ;failed not equal (non zero)
>
20c0 : 28 > plp ;restore status
set_a $80,0
> load_flag 0
20c1 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
20c3 : 48 > pha ;use stack to load status
20c4 : a980 > lda #$80 ;precharge accu
20c6 : 28 > plp
20c7 : dd1702 cmp abs1,x
tst_a $80,fc
20ca : 08 > php ;save flags
20cb : c980 > cmp #$80 ;test result
> trap_ne
20cd : d0fe > bne * ;failed not equal (non zero)
>
20cf : 68 > pla ;load status
20d0 : 48 > pha
> cmp_flag fc
20d1 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
20d3 : d0fe > bne * ;failed not equal (non zero)
>
20d5 : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
20d6 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
20d8 : 48 > pha ;use stack to load status
20d9 : a97f > lda #$7f ;precharge accu
20db : 28 > plp
20dc : dd1702 cmp abs1,x
tst_a $7f,fzc
20df : 08 > php ;save flags
20e0 : c97f > cmp #$7f ;test result
> trap_ne
20e2 : d0fe > bne * ;failed not equal (non zero)
>
20e4 : 68 > pla ;load status
20e5 : 48 > pha
> cmp_flag fzc
20e6 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
20e8 : d0fe > bne * ;failed not equal (non zero)
>
20ea : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
20eb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
20ed : 48 > pha ;use stack to load status
20ee : a97e > lda #$7e ;precharge accu
20f0 : 28 > plp
20f1 : dd1702 cmp abs1,x
tst_a $7e,fn
20f4 : 08 > php ;save flags
20f5 : c97e > cmp #$7e ;test result
> trap_ne
20f7 : d0fe > bne * ;failed not equal (non zero)
>
20f9 : 68 > pla ;load status
20fa : 48 > pha
> cmp_flag fn
20fb : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
20fd : d0fe > bne * ;failed not equal (non zero)
>
20ff : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
2100 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2102 : 48 > pha ;use stack to load status
2103 : a980 > lda #$80 ;precharge accu
2105 : 28 > plp
2106 : dd1702 cmp abs1,x
tst_a $80,~fnz
2109 : 08 > php ;save flags
210a : c980 > cmp #$80 ;test result
> trap_ne
210c : d0fe > bne * ;failed not equal (non zero)
>
210e : 68 > pla ;load status
210f : 48 > pha
> cmp_flag ~fnz
2110 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2112 : d0fe > bne * ;failed not equal (non zero)
>
2114 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
2115 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2117 : 48 > pha ;use stack to load status
2118 : a97f > lda #$7f ;precharge accu
211a : 28 > plp
211b : dd1702 cmp abs1,x
tst_a $7f,~fn
211e : 08 > php ;save flags
211f : c97f > cmp #$7f ;test result
> trap_ne
2121 : d0fe > bne * ;failed not equal (non zero)
>
2123 : 68 > pla ;load status
2124 : 48 > pha
> cmp_flag ~fn
2125 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2127 : d0fe > bne * ;failed not equal (non zero)
>
2129 : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
212a : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
212c : 48 > pha ;use stack to load status
212d : a97e > lda #$7e ;precharge accu
212f : 28 > plp
2130 : dd1702 cmp abs1,x
tst_a $7e,~fzc
2133 : 08 > php ;save flags
2134 : c97e > cmp #$7e ;test result
> trap_ne
2136 : d0fe > bne * ;failed not equal (non zero)
>
2138 : 68 > pla ;load status
2139 : 48 > pha
> cmp_flag ~fzc
213a : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
213c : d0fe > bne * ;failed not equal (non zero)
>
213e : 28 > plp ;restore status
213f : a004 ldy #4 ;with indexing by Y
2141 : a208 ldx #8 ;with indexed indirect
set_a $80,0
> load_flag 0
2143 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2145 : 48 > pha ;use stack to load status
2146 : a980 > lda #$80 ;precharge accu
2148 : 28 > plp
2149 : d91702 cmp abs1,y
tst_a $80,fc
214c : 08 > php ;save flags
214d : c980 > cmp #$80 ;test result
> trap_ne
214f : d0fe > bne * ;failed not equal (non zero)
>
2151 : 68 > pla ;load status
2152 : 48 > pha
> cmp_flag fc
2153 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2155 : d0fe > bne * ;failed not equal (non zero)
>
2157 : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
2158 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
215a : 48 > pha ;use stack to load status
215b : a97f > lda #$7f ;precharge accu
215d : 28 > plp
215e : d91702 cmp abs1,y
tst_a $7f,fzc
2161 : 08 > php ;save flags
2162 : c97f > cmp #$7f ;test result
> trap_ne
2164 : d0fe > bne * ;failed not equal (non zero)
>
2166 : 68 > pla ;load status
2167 : 48 > pha
> cmp_flag fzc
2168 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
216a : d0fe > bne * ;failed not equal (non zero)
>
216c : 28 > plp ;restore status
set_a $7e,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 : a97e > lda #$7e ;precharge accu
2172 : 28 > plp
2173 : d91702 cmp abs1,y
tst_a $7e,fn
2176 : 08 > php ;save flags
2177 : c97e > cmp #$7e ;test result
> trap_ne
2179 : d0fe > bne * ;failed not equal (non zero)
>
217b : 68 > pla ;load status
217c : 48 > pha
> cmp_flag fn
217d : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
217f : d0fe > bne * ;failed not equal (non zero)
>
2181 : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
2182 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2184 : 48 > pha ;use stack to load status
2185 : a980 > lda #$80 ;precharge accu
2187 : 28 > plp
2188 : d91702 cmp abs1,y
tst_a $80,~fnz
218b : 08 > php ;save flags
218c : c980 > cmp #$80 ;test result
> trap_ne
218e : d0fe > bne * ;failed not equal (non zero)
>
2190 : 68 > pla ;load status
2191 : 48 > pha
> cmp_flag ~fnz
2192 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2194 : d0fe > bne * ;failed not equal (non zero)
>
2196 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
2197 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2199 : 48 > pha ;use stack to load status
219a : a97f > lda #$7f ;precharge accu
219c : 28 > plp
219d : d91702 cmp abs1,y
tst_a $7f,~fn
21a0 : 08 > php ;save flags
21a1 : c97f > cmp #$7f ;test result
> trap_ne
21a3 : d0fe > bne * ;failed not equal (non zero)
>
21a5 : 68 > pla ;load status
21a6 : 48 > pha
> cmp_flag ~fn
21a7 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
21a9 : d0fe > bne * ;failed not equal (non zero)
>
21ab : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
21ac : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
21ae : 48 > pha ;use stack to load status
21af : a97e > lda #$7e ;precharge accu
21b1 : 28 > plp
21b2 : d91702 cmp abs1,y
tst_a $7e,~fzc
21b5 : 08 > php ;save flags
21b6 : c97e > cmp #$7e ;test result
> trap_ne
21b8 : d0fe > bne * ;failed not equal (non zero)
>
21ba : 68 > pla ;load status
21bb : 48 > pha
> cmp_flag ~fzc
21bc : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
21be : d0fe > bne * ;failed not equal (non zero)
>
21c0 : 28 > plp ;restore status
set_a $80,0
> load_flag 0
21c1 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
21c3 : 48 > pha ;use stack to load status
21c4 : a980 > lda #$80 ;precharge accu
21c6 : 28 > plp
21c7 : c124 cmp (ind1,x)
tst_a $80,fc
21c9 : 08 > php ;save flags
21ca : c980 > cmp #$80 ;test result
> trap_ne
21cc : d0fe > bne * ;failed not equal (non zero)
>
21ce : 68 > pla ;load status
21cf : 48 > pha
> cmp_flag fc
21d0 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
21d2 : d0fe > bne * ;failed not equal (non zero)
>
21d4 : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
21d5 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
21d7 : 48 > pha ;use stack to load status
21d8 : a97f > lda #$7f ;precharge accu
21da : 28 > plp
21db : c124 cmp (ind1,x)
tst_a $7f,fzc
21dd : 08 > php ;save flags
21de : c97f > cmp #$7f ;test result
> trap_ne
21e0 : d0fe > bne * ;failed not equal (non zero)
>
21e2 : 68 > pla ;load status
21e3 : 48 > pha
> cmp_flag fzc
21e4 : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
21e6 : d0fe > bne * ;failed not equal (non zero)
>
21e8 : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
21e9 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
21eb : 48 > pha ;use stack to load status
21ec : a97e > lda #$7e ;precharge accu
21ee : 28 > plp
21ef : c124 cmp (ind1,x)
tst_a $7e,fn
21f1 : 08 > php ;save flags
21f2 : c97e > cmp #$7e ;test result
> trap_ne
21f4 : d0fe > bne * ;failed not equal (non zero)
>
21f6 : 68 > pla ;load status
21f7 : 48 > pha
> cmp_flag fn
21f8 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
21fa : d0fe > bne * ;failed not equal (non zero)
>
21fc : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
21fd : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
21ff : 48 > pha ;use stack to load status
2200 : a980 > lda #$80 ;precharge accu
2202 : 28 > plp
2203 : c124 cmp (ind1,x)
tst_a $80,~fnz
2205 : 08 > php ;save flags
2206 : c980 > cmp #$80 ;test result
> trap_ne
2208 : d0fe > bne * ;failed not equal (non zero)
>
220a : 68 > pla ;load status
220b : 48 > pha
> cmp_flag ~fnz
220c : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
220e : d0fe > bne * ;failed not equal (non zero)
>
2210 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
2211 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2213 : 48 > pha ;use stack to load status
2214 : a97f > lda #$7f ;precharge accu
2216 : 28 > plp
2217 : c124 cmp (ind1,x)
tst_a $7f,~fn
2219 : 08 > php ;save flags
221a : c97f > cmp #$7f ;test result
> trap_ne
221c : d0fe > bne * ;failed not equal (non zero)
>
221e : 68 > pla ;load status
221f : 48 > pha
> cmp_flag ~fn
2220 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2222 : d0fe > bne * ;failed not equal (non zero)
>
2224 : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
2225 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2227 : 48 > pha ;use stack to load status
2228 : a97e > lda #$7e ;precharge accu
222a : 28 > plp
222b : c124 cmp (ind1,x)
tst_a $7e,~fzc
222d : 08 > php ;save flags
222e : c97e > cmp #$7e ;test result
> trap_ne
2230 : d0fe > bne * ;failed not equal (non zero)
>
2232 : 68 > pla ;load status
2233 : 48 > pha
> cmp_flag ~fzc
2234 : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2236 : d0fe > bne * ;failed not equal (non zero)
>
2238 : 28 > plp ;restore status
set_a $80,0
> load_flag 0
2239 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
223b : 48 > pha ;use stack to load status
223c : a980 > lda #$80 ;precharge accu
223e : 28 > plp
223f : d124 cmp (ind1),y
tst_a $80,fc
2241 : 08 > php ;save flags
2242 : c980 > cmp #$80 ;test result
> trap_ne
2244 : d0fe > bne * ;failed not equal (non zero)
>
2246 : 68 > pla ;load status
2247 : 48 > pha
> cmp_flag fc
2248 : c931 > cmp #(fc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
224a : d0fe > bne * ;failed not equal (non zero)
>
224c : 28 > plp ;restore status
set_a $7f,0
> load_flag 0
224d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
224f : 48 > pha ;use stack to load status
2250 : a97f > lda #$7f ;precharge accu
2252 : 28 > plp
2253 : d124 cmp (ind1),y
tst_a $7f,fzc
2255 : 08 > php ;save flags
2256 : c97f > cmp #$7f ;test result
> trap_ne
2258 : d0fe > bne * ;failed not equal (non zero)
>
225a : 68 > pla ;load status
225b : 48 > pha
> cmp_flag fzc
225c : c933 > cmp #(fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
225e : d0fe > bne * ;failed not equal (non zero)
>
2260 : 28 > plp ;restore status
set_a $7e,0
> load_flag 0
2261 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2263 : 48 > pha ;use stack to load status
2264 : a97e > lda #$7e ;precharge accu
2266 : 28 > plp
2267 : d124 cmp (ind1),y
tst_a $7e,fn
2269 : 08 > php ;save flags
226a : c97e > cmp #$7e ;test result
> trap_ne
226c : d0fe > bne * ;failed not equal (non zero)
>
226e : 68 > pla ;load status
226f : 48 > pha
> cmp_flag fn
2270 : c9b0 > cmp #(fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2272 : d0fe > bne * ;failed not equal (non zero)
>
2274 : 28 > plp ;restore status
set_a $80,$ff
> load_flag $ff
2275 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2277 : 48 > pha ;use stack to load status
2278 : a980 > lda #$80 ;precharge accu
227a : 28 > plp
227b : d124 cmp (ind1),y
tst_a $80,~fnz
227d : 08 > php ;save flags
227e : c980 > cmp #$80 ;test result
> trap_ne
2280 : d0fe > bne * ;failed not equal (non zero)
>
2282 : 68 > pla ;load status
2283 : 48 > pha
> cmp_flag ~fnz
2284 : c97d > cmp #(~fnz|fao)&m8 ;expected flags + always on bits
>
> trap_ne
2286 : d0fe > bne * ;failed not equal (non zero)
>
2288 : 28 > plp ;restore status
set_a $7f,$ff
> load_flag $ff
2289 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
228b : 48 > pha ;use stack to load status
228c : a97f > lda #$7f ;precharge accu
228e : 28 > plp
228f : d124 cmp (ind1),y
tst_a $7f,~fn
2291 : 08 > php ;save flags
2292 : c97f > cmp #$7f ;test result
> trap_ne
2294 : d0fe > bne * ;failed not equal (non zero)
>
2296 : 68 > pla ;load status
2297 : 48 > pha
> cmp_flag ~fn
2298 : c97f > cmp #(~fn|fao)&m8 ;expected flags + always on bits
>
> trap_ne
229a : d0fe > bne * ;failed not equal (non zero)
>
229c : 28 > plp ;restore status
set_a $7e,$ff
> load_flag $ff
229d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
229f : 48 > pha ;use stack to load status
22a0 : a97e > lda #$7e ;precharge accu
22a2 : 28 > plp
22a3 : d124 cmp (ind1),y
tst_a $7e,~fzc
22a5 : 08 > php ;save flags
22a6 : c97e > cmp #$7e ;test result
> trap_ne
22a8 : d0fe > bne * ;failed not equal (non zero)
>
22aa : 68 > pla ;load status
22ab : 48 > pha
> cmp_flag ~fzc
22ac : c9fc > cmp #(~fzc|fao)&m8 ;expected flags + always on bits
>
> trap_ne
22ae : d0fe > bne * ;failed not equal (non zero)
>
22b0 : 28 > plp ;restore status
next_test
22b1 : ad0002 > lda test_case ;previous test
22b4 : c91c > cmp #test_num
> trap_ne ;test is out of sequence
22b6 : d0fe > bne * ;failed not equal (non zero)
>
001d = >test_num = test_num + 1
22b8 : a91d > lda #test_num ;*** next tests' number
22ba : 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
22bd : a203 ldx #3
22bf : tasl
set_ax zp1,0
> load_flag 0
22bf : a900 > lda #0 ;allow test to change I-flag (no mask)
>
22c1 : 48 > pha ;use stack to load status
22c2 : b513 > lda zp1,x ;precharge accu
22c4 : 28 > plp
22c5 : 0a asl a
tst_ax rASL,fASL,0
22c6 : 08 > php ;save flags
22c7 : dd2002 > cmp rASL,x ;test result
> trap_ne
22ca : d0fe > bne * ;failed not equal (non zero)
>
22cc : 68 > pla ;load status
> eor_flag 0
22cd : 4930 > eor #0|fao ;invert expected flags + always on bits
>
22cf : dd3002 > cmp fASL,x ;test flags
> trap_ne ;
22d2 : d0fe > bne * ;failed not equal (non zero)
>
22d4 : ca dex
22d5 : 10e8 bpl tasl
22d7 : a203 ldx #3
22d9 : tasl1
set_ax zp1,$ff
> load_flag $ff
22d9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
22db : 48 > pha ;use stack to load status
22dc : b513 > lda zp1,x ;precharge accu
22de : 28 > plp
22df : 0a asl a
tst_ax rASL,fASL,$ff-fnzc
22e0 : 08 > php ;save flags
22e1 : dd2002 > cmp rASL,x ;test result
> trap_ne
22e4 : d0fe > bne * ;failed not equal (non zero)
>
22e6 : 68 > pla ;load status
> eor_flag $ff-fnzc
22e7 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
22e9 : dd3002 > cmp fASL,x ;test flags
> trap_ne ;
22ec : d0fe > bne * ;failed not equal (non zero)
>
22ee : ca dex
22ef : 10e8 bpl tasl1
22f1 : a203 ldx #3
22f3 : tlsr
set_ax zp1,0
> load_flag 0
22f3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
22f5 : 48 > pha ;use stack to load status
22f6 : b513 > lda zp1,x ;precharge accu
22f8 : 28 > plp
22f9 : 4a lsr a
tst_ax rLSR,fLSR,0
22fa : 08 > php ;save flags
22fb : dd2802 > cmp rLSR,x ;test result
> trap_ne
22fe : d0fe > bne * ;failed not equal (non zero)
>
2300 : 68 > pla ;load status
> eor_flag 0
2301 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2303 : dd3802 > cmp fLSR,x ;test flags
> trap_ne ;
2306 : d0fe > bne * ;failed not equal (non zero)
>
2308 : ca dex
2309 : 10e8 bpl tlsr
230b : a203 ldx #3
230d : tlsr1
set_ax zp1,$ff
> load_flag $ff
230d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
230f : 48 > pha ;use stack to load status
2310 : b513 > lda zp1,x ;precharge accu
2312 : 28 > plp
2313 : 4a lsr a
tst_ax rLSR,fLSR,$ff-fnzc
2314 : 08 > php ;save flags
2315 : dd2802 > cmp rLSR,x ;test result
> trap_ne
2318 : d0fe > bne * ;failed not equal (non zero)
>
231a : 68 > pla ;load status
> eor_flag $ff-fnzc
231b : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
231d : dd3802 > cmp fLSR,x ;test flags
> trap_ne ;
2320 : d0fe > bne * ;failed not equal (non zero)
>
2322 : ca dex
2323 : 10e8 bpl tlsr1
2325 : a203 ldx #3
2327 : trol
set_ax zp1,0
> load_flag 0
2327 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2329 : 48 > pha ;use stack to load status
232a : b513 > lda zp1,x ;precharge accu
232c : 28 > plp
232d : 2a rol a
tst_ax rROL,fROL,0
232e : 08 > php ;save flags
232f : dd2002 > cmp rROL,x ;test result
> trap_ne
2332 : d0fe > bne * ;failed not equal (non zero)
>
2334 : 68 > pla ;load status
> eor_flag 0
2335 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2337 : dd3002 > cmp fROL,x ;test flags
> trap_ne ;
233a : d0fe > bne * ;failed not equal (non zero)
>
233c : ca dex
233d : 10e8 bpl trol
233f : a203 ldx #3
2341 : trol1
set_ax zp1,$ff-fc
> load_flag $ff-fc
2341 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
2343 : 48 > pha ;use stack to load status
2344 : b513 > lda zp1,x ;precharge accu
2346 : 28 > plp
2347 : 2a rol a
tst_ax rROL,fROL,$ff-fnzc
2348 : 08 > php ;save flags
2349 : dd2002 > cmp rROL,x ;test result
> trap_ne
234c : d0fe > bne * ;failed not equal (non zero)
>
234e : 68 > pla ;load status
> eor_flag $ff-fnzc
234f : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2351 : dd3002 > cmp fROL,x ;test flags
> trap_ne ;
2354 : d0fe > bne * ;failed not equal (non zero)
>
2356 : ca dex
2357 : 10e8 bpl trol1
2359 : a203 ldx #3
235b : trolc
set_ax zp1,fc
> load_flag fc
235b : a901 > lda #fc ;allow test to change I-flag (no mask)
>
235d : 48 > pha ;use stack to load status
235e : b513 > lda zp1,x ;precharge accu
2360 : 28 > plp
2361 : 2a rol a
tst_ax rROLc,fROLc,0
2362 : 08 > php ;save flags
2363 : dd2402 > cmp rROLc,x ;test result
> trap_ne
2366 : d0fe > bne * ;failed not equal (non zero)
>
2368 : 68 > pla ;load status
> eor_flag 0
2369 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
236b : dd3402 > cmp fROLc,x ;test flags
> trap_ne ;
236e : d0fe > bne * ;failed not equal (non zero)
>
2370 : ca dex
2371 : 10e8 bpl trolc
2373 : a203 ldx #3
2375 : trolc1
set_ax zp1,$ff
> load_flag $ff
2375 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2377 : 48 > pha ;use stack to load status
2378 : b513 > lda zp1,x ;precharge accu
237a : 28 > plp
237b : 2a rol a
tst_ax rROLc,fROLc,$ff-fnzc
237c : 08 > php ;save flags
237d : dd2402 > cmp rROLc,x ;test result
> trap_ne
2380 : d0fe > bne * ;failed not equal (non zero)
>
2382 : 68 > pla ;load status
> eor_flag $ff-fnzc
2383 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2385 : dd3402 > cmp fROLc,x ;test flags
> trap_ne ;
2388 : d0fe > bne * ;failed not equal (non zero)
>
238a : ca dex
238b : 10e8 bpl trolc1
238d : a203 ldx #3
238f : tror
set_ax zp1,0
> load_flag 0
238f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2391 : 48 > pha ;use stack to load status
2392 : b513 > lda zp1,x ;precharge accu
2394 : 28 > plp
2395 : 6a ror a
tst_ax rROR,fROR,0
2396 : 08 > php ;save flags
2397 : dd2802 > cmp rROR,x ;test result
> trap_ne
239a : d0fe > bne * ;failed not equal (non zero)
>
239c : 68 > pla ;load status
> eor_flag 0
239d : 4930 > eor #0|fao ;invert expected flags + always on bits
>
239f : dd3802 > cmp fROR,x ;test flags
> trap_ne ;
23a2 : d0fe > bne * ;failed not equal (non zero)
>
23a4 : ca dex
23a5 : 10e8 bpl tror
23a7 : a203 ldx #3
23a9 : tror1
set_ax zp1,$ff-fc
> load_flag $ff-fc
23a9 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
23ab : 48 > pha ;use stack to load status
23ac : b513 > lda zp1,x ;precharge accu
23ae : 28 > plp
23af : 6a ror a
tst_ax rROR,fROR,$ff-fnzc
23b0 : 08 > php ;save flags
23b1 : dd2802 > cmp rROR,x ;test result
> trap_ne
23b4 : d0fe > bne * ;failed not equal (non zero)
>
23b6 : 68 > pla ;load status
> eor_flag $ff-fnzc
23b7 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
23b9 : dd3802 > cmp fROR,x ;test flags
> trap_ne ;
23bc : d0fe > bne * ;failed not equal (non zero)
>
23be : ca dex
23bf : 10e8 bpl tror1
23c1 : a203 ldx #3
23c3 : trorc
set_ax zp1,fc
> load_flag fc
23c3 : a901 > lda #fc ;allow test to change I-flag (no mask)
>
23c5 : 48 > pha ;use stack to load status
23c6 : b513 > lda zp1,x ;precharge accu
23c8 : 28 > plp
23c9 : 6a ror a
tst_ax rRORc,fRORc,0
23ca : 08 > php ;save flags
23cb : dd2c02 > cmp rRORc,x ;test result
> trap_ne
23ce : d0fe > bne * ;failed not equal (non zero)
>
23d0 : 68 > pla ;load status
> eor_flag 0
23d1 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
23d3 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne ;
23d6 : d0fe > bne * ;failed not equal (non zero)
>
23d8 : ca dex
23d9 : 10e8 bpl trorc
23db : a203 ldx #3
23dd : trorc1
set_ax zp1,$ff
> load_flag $ff
23dd : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
23df : 48 > pha ;use stack to load status
23e0 : b513 > lda zp1,x ;precharge accu
23e2 : 28 > plp
23e3 : 6a ror a
tst_ax rRORc,fRORc,$ff-fnzc
23e4 : 08 > php ;save flags
23e5 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
23e8 : d0fe > bne * ;failed not equal (non zero)
>
23ea : 68 > pla ;load status
> eor_flag $ff-fnzc
23eb : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
23ed : dd3c02 > cmp fRORc,x ;test flags
> trap_ne ;
23f0 : d0fe > bne * ;failed not equal (non zero)
>
23f2 : ca dex
23f3 : 10e8 bpl trorc1
next_test
23f5 : ad0002 > lda test_case ;previous test
23f8 : c91d > cmp #test_num
> trap_ne ;test is out of sequence
23fa : d0fe > bne * ;failed not equal (non zero)
>
001e = >test_num = test_num + 1
23fc : a91e > lda #test_num ;*** next tests' number
23fe : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; shifts - zeropage
2401 : a203 ldx #3
2403 : tasl2
set_z zp1,0
> load_flag 0
2403 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2405 : 48 > pha ;use stack to load status
2406 : b513 > lda zp1,x ;load to zeropage
2408 : 850c > sta zpt
240a : 28 > plp
240b : 060c asl zpt
tst_z rASL,fASL,0
240d : 08 > php ;save flags
240e : a50c > lda zpt
2410 : dd2002 > cmp rASL,x ;test result
> trap_ne
2413 : d0fe > bne * ;failed not equal (non zero)
>
2415 : 68 > pla ;load status
> eor_flag 0
2416 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2418 : dd3002 > cmp fASL,x ;test flags
> trap_ne
241b : d0fe > bne * ;failed not equal (non zero)
>
241d : ca dex
241e : 10e3 bpl tasl2
2420 : a203 ldx #3
2422 : tasl3
set_z zp1,$ff
> load_flag $ff
2422 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2424 : 48 > pha ;use stack to load status
2425 : b513 > lda zp1,x ;load to zeropage
2427 : 850c > sta zpt
2429 : 28 > plp
242a : 060c asl zpt
tst_z rASL,fASL,$ff-fnzc
242c : 08 > php ;save flags
242d : a50c > lda zpt
242f : dd2002 > cmp rASL,x ;test result
> trap_ne
2432 : d0fe > bne * ;failed not equal (non zero)
>
2434 : 68 > pla ;load status
> eor_flag $ff-fnzc
2435 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2437 : dd3002 > cmp fASL,x ;test flags
> trap_ne
243a : d0fe > bne * ;failed not equal (non zero)
>
243c : ca dex
243d : 10e3 bpl tasl3
243f : a203 ldx #3
2441 : tlsr2
set_z zp1,0
> load_flag 0
2441 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2443 : 48 > pha ;use stack to load status
2444 : b513 > lda zp1,x ;load to zeropage
2446 : 850c > sta zpt
2448 : 28 > plp
2449 : 460c lsr zpt
tst_z rLSR,fLSR,0
244b : 08 > php ;save flags
244c : a50c > lda zpt
244e : dd2802 > cmp rLSR,x ;test result
> trap_ne
2451 : d0fe > bne * ;failed not equal (non zero)
>
2453 : 68 > pla ;load status
> eor_flag 0
2454 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2456 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
2459 : d0fe > bne * ;failed not equal (non zero)
>
245b : ca dex
245c : 10e3 bpl tlsr2
245e : a203 ldx #3
2460 : tlsr3
set_z zp1,$ff
> load_flag $ff
2460 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2462 : 48 > pha ;use stack to load status
2463 : b513 > lda zp1,x ;load to zeropage
2465 : 850c > sta zpt
2467 : 28 > plp
2468 : 460c lsr zpt
tst_z rLSR,fLSR,$ff-fnzc
246a : 08 > php ;save flags
246b : a50c > lda zpt
246d : dd2802 > cmp rLSR,x ;test result
> trap_ne
2470 : d0fe > bne * ;failed not equal (non zero)
>
2472 : 68 > pla ;load status
> eor_flag $ff-fnzc
2473 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2475 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
2478 : d0fe > bne * ;failed not equal (non zero)
>
247a : ca dex
247b : 10e3 bpl tlsr3
247d : a203 ldx #3
247f : trol2
set_z zp1,0
> load_flag 0
247f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2481 : 48 > pha ;use stack to load status
2482 : b513 > lda zp1,x ;load to zeropage
2484 : 850c > sta zpt
2486 : 28 > plp
2487 : 260c rol zpt
tst_z rROL,fROL,0
2489 : 08 > php ;save flags
248a : a50c > lda zpt
248c : dd2002 > cmp rROL,x ;test result
> trap_ne
248f : d0fe > bne * ;failed not equal (non zero)
>
2491 : 68 > pla ;load status
> eor_flag 0
2492 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2494 : dd3002 > cmp fROL,x ;test flags
> trap_ne
2497 : d0fe > bne * ;failed not equal (non zero)
>
2499 : ca dex
249a : 10e3 bpl trol2
249c : a203 ldx #3
249e : trol3
set_z zp1,$ff-fc
> load_flag $ff-fc
249e : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
24a0 : 48 > pha ;use stack to load status
24a1 : b513 > lda zp1,x ;load to zeropage
24a3 : 850c > sta zpt
24a5 : 28 > plp
24a6 : 260c rol zpt
tst_z rROL,fROL,$ff-fnzc
24a8 : 08 > php ;save flags
24a9 : a50c > lda zpt
24ab : dd2002 > cmp rROL,x ;test result
> trap_ne
24ae : d0fe > bne * ;failed not equal (non zero)
>
24b0 : 68 > pla ;load status
> eor_flag $ff-fnzc
24b1 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
24b3 : dd3002 > cmp fROL,x ;test flags
> trap_ne
24b6 : d0fe > bne * ;failed not equal (non zero)
>
24b8 : ca dex
24b9 : 10e3 bpl trol3
24bb : a203 ldx #3
24bd : trolc2
set_z zp1,fc
> load_flag fc
24bd : a901 > lda #fc ;allow test to change I-flag (no mask)
>
24bf : 48 > pha ;use stack to load status
24c0 : b513 > lda zp1,x ;load to zeropage
24c2 : 850c > sta zpt
24c4 : 28 > plp
24c5 : 260c rol zpt
tst_z rROLc,fROLc,0
24c7 : 08 > php ;save flags
24c8 : a50c > lda zpt
24ca : dd2402 > cmp rROLc,x ;test result
> trap_ne
24cd : d0fe > bne * ;failed not equal (non zero)
>
24cf : 68 > pla ;load status
> eor_flag 0
24d0 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
24d2 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
24d5 : d0fe > bne * ;failed not equal (non zero)
>
24d7 : ca dex
24d8 : 10e3 bpl trolc2
24da : a203 ldx #3
24dc : trolc3
set_z zp1,$ff
> load_flag $ff
24dc : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
24de : 48 > pha ;use stack to load status
24df : b513 > lda zp1,x ;load to zeropage
24e1 : 850c > sta zpt
24e3 : 28 > plp
24e4 : 260c rol zpt
tst_z rROLc,fROLc,$ff-fnzc
24e6 : 08 > php ;save flags
24e7 : a50c > lda zpt
24e9 : dd2402 > cmp rROLc,x ;test result
> trap_ne
24ec : d0fe > bne * ;failed not equal (non zero)
>
24ee : 68 > pla ;load status
> eor_flag $ff-fnzc
24ef : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
24f1 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
24f4 : d0fe > bne * ;failed not equal (non zero)
>
24f6 : ca dex
24f7 : 10e3 bpl trolc3
24f9 : a203 ldx #3
24fb : tror2
set_z zp1,0
> load_flag 0
24fb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
24fd : 48 > pha ;use stack to load status
24fe : b513 > lda zp1,x ;load to zeropage
2500 : 850c > sta zpt
2502 : 28 > plp
2503 : 660c ror zpt
tst_z rROR,fROR,0
2505 : 08 > php ;save flags
2506 : a50c > lda zpt
2508 : dd2802 > cmp rROR,x ;test result
> trap_ne
250b : d0fe > bne * ;failed not equal (non zero)
>
250d : 68 > pla ;load status
> eor_flag 0
250e : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2510 : dd3802 > cmp fROR,x ;test flags
> trap_ne
2513 : d0fe > bne * ;failed not equal (non zero)
>
2515 : ca dex
2516 : 10e3 bpl tror2
2518 : a203 ldx #3
251a : tror3
set_z zp1,$ff-fc
> load_flag $ff-fc
251a : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
251c : 48 > pha ;use stack to load status
251d : b513 > lda zp1,x ;load to zeropage
251f : 850c > sta zpt
2521 : 28 > plp
2522 : 660c ror zpt
tst_z rROR,fROR,$ff-fnzc
2524 : 08 > php ;save flags
2525 : a50c > lda zpt
2527 : dd2802 > cmp rROR,x ;test result
> trap_ne
252a : d0fe > bne * ;failed not equal (non zero)
>
252c : 68 > pla ;load status
> eor_flag $ff-fnzc
252d : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
252f : dd3802 > cmp fROR,x ;test flags
> trap_ne
2532 : d0fe > bne * ;failed not equal (non zero)
>
2534 : ca dex
2535 : 10e3 bpl tror3
2537 : a203 ldx #3
2539 : trorc2
set_z zp1,fc
> load_flag fc
2539 : a901 > lda #fc ;allow test to change I-flag (no mask)
>
253b : 48 > pha ;use stack to load status
253c : b513 > lda zp1,x ;load to zeropage
253e : 850c > sta zpt
2540 : 28 > plp
2541 : 660c ror zpt
tst_z rRORc,fRORc,0
2543 : 08 > php ;save flags
2544 : a50c > lda zpt
2546 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
2549 : d0fe > bne * ;failed not equal (non zero)
>
254b : 68 > pla ;load status
> eor_flag 0
254c : 4930 > eor #0|fao ;invert expected flags + always on bits
>
254e : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2551 : d0fe > bne * ;failed not equal (non zero)
>
2553 : ca dex
2554 : 10e3 bpl trorc2
2556 : a203 ldx #3
2558 : trorc3
set_z zp1,$ff
> load_flag $ff
2558 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
255a : 48 > pha ;use stack to load status
255b : b513 > lda zp1,x ;load to zeropage
255d : 850c > sta zpt
255f : 28 > plp
2560 : 660c ror zpt
tst_z rRORc,fRORc,$ff-fnzc
2562 : 08 > php ;save flags
2563 : a50c > lda zpt
2565 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
2568 : d0fe > bne * ;failed not equal (non zero)
>
256a : 68 > pla ;load status
> eor_flag $ff-fnzc
256b : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
256d : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2570 : d0fe > bne * ;failed not equal (non zero)
>
2572 : ca dex
2573 : 10e3 bpl trorc3
next_test
2575 : ad0002 > lda test_case ;previous test
2578 : c91e > cmp #test_num
> trap_ne ;test is out of sequence
257a : d0fe > bne * ;failed not equal (non zero)
>
001f = >test_num = test_num + 1
257c : a91f > lda #test_num ;*** next tests' number
257e : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; shifts - absolute
2581 : a203 ldx #3
2583 : tasl4
set_abs zp1,0
> load_flag 0
2583 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2585 : 48 > pha ;use stack to load status
2586 : b513 > lda zp1,x ;load to memory
2588 : 8d0302 > sta abst
258b : 28 > plp
258c : 0e0302 asl abst
tst_abs rASL,fASL,0
258f : 08 > php ;save flags
2590 : ad0302 > lda abst
2593 : dd2002 > cmp rASL,x ;test result
> trap_ne
2596 : d0fe > bne * ;failed not equal (non zero)
>
2598 : 68 > pla ;load status
> eor_flag 0
2599 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
259b : dd3002 > cmp fASL,x ;test flags
> trap_ne
259e : d0fe > bne * ;failed not equal (non zero)
>
25a0 : ca dex
25a1 : 10e0 bpl tasl4
25a3 : a203 ldx #3
25a5 : tasl5
set_abs zp1,$ff
> load_flag $ff
25a5 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
25a7 : 48 > pha ;use stack to load status
25a8 : b513 > lda zp1,x ;load to memory
25aa : 8d0302 > sta abst
25ad : 28 > plp
25ae : 0e0302 asl abst
tst_abs rASL,fASL,$ff-fnzc
25b1 : 08 > php ;save flags
25b2 : ad0302 > lda abst
25b5 : dd2002 > cmp rASL,x ;test result
> trap_ne
25b8 : d0fe > bne * ;failed not equal (non zero)
>
25ba : 68 > pla ;load status
> eor_flag $ff-fnzc
25bb : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
25bd : dd3002 > cmp fASL,x ;test flags
> trap_ne
25c0 : d0fe > bne * ;failed not equal (non zero)
>
25c2 : ca dex
25c3 : 10e0 bpl tasl5
25c5 : a203 ldx #3
25c7 : tlsr4
set_abs zp1,0
> load_flag 0
25c7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
25c9 : 48 > pha ;use stack to load status
25ca : b513 > lda zp1,x ;load to memory
25cc : 8d0302 > sta abst
25cf : 28 > plp
25d0 : 4e0302 lsr abst
tst_abs rLSR,fLSR,0
25d3 : 08 > php ;save flags
25d4 : ad0302 > lda abst
25d7 : dd2802 > cmp rLSR,x ;test result
> trap_ne
25da : d0fe > bne * ;failed not equal (non zero)
>
25dc : 68 > pla ;load status
> eor_flag 0
25dd : 4930 > eor #0|fao ;invert expected flags + always on bits
>
25df : dd3802 > cmp fLSR,x ;test flags
> trap_ne
25e2 : d0fe > bne * ;failed not equal (non zero)
>
25e4 : ca dex
25e5 : 10e0 bpl tlsr4
25e7 : a203 ldx #3
25e9 : tlsr5
set_abs zp1,$ff
> load_flag $ff
25e9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
25eb : 48 > pha ;use stack to load status
25ec : b513 > lda zp1,x ;load to memory
25ee : 8d0302 > sta abst
25f1 : 28 > plp
25f2 : 4e0302 lsr abst
tst_abs rLSR,fLSR,$ff-fnzc
25f5 : 08 > php ;save flags
25f6 : ad0302 > lda abst
25f9 : dd2802 > cmp rLSR,x ;test result
> trap_ne
25fc : d0fe > bne * ;failed not equal (non zero)
>
25fe : 68 > pla ;load status
> eor_flag $ff-fnzc
25ff : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2601 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
2604 : d0fe > bne * ;failed not equal (non zero)
>
2606 : ca dex
2607 : 10e0 bpl tlsr5
2609 : a203 ldx #3
260b : trol4
set_abs zp1,0
> load_flag 0
260b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
260d : 48 > pha ;use stack to load status
260e : b513 > lda zp1,x ;load to memory
2610 : 8d0302 > sta abst
2613 : 28 > plp
2614 : 2e0302 rol abst
tst_abs rROL,fROL,0
2617 : 08 > php ;save flags
2618 : ad0302 > lda abst
261b : dd2002 > cmp rROL,x ;test result
> trap_ne
261e : d0fe > bne * ;failed not equal (non zero)
>
2620 : 68 > pla ;load status
> eor_flag 0
2621 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2623 : dd3002 > cmp fROL,x ;test flags
> trap_ne
2626 : d0fe > bne * ;failed not equal (non zero)
>
2628 : ca dex
2629 : 10e0 bpl trol4
262b : a203 ldx #3
262d : trol5
set_abs zp1,$ff-fc
> load_flag $ff-fc
262d : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
262f : 48 > pha ;use stack to load status
2630 : b513 > lda zp1,x ;load to memory
2632 : 8d0302 > sta abst
2635 : 28 > plp
2636 : 2e0302 rol abst
tst_abs rROL,fROL,$ff-fnzc
2639 : 08 > php ;save flags
263a : ad0302 > lda abst
263d : dd2002 > cmp rROL,x ;test result
> trap_ne
2640 : d0fe > bne * ;failed not equal (non zero)
>
2642 : 68 > pla ;load status
> eor_flag $ff-fnzc
2643 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2645 : dd3002 > cmp fROL,x ;test flags
> trap_ne
2648 : d0fe > bne * ;failed not equal (non zero)
>
264a : ca dex
264b : 10e0 bpl trol5
264d : a203 ldx #3
264f : trolc4
set_abs zp1,fc
> load_flag fc
264f : a901 > lda #fc ;allow test to change I-flag (no mask)
>
2651 : 48 > pha ;use stack to load status
2652 : b513 > lda zp1,x ;load to memory
2654 : 8d0302 > sta abst
2657 : 28 > plp
2658 : 2e0302 rol abst
tst_abs rROLc,fROLc,0
265b : 08 > php ;save flags
265c : ad0302 > lda abst
265f : dd2402 > cmp rROLc,x ;test result
> trap_ne
2662 : d0fe > bne * ;failed not equal (non zero)
>
2664 : 68 > pla ;load status
> eor_flag 0
2665 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2667 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
266a : d0fe > bne * ;failed not equal (non zero)
>
266c : ca dex
266d : 10e0 bpl trolc4
266f : a203 ldx #3
2671 : trolc5
set_abs zp1,$ff
> load_flag $ff
2671 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2673 : 48 > pha ;use stack to load status
2674 : b513 > lda zp1,x ;load to memory
2676 : 8d0302 > sta abst
2679 : 28 > plp
267a : 2e0302 rol abst
tst_abs rROLc,fROLc,$ff-fnzc
267d : 08 > php ;save flags
267e : ad0302 > lda abst
2681 : dd2402 > cmp rROLc,x ;test result
> trap_ne
2684 : d0fe > bne * ;failed not equal (non zero)
>
2686 : 68 > pla ;load status
> eor_flag $ff-fnzc
2687 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2689 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
268c : d0fe > bne * ;failed not equal (non zero)
>
268e : ca dex
268f : 10e0 bpl trolc5
2691 : a203 ldx #3
2693 : tror4
set_abs zp1,0
> load_flag 0
2693 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2695 : 48 > pha ;use stack to load status
2696 : b513 > lda zp1,x ;load to memory
2698 : 8d0302 > sta abst
269b : 28 > plp
269c : 6e0302 ror abst
tst_abs rROR,fROR,0
269f : 08 > php ;save flags
26a0 : ad0302 > lda abst
26a3 : dd2802 > cmp rROR,x ;test result
> trap_ne
26a6 : d0fe > bne * ;failed not equal (non zero)
>
26a8 : 68 > pla ;load status
> eor_flag 0
26a9 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
26ab : dd3802 > cmp fROR,x ;test flags
> trap_ne
26ae : d0fe > bne * ;failed not equal (non zero)
>
26b0 : ca dex
26b1 : 10e0 bpl tror4
26b3 : a203 ldx #3
26b5 : tror5
set_abs zp1,$ff-fc
> load_flag $ff-fc
26b5 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
26b7 : 48 > pha ;use stack to load status
26b8 : b513 > lda zp1,x ;load to memory
26ba : 8d0302 > sta abst
26bd : 28 > plp
26be : 6e0302 ror abst
tst_abs rROR,fROR,$ff-fnzc
26c1 : 08 > php ;save flags
26c2 : ad0302 > lda abst
26c5 : dd2802 > cmp rROR,x ;test result
> trap_ne
26c8 : d0fe > bne * ;failed not equal (non zero)
>
26ca : 68 > pla ;load status
> eor_flag $ff-fnzc
26cb : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
26cd : dd3802 > cmp fROR,x ;test flags
> trap_ne
26d0 : d0fe > bne * ;failed not equal (non zero)
>
26d2 : ca dex
26d3 : 10e0 bpl tror5
26d5 : a203 ldx #3
26d7 : trorc4
set_abs zp1,fc
> load_flag fc
26d7 : a901 > lda #fc ;allow test to change I-flag (no mask)
>
26d9 : 48 > pha ;use stack to load status
26da : b513 > lda zp1,x ;load to memory
26dc : 8d0302 > sta abst
26df : 28 > plp
26e0 : 6e0302 ror abst
tst_abs rRORc,fRORc,0
26e3 : 08 > php ;save flags
26e4 : ad0302 > lda abst
26e7 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
26ea : d0fe > bne * ;failed not equal (non zero)
>
26ec : 68 > pla ;load status
> eor_flag 0
26ed : 4930 > eor #0|fao ;invert expected flags + always on bits
>
26ef : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
26f2 : d0fe > bne * ;failed not equal (non zero)
>
26f4 : ca dex
26f5 : 10e0 bpl trorc4
26f7 : a203 ldx #3
26f9 : trorc5
set_abs zp1,$ff
> load_flag $ff
26f9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
26fb : 48 > pha ;use stack to load status
26fc : b513 > lda zp1,x ;load to memory
26fe : 8d0302 > sta abst
2701 : 28 > plp
2702 : 6e0302 ror abst
tst_abs rRORc,fRORc,$ff-fnzc
2705 : 08 > php ;save flags
2706 : ad0302 > lda abst
2709 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
270c : d0fe > bne * ;failed not equal (non zero)
>
270e : 68 > pla ;load status
> eor_flag $ff-fnzc
270f : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2711 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2714 : d0fe > bne * ;failed not equal (non zero)
>
2716 : ca dex
2717 : 10e0 bpl trorc5
next_test
2719 : ad0002 > lda test_case ;previous test
271c : c91f > cmp #test_num
> trap_ne ;test is out of sequence
271e : d0fe > bne * ;failed not equal (non zero)
>
0020 = >test_num = test_num + 1
2720 : a920 > lda #test_num ;*** next tests' number
2722 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; shifts - zp indexed
2725 : a203 ldx #3
2727 : tasl6
set_zx zp1,0
> load_flag 0
2727 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2729 : 48 > pha ;use stack to load status
272a : b513 > lda zp1,x ;load to indexed zeropage
272c : 950c > sta zpt,x
272e : 28 > plp
272f : 160c asl zpt,x
tst_zx rASL,fASL,0
2731 : 08 > php ;save flags
2732 : b50c > lda zpt,x
2734 : dd2002 > cmp rASL,x ;test result
> trap_ne
2737 : d0fe > bne * ;failed not equal (non zero)
>
2739 : 68 > pla ;load status
> eor_flag 0
273a : 4930 > eor #0|fao ;invert expected flags + always on bits
>
273c : dd3002 > cmp fASL,x ;test flags
> trap_ne
273f : d0fe > bne * ;failed not equal (non zero)
>
2741 : ca dex
2742 : 10e3 bpl tasl6
2744 : a203 ldx #3
2746 : tasl7
set_zx zp1,$ff
> load_flag $ff
2746 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2748 : 48 > pha ;use stack to load status
2749 : b513 > lda zp1,x ;load to indexed zeropage
274b : 950c > sta zpt,x
274d : 28 > plp
274e : 160c asl zpt,x
tst_zx rASL,fASL,$ff-fnzc
2750 : 08 > php ;save flags
2751 : b50c > lda zpt,x
2753 : dd2002 > cmp rASL,x ;test result
> trap_ne
2756 : d0fe > bne * ;failed not equal (non zero)
>
2758 : 68 > pla ;load status
> eor_flag $ff-fnzc
2759 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
275b : dd3002 > cmp fASL,x ;test flags
> trap_ne
275e : d0fe > bne * ;failed not equal (non zero)
>
2760 : ca dex
2761 : 10e3 bpl tasl7
2763 : a203 ldx #3
2765 : tlsr6
set_zx zp1,0
> load_flag 0
2765 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2767 : 48 > pha ;use stack to load status
2768 : b513 > lda zp1,x ;load to indexed zeropage
276a : 950c > sta zpt,x
276c : 28 > plp
276d : 560c lsr zpt,x
tst_zx rLSR,fLSR,0
276f : 08 > php ;save flags
2770 : b50c > lda zpt,x
2772 : dd2802 > cmp rLSR,x ;test result
> trap_ne
2775 : d0fe > bne * ;failed not equal (non zero)
>
2777 : 68 > pla ;load status
> eor_flag 0
2778 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
277a : dd3802 > cmp fLSR,x ;test flags
> trap_ne
277d : d0fe > bne * ;failed not equal (non zero)
>
277f : ca dex
2780 : 10e3 bpl tlsr6
2782 : a203 ldx #3
2784 : tlsr7
set_zx zp1,$ff
> load_flag $ff
2784 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2786 : 48 > pha ;use stack to load status
2787 : b513 > lda zp1,x ;load to indexed zeropage
2789 : 950c > sta zpt,x
278b : 28 > plp
278c : 560c lsr zpt,x
tst_zx rLSR,fLSR,$ff-fnzc
278e : 08 > php ;save flags
278f : b50c > lda zpt,x
2791 : dd2802 > cmp rLSR,x ;test result
> trap_ne
2794 : d0fe > bne * ;failed not equal (non zero)
>
2796 : 68 > pla ;load status
> eor_flag $ff-fnzc
2797 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2799 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
279c : d0fe > bne * ;failed not equal (non zero)
>
279e : ca dex
279f : 10e3 bpl tlsr7
27a1 : a203 ldx #3
27a3 : trol6
set_zx zp1,0
> load_flag 0
27a3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
27a5 : 48 > pha ;use stack to load status
27a6 : b513 > lda zp1,x ;load to indexed zeropage
27a8 : 950c > sta zpt,x
27aa : 28 > plp
27ab : 360c rol zpt,x
tst_zx rROL,fROL,0
27ad : 08 > php ;save flags
27ae : b50c > lda zpt,x
27b0 : dd2002 > cmp rROL,x ;test result
> trap_ne
27b3 : d0fe > bne * ;failed not equal (non zero)
>
27b5 : 68 > pla ;load status
> eor_flag 0
27b6 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
27b8 : dd3002 > cmp fROL,x ;test flags
> trap_ne
27bb : d0fe > bne * ;failed not equal (non zero)
>
27bd : ca dex
27be : 10e3 bpl trol6
27c0 : a203 ldx #3
27c2 : trol7
set_zx zp1,$ff-fc
> load_flag $ff-fc
27c2 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
27c4 : 48 > pha ;use stack to load status
27c5 : b513 > lda zp1,x ;load to indexed zeropage
27c7 : 950c > sta zpt,x
27c9 : 28 > plp
27ca : 360c rol zpt,x
tst_zx rROL,fROL,$ff-fnzc
27cc : 08 > php ;save flags
27cd : b50c > lda zpt,x
27cf : dd2002 > cmp rROL,x ;test result
> trap_ne
27d2 : d0fe > bne * ;failed not equal (non zero)
>
27d4 : 68 > pla ;load status
> eor_flag $ff-fnzc
27d5 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
27d7 : dd3002 > cmp fROL,x ;test flags
> trap_ne
27da : d0fe > bne * ;failed not equal (non zero)
>
27dc : ca dex
27dd : 10e3 bpl trol7
27df : a203 ldx #3
27e1 : trolc6
set_zx zp1,fc
> load_flag fc
27e1 : a901 > lda #fc ;allow test to change I-flag (no mask)
>
27e3 : 48 > pha ;use stack to load status
27e4 : b513 > lda zp1,x ;load to indexed zeropage
27e6 : 950c > sta zpt,x
27e8 : 28 > plp
27e9 : 360c rol zpt,x
tst_zx rROLc,fROLc,0
27eb : 08 > php ;save flags
27ec : b50c > lda zpt,x
27ee : dd2402 > cmp rROLc,x ;test result
> trap_ne
27f1 : d0fe > bne * ;failed not equal (non zero)
>
27f3 : 68 > pla ;load status
> eor_flag 0
27f4 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
27f6 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
27f9 : d0fe > bne * ;failed not equal (non zero)
>
27fb : ca dex
27fc : 10e3 bpl trolc6
27fe : a203 ldx #3
2800 : trolc7
set_zx zp1,$ff
> load_flag $ff
2800 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2802 : 48 > pha ;use stack to load status
2803 : b513 > lda zp1,x ;load to indexed zeropage
2805 : 950c > sta zpt,x
2807 : 28 > plp
2808 : 360c rol zpt,x
tst_zx rROLc,fROLc,$ff-fnzc
280a : 08 > php ;save flags
280b : b50c > lda zpt,x
280d : dd2402 > cmp rROLc,x ;test result
> trap_ne
2810 : d0fe > bne * ;failed not equal (non zero)
>
2812 : 68 > pla ;load status
> eor_flag $ff-fnzc
2813 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2815 : dd3402 > cmp fROLc,x ;test flags
> trap_ne
2818 : d0fe > bne * ;failed not equal (non zero)
>
281a : ca dex
281b : 10e3 bpl trolc7
281d : a203 ldx #3
281f : tror6
set_zx zp1,0
> load_flag 0
281f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2821 : 48 > pha ;use stack to load status
2822 : b513 > lda zp1,x ;load to indexed zeropage
2824 : 950c > sta zpt,x
2826 : 28 > plp
2827 : 760c ror zpt,x
tst_zx rROR,fROR,0
2829 : 08 > php ;save flags
282a : b50c > lda zpt,x
282c : dd2802 > cmp rROR,x ;test result
> trap_ne
282f : d0fe > bne * ;failed not equal (non zero)
>
2831 : 68 > pla ;load status
> eor_flag 0
2832 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2834 : dd3802 > cmp fROR,x ;test flags
> trap_ne
2837 : d0fe > bne * ;failed not equal (non zero)
>
2839 : ca dex
283a : 10e3 bpl tror6
283c : a203 ldx #3
283e : tror7
set_zx zp1,$ff-fc
> load_flag $ff-fc
283e : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
2840 : 48 > pha ;use stack to load status
2841 : b513 > lda zp1,x ;load to indexed zeropage
2843 : 950c > sta zpt,x
2845 : 28 > plp
2846 : 760c ror zpt,x
tst_zx rROR,fROR,$ff-fnzc
2848 : 08 > php ;save flags
2849 : b50c > lda zpt,x
284b : dd2802 > cmp rROR,x ;test result
> trap_ne
284e : d0fe > bne * ;failed not equal (non zero)
>
2850 : 68 > pla ;load status
> eor_flag $ff-fnzc
2851 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2853 : dd3802 > cmp fROR,x ;test flags
> trap_ne
2856 : d0fe > bne * ;failed not equal (non zero)
>
2858 : ca dex
2859 : 10e3 bpl tror7
285b : a203 ldx #3
285d : trorc6
set_zx zp1,fc
> load_flag fc
285d : a901 > lda #fc ;allow test to change I-flag (no mask)
>
285f : 48 > pha ;use stack to load status
2860 : b513 > lda zp1,x ;load to indexed zeropage
2862 : 950c > sta zpt,x
2864 : 28 > plp
2865 : 760c ror zpt,x
tst_zx rRORc,fRORc,0
2867 : 08 > php ;save flags
2868 : b50c > lda zpt,x
286a : dd2c02 > cmp rRORc,x ;test result
> trap_ne
286d : d0fe > bne * ;failed not equal (non zero)
>
286f : 68 > pla ;load status
> eor_flag 0
2870 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2872 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2875 : d0fe > bne * ;failed not equal (non zero)
>
2877 : ca dex
2878 : 10e3 bpl trorc6
287a : a203 ldx #3
287c : trorc7
set_zx zp1,$ff
> load_flag $ff
287c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
287e : 48 > pha ;use stack to load status
287f : b513 > lda zp1,x ;load to indexed zeropage
2881 : 950c > sta zpt,x
2883 : 28 > plp
2884 : 760c ror zpt,x
tst_zx rRORc,fRORc,$ff-fnzc
2886 : 08 > php ;save flags
2887 : b50c > lda zpt,x
2889 : dd2c02 > cmp rRORc,x ;test result
> trap_ne
288c : d0fe > bne * ;failed not equal (non zero)
>
288e : 68 > pla ;load status
> eor_flag $ff-fnzc
288f : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2891 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2894 : d0fe > bne * ;failed not equal (non zero)
>
2896 : ca dex
2897 : 10e3 bpl trorc7
next_test
2899 : ad0002 > lda test_case ;previous test
289c : c920 > cmp #test_num
> trap_ne ;test is out of sequence
289e : d0fe > bne * ;failed not equal (non zero)
>
0021 = >test_num = test_num + 1
28a0 : a921 > lda #test_num ;*** next tests' number
28a2 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; shifts - abs indexed
28a5 : a203 ldx #3
28a7 : tasl8
set_absx zp1,0
> load_flag 0
28a7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
28a9 : 48 > pha ;use stack to load status
28aa : b513 > lda zp1,x ;load to indexed memory
28ac : 9d0302 > sta abst,x
28af : 28 > plp
28b0 : 1e0302 asl abst,x
tst_absx rASL,fASL,0
28b3 : 08 > php ;save flags
28b4 : bd0302 > lda abst,x
28b7 : dd2002 > cmp rASL,x ;test result
> trap_ne
28ba : d0fe > bne * ;failed not equal (non zero)
>
28bc : 68 > pla ;load status
> eor_flag 0
28bd : 4930 > eor #0|fao ;invert expected flags + always on bits
>
28bf : dd3002 > cmp fASL,x ;test flags
> trap_ne
28c2 : d0fe > bne * ;failed not equal (non zero)
>
28c4 : ca dex
28c5 : 10e0 bpl tasl8
28c7 : a203 ldx #3
28c9 : tasl9
set_absx zp1,$ff
> load_flag $ff
28c9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
28cb : 48 > pha ;use stack to load status
28cc : b513 > lda zp1,x ;load to indexed memory
28ce : 9d0302 > sta abst,x
28d1 : 28 > plp
28d2 : 1e0302 asl abst,x
tst_absx rASL,fASL,$ff-fnzc
28d5 : 08 > php ;save flags
28d6 : bd0302 > lda abst,x
28d9 : dd2002 > cmp rASL,x ;test result
> trap_ne
28dc : d0fe > bne * ;failed not equal (non zero)
>
28de : 68 > pla ;load status
> eor_flag $ff-fnzc
28df : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
28e1 : dd3002 > cmp fASL,x ;test flags
> trap_ne
28e4 : d0fe > bne * ;failed not equal (non zero)
>
28e6 : ca dex
28e7 : 10e0 bpl tasl9
28e9 : a203 ldx #3
28eb : tlsr8
set_absx zp1,0
> load_flag 0
28eb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
28ed : 48 > pha ;use stack to load status
28ee : b513 > lda zp1,x ;load to indexed memory
28f0 : 9d0302 > sta abst,x
28f3 : 28 > plp
28f4 : 5e0302 lsr abst,x
tst_absx rLSR,fLSR,0
28f7 : 08 > php ;save flags
28f8 : bd0302 > lda abst,x
28fb : dd2802 > cmp rLSR,x ;test result
> trap_ne
28fe : d0fe > bne * ;failed not equal (non zero)
>
2900 : 68 > pla ;load status
> eor_flag 0
2901 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2903 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
2906 : d0fe > bne * ;failed not equal (non zero)
>
2908 : ca dex
2909 : 10e0 bpl tlsr8
290b : a203 ldx #3
290d : tlsr9
set_absx zp1,$ff
> load_flag $ff
290d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
290f : 48 > pha ;use stack to load status
2910 : b513 > lda zp1,x ;load to indexed memory
2912 : 9d0302 > sta abst,x
2915 : 28 > plp
2916 : 5e0302 lsr abst,x
tst_absx rLSR,fLSR,$ff-fnzc
2919 : 08 > php ;save flags
291a : bd0302 > lda abst,x
291d : dd2802 > cmp rLSR,x ;test result
> trap_ne
2920 : d0fe > bne * ;failed not equal (non zero)
>
2922 : 68 > pla ;load status
> eor_flag $ff-fnzc
2923 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2925 : dd3802 > cmp fLSR,x ;test flags
> trap_ne
2928 : d0fe > bne * ;failed not equal (non zero)
>
292a : ca dex
292b : 10e0 bpl tlsr9
292d : a203 ldx #3
292f : trol8
set_absx zp1,0
> load_flag 0
292f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2931 : 48 > pha ;use stack to load status
2932 : b513 > lda zp1,x ;load to indexed memory
2934 : 9d0302 > sta abst,x
2937 : 28 > plp
2938 : 3e0302 rol abst,x
tst_absx rROL,fROL,0
293b : 08 > php ;save flags
293c : bd0302 > lda abst,x
293f : dd2002 > cmp rROL,x ;test result
> trap_ne
2942 : d0fe > bne * ;failed not equal (non zero)
>
2944 : 68 > pla ;load status
> eor_flag 0
2945 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2947 : dd3002 > cmp fROL,x ;test flags
> trap_ne
294a : d0fe > bne * ;failed not equal (non zero)
>
294c : ca dex
294d : 10e0 bpl trol8
294f : a203 ldx #3
2951 : trol9
set_absx zp1,$ff-fc
> load_flag $ff-fc
2951 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
2953 : 48 > pha ;use stack to load status
2954 : b513 > lda zp1,x ;load to indexed memory
2956 : 9d0302 > sta abst,x
2959 : 28 > plp
295a : 3e0302 rol abst,x
tst_absx rROL,fROL,$ff-fnzc
295d : 08 > php ;save flags
295e : bd0302 > lda abst,x
2961 : dd2002 > cmp rROL,x ;test result
> trap_ne
2964 : d0fe > bne * ;failed not equal (non zero)
>
2966 : 68 > pla ;load status
> eor_flag $ff-fnzc
2967 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2969 : dd3002 > cmp fROL,x ;test flags
> trap_ne
296c : d0fe > bne * ;failed not equal (non zero)
>
296e : ca dex
296f : 10e0 bpl trol9
2971 : a203 ldx #3
2973 : trolc8
set_absx zp1,fc
> load_flag fc
2973 : a901 > lda #fc ;allow test to change I-flag (no mask)
>
2975 : 48 > pha ;use stack to load status
2976 : b513 > lda zp1,x ;load to indexed memory
2978 : 9d0302 > sta abst,x
297b : 28 > plp
297c : 3e0302 rol abst,x
tst_absx rROLc,fROLc,0
297f : 08 > php ;save flags
2980 : bd0302 > lda abst,x
2983 : dd2402 > cmp rROLc,x ;test result
> trap_ne
2986 : d0fe > bne * ;failed not equal (non zero)
>
2988 : 68 > pla ;load status
> eor_flag 0
2989 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
298b : dd3402 > cmp fROLc,x ;test flags
> trap_ne
298e : d0fe > bne * ;failed not equal (non zero)
>
2990 : ca dex
2991 : 10e0 bpl trolc8
2993 : a203 ldx #3
2995 : trolc9
set_absx zp1,$ff
> load_flag $ff
2995 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2997 : 48 > pha ;use stack to load status
2998 : b513 > lda zp1,x ;load to indexed memory
299a : 9d0302 > sta abst,x
299d : 28 > plp
299e : 3e0302 rol abst,x
tst_absx rROLc,fROLc,$ff-fnzc
29a1 : 08 > php ;save flags
29a2 : bd0302 > lda abst,x
29a5 : dd2402 > cmp rROLc,x ;test result
> trap_ne
29a8 : d0fe > bne * ;failed not equal (non zero)
>
29aa : 68 > pla ;load status
> eor_flag $ff-fnzc
29ab : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
29ad : dd3402 > cmp fROLc,x ;test flags
> trap_ne
29b0 : d0fe > bne * ;failed not equal (non zero)
>
29b2 : ca dex
29b3 : 10e0 bpl trolc9
29b5 : a203 ldx #3
29b7 : tror8
set_absx zp1,0
> load_flag 0
29b7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
29b9 : 48 > pha ;use stack to load status
29ba : b513 > lda zp1,x ;load to indexed memory
29bc : 9d0302 > sta abst,x
29bf : 28 > plp
29c0 : 7e0302 ror abst,x
tst_absx rROR,fROR,0
29c3 : 08 > php ;save flags
29c4 : bd0302 > lda abst,x
29c7 : dd2802 > cmp rROR,x ;test result
> trap_ne
29ca : d0fe > bne * ;failed not equal (non zero)
>
29cc : 68 > pla ;load status
> eor_flag 0
29cd : 4930 > eor #0|fao ;invert expected flags + always on bits
>
29cf : dd3802 > cmp fROR,x ;test flags
> trap_ne
29d2 : d0fe > bne * ;failed not equal (non zero)
>
29d4 : ca dex
29d5 : 10e0 bpl tror8
29d7 : a203 ldx #3
29d9 : tror9
set_absx zp1,$ff-fc
> load_flag $ff-fc
29d9 : a9fe > lda #$ff-fc ;allow test to change I-flag (no mask)
>
29db : 48 > pha ;use stack to load status
29dc : b513 > lda zp1,x ;load to indexed memory
29de : 9d0302 > sta abst,x
29e1 : 28 > plp
29e2 : 7e0302 ror abst,x
tst_absx rROR,fROR,$ff-fnzc
29e5 : 08 > php ;save flags
29e6 : bd0302 > lda abst,x
29e9 : dd2802 > cmp rROR,x ;test result
> trap_ne
29ec : d0fe > bne * ;failed not equal (non zero)
>
29ee : 68 > pla ;load status
> eor_flag $ff-fnzc
29ef : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
29f1 : dd3802 > cmp fROR,x ;test flags
> trap_ne
29f4 : d0fe > bne * ;failed not equal (non zero)
>
29f6 : ca dex
29f7 : 10e0 bpl tror9
29f9 : a203 ldx #3
29fb : trorc8
set_absx zp1,fc
> load_flag fc
29fb : a901 > lda #fc ;allow test to change I-flag (no mask)
>
29fd : 48 > pha ;use stack to load status
29fe : b513 > lda zp1,x ;load to indexed memory
2a00 : 9d0302 > sta abst,x
2a03 : 28 > plp
2a04 : 7e0302 ror abst,x
tst_absx rRORc,fRORc,0
2a07 : 08 > php ;save flags
2a08 : bd0302 > lda abst,x
2a0b : dd2c02 > cmp rRORc,x ;test result
> trap_ne
2a0e : d0fe > bne * ;failed not equal (non zero)
>
2a10 : 68 > pla ;load status
> eor_flag 0
2a11 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2a13 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2a16 : d0fe > bne * ;failed not equal (non zero)
>
2a18 : ca dex
2a19 : 10e0 bpl trorc8
2a1b : a203 ldx #3
2a1d : trorc9
set_absx zp1,$ff
> load_flag $ff
2a1d : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2a1f : 48 > pha ;use stack to load status
2a20 : b513 > lda zp1,x ;load to indexed memory
2a22 : 9d0302 > sta abst,x
2a25 : 28 > plp
2a26 : 7e0302 ror abst,x
tst_absx rRORc,fRORc,$ff-fnzc
2a29 : 08 > php ;save flags
2a2a : bd0302 > lda abst,x
2a2d : dd2c02 > cmp rRORc,x ;test result
> trap_ne
2a30 : d0fe > bne * ;failed not equal (non zero)
>
2a32 : 68 > pla ;load status
> eor_flag $ff-fnzc
2a33 : 497c > eor #$ff-fnzc|fao ;invert expected flags + always on bits
>
2a35 : dd3c02 > cmp fRORc,x ;test flags
> trap_ne
2a38 : d0fe > bne * ;failed not equal (non zero)
>
2a3a : ca dex
2a3b : 10e0 bpl trorc9
next_test
2a3d : ad0002 > lda test_case ;previous test
2a40 : c921 > cmp #test_num
> trap_ne ;test is out of sequence
2a42 : d0fe > bne * ;failed not equal (non zero)
>
0022 = >test_num = test_num + 1
2a44 : a922 > lda #test_num ;*** next tests' number
2a46 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; testing memory increment/decrement - INC DEC all addressing modes
; zeropage
2a49 : a200 ldx #0
2a4b : a97e lda #$7e
2a4d : 850c sta zpt
2a4f : tinc
set_stat 0
> load_flag 0
2a4f : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2a51 : 48 > pha ;use stack to load status
2a52 : 28 > plp
2a53 : e60c inc zpt
tst_z rINC,fINC,0
2a55 : 08 > php ;save flags
2a56 : a50c > lda zpt
2a58 : dd4002 > cmp rINC,x ;test result
> trap_ne
2a5b : d0fe > bne * ;failed not equal (non zero)
>
2a5d : 68 > pla ;load status
> eor_flag 0
2a5e : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2a60 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2a63 : d0fe > bne * ;failed not equal (non zero)
>
2a65 : e8 inx
2a66 : e002 cpx #2
2a68 : d004 bne tinc1
2a6a : a9fe lda #$fe
2a6c : 850c sta zpt
2a6e : e005 tinc1 cpx #5
2a70 : d0dd bne tinc
2a72 : ca dex
2a73 : e60c inc zpt
2a75 : tdec
set_stat 0
> load_flag 0
2a75 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2a77 : 48 > pha ;use stack to load status
2a78 : 28 > plp
2a79 : c60c dec zpt
tst_z rINC,fINC,0
2a7b : 08 > php ;save flags
2a7c : a50c > lda zpt
2a7e : dd4002 > cmp rINC,x ;test result
> trap_ne
2a81 : d0fe > bne * ;failed not equal (non zero)
>
2a83 : 68 > pla ;load status
> eor_flag 0
2a84 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2a86 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2a89 : d0fe > bne * ;failed not equal (non zero)
>
2a8b : ca dex
2a8c : 300a bmi tdec1
2a8e : e001 cpx #1
2a90 : d0e3 bne tdec
2a92 : a981 lda #$81
2a94 : 850c sta zpt
2a96 : d0dd bne tdec
2a98 : tdec1
2a98 : a200 ldx #0
2a9a : a97e lda #$7e
2a9c : 850c sta zpt
2a9e : tinc10
set_stat $ff
> load_flag $ff
2a9e : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2aa0 : 48 > pha ;use stack to load status
2aa1 : 28 > plp
2aa2 : e60c inc zpt
tst_z rINC,fINC,$ff-fnz
2aa4 : 08 > php ;save flags
2aa5 : a50c > lda zpt
2aa7 : dd4002 > cmp rINC,x ;test result
> trap_ne
2aaa : d0fe > bne * ;failed not equal (non zero)
>
2aac : 68 > pla ;load status
> eor_flag $ff-fnz
2aad : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2aaf : dd4502 > cmp fINC,x ;test flags
> trap_ne
2ab2 : d0fe > bne * ;failed not equal (non zero)
>
2ab4 : e8 inx
2ab5 : e002 cpx #2
2ab7 : d004 bne tinc11
2ab9 : a9fe lda #$fe
2abb : 850c sta zpt
2abd : e005 tinc11 cpx #5
2abf : d0dd bne tinc10
2ac1 : ca dex
2ac2 : e60c inc zpt
2ac4 : tdec10
set_stat $ff
> load_flag $ff
2ac4 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2ac6 : 48 > pha ;use stack to load status
2ac7 : 28 > plp
2ac8 : c60c dec zpt
tst_z rINC,fINC,$ff-fnz
2aca : 08 > php ;save flags
2acb : a50c > lda zpt
2acd : dd4002 > cmp rINC,x ;test result
> trap_ne
2ad0 : d0fe > bne * ;failed not equal (non zero)
>
2ad2 : 68 > pla ;load status
> eor_flag $ff-fnz
2ad3 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2ad5 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2ad8 : d0fe > bne * ;failed not equal (non zero)
>
2ada : ca dex
2adb : 300a bmi tdec11
2add : e001 cpx #1
2adf : d0e3 bne tdec10
2ae1 : a981 lda #$81
2ae3 : 850c sta zpt
2ae5 : d0dd bne tdec10
2ae7 : tdec11
next_test
2ae7 : ad0002 > lda test_case ;previous test
2aea : c922 > cmp #test_num
> trap_ne ;test is out of sequence
2aec : d0fe > bne * ;failed not equal (non zero)
>
0023 = >test_num = test_num + 1
2aee : a923 > lda #test_num ;*** next tests' number
2af0 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; absolute memory
2af3 : a200 ldx #0
2af5 : a97e lda #$7e
2af7 : 8d0302 sta abst
2afa : tinc2
set_stat 0
> load_flag 0
2afa : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2afc : 48 > pha ;use stack to load status
2afd : 28 > plp
2afe : ee0302 inc abst
tst_abs rINC,fINC,0
2b01 : 08 > php ;save flags
2b02 : ad0302 > lda abst
2b05 : dd4002 > cmp rINC,x ;test result
> trap_ne
2b08 : d0fe > bne * ;failed not equal (non zero)
>
2b0a : 68 > pla ;load status
> eor_flag 0
2b0b : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2b0d : dd4502 > cmp fINC,x ;test flags
> trap_ne
2b10 : d0fe > bne * ;failed not equal (non zero)
>
2b12 : e8 inx
2b13 : e002 cpx #2
2b15 : d005 bne tinc3
2b17 : a9fe lda #$fe
2b19 : 8d0302 sta abst
2b1c : e005 tinc3 cpx #5
2b1e : d0da bne tinc2
2b20 : ca dex
2b21 : ee0302 inc abst
2b24 : tdec2
set_stat 0
> load_flag 0
2b24 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2b26 : 48 > pha ;use stack to load status
2b27 : 28 > plp
2b28 : ce0302 dec abst
tst_abs rINC,fINC,0
2b2b : 08 > php ;save flags
2b2c : ad0302 > lda abst
2b2f : dd4002 > cmp rINC,x ;test result
> trap_ne
2b32 : d0fe > bne * ;failed not equal (non zero)
>
2b34 : 68 > pla ;load status
> eor_flag 0
2b35 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2b37 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2b3a : d0fe > bne * ;failed not equal (non zero)
>
2b3c : ca dex
2b3d : 300b bmi tdec3
2b3f : e001 cpx #1
2b41 : d0e1 bne tdec2
2b43 : a981 lda #$81
2b45 : 8d0302 sta abst
2b48 : d0da bne tdec2
2b4a : tdec3
2b4a : a200 ldx #0
2b4c : a97e lda #$7e
2b4e : 8d0302 sta abst
2b51 : tinc12
set_stat $ff
> load_flag $ff
2b51 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2b53 : 48 > pha ;use stack to load status
2b54 : 28 > plp
2b55 : ee0302 inc abst
tst_abs rINC,fINC,$ff-fnz
2b58 : 08 > php ;save flags
2b59 : ad0302 > lda abst
2b5c : dd4002 > cmp rINC,x ;test result
> trap_ne
2b5f : d0fe > bne * ;failed not equal (non zero)
>
2b61 : 68 > pla ;load status
> eor_flag $ff-fnz
2b62 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2b64 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2b67 : d0fe > bne * ;failed not equal (non zero)
>
2b69 : e8 inx
2b6a : e002 cpx #2
2b6c : d005 bne tinc13
2b6e : a9fe lda #$fe
2b70 : 8d0302 sta abst
2b73 : e005 tinc13 cpx #5
2b75 : d0da bne tinc12
2b77 : ca dex
2b78 : ee0302 inc abst
2b7b : tdec12
set_stat $ff
> load_flag $ff
2b7b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2b7d : 48 > pha ;use stack to load status
2b7e : 28 > plp
2b7f : ce0302 dec abst
tst_abs rINC,fINC,$ff-fnz
2b82 : 08 > php ;save flags
2b83 : ad0302 > lda abst
2b86 : dd4002 > cmp rINC,x ;test result
> trap_ne
2b89 : d0fe > bne * ;failed not equal (non zero)
>
2b8b : 68 > pla ;load status
> eor_flag $ff-fnz
2b8c : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2b8e : dd4502 > cmp fINC,x ;test flags
> trap_ne
2b91 : d0fe > bne * ;failed not equal (non zero)
>
2b93 : ca dex
2b94 : 300b bmi tdec13
2b96 : e001 cpx #1
2b98 : d0e1 bne tdec12
2b9a : a981 lda #$81
2b9c : 8d0302 sta abst
2b9f : d0da bne tdec12
2ba1 : tdec13
next_test
2ba1 : ad0002 > lda test_case ;previous test
2ba4 : c923 > cmp #test_num
> trap_ne ;test is out of sequence
2ba6 : d0fe > bne * ;failed not equal (non zero)
>
0024 = >test_num = test_num + 1
2ba8 : a924 > lda #test_num ;*** next tests' number
2baa : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; zeropage indexed
2bad : a200 ldx #0
2baf : a97e lda #$7e
2bb1 : 950c tinc4 sta zpt,x
set_stat 0
> load_flag 0
2bb3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2bb5 : 48 > pha ;use stack to load status
2bb6 : 28 > plp
2bb7 : f60c inc zpt,x
tst_zx rINC,fINC,0
2bb9 : 08 > php ;save flags
2bba : b50c > lda zpt,x
2bbc : dd4002 > cmp rINC,x ;test result
> trap_ne
2bbf : d0fe > bne * ;failed not equal (non zero)
>
2bc1 : 68 > pla ;load status
> eor_flag 0
2bc2 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2bc4 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2bc7 : d0fe > bne * ;failed not equal (non zero)
>
2bc9 : b50c lda zpt,x
2bcb : e8 inx
2bcc : e002 cpx #2
2bce : d002 bne tinc5
2bd0 : a9fe lda #$fe
2bd2 : e005 tinc5 cpx #5
2bd4 : d0db bne tinc4
2bd6 : ca dex
2bd7 : a902 lda #2
2bd9 : 950c tdec4 sta zpt,x
set_stat 0
> load_flag 0
2bdb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2bdd : 48 > pha ;use stack to load status
2bde : 28 > plp
2bdf : d60c dec zpt,x
tst_zx rINC,fINC,0
2be1 : 08 > php ;save flags
2be2 : b50c > lda zpt,x
2be4 : dd4002 > cmp rINC,x ;test result
> trap_ne
2be7 : d0fe > bne * ;failed not equal (non zero)
>
2be9 : 68 > pla ;load status
> eor_flag 0
2bea : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2bec : dd4502 > cmp fINC,x ;test flags
> trap_ne
2bef : d0fe > bne * ;failed not equal (non zero)
>
2bf1 : b50c lda zpt,x
2bf3 : ca dex
2bf4 : 3008 bmi tdec5
2bf6 : e001 cpx #1
2bf8 : d0df bne tdec4
2bfa : a981 lda #$81
2bfc : d0db bne tdec4
2bfe : tdec5
2bfe : a200 ldx #0
2c00 : a97e lda #$7e
2c02 : 950c tinc14 sta zpt,x
set_stat $ff
> load_flag $ff
2c04 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2c06 : 48 > pha ;use stack to load status
2c07 : 28 > plp
2c08 : f60c inc zpt,x
tst_zx rINC,fINC,$ff-fnz
2c0a : 08 > php ;save flags
2c0b : b50c > lda zpt,x
2c0d : dd4002 > cmp rINC,x ;test result
> trap_ne
2c10 : d0fe > bne * ;failed not equal (non zero)
>
2c12 : 68 > pla ;load status
> eor_flag $ff-fnz
2c13 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2c15 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2c18 : d0fe > bne * ;failed not equal (non zero)
>
2c1a : b50c lda zpt,x
2c1c : e8 inx
2c1d : e002 cpx #2
2c1f : d002 bne tinc15
2c21 : a9fe lda #$fe
2c23 : e005 tinc15 cpx #5
2c25 : d0db bne tinc14
2c27 : ca dex
2c28 : a902 lda #2
2c2a : 950c tdec14 sta zpt,x
set_stat $ff
> load_flag $ff
2c2c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2c2e : 48 > pha ;use stack to load status
2c2f : 28 > plp
2c30 : d60c dec zpt,x
tst_zx rINC,fINC,$ff-fnz
2c32 : 08 > php ;save flags
2c33 : b50c > lda zpt,x
2c35 : dd4002 > cmp rINC,x ;test result
> trap_ne
2c38 : d0fe > bne * ;failed not equal (non zero)
>
2c3a : 68 > pla ;load status
> eor_flag $ff-fnz
2c3b : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2c3d : dd4502 > cmp fINC,x ;test flags
> trap_ne
2c40 : d0fe > bne * ;failed not equal (non zero)
>
2c42 : b50c lda zpt,x
2c44 : ca dex
2c45 : 3008 bmi tdec15
2c47 : e001 cpx #1
2c49 : d0df bne tdec14
2c4b : a981 lda #$81
2c4d : d0db bne tdec14
2c4f : tdec15
next_test
2c4f : ad0002 > lda test_case ;previous test
2c52 : c924 > cmp #test_num
> trap_ne ;test is out of sequence
2c54 : d0fe > bne * ;failed not equal (non zero)
>
0025 = >test_num = test_num + 1
2c56 : a925 > lda #test_num ;*** next tests' number
2c58 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; memory indexed
2c5b : a200 ldx #0
2c5d : a97e lda #$7e
2c5f : 9d0302 tinc6 sta abst,x
set_stat 0
> load_flag 0
2c62 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2c64 : 48 > pha ;use stack to load status
2c65 : 28 > plp
2c66 : fe0302 inc abst,x
tst_absx rINC,fINC,0
2c69 : 08 > php ;save flags
2c6a : bd0302 > lda abst,x
2c6d : dd4002 > cmp rINC,x ;test result
> trap_ne
2c70 : d0fe > bne * ;failed not equal (non zero)
>
2c72 : 68 > pla ;load status
> eor_flag 0
2c73 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2c75 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2c78 : d0fe > bne * ;failed not equal (non zero)
>
2c7a : bd0302 lda abst,x
2c7d : e8 inx
2c7e : e002 cpx #2
2c80 : d002 bne tinc7
2c82 : a9fe lda #$fe
2c84 : e005 tinc7 cpx #5
2c86 : d0d7 bne tinc6
2c88 : ca dex
2c89 : a902 lda #2
2c8b : 9d0302 tdec6 sta abst,x
set_stat 0
> load_flag 0
2c8e : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2c90 : 48 > pha ;use stack to load status
2c91 : 28 > plp
2c92 : de0302 dec abst,x
tst_absx rINC,fINC,0
2c95 : 08 > php ;save flags
2c96 : bd0302 > lda abst,x
2c99 : dd4002 > cmp rINC,x ;test result
> trap_ne
2c9c : d0fe > bne * ;failed not equal (non zero)
>
2c9e : 68 > pla ;load status
> eor_flag 0
2c9f : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2ca1 : dd4502 > cmp fINC,x ;test flags
> trap_ne
2ca4 : d0fe > bne * ;failed not equal (non zero)
>
2ca6 : bd0302 lda abst,x
2ca9 : ca dex
2caa : 3008 bmi tdec7
2cac : e001 cpx #1
2cae : d0db bne tdec6
2cb0 : a981 lda #$81
2cb2 : d0d7 bne tdec6
2cb4 : tdec7
2cb4 : a200 ldx #0
2cb6 : a97e lda #$7e
2cb8 : 9d0302 tinc16 sta abst,x
set_stat $ff
> load_flag $ff
2cbb : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2cbd : 48 > pha ;use stack to load status
2cbe : 28 > plp
2cbf : fe0302 inc abst,x
tst_absx rINC,fINC,$ff-fnz
2cc2 : 08 > php ;save flags
2cc3 : bd0302 > lda abst,x
2cc6 : dd4002 > cmp rINC,x ;test result
> trap_ne
2cc9 : d0fe > bne * ;failed not equal (non zero)
>
2ccb : 68 > pla ;load status
> eor_flag $ff-fnz
2ccc : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2cce : dd4502 > cmp fINC,x ;test flags
> trap_ne
2cd1 : d0fe > bne * ;failed not equal (non zero)
>
2cd3 : bd0302 lda abst,x
2cd6 : e8 inx
2cd7 : e002 cpx #2
2cd9 : d002 bne tinc17
2cdb : a9fe lda #$fe
2cdd : e005 tinc17 cpx #5
2cdf : d0d7 bne tinc16
2ce1 : ca dex
2ce2 : a902 lda #2
2ce4 : 9d0302 tdec16 sta abst,x
set_stat $ff
> load_flag $ff
2ce7 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2ce9 : 48 > pha ;use stack to load status
2cea : 28 > plp
2ceb : de0302 dec abst,x
tst_absx rINC,fINC,$ff-fnz
2cee : 08 > php ;save flags
2cef : bd0302 > lda abst,x
2cf2 : dd4002 > cmp rINC,x ;test result
> trap_ne
2cf5 : d0fe > bne * ;failed not equal (non zero)
>
2cf7 : 68 > pla ;load status
> eor_flag $ff-fnz
2cf8 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2cfa : dd4502 > cmp fINC,x ;test flags
> trap_ne
2cfd : d0fe > bne * ;failed not equal (non zero)
>
2cff : bd0302 lda abst,x
2d02 : ca dex
2d03 : 3008 bmi tdec17
2d05 : e001 cpx #1
2d07 : d0db bne tdec16
2d09 : a981 lda #$81
2d0b : d0d7 bne tdec16
2d0d : tdec17
next_test
2d0d : ad0002 > lda test_case ;previous test
2d10 : c925 > cmp #test_num
> trap_ne ;test is out of sequence
2d12 : d0fe > bne * ;failed not equal (non zero)
>
0026 = >test_num = test_num + 1
2d14 : a926 > lda #test_num ;*** next tests' number
2d16 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; testing logical instructions - AND EOR ORA all addressing modes
; AND
2d19 : a203 ldx #3 ;immediate
2d1b : b51c tand lda zpAN,x
2d1d : 8d0902 sta ex_andi+1 ;set AND # operand
set_ax absANa,0
> load_flag 0
2d20 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2d22 : 48 > pha ;use stack to load status
2d23 : bd5a02 > lda absANa,x ;precharge accu
2d26 : 28 > plp
2d27 : 200802 jsr ex_andi ;execute AND # in RAM
tst_ax absrlo,absflo,0
2d2a : 08 > php ;save flags
2d2b : dd6202 > cmp absrlo,x ;test result
> trap_ne
2d2e : d0fe > bne * ;failed not equal (non zero)
>
2d30 : 68 > pla ;load status
> eor_flag 0
2d31 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2d33 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2d36 : d0fe > bne * ;failed not equal (non zero)
>
2d38 : ca dex
2d39 : 10e0 bpl tand
2d3b : a203 ldx #3
2d3d : b51c tand1 lda zpAN,x
2d3f : 8d0902 sta ex_andi+1 ;set AND # operand
set_ax absANa,$ff
> load_flag $ff
2d42 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2d44 : 48 > pha ;use stack to load status
2d45 : bd5a02 > lda absANa,x ;precharge accu
2d48 : 28 > plp
2d49 : 200802 jsr ex_andi ;execute AND # in RAM
tst_ax absrlo,absflo,$ff-fnz
2d4c : 08 > php ;save flags
2d4d : dd6202 > cmp absrlo,x ;test result
> trap_ne
2d50 : d0fe > bne * ;failed not equal (non zero)
>
2d52 : 68 > pla ;load status
> eor_flag $ff-fnz
2d53 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2d55 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2d58 : d0fe > bne * ;failed not equal (non zero)
>
2d5a : ca dex
2d5b : 10e0 bpl tand1
2d5d : a203 ldx #3 ;zp
2d5f : b51c tand2 lda zpAN,x
2d61 : 850c sta zpt
set_ax absANa,0
> load_flag 0
2d63 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2d65 : 48 > pha ;use stack to load status
2d66 : bd5a02 > lda absANa,x ;precharge accu
2d69 : 28 > plp
2d6a : 250c and zpt
tst_ax absrlo,absflo,0
2d6c : 08 > php ;save flags
2d6d : dd6202 > cmp absrlo,x ;test result
> trap_ne
2d70 : d0fe > bne * ;failed not equal (non zero)
>
2d72 : 68 > pla ;load status
> eor_flag 0
2d73 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2d75 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2d78 : d0fe > bne * ;failed not equal (non zero)
>
2d7a : ca dex
2d7b : 10e2 bpl tand2
2d7d : a203 ldx #3
2d7f : b51c tand3 lda zpAN,x
2d81 : 850c sta zpt
set_ax absANa,$ff
> load_flag $ff
2d83 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2d85 : 48 > pha ;use stack to load status
2d86 : bd5a02 > lda absANa,x ;precharge accu
2d89 : 28 > plp
2d8a : 250c and zpt
tst_ax absrlo,absflo,$ff-fnz
2d8c : 08 > php ;save flags
2d8d : dd6202 > cmp absrlo,x ;test result
> trap_ne
2d90 : d0fe > bne * ;failed not equal (non zero)
>
2d92 : 68 > pla ;load status
> eor_flag $ff-fnz
2d93 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2d95 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2d98 : d0fe > bne * ;failed not equal (non zero)
>
2d9a : ca dex
2d9b : 10e2 bpl tand3
2d9d : a203 ldx #3 ;abs
2d9f : b51c tand4 lda zpAN,x
2da1 : 8d0302 sta abst
set_ax absANa,0
> load_flag 0
2da4 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2da6 : 48 > pha ;use stack to load status
2da7 : bd5a02 > lda absANa,x ;precharge accu
2daa : 28 > plp
2dab : 2d0302 and abst
tst_ax absrlo,absflo,0
2dae : 08 > php ;save flags
2daf : dd6202 > cmp absrlo,x ;test result
> trap_ne
2db2 : d0fe > bne * ;failed not equal (non zero)
>
2db4 : 68 > pla ;load status
> eor_flag 0
2db5 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2db7 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2dba : d0fe > bne * ;failed not equal (non zero)
>
2dbc : ca dex
2dbd : 10e0 bpl tand4
2dbf : a203 ldx #3
2dc1 : b51c tand5 lda zpAN,x
2dc3 : 8d0302 sta abst
set_ax absANa,$ff
> load_flag $ff
2dc6 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2dc8 : 48 > pha ;use stack to load status
2dc9 : bd5a02 > lda absANa,x ;precharge accu
2dcc : 28 > plp
2dcd : 2d0302 and abst
tst_ax absrlo,absflo,$ff-fnz
2dd0 : 08 > php ;save flags
2dd1 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2dd4 : d0fe > bne * ;failed not equal (non zero)
>
2dd6 : 68 > pla ;load status
> eor_flag $ff-fnz
2dd7 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2dd9 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2ddc : d0fe > bne * ;failed not equal (non zero)
>
2dde : ca dex
2ddf : 1002 bpl tand6
2de1 : a203 ldx #3 ;zp,x
2de3 : tand6
set_ax absANa,0
> load_flag 0
2de3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2de5 : 48 > pha ;use stack to load status
2de6 : bd5a02 > lda absANa,x ;precharge accu
2de9 : 28 > plp
2dea : 351c and zpAN,x
tst_ax absrlo,absflo,0
2dec : 08 > php ;save flags
2ded : dd6202 > cmp absrlo,x ;test result
> trap_ne
2df0 : d0fe > bne * ;failed not equal (non zero)
>
2df2 : 68 > pla ;load status
> eor_flag 0
2df3 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2df5 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2df8 : d0fe > bne * ;failed not equal (non zero)
>
2dfa : ca dex
2dfb : 10e6 bpl tand6
2dfd : a203 ldx #3
2dff : tand7
set_ax absANa,$ff
> load_flag $ff
2dff : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2e01 : 48 > pha ;use stack to load status
2e02 : bd5a02 > lda absANa,x ;precharge accu
2e05 : 28 > plp
2e06 : 351c and zpAN,x
tst_ax absrlo,absflo,$ff-fnz
2e08 : 08 > php ;save flags
2e09 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2e0c : d0fe > bne * ;failed not equal (non zero)
>
2e0e : 68 > pla ;load status
> eor_flag $ff-fnz
2e0f : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2e11 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2e14 : d0fe > bne * ;failed not equal (non zero)
>
2e16 : ca dex
2e17 : 10e6 bpl tand7
2e19 : a203 ldx #3 ;abs,x
2e1b : tand8
set_ax absANa,0
> load_flag 0
2e1b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2e1d : 48 > pha ;use stack to load status
2e1e : bd5a02 > lda absANa,x ;precharge accu
2e21 : 28 > plp
2e22 : 3d4e02 and absAN,x
tst_ax absrlo,absflo,0
2e25 : 08 > php ;save flags
2e26 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2e29 : d0fe > bne * ;failed not equal (non zero)
>
2e2b : 68 > pla ;load status
> eor_flag 0
2e2c : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2e2e : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2e31 : d0fe > bne * ;failed not equal (non zero)
>
2e33 : ca dex
2e34 : 10e5 bpl tand8
2e36 : a203 ldx #3
2e38 : tand9
set_ax absANa,$ff
> load_flag $ff
2e38 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2e3a : 48 > pha ;use stack to load status
2e3b : bd5a02 > lda absANa,x ;precharge accu
2e3e : 28 > plp
2e3f : 3d4e02 and absAN,x
tst_ax absrlo,absflo,$ff-fnz
2e42 : 08 > php ;save flags
2e43 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2e46 : d0fe > bne * ;failed not equal (non zero)
>
2e48 : 68 > pla ;load status
> eor_flag $ff-fnz
2e49 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2e4b : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2e4e : d0fe > bne * ;failed not equal (non zero)
>
2e50 : ca dex
2e51 : 10e5 bpl tand9
2e53 : a003 ldy #3 ;abs,y
2e55 : tand10
set_ay absANa,0
> load_flag 0
2e55 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2e57 : 48 > pha ;use stack to load status
2e58 : b95a02 > lda absANa,y ;precharge accu
2e5b : 28 > plp
2e5c : 394e02 and absAN,y
tst_ay absrlo,absflo,0
2e5f : 08 > php ;save flags
2e60 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2e63 : d0fe > bne * ;failed not equal (non zero)
>
2e65 : 68 > pla ;load status
> eor_flag 0
2e66 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2e68 : d96602 > cmp absflo,y ;test flags
> trap_ne
2e6b : d0fe > bne * ;failed not equal (non zero)
>
2e6d : 88 dey
2e6e : 10e5 bpl tand10
2e70 : a003 ldy #3
2e72 : tand11
set_ay absANa,$ff
> load_flag $ff
2e72 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2e74 : 48 > pha ;use stack to load status
2e75 : b95a02 > lda absANa,y ;precharge accu
2e78 : 28 > plp
2e79 : 394e02 and absAN,y
tst_ay absrlo,absflo,$ff-fnz
2e7c : 08 > php ;save flags
2e7d : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2e80 : d0fe > bne * ;failed not equal (non zero)
>
2e82 : 68 > pla ;load status
> eor_flag $ff-fnz
2e83 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2e85 : d96602 > cmp absflo,y ;test flags
> trap_ne
2e88 : d0fe > bne * ;failed not equal (non zero)
>
2e8a : 88 dey
2e8b : 10e5 bpl tand11
2e8d : a206 ldx #6 ;(zp,x)
2e8f : a003 ldy #3
2e91 : tand12
set_ay absANa,0
> load_flag 0
2e91 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2e93 : 48 > pha ;use stack to load status
2e94 : b95a02 > lda absANa,y ;precharge accu
2e97 : 28 > plp
2e98 : 213a and (indAN,x)
tst_ay absrlo,absflo,0
2e9a : 08 > php ;save flags
2e9b : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2e9e : d0fe > bne * ;failed not equal (non zero)
>
2ea0 : 68 > pla ;load status
> eor_flag 0
2ea1 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2ea3 : d96602 > cmp absflo,y ;test flags
> trap_ne
2ea6 : d0fe > bne * ;failed not equal (non zero)
>
2ea8 : ca dex
2ea9 : ca dex
2eaa : 88 dey
2eab : 10e4 bpl tand12
2ead : a206 ldx #6
2eaf : a003 ldy #3
2eb1 : tand13
set_ay absANa,$ff
> load_flag $ff
2eb1 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2eb3 : 48 > pha ;use stack to load status
2eb4 : b95a02 > lda absANa,y ;precharge accu
2eb7 : 28 > plp
2eb8 : 213a and (indAN,x)
tst_ay absrlo,absflo,$ff-fnz
2eba : 08 > php ;save flags
2ebb : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2ebe : d0fe > bne * ;failed not equal (non zero)
>
2ec0 : 68 > pla ;load status
> eor_flag $ff-fnz
2ec1 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2ec3 : d96602 > cmp absflo,y ;test flags
> trap_ne
2ec6 : d0fe > bne * ;failed not equal (non zero)
>
2ec8 : ca dex
2ec9 : ca dex
2eca : 88 dey
2ecb : 10e4 bpl tand13
2ecd : a003 ldy #3 ;(zp),y
2ecf : tand14
set_ay absANa,0
> load_flag 0
2ecf : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2ed1 : 48 > pha ;use stack to load status
2ed2 : b95a02 > lda absANa,y ;precharge accu
2ed5 : 28 > plp
2ed6 : 313a and (indAN),y
tst_ay absrlo,absflo,0
2ed8 : 08 > php ;save flags
2ed9 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2edc : d0fe > bne * ;failed not equal (non zero)
>
2ede : 68 > pla ;load status
> eor_flag 0
2edf : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2ee1 : d96602 > cmp absflo,y ;test flags
> trap_ne
2ee4 : d0fe > bne * ;failed not equal (non zero)
>
2ee6 : 88 dey
2ee7 : 10e6 bpl tand14
2ee9 : a003 ldy #3
2eeb : tand15
set_ay absANa,$ff
> load_flag $ff
2eeb : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2eed : 48 > pha ;use stack to load status
2eee : b95a02 > lda absANa,y ;precharge accu
2ef1 : 28 > plp
2ef2 : 313a and (indAN),y
tst_ay absrlo,absflo,$ff-fnz
2ef4 : 08 > php ;save flags
2ef5 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
2ef8 : d0fe > bne * ;failed not equal (non zero)
>
2efa : 68 > pla ;load status
> eor_flag $ff-fnz
2efb : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2efd : d96602 > cmp absflo,y ;test flags
> trap_ne
2f00 : d0fe > bne * ;failed not equal (non zero)
>
2f02 : 88 dey
2f03 : 10e6 bpl tand15
next_test
2f05 : ad0002 > lda test_case ;previous test
2f08 : c926 > cmp #test_num
> trap_ne ;test is out of sequence
2f0a : d0fe > bne * ;failed not equal (non zero)
>
0027 = >test_num = test_num + 1
2f0c : a927 > lda #test_num ;*** next tests' number
2f0e : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; EOR
2f11 : a203 ldx #3 ;immediate - self modifying code
2f13 : b520 teor lda zpEO,x
2f15 : 8d0c02 sta ex_eori+1 ;set EOR # operand
set_ax absEOa,0
> load_flag 0
2f18 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2f1a : 48 > pha ;use stack to load status
2f1b : bd5e02 > lda absEOa,x ;precharge accu
2f1e : 28 > plp
2f1f : 200b02 jsr ex_eori ;execute EOR # in RAM
tst_ax absrlo,absflo,0
2f22 : 08 > php ;save flags
2f23 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2f26 : d0fe > bne * ;failed not equal (non zero)
>
2f28 : 68 > pla ;load status
> eor_flag 0
2f29 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2f2b : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2f2e : d0fe > bne * ;failed not equal (non zero)
>
2f30 : ca dex
2f31 : 10e0 bpl teor
2f33 : a203 ldx #3
2f35 : b520 teor1 lda zpEO,x
2f37 : 8d0c02 sta ex_eori+1 ;set EOR # operand
set_ax absEOa,$ff
> load_flag $ff
2f3a : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2f3c : 48 > pha ;use stack to load status
2f3d : bd5e02 > lda absEOa,x ;precharge accu
2f40 : 28 > plp
2f41 : 200b02 jsr ex_eori ;execute EOR # in RAM
tst_ax absrlo,absflo,$ff-fnz
2f44 : 08 > php ;save flags
2f45 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2f48 : d0fe > bne * ;failed not equal (non zero)
>
2f4a : 68 > pla ;load status
> eor_flag $ff-fnz
2f4b : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2f4d : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2f50 : d0fe > bne * ;failed not equal (non zero)
>
2f52 : ca dex
2f53 : 10e0 bpl teor1
2f55 : a203 ldx #3 ;zp
2f57 : b520 teor2 lda zpEO,x
2f59 : 850c sta zpt
set_ax absEOa,0
> load_flag 0
2f5b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2f5d : 48 > pha ;use stack to load status
2f5e : bd5e02 > lda absEOa,x ;precharge accu
2f61 : 28 > plp
2f62 : 450c eor zpt
tst_ax absrlo,absflo,0
2f64 : 08 > php ;save flags
2f65 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2f68 : d0fe > bne * ;failed not equal (non zero)
>
2f6a : 68 > pla ;load status
> eor_flag 0
2f6b : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2f6d : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2f70 : d0fe > bne * ;failed not equal (non zero)
>
2f72 : ca dex
2f73 : 10e2 bpl teor2
2f75 : a203 ldx #3
2f77 : b520 teor3 lda zpEO,x
2f79 : 850c sta zpt
set_ax absEOa,$ff
> load_flag $ff
2f7b : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2f7d : 48 > pha ;use stack to load status
2f7e : bd5e02 > lda absEOa,x ;precharge accu
2f81 : 28 > plp
2f82 : 450c eor zpt
tst_ax absrlo,absflo,$ff-fnz
2f84 : 08 > php ;save flags
2f85 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2f88 : d0fe > bne * ;failed not equal (non zero)
>
2f8a : 68 > pla ;load status
> eor_flag $ff-fnz
2f8b : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2f8d : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2f90 : d0fe > bne * ;failed not equal (non zero)
>
2f92 : ca dex
2f93 : 10e2 bpl teor3
2f95 : a203 ldx #3 ;abs
2f97 : b520 teor4 lda zpEO,x
2f99 : 8d0302 sta abst
set_ax absEOa,0
> load_flag 0
2f9c : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2f9e : 48 > pha ;use stack to load status
2f9f : bd5e02 > lda absEOa,x ;precharge accu
2fa2 : 28 > plp
2fa3 : 4d0302 eor abst
tst_ax absrlo,absflo,0
2fa6 : 08 > php ;save flags
2fa7 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2faa : d0fe > bne * ;failed not equal (non zero)
>
2fac : 68 > pla ;load status
> eor_flag 0
2fad : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2faf : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2fb2 : d0fe > bne * ;failed not equal (non zero)
>
2fb4 : ca dex
2fb5 : 10e0 bpl teor4
2fb7 : a203 ldx #3
2fb9 : b520 teor5 lda zpEO,x
2fbb : 8d0302 sta abst
set_ax absEOa,$ff
> load_flag $ff
2fbe : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2fc0 : 48 > pha ;use stack to load status
2fc1 : bd5e02 > lda absEOa,x ;precharge accu
2fc4 : 28 > plp
2fc5 : 4d0302 eor abst
tst_ax absrlo,absflo,$ff-fnz
2fc8 : 08 > php ;save flags
2fc9 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2fcc : d0fe > bne * ;failed not equal (non zero)
>
2fce : 68 > pla ;load status
> eor_flag $ff-fnz
2fcf : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
2fd1 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2fd4 : d0fe > bne * ;failed not equal (non zero)
>
2fd6 : ca dex
2fd7 : 1002 bpl teor6
2fd9 : a203 ldx #3 ;zp,x
2fdb : teor6
set_ax absEOa,0
> load_flag 0
2fdb : a900 > lda #0 ;allow test to change I-flag (no mask)
>
2fdd : 48 > pha ;use stack to load status
2fde : bd5e02 > lda absEOa,x ;precharge accu
2fe1 : 28 > plp
2fe2 : 5520 eor zpEO,x
tst_ax absrlo,absflo,0
2fe4 : 08 > php ;save flags
2fe5 : dd6202 > cmp absrlo,x ;test result
> trap_ne
2fe8 : d0fe > bne * ;failed not equal (non zero)
>
2fea : 68 > pla ;load status
> eor_flag 0
2feb : 4930 > eor #0|fao ;invert expected flags + always on bits
>
2fed : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
2ff0 : d0fe > bne * ;failed not equal (non zero)
>
2ff2 : ca dex
2ff3 : 10e6 bpl teor6
2ff5 : a203 ldx #3
2ff7 : teor7
set_ax absEOa,$ff
> load_flag $ff
2ff7 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
2ff9 : 48 > pha ;use stack to load status
2ffa : bd5e02 > lda absEOa,x ;precharge accu
2ffd : 28 > plp
2ffe : 5520 eor zpEO,x
tst_ax absrlo,absflo,$ff-fnz
3000 : 08 > php ;save flags
3001 : dd6202 > cmp absrlo,x ;test result
> trap_ne
3004 : d0fe > bne * ;failed not equal (non zero)
>
3006 : 68 > pla ;load status
> eor_flag $ff-fnz
3007 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3009 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
300c : d0fe > bne * ;failed not equal (non zero)
>
300e : ca dex
300f : 10e6 bpl teor7
3011 : a203 ldx #3 ;abs,x
3013 : teor8
set_ax absEOa,0
> load_flag 0
3013 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3015 : 48 > pha ;use stack to load status
3016 : bd5e02 > lda absEOa,x ;precharge accu
3019 : 28 > plp
301a : 5d5202 eor absEO,x
tst_ax absrlo,absflo,0
301d : 08 > php ;save flags
301e : dd6202 > cmp absrlo,x ;test result
> trap_ne
3021 : d0fe > bne * ;failed not equal (non zero)
>
3023 : 68 > pla ;load status
> eor_flag 0
3024 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3026 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3029 : d0fe > bne * ;failed not equal (non zero)
>
302b : ca dex
302c : 10e5 bpl teor8
302e : a203 ldx #3
3030 : teor9
set_ax absEOa,$ff
> load_flag $ff
3030 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3032 : 48 > pha ;use stack to load status
3033 : bd5e02 > lda absEOa,x ;precharge accu
3036 : 28 > plp
3037 : 5d5202 eor absEO,x
tst_ax absrlo,absflo,$ff-fnz
303a : 08 > php ;save flags
303b : dd6202 > cmp absrlo,x ;test result
> trap_ne
303e : d0fe > bne * ;failed not equal (non zero)
>
3040 : 68 > pla ;load status
> eor_flag $ff-fnz
3041 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3043 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3046 : d0fe > bne * ;failed not equal (non zero)
>
3048 : ca dex
3049 : 10e5 bpl teor9
304b : a003 ldy #3 ;abs,y
304d : teor10
set_ay absEOa,0
> load_flag 0
304d : a900 > lda #0 ;allow test to change I-flag (no mask)
>
304f : 48 > pha ;use stack to load status
3050 : b95e02 > lda absEOa,y ;precharge accu
3053 : 28 > plp
3054 : 595202 eor absEO,y
tst_ay absrlo,absflo,0
3057 : 08 > php ;save flags
3058 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
305b : d0fe > bne * ;failed not equal (non zero)
>
305d : 68 > pla ;load status
> eor_flag 0
305e : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3060 : d96602 > cmp absflo,y ;test flags
> trap_ne
3063 : d0fe > bne * ;failed not equal (non zero)
>
3065 : 88 dey
3066 : 10e5 bpl teor10
3068 : a003 ldy #3
306a : teor11
set_ay absEOa,$ff
> load_flag $ff
306a : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
306c : 48 > pha ;use stack to load status
306d : b95e02 > lda absEOa,y ;precharge accu
3070 : 28 > plp
3071 : 595202 eor absEO,y
tst_ay absrlo,absflo,$ff-fnz
3074 : 08 > php ;save flags
3075 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
3078 : d0fe > bne * ;failed not equal (non zero)
>
307a : 68 > pla ;load status
> eor_flag $ff-fnz
307b : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
307d : d96602 > cmp absflo,y ;test flags
> trap_ne
3080 : d0fe > bne * ;failed not equal (non zero)
>
3082 : 88 dey
3083 : 10e5 bpl teor11
3085 : a206 ldx #6 ;(zp,x)
3087 : a003 ldy #3
3089 : teor12
set_ay absEOa,0
> load_flag 0
3089 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
308b : 48 > pha ;use stack to load status
308c : b95e02 > lda absEOa,y ;precharge accu
308f : 28 > plp
3090 : 4142 eor (indEO,x)
tst_ay absrlo,absflo,0
3092 : 08 > php ;save flags
3093 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
3096 : d0fe > bne * ;failed not equal (non zero)
>
3098 : 68 > pla ;load status
> eor_flag 0
3099 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
309b : d96602 > cmp absflo,y ;test flags
> trap_ne
309e : d0fe > bne * ;failed not equal (non zero)
>
30a0 : ca dex
30a1 : ca dex
30a2 : 88 dey
30a3 : 10e4 bpl teor12
30a5 : a206 ldx #6
30a7 : a003 ldy #3
30a9 : teor13
set_ay absEOa,$ff
> load_flag $ff
30a9 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
30ab : 48 > pha ;use stack to load status
30ac : b95e02 > lda absEOa,y ;precharge accu
30af : 28 > plp
30b0 : 4142 eor (indEO,x)
tst_ay absrlo,absflo,$ff-fnz
30b2 : 08 > php ;save flags
30b3 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
30b6 : d0fe > bne * ;failed not equal (non zero)
>
30b8 : 68 > pla ;load status
> eor_flag $ff-fnz
30b9 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
30bb : d96602 > cmp absflo,y ;test flags
> trap_ne
30be : d0fe > bne * ;failed not equal (non zero)
>
30c0 : ca dex
30c1 : ca dex
30c2 : 88 dey
30c3 : 10e4 bpl teor13
30c5 : a003 ldy #3 ;(zp),y
30c7 : teor14
set_ay absEOa,0
> load_flag 0
30c7 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
30c9 : 48 > pha ;use stack to load status
30ca : b95e02 > lda absEOa,y ;precharge accu
30cd : 28 > plp
30ce : 5142 eor (indEO),y
tst_ay absrlo,absflo,0
30d0 : 08 > php ;save flags
30d1 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
30d4 : d0fe > bne * ;failed not equal (non zero)
>
30d6 : 68 > pla ;load status
> eor_flag 0
30d7 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
30d9 : d96602 > cmp absflo,y ;test flags
> trap_ne
30dc : d0fe > bne * ;failed not equal (non zero)
>
30de : 88 dey
30df : 10e6 bpl teor14
30e1 : a003 ldy #3
30e3 : teor15
set_ay absEOa,$ff
> load_flag $ff
30e3 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
30e5 : 48 > pha ;use stack to load status
30e6 : b95e02 > lda absEOa,y ;precharge accu
30e9 : 28 > plp
30ea : 5142 eor (indEO),y
tst_ay absrlo,absflo,$ff-fnz
30ec : 08 > php ;save flags
30ed : d96202 > cmp absrlo,y ;test result
> trap_ne ;
30f0 : d0fe > bne * ;failed not equal (non zero)
>
30f2 : 68 > pla ;load status
> eor_flag $ff-fnz
30f3 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
30f5 : d96602 > cmp absflo,y ;test flags
> trap_ne
30f8 : d0fe > bne * ;failed not equal (non zero)
>
30fa : 88 dey
30fb : 10e6 bpl teor15
next_test
30fd : ad0002 > lda test_case ;previous test
3100 : c927 > cmp #test_num
> trap_ne ;test is out of sequence
3102 : d0fe > bne * ;failed not equal (non zero)
>
0028 = >test_num = test_num + 1
3104 : a928 > lda #test_num ;*** next tests' number
3106 : 8d0002 > sta test_case
> ;check_ram ;uncomment to find altered RAM after each test
; OR
3109 : a203 ldx #3 ;immediate - self modifying code
310b : b518 tora lda zpOR,x
310d : 8d0f02 sta ex_orai+1 ;set ORA # operand
set_ax absORa,0
> load_flag 0
3110 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3112 : 48 > pha ;use stack to load status
3113 : bd5602 > lda absORa,x ;precharge accu
3116 : 28 > plp
3117 : 200e02 jsr ex_orai ;execute ORA # in RAM
tst_ax absrlo,absflo,0
311a : 08 > php ;save flags
311b : dd6202 > cmp absrlo,x ;test result
> trap_ne
311e : d0fe > bne * ;failed not equal (non zero)
>
3120 : 68 > pla ;load status
> eor_flag 0
3121 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3123 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3126 : d0fe > bne * ;failed not equal (non zero)
>
3128 : ca dex
3129 : 10e0 bpl tora
312b : a203 ldx #3
312d : b518 tora1 lda zpOR,x
312f : 8d0f02 sta ex_orai+1 ;set ORA # operand
set_ax absORa,$ff
> load_flag $ff
3132 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3134 : 48 > pha ;use stack to load status
3135 : bd5602 > lda absORa,x ;precharge accu
3138 : 28 > plp
3139 : 200e02 jsr ex_orai ;execute ORA # in RAM
tst_ax absrlo,absflo,$ff-fnz
313c : 08 > php ;save flags
313d : dd6202 > cmp absrlo,x ;test result
> trap_ne
3140 : d0fe > bne * ;failed not equal (non zero)
>
3142 : 68 > pla ;load status
> eor_flag $ff-fnz
3143 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3145 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3148 : d0fe > bne * ;failed not equal (non zero)
>
314a : ca dex
314b : 10e0 bpl tora1
314d : a203 ldx #3 ;zp
314f : b518 tora2 lda zpOR,x
3151 : 850c sta zpt
set_ax absORa,0
> load_flag 0
3153 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3155 : 48 > pha ;use stack to load status
3156 : bd5602 > lda absORa,x ;precharge accu
3159 : 28 > plp
315a : 050c ora zpt
tst_ax absrlo,absflo,0
315c : 08 > php ;save flags
315d : dd6202 > cmp absrlo,x ;test result
> trap_ne
3160 : d0fe > bne * ;failed not equal (non zero)
>
3162 : 68 > pla ;load status
> eor_flag 0
3163 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3165 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3168 : d0fe > bne * ;failed not equal (non zero)
>
316a : ca dex
316b : 10e2 bpl tora2
316d : a203 ldx #3
316f : b518 tora3 lda zpOR,x
3171 : 850c sta zpt
set_ax absORa,$ff
> load_flag $ff
3173 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3175 : 48 > pha ;use stack to load status
3176 : bd5602 > lda absORa,x ;precharge accu
3179 : 28 > plp
317a : 050c ora zpt
tst_ax absrlo,absflo,$ff-fnz
317c : 08 > php ;save flags
317d : dd6202 > cmp absrlo,x ;test result
> trap_ne
3180 : d0fe > bne * ;failed not equal (non zero)
>
3182 : 68 > pla ;load status
> eor_flag $ff-fnz
3183 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3185 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3188 : d0fe > bne * ;failed not equal (non zero)
>
318a : ca dex
318b : 10e2 bpl tora3
318d : a203 ldx #3 ;abs
318f : b518 tora4 lda zpOR,x
3191 : 8d0302 sta abst
set_ax absORa,0
> load_flag 0
3194 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3196 : 48 > pha ;use stack to load status
3197 : bd5602 > lda absORa,x ;precharge accu
319a : 28 > plp
319b : 0d0302 ora abst
tst_ax absrlo,absflo,0
319e : 08 > php ;save flags
319f : dd6202 > cmp absrlo,x ;test result
> trap_ne
31a2 : d0fe > bne * ;failed not equal (non zero)
>
31a4 : 68 > pla ;load status
> eor_flag 0
31a5 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
31a7 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
31aa : d0fe > bne * ;failed not equal (non zero)
>
31ac : ca dex
31ad : 10e0 bpl tora4
31af : a203 ldx #3
31b1 : b518 tora5 lda zpOR,x
31b3 : 8d0302 sta abst
set_ax absORa,$ff
> load_flag $ff
31b6 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
31b8 : 48 > pha ;use stack to load status
31b9 : bd5602 > lda absORa,x ;precharge accu
31bc : 28 > plp
31bd : 0d0302 ora abst
tst_ax absrlo,absflo,$ff-fnz
31c0 : 08 > php ;save flags
31c1 : dd6202 > cmp absrlo,x ;test result
> trap_ne
31c4 : d0fe > bne * ;failed not equal (non zero)
>
31c6 : 68 > pla ;load status
> eor_flag $ff-fnz
31c7 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
31c9 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
31cc : d0fe > bne * ;failed not equal (non zero)
>
31ce : ca dex
31cf : 1002 bpl tora6
31d1 : a203 ldx #3 ;zp,x
31d3 : tora6
set_ax absORa,0
> load_flag 0
31d3 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
31d5 : 48 > pha ;use stack to load status
31d6 : bd5602 > lda absORa,x ;precharge accu
31d9 : 28 > plp
31da : 1518 ora zpOR,x
tst_ax absrlo,absflo,0
31dc : 08 > php ;save flags
31dd : dd6202 > cmp absrlo,x ;test result
> trap_ne
31e0 : d0fe > bne * ;failed not equal (non zero)
>
31e2 : 68 > pla ;load status
> eor_flag 0
31e3 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
31e5 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
31e8 : d0fe > bne * ;failed not equal (non zero)
>
31ea : ca dex
31eb : 10e6 bpl tora6
31ed : a203 ldx #3
31ef : tora7
set_ax absORa,$ff
> load_flag $ff
31ef : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
31f1 : 48 > pha ;use stack to load status
31f2 : bd5602 > lda absORa,x ;precharge accu
31f5 : 28 > plp
31f6 : 1518 ora zpOR,x
tst_ax absrlo,absflo,$ff-fnz
31f8 : 08 > php ;save flags
31f9 : dd6202 > cmp absrlo,x ;test result
> trap_ne
31fc : d0fe > bne * ;failed not equal (non zero)
>
31fe : 68 > pla ;load status
> eor_flag $ff-fnz
31ff : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3201 : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3204 : d0fe > bne * ;failed not equal (non zero)
>
3206 : ca dex
3207 : 10e6 bpl tora7
3209 : a203 ldx #3 ;abs,x
320b : tora8
set_ax absORa,0
> load_flag 0
320b : a900 > lda #0 ;allow test to change I-flag (no mask)
>
320d : 48 > pha ;use stack to load status
320e : bd5602 > lda absORa,x ;precharge accu
3211 : 28 > plp
3212 : 1d4a02 ora absOR,x
tst_ax absrlo,absflo,0
3215 : 08 > php ;save flags
3216 : dd6202 > cmp absrlo,x ;test result
> trap_ne
3219 : d0fe > bne * ;failed not equal (non zero)
>
321b : 68 > pla ;load status
> eor_flag 0
321c : 4930 > eor #0|fao ;invert expected flags + always on bits
>
321e : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
3221 : d0fe > bne * ;failed not equal (non zero)
>
3223 : ca dex
3224 : 10e5 bpl tora8
3226 : a203 ldx #3
3228 : tora9
set_ax absORa,$ff
> load_flag $ff
3228 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
322a : 48 > pha ;use stack to load status
322b : bd5602 > lda absORa,x ;precharge accu
322e : 28 > plp
322f : 1d4a02 ora absOR,x
tst_ax absrlo,absflo,$ff-fnz
3232 : 08 > php ;save flags
3233 : dd6202 > cmp absrlo,x ;test result
> trap_ne
3236 : d0fe > bne * ;failed not equal (non zero)
>
3238 : 68 > pla ;load status
> eor_flag $ff-fnz
3239 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
323b : dd6602 > cmp absflo,x ;test flags
> trap_ne ;
323e : d0fe > bne * ;failed not equal (non zero)
>
3240 : ca dex
3241 : 10e5 bpl tora9
3243 : a003 ldy #3 ;abs,y
3245 : tora10
set_ay absORa,0
> load_flag 0
3245 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3247 : 48 > pha ;use stack to load status
3248 : b95602 > lda absORa,y ;precharge accu
324b : 28 > plp
324c : 194a02 ora absOR,y
tst_ay absrlo,absflo,0
324f : 08 > php ;save flags
3250 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
3253 : d0fe > bne * ;failed not equal (non zero)
>
3255 : 68 > pla ;load status
> eor_flag 0
3256 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3258 : d96602 > cmp absflo,y ;test flags
> trap_ne
325b : d0fe > bne * ;failed not equal (non zero)
>
325d : 88 dey
325e : 10e5 bpl tora10
3260 : a003 ldy #3
3262 : tora11
set_ay absORa,$ff
> load_flag $ff
3262 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3264 : 48 > pha ;use stack to load status
3265 : b95602 > lda absORa,y ;precharge accu
3268 : 28 > plp
3269 : 194a02 ora absOR,y
tst_ay absrlo,absflo,$ff-fnz
326c : 08 > php ;save flags
326d : d96202 > cmp absrlo,y ;test result
> trap_ne ;
3270 : d0fe > bne * ;failed not equal (non zero)
>
3272 : 68 > pla ;load status
> eor_flag $ff-fnz
3273 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
3275 : d96602 > cmp absflo,y ;test flags
> trap_ne
3278 : d0fe > bne * ;failed not equal (non zero)
>
327a : 88 dey
327b : 10e5 bpl tora11
327d : a206 ldx #6 ;(zp,x)
327f : a003 ldy #3
3281 : tora12
set_ay absORa,0
> load_flag 0
3281 : a900 > lda #0 ;allow test to change I-flag (no mask)
>
3283 : 48 > pha ;use stack to load status
3284 : b95602 > lda absORa,y ;precharge accu
3287 : 28 > plp
3288 : 014a ora (indOR,x)
tst_ay absrlo,absflo,0
328a : 08 > php ;save flags
328b : d96202 > cmp absrlo,y ;test result
> trap_ne ;
328e : d0fe > bne * ;failed not equal (non zero)
>
3290 : 68 > pla ;load status
> eor_flag 0
3291 : 4930 > eor #0|fao ;invert expected flags + always on bits
>
3293 : d96602 > cmp absflo,y ;test flags
> trap_ne
3296 : d0fe > bne * ;failed not equal (non zero)
>
3298 : ca dex
3299 : ca dex
329a : 88 dey
329b : 10e4 bpl tora12
329d : a206 ldx #6
329f : a003 ldy #3
32a1 : tora13
set_ay absORa,$ff
> load_flag $ff
32a1 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
32a3 : 48 > pha ;use stack to load status
32a4 : b95602 > lda absORa,y ;precharge accu
32a7 : 28 > plp
32a8 : 014a ora (indOR,x)
tst_ay absrlo,absflo,$ff-fnz
32aa : 08 > php ;save flags
32ab : d96202 > cmp absrlo,y ;test result
> trap_ne ;
32ae : d0fe > bne * ;failed not equal (non zero)
>
32b0 : 68 > pla ;load status
> eor_flag $ff-fnz
32b1 : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
32b3 : d96602 > cmp absflo,y ;test flags
> trap_ne
32b6 : d0fe > bne * ;failed not equal (non zero)
>
32b8 : ca dex
32b9 : ca dex
32ba : 88 dey
32bb : 10e4 bpl tora13
32bd : a003 ldy #3 ;(zp),y
32bf : tora14
set_ay absORa,0
> load_flag 0
32bf : a900 > lda #0 ;allow test to change I-flag (no mask)
>
32c1 : 48 > pha ;use stack to load status
32c2 : b95602 > lda absORa,y ;precharge accu
32c5 : 28 > plp
32c6 : 114a ora (indOR),y
tst_ay absrlo,absflo,0
32c8 : 08 > php ;save flags
32c9 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
32cc : d0fe > bne * ;failed not equal (non zero)
>
32ce : 68 > pla ;load status
> eor_flag 0
32cf : 4930 > eor #0|fao ;invert expected flags + always on bits
>
32d1 : d96602 > cmp absflo,y ;test flags
> trap_ne
32d4 : d0fe > bne * ;failed not equal (non zero)
>
32d6 : 88 dey
32d7 : 10e6 bpl tora14
32d9 : a003 ldy #3
32db : tora15
set_ay absORa,$ff
> load_flag $ff
32db : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
32dd : 48 > pha ;use stack to load status
32de : b95602 > lda absORa,y ;precharge accu
32e1 : 28 > plp
32e2 : 114a ora (indOR),y
tst_ay absrlo,absflo,$ff-fnz
32e4 : 08 > php ;save flags
32e5 : d96202 > cmp absrlo,y ;test result
> trap_ne ;
32e8 : d0fe > bne * ;failed not equal (non zero)
>
32ea : 68 > pla ;load status
> eor_flag $ff-fnz
32eb : 497d > eor #$ff-fnz|fao ;invert expected flags + always on bits
>
32ed : d96602 > cmp absflo,y ;test flags
> trap_ne
32f0 : d0fe > bne * ;failed not equal (non zero)
>
32f2 : 88 dey
32f3 : 10e6 bpl tora15
if I_flag = 3
32f5 : 58 cli
endif
next_test
32f6 : ad0002 > lda test_case ;previous test
32f9 : c928 > cmp #test_num
> trap_ne ;test is out of sequence
32fb : d0fe > bne * ;failed not equal (non zero)
>
0029 = >test_num = test_num + 1
32fd : a929 > lda #test_num ;*** next tests' number
32ff : 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
3302 : d8 cld
3303 : a20e ldx #ad2 ;for indexed test
3305 : a0ff ldy #$ff ;max range
3307 : a900 lda #0 ;start with adding zeroes & no carry
3309 : 850c sta adfc ;carry in - for diag
330b : 850d sta ad1 ;operand 1 - accumulator
330d : 850e sta ad2 ;operand 2 - memory or immediate
330f : 8d0302 sta ada2 ;non zp
3312 : 850f sta adrl ;expected result bits 0-7
3314 : 8510 sta adrh ;expected result bit 8 (carry out)
3316 : a9ff lda #$ff ;complemented operand 2 for subtract
3318 : 8512 sta sb2
331a : 8d0402 sta sba2 ;non zp
331d : a902 lda #2 ;expected Z-flag
331f : 8511 sta adrf
3321 : 18 tadd clc ;test with carry clear
3322 : 209c35 jsr chkadd
3325 : e60c inc adfc ;now with carry
3327 : e60f inc adrl ;result +1
3329 : 08 php ;save N & Z from low result
332a : 08 php
332b : 68 pla ;accu holds expected flags
332c : 2982 and #$82 ;mask N & Z
332e : 28 plp
332f : d002 bne tadd1
3331 : e610 inc adrh ;result bit 8 - carry
3333 : 0510 tadd1 ora adrh ;merge C to expected flags
3335 : 8511 sta adrf ;save expected flags except overflow
3337 : 38 sec ;test with carry set
3338 : 209c35 jsr chkadd
333b : c60c dec adfc ;same for operand +1 but no carry
333d : e60d inc ad1
333f : d0e0 bne tadd ;iterate op1
3341 : a900 lda #0 ;preset result to op2 when op1 = 0
3343 : 8510 sta adrh
3345 : ee0302 inc ada2
3348 : e60e inc ad2
334a : 08 php ;save NZ as operand 2 becomes the new result
334b : 68 pla
334c : 2982 and #$82 ;mask N00000Z0
334e : 8511 sta adrf ;no need to check carry as we are adding to 0
3350 : c612 dec sb2 ;complement subtract operand 2
3352 : ce0402 dec sba2
3355 : a50e lda ad2
3357 : 850f sta adrl
3359 : d0c6 bne tadd ;iterate op2
if disable_decimal < 1
next_test
335b : ad0002 > lda test_case ;previous test
335e : c929 > cmp #test_num
> trap_ne ;test is out of sequence
3360 : d0fe > bne * ;failed not equal (non zero)
>
002a = >test_num = test_num + 1
3362 : a92a > lda #test_num ;*** next tests' number
3364 : 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
3367 : f8 sed
3368 : a20e ldx #ad2 ;for indexed test
336a : a0ff ldy #$ff ;max range
336c : a999 lda #$99 ;start with adding 99 to 99 with carry
336e : 850d sta ad1 ;operand 1 - accumulator
3370 : 850e sta ad2 ;operand 2 - memory or immediate
3372 : 8d0302 sta ada2 ;non zp
3375 : 850f sta adrl ;expected result bits 0-7
3377 : a901 lda #1 ;set carry in & out
3379 : 850c sta adfc ;carry in - for diag
337b : 8510 sta adrh ;expected result bit 8 (carry out)
337d : a900 lda #0 ;complemented operand 2 for subtract
337f : 8512 sta sb2
3381 : 8d0402 sta sba2 ;non zp
3384 : 38 tdad sec ;test with carry set
3385 : 206934 jsr chkdad
3388 : c60c dec adfc ;now with carry clear
338a : a50f lda adrl ;decimal adjust result
338c : d008 bne tdad1 ;skip clear carry & preset result 99 (9A-1)
338e : c610 dec adrh
3390 : a999 lda #$99
3392 : 850f sta adrl
3394 : d012 bne tdad3
3396 : 290f tdad1 and #$f ;lower nibble mask
3398 : d00c bne tdad2 ;no decimal adjust needed
339a : c60f dec adrl ;decimal adjust (?0-6)
339c : c60f dec adrl
339e : c60f dec adrl
33a0 : c60f dec adrl
33a2 : c60f dec adrl
33a4 : c60f dec adrl
33a6 : c60f tdad2 dec adrl ;result -1
33a8 : 18 tdad3 clc ;test with carry clear
33a9 : 206934 jsr chkdad
33ac : e60c inc adfc ;same for operand -1 but with carry
33ae : a50d lda ad1 ;decimal adjust operand 1
33b0 : f015 beq tdad5 ;iterate operand 2
33b2 : 290f and #$f ;lower nibble mask
33b4 : d00c bne tdad4 ;skip decimal adjust
33b6 : c60d dec ad1 ;decimal adjust (?0-6)
33b8 : c60d dec ad1
33ba : c60d dec ad1
33bc : c60d dec ad1
33be : c60d dec ad1
33c0 : c60d dec ad1
33c2 : c60d tdad4 dec ad1 ;operand 1 -1
33c4 : 4c8433 jmp tdad ;iterate op1
33c7 : a999 tdad5 lda #$99 ;precharge op1 max
33c9 : 850d sta ad1
33cb : a50e lda ad2 ;decimal adjust operand 2
33cd : f030 beq tdad7 ;end of iteration
33cf : 290f and #$f ;lower nibble mask
33d1 : d018 bne tdad6 ;skip decimal adjust
33d3 : c60e dec ad2 ;decimal adjust (?0-6)
33d5 : c60e dec ad2
33d7 : c60e dec ad2
33d9 : c60e dec ad2
33db : c60e dec ad2
33dd : c60e dec ad2
33df : e612 inc sb2 ;complemented decimal adjust for subtract (?9+6)
33e1 : e612 inc sb2
33e3 : e612 inc sb2
33e5 : e612 inc sb2
33e7 : e612 inc sb2
33e9 : e612 inc sb2
33eb : c60e tdad6 dec ad2 ;operand 2 -1
33ed : e612 inc sb2 ;complemented operand for subtract
33ef : a512 lda sb2
33f1 : 8d0402 sta sba2 ;copy as non zp operand
33f4 : a50e lda ad2
33f6 : 8d0302 sta ada2 ;copy as non zp operand
33f9 : 850f sta adrl ;new result since op1+carry=00+carry +op2=op2
33fb : e610 inc adrh ;result carry
33fd : d085 bne tdad ;iterate op2
33ff : tdad7
next_test
33ff : ad0002 > lda test_case ;previous test
3402 : c92a > cmp #test_num
> trap_ne ;test is out of sequence
3404 : d0fe > bne * ;failed not equal (non zero)
>
002b = >test_num = test_num + 1
3406 : a92b > lda #test_num ;*** next tests' number
3408 : 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
340b : 18 clc
340c : d8 cld
340d : 08 php
340e : a955 lda #$55
3410 : 6955 adc #$55
3412 : c9aa cmp #$aa
trap_ne ;expected binary result after cld
3414 : d0fe > bne * ;failed not equal (non zero)
3416 : 18 clc
3417 : f8 sed
3418 : 08 php
3419 : a955 lda #$55
341b : 6955 adc #$55
341d : c910 cmp #$10
trap_ne ;expected decimal result after sed
341f : d0fe > bne * ;failed not equal (non zero)
3421 : d8 cld
3422 : 28 plp
3423 : a955 lda #$55
3425 : 6955 adc #$55
3427 : c910 cmp #$10
trap_ne ;expected decimal result after plp D=1
3429 : d0fe > bne * ;failed not equal (non zero)
342b : 28 plp
342c : a955 lda #$55
342e : 6955 adc #$55
3430 : c9aa cmp #$aa
trap_ne ;expected binary result after plp D=0
3432 : d0fe > bne * ;failed not equal (non zero)
3434 : 18 clc
3435 : a934 lda #hi bin_rti_ret ;emulated interrupt for rti
3437 : 48 pha
3438 : a94f lda #lo bin_rti_ret
343a : 48 pha
343b : 08 php
343c : f8 sed
343d : a934 lda #hi dec_rti_ret ;emulated interrupt for rti
343f : 48 pha
3440 : a946 lda #lo dec_rti_ret
3442 : 48 pha
3443 : 08 php
3444 : d8 cld
3445 : 40 rti
3446 : dec_rti_ret
3446 : a955 lda #$55
3448 : 6955 adc #$55
344a : c910 cmp #$10
trap_ne ;expected decimal result after rti D=1
344c : d0fe > bne * ;failed not equal (non zero)
344e : 40 rti
344f : bin_rti_ret
344f : a955 lda #$55
3451 : 6955 adc #$55
3453 : c9aa cmp #$aa
trap_ne ;expected binary result after rti D=0
3455 : d0fe > bne * ;failed not equal (non zero)
endif
3457 : ad0002 lda test_case
345a : c92b cmp #test_num
trap_ne ;previous test is out of sequence
345c : d0fe > bne * ;failed not equal (non zero)
345e : a9f0 lda #$f0 ;mark opcode testing complete
3460 : 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
3463 : 4c6334 > jmp * ;test passed, no errors
; -------------
; S U C C E S S ************************************************
3466 : 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
3469 : chkdad
; decimal ADC / SBC zp
3469 : 08 php ;save carry for subtract
346a : a50d lda ad1
346c : 650e adc ad2 ;perform add
346e : 08 php
346f : c50f cmp adrl ;check result
trap_ne ;bad result
3471 : d0fe > bne * ;failed not equal (non zero)
3473 : 68 pla ;check flags
3474 : 2901 and #1 ;mask carry
3476 : c510 cmp adrh
trap_ne ;bad carry
3478 : d0fe > bne * ;failed not equal (non zero)
347a : 28 plp
347b : 08 php ;save carry for next add
347c : a50d lda ad1
347e : e512 sbc sb2 ;perform subtract
3480 : 08 php
3481 : c50f cmp adrl ;check result
trap_ne ;bad result
3483 : d0fe > bne * ;failed not equal (non zero)
3485 : 68 pla ;check flags
3486 : 2901 and #1 ;mask carry
3488 : c510 cmp adrh
trap_ne ;bad flags
348a : d0fe > bne * ;failed not equal (non zero)
348c : 28 plp
; decimal ADC / SBC abs
348d : 08 php ;save carry for subtract
348e : a50d lda ad1
3490 : 6d0302 adc ada2 ;perform add
3493 : 08 php
3494 : c50f cmp adrl ;check result
trap_ne ;bad result
3496 : d0fe > bne * ;failed not equal (non zero)
3498 : 68 pla ;check flags
3499 : 2901 and #1 ;mask carry
349b : c510 cmp adrh
trap_ne ;bad carry
349d : d0fe > bne * ;failed not equal (non zero)
349f : 28 plp
34a0 : 08 php ;save carry for next add
34a1 : a50d lda ad1
34a3 : ed0402 sbc sba2 ;perform subtract
34a6 : 08 php
34a7 : c50f cmp adrl ;check result
trap_ne ;bad result
34a9 : d0fe > bne * ;failed not equal (non zero)
34ab : 68 pla ;check flags
34ac : 2901 and #1 ;mask carry
34ae : c510 cmp adrh
trap_ne ;bad carry
34b0 : d0fe > bne * ;failed not equal (non zero)
34b2 : 28 plp
; decimal ADC / SBC #
34b3 : 08 php ;save carry for subtract
34b4 : a50e lda ad2
34b6 : 8d1202 sta ex_adci+1 ;set ADC # operand
34b9 : a50d lda ad1
34bb : 201102 jsr ex_adci ;execute ADC # in RAM
34be : 08 php
34bf : c50f cmp adrl ;check result
trap_ne ;bad result
34c1 : d0fe > bne * ;failed not equal (non zero)
34c3 : 68 pla ;check flags
34c4 : 2901 and #1 ;mask carry
34c6 : c510 cmp adrh
trap_ne ;bad carry
34c8 : d0fe > bne * ;failed not equal (non zero)
34ca : 28 plp
34cb : 08 php ;save carry for next add
34cc : a512 lda sb2
34ce : 8d1502 sta ex_sbci+1 ;set SBC # operand
34d1 : a50d lda ad1
34d3 : 201402 jsr ex_sbci ;execute SBC # in RAM
34d6 : 08 php
34d7 : c50f cmp adrl ;check result
trap_ne ;bad result
34d9 : d0fe > bne * ;failed not equal (non zero)
34db : 68 pla ;check flags
34dc : 2901 and #1 ;mask carry
34de : c510 cmp adrh
trap_ne ;bad carry
34e0 : d0fe > bne * ;failed not equal (non zero)
34e2 : 28 plp
; decimal ADC / SBC zp,x
34e3 : 08 php ;save carry for subtract
34e4 : a50d lda ad1
34e6 : 7500 adc 0,x ;perform add
34e8 : 08 php
34e9 : c50f cmp adrl ;check result
trap_ne ;bad result
34eb : d0fe > bne * ;failed not equal (non zero)
34ed : 68 pla ;check flags
34ee : 2901 and #1 ;mask carry
34f0 : c510 cmp adrh
trap_ne ;bad carry
34f2 : d0fe > bne * ;failed not equal (non zero)
34f4 : 28 plp
34f5 : 08 php ;save carry for next add
34f6 : a50d lda ad1
34f8 : f504 sbc sb2-ad2,x ;perform subtract
34fa : 08 php
34fb : c50f cmp adrl ;check result
trap_ne ;bad result
34fd : d0fe > bne * ;failed not equal (non zero)
34ff : 68 pla ;check flags
3500 : 2901 and #1 ;mask carry
3502 : c510 cmp adrh
trap_ne ;bad carry
3504 : d0fe > bne * ;failed not equal (non zero)
3506 : 28 plp
; decimal ADC / SBC abs,x
3507 : 08 php ;save carry for subtract
3508 : a50d lda ad1
350a : 7df501 adc ada2-ad2,x ;perform add
350d : 08 php
350e : c50f cmp adrl ;check result
trap_ne ;bad result
3510 : d0fe > bne * ;failed not equal (non zero)
3512 : 68 pla ;check flags
3513 : 2901 and #1 ;mask carry
3515 : c510 cmp adrh
trap_ne ;bad carry
3517 : d0fe > bne * ;failed not equal (non zero)
3519 : 28 plp
351a : 08 php ;save carry for next add
351b : a50d lda ad1
351d : fdf601 sbc sba2-ad2,x ;perform subtract
3520 : 08 php
3521 : c50f cmp adrl ;check result
trap_ne ;bad result
3523 : d0fe > bne * ;failed not equal (non zero)
3525 : 68 pla ;check flags
3526 : 2901 and #1 ;mask carry
3528 : c510 cmp adrh
trap_ne ;bad carry
352a : d0fe > bne * ;failed not equal (non zero)
352c : 28 plp
; decimal ADC / SBC abs,y
352d : 08 php ;save carry for subtract
352e : a50d lda ad1
3530 : 790401 adc ada2-$ff,y ;perform add
3533 : 08 php
3534 : c50f cmp adrl ;check result
trap_ne ;bad result
3536 : d0fe > bne * ;failed not equal (non zero)
3538 : 68 pla ;check flags
3539 : 2901 and #1 ;mask carry
353b : c510 cmp adrh
trap_ne ;bad carry
353d : d0fe > bne * ;failed not equal (non zero)
353f : 28 plp
3540 : 08 php ;save carry for next add
3541 : a50d lda ad1
3543 : f90501 sbc sba2-$ff,y ;perform subtract
3546 : 08 php
3547 : c50f cmp adrl ;check result
trap_ne ;bad result
3549 : d0fe > bne * ;failed not equal (non zero)
354b : 68 pla ;check flags
354c : 2901 and #1 ;mask carry
354e : c510 cmp adrh
trap_ne ;bad carry
3550 : d0fe > bne * ;failed not equal (non zero)
3552 : 28 plp
; decimal ADC / SBC (zp,x)
3553 : 08 php ;save carry for subtract
3554 : a50d lda ad1
3556 : 6144 adc (lo adi2-ad2,x) ;perform add
3558 : 08 php
3559 : c50f cmp adrl ;check result
trap_ne ;bad result
355b : d0fe > bne * ;failed not equal (non zero)
355d : 68 pla ;check flags
355e : 2901 and #1 ;mask carry
3560 : c510 cmp adrh
trap_ne ;bad carry
3562 : d0fe > bne * ;failed not equal (non zero)
3564 : 28 plp
3565 : 08 php ;save carry for next add
3566 : a50d lda ad1
3568 : e146 sbc (lo sbi2-ad2,x) ;perform subtract
356a : 08 php
356b : c50f cmp adrl ;check result
trap_ne ;bad result
356d : d0fe > bne * ;failed not equal (non zero)
356f : 68 pla ;check flags
3570 : 2901 and #1 ;mask carry
3572 : c510 cmp adrh
trap_ne ;bad carry
3574 : d0fe > bne * ;failed not equal (non zero)
3576 : 28 plp
; decimal ADC / SBC (abs),y
3577 : 08 php ;save carry for subtract
3578 : a50d lda ad1
357a : 7156 adc (adiy2),y ;perform add
357c : 08 php
357d : c50f cmp adrl ;check result
trap_ne ;bad result
357f : d0fe > bne * ;failed not equal (non zero)
3581 : 68 pla ;check flags
3582 : 2901 and #1 ;mask carry
3584 : c510 cmp adrh
trap_ne ;bad carry
3586 : d0fe > bne * ;failed not equal (non zero)
3588 : 28 plp
3589 : 08 php ;save carry for next add
358a : a50d lda ad1
358c : f158 sbc (sbiy2),y ;perform subtract
358e : 08 php
358f : c50f cmp adrl ;check result
trap_ne ;bad result
3591 : d0fe > bne * ;failed not equal (non zero)
3593 : 68 pla ;check flags
3594 : 2901 and #1 ;mask carry
3596 : c510 cmp adrh
trap_ne ;bad carry
3598 : d0fe > bne * ;failed not equal (non zero)
359a : 28 plp
359b : 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
359c : a511 chkadd lda adrf ;add V-flag if overflow
359e : 2983 and #$83 ;keep N-----ZC / clear V
35a0 : 48 pha
35a1 : a50d lda ad1 ;test sign unequal between operands
35a3 : 450e eor ad2
35a5 : 300a bmi ckad1 ;no overflow possible - operands have different sign
35a7 : a50d lda ad1 ;test sign equal between operands and result
35a9 : 450f eor adrl
35ab : 1004 bpl ckad1 ;no overflow occured - operand and result have same sign
35ad : 68 pla
35ae : 0940 ora #$40 ;set V
35b0 : 48 pha
35b1 : 68 ckad1 pla
35b2 : 8511 sta adrf ;save expected flags
; binary ADC / SBC zp
35b4 : 08 php ;save carry for subtract
35b5 : a50d lda ad1
35b7 : 650e adc ad2 ;perform add
35b9 : 08 php
35ba : c50f cmp adrl ;check result
trap_ne ;bad result
35bc : d0fe > bne * ;failed not equal (non zero)
35be : 68 pla ;check flags
35bf : 29c3 and #$c3 ;mask NV----ZC
35c1 : c511 cmp adrf
trap_ne ;bad flags
35c3 : d0fe > bne * ;failed not equal (non zero)
35c5 : 28 plp
35c6 : 08 php ;save carry for next add
35c7 : a50d lda ad1
35c9 : e512 sbc sb2 ;perform subtract
35cb : 08 php
35cc : c50f cmp adrl ;check result
trap_ne ;bad result
35ce : d0fe > bne * ;failed not equal (non zero)
35d0 : 68 pla ;check flags
35d1 : 29c3 and #$c3 ;mask NV----ZC
35d3 : c511 cmp adrf
trap_ne ;bad flags
35d5 : d0fe > bne * ;failed not equal (non zero)
35d7 : 28 plp
; binary ADC / SBC abs
35d8 : 08 php ;save carry for subtract
35d9 : a50d lda ad1
35db : 6d0302 adc ada2 ;perform add
35de : 08 php
35df : c50f cmp adrl ;check result
trap_ne ;bad result
35e1 : d0fe > bne * ;failed not equal (non zero)
35e3 : 68 pla ;check flags
35e4 : 29c3 and #$c3 ;mask NV----ZC
35e6 : c511 cmp adrf
trap_ne ;bad flags
35e8 : d0fe > bne * ;failed not equal (non zero)
35ea : 28 plp
35eb : 08 php ;save carry for next add
35ec : a50d lda ad1
35ee : ed0402 sbc sba2 ;perform subtract
35f1 : 08 php
35f2 : c50f cmp adrl ;check result
trap_ne ;bad result
35f4 : d0fe > bne * ;failed not equal (non zero)
35f6 : 68 pla ;check flags
35f7 : 29c3 and #$c3 ;mask NV----ZC
35f9 : c511 cmp adrf
trap_ne ;bad flags
35fb : d0fe > bne * ;failed not equal (non zero)
35fd : 28 plp
; binary ADC / SBC #
35fe : 08 php ;save carry for subtract
35ff : a50e lda ad2
3601 : 8d1202 sta ex_adci+1 ;set ADC # operand
3604 : a50d lda ad1
3606 : 201102 jsr ex_adci ;execute ADC # in RAM
3609 : 08 php
360a : c50f cmp adrl ;check result
trap_ne ;bad result
360c : d0fe > bne * ;failed not equal (non zero)
360e : 68 pla ;check flags
360f : 29c3 and #$c3 ;mask NV----ZC
3611 : c511 cmp adrf
trap_ne ;bad flags
3613 : d0fe > bne * ;failed not equal (non zero)
3615 : 28 plp
3616 : 08 php ;save carry for next add
3617 : a512 lda sb2
3619 : 8d1502 sta ex_sbci+1 ;set SBC # operand
361c : a50d lda ad1
361e : 201402 jsr ex_sbci ;execute SBC # in RAM
3621 : 08 php
3622 : c50f cmp adrl ;check result
trap_ne ;bad result
3624 : d0fe > bne * ;failed not equal (non zero)
3626 : 68 pla ;check flags
3627 : 29c3 and #$c3 ;mask NV----ZC
3629 : c511 cmp adrf
trap_ne ;bad flags
362b : d0fe > bne * ;failed not equal (non zero)
362d : 28 plp
; binary ADC / SBC zp,x
362e : 08 php ;save carry for subtract
362f : a50d lda ad1
3631 : 7500 adc 0,x ;perform add
3633 : 08 php
3634 : c50f cmp adrl ;check result
trap_ne ;bad result
3636 : d0fe > bne * ;failed not equal (non zero)
3638 : 68 pla ;check flags
3639 : 29c3 and #$c3 ;mask NV----ZC
363b : c511 cmp adrf
trap_ne ;bad flags
363d : d0fe > bne * ;failed not equal (non zero)
363f : 28 plp
3640 : 08 php ;save carry for next add
3641 : a50d lda ad1
3643 : f504 sbc sb2-ad2,x ;perform subtract
3645 : 08 php
3646 : c50f cmp adrl ;check result
trap_ne ;bad result
3648 : d0fe > bne * ;failed not equal (non zero)
364a : 68 pla ;check flags
364b : 29c3 and #$c3 ;mask NV----ZC
364d : c511 cmp adrf
trap_ne ;bad flags
364f : d0fe > bne * ;failed not equal (non zero)
3651 : 28 plp
; binary ADC / SBC abs,x
3652 : 08 php ;save carry for subtract
3653 : a50d lda ad1
3655 : 7df501 adc ada2-ad2,x ;perform add
3658 : 08 php
3659 : c50f cmp adrl ;check result
trap_ne ;bad result
365b : d0fe > bne * ;failed not equal (non zero)
365d : 68 pla ;check flags
365e : 29c3 and #$c3 ;mask NV----ZC
3660 : c511 cmp adrf
trap_ne ;bad flags
3662 : d0fe > bne * ;failed not equal (non zero)
3664 : 28 plp
3665 : 08 php ;save carry for next add
3666 : a50d lda ad1
3668 : fdf601 sbc sba2-ad2,x ;perform subtract
366b : 08 php
366c : c50f cmp adrl ;check result
trap_ne ;bad result
366e : d0fe > bne * ;failed not equal (non zero)
3670 : 68 pla ;check flags
3671 : 29c3 and #$c3 ;mask NV----ZC
3673 : c511 cmp adrf
trap_ne ;bad flags
3675 : d0fe > bne * ;failed not equal (non zero)
3677 : 28 plp
; binary ADC / SBC abs,y
3678 : 08 php ;save carry for subtract
3679 : a50d lda ad1
367b : 790401 adc ada2-$ff,y ;perform add
367e : 08 php
367f : c50f cmp adrl ;check result
trap_ne ;bad result
3681 : d0fe > bne * ;failed not equal (non zero)
3683 : 68 pla ;check flags
3684 : 29c3 and #$c3 ;mask NV----ZC
3686 : c511 cmp adrf
trap_ne ;bad flags
3688 : d0fe > bne * ;failed not equal (non zero)
368a : 28 plp
368b : 08 php ;save carry for next add
368c : a50d lda ad1
368e : f90501 sbc sba2-$ff,y ;perform subtract
3691 : 08 php
3692 : c50f cmp adrl ;check result
trap_ne ;bad result
3694 : d0fe > bne * ;failed not equal (non zero)
3696 : 68 pla ;check flags
3697 : 29c3 and #$c3 ;mask NV----ZC
3699 : c511 cmp adrf
trap_ne ;bad flags
369b : d0fe > bne * ;failed not equal (non zero)
369d : 28 plp
; binary ADC / SBC (zp,x)
369e : 08 php ;save carry for subtract
369f : a50d lda ad1
36a1 : 6144 adc (lo adi2-ad2,x) ;perform add
36a3 : 08 php
36a4 : c50f cmp adrl ;check result
trap_ne ;bad result
36a6 : d0fe > bne * ;failed not equal (non zero)
36a8 : 68 pla ;check flags
36a9 : 29c3 and #$c3 ;mask NV----ZC
36ab : c511 cmp adrf
trap_ne ;bad flags
36ad : d0fe > bne * ;failed not equal (non zero)
36af : 28 plp
36b0 : 08 php ;save carry for next add
36b1 : a50d lda ad1
36b3 : e146 sbc (lo sbi2-ad2,x) ;perform subtract
36b5 : 08 php
36b6 : c50f cmp adrl ;check result
trap_ne ;bad result
36b8 : d0fe > bne * ;failed not equal (non zero)
36ba : 68 pla ;check flags
36bb : 29c3 and #$c3 ;mask NV----ZC
36bd : c511 cmp adrf
trap_ne ;bad flags
36bf : d0fe > bne * ;failed not equal (non zero)
36c1 : 28 plp
; binary ADC / SBC (abs),y
36c2 : 08 php ;save carry for subtract
36c3 : a50d lda ad1
36c5 : 7156 adc (adiy2),y ;perform add
36c7 : 08 php
36c8 : c50f cmp adrl ;check result
trap_ne ;bad result
36ca : d0fe > bne * ;failed not equal (non zero)
36cc : 68 pla ;check flags
36cd : 29c3 and #$c3 ;mask NV----ZC
36cf : c511 cmp adrf
trap_ne ;bad flags
36d1 : d0fe > bne * ;failed not equal (non zero)
36d3 : 28 plp
36d4 : 08 php ;save carry for next add
36d5 : a50d lda ad1
36d7 : f158 sbc (sbiy2),y ;perform subtract
36d9 : 08 php
36da : c50f cmp adrl ;check result
trap_ne ;bad result
36dc : d0fe > bne * ;failed not equal (non zero)
36de : 68 pla ;check flags
36df : 29c3 and #$c3 ;mask NV----ZC
36e1 : c511 cmp adrf
trap_ne ;bad flags
36e3 : d0fe > bne * ;failed not equal (non zero)
36e5 : 28 plp
36e6 : 60 rts
; target for the jump absolute test
36e7 : 88 dey
36e8 : 88 dey
36e9 : test_far
36e9 : 08 php ;either SP or Y count will fail, if we do not hit
36ea : 88 dey
36eb : 88 dey
36ec : 88 dey
36ed : 28 plp
trap_cs ;flags loaded?
36ee : b0fe > bcs * ;failed carry set
trap_vs
36f0 : 70fe > bvs * ;failed overflow set
trap_mi
36f2 : 30fe > bmi * ;failed minus (bit 7 set)
trap_eq
36f4 : f0fe > beq * ;failed equal (zero)
36f6 : c946 cmp #'F' ;registers loaded?
trap_ne
36f8 : d0fe > bne * ;failed not equal (non zero)
36fa : e041 cpx #'A'
trap_ne
36fc : d0fe > bne * ;failed not equal (non zero)
36fe : c04f cpy #('R'-3)
trap_ne
3700 : d0fe > bne * ;failed not equal (non zero)
3702 : 48 pha ;save a,x
3703 : 8a txa
3704 : 48 pha
3705 : ba tsx
3706 : e0fd cpx #$fd ;check SP
trap_ne
3708 : d0fe > bne * ;failed not equal (non zero)
370a : 68 pla ;restore x
370b : aa tax
set_stat $ff
> load_flag $ff
370c : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
370e : 48 > pha ;use stack to load status
370f : 28 > plp
3710 : 68 pla ;restore a
3711 : e8 inx ;return registers with modifications
3712 : 49aa eor #$aa ;N=1, V=1, Z=0, C=1
3714 : 4c2f09 jmp far_ret
; target for the jump indirect test
3717 : 00 align
3718 : 2137 ptr_tst_ind dw test_ind
371a : 8409 ptr_ind_ret dw ind_ret
trap ;runover protection
371c : 4c1c37 > jmp * ;failed anyway
371f : 88 dey
3720 : 88 dey
3721 : test_ind
3721 : 08 php ;either SP or Y count will fail, if we do not hit
3722 : 88 dey
3723 : 88 dey
3724 : 88 dey
3725 : 28 plp
trap_cs ;flags loaded?
3726 : b0fe > bcs * ;failed carry set
trap_vs
3728 : 70fe > bvs * ;failed overflow set
trap_mi
372a : 30fe > bmi * ;failed minus (bit 7 set)
trap_eq
372c : f0fe > beq * ;failed equal (zero)
372e : c949 cmp #'I' ;registers loaded?
trap_ne
3730 : d0fe > bne * ;failed not equal (non zero)
3732 : e04e cpx #'N'
trap_ne
3734 : d0fe > bne * ;failed not equal (non zero)
3736 : c041 cpy #('D'-3)
trap_ne
3738 : d0fe > bne * ;failed not equal (non zero)
373a : 48 pha ;save a,x
373b : 8a txa
373c : 48 pha
373d : ba tsx
373e : e0fd cpx #$fd ;check SP
trap_ne
3740 : d0fe > bne * ;failed not equal (non zero)
3742 : 68 pla ;restore x
3743 : aa tax
set_stat $ff
> load_flag $ff
3744 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3746 : 48 > pha ;use stack to load status
3747 : 28 > plp
3748 : 68 pla ;restore a
3749 : e8 inx ;return registers with modifications
374a : 49aa eor #$aa ;N=1, V=1, Z=0, C=1
374c : 6c1a37 jmp (ptr_ind_ret)
trap ;runover protection
374f : 4c4f37 > jmp * ;failed anyway
; target for the jump subroutine test
3752 : 88 dey
3753 : 88 dey
3754 : test_jsr
3754 : 08 php ;either SP or Y count will fail, if we do not hit
3755 : 88 dey
3756 : 88 dey
3757 : 88 dey
3758 : 28 plp
trap_cs ;flags loaded?
3759 : b0fe > bcs * ;failed carry set
trap_vs
375b : 70fe > bvs * ;failed overflow set
trap_mi
375d : 30fe > bmi * ;failed minus (bit 7 set)
trap_eq
375f : f0fe > beq * ;failed equal (zero)
3761 : c94a cmp #'J' ;registers loaded?
trap_ne
3763 : d0fe > bne * ;failed not equal (non zero)
3765 : e053 cpx #'S'
trap_ne
3767 : d0fe > bne * ;failed not equal (non zero)
3769 : c04f cpy #('R'-3)
trap_ne
376b : d0fe > bne * ;failed not equal (non zero)
376d : 48 pha ;save a,x
376e : 8a txa
376f : 48 pha
3770 : ba tsx ;sp -4? (return addr,a,x)
3771 : e0fb cpx #$fb
trap_ne
3773 : d0fe > bne * ;failed not equal (non zero)
3775 : adff01 lda $1ff ;propper return on stack
3778 : c909 cmp #hi(jsr_ret)
trap_ne
377a : d0fe > bne * ;failed not equal (non zero)
377c : adfe01 lda $1fe
377f : c9ba cmp #lo(jsr_ret)
trap_ne
3781 : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
3783 : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
3785 : 48 > pha ;use stack to load status
3786 : 28 > plp
3787 : 68 pla ;pull x,a
3788 : aa tax
3789 : 68 pla
378a : e8 inx ;return registers with modifications
378b : 49aa eor #$aa ;N=1, V=1, Z=0, C=1
378d : 60 rts
trap ;runover protection
378e : 4c8e37 > jmp * ;failed anyway
;trap in case of unexpected IRQ, NMI, BRK, RESET - BRK test target
3791 : nmi_trap
trap ;check stack for conditions at NMI
3791 : 4c9137 > jmp * ;failed anyway
3794 : res_trap
trap ;unexpected RESET
3794 : 4c9437 > jmp * ;failed anyway
3797 : 88 dey
3798 : 88 dey
3799 : irq_trap ;BRK test or unextpected BRK or IRQ
3799 : 08 php ;either SP or Y count will fail, if we do not hit
379a : 88 dey
379b : 88 dey
379c : 88 dey
;next 4 traps could be caused by unexpected BRK or IRQ
;check stack for BREAK and originating location
;possible jump/branch into weeds (uninitialized space)
379d : c942 cmp #'B' ;registers loaded?
trap_ne
379f : d0fe > bne * ;failed not equal (non zero)
37a1 : e052 cpx #'R'
trap_ne
37a3 : d0fe > bne * ;failed not equal (non zero)
37a5 : c048 cpy #('K'-3)
trap_ne
37a7 : d0fe > bne * ;failed not equal (non zero)
37a9 : 850a sta irq_a ;save registers during break test
37ab : 860b stx irq_x
37ad : ba tsx ;test break on stack
37ae : bd0201 lda $102,x
cmp_flag 0 ;break test should have B=1
37b1 : c930 > cmp #(0 |fao)&m8 ;expected flags + always on bits
trap_ne ; - no break flag on stack
37b3 : d0fe > bne * ;failed not equal (non zero)
37b5 : 68 pla
37b6 : c934 cmp #fai ;should have added interrupt disable
trap_ne
37b8 : d0fe > bne * ;failed not equal (non zero)
37ba : ba tsx
37bb : e0fc cpx #$fc ;sp -3? (return addr, flags)
trap_ne
37bd : d0fe > bne * ;failed not equal (non zero)
37bf : adff01 lda $1ff ;propper return on stack
37c2 : c909 cmp #hi(brk_ret)
trap_ne
37c4 : d0fe > bne * ;failed not equal (non zero)
37c6 : adfe01 lda $1fe
37c9 : c9f1 cmp #lo(brk_ret)
trap_ne
37cb : d0fe > bne * ;failed not equal (non zero)
set_stat $ff
> load_flag $ff
37cd : a9ff > lda #$ff ;allow test to change I-flag (no mask)
>
37cf : 48 > pha ;use stack to load status
37d0 : 28 > plp
37d1 : a60b ldx irq_x
37d3 : e8 inx ;return registers with modifications
37d4 : a50a lda irq_a
37d6 : 49aa eor #$aa ;N=1, V=1, Z=0, C=1 but original flags should be restored
37d8 : 40 rti
trap ;runover protection
37d9 : 4cd937 > jmp * ;failed anyway
if report = 1
include "report.i65"
endif
;copy of data to initialize BSS segment
if load_data_direct != 1
37dc : zp_init
37dc : c3824100 zp1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
37e0 : 7f zp7f_ db $7f ;test pattern for compare
;logical zeropage operands
37e1 : 001f7180 zpOR_ db 0,$1f,$71,$80 ;test pattern for OR
37e5 : 0fff7f80 zpAN_ db $0f,$ff,$7f,$80 ;test pattern for AND
37e9 : ff0f8f8f zpEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR
;indirect addressing pointers
37ed : 1702 ind1_ dw abs1 ;indirect pointer to pattern in absolute memory
37ef : 1802 dw abs1+1
37f1 : 1902 dw abs1+2
37f3 : 1a02 dw abs1+3
37f5 : 1b02 dw abs7f
37f7 : 1f01 inw1_ dw abs1-$f8 ;indirect pointer for wrap-test pattern
37f9 : 0302 indt_ dw abst ;indirect pointer to store area in absolute memory
37fb : 0402 dw abst+1
37fd : 0502 dw abst+2
37ff : 0602 dw abst+3
3801 : 0b01 inwt_ dw abst-$f8 ;indirect pointer for wrap-test store
3803 : 4e02 indAN_ dw absAN ;indirect pointer to AND pattern in absolute memory
3805 : 4f02 dw absAN+1
3807 : 5002 dw absAN+2
3809 : 5102 dw absAN+3
380b : 5202 indEO_ dw absEO ;indirect pointer to EOR pattern in absolute memory
380d : 5302 dw absEO+1
380f : 5402 dw absEO+2
3811 : 5502 dw absEO+3
3813 : 4a02 indOR_ dw absOR ;indirect pointer to OR pattern in absolute memory
3815 : 4b02 dw absOR+1
3817 : 4c02 dw absOR+2
3819 : 4d02 dw absOR+3
;add/subtract indirect pointers
381b : 0302 adi2_ dw ada2 ;indirect pointer to operand 2 in absolute memory
381d : 0402 sbi2_ dw sba2 ;indirect pointer to complemented operand 2 (SBC)
381f : 0401 adiy2_ dw ada2-$ff ;with offset for indirect indexed
3821 : 0501 sbiy2_ dw sba2-$ff
3823 : 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
3823 : data_init
3823 : 2900 ex_and_ and #0 ;execute immediate opcodes
3825 : 60 rts
3826 : 4900 ex_eor_ eor #0 ;execute immediate opcodes
3828 : 60 rts
3829 : 0900 ex_ora_ ora #0 ;execute immediate opcodes
382b : 60 rts
382c : 6900 ex_adc_ adc #0 ;execute immediate opcodes
382e : 60 rts
382f : e900 ex_sbc_ sbc #0 ;execute immediate opcodes
3831 : 60 rts
3832 : c3824100 abs1_ db $c3,$82,$41,0 ;test patterns for LDx BIT ROL ROR ASL LSR
3836 : 7f abs7f_ db $7f ;test pattern for compare
;loads
3837 : 80800002 fLDx_ db fn,fn,0,fz ;expected flags for load
;shifts
383b : rASL_ ;expected result ASL & ROL -carry
383b : 86048200 rROL_ db $86,$04,$82,0 ; "
383f : 87058301 rROLc_ db $87,$05,$83,1 ;expected result ROL +carry
3843 : rLSR_ ;expected result LSR & ROR -carry
3843 : 61412000 rROR_ db $61,$41,$20,0 ; "
3847 : e1c1a080 rRORc_ db $e1,$c1,$a0,$80 ;expected result ROR +carry
384b : fASL_ ;expected flags for shifts
384b : 81018002 fROL_ db fnc,fc,fn,fz ;no carry in
384f : 81018000 fROLc_ db fnc,fc,fn,0 ;carry in
3853 : fLSR_
3853 : 01000102 fROR_ db fc,0,fc,fz ;no carry in
3857 : 81808180 fRORc_ db fnc,fn,fnc,fn ;carry in
;increments (decrements)
385b : 7f80ff0001 rINC_ db $7f,$80,$ff,0,1 ;expected result for INC/DEC
3860 : 0080800200 fINC_ db 0,fn,fn,fz,0 ;expected flags for INC/DEC
;logical memory operand
3865 : 001f7180 absOR_ db 0,$1f,$71,$80 ;test pattern for OR
3869 : 0fff7f80 absAN_ db $0f,$ff,$7f,$80 ;test pattern for AND
386d : ff0f8f8f absEO_ db $ff,$0f,$8f,$8f ;test pattern for EOR
;logical accu operand
3871 : 00f11f00 absORa_ db 0,$f1,$1f,0 ;test pattern for OR
3875 : f0ffffff absANa_ db $f0,$ff,$ff,$ff ;test pattern for AND
3879 : fff0f00f absEOa_ db $ff,$f0,$f0,$0f ;test pattern for EOR
;logical results
387d : 00ff7f80 absrlo_ db 0,$ff,$7f,$80
3881 : 02800080 absflo_ db fz,fn,0,fn
3885 : 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
3885 : vec_init
3885 : 9137 dw nmi_trap
3887 : 9437 dw res_trap
3889 : 9937 dw irq_trap
fffa = 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
fffa = end start
No errors in pass 2.
Wrote binary from address $0400 through $388a.
Total size 13451 bytes.
Program start address is at $0400 (1024).
================================================
FILE: assets/tests/README.md
================================================
These are Klaus Dormann 6502 functional tests, also available at:
https://github.com/Klaus2m5/6502_65C02_functional_tests
# 6502_functional_test.a65
Source code
# 6502_functional_test.bin
Assembled binary to be loaded at 0x400
# 6502_functional_test.lst
Listing file, comes in useful to identify bugs, since these tests have no
actual output.
================================================
FILE: cmake/FindSDL2.cmake
================================================
# This module defines
# SDL2_LIBRARY, the name of the library to link against
# SDL2_FOUND, if false, do not try to link to SDL2
# SDL2_INCLUDE_DIR, where to find SDL.h
#
# This module responds to the the flag:
# SDL2_BUILDING_LIBRARY
# If this is defined, then no SDL2main will be linked in because
# only applications need main().
# Otherwise, it is assumed you are building an application and this
# module will attempt to locate and set the the proper link flags
# as part of the returned SDL2_LIBRARY variable.
#
# Don't forget to include SDLmain.h and SDLmain.m your project for the
# OS X framework based version. (Other versions link to -lSDL2main which
# this module will try to find on your behalf.) Also for OS X, this
# module will automatically add the -framework Cocoa on your behalf.
#
#
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
# as appropriate. These values are used to generate the final SDL2_LIBRARY
# variable, but when these values are unset, SDL2_LIBRARY does not get created.
#
#
# $SDL2DIR is an environment variable that would
# correspond to the ./configure --prefix=$SDL2DIR
# used in building SDL2.
# l.e.galup 9-20-02
#
# Modified by Eric Wing.
# Added code to assist with automated building by using environmental variables
# and providing a more controlled/consistent search behavior.
# Added new modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
# Also corrected the header search path to follow "proper" SDL guidelines.
# Added a search for SDL2main which is needed by some platforms.
# Added a search for threads which is needed by some platforms.
# Added needed compile switches for MinGW.
#
# On OSX, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# SDL2_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
#
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
# This needed to change because "proper" SDL convention
# is #include "SDL.h", not . This is done for portability
# reasons because not all systems place things in SDL2/ (see FreeBSD).
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
message("")
SET(SDL2_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
${SDL2_PATH}
)
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
HINTS
$ENV{SDL2DIR}
PATH_SUFFIXES include/SDL2 include
PATHS ${SDL2_SEARCH_PATHS}
)
FIND_LIBRARY(SDL2_LIBRARY_TEMP
NAMES SDL2
HINTS
$ENV{SDL2DIR}
PATH_SUFFIXES lib64 lib
PATHS ${SDL2_SEARCH_PATHS}
)
IF(NOT SDL2_BUILDING_LIBRARY)
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
# Non-OS X framework versions expect you to also dynamically link to
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
# seem to provide SDL2main for compatibility even though they don't
# necessarily need it.
FIND_LIBRARY(SDL2MAIN_LIBRARY
NAMES SDL2main
HINTS
$ENV{SDL2DIR}
PATH_SUFFIXES lib64 lib
PATHS ${SDL2_SEARCH_PATHS}
)
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
ENDIF(NOT SDL2_BUILDING_LIBRARY)
# SDL2 may require threads on your system.
# The Apple build may not need an explicit flag because one of the
# frameworks may already provide it.
# But for non-OSX systems, I will use the CMake Threads package.
IF(NOT APPLE)
FIND_PACKAGE(Threads)
ENDIF(NOT APPLE)
# MinGW needs an additional library, mwindows
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
# (Actually on second look, I think it only needs one of the m* libraries.)
IF(MINGW)
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
ENDIF(MINGW)
IF(SDL2_LIBRARY_TEMP)
# For SDL2main
IF(NOT SDL2_BUILDING_LIBRARY)
IF(SDL2MAIN_LIBRARY)
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
ENDIF(SDL2MAIN_LIBRARY)
ENDIF(NOT SDL2_BUILDING_LIBRARY)
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
# CMake doesn't display the -framework Cocoa string in the UI even
# though it actually is there if I modify a pre-used variable.
# I think it has something to do with the CACHE STRING.
# So I use a temporary variable until the end so I can set the
# "real" variable in one-shot.
IF(APPLE)
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
ENDIF(APPLE)
# For threads, as mentioned Apple doesn't need this.
# In fact, there seems to be a problem if I used the Threads package
# and try using this line, so I'm just skipping it entirely for OS X.
IF(NOT APPLE)
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
ENDIF(NOT APPLE)
# For MinGW library
IF(MINGW)
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
ENDIF(MINGW)
# Set the final string here so the GUI reflects the final state.
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
ENDIF(SDL2_LIBRARY_TEMP)
message("")
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
================================================
FILE: cmake/FindSDL2_image.cmake
================================================
# Locate SDL_image library
#
# This module defines:
#
# ::
#
# SDL_IMAGE_LIBRARIES, the name of the library to link against
# SDL_IMAGE_INCLUDE_DIRS, where to find the headers
# SDL_IMAGE_FOUND, if false, do not try to link against
# SDL_IMAGE_VERSION_STRING - human-readable string containing the version of SDL_image
#
#
#
# For backward compatiblity the following variables are also set:
#
# ::
#
# SDLIMAGE_LIBRARY (same value as SDL_IMAGE_LIBRARIES)
# SDLIMAGE_INCLUDE_DIR (same value as SDL_IMAGE_INCLUDE_DIRS)
# SDLIMAGE_FOUND (same value as SDL_IMAGE_FOUND)
#
#
#
# $SDLDIR is an environment variable that would correspond to the
# ./configure --prefix=$SDLDIR used in building SDL.
#
# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
HINTS
ENV SDL2IMAGEDIR
ENV SDL2DIR
PATH_SUFFIXES SDL2
# path suffixes to search inside ENV{SDLDIR}
include/SDL2 include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_IMAGE_LIBRARY
NAMES SDL2_image
HINTS
ENV SDL2IMAGEDIR
ENV SDL2DIR
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h")
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}")
set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH})
unset(SDL2_IMAGE_VERSION_MAJOR_LINE)
unset(SDL2_IMAGE_VERSION_MINOR_LINE)
unset(SDL2_IMAGE_VERSION_PATCH_LINE)
unset(SDL2_IMAGE_VERSION_MAJOR)
unset(SDL2_IMAGE_VERSION_MINOR)
unset(SDL2_IMAGE_VERSION_PATCH)
endif()
set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY})
set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image
REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS
VERSION_VAR SDL2_IMAGE_VERSION_STRING)
# for backward compatiblity
#set(SDLIMAGE_LIBRARY ${SDL_IMAGE_LIBRARIES})
#set(SDLIMAGE_INCLUDE_DIR ${SDL_IMAGE_INCLUDE_DIRS})
#set(SDLIMAGE_FOUND ${SDL_IMAGE_FOUND})
mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
================================================
FILE: cmake/FindSDL2_net.cmake
================================================
# - Find SDL2_net library and headers
#
# Find module for SDL_net 2.0 (http://www.libsdl.org/projects/SDL_net/).
# It defines the following variables:
# SDL2_NET_INCLUDE_DIRS - The location of the headers, e.g., SDL_net.h.
# SDL2_NET_LIBRARIES - The libraries to link against to use SDL2_net.
# SDL2_NET_FOUND - If false, do not try to use SDL2_net.
# SDL2_NET_VERSION_STRING
# Human-readable string containing the version of SDL2_net.
#
# Also defined, but not for general use are:
# SDL2_NET_INCLUDE_DIR - The directory that contains SDL_net.h.
# SDL2_NET_LIBRARY - The location of the SDL2_net library.
#
#=============================================================================
# Copyright 2013 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_SDL2_NET QUIET SDL2_net)
find_path(SDL2_NET_INCLUDE_DIR
NAMES SDL_net.h
HINTS
${PC_SDL2_NET_INCLUDEDIR}
${PC_SDL2_NET_INCLUDE_DIRS}
PATH_SUFFIXES SDL2
)
find_library(SDL2_NET_LIBRARY
NAMES SDL2_net
HINTS
${PC_SDL2_NET_LIBDIR}
${PC_SDL2_NET_LIBRARY_DIRS}
PATH_SUFFIXES x64 x86
)
if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
set(SDL2_NET_VERSION_STRING ${SDL2_NET_VERSION_MAJOR}.${SDL2_NET_VERSION_MINOR}.${SDL2_NET_VERSION_PATCH})
unset(SDL2_NET_VERSION_MAJOR_LINE)
unset(SDL2_NET_VERSION_MINOR_LINE)
unset(SDL2_NET_VERSION_PATCH_LINE)
unset(SDL2_NET_VERSION_MAJOR)
unset(SDL2_NET_VERSION_MINOR)
unset(SDL2_NET_VERSION_PATCH)
endif()
set(SDL2_NET_INCLUDE_DIRS ${SDL2_NET_INCLUDE_DIR})
set(SDL2_NET_LIBRARIES ${SDL2_NET_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SDL2_net
REQUIRED_VARS SDL2_NET_INCLUDE_DIRS SDL2_NET_LIBRARIES
VERSION_VAR SDL2_NET_VERSION_STRING)
mark_as_advanced(SDL2_NET_INCLUDE_DIR SDL2_NET_LIBRARY)
================================================
FILE: cmake/FindSDL2_ttf.cmake
================================================
# Locate SDL_image library
#
# This module defines:
#
# ::
#
# SDL_TTF_LIBRARIES, the name of the library to link against
# SDL_TTF_INCLUDE_DIRS, where to find the headers
# SDL_TTF_FOUND, if false, do not try to link against
# SDL_F_VERSION_STRING - human-readable string containing the version of SDL_ttf
#
#
#
# For backward compatiblity the following variables are also set:
#
# ::
#
# SDLTTF_LIBRARY (same value as SDL_TTF_LIBRARIES)
# SDLTTF_INCLUDE_DIR (same value as SDL_TTF_INCLUDE_DIRS)
# SDLTTF_FOUND (same value as SDL_TTF_FOUND)
#
#
#
# $SDLDIR is an environment variable that would correspond to the
# ./configure --prefix=$SDLDIR used in building SDL.
#
# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
# Copyright 2012 Benjamin Eikel
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h
HINTS
ENV SDL2TTFDIR
ENV SDL2DIR
PATH_SUFFIXES SDL2
# path suffixes to search inside ENV{SDLDIR}
include/SDL2 include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_TTF_LIBRARY
NAMES SDL2_ttf
HINTS
ENV SDL2TTFDIR
ENV SDL2DIR
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h")
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
unset(SDL2_TTF_VERSION_MAJOR_LINE)
unset(SDL2_TTF_VERSION_MINOR_LINE)
unset(SDL2_TTF_VERSION_PATCH_LINE)
unset(SDL2_TTF_VERSION_MAJOR)
unset(SDL2_TTF_VERSION_MINOR)
unset(SDL2_TTF_VERSION_PATCH)
endif()
set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY})
set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf
REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS
VERSION_VAR SDL2_TTF_VERSION_STRING)
# for backward compatiblity
#set(SDLTTF_LIBRARY ${SDL_TTF_LIBRARIES})
#set(SDLTTF_INCLUDE_DIR ${SDL_TTF_INCLUDE_DIRS})
#set(SDLTTF_FOUND ${SDL_TTF_FOUND})
mark_as_advanced(SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR)
================================================
FILE: cmake/README.md
================================================
These have been downloaded from:
https://github.com/tcbrindle/sdl2-cmake-scripts
================================================
FILE: doc/.gitignore
================================================
html/
================================================
FILE: doc/doxygen.conf
================================================
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Emudore"
PROJECT_NUMBER =
PROJECT_BRIEF = "Commodore 64 emulator"
PROJECT_LOGO =
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../src/
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.markdown \
*.md \
*.mm \
*.dox \
*.py \
*.f90 \
*.f \
*.for \
*.vhd \
*.vhdl
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = YES
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
================================================
FILE: res/emudore.rc
================================================
IDI_ICON1 ICON DISCARDABLE "emudore.ico"
================================================
FILE: src/c64.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "c64.h"
#include "util.h"
C64::C64()
{
/* create chips */
cpu_ = new Cpu();
mem_ = new Memory();
cia1_ = new Cia1();
cia2_ = new Cia2();
vic_ = new Vic();
sid_ = new Sid();
io_ = new IO();
/* init cpu */
cpu_->memory(mem_);
cpu_->reset();
/* init vic-ii */
vic_->memory(mem_);
vic_->cpu(cpu_);
vic_->io(io_);
/* init cia1 */
cia1_->cpu(cpu_);
cia1_->io(io_);
/* init cia2 */
cia2_->cpu(cpu_);
/* init io */
io_->cpu(cpu_);
/* DMA */
mem_->vic(vic_);
mem_->cia1(cia1_);
mem_->cia2(cia2_);
/* r2 support */
#ifdef DEBUGGER_SUPPORT
debugger_ = new Debugger();
debugger_->memory(mem_);
debugger_->cpu(cpu_);
#endif
}
C64::~C64()
{
delete cpu_;
delete mem_;
delete cia1_;
delete cia2_;
delete vic_;
delete sid_;
delete io_;
#ifdef DEBUGGER_SUPPORT
delete debugger_;
#endif
}
void C64::start()
{
/* main emulator loop */
while(true)
{
#ifdef DEBUGGER_SUPPORT
if(!debugger_->emulate())
break;
#endif
/* CIA1 */
if(!cia1_->emulate())
break;
/* CIA2 */
if(!cia2_->emulate())
break;
/* CPU */
if(!cpu_->emulate())
break;
/* VIC-II */
if(!vic_->emulate())
break;
/* IO */
if(!io_->emulate())
break;
/* callback */
if(callback_ && !callback_())
break;
}
}
/**
* @brief emscripten's main loop
*/
void C64::emscripten_loop()
{
unsigned int frame = vic_->frames();
while(frame == vic_->frames())
{
/* CIA1 */
cia1_->emulate();
/* CIA2 */
cia2_->emulate();
/* CPU */
cpu_->emulate();
/* VIC-II */
vic_->emulate();
/* IO */
io_->emulate();
/* callback */
if(callback_) callback_();
}
}
/**
* @brief runs Klaus Dormann's 6502 test suite
*
* https://github.com/Klaus2m5/6502_65C02_functional_tests
*/
void C64::test_cpu()
{
uint16_t pc=0;
/* unmap C64 ROMs */
mem_->write_byte(Memory::kAddrMemoryLayout, 0);
/* load tests into RAM */
mem_->load_ram("tests/6502_functional_test.bin",0x400);
cpu_->pc(0x400);
while(true)
{
if(pc == cpu_->pc())
{
D("infinite loop at %x\n",pc);
break;
}
else if(cpu_->pc() == 0x3463)
{
D("test passed!\n");
break;
}
pc = cpu_->pc();
if(!cpu_->emulate())
break;
}
}
================================================
FILE: src/c64.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_C64_H
#define EMUDORE_C64_H
#include
#include "cpu.h"
#include "memory.h"
#include "cia1.h"
#include "cia2.h"
#include "vic.h"
#include "sid.h"
#include "io.h"
#ifdef DEBUGGER_SUPPORT
#include "debugger.h"
#endif
/**
* @brief Commodore 64
*
* This class glues together all the different
* components in a Commodore 64 computer
*/
class C64
{
private:
Cpu *cpu_;
Memory *mem_;
Cia1 *cia1_;
Cia2 *cia2_;
Vic *vic_;
Sid *sid_;
IO *io_;
std::function callback_;
#ifdef DEBUGGER_SUPPORT
Debugger *debugger_;
#endif
public:
C64();
~C64();
void start();
void emscripten_loop();
void callback(std::function cb){callback_ = cb;};
Cpu * cpu(){return cpu_;};
Memory * memory(){return mem_;};
IO * io(){return io_;};
/* test cpu */
void test_cpu();
};
#endif
================================================
FILE: src/cia1.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cia1.h"
// ctor /////////////////////////////////////////////////////////////////////
Cia1::Cia1()
{
timer_a_latch_ = timer_b_latch_ = timer_a_counter_ = timer_b_counter_ = 0;
timer_a_enabled_ = timer_b_enabled_ = timer_a_irq_enabled_ = timer_b_irq_enabled_ = false;
timer_a_irq_triggered_ = timer_b_irq_triggered_ = false;
timer_a_input_mode_ = timer_b_input_mode_ = kModeProcessor;
timer_a_run_mode_ = timer_b_run_mode_ = kModeRestart;
pra_ = prb_ = 0xff;
prev_cpu_cycles_ = 0;
}
// DMA register access //////////////////////////////////////////////////////
void Cia1::write_register(uint8_t r, uint8_t v)
{
switch(r)
{
/* data port a (PRA), keyboard matrix cols and joystick #2 */
case 0x0:
pra_ = v;
break;
/* data port b (PRB), keyboard matrix rows and joystick #1 */
case 0x1:
break;
/* data direction port a (DDRA) */
case 0x2:
break;
/* data direction port b (DDRB) */
case 0x3:
break;
/* timer a low byte */
case 0x4:
timer_a_latch_ &= 0xff00;
timer_a_latch_ |= v;
break;
/* timer a high byte */
case 0x5:
timer_a_latch_ &= 0x00ff;
timer_a_latch_ |= v << 8;
break;
/* timer b low byte */
case 0x6:
timer_b_latch_ &= 0xff00;
timer_b_latch_ |= v;
break;
/* timer b high byte */
case 0x7:
timer_b_latch_ &= 0x00ff;
timer_b_latch_ |= v << 8;
break;
/* RTC 1/10s */
case 0x8:
break;
/* RTC seconds */
case 0x9:
break;
/* RTC minutes */
case 0xa:
break;
/* RTC hours */
case 0xb:
break;
/* shift serial */
case 0xc:
break;
/* interrupt control and status */
case 0xd:
/**
* if bit 7 is set, enable selected mask of
* interrupts, else disable them
*/
if(ISSET_BIT(v,0)) timer_a_irq_enabled_ = ISSET_BIT(v,7);
if(ISSET_BIT(v,1)) timer_b_irq_enabled_ = ISSET_BIT(v,7);
break;
/* control timer a */
case 0xe:
timer_a_enabled_ = ((v&(1<<0))!=0);
timer_a_input_mode_ = (v&(1<<5)) >> 5;
/* load latch requested */
if((v&(1<<4))!=0)
timer_a_counter_ = timer_a_latch_;
break;
/* control timer b */
case 0xf:
timer_b_enabled_ = ((v&0x1)!=0);
timer_b_input_mode_ = (v&(1<<5)) | (v&(1<<6)) >> 5;
/* load latch requested */
if((v&(1<<4))!=0)
timer_b_counter_ = timer_b_latch_;
break;
}
}
uint8_t Cia1::read_register(uint8_t r)
{
uint8_t retval = 0;
switch(r)
{
/* data port a (PRA), keyboard matrix cols and joystick #2 */
case 0x0:
break;
/* data port b (PRB), keyboard matrix rows and joystick #1 */
case 0x1:
if (pra_ == 0xff) retval = 0xff;
else if(pra_)
{
int col = 0;
uint8_t v = ~pra_;
while (v >>= 1)col++;
retval = io_->keyboard_matrix_row(col);
}
break;
/* data direction port a (DDRA) */
case 0x2:
break;
/* data direction port b (DDRB) */
case 0x3:
break;
/* timer a low byte */
case 0x4:
retval = (uint8_t)(timer_a_counter_ & 0x00ff);
break;
/* timer a high byte */
case 0x5:
retval = (uint8_t)((timer_a_counter_ & 0xff00) >> 8);
break;
/* timer b low byte */
case 0x6:
retval = (uint8_t)(timer_b_counter_ & 0x00ff);
break;
/* timer b high byte */
case 0x7:
retval = (uint8_t)((timer_b_counter_ & 0xff00) >> 8);
break;
/* RTC 1/10s */
case 0x8:
break;
/* RTC seconds */
case 0x9:
break;
/* RTC minutes */
case 0xa:
break;
/* RTC hours */
case 0xb:
break;
/* shift serial */
case 0xc:
break;
/* interrupt control and status */
case 0xd:
if(timer_a_irq_triggered_ ||
timer_b_irq_triggered_)
{
retval |= (1 << 7); // IRQ occured
if(timer_a_irq_triggered_) retval |= (1 << 0);
if(timer_b_irq_triggered_) retval |= (1 << 1);
}
break;
/* control timer a */
case 0xe:
break;
/* control timer b */
case 0xf:
break;
}
return retval;
}
// timer reset ///////////////////////////////////////////////////////////////
void Cia1::reset_timer_a()
{
switch(timer_a_run_mode_)
{
case kModeRestart:
timer_a_counter_ = timer_a_latch_;
break;
case kModeOneTime:
timer_a_enabled_ = false;
break;
}
}
void Cia1::reset_timer_b()
{
switch(timer_b_run_mode_)
{
case kModeRestart:
timer_b_counter_ = timer_b_latch_;
break;
case kModeOneTime:
timer_b_enabled_ = false;
break;
}
}
// emulation ////////////////////////////////////////////////////////////////
bool Cia1::emulate()
{
/* timer a */
if(timer_a_enabled_)
{
switch(timer_a_input_mode_)
{
case kModeProcessor:
timer_a_counter_ -= cpu_->cycles() - prev_cpu_cycles_;
if (timer_a_counter_ <= 0)
{
if(timer_a_irq_enabled_)
{
timer_a_irq_triggered_ = true;
cpu_->irq();
}
reset_timer_a();
}
break;
case kModeCNT:
break;
}
}
/* timer b */
if(timer_b_enabled_)
{
switch(timer_b_input_mode_)
{
case kModeProcessor:
timer_b_counter_ -= cpu_->cycles() - prev_cpu_cycles_;
if (timer_b_counter_ <= 0)
{
if(timer_b_irq_enabled_)
{
timer_b_irq_triggered_ = true;
cpu_->irq();
}
reset_timer_b();
}
break;
case kModeCNT:
break;
case kModeTimerA:
break;
case kModeTimerACNT:
break;
}
}
prev_cpu_cycles_ = cpu_->cycles();
return true;
}
================================================
FILE: src/cia1.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_CIA1_H
#define EMUDORE_CIA1_H
#include "io.h"
#include "cpu.h"
/**
* @brief MOS 6526 Complex Interface Adapter #1
*
* - Memory area : $DC00-$DCFF
* - Tasks : Keyboard, Joystick, Paddles, Datasette, IRQ control
*/
class Cia1
{
private:
Cpu *cpu_;
IO *io_;
int16_t timer_a_latch_;
int16_t timer_b_latch_;
int16_t timer_a_counter_;
int16_t timer_b_counter_;
bool timer_a_enabled_;
bool timer_b_enabled_;
bool timer_a_irq_enabled_;
bool timer_b_irq_enabled_;
bool timer_a_irq_triggered_;
bool timer_b_irq_triggered_;
uint8_t timer_a_run_mode_;
uint8_t timer_b_run_mode_;
uint8_t timer_a_input_mode_;
uint8_t timer_b_input_mode_;
unsigned int prev_cpu_cycles_;
uint8_t pra_, prb_;
public:
Cia1();
void cpu(Cpu *v){ cpu_ = v;};
void io(IO *v){ io_ = v;};
void write_register(uint8_t r, uint8_t v);
uint8_t read_register(uint8_t r);
void reset_timer_a();
void reset_timer_b();
bool emulate();
/* constants */
enum kInputMode
{
kModeProcessor,
kModeCNT,
kModeTimerA,
kModeTimerACNT
};
enum kRunMode
{
kModeRestart,
kModeOneTime
};
};
#endif
================================================
FILE: src/cia2.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cia2.h"
// ctor /////////////////////////////////////////////////////////////////////
Cia2::Cia2()
{
timer_a_latch_ = timer_b_latch_ = timer_a_counter_ = timer_b_counter_ = 0;
timer_a_enabled_ = timer_b_enabled_ = timer_a_irq_enabled_ = timer_b_irq_enabled_ = false;
timer_a_irq_triggered_ = timer_b_irq_triggered_ = false;
timer_a_input_mode_ = timer_b_input_mode_ = kModeProcessor;
timer_a_run_mode_ = timer_b_run_mode_ = kModeRestart;
pra_ = prb_ = 0xff;
prev_cpu_cycles_ = 0;
}
// DMA register access //////////////////////////////////////////////////////
void Cia2::write_register(uint8_t r, uint8_t v)
{
switch(r)
{
/* data port a (PRA) */
case 0x0:
pra_ = v;
break;
/* data port b (PRB) */
case 0x1:
prb_ = v;
break;
/* data direction port a (DDRA) */
case 0x2:
break;
/* data direction port b (DDRB) */
case 0x3:
break;
/* timer a low byte */
case 0x4:
timer_a_latch_ &= 0xff00;
timer_a_latch_ |= v;
break;
/* timer a high byte */
case 0x5:
timer_a_latch_ &= 0x00ff;
timer_a_latch_ |= v << 8;
break;
/* timer b low byte */
case 0x6:
timer_b_latch_ &= 0xff00;
timer_b_latch_ |= v;
break;
/* timer b high byte */
case 0x7:
timer_b_latch_ &= 0x00ff;
timer_b_latch_ |= v << 8;
break;
/* RTC 1/10s */
case 0x8:
break;
/* RTC seconds */
case 0x9:
break;
/* RTC minutes */
case 0xa:
break;
/* RTC hours */
case 0xb:
break;
/* shift serial */
case 0xc:
break;
/* interrupt control and status */
case 0xd:
/**
* if bit 7 is set, enable selected mask of
* interrupts, else disable them
*/
if(ISSET_BIT(v,0)) timer_a_irq_enabled_ = ISSET_BIT(v,7);
if(ISSET_BIT(v,1)) timer_b_irq_enabled_ = ISSET_BIT(v,7);
break;
/* control timer a */
case 0xe:
timer_a_enabled_ = ((v&(1<<0))!=0);
timer_a_input_mode_ = (v&(1<<5)) >> 5;
/* load latch requested */
if((v&(1<<4))!=0)
timer_a_counter_ = timer_a_latch_;
break;
/* control timer b */
case 0xf:
timer_b_enabled_ = ((v&0x1)!=0);
timer_b_input_mode_ = (v&(1<<5)) | (v&(1<<6)) >> 5;
/* load latch requested */
if((v&(1<<4))!=0)
timer_b_counter_ = timer_b_latch_;
break;
}
}
uint8_t Cia2::read_register(uint8_t r)
{
uint8_t retval = 0;
switch(r)
{
/* data port a (PRA) */
case 0x0:
retval = pra_;
break;
/* data port b (PRB) */
case 0x1:
retval = prb_;
break;
/* data direction port a (DDRA) */
case 0x2:
break;
/* data direction port b (DDRB) */
case 0x3:
break;
/* timer a low byte */
case 0x4:
retval = (uint8_t)(timer_a_counter_ & 0x00ff);
break;
/* timer a high byte */
case 0x5:
retval = (uint8_t)((timer_a_counter_ & 0xff00) >> 8);
break;
/* timer b low byte */
case 0x6:
retval = (uint8_t)(timer_b_counter_ & 0x00ff);
break;
/* timer b high byte */
case 0x7:
retval = (uint8_t)((timer_b_counter_ & 0xff00) >> 8);
break;
/* RTC 1/10s */
case 0x8:
break;
/* RTC seconds */
case 0x9:
break;
/* RTC minutes */
case 0xa:
break;
/* RTC hours */
case 0xb:
break;
/* shift serial */
case 0xc:
break;
/* interrupt control and status */
case 0xd:
if(timer_a_irq_triggered_ ||
timer_b_irq_triggered_)
{
retval |= (1 << 7); // IRQ occured
if(timer_a_irq_triggered_) retval |= (1 << 0);
if(timer_b_irq_triggered_) retval |= (1 << 1);
}
break;
/* control timer a */
case 0xe:
break;
/* control timer b */
case 0xf:
break;
}
return retval;
}
// timer reset ///////////////////////////////////////////////////////////////
void Cia2::reset_timer_a()
{
switch(timer_a_run_mode_)
{
case kModeRestart:
timer_a_counter_ = timer_a_latch_;
break;
case kModeOneTime:
timer_a_enabled_ = false;
break;
}
}
void Cia2::reset_timer_b()
{
switch(timer_b_run_mode_)
{
case kModeRestart:
timer_b_counter_ = timer_b_latch_;
break;
case kModeOneTime:
timer_b_enabled_ = false;
break;
}
}
// VIC banking ///////////////////////////////////////////////////////////////
/**
* @brief retrieves vic base address
*
* PRA bits (0..1)
*
* %00, 0: Bank 3: $C000-$FFFF, 49152-65535
* %01, 1: Bank 2: $8000-$BFFF, 32768-49151
* %10, 2: Bank 1: $4000-$7FFF, 16384-32767
* %11, 3: Bank 0: $0000-$3FFF, 0-16383 (standard)
*/
uint16_t Cia2::vic_base_address()
{
return ((~pra_&0x3) << 14);
}
// emulation ////////////////////////////////////////////////////////////////
bool Cia2::emulate()
{
/* timer a */
if(timer_a_enabled_)
{
switch(timer_a_input_mode_)
{
case kModeProcessor:
timer_a_counter_ -= cpu_->cycles() - prev_cpu_cycles_;
if (timer_a_counter_ <= 0)
{
if(timer_a_irq_enabled_)
{
timer_a_irq_triggered_ = true;
cpu_->nmi();
}
reset_timer_a();
}
break;
case kModeCNT:
break;
}
}
/* timer b */
if(timer_b_enabled_)
{
switch(timer_b_input_mode_)
{
case kModeProcessor:
timer_b_counter_ -= cpu_->cycles() - prev_cpu_cycles_;
if (timer_b_counter_ <= 0)
{
if(timer_b_irq_enabled_)
{
timer_b_irq_triggered_ = true;
cpu_->nmi();
}
reset_timer_b();
}
break;
case kModeCNT:
break;
case kModeTimerA:
break;
case kModeTimerACNT:
break;
}
}
prev_cpu_cycles_ = cpu_->cycles();
return true;
}
================================================
FILE: src/cia2.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_CIA2_H
#define EMUDORE_CIA2_H
#include "io.h"
#include "cpu.h"
/**
* @brief MOS 6526 Complex Interface Adapter #2
*
* - Memory area : $DD00-$DDFF
* - Tasks : Serial bus, RS-232, VIC banking, NMI control
*/
class Cia2
{
private:
Cpu *cpu_;
int16_t timer_a_latch_;
int16_t timer_b_latch_;
int16_t timer_a_counter_;
int16_t timer_b_counter_;
bool timer_a_enabled_;
bool timer_b_enabled_;
bool timer_a_irq_enabled_;
bool timer_b_irq_enabled_;
bool timer_a_irq_triggered_;
bool timer_b_irq_triggered_;
uint8_t timer_a_run_mode_;
uint8_t timer_b_run_mode_;
uint8_t timer_a_input_mode_;
uint8_t timer_b_input_mode_;
unsigned int prev_cpu_cycles_;
uint8_t pra_, prb_;
public:
Cia2();
void cpu(Cpu *v){ cpu_ = v;};
void write_register(uint8_t r, uint8_t v);
uint8_t read_register(uint8_t r);
void reset_timer_a();
void reset_timer_b();
uint16_t vic_base_address();
bool emulate();
/* constants */
enum kInputMode
{
kModeProcessor,
kModeCNT,
kModeTimerA,
kModeTimerACNT
};
enum kRunMode
{
kModeRestart,
kModeOneTime
};
};
#endif
================================================
FILE: src/cpu.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cpu.h"
#include "util.h"
#include
/**
* @brief Cold reset
*
* https://www.c64-wiki.com/index.php/Reset_(Process)
*/
void Cpu::reset()
{
a_ = x_ = y_ = sp_ = 0;
cf_ = zf_ = idf_ = dmf_ = bcf_ = of_ = nf_ = false;
pc(mem_->read_word(Memory::kAddrResetVector));
cycles_ = 6;
}
/**
* @brief emulate instruction
* @return returns false if something goes wrong (e.g. illegal instruction)
*
* Current limitations:
*
* - Illegal instructions are not implemented
* - Excess cycles due to page boundary crossing are not calculated
* - Some known architectural bugs are not emulated
*/
bool Cpu::emulate()
{
/* fetch instruction */
uint8_t insn = fetch_op();
bool retval = true;
/* emulate instruction */
switch(insn)
{
/* BRK */
case 0x0: brk(); break;
/* ORA (nn,X) */
case 0x1: ora(load_byte(addr_indx()),6); break;
/* ORA nn */
case 0x5: ora(load_byte(addr_zero()),3); break;
/* ASL nn */
case 0x6: asl_mem(addr_zero(),5); break;
/* PHP */
case 0x8: php(); break;
/* ORA #nn */
case 0x9: ora(fetch_op(),2); break;
/* ASL A */
case 0xA: asl_a(); break;
/* ORA nnnn */
case 0xD: ora(load_byte(addr_abs()),4); break;
/* ASL nnnn */
case 0xE: asl_mem(addr_abs(),6); break;
/* BPL nn */
case 0x10: bpl(); break;
/* ORA (nn,Y) */
case 0x11: ora(load_byte(addr_indy()),5); break;
/* ORA nn,X */
case 0x15: ora(load_byte(addr_zerox()),4); break;
/* ASL nn,X */
case 0x16: asl_mem(addr_zerox(),6); break;
/* CLC */
case 0x18: clc(); break;
/* ORA nnnn,Y */
case 0x19: ora(load_byte(addr_absy()),4); break;
/* ORA nnnn,X */
case 0x1D: ora(load_byte(addr_absx()),4); break;
/* ASL nnnn,X */
case 0x1E: asl_mem(addr_absx(),7); break;
/* JSR */
case 0x20: jsr(); break;
/* AND (nn,X) */
case 0x21: _and(load_byte(addr_indx()),6); break;
/* BIT nn */
case 0x24: bit(addr_zero(),3); break;
/* AND nn */
case 0x25: _and(load_byte(addr_zero()),3); break;
/* ROL nn */
case 0x26: rol_mem(addr_zero(),5); break;
/* PLP */
case 0x28: plp(); break;
/* AND #nn */
case 0x29: _and(fetch_op(),2); break;
/* ROL A */
case 0x2A: rol_a(); break;
/* BIT nnnn */
case 0x2C: bit(addr_abs(),4); break;
/* AND nnnn */
case 0x2D: _and(load_byte(addr_abs()),4); break;
/* ROL nnnn */
case 0x2E: rol_mem(addr_abs(),6); break;
/* BMI nn */
case 0x30: bmi(); break;
/* AND (nn,Y) */
case 0x31: _and(load_byte(addr_indy()),5); break;
/* AND nn,X */
case 0x35: _and(load_byte(addr_zerox()),4); break;
/* ROL nn,X */
case 0x36: rol_mem(addr_zerox(),6); break;
/* SEC */
case 0x38: sec(); break;
/* AND nnnn,Y */
case 0x39: _and(load_byte(addr_absy()),4); break;
/* AND nnnn,X */
case 0x3D: _and(load_byte(addr_absx()),4); break;
/* ROL nnnn,X */
case 0x3E: rol_mem(addr_absx(),7); break;
/* RTI */
case 0x40: rti(); break;
/* EOR (nn,X) */
case 0x41: eor(load_byte(addr_indx()),6); break;
/* EOR nn */
case 0x45: eor(load_byte(addr_zero()),3); break;
/* LSR nn */
case 0x46: lsr_mem(addr_zero(),5); break;
/* PHA */
case 0x48: pha(); break;
/* EOR #nn */
case 0x49: eor(fetch_op(),2); break;
/* BVC */
case 0x50: bvc(); break;
/* JMP nnnn */
case 0x4C: jmp(); break;
/* EOR nnnn */
case 0x4D: eor(load_byte(addr_abs()),4); break;
/* LSR A */
case 0x4A: lsr_a(); break;
/* LSR nnnn */
case 0x4E: lsr_mem(addr_abs(),6); break;
/* EOR (nn,Y) */
case 0x51: eor(load_byte(addr_indy()),5); break;
/* EOR nn,X */
case 0x55: eor(load_byte(addr_zerox()),4); break;
/* LSR nn,X */
case 0x56: lsr_mem(addr_zerox(),6); break;
/* CLI */
case 0x58: cli(); break;
/* EOR nnnn,Y */
case 0x59: eor(load_byte(addr_absy()),4); break;
/* EOR nnnn,X */
case 0x5D: eor(load_byte(addr_absx()),4); break;
/* LSR nnnn,X */
case 0x5E: lsr_mem(addr_absx(),7); break;
/* RTS */
case 0x60: rts(); break;
/* ADC (nn,X) */
case 0x61: adc(load_byte(addr_indx()),6); break;
/* ADC nn */
case 0x65: adc(load_byte(addr_zero()),3); break;
/* ROR nn */
case 0x66: ror_mem(addr_zero(),5); break;
/* PLA */
case 0x68: pla(); break;
/* ADC #nn */
case 0x69: adc(fetch_op(),2); break;
/* ROR A */
case 0x6A: ror_a(); break;
/* JMP (nnnn) */
case 0x6C: jmp_ind(); break;
/* ADC nnnn */
case 0x6D: adc(load_byte(addr_abs()),4); break;
/* ROR nnnn */
case 0x6E: ror_mem(addr_abs(),6); break;
/* BVS */
case 0x70: bvs(); break;
/* ADC (nn,Y) */
case 0x71: adc(load_byte(addr_indy()),5); break;
/* ADC nn,X */
case 0x75: adc(load_byte(addr_zerox()),4); break;
/* ROR nn,X */
case 0x76: ror_mem(addr_zerox(),6); break;
/* SEI */
case 0x78: sei(); break;
/* ADC nnnn,Y */
case 0x79: adc(load_byte(addr_absy()),4); break;
/* ADC nnnn,X */
case 0x7D: adc(load_byte(addr_absx()),4); break;
/* ROR nnnn,X */
case 0x7E: ror_mem(addr_absx(),7); break;
/* STA (nn,X) */
case 0x81: sta(addr_indx(),6); break;
/* STY nn */
case 0x84: sty(addr_zero(),3); break;
/* STA nn */
case 0x85: sta(addr_zero(),3); break;
/* STX nn */
case 0x86: stx(addr_zero(),3); break;
/* DEY */
case 0x88: dey(); break;
/* TXA */
case 0x8A: txa(); break;
/* STY nnnn */
case 0x8C: sty(addr_abs(),4); break;
/* STA nnnn */
case 0x8D: sta(addr_abs(),4); break;
/* STX nnnn */
case 0x8E: stx(addr_abs(),4); break;
/* BCC nn */
case 0x90: bcc(); break;
/* STA (nn,Y) */
case 0x91: sta(addr_indy(),6); break;
/* STY nn,X */
case 0x94: sty(addr_zerox(),4); break;
/* STA nn,X */
case 0x95: sta(addr_zerox(),4); break;
/* STX nn,Y */
case 0x96: stx(addr_zeroy(),4); break;
/* TYA */
case 0x98: tya(); break;
/* STA nnnn,Y */
case 0x99: sta(addr_absy(),5); break;
/* TXS */
case 0x9A: txs(); break;
/* STA nnnn,X */
case 0x9D: sta(addr_absx(),5); break;
/* LDY #nn */
case 0xA0: ldy(fetch_op(),2); break;
/* LDA (nn,X) */
case 0xA1: lda(load_byte(addr_indx()),6); break;
/* LDX #nn */
case 0xA2: ldx(fetch_op(),2); break;
/* LDY nn */
case 0xA4: ldy(load_byte(addr_zero()),3); break;
/* LDA nn */
case 0xA5: lda(load_byte(addr_zero()),3); break;
/* LDX nn */
case 0xA6: ldx(load_byte(addr_zero()),3); break;
/* TAY */
case 0xA8: tay(); break;
/* LDA #nn */
case 0xA9: lda(fetch_op(),2); break;
/* TAX */
case 0xAA: tax(); break;
/* LDY nnnn */
case 0xAC: ldy(load_byte(addr_abs()),4); break;
/* LDA nnnn */
case 0xAD: lda(load_byte(addr_abs()),4); break;
/* LDX nnnn */
case 0xAE: ldx(load_byte(addr_abs()),4); break;
/* BCS nn */
case 0xB0: bcs(); break;
/* LDA (nn,Y) */
case 0xB1: lda(load_byte(addr_indy()),5); break;
/* LDY nn,X */
case 0xB4: ldy(load_byte(addr_zerox()),3); break;
/* LDA nn,X */
case 0xB5: lda(load_byte(addr_zerox()),3); break;
/* LDX nn,Y */
case 0xB6: ldx(load_byte(addr_zeroy()),3); break;
/* CLV */
case 0xB8: clv(); break;
/* LDA nnnn,Y */
case 0xB9: lda(load_byte(addr_absy()),4); break;
/* TSX */
case 0xBA: tsx(); break;
/* LDY nnnn,X */
case 0xBC: ldy(load_byte(addr_absx()),4); break;
/* LDA nnnn,X */
case 0xBD: lda(load_byte(addr_absx()),4); break;
/* LDX nnnn,Y */
case 0xBE: ldx(load_byte(addr_absy()),4); break;
/* CPY #nn */
case 0xC0: cpy(fetch_op(),2); break;
/* CMP (nn,X) */
case 0xC1: cmp(load_byte(addr_indx()),6); break;
/* CPY nn */
case 0xC4: cpy(load_byte(addr_zero()),3); break;
/* CMP nn */
case 0xC5: cmp(load_byte(addr_zero()),3); break;
/* DEC nn */
case 0xC6: dec(addr_zero(),5); break;
/* INY */
case 0xC8: iny(); break;
/* CMP #nn */
case 0xC9: cmp(fetch_op(),2); break;
/* DEX */
case 0xCA: dex(); break;
/* CPY nnnn */
case 0xCC: cpy(load_byte(addr_abs()),4); break;
/* CMP nnnn */
case 0xCD: cmp(load_byte(addr_abs()),4); break;
/* DEC nnnn */
case 0xCE: dec(addr_abs(),6); break;
/* BNE nn */
case 0xD0: bne(); break;
/* CMP (nn,Y) */
case 0xD1: cmp(load_byte(addr_indy()),5); break;
/* CMP nn,X */
case 0xD5: cmp(load_byte(addr_zerox()),4); break;
/* DEC nn,X */
case 0xD6: dec(addr_zerox(),6); break;
/* CLD */
case 0xD8: cld(); break;
/* CMP nnnn,Y */
case 0xD9: cmp(load_byte(addr_absy()),4); break;
/* CMP nnnn,X */
case 0xDD: cmp(load_byte(addr_absx()),4); break;
/* DEC nnnn,X */
case 0xDE: dec(addr_absx(),7); break;
/* CPX #nn */
case 0xE0: cpx(fetch_op(),2); break;
/* SBC (nn,X) */
case 0xE1: sbc(load_byte(addr_indx()),6); break;
/* CPX nn */
case 0xE4: cpx(load_byte(addr_zero()),3); break;
/* SBC nn */
case 0xE5: sbc(load_byte(addr_zero()),3); break;
/* INC nn */
case 0xE6: inc(addr_zero(),5); break;
/* INX */
case 0xE8: inx(); break;
/* SBC #nn */
case 0xE9: sbc(fetch_op(),2); break;
/* NOP */
case 0xEA: nop(); break;
/* CPX nnnn */
case 0xEC: cpx(load_byte(addr_abs()),4); break;
/* SBC nnnn */
case 0xED: sbc(load_byte(addr_abs()),4); break;
/* INC nnnn */
case 0xEE: inc(addr_abs(),6); break;
/* BEQ nn */
case 0xF0: beq(); break;
/* SBC (nn,Y) */
case 0xF1: sbc(load_byte(addr_indy()),5); break;
/* SBC nn,X */
case 0xF5: sbc(load_byte(addr_zerox()),4); break;
/* INC nn,X */
case 0xF6: inc(addr_zerox(),6); break;
/* SED */
case 0xF8: sed(); break;
/* SBC nnnn,Y */
case 0xF9: sbc(load_byte(addr_absy()),4); break;
/* SBC nnnn,X */
case 0xFD: sbc(load_byte(addr_absx()),4); break;
/* INC nnnn,X */
case 0xFE: inc(addr_absx(),7); break;
/* Unknown or illegal instruction */
default:
D("Unknown instruction: %X at %04x\n", insn,pc());
retval = false;
}
return retval;
}
// helpers ///////////////////////////////////////////////////////////////////
uint8_t Cpu::load_byte(uint16_t addr)
{
return mem_->read_byte(addr);
}
void Cpu::push(uint8_t v)
{
uint16_t addr = Memory::kBaseAddrStack+sp_;
mem_->write_byte(addr,v);
sp_--;
}
uint8_t Cpu::pop()
{
uint16_t addr = ++sp_+Memory::kBaseAddrStack;
return load_byte(addr);
}
uint8_t Cpu::fetch_op()
{
return load_byte(pc_++);
}
uint16_t Cpu::fetch_opw()
{
uint16_t retval = mem_->read_word(pc_);
pc_+=2;
return retval;
}
uint16_t Cpu::addr_zero()
{
uint16_t addr = fetch_op();
return addr;
}
uint16_t Cpu::addr_zerox()
{
/* wraps around the zeropage */
uint16_t addr = (fetch_op() + x()) & 0xff ;
return addr;
}
uint16_t Cpu::addr_zeroy()
{
/* wraps around the zeropage */
uint16_t addr = (fetch_op() + y()) & 0xff;
return addr;
}
uint16_t Cpu::addr_abs()
{
uint16_t addr = fetch_opw();
return addr;
}
uint16_t Cpu::addr_absy()
{
uint16_t addr = fetch_opw() + y();
return addr;
}
uint16_t Cpu::addr_absx()
{
uint16_t addr = fetch_opw() + x();
return addr;
}
uint16_t Cpu::addr_indx()
{
/* wraps around the zeropage */
uint16_t addr = mem_->read_word((addr_zero() + x()) & 0xff);
return addr;
}
uint16_t Cpu::addr_indy()
{
uint16_t addr = mem_->read_word(addr_zero()) + y();
return addr;
}
// Instructions: data handling and memory operations ////////////////////////
/**
* @brief STore Accumulator
*/
void Cpu::sta(uint16_t addr, uint8_t cycles)
{
mem_->write_byte(addr,a());
tick(cycles);
}
/**
* @brief STore X
*/
void Cpu::stx(uint16_t addr, uint8_t cycles)
{
mem_->write_byte(addr,x());
tick(cycles);
}
/**
* @brief STore Y
*/
void Cpu::sty(uint16_t addr, uint8_t cycles)
{
mem_->write_byte(addr,y());
tick(cycles);
}
/**
* @brief Transfer X to Stack pointer
*/
void Cpu::txs()
{
sp(x());
tick(2);
}
/**
* @brief Transfer Stack pointer to X
*/
void Cpu::tsx()
{
x(sp());
SET_ZF(x());
SET_NF(x());
tick(2);
}
/**
* @brief LoaD Accumulator
*/
void Cpu::lda(uint8_t v, uint8_t cycles)
{
a(v);
SET_ZF(a());
SET_NF(a());
tick(cycles);
}
/**
* @brief LoaD X
*/
void Cpu::ldx(uint8_t v, uint8_t cycles)
{
x(v);
SET_ZF(x());
SET_NF(x());
tick(cycles);
}
/**
* @brief LoaD Y
*/
void Cpu::ldy(uint8_t v, uint8_t cycles)
{
y(v);
SET_ZF(y());
SET_NF(y());
tick(cycles);
}
/**
* @brief Transfer X to Accumulator
*/
void Cpu::txa()
{
a(x());
SET_ZF(a());
SET_NF(a());
tick(2);
}
/**
* @brief Transfer Accumulator to X
*/
void Cpu::tax()
{
x(a());
SET_ZF(x());
SET_NF(x());
tick(2);
}
/**
* @brief Transfer Accumulator to Y
*/
void Cpu::tay()
{
y(a());
SET_ZF(y());
SET_NF(y());
tick(2);
}
/**
* @brief Transfer Y to Accumulator
*/
void Cpu::tya()
{
a(y());
SET_ZF(a());
SET_NF(a());
tick(2);
}
/**
* @brief PusH Accumulator
*/
void Cpu::pha()
{
push(a());
tick(3);
}
/**
* @brief PuLl Accumulator
*/
void Cpu::pla()
{
a(pop());
SET_ZF(a());
SET_NF(a());
tick(4);
}
// Instructions: logic operations ///////////////////////////////////////////
/**
* @brief Logical OR on Accumulator
*/
void Cpu::ora(uint8_t v, uint8_t cycles)
{
a(a()|v);
SET_ZF(a());
SET_NF(a());
tick(cycles);
}
/**
* @brief Logical AND
*/
void Cpu::_and(uint8_t v, uint8_t cycles)
{
a(a()&v);
SET_ZF(a());
SET_NF(a());
tick(cycles);
}
/**
* @brief BIT test
*/
void Cpu::bit(uint16_t addr, uint8_t cycles)
{
uint8_t t = load_byte(addr);
of((t&0x40)!=0);
SET_NF(t);
SET_ZF(t&a());
tick(cycles);
}
/**
* @brief ROtate Left
*/
uint8_t Cpu::rol(uint8_t v)
{
uint16_t t = (v << 1) | (uint8_t)cf();
cf((t&0x100)!=0);
SET_ZF(t);
SET_NF(t);
return (uint8_t)t;
}
/**
* @brief ROL A register
*/
void Cpu::rol_a()
{
a(rol(a()));
tick(2);
}
/**
* @brief ROL mem
*/
void Cpu::rol_mem(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
/* see ASL doc */
mem_->write_byte(addr,v);
mem_->write_byte(addr,rol(v));
tick(cycles);
}
/**
* @brief ROtate Right
*/
uint8_t Cpu::ror(uint8_t v)
{
uint16_t t = (v >> 1) | (uint8_t)(cf() << 7);
cf((v&0x1)!=0);
SET_ZF(t);
SET_NF(t);
return (uint8_t)t;
}
/**
* @brief ROR A register
*/
void Cpu::ror_a()
{
a(ror(a()));
tick(2);
}
/**
* @brief ROR mem
*/
void Cpu::ror_mem(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
/* see ASL doc */
mem_->write_byte(addr,v);
mem_->write_byte(addr,ror(v));
tick(cycles);
}
/**
* @brief Logic Shift Right
*/
uint8_t Cpu::lsr(uint8_t v)
{
uint8_t t = v >> 1;
cf((v&0x1)!=0);
SET_ZF(t);
SET_NF(t);
return t;
}
/**
* @brief LSR A
*/
void Cpu::lsr_a()
{
a(lsr(a()));
tick(2);
}
/**
* @brief LSR mem
*/
void Cpu::lsr_mem(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
/* see ASL doc */
mem_->write_byte(addr,v);
mem_->write_byte(addr,lsr(v));
tick(cycles);
}
/**
* @brief Arithmetic Shift Left
*/
uint8_t Cpu::asl(uint8_t v)
{
uint8_t t = (v << 1) & 0xff;
cf((v&0x80)!=0);
SET_ZF(t);
SET_NF(t);
return t;
}
/**
* @brief ASL A
*/
void Cpu::asl_a()
{
a(asl(a()));
tick(2);
}
/**
* @brief ASL mem
*
* ASL and the other read-modify-write instructions contain a bug (wikipedia):
*
* --
* The 6502's read-modify-write instructions perform one read and two write
* cycles. First the unmodified data that was read is written back, and then
* the modified data is written. This characteristic may cause issues by
* twice accessing hardware that acts on a write. This anomaly continued
* through the entire NMOS line, but was fixed in the CMOS derivatives, in
* which the processor will do two reads and one write cycle.
* --
*
* I have come across code that uses this side-effect as a feature, for
* instance, the following instruction will acknowledge VIC interrupts
* on the first write cycle:
*
* ASL $d019
*
* So.. we need to mimic the behaviour.
*/
void Cpu::asl_mem(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
mem_->write_byte(addr,v);
mem_->write_byte(addr,asl(v));
tick(cycles);
}
/**
* @brief Exclusive OR
*/
void Cpu::eor(uint8_t v, uint8_t cycles)
{
a(a()^v);
SET_ZF(a());
SET_NF(a());
tick(cycles);
}
// Instructions: arithmetic operations //////////////////////////////////////
/**
* @brief INCrement
*/
void Cpu::inc(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
/* see ASL doc */
mem_->write_byte(addr,v);
v++;
mem_->write_byte(addr,v);
SET_ZF(v);
SET_NF(v);
}
/**
* @brief DECrement
*/
void Cpu::dec(uint16_t addr, uint8_t cycles)
{
uint8_t v = load_byte(addr);
/* see ASL doc */
mem_->write_byte(addr,v);
v--;
mem_->write_byte(addr,v);
SET_ZF(v);
SET_NF(v);
}
/**
* @brief INcrement X
*/
void Cpu::inx()
{
x_+=1;
SET_ZF(x());
SET_NF(x());
tick(2);
}
/**
* @brief INcrement Y
*/
void Cpu::iny()
{
y_+=1;
SET_ZF(y());
SET_NF(y());
tick(2);
}
/**
* @brief DEcrement X
*/
void Cpu::dex()
{
x_-=1;
SET_ZF(x());
SET_NF(x());
tick(2);
}
/**
* @brief DEcrement Y
*/
void Cpu::dey()
{
y_-=1;
SET_ZF(y());
SET_NF(y());
tick(2);
}
/**
* @brief ADd with Carry
*/
void Cpu::adc(uint8_t v, uint8_t cycles)
{
uint16_t t;
if(dmf())
{
t = (a()&0xf) + (v&0xf) + (cf() ? 1 : 0);
if (t > 0x09)
t += 0x6;
t += (a()&0xf0) + (v&0xf0);
if((t & 0x1f0) > 0x90)
t += 0x60;
}
else
{
t = a() + v + (cf() ? 1 : 0);
}
cf(t>0xff);
t=t&0xff;
of(!((a()^v)&0x80) && ((a()^t) & 0x80));
SET_ZF(t);
SET_NF(t);
a((uint8_t)t);
}
/**
* @brief SuBstract with Carry
*/
void Cpu::sbc(uint8_t v, uint8_t cycles)
{
uint16_t t;
if(dmf())
{
t = (a()&0xf) - (v&0xf) - (cf() ? 0 : 1);
if((t & 0x10) != 0)
t = ((t-0x6)&0xf) | ((a()&0xf0) - (v&0xf0) - 0x10);
else
t = (t&0xf) | ((a()&0xf0) - (v&0xf0));
if((t&0x100)!=0)
t -= 0x60;
}
else
{
t = a() - v - (cf() ? 0 : 1);
}
cf(t<0x100);
t=t&0xff;
of(((a()^t)&0x80) && ((a()^v) & 0x80));
SET_ZF(t);
SET_NF(t);
a((uint8_t)t);
}
// Instructions: flag access /////////////////////////////////////////////////
/**
* @brief SEt Interrupt flag
*/
void Cpu::sei()
{
idf(true);
tick(2);
}
/**
* @brief CLear Interrupt flag
*/
void Cpu::cli()
{
idf(false);
tick(2);
}
/**
* @brief SEt Carry flag
*/
void Cpu::sec()
{
cf(true);
tick(2);
}
/**
* @brief CLear Carry flag
*/
void Cpu::clc()
{
cf(false);
tick(2);
}
/**
* @brief SEt Decimal flag
*/
void Cpu::sed()
{
dmf(true);
tick(2);
}
/**
* @brief CLear Decimal flag
*/
void Cpu::cld()
{
dmf(false);
tick(2);
}
/**
* @brief CLear oVerflow flag
*/
void Cpu::clv()
{
of(false);
tick(2);
}
uint8_t Cpu::flags()
{
uint8_t v=0;
v |= cf() << 0;
v |= zf() << 1;
v |= idf() << 2;
v |= dmf() << 3;
/* brk & php instructions push the bcf flag active */
v |= 1 << 4;
/* unused, always set */
v |= 1 << 5;
v |= of() << 6;
v |= nf() << 7;
return v;
}
void Cpu::flags(uint8_t v)
{
cf(ISSET_BIT(v,0));
zf(ISSET_BIT(v,1));
idf(ISSET_BIT(v,2));
dmf(ISSET_BIT(v,3));
of(ISSET_BIT(v,6));
nf(ISSET_BIT(v,7));
}
/**
* @brief PusH Processor flags
*/
void Cpu::php()
{
push(flags());
tick(3);
}
/**
* @brief PuLl Processor flags
*/
void Cpu::plp()
{
flags(pop());
tick(4);
}
/**
* @brief Jump to SubRoutine
*
* Note that JSR does not push the address of the next instruction
* to the stack but the address to the last byte of its own
* instruction.
*/
void Cpu::jsr()
{
uint16_t addr = addr_abs();
push(((pc()-1) >> 8) & 0xff);
push(((pc()-1) & 0xff));
pc(addr);
tick(6);
}
/**
* @brief JuMP
*/
void Cpu::jmp()
{
uint16_t addr = addr_abs();
pc(addr);
tick(3);
}
/**
* @brief JuMP (indirect)
*/
void Cpu::jmp_ind()
{
uint16_t addr = mem_->read_word(addr_abs());
pc(addr);
tick(3);
}
/**
* @brief ReTurn from SubRoutine
*/
void Cpu::rts()
{
uint16_t addr = (pop() + (pop() << 8)) + 1;
pc(addr);
tick(6);
}
/**
* @brief Branch if Not Equal
*/
void Cpu::bne()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(!zf()) pc(addr);
tick(2);
}
/**
* @brief CoMPare
*/
void Cpu::cmp(uint8_t v, uint8_t cycles)
{
uint16_t t;
t = a() - v;
cf(t<0x100);
t = t&0xff;
SET_ZF(t);
SET_NF(t);
tick(cycles);
}
/**
* @brief CoMPare X
*/
void Cpu::cpx(uint8_t v, uint8_t cycles)
{
uint16_t t;
t = x() - v;
cf(t<0x100);
t = t&0xff;
SET_ZF(t);
SET_NF(t);
tick(cycles);
}
/**
* @brief CoMPare Y
*/
void Cpu::cpy(uint8_t v, uint8_t cycles)
{
uint16_t t;
t = y() - v;
cf(t<0x100);
t = t&0xff;
SET_ZF(t);
SET_NF(t);
tick(cycles);
}
/**
* @brief Branch if Equal
*/
void Cpu::beq()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(zf()) pc(addr);
tick(2);
}
/**
* @brief Branch if Carry is Set
*/
void Cpu::bcs()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(cf()) pc(addr);
tick(2);
}
/**
* @brief Branch if Carry is Clear
*/
void Cpu::bcc()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(!cf()) pc(addr);
tick(2);
}
/**
* @brief, Branch if PLus
*/
void Cpu::bpl()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(!nf()) pc(addr);
tick(2);
}
/**
* @brief Branch if MInus
*/
void Cpu::bmi()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(nf()) pc(addr);
tick(2);
}
/**
* @brief Branch if oVerflow Clear
*/
void Cpu::bvc()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(!of()) pc(addr);
tick(2);
}
/**
* @brief Branch if oVerflow Set
*/
void Cpu::bvs()
{
uint16_t addr = (int8_t) fetch_op() + pc();
if(of()) pc(addr);
tick(2);
}
// misc //////////////////////////////////////////////////////////////////////
/**
* @brief No OPeration
*/
void Cpu::nop()
{
tick(2);
}
/**
* @brief BReaKpoint
*/
void Cpu::brk()
{
push(((pc()+1) >> 8) & 0xff);
push(((pc()+1) & 0xff));
push(flags());
pc(mem_->read_word(Memory::kAddrIRQVector));
idf(true);
bcf(true);
tick(7);
}
/**
* @brief ReTurn from Interrupt
*/
void Cpu::rti()
{
flags(pop());
pc(pop() + (pop() << 8));
tick(7);
}
// interrupts ///////////////////////////////////////////////////////////////
/**
* @brief Interrupt ReQuest
*/
void Cpu::irq()
{
if(!idf())
{
push(((pc()) >> 8) & 0xff);
push(((pc()) & 0xff));
/* push flags with bcf cleared */
push((flags()&0xef));
pc(mem_->read_word(Memory::kAddrIRQVector));
idf(true);
tick(7);
}
}
/**
* @brief Non Maskable Interrupt
*/
void Cpu::nmi()
{
push(((pc()) >> 8) & 0xff);
push(((pc()) & 0xff));
/* push flags with bcf cleared */
push((flags() & 0xef));
pc(mem_->read_word(Memory::kAddrNMIVector));
tick(7);
}
// debugging /////////////////////////////////////////////////////////////////
void Cpu::dump_regs()
{
std::stringstream sflags;
if(cf()) sflags << "CF ";
if(zf()) sflags << "ZF ";
if(idf()) sflags << "IDF ";
if(dmf()) sflags << "DMF ";
if(bcf()) sflags << "BCF ";
if(of()) sflags << "OF ";
if(nf()) sflags << "NF ";
D("pc=%04x, a=%02x x=%02x y=%02x sp=%02x flags= %s\n",
pc(),a(),x(),y(),sp(),sflags.str().c_str());
}
void Cpu::dump_regs_json()
{
D("{");
D("\"pc\":%d,",pc());
D("\"a\":%d,",a());
D("\"x\":%d,",x());
D("\"y\":%d,",y());
D("\"sp\":%d",sp());
D("}\n");
}
================================================
FILE: src/cpu.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_CPU_H
#define EMUDORE_CPU_H
#include
#include "memory.h"
/**
* @brief MOS 6510 microprocessor
*/
class Cpu
{
private:
/* registers */
uint16_t pc_;
uint8_t sp_, a_, x_, y_;
/* flags (p/status reg) */
bool cf_,zf_,idf_,dmf_,bcf_,of_,nf_;
/* memory and clock */
Memory *mem_;
unsigned int cycles_;
/* helpers */
inline uint8_t load_byte(uint16_t addr);
inline void push(uint8_t);
inline uint8_t pop();
inline uint8_t fetch_op();
inline uint16_t fetch_opw();
inline uint16_t addr_zero();
inline uint16_t addr_zerox();
inline uint16_t addr_zeroy();
inline uint16_t addr_abs();
inline uint16_t addr_absy();
inline uint16_t addr_absx();
inline uint16_t addr_indx();
inline uint16_t addr_indy();
inline uint8_t rol(uint8_t v);
inline uint8_t ror(uint8_t v);
inline uint8_t lsr(uint8_t v);
inline uint8_t asl(uint8_t v);
inline void tick(uint8_t v){cycles_+=v;};
inline uint8_t flags();
inline void flags(uint8_t v);
/* instructions : data handling and memory operations */
inline void sta(uint16_t addr, uint8_t cycles);
inline void stx(uint16_t addr, uint8_t cycles);
inline void sty(uint16_t addr, uint8_t cycles);
inline void lda(uint8_t v, uint8_t cycles);
inline void ldx(uint8_t v, uint8_t cycles);
inline void ldy(uint8_t v, uint8_t cycles);
inline void txs();
inline void tsx();
inline void tax();
inline void txa();
inline void tay();
inline void tya();
inline void pha();
inline void pla();
/* instructions: logic operations */
inline void ora(uint8_t v, uint8_t cycles);
inline void _and(uint8_t v, uint8_t cycles);
inline void bit(uint16_t addr, uint8_t cycles);
inline void rol_a();
inline void rol_mem(uint16_t addr, uint8_t cycles);
inline void ror_a();
inline void ror_mem(uint16_t addr, uint8_t cycles);
inline void asl_a();
inline void asl_mem(uint16_t addr, uint8_t cycles);
inline void lsr_a();
inline void lsr_mem(uint16_t addr, uint8_t cycles);
inline void eor(uint8_t v, uint8_t cycles);
/* instructions: arithmetic operations */
inline void inc(uint16_t addr, uint8_t cycles);
inline void dec(uint16_t addr, uint8_t cycles);
inline void inx();
inline void iny();
inline void dex();
inline void dey();
inline void adc(uint8_t v, uint8_t cycles);
inline void sbc(uint8_t v, uint8_t cycles);
/* instructions: flag access */
inline void sei();
inline void cli();
inline void sec();
inline void clc();
inline void sed();
inline void cld();
inline void clv();
inline void php();
inline void plp();
/* instructions: control flow */
inline void cmp(uint8_t v, uint8_t cycles);
inline void cpx(uint8_t v, uint8_t cycles);
inline void cpy(uint8_t v, uint8_t cycles);
inline void rts();
inline void jsr();
inline void bne();
inline void beq();
inline void bcs();
inline void bcc();
inline void bpl();
inline void bmi();
inline void bvc();
inline void bvs();
inline void jmp();
inline void jmp_ind();
/* instructions: misc */
inline void nop();
inline void brk();
inline void rti();
public:
/* cpu state */
void reset();
bool emulate();
/* memory */
void memory(Memory *v){mem_ = v;};
Memory* memory(){return mem_;};
/* register access */
inline uint16_t pc() {return pc_;};
inline void pc(uint16_t v) {pc_=v;};
inline uint8_t sp() {return sp_;};
inline void sp(uint8_t v) {sp_=v;};
inline uint8_t a() {return a_;};
inline void a(uint8_t v) {a_=v;};
inline uint8_t x() {return x_;};
inline void x(uint8_t v) {x_=v;};
inline uint8_t y() {return y_;};
inline void y(uint8_t v) {y_=v;};
/* flags */
inline bool cf() {return cf_;};
inline void cf(bool v) { cf_=v;};
inline bool zf() {return zf_;};
inline void zf(bool v) {zf_=v;};
inline bool idf() {return idf_;};
inline void idf(bool v) { idf_=v;};
inline bool dmf() {return dmf_;};
inline void dmf(bool v) { dmf_=v;};
inline bool bcf() {return bcf_;};
inline void bcf(bool v) { bcf_=v;};
inline bool of() {return of_;};
inline void of(bool v) { of_=v;};
inline bool nf() {return nf_;};
inline void nf(bool v) {nf_=v;};
/* clock */
inline unsigned int cycles(){return cycles_;};
inline void cycles(unsigned int v){cycles_=v;};
/* interrupts */
void nmi();
void irq();
/* debug */
void dump_regs();
void dump_regs_json();
};
/* macro helpers */
#define SET_ZF(val) (zf(!(uint8_t)(val)))
#define SET_NF(val) (nf(((uint8_t)(val)&0x80)!=0))
#endif
================================================
FILE: src/debugger.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "util.h"
#include "debugger.h"
Debugger::Debugger()
{
int e = 1;
offset_ = 0;
struct sockaddr_in serv_addr;
/* SOCK_NONBLOCK requires a Linux kernel >= 2.6.27 */
#ifdef SOCK_NONBLOCK
ss_ = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
#else
ss_ = socket(AF_INET, SOCK_STREAM,0);
fcntl(ss_, F_SETFL, fcntl(ss_, F_GETFL, 0) | O_NONBLOCK);
#endif
if(ss_ < 0)
{
D("Debuggger: Error opening socket\n");
exit(1);
}
setsockopt(ss_, SOL_SOCKET, SO_REUSEADDR, &e, sizeof(int));
bzero((char *) &serv_addr, sizeof(serv_addr));
/* init socket struct */
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(kDbgPort);
/* bind */
if (bind(ss_, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
D("Debugger: ERROR binding\n");
exit(1);
}
/* listen */
listen(ss_ , 3);
}
Debugger::~Debugger()
{
close(ss_);
}
std::vector Debugger::split_cmd(const std::string &s)
{
const char c = ' ';
std::string buff{""};
std::vector v;
for(auto n:s)
{
if(n != c) buff+=n; else
if(n == c && buff != "") { v.push_back(buff); buff = ""; }
}
if(buff != "") v.push_back(buff);
return v;
}
uint16_t Debugger::emu_seek(uint16_t offset, int whence)
{
switch(whence)
{
case SEEK_SET:
offset_ = offset;
break;
case SEEK_CUR:
offset_ = offset + offset_;
break;
case SEEK_END:
offset_ = 0xffff + offset;
break;
}
return offset_;
}
uint8_t * Debugger::emu_read_mem(size_t sz)
{
uint8_t *mem = (uint8_t *) malloc(sz);
for(size_t i = 0 ; i < sz ; i++)
mem[i] = mem_->read_byte(offset_ + i);
return mem;
}
void Debugger::emu_write_mem(uint8_t *mem, size_t sz)
{
for(size_t i = 0 ; i < sz ; i++)
{
mem_->write_byte(offset_++,mem[i]);
}
}
std::string Debugger::regs_cmd()
{
std::stringstream v;
v << std::hex << std::setfill('0');
v << "a = 0x" << std::setw(2) << (unsigned int) cpu_->a() << "\n";
v << "x = 0x" << std::setw(2) << (unsigned int) cpu_->x() << "\n";
v << "y = 0x" << std::setw(2) << (unsigned int) cpu_->y() << "\n";
v << "sp = 0x" << std::setw(2) << (unsigned int) cpu_->sp() << "\n";
v << "pc = 0x" << std::setw(4) << (unsigned int) cpu_->pc() << "\n";
v << "flags = ";
if(cpu_->cf()) v << "cf ";
if(cpu_->zf()) v << "zf ";
if(cpu_->idf()) v << "idf ";
if(cpu_->dmf()) v << "dmf ";
if(cpu_->bcf()) v << "bcf ";
if(cpu_->of()) v << "of ";
if(cpu_->nf()) v << "nf ";
v << "\n";
return v.str();
}
std::string Debugger::emu_handle_cmd(const std::string &s)
{
std::vector args = split_cmd(s);
std::string r("");
try
{
if(args.at(0) == "dr")
r = regs_cmd();
}
catch(const std::out_of_range){}
return r;
}
bool Debugger::emulate()
{
int sockfd;
struct sockaddr_in sa;
socklen_t sl = sizeof(sa);
/* non blocking */
sockfd = accept(ss_, (struct sockaddr *)&sa, &sl);
if(sockfd > 0)
{
/* unset fd's O_NONBLOCK flag
* on Linux reading from the fd seems to block while
* on OSX it seems to inherit the socket's non-blocking flag
*/
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) &~ O_NONBLOCK);
D("Debugger: client connected\n");
/* emulation paused while debugger is connected */
while(1)
{
int whence;
uint8_t *mem;
uint32_t sz;
uint64_t offset;
uint8_t buff[kMaxCmdLen];
std::string r;
/* continue emulation if debugger disconnected */
if(!recv(sockfd,buff,1,0))
{
D("Debugger: client disconnected\n");
break;
}
switch(buff[0])
{
case RAP_RMT_OPEN:
recv(sockfd,&buff[1],2,0);
recv(sockfd,&buff[3],(int)buff[2],0);
buff[0] = RAP_RMT_OPEN | RAP_RMT_REPLY;
send(sockfd,buff,5,0);
break;
case RAP_RMT_SEEK:
recv(sockfd,&buff[1],9,0);
whence = buff[1];
offset = ntohll(*(uint64_t*)&buff[2]);
offset = htonll(emu_seek((uint16_t)offset,whence));
buff[0] = RAP_RMT_SEEK | RAP_RMT_REPLY;
send(sockfd,buff,1,0);
send(sockfd,&offset,8,0);
break;
case RAP_RMT_READ:
recv(sockfd,&buff[1],4,0);
sz = ntohl(*(uint32_t*)&buff[1]);
buff[0] = RAP_RMT_READ | RAP_RMT_REPLY;
mem = emu_read_mem(sz);
send(sockfd,buff,5,0);
send(sockfd,mem,sz,0);
free(mem);
break;
case RAP_RMT_WRITE:
recv(sockfd,&buff[1],4,0);
sz = ntohl(*(uint32_t*)&buff[1]);
recv(sockfd,&buff[5],sz,0);
emu_write_mem(&buff[5],sz);
buff[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
send(sockfd,buff,5,0);
break;
case RAP_RMT_CMD:
recv(sockfd,&buff[1],4,0);
sz = ntohl(*(uint32_t*)&buff[1]);
recv(sockfd,&buff[5],sz,0);
r = emu_handle_cmd(std::string((char*)&buff[5],(size_t)(sz-1)));
*(uint32_t*)(&buff[1]) = htonl(r.length());
buff[0] = RAP_RMT_CMD | RAP_RMT_REPLY;
send(sockfd,buff,5,0);
send(sockfd,r.c_str(),r.length(),0);
break;
default:
D("Debugger: Unknown command %x\n",buff[0]);
break;
}
}
}
return true;
}
================================================
FILE: src/debugger.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_DEBUGGER_H
#define EMUDORE_DEBUGGER_H
/**
* @brief Debugger
*
* Sponsored by radare2
*
* https://github.com/radare/radare2
*/
#include "cpu.h"
#include "memory.h"
#include
#include
class Debugger
{
private:
int ss_;
uint16_t offset_;
Cpu *cpu_;
Memory *mem_;
uint16_t emu_seek(uint16_t offset, int whence);
uint8_t * emu_read_mem(size_t sz);
std::string emu_handle_cmd(const std::string &s);
void emu_write_mem(uint8_t *mem, size_t sz);
std::vector split_cmd(const std::string &s);
std::string regs_cmd();
public:
Debugger();
~Debugger();
void cpu(Cpu *v){cpu_=v;};
void memory(Memory *v){mem_=v;};
bool emulate();
static const int kDbgPort = 9999;
static const int kMaxCmdLen = 256;
enum kDbgCommands{
RAP_RMT_OPEN = 0x01,
RAP_RMT_READ,
RAP_RMT_WRITE,
RAP_RMT_SEEK,
RAP_RMT_CLOSE,
RAP_RMT_CMD,
RAP_RMT_REPLY = 0x80,
RAP_RMT_MAX = 4096
};
};
#endif
================================================
FILE: src/io.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include
#include "io.h"
#include "vic.h"
// clas ctor and dtor //////////////////////////////////////////////////////////
IO::IO()
{
SDL_Init(SDL_INIT_VIDEO);
/**
* We create the window double the original pixel size,
* the renderer takes care of upscaling
*/
window_ = SDL_CreateWindow(
"emudore",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
Vic::kVisibleScreenWidth * 2,
Vic::kVisibleScreenHeight * 2,
SDL_WINDOW_OPENGL
);
cols_ = Vic::kVisibleScreenWidth;
rows_ = Vic::kVisibleScreenHeight;
/* use a single texture and hardware acceleration */
renderer_ = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED);
texture_ = SDL_CreateTexture(renderer_,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
cols_,
rows_);
format_ = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
/**
* unfortunately, we need to keep a copy of the rendered frame
* in our own memory, there does not seem to be a way around
* that would allow manipulating pixels straight on the GPU
* memory due to how the image is internally stored, etc..
*
* The rendered frame gets uploaded to the GPU on every
* screen refresh.
*/
frame_ = new uint32_t[cols_ * rows_]();
init_color_palette();
init_keyboard();
next_key_event_at_ = 0;
prev_frame_was_at_ = std::chrono::high_resolution_clock::now();
}
IO::~IO()
{
delete [] frame_;
SDL_DestroyRenderer(renderer_);
SDL_DestroyTexture(texture_);
SDL_FreeFormat(format_);
SDL_Quit();
}
// init io devices ////////////////////////////////////////////////////////////
/**
* @brief init keyboard state and keymap
*/
void IO::init_keyboard()
{
/* init keyboard matrix state */
for(size_t i=0 ; i < sizeof(keyboard_matrix_) ; i++)
{
keyboard_matrix_[i] = 0xff;
}
/* character to sdl key map */
charmap_['A'] = {SDL_SCANCODE_A};
charmap_['B'] = {SDL_SCANCODE_B};
charmap_['C'] = {SDL_SCANCODE_C};
charmap_['D'] = {SDL_SCANCODE_D};
charmap_['E'] = {SDL_SCANCODE_E};
charmap_['F'] = {SDL_SCANCODE_F};
charmap_['G'] = {SDL_SCANCODE_G};
charmap_['H'] = {SDL_SCANCODE_H};
charmap_['I'] = {SDL_SCANCODE_I};
charmap_['J'] = {SDL_SCANCODE_J};
charmap_['K'] = {SDL_SCANCODE_K};
charmap_['L'] = {SDL_SCANCODE_L};
charmap_['M'] = {SDL_SCANCODE_M};
charmap_['N'] = {SDL_SCANCODE_N};
charmap_['O'] = {SDL_SCANCODE_O};
charmap_['P'] = {SDL_SCANCODE_P};
charmap_['Q'] = {SDL_SCANCODE_Q};
charmap_['R'] = {SDL_SCANCODE_R};
charmap_['S'] = {SDL_SCANCODE_S};
charmap_['T'] = {SDL_SCANCODE_T};
charmap_['U'] = {SDL_SCANCODE_U};
charmap_['V'] = {SDL_SCANCODE_V};
charmap_['W'] = {SDL_SCANCODE_W};
charmap_['X'] = {SDL_SCANCODE_X};
charmap_['Y'] = {SDL_SCANCODE_Y};
charmap_['Z'] = {SDL_SCANCODE_Z};
charmap_['1'] = {SDL_SCANCODE_1};
charmap_['2'] = {SDL_SCANCODE_2};
charmap_['3'] = {SDL_SCANCODE_3};
charmap_['4'] = {SDL_SCANCODE_4};
charmap_['5'] = {SDL_SCANCODE_5};
charmap_['6'] = {SDL_SCANCODE_6};
charmap_['7'] = {SDL_SCANCODE_7};
charmap_['8'] = {SDL_SCANCODE_8};
charmap_['9'] = {SDL_SCANCODE_9};
charmap_['0'] = {SDL_SCANCODE_0};
charmap_['\n'] = {SDL_SCANCODE_RETURN};
charmap_[' '] = {SDL_SCANCODE_SPACE};
charmap_[','] = {SDL_SCANCODE_COMMA};
charmap_['.'] = {SDL_SCANCODE_PERIOD};
charmap_['/'] = {SDL_SCANCODE_SLASH};
charmap_[';'] = {SDL_SCANCODE_SEMICOLON};
charmap_['='] = {SDL_SCANCODE_EQUALS};
charmap_['-'] = {SDL_SCANCODE_MINUS};
charmap_[':'] = {SDL_SCANCODE_BACKSLASH};
charmap_['+'] = {SDL_SCANCODE_LEFTBRACKET};
charmap_['*'] = {SDL_SCANCODE_RIGHTBRACKET};
charmap_['@'] = {SDL_SCANCODE_APOSTROPHE};
charmap_['('] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_8};
charmap_[')'] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_9};
charmap_['<'] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_COMMA};
charmap_['>'] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_PERIOD};
charmap_['"'] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_2};
charmap_['$'] = {SDL_SCANCODE_LSHIFT,SDL_SCANCODE_4};
/* keymap letters */
keymap_[SDL_SCANCODE_A] = std::make_pair(1,2);
keymap_[SDL_SCANCODE_B] = std::make_pair(3,4);
keymap_[SDL_SCANCODE_C] = std::make_pair(2,4);
keymap_[SDL_SCANCODE_D] = std::make_pair(2,2);
keymap_[SDL_SCANCODE_E] = std::make_pair(1,6);
keymap_[SDL_SCANCODE_F] = std::make_pair(2,5);
keymap_[SDL_SCANCODE_G] = std::make_pair(3,2);
keymap_[SDL_SCANCODE_H] = std::make_pair(3,5);
keymap_[SDL_SCANCODE_I] = std::make_pair(4,1);
keymap_[SDL_SCANCODE_J] = std::make_pair(4,2);
keymap_[SDL_SCANCODE_K] = std::make_pair(4,5);
keymap_[SDL_SCANCODE_L] = std::make_pair(5,2);
keymap_[SDL_SCANCODE_M] = std::make_pair(4,4);
keymap_[SDL_SCANCODE_N] = std::make_pair(4,7);
keymap_[SDL_SCANCODE_O] = std::make_pair(4,6);
keymap_[SDL_SCANCODE_P] = std::make_pair(5,1);
keymap_[SDL_SCANCODE_Q] = std::make_pair(7,6);
keymap_[SDL_SCANCODE_R] = std::make_pair(2,1);
keymap_[SDL_SCANCODE_S] = std::make_pair(1,5);
keymap_[SDL_SCANCODE_T] = std::make_pair(2,6);
keymap_[SDL_SCANCODE_U] = std::make_pair(3,6);
keymap_[SDL_SCANCODE_V] = std::make_pair(3,7);
keymap_[SDL_SCANCODE_W] = std::make_pair(1,1);
keymap_[SDL_SCANCODE_X] = std::make_pair(2,7);
keymap_[SDL_SCANCODE_Y] = std::make_pair(3,1);
keymap_[SDL_SCANCODE_Z] = std::make_pair(1,4);
/* keymap numbers */
keymap_[SDL_SCANCODE_1] = std::make_pair(7,0);
keymap_[SDL_SCANCODE_2] = std::make_pair(7,3);
keymap_[SDL_SCANCODE_3] = std::make_pair(1,0);
keymap_[SDL_SCANCODE_4] = std::make_pair(1,3);
keymap_[SDL_SCANCODE_5] = std::make_pair(2,0);
keymap_[SDL_SCANCODE_6] = std::make_pair(2,3);
keymap_[SDL_SCANCODE_7] = std::make_pair(3,0);
keymap_[SDL_SCANCODE_8] = std::make_pair(3,3);
keymap_[SDL_SCANCODE_9] = std::make_pair(4,0);
keymap_[SDL_SCANCODE_0] = std::make_pair(4,3);
/* keymap function keys */
keymap_[SDL_SCANCODE_F1] = std::make_pair(0,4);
keymap_[SDL_SCANCODE_F3] = std::make_pair(0,4);
keymap_[SDL_SCANCODE_F5] = std::make_pair(0,4);
keymap_[SDL_SCANCODE_F7] = std::make_pair(0,4);
/* keymap: other */
keymap_[SDL_SCANCODE_RETURN] = std::make_pair(0,1);
keymap_[SDL_SCANCODE_SPACE] = std::make_pair(7,4);
keymap_[SDL_SCANCODE_LSHIFT] = std::make_pair(1,7);
keymap_[SDL_SCANCODE_RSHIFT] = std::make_pair(6,4);
keymap_[SDL_SCANCODE_COMMA] = std::make_pair(5,7);
keymap_[SDL_SCANCODE_PERIOD] = std::make_pair(5,4);
keymap_[SDL_SCANCODE_SLASH] = std::make_pair(6,7);
keymap_[SDL_SCANCODE_SEMICOLON] = std::make_pair(6,2);
keymap_[SDL_SCANCODE_EQUALS] = std::make_pair(6,5);
keymap_[SDL_SCANCODE_BACKSPACE] = std::make_pair(0,0);
keymap_[SDL_SCANCODE_MINUS] = std::make_pair(5,3);
/* keymap: these are mapped to other keys */
keymap_[SDL_SCANCODE_BACKSLASH] = std::make_pair(5,5); // :
keymap_[SDL_SCANCODE_LEFTBRACKET] = std::make_pair(5,0); // +
keymap_[SDL_SCANCODE_RIGHTBRACKET] = std::make_pair(6,1); // *
keymap_[SDL_SCANCODE_APOSTROPHE] = std::make_pair(5,6); // @
keymap_[SDL_SCANCODE_LGUI] = std::make_pair(7,5); // commodore key
}
/**
* @brief init c64 color palette
*/
void IO::init_color_palette()
{
color_palette[0] = SDL_MapRGB(format_, 0x00, 0x00, 0x00);
color_palette[1] = SDL_MapRGB(format_, 0xff, 0xff, 0xff);
color_palette[2] = SDL_MapRGB(format_, 0xab, 0x31, 0x26);
color_palette[3] = SDL_MapRGB(format_, 0x66, 0xda, 0xff);
color_palette[4] = SDL_MapRGB(format_, 0xbb, 0x3f, 0xb8);
color_palette[5] = SDL_MapRGB(format_, 0x55, 0xce, 0x58);
color_palette[6] = SDL_MapRGB(format_, 0x1d, 0x0e, 0x97);
color_palette[7] = SDL_MapRGB(format_, 0xea, 0xf5, 0x7c);
color_palette[8] = SDL_MapRGB(format_, 0xb9, 0x74, 0x18);
color_palette[9] = SDL_MapRGB(format_, 0x78, 0x53, 0x00);
color_palette[10] = SDL_MapRGB(format_, 0xdd, 0x93, 0x87);
color_palette[11] = SDL_MapRGB(format_, 0x5b, 0x5b, 0x5b);
color_palette[12] = SDL_MapRGB(format_, 0x8b, 0x8b, 0x8b);
color_palette[13] = SDL_MapRGB(format_, 0xb0, 0xf4, 0xac);
color_palette[14] = SDL_MapRGB(format_, 0xaa, 0x9d, 0xef);
color_palette[15] = SDL_MapRGB(format_, 0xb8, 0xb8, 0xb8);
}
// emulation ///////////////////////////////////////////////////////////////////
bool IO::emulate()
{
return retval_;
}
void IO::process_events()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
handle_keydown(event.key.keysym.scancode);
break;
case SDL_KEYUP:
handle_keyup(event.key.keysym.scancode);
break;
case SDL_QUIT:
retval_ = false;
break;
}
}
/* process fake keystrokes if any */
if(!key_event_queue_.empty() &&
cpu_->cycles() > next_key_event_at_)
{
std::pair &ev = key_event_queue_.front();
key_event_queue_.pop();
switch(ev.first)
{
case kPress:
handle_keydown(ev.second);
break;
case kRelease:
handle_keyup(ev.second);
break;
}
next_key_event_at_ = cpu_->cycles() + kWait;
}
}
// keyboard handling ///////////////////////////////////////////////////////////
/**
* @brief emulate keydown
*/
void IO::handle_keydown(SDL_Keycode k)
{
try
{
uint8_t mask = ~(1 << keymap_.at(k).second);
keyboard_matrix_[keymap_.at(k).first] &= mask;
}
catch(const std::out_of_range){}
}
/**
* @brief emulate keyup
*/
void IO::handle_keyup(SDL_Keycode k)
{
try
{
uint8_t mask = (1 << keymap_.at(k).second);
keyboard_matrix_[keymap_.at(k).first] |= mask;
}
catch(const std::out_of_range){}
}
/**
* @brief fake press a key, monkeys love it
*
* Characters are added to a queue and processed within
* the emulation loop.
*/
void IO::type_character(char c)
{
try
{
for(SDL_Keycode &k: charmap_.at(toupper(c)))
key_event_queue_.push(std::make_pair(kPress,k));
for(SDL_Keycode &k: charmap_.at(toupper(c)))
key_event_queue_.push(std::make_pair(kRelease,k));
}
catch(const std::out_of_range){}
}
// screen handling /////////////////////////////////////////////////////////////
void IO::screen_draw_rect(int x, int y, int n, int color)
{
for(int i=0; i < n ; i++)
{
screen_update_pixel(x+i,y,color);
}
}
void IO::screen_draw_border(int y, int color)
{
screen_draw_rect(0,y,cols_,color);
}
/**
* @brief refresh screen
*
* Upload the texture to the GPU
*/
void IO::screen_refresh()
{
SDL_UpdateTexture(texture_, NULL, frame_, cols_ * sizeof(uint32_t));
SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_,texture_, NULL, NULL);
SDL_RenderPresent(renderer_);
/* process SDL events once every frame */
process_events();
/* perform vertical refresh sync */
vsync();
}
/**
* @brief vsync
*
* vsync() is called at the end of every frame, if we are ahead
* of time compared to a real C64 (very likely) we sleep for a bit,
* this way we avoid running at full speed allowing the host CPU to
* take a little nap before getting back to work.
*
* This should also help with performance runing on slow computers,
* uploading data to the GPU is a relatively slow operation, doing
* more fps obviously has a performance impact.
*
* Also, and more importantly, by doing this we emulate the actual
* speed of the C64 so visual effects do not look accelerated and
* games become playable :)
*/
void IO::vsync()
{
using namespace std::chrono;
auto t = high_resolution_clock::now() - prev_frame_was_at_;
duration rr(Vic::kRefreshRate);
/**
* Microsoft's chrono is buggy and does not properly handle
* doubles, we need to recast to milliseconds.
*/
auto ttw = duration_cast(rr - t);
std::this_thread::sleep_for(ttw);
prev_frame_was_at_ = std::chrono::high_resolution_clock::now();
}
================================================
FILE: src/io.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_IO_H
#define EMUDORE_IO_H
#include
#include
#include
#include
#include
#include
#include
#include "cpu.h"
#include "util.h"
/**
* @brief IO devices
*
* This class implements Input/Output devices connected to the
* Commodore 64 such as the screen and keyboard.
*
* Current backend is SDL2.
*/
class IO
{
private:
Cpu *cpu_;
SDL_Window *window_;
SDL_Renderer *renderer_;
SDL_Texture *texture_;
SDL_PixelFormat *format_;
uint32_t *frame_;
size_t cols_;
size_t rows_;
unsigned int color_palette[16];
uint8_t keyboard_matrix_[8];
bool retval_ = true;
/* keyboard mappings */
std::unordered_map> keymap_;
std::unordered_map> charmap_;
enum kKeyEvent
{
kPress,
kRelease,
};
/* key events */
std::queue> key_event_queue_;
unsigned int next_key_event_at_;
static const int kWait = 18000;
/* vertical refresh sync */
std::chrono::high_resolution_clock::time_point prev_frame_was_at_;
void vsync();
public:
IO();
~IO();
bool emulate();
void process_events();
void cpu(Cpu *v){cpu_=v;};
void init_color_palette();
void init_keyboard();
void handle_keydown(SDL_Keycode k);
void handle_keyup(SDL_Keycode k);
void type_character(char c);
inline uint8_t keyboard_matrix_row(int col){return keyboard_matrix_[col];};
void screen_update_pixel(int x, int y, int color);
void screen_draw_rect(int x, int y, int n, int color);
void screen_draw_border(int y, int color);
void screen_refresh();
};
// inline member functions accesible from other classes /////////////////////
inline void IO::screen_update_pixel(int x, int y, int color)
{
frame_[y * cols_ + x] = color_palette[color & 0xf];
};
#endif
================================================
FILE: src/loader.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "loader.h"
Loader::Loader(C64 *c64)
{
c64_ = c64;
io_ = c64_->io();
cpu_ = c64_->cpu();
mem_ = c64_->memory();
booted_up_ = false;
format_ = kNone;
}
// common ///////////////////////////////////////////////////////////////////
uint16_t Loader::read_short_le()
{
char b;
uint16_t v = 0;
is_.get(b);
v |= (b);
is_.get(b);
v |= b << 8;
return v;
}
// BASIC listings ///////////////////////////////////////////////////////////
void Loader::bas(const std::string &f)
{
format_ = kBasic;
is_.open(f,std::ios::in);
}
void Loader::load_basic()
{
char c;
if(is_.is_open())
{
while(is_.good())
{
is_.get(c);
io_->IO::type_character(c);
}
}
}
// PRG //////////////////////////////////////////////////////////////////////
void Loader::prg(const std::string &f)
{
format_ = kPRG;
is_.open(f,std::ios::in|std::ios::binary);
}
void Loader::load_prg()
{
char b;
uint16_t pbuf, addr;
pbuf = addr = read_short_le();
if(is_.is_open())
{
while(is_.good())
{
is_.get(b);
mem_->write_byte_no_io(pbuf++,b);
}
/* basic-tokenized prg */
if(addr == kBasicPrgStart)
{
/* make BASIC happy */
mem_->write_word_no_io(kBasicTxtTab,kBasicPrgStart);
mem_->write_word_no_io(kBasicVarTab,pbuf);
mem_->write_word_no_io(kBasicAryTab,pbuf);
mem_->write_word_no_io(kBasicStrEnd,pbuf);
/* exec RUN */
for(char &c: std::string("RUN\n"))
io_->IO::type_character(c);
}
/* ML */
else cpu_->pc(addr);
}
}
// emulate //////////////////////////////////////////////////////////////////
bool Loader::emulate()
{
if(booted_up_)
{
switch(format_)
{
case kBasic:
load_basic();
break;
case kPRG:
load_prg();
break;
default:
break;
}
return false;
}
else
{
/* at this point BASIC is ready */
if(cpu_->pc() == 0xa65c)
booted_up_ = true;
}
return true;
}
================================================
FILE: src/loader.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_LOADER_H
#define EMUDORE_LOADER_H
#include
#include "c64.h"
/**
* @brief Program loader
*/
class Loader
{
private:
bool booted_up_;
C64 *c64_;
IO *io_;
Cpu *cpu_;
Memory *mem_;
std::ifstream is_;
enum kFormat
{
kNone,
kBasic,
kPRG
};
kFormat format_;
void load_basic();
void load_prg();
uint16_t read_short_le();
public:
Loader(C64 *c64);
void bas(const std::string &f);
void prg(const std::string &f);
bool emulate();
/* constants */
static const uint16_t kBasicPrgStart = 0x0801;
static const uint16_t kBasicTxtTab = 0x002b;
static const uint16_t kBasicVarTab = 0x002d;
static const uint16_t kBasicAryTab = 0x002f;
static const uint16_t kBasicStrEnd = 0x0031;
};
#endif
================================================
FILE: src/main.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include
#include
#include
#include "c64.h"
#include "loader.h"
#ifdef EMSCRIPTEN
#include
#endif
C64 *c64;
Loader *loader;
bool wget_download_finished = false;
bool loader_cb()
{
if(!loader->emulate())
c64->callback(nullptr);
return true;
}
bool emscripten_loader_cb()
{
if (!loader->emulate() && wget_download_finished)
c64->callback(nullptr);
return true;
}
void load_file(const char *file)
{
std::string f(file);
size_t ext_i = f.find_last_of(".");
if(ext_i != std::string::npos)
{
std::string ext(f.substr(ext_i+1));
std::transform(ext.begin(),ext.end(),ext.begin(),::tolower);
if(ext == "bas"){
loader->bas(f);
}
else if(ext == "prg"){
loader->prg(f);
}
}
}
void wget_cb(const char *f)
{
wget_download_finished = true;
load_file(f);
}
void emscripten_loop()
{
c64->emscripten_loop();
}
int main(int argc, char **argv)
{
c64 = new C64();
/* check if asked load a program */
if(argc != 1)
{
loader = new Loader(c64);
#ifdef EMSCRIPTEN
std::string f(argv[1]);
size_t sp = f.find_last_of("/");
if(sp != std::string::npos)
{
std::string fname(f.substr(sp+1));
c64->callback(emscripten_loader_cb);
emscripten_async_wget(argv[1],fname.c_str(),wget_cb,nullptr);
}
#else
c64->callback(loader_cb);
load_file(argv[1]);
#endif
}
#ifdef EMSCRIPTEN
emscripten_set_main_loop(emscripten_loop,0,0);
#else
c64->start();
#endif
return 0;
}
================================================
FILE: src/memory.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include
#include "memory.h"
#include "util.h"
#include "vic.h"
#include "cia1.h"
#include "cia2.h"
Memory::Memory()
{
/**
* 64 kB memory buffers, zeroed.
*
* We use two buffers to handle special circumstances, for instance,
* any write to a ROM-mapped location will in turn store data on the
* hidden RAM, this trickery is used in certain graphic modes.
*/
mem_ram_ = new uint8_t[kMemSize]();
mem_rom_ = new uint8_t[kMemSize]();
/* configure memory layout */
setup_memory_banks(kLORAM|kHIRAM|kCHAREN);
/* configure data directional bits */
write_byte_no_io(kAddrDataDirection,0x2f);
}
Memory::~Memory()
{
delete [] mem_ram_;
delete [] mem_rom_;
}
/**
* @brief configure memory banks
*
* There are five latch bits that control the configuration allowing
* for a total of 32 different memory layouts, for now we only take
* in count three bits : HIRAM/LORAM/CHAREN
*/
void Memory::setup_memory_banks(uint8_t v)
{
/* get config bits */
bool hiram = ((v&kHIRAM) != 0);
bool loram = ((v&kLORAM) != 0);
bool charen = ((v&kCHAREN)!= 0);
/* init everything to ram */
for(size_t i=0 ; i < sizeof(banks_) ; i++)
banks_[i] = kRAM;
/* load ROMs */
load_rom("basic.901226-01.bin",kBaseAddrBasic);
load_rom("characters.901225-01.bin",kBaseAddrChars);
load_rom("kernal.901227-03.bin",kBaseAddrKernal);
/* kernal */
if (hiram)
banks_[kBankKernal] = kROM;
/* basic */
if (loram && hiram)
banks_[kBankBasic] = kROM;
/* charen */
if (charen && (loram || hiram))
banks_[kBankCharen] = kIO;
else if (charen && !loram && !hiram)
banks_[kBankCharen] = kRAM;
else
banks_[kBankCharen] = kROM;
/* write the config to the zero page */
write_byte_no_io(kAddrMemoryLayout, v);
}
/**
* @brief writes a byte to RAM without performing I/O
*/
void Memory::write_byte_no_io(uint16_t addr, uint8_t v)
{
mem_ram_[addr] = v;
}
/**
* @brief writes a byte to RAM handling I/O
*/
void Memory::write_byte(uint16_t addr, uint8_t v)
{
uint16_t page = addr&0xff00;
/* ZP */
if (page == kAddrZeroPage)
{
/* bank switching */
if (addr == kAddrMemoryLayout)
setup_memory_banks(v);
else
mem_ram_[addr] = v;
}
/* VIC-II DMA or Character ROM */
else if (page >= kAddrVicFirstPage && page <= kAddrVicLastPage)
{
if(banks_[kBankCharen] == kIO)
vic_->write_register(addr&0x7f,v);
else
mem_ram_[addr] = v;
}
/* CIA1 */
else if (page == kAddrCIA1Page)
{
if(banks_[kBankCharen] == kIO)
cia1_->write_register(addr&0x0f,v);
else
mem_ram_[addr] = v;
}
else if (page == kAddrCIA2Page)
{
if(banks_[kBankCharen] == kIO)
cia2_->write_register(addr&0x0f,v);
else
mem_ram_[addr] = v;
}
/* default */
else
{
mem_ram_[addr] = v;
}
}
/**
* @brief reads a byte from RAM or ROM (depending on bank config)
*/
uint8_t Memory::read_byte(uint16_t addr)
{
uint8_t retval = 0;
uint16_t page = addr&0xff00;
/* VIC-II DMA or Character ROM */
if (page >= kAddrVicFirstPage && page <= kAddrVicLastPage)
{
if(banks_[kBankCharen] == kIO)
retval = vic_->read_register(addr&0x7f);
else if(banks_[kBankCharen] == kROM)
retval = mem_rom_[addr];
else
retval = mem_ram_[addr];
}
/* CIA1 */
else if (page == kAddrCIA1Page)
{
if(banks_[kBankCharen] == kIO)
retval = cia1_->read_register(addr&0x0f);
else
retval = mem_ram_[addr];
}
/* CIA2 */
else if (page == kAddrCIA2Page)
{
if(banks_[kBankCharen] == kIO)
retval = cia2_->read_register(addr&0x0f);
else
retval = mem_ram_[addr];
}
/* BASIC or RAM */
else if (page >= kAddrBasicFirstPage && page <= kAddrBasicLastPage)
{
if (banks_[kBankBasic] == kROM)
retval = mem_rom_[addr];
else
retval = mem_ram_[addr];
}
/* KERNAL */
else if (page >= kAddrKernalFirstPage && page <= kAddrKernalLastPage)
{
if (banks_[kBankKernal] == kROM)
retval = mem_rom_[addr];
else
retval = mem_ram_[addr];
}
/* default */
else
{
retval = mem_ram_[addr];
}
return retval;
}
/**
* @brief writes a byte without performing I/O (always to RAM)
*/
uint8_t Memory::read_byte_no_io(uint16_t addr)
{
return mem_ram_[addr];
}
/**
* @brief reads a word performing I/O
*/
uint16_t Memory::read_word(uint16_t addr)
{
return read_byte(addr) | (read_byte(addr+1) << 8);
}
/**
* @brief reads a word withouth performing I/O
*/
uint16_t Memory::read_word_no_io(uint16_t addr)
{
return read_byte_no_io(addr) | (read_byte_no_io(addr+1) << 8);
}
/**
* @brief writes a word performing I/O
*/
void Memory::write_word(uint16_t addr, uint16_t v)
{
write_byte(addr, (uint8_t)(v));
write_byte(addr+1, (uint8_t)(v>>8));
}
/**
* @brief writes a word without performing I/O
*/
void Memory::write_word_no_io(uint16_t addr, uint16_t v)
{
write_byte_no_io(addr, (uint8_t)(v));
write_byte_no_io(addr+1, (uint8_t)(v>>8));
}
/**
* @brief read byte (from VIC's perspective)
*
* The VIC has only 14 address lines so it can only access
* 16kB of memory at once, the two missing address bits are
* provided by CIA2.
*
* The VIC always reads from RAM ignoring the memory configuration,
* there's one exception: the character generator ROM. Unless the
* Ultimax mode is selected, VIC sees the character generator ROM
* in the memory areas:
*
* 1000-1FFF
* 9000-9FFF
*/
uint8_t Memory::vic_read_byte(uint16_t addr)
{
uint8_t v;
uint16_t vic_addr = cia2_->vic_base_address() + (addr & 0x3fff);
if((vic_addr >= 0x1000 && vic_addr < 0x2000) ||
(vic_addr >= 0x9000 && vic_addr < 0xa000))
v = mem_rom_[kBaseAddrChars + (vic_addr & 0xfff)];
else
v = read_byte_no_io(vic_addr);
return v;
}
/**
* @brief loads a external binary into ROM
*/
void Memory::load_rom(const std::string &f, uint16_t baseaddr)
{
std::string path = "./assets/roms/" + f;
std::ifstream is(path, std::ios::in | std::ios::binary);
if(is)
{
is.seekg (0, is.end);
std::streamoff length = is.tellg();
is.seekg (0, is.beg);
is.read ((char *) &mem_rom_[baseaddr],length);
}
}
/**
* @brief loads a external binary into RAM
*/
void Memory::load_ram(const std::string &f, uint16_t baseaddr)
{
std::string path = "./assets/" + f;
std::ifstream is(path, std::ios::in | std::ios::binary);
if(is)
{
is.seekg (0, is.end);
std::streamoff length = is.tellg();
is.seekg (0, is.beg);
is.read ((char *) &mem_ram_[baseaddr],length);
}
}
// debug ////////////////////////////////////////////////////////////////////
/**
* @brief dumps memory as seen by the CPU to stdout
*/
void Memory::dump()
{
for(unsigned int p=0 ; p < kMemSize ; p++)
{
std::cout << read_byte(p);
}
}
================================================
FILE: src/memory.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_MEMORY_H
#define EMUDORE_MEMORY_H
#include
#include
/* forward declarations */
class Vic;
class Cia1;
class Cia2;
class Sid;
/**
* @brief DRAM
*
* - @c $0000-$00FF Page 0 Zeropage addressing
* - @c $0100-$01FF Page 1 Enhanced Zeropage contains the stack
* - @c $0200-$02FF Page 2 Operating System and BASIC pointers
* - @c $0300-$03FF Page 3 Operating System and BASIC pointers
* - @c $0400-$07FF Page 4-7 Screen Memory
* - @c $0800-$9FFF Page 8-159 Free BASIC program storage area (38911 bytes)
* - @c $A000-$BFFF Page 160-191 Free machine language program storage area (when switched-out with ROM)
* - @c $C000-$CFFF Page 192-207 Free machine language program storage area
* - @c $D000-$D3FF Page 208-211
* - @c $D400-$D4FF Page 212-215
* - @c $D800-$DBFF Page 216-219
* - @c $DC00-$DCFF Page 220
* - @c $DD00-$DDFF Page 221
* - @c $DE00-$DFFF Page 222-223 Reserved for interface extensions
* - @c $E000-$FFFF Page 224-255 Free machine language program storage area (when switched-out with ROM)
*/
class Memory
{
private:
uint8_t *mem_ram_;
uint8_t *mem_rom_;
uint8_t banks_[7];
Vic *vic_;
Cia1 *cia1_;
Cia2 *cia2_;
Sid *sid_;
public:
Memory();
~Memory();
void vic(Vic *v){vic_ = v;};
void cia1(Cia1 *v){cia1_ = v;};
void cia2(Cia2 *v){cia2_ = v;};
/* bank switching */
enum kBankCfg
{
kROM,
kRAM,
kIO
};
enum Banks
{
kBankBasic = 3,
kBankCharen = 5,
kBankKernal = 6,
};
void setup_memory_banks(uint8_t v);
/* read/write memory */
uint8_t read_byte(uint16_t addr);
uint8_t read_byte_no_io(uint16_t addr);
void write_byte(uint16_t addr, uint8_t v);
void write_byte_no_io(uint16_t addr, uint8_t v);
uint16_t read_word(uint16_t addr);
uint16_t read_word_no_io(uint16_t);
void write_word(uint16_t addr, uint16_t v);
void write_word_no_io(uint16_t addr, uint16_t v);
/* vic memory access */
uint8_t vic_read_byte(uint16_t addr);
uint8_t read_byte_rom(uint16_t addr);
/* load external binaries */
void load_rom(const std::string &f, uint16_t baseaddr);
void load_ram(const std::string &f, uint16_t baseaddr);
/* debug */
void dump();
void print_screen_text();
/* constants */
static const size_t kMemSize = 0x10000;
/* memory addresses */
static const uint16_t kBaseAddrBasic = 0xa000;
static const uint16_t kBaseAddrKernal = 0xe000;
static const uint16_t kBaseAddrStack = 0x0100;
static const uint16_t kBaseAddrScreen = 0x0400;
static const uint16_t kBaseAddrChars = 0xd000;
static const uint16_t kBaseAddrBitmap = 0x0000;
static const uint16_t kBaseAddrColorRAM = 0xd800;
static const uint16_t kAddrResetVector = 0xfffc;
static const uint16_t kAddrIRQVector = 0xfffe;
static const uint16_t kAddrNMIVector = 0xfffa;
static const uint16_t kAddrDataDirection = 0x0000;
static const uint16_t kAddrMemoryLayout = 0x0001;
static const uint16_t kAddrColorRAM = 0xd800;
/* memory layout */
static const uint16_t kAddrZeroPage = 0x0000;
static const uint16_t kAddrVicFirstPage = 0xd000;
static const uint16_t kAddrVicLastPage = 0xd300;
static const uint16_t kAddrCIA1Page = 0xdc00;
static const uint16_t kAddrCIA2Page = 0xdd00;
static const uint16_t kAddrBasicFirstPage = 0xa000;
static const uint16_t kAddrBasicLastPage = 0xbf00;
static const uint16_t kAddrKernalFirstPage = 0xe000;
static const uint16_t kAddrKernalLastPage = 0xff00;
/* bank switching */
static const uint8_t kLORAM = 1 << 0;
static const uint8_t kHIRAM = 1 << 1;
static const uint8_t kCHAREN = 1 << 2;
};
#endif
================================================
FILE: src/sid.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_SID_H
#define EMUDORE_SID_H
/**
* @brief MOS 6581 SID (Sound Interface Device)
*
* - Memory area : $D400-$D7FF
* - Tasks : Sound
*/
class Sid
{
private:
public:
};
#endif
================================================
FILE: src/util.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_UTIL_H
#define EMUDORE_UTIL_H
#include
#ifndef NDEBUG
#define D(...) fprintf (stderr,__VA_ARGS__)
#else
#define D(...) do {} while (0)
#endif
#define ISSET_BIT(v,b) ((v&(1<
# include
#elif defined(_MSC_VER)
# include
#else
# include
#endif
#if !defined(htonll) && !defined(ntohll)
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if defined(__APPLE__)
# define htonll(x) OSSwapInt64(x)
# define ntohll(x) OSSwapInt64(x)
# elif defined(_MSC_VER)
# define htonll(x) _byteswap_uint64(x)
# define ntohll(x) _byteswap_uint64(x)
# else
# define htonll(x) bswap_64(x)
# define ntohll(x) bswap_64(x)
# endif
#else
# define htonll(x) (x)
# define ntohll(x) (x)
#endif
#endif
#endif
================================================
FILE: src/vic.cpp
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vic.h"
#include "util.h"
// ctor and emulate() ///////////////////////////////////////////////////////
Vic::Vic()
{
/* raster */
raster_irq_ = raster_c_ = 0;
irq_enabled_ = irq_status_ = 0;
next_raster_at_ = kLineCycles;
/* sprites */
for(int i = 0 ; i<8 ; i++)
{
mx_[i] = my_[i] = sprite_colors_[i] = 0;
}
msbx_ = sprite_double_height_ = sprite_double_width_ = 0;
sprite_enabled_ = sprite_priority_ = sprite_multicolor_ = 0;
sprite_shared_colors_[0] = sprite_shared_colors_[1] = 0;
/* colors */
border_color_ = 0;
bgcolor_[0] = bgcolor_[1] = bgcolor_[2] = bgcolor_[3] = 0;
/* control regs */
cr1_ = cr2_ = 0;
/* frame counter */
frame_c_ = 0;
/* default memory pointers */
screen_mem_ = Memory::kBaseAddrScreen;
char_mem_ = Memory::kBaseAddrChars;
bitmap_mem_ = Memory::kBaseAddrBitmap;
/* bit 0 is unused */
mem_pointers_ = (1 << 0);
/* current graphic mode */
graphic_mode_ = kCharMode;
}
bool Vic::emulate()
{
/**
* if there are unacknowledged interrupts
* raise an interrupt again
**/
if((read_register(0x19) & 0x80) != 0)
{
cpu_->irq();
}
/* are we at the next raster line? */
if (cpu_->cycles() >= next_raster_at_)
{
int rstr = raster_counter();
/* check raster IRQs */
if (raster_irq_enabled() &&
rstr == raster_irq_)
{
/* set interrupt origin (raster) */
irq_status_ |= (1<<0);
/* raise interrupt */
cpu_->irq();
}
if (rstr >= kFirstVisibleLine &&
rstr < kLastVisibleLine)
{
/* draw border */
int screen_y = rstr - kFirstVisibleLine;
io_->screen_draw_border(screen_y,border_color_);
/* draw raster on current graphic mode */
switch(graphic_mode_)
{
case kCharMode:
case kMCCharMode:
draw_raster_char_mode();
break;
case kBitmapMode:
case kMCBitmapMode:
draw_raster_bitmap_mode();
break;
default:
D("unsupported graphic mode: %d\n",graphic_mode_);
return false;
}
/* draw sprites */
draw_raster_sprites();
}
/* next raster */
if(is_bad_line())
next_raster_at_+= kBadLineCycles;
else
next_raster_at_+= kLineCycles;
/* update raster */
raster_counter(++rstr);
if (rstr >= kScreenLines)
{
io_->screen_refresh();
frame_c_++;
raster_counter(0);
}
}
return true;
}
// DMA register access //////////////////////////////////////////////////////
uint8_t Vic::read_register(uint8_t r)
{
uint8_t retval;
switch(r)
{
/* get X coord of sprite n*/
case 0x0:
case 0x2:
case 0x4:
case 0x6:
case 0x8:
case 0xc:
case 0xe:
retval = mx_[r >> 1];
break;
/* get Y coord of sprite n */
case 0x1:
case 0x3:
case 0x5:
case 0x7:
case 0x9:
case 0xb:
case 0xd:
case 0xf:
retval = my_[r >> 1];
break;
/* MSBs of sprites X coordinates */
case 0x10:
retval = msbx_;
break;
/* control register 1 */
case 0x11:
retval = cr1_;
break;
/* raster counter */
case 0x12:
retval = raster_c_;
break;
/* sprite enable register */
case 0x15:
retval = sprite_enabled_;
break;
/* control register 2 */
case 0x16:
retval = cr2_;
break;
/* sprite double height */
case 0x17:
retval = sprite_double_height_;
break;
/* memory pointers */
case 0x18:
retval = mem_pointers_;
break;
/**
* interrupt status register
* IRQ| - | - | - | ILP|IMMC|IMBC|IRST|
*/
case 0x19:
retval = (0xf & irq_status_);
if(retval!=0) retval |= 0x80; // IRQ bit
retval |= 0x70; // non-connected bits (always set)
break;
/**
* interrupt enable register
* - | - | - | - | ELP|EMMC|EMBC|ERST|
*/
case 0x1a:
retval = (0xf0 | irq_enabled_);
break;
/* sprite priority register */
case 0x1b:
retval = sprite_priority_;
break;
/* sprite multicolor mode */
case 0x1c:
retval = sprite_multicolor_;
break;
/* sprite double width */
case 0x1d:
retval = sprite_double_width_;
break;
/* border color */
case 0x20:
retval = border_color_;
break;
/* background colors */
case 0x21:
case 0x22:
case 0x23:
case 0x24:
retval = bgcolor_[r-0x21];
break;
/* sprite colors */
case 0x25:
case 0x26:
retval = sprite_shared_colors_[r-0x25];
break;
case 0x27:
case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
case 0x2c:
case 0x2d:
case 0x2e:
retval = sprite_colors_[r-0x27];
break;
/* unused */
case 0x2f:
case 0x30:
case 0x31:
case 0x32:
case 0x33:
case 0x34:
case 0x35:
case 0x36:
case 0x37:
case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
default:
retval = 0xff;
break;
}
return retval;
}
void Vic::write_register(uint8_t r, uint8_t v)
{
switch(r)
{
/* store X coord of sprite n*/
case 0x0:
case 0x2:
case 0x4:
case 0x6:
case 0x8:
case 0xc:
case 0xe:
mx_[r >> 1] = v;
break;
/* store Y coord of sprite n */
case 0x1:
case 0x3:
case 0x5:
case 0x7:
case 0x9:
case 0xb:
case 0xd:
case 0xf:
my_[r >> 1] = v;
break;
/* MSBs of X coordinates */
case 0x10:
msbx_ = v;
break;
/* control register 1 */
case 0x11:
cr1_ = (v&0x7f);
raster_irq_ &= 0xff;
raster_irq_ |= (v&0x80) << 1;
set_graphic_mode();
break;
/* raster irq */
case 0x12:
raster_irq_ = v | (raster_irq_ & (1 << 8));
break;
/* sprite enable register */
case 0x15:
sprite_enabled_ = v;
break;
/* control register 2 */
case 0x16:
cr2_ = v;
set_graphic_mode();
break;
/* sprite double height */
case 0x17:
sprite_double_height_ = v;
break;
/* memory pointers */
case 0x18:
/* bits ----xxx- */
char_mem_ = (v&0xe) << 10;
/* bits xxxx---- */
screen_mem_ = (v&0xf0) << 6;
/* bit ----x--- */
bitmap_mem_ = (v&0x8) << 10;
/* save reg value (last bit always set)*/
mem_pointers_ = v | (1 << 0);
break;
/* interrupt request register */
case 0x19:
/* acknowledge interrupts by mask */
irq_status_ &= ~(v&0xf);
break;
/* interrupt enable register */
case 0x1a:
irq_enabled_= v;
break;
/* sprite priority register */
case 0x1b:
sprite_priority_ = v;
break;
/* sprite multicolor mode */
case 0x1c:
sprite_multicolor_ = v;
break;
/* sprite double width */
case 0x1d:
sprite_double_width_ = v;
break;
/* border color */
case 0x20:
border_color_ = v;
break;
/* background colors */
case 0x21:
case 0x22:
case 0x23:
case 0x24:
bgcolor_[r-0x21] = v;
break;
/* sprite colors */
case 0x25:
case 0x26:
sprite_shared_colors_[r-0x25] = v;
break;
case 0x27:
case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
case 0x2c:
case 0x2d:
case 0x2e:
sprite_colors_[r-0x27] = v;
break;
/* unused */
case 0x2f:
case 0x30:
case 0x31:
case 0x32:
case 0x33:
case 0x34:
case 0x35:
case 0x36:
case 0x37:
case 0x38:
case 0x39:
case 0x3a:
case 0x3b:
case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
default:
break;
}
}
// graphics //////////////////////////////////////////////////////////////////
/**
* @brief set current graphic mode
*/
void Vic::set_graphic_mode()
{
bool ecm = ((cr1_ & (1<<6))!= 0);
bool bmm = ((cr1_ & (1<<5))!= 0);
bool mcm = ((cr2_ & (1<<4))!= 0);
if(!ecm && !bmm && !mcm)
graphic_mode_ = kCharMode;
else if(!ecm && !bmm && mcm)
graphic_mode_ = kMCCharMode;
else if(!ecm && bmm && !mcm)
graphic_mode_ = kBitmapMode;
else if(!ecm && bmm && mcm)
graphic_mode_ = kMCBitmapMode;
else if(ecm && !bmm && !mcm)
graphic_mode_ = kExtBgMode;
else
graphic_mode_ = kIllegalMode;
}
/**
* @brief retrieves a character from screen Memory
*/
uint8_t Vic::get_screen_char(int column, int row)
{
uint16_t addr = screen_mem_ + (row * kGCols) + column;
return mem_->vic_read_byte(addr);
}
/**
* @brief retrives color RAM for given screen coords
*/
uint8_t Vic::get_char_color(int column, int row)
{
uint16_t addr = Memory::kAddrColorRAM + (row * kGCols) + column;
return (mem_->read_byte_no_io(addr) & 0x0f);
}
/**
* @brief retrieves pixel data from character memory
*/
uint8_t Vic::get_char_data(int chr, int line)
{
uint16_t addr = char_mem_ + (chr * 8) + line;
return mem_->vic_read_byte(addr);
}
/**
* @brief retrieves pixel data from bitmap memory
*/
uint8_t Vic::get_bitmap_data(int column, int row, int line)
{
uint16_t addr = bitmap_mem_ + (row * kGCols + column) * 8 + line;
return mem_->vic_read_byte(addr);
}
/**
* @brief get sprite pointer
*
* n is sprite # (0-7)
*/
uint16_t Vic::get_sprite_ptr(int n)
{
uint16_t ptraddr = screen_mem_ + kSpritePtrsOffset + n;
return kSpriteSize * mem_->vic_read_byte(ptraddr);
}
// raster drawing ///////////////////////////////////////////////////////////
void Vic::draw_char(int x, int y, uint8_t data, uint8_t color)
{
for(int i=0 ; i < 8 ; i++)
{
int xoffs = x + 8 - i + horizontal_scroll();
/* don't draw outside (due to horizontal scroll) */
if(xoffs > kGFirstCol + kGResX)
continue;
/* draw pixel */
if(ISSET_BIT(data,i))
{
io_->screen_update_pixel(
xoffs,
y,
color);
}
}
}
void Vic::draw_mcchar(int x, int y, uint8_t data, uint8_t color)
{
for(int i=0 ; i < 4 ; i++)
{
/* color */
uint8_t c;
/* color source */
uint8_t cs = ((data >> i*2) & 0x3);
switch(cs)
{
case 0:
c = bgcolor_[0];
break;
case 1:
c = bgcolor_[1];
break;
case 2:
c = bgcolor_[2];
break;
case 3:
c = color;
break;
}
int xoffs = x + 8 - i * 2 + horizontal_scroll();
io_->screen_update_pixel(
xoffs,
y,
c);
io_->screen_update_pixel(
xoffs + 1,
y,
c);
}
}
void Vic::draw_raster_char_mode()
{
int rstr = raster_counter();
int y = rstr - kFirstVisibleLine;
if((rstr >= kGFirstLine) &&
(rstr < kGLastLine) &&
!is_screen_off())
{
/* draw background */
io_->screen_draw_rect(kGFirstCol,y,kGResX,bgcolor_[0]);
/* draw characters */
for(int column=0; column < kGCols ; column++)
{
/* check 38 cols mode */
if(!ISSET_BIT(cr2_,3))
{
if (column == 0) continue;
if (column == kGCols -1 ) continue;
}
int x = kGFirstCol + column * 8;
int line = rstr - kGFirstLine;
int row = line/8;
int char_row = line % 8;
/* retrieve screen character */
uint8_t c = get_screen_char(column,row);
/* retrieve character bitmap data */
uint8_t data = get_char_data(c,char_row);
/* retrieve color data */
uint8_t color = get_char_color(column,row);
/* draw character */
if(graphic_mode_ == kMCCharMode && ISSET_BIT(color,3))
draw_mcchar(x,y,data,(color&0x7));
else
draw_char(x,y,data,color);
}
}
}
void Vic::draw_bitmap(int x, int y, uint8_t data, uint8_t color)
{
uint8_t forec = (color >> 4) & 0xf;
uint8_t bgc = color & 0xf;
for(int i=0 ; i < 8 ; i++)
{
int xoffs = x + 8 - i + horizontal_scroll();
/* don't draw outside (due to horizontal scroll) */
if(xoffs > kGFirstCol + kGResX)
continue;
/* draw pixel */
if(ISSET_BIT(data,i))
{
io_->screen_update_pixel(
xoffs,
y,
forec);
}
else
{
io_->screen_update_pixel(
xoffs,
y,
bgc);
}
}
}
void Vic::draw_mcbitmap(int x, int y, uint8_t data, uint8_t scolor, uint8_t rcolor)
{
for(int i=0 ; i < 4 ; i++)
{
/* color */
uint8_t c;
/* color source */
uint8_t cs = ((data >> i*2) & 0x3);
switch(cs)
{
case 0:
c = bgcolor_[0];
break;
case 1:
c = (scolor >> 4) & 0xf;
break;
case 2:
c = scolor & 0xf;
break;
case 3:
c = rcolor;
break;
}
int xoffs = x + 8 - i * 2 + horizontal_scroll();
io_->screen_update_pixel(
xoffs,
y,
c);
io_->screen_update_pixel(
xoffs + 1,
y,
c);
}
}
void Vic::draw_raster_bitmap_mode()
{
int rstr = raster_counter();
int y = rstr - kFirstVisibleLine;
if((rstr >= kGFirstLine) &&
(rstr < kGLastLine) &&
!is_screen_off())
{
/* draw background */
io_->screen_draw_rect(kGFirstCol,y,kGResX,bgcolor_[0]);
/* draw bitmaps */
for(int column=0; column < kGCols ; column++)
{
int x = kGFirstCol + column * 8;
int line = rstr - kGFirstLine;
int row = line/8;
int bitmap_row = line % 8;
/* retrieve bitmap data */
uint8_t data = get_bitmap_data(column,row,bitmap_row);
/* retrieve color data */
uint8_t scolor = get_screen_char(column,row);
uint8_t rcolor = get_char_color(column,row);
/* draw bitmap */
if(graphic_mode_ == kBitmapMode)
draw_bitmap(x,y,data,scolor);
else
draw_mcbitmap(x,y,data,scolor,rcolor);
}
}
}
void Vic::draw_mcsprite(int x, int y, int sprite, int row)
{
uint16_t addr = get_sprite_ptr(sprite);
for (int i=0; i < 3 ; i++)
{
uint8_t data = mem_->vic_read_byte(addr + row * 3 + i);
for (int j=0; j < 4; j++)
{
/* color */
uint8_t c = 0;
/* color source */
uint8_t cs = ((data >> j*2) & 0x3);
switch(cs)
{
/* transparent */
case 0:
break;
case 1:
c = sprite_shared_colors_[0];
break;
case 2:
c = sprite_colors_[sprite];
break;
case 3:
c = sprite_shared_colors_[1];
break;
}
/* draw if not transparent */
if(cs != 0)
{
io_->screen_update_pixel(
x + i*8 + 8 - j * 2,
y,
c);
io_->screen_update_pixel(
x + i*8 + 8 - j * 2 + 1,
y,
c);
}
}
}
}
void Vic::draw_sprite(int x, int y, int sprite, int row)
{
int swid = is_double_width_sprite(sprite) ? 2 : 1;
uint16_t addr = get_sprite_ptr(sprite);
for(int w=0; w < swid ; w++ )
{
for (int i=0; i < 3 ; i++)
{
uint8_t data = mem_->vic_read_byte(addr + row * 3 + i);
for (int j=0; j < 8; j++)
{
if(ISSET_BIT(data,j))
{
int new_x = (x+w + (i*8*swid) + (8*swid) - (j*swid)) ;
int color = sprite_colors_[sprite];
int side_border_offset = 0;
int top_border_offset = 0;
int btm_border_offset = 0;
/* check 38 cols mode */
if(!ISSET_BIT(cr2_,3))
side_border_offset = 8;
/* check 24 line mode */
if(!ISSET_BIT(cr1_,3))
{
top_border_offset = 2;
btm_border_offset = 4;
}
/* check bounds */
if(new_x <= kGFirstCol+side_border_offset ||
y < kGFirstCol + top_border_offset ||
new_x > kGResX+kGFirstCol-side_border_offset ||
y >= kGResY+kGFirstCol - btm_border_offset)
color = border_color_;
/* update pixel */
io_->screen_update_pixel(
new_x,
y,
color);
}
}
}
}
}
void Vic::draw_raster_sprites()
{
if(sprite_enabled_ != 0)
{
int rstr = raster_counter();
int y = rstr - kFirstVisibleLine;
int sp_y = rstr - kSpritesFirstLine;
/* loop over sprites reverse order */
for(int n=7; n >= 0 ; n--)
{
int height = is_double_height_sprite(n) ? kSpriteHeight * 2 : kSpriteHeight;
/* check if the sprite is visible */
if(is_sprite_enabled(n) &&
sp_y >= my_[n] &&
sp_y < my_[n] + height)
{
int row = sp_y - my_[n];
int x = kSpritesFirstCol + sprite_x(n);
if(is_double_height_sprite(n))
{
row = (sp_y - my_[n])/2;
}
if(is_multicolor_sprite(n))
{
draw_mcsprite(x,y,n,row);
}
else
{
draw_sprite(x,y,n,row);
}
}
}
}
}
// helpers ///////////////////////////////////////////////////////////////////
void Vic::raster_counter(int v)
{
raster_c_ = (uint8_t)(v&0xff);
cr1_ &= 0x7f;
cr1_ |= ((v >> 1)&0x80);
}
int Vic::raster_counter()
{
return (raster_c_ | ((cr1_&0x80) << 1));
}
/**
* @brief screen on/off
*
* Bit #4 of cr1 :
*
* 0 = Screen off, complete screen is covered by border.
* 1 = Screen on, normal screen contents are visible.
*/
bool Vic::is_screen_off()
{
return ((cr1_&(1<<4)) == 0);
}
/**
* @brief checks for bad line condition
*
* According to Christian Bauer's paper:
*
* A Bad Line Condition is given at any arbitrary clock cycle,
* if at the negative edge of 0 at the beginning of the cycle
* RASTER >= $30 and RASTER <= $f7 and the lower three bits
* of RASTER are equal to YSCROLL and if the DEN bit was set
* during an arbitrary cycle of raster line $30.
*
*/
bool Vic::is_bad_line()
{
int rstr = raster_counter();
return (rstr >= 0x30 &&
rstr <= 0xf7 &&
(rstr & 0x7) == (vertical_scroll() & 0x7));
}
/**
* @brief check if raster irq is enabled
*/
bool Vic::raster_irq_enabled()
{
return ISSET_BIT(irq_enabled_,0);
}
/**
* @brief get vertical raster scroll
*/
uint8_t Vic::vertical_scroll()
{
return(cr1_&0x7);
}
/**
* @brief get horizontal raster scroll
*/
uint8_t Vic::horizontal_scroll()
{
return(cr2_&0x7);
}
/**
* @brief check if sprite #n is enabled
*/
bool Vic::is_sprite_enabled(int n)
{
return ISSET_BIT(sprite_enabled_,n);
}
/**
* @brief check if sprite #n is in background
*/
bool Vic::is_background_sprite(int n)
{
return ISSET_BIT(sprite_priority_,n);
}
/**
* @brief check if sprite #n is double width
*/
bool Vic::is_double_width_sprite(int n)
{
return ISSET_BIT(sprite_double_width_,n);
}
/**
* @brief check if sprite #n is double height
*/
bool Vic::is_double_height_sprite(int n)
{
return ISSET_BIT(sprite_double_height_,n);
}
/**
* @brief check if sprite #n is multicolor
*/
bool Vic::is_multicolor_sprite(int n)
{
return ISSET_BIT(sprite_multicolor_,n);
}
/**
* @brief returns sprite x coordinate
*/
int Vic::sprite_x(int n)
{
int x = mx_[n];
if(ISSET_BIT(msbx_,n))
x |= 1 << 8;
return x;
}
================================================
FILE: src/vic.h
================================================
/*
* emudore, Commodore 64 emulator
* Copyright (c) 2016, Mario Ballano
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMUDORE_VIC_H
#define EMUDORE_VIC_H
#include "io.h"
#include "cpu.h"
#include "memory.h"
/**
* @brief MOS Video Interface Chip II (VIC-II)
*
* MOS 6567 NTSC
* MOS 6569 PAL
*
* This class implements the PAL version of the chip
*/
class Vic
{
private:
Memory *mem_;
Cpu *cpu_;
IO *io_;
/* sprites */
uint8_t mx_[8];
uint8_t my_[8];
uint8_t msbx_;
uint8_t sprite_enabled_;
uint8_t sprite_priority_;
uint8_t sprite_multicolor_;
uint8_t sprite_double_width_;
uint8_t sprite_double_height_;
uint8_t sprite_shared_colors_[2];
uint8_t sprite_colors_[8];
/* background and border colors */
uint8_t border_color_;
uint8_t bgcolor_[4];
/* cpu sync */
unsigned int next_raster_at_;
/* frame counter */
unsigned int frame_c_;
/* control registers */
uint8_t cr1_;
uint8_t cr2_;
/* raster */
uint8_t raster_c_;
int raster_irq_;
/* interrupt control */
uint8_t irq_status_;
uint8_t irq_enabled_;
/* screen, character memory and bitmap addresses */
uint16_t screen_mem_;
uint16_t char_mem_;
uint16_t bitmap_mem_;
uint8_t mem_pointers_;
/* helpers */
inline void raster_counter(int v);
inline int raster_counter();
inline bool is_screen_off();
inline bool is_bad_line();
inline bool raster_irq_enabled();
inline uint8_t vertical_scroll();
inline uint8_t horizontal_scroll();
inline bool is_sprite_enabled(int n);
inline bool is_background_sprite(int n);
inline bool is_double_width_sprite(int n);
inline bool is_double_height_sprite(int n);
inline bool is_multicolor_sprite(int n);
inline int sprite_x(int n);
/* graphics */
inline void draw_raster_char_mode();
inline void draw_raster_bitmap_mode();
inline void draw_raster_sprites();
inline void draw_sprite(int x, int y, int sprite, int row);
inline void draw_mcsprite(int x, int y, int sprite, int row);
inline void draw_char(int x, int y, uint8_t data, uint8_t color);
inline void draw_mcchar(int x, int y, uint8_t data, uint8_t color);
inline void draw_bitmap(int x, int y, uint8_t data, uint8_t color);
inline void draw_mcbitmap(int x, int y, uint8_t data, uint8_t scolor, uint8_t rcolor);
inline uint8_t get_screen_char(int column, int row);
inline uint8_t get_char_color(int column, int row);
inline uint8_t get_char_data(int chr, int line);
inline uint8_t get_bitmap_data(int column, int row, int line);
inline uint16_t get_sprite_ptr(int n);
inline void set_graphic_mode();
public:
Vic();
bool emulate();
void memory(Memory *v){mem_ = v;};
void cpu(Cpu *v){cpu_ = v;};
void io(IO *v){io_ = v;};
void write_register(uint8_t r, uint8_t v);
uint8_t read_register(uint8_t r);
unsigned int frames(){return frame_c_;};
/* constants */
static const int kScreenLines = 312;
static const int kScreenCols = 504;
static const int kVisibleScreenWidth = 403;
static const int kVisibleScreenHeight = 284;
static const int kFirstVisibleLine = 14;
static const int kLastVisibleLine = 298;
static const int kLineCycles = 63;
static const int kBadLineCycles = 23;
static constexpr double kRefreshRate = 1 / 50.125; // ~50Hz (PAL)
static const int kSpritePtrsOffset = 0x3f8;
/* graphic modes */
enum kGraphicMode
{
kCharMode,
kMCCharMode,
kBitmapMode,
kMCBitmapMode,
kExtBgMode,
kIllegalMode,
};
kGraphicMode graphic_mode_;
/* graphics constants */
static const int kGResX = 320;
static const int kGResY = 200;
static const int kGCols = 40;
static const int kGRows = 25;
static const int kGFirstLine = 56;
static const int kGLastLine = 256;
static const int kGFirstCol = 42;
/* sprites */
static const int kSpriteWidth = 24;
static const int kSpriteHeight = 21;
static const int kSpriteSize = 64;
static const int kSpritesFirstLine = 6;
static const int kSpritesFirstCol = 18;
};
#endif