Giter Club home page Giter Club logo

processortests's Introduction

This repository is archived, having been subdivided by test set. See https://github.com/orgs/SingleStepTests/ for its continuation.


Previous README:

ProcessorTests

This repository contains tests for a variety of processors, provided as an aid to reimplementation.

Each test:

  • requires execution of only a single instruction; and
  • provides full processor and memory state before and after.

Tests are randomly generated, in substantial volume.

Methodology

To generate each test set, an implementation is used that:

  • conforms to all available documentation, official and third-party;
  • passes all other published test sets; and
  • has been verified by usage in an emulated machine.

In addition to the standard Git history, test sets are manually versioned to permit for potential future breaking changes in JSON format.

Please report any discrepancies uncovered, either as an issue or via a correcting pull request.

Other Test Sets

For similar test sets from other, see:

processortests's People

Contributors

dbalsom avatar tomharte avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

processortests's Issues

Test case issue `5ca0` `ADD.l Q, -(A0)`

I don't understand why SSP and USP are being affected by ADD.l with A0. I checked the documentation and except for when you're using A7, I couldn't find any other rules for the stack pointer. 14 bytes are pushed on the stack while the stack shouldn't be affect at all. Could you please explain?

5ca0 [ADD.l 6, -(A0)] 1
Len = 52

==== Initial ====
D0 = 1161947774         0x4541ea7e      0b01000101 01000001 11101010 01111110
D1 = 3545793314         0xd3588322      0b11010011 01011000 10000011 00100010
D2 = 6843363    0x686be3        0b00000000011010000110101111100011
D3 = 1874953047         0x6fc18357      0b01101111 11000001 10000011 01010111
D4 = 563902468  0x219c7804      0b00100001 10011100 01111000 00000100
D5 = 1547052916         0x5c362774      0b01011100 00110110 00100111 01110100
D6 = 2579288926         0x99bcd35e      0b10011001 10111100 11010011 01011110
D7 = 2737427263         0xa329d33f      0b10100011 00101001 11010011 00111111
A0 = 2507314547         0x95729573      0b10010101 01110010 10010101 01110011
A1 = 1944242239         0x73e2c83f      0b01110011 11100010 11001000 00111111
A2 = 1816450827         0x6c44d70b      0b01101100 01000100 11010111 00001011
A3 = 3761516030         0xe0342dfe      0b11100000 00110100 00101101 11111110
A4 = 2360450905         0x8cb19f59      0b10001100 10110001 10011111 01011001
A5 = 3481664964         0xcf85fdc4      0b11001111 10000101 11111101 11000100
A6 = 965124532  0x3986a1b4      0b00111001 10000110 10100001 10110100
SSP = 2048      0x800   0b00000000000000000000100000000000
USP = 2048      0x800   0b00000000000000000000100000000000
PC = 3072       0xc00   0b00000000000000000000110000000000
SR = 9997       0x270d  0b00000000000000000010011100001101
Prefetch: 23712, 38522
[MEMORY]
12 (C) =        0       0
13 (D) =        0       0
14 (E) =        20      14
15 (F) =        0       0
5120 (1400) =   248     F8
5121 (1401) =   56      38
5122 (1402) =   3       3
5123 (1403) =   251     FB

==== Final ====
D0 = 1161947774         0x4541ea7e      0b01000101 01000001 11101010 01111110
D1 = 3545793314         0xd3588322      0b11010011 01011000 10000011 00100010
D2 = 6843363    0x686be3        0b00000000011010000110101111100011
D3 = 1874953047         0x6fc18357      0b01101111 11000001 10000011 01010111
D4 = 563902468  0x219c7804      0b00100001 10011100 01111000 00000100
D5 = 1547052916         0x5c362774      0b01011100 00110110 00100111 01110100
D6 = 2579288926         0x99bcd35e      0b10011001 10111100 11010011 01011110
D7 = 2737427263         0xa329d33f      0b10100011 00101001 11010011 00111111
A0 = 2507314543         0x9572956f      0b10010101 01110010 10010101 01101111
A1 = 1944242239         0x73e2c83f      0b01110011 11100010 11001000 00111111
A2 = 1816450827         0x6c44d70b      0b01101100 01000100 11010111 00001011
A3 = 3761516030         0xe0342dfe      0b11100000 00110100 00101101 11111110
A4 = 2360450905         0x8cb19f59      0b10001100 10110001 10011111 01011001
A5 = 3481664964         0xcf85fdc4      0b11001111 10000101 11111101 11000100
A6 = 965124532  0x3986a1b4      0b00111001 10000110 10100001 10110100
SSP = 2034      0x7f2   0b00000000000000000000011111110010
USP = 2034      0x7f2   0b00000000000000000000011111110010
PC = 5120       0x1400  0b00000000000000000001010000000000
SR = 9997       0x270d  0b00000000000000000010011100001101
Prefetch: 63544, 1019
[MEMORY]
12 (C) =        0       0
13 (D) =        0       0
14 (E) =        20      14
15 (F) =        0       0
2034 (7F2) =    92      5C
2035 (7F3) =    181     B5
2036 (7F4) =    149     95
2037 (7F5) =    114     72
2038 (7F6) =    149     95
2039 (7F7) =    111     6F
2040 (7F8) =    92      5C
2041 (7F9) =    160     A0
2042 (7FA) =    39      27
2043 (7FB) =    13      D
2044 (7FC) =    0       0
2045 (7FD) =    0       0
2046 (7FE) =    12      C
2047 (7FF) =    0       0
5120 (1400) =   248     F8
5121 (1401) =   56      38
5122 (1402) =   3       3
5123 (1403) =   251     FB

JSR high byte issue

I'm working on a 6502 based emulator, and have gotten through 74,044 tests so far, but having a strange issue with a JSR test.
I'm getting the following test failure:

Error for test (74044): 20 55 13

Instruction: JSR Absolute

Expected PC to be 0155, got 1355 for test 20 55 13
Initial state:
{"pc":379,"s":125,"a":158,"x":137,"y":52,"p":230,"ram":[[379,32],[380,85],[381,19],[341,173]]}

Final state:
{"pc":341,"s":123,"a":158,"x":137,"y":52,"p":230,"ram":[[341,173],[379,32],[380,125],[381,1]]}

Actual state:
PC:$1355  A:$9E  X:$89  Y:$34  SP:$7B  Flags:[NV-UbdIZc]

RAM Setup:
$017B: $20
$017C: $55
$017D: $13
$0155: $AD

Expected Bus Operations:

[379,32,"read"]
[380,85,"read"]
[381,19,"read"]
[381,1,"write"]
[380,125,"write"]
[381,1,"read"]

It looks like the test is expecting the JSR to disregard the high byte (or keep the same one). Is there some strange JSR or absolute addressing bug that I'm not aware of? Or am I doing something dumb in my emulator.

What it wants the PC to be at: 0x017B (379)
What it is in my emulator: 0x1355 (4949)

You can see that it reads the opcode ($20), then low byte of destination $55, then the destination high byte $13. This gives a total destination of $1355. The fact that it's jumping to $0155 makes it obvious its expecting to discard the high byte of the jump instruction, but I cannot find information anywhere online to explain what edge case would cause this wrap.

For now I've updated the test to have an expected PC of 4949.

8088 8D instruction (LEA) test has LEA r, r forms.

According to the readme, the form of the LEA instruction "LEA r, r" should not appear in the tests because it is not defined. However, there are tests of this form, such as "LEA dx, dx".

e.g.:

{
    "name": "lea dx, dx",
    "bytes": [38, 141, 210],
    "initial": {
        "regs": {
            "ax": 53822,
            "bx": 42257,
            "cx": 16234,
            "dx": 58498,
            "cs": 18747,
            "ss": 29741,
            "ds": 58434,
            "es": 25500,
            "sp": 46446,
            "bp": 58072,
            "si": 22081,
            "di": 10332,
            "ip": 40845,
            "flags": 64642
        },
        "ram": [
            [340797, 38],
            [340798, 141],
            [340799, 210],
            [340800, 144]
        ],
        "queue": []
    },
    "final": {
        "regs": {
            "ax": 53822,
            "bx": 42257,
            "cx": 16234,
            "dx": 19841,
            "cs": 18747,
            "ss": 29741,
            "ds": 58434,
            "es": 25500,
            "sp": 46446,
            "bp": 58072,
            "si": 22081,
            "di": 10332,
            "ip": 40848,
            "flags": 64642
        },
        "ram": [
            [340797, 38],
            [340798, 141],
            [340799, 210],
            [340800, 144]
        ],
        "queue": []
    },
    "cycles": [
        ["-", 340798, "CS", "R--", "---", 0, "CODE", "T2", "F", 38],
        ["-", 340798, "CS", "R--", "---", 141, "PASV", "T3", "-", 0],
        ["-", 340798, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 340799, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 340799, "CS", "R--", "---", 0, "CODE", "T2", "F", 141],
        ["-", 340799, "CS", "R--", "---", 210, "PASV", "T3", "-", 0],
        ["-", 340799, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 340800, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 340800, "CS", "R--", "---", 0, "CODE", "T2", "S", 210],
        ["-", 340800, "CS", "R--", "---", 144, "PASV", "T3", "-", 0],
        ["-", 340800, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 340801, "--", "---", "---", 0, "CODE", "T1", "-", 0]
    ]
},

68000: shift operations have incorrect flags

The C, X, and V bits appear to be wrong in a lot of cases for shift operations. Some examples:

"e327 [ASL.b D1, D7] 7"
initial d1: 0xD462DA67 d7: 0x3BBDD492
final d7: 0x3BBDD400 sr: 0x2717
Effectively 0x92 << 0x27 = 0, yet both the C and X bits are set in the final state.

"e502 [ASL.b Q, D2] 42"
intial d2: 0xAA7B9CD7
final d2: 0xAA7B9C5C sr: 0x2711
Effectively 0xD7 << 2 = 0x5C, yet the V bit is not set in the final state.

Possible wrong cycle count for NES 6502 0C and 1/3/5/7/D/FC

I've been tinkering with some NES stuff and noticed a couple of inconsistencies in my log compared to the so-called golden log: at C6C9 cycle 14602 it executes an illegal opcode 0C which takes 4 cycles according to Graham's table (next instruction EA starts executing at 14606, the registers shown are previous to executing the instruction in the same line).

C6C9  0C A9 A9 *NOP $A9A9 = A9                  A:AA X:97 Y:4E P:EF SP:F7 PPU:128,158 CYC:14602
C6CC  EA        NOP                             A:AA X:97 Y:4E P:EF SP:F7 PPU:128,170 CYC:14606

The 0c.json file only lists 3 cycles per scenario in similar cases:

{ "name": "0c a2 a9",
"initial": { "pc": 59470, "s": 214, "a": 45, "x": 25, "y": 156, "p": 170, "ram": [ [59470, 12], [59471, 162], [59472, 169], [59473, 137]]},
"final": { "pc": 59473, "s": 214, "a": 45, "x": 25, "y": 156, "p": 170, "ram": [ [59470, 12], [59471, 162], [59472, 169], [59473, 137]]}, 
"cycles": [ [59470, 12, "read"], [59471, 162, "read"], [59472, 169, "read"]] },

The same table mentions that 1C, 3C, 5C, 6C, DC and FC all require 4 or 5 cycles, the extra one is added if the address crosses a page boundary, however in these files there are always 4 cycles listed.

It's literally impossible to find information for the NES specifically but I found other instances like 6502 Undocumented Opcodes from 1997 based on the Atari 8-bit 6502 which quotes a list by Joakim Atterhal and Freddy Offenga published in the Atari 8-bit disk magazine "Mega Maga-zine" issue 6, Extra Instructions Of The 65XX Series CPU based on Commodore 64 from 1995 where it mentions having used "The Complete Inner Space Anthology" by Karl J H Hildon from 1984-85 (found some old scans of page 22 which list the codes but not the cycles and quotes a couple of articles by Grainger and Raeto Collin West back in 1981), and No More Secrets PDF from 2020 which borrows heavily from the previous documents (which also mentions it's focused on Commodore 64).

From "Extra Instructions Of The 65XX Series CPU":

SKW    ***
SKW skips next word (two bytes).
Opcodes: 0C, 1C, 3C, 5C, 7C, DC, FC.
Takes 4 cycles to execute.

To be dizzyingly precise, SKW actually performs a read operation.  It's 
just that the value read is not stored in any register.  Further, opcode 0C 
uses the absolute addressing mode.  The two bytes which follow it form the 
absolute address.  All the other SKW opcodes use the absolute indexed X 
addressing mode.  If a page boundary is crossed, the execution time of one 
of these SKW opcodes is upped to 5 clock cycles.

A few other routes mention findings rooting back Wolfgang Lorenz and his test suite for Commodore 64 and its MOS6510, however these aren't 100% compatible with 6502. I'm not sure if the files in your tests are correct or if they need to be modified but as I'm trying to emulate the NES as close as possible I will add an extra directive to decide whether I want 100% test compatibility or 100% nestest compatibility.

Great job with the set, it absolutely helped me nail a CPU emulator in one try using TDD!

WDC 65C02 STZ issue

Hello --

While testing against my in development 65C02 core, I noticed that the STZ opcode tests have no way of knowing if the zero was actually written if you are ignoring the memory read/write cycles due to the memory being initialized to zero already. Here is an example test:

{ "name": "64 eb 28", "initial": { "pc": 43470, "s": 126, "a": 172, "x": 181, "y": 204, "p": 45, "ram": [ [43470, 100], [43471, 235], [43472, 40]]}, "final": { "pc": 43472, "s": 126, "a": 172, "x": 181, "y": 204, "p": 45, "ram": [ [235, 0], [43470, 100], [43471, 235], [43472, 40]]}, "cycles": [ [43470, 100, "read"], [43471, 235, "read"], [235, 0, "write"]] },

In this example, the final values of memory do include memory address 235 being set to 0. But the initial RAM values do not initialize it to anything besides 0. I was able to fool the test in this case by just reading the zero page address and doing nothing, which is definitely not a valid way of implementing this instruction.

For these instructions, can an initial value that is non-zero be specified in the RAM location the STZ opcode is being tested on? I can also work around this by randomizing the contents of my RAM before running tests, but this means the testing is non-deterministic and will also take longer to run due to initializing 64KB of memory to random values for each test.

Thanks!

Something wrong with the 680x0 tests or I don't undestand how it works?

I'm very confused, please help me understand.
The first test I tried for 680x0 in ABCD.json looks confusing.
It is testing "ABCD.B -(A5),-(A6)"
The initial A5 is 281750813 and A6 is 270492367.
The initial and final memory sections do not specify the values of the addresses 281750813 or 270492367 so I don't know how the information in the JSON helps to test this instruction.
The memory sections do however specify value of some other random address 2056910 (not referenced by any of the initial registers) with the initial and final values being different (but this is no where near where A6 is pointing to)
The final values for A5 and A6 have correctly been decremented but the "transaction" section indicates that it does not read from the addresses they point to.
Instead it says there is a read from 13315356 and 2056910 then a write to 2056910.
I assume the initial A5 should be 13315356 and the initial A6 should be 2056910 or the memory/transaction sections should be referencing 281750813 and 270492367?
Is there some kind of masking that needs to be applied to A5 and A6 before the test is run?

Thanks

65816 opcode 0x35

It seems there might be an issue with opcode 0x35 in emulation mode. The test cases expect the page to always wrap but it was only supposed to when the lower byte of the direct page register is 0x00. This seems to match what bsnes does (by the looks of the code). Also, I found some documentation that leads to the same conclusion:

http://www.6502.org/tutorials/65c816opcodes.html

5.11 (DIRECT,X)
Length: 2 bytes, $OP $LL

(direct,X) addressing uses a 16-bit pointer. When the e flag is 1 and the DL register is $00 (both conditions must be met), the address of the pointer is:

+-----------+-----------+-----------+
!     0     !    DH     !   $LL+X   ! pointer lo
+-----------+-----------+-----------+
+-----------+-----------+-----------+
!     0     !    DH     !  $LL+X+1  ! pointer hi
+-----------+-----------+-----------+

github org for tests?

This repo is getting a bit huge; and I will have another set to contribute soon which is going to make it even bigger.

What would you think about making a GitHub organization for the CPU tests and having each architecture in its own repo? That would reduce the requirement for people to check out multiple gigabytes, and modifications/updates to one set/repo wouldn't bloat all of them.

68000 test generation and random data

Looking at the 68000 tests, it seems that the initial state of the CPU for each test is seemingly random. I don't seem to find the generator (I guess it's not public), so I am not exactly sure "how much random" it is: whether all registers are random, or some are tweaked from an initial random state to reproduce specific behaviors to be tested.

I am trying to run the tests on embedded devices and this is proving a big complex because of the sheer size of the test vectors. I don't mind them being big as in "many tests" (could use even more!), but the problem is that the test data itself is very badly compressible because the initial/final state is really full of random numbers.

I was wondering if, in general, it would be possible to make public the PRNG algorithm used to generate the random initial state, and maybe put the seed for the PRNG in each test. If each test contained the seed used to generate its initial state (and the PRNG was documented), I could in theory regenerate the state from the seed only, without having to embed it altogether. If the initial state was then tweaked a bit after the PRNG pass, I could store just the differences, which would probably be much smaller.

Does this make any sense?

65816: Incorrect final address for instructions with stack-relative addressing in emulation mode

For example, in test "03 e 10000" (which is ORA d, S), S is $0143, the operand is $31,
so the resultant address should be $0174, but the test instead expects $b374. AFAICU
stack-relative addressing does not have any page wrapping rules (vs. e.g. direct page
relative), and I don't see how one would arrive at page $b3 anyway.

Worth noting that all of the native mode tests for stack-relative instructions are fine, only
emulation mode tests are affected.

Relevant part of test:

"initial": {
    ...
    "s": 323,
    ...
},
...
"cycles": [
    [16255905, 3, "dp-remx-"],
    [16255906, 49, "-p-remx-"],
    [16255906, null, "---remx-"],
    [45940, 78, "d--remx-"]
]

My test suite runner output:
image

Possibly wrong test case d133 [ADD.b D0, (d8, A3, Xn)]

Here's the test case. The problem is basically that I cannot even manually figure out how 13367077 is calculated, I cannot figure out the unmasked value.
Judging by the eighth bit of the second prefetch value (15214), we have a full-extension word to deal with. For some reason, I/IS bits map to a reserved combination! And when I read the next long word (judging by index size), and add all of that up, I can't get the result.

d133 [ADD.b D0, (d8, A3, Xn)] 1
Len = 18

==== Initial ====
D0 = 2308435391 	0x8997edbf 	0b10001001 10010111 11101101 10111111 
D1 = 1060694383 	0x3f38e96f 	0b00111111 00111000 11101001 01101111 
D2 = 144798559 		0x8a1735f 	0b00001000 10100001 01110011 01011111 
D3 = 1114670029 	0x427083cd 	0b01000010 01110000 10000011 11001101 
D4 = 3546817942 	0xd3682596 	0b11010011 01101000 00100101 10010110 
D5 = 3017016069 	0xb3d40305 	0b10110011 11010100 00000011 00000101 
D6 = 157945861 		0x96a1005 	0b00001001 01101010 00010000 00000101 
D7 = 3531664314 	0xd280ebba 	0b11010010 10000000 11101011 10111010 
A0 = 1707790453 	0x65cad075 	0b01100101 11001010 11010000 01110101 
A1 = 3858677903 	0xe5fec08f 	0b11100101 11111110 11000000 10001111 
A2 = 3797006336 	0xe251b800 	0b11100010 01010001 10111000 00000000 
A3 = 2874897130 	0xab5b72ea 	0b10101011 01011011 01110010 11101010 
A4 = 3126142618 	0xba55269a 	0b10111010 01010101 00100110 10011010 
A5 = 271034980 		0x1027aa64 	0b00010000 00100111 10101010 01100100 
A6 = 2663102061 	0x9ebbb66d 	0b10011110 10111011 10110110 01101101 
SSP = 2048 		0x800 	0b00000000000000000000100000000000
USP = 2048 		0x800 	0b00000000000000000000100000000000
PC = 3072 		0xc00 	0b00000000000000000000110000000000
SR = 9993 		0x2709 	0b00000000000000000010011100001001
Prefetch: 53555, 15214	0x3B6E		0b00111011 01101110
[MEMORY]
3079 = 160	A0	41206
3078 = 246	F6	
13367077 = 228	E4
3077 = 181	B5
3076 = 237	ED	46573	87779	175558

==== Final ====
D0 = 2308435391 	0x8997edbf 	0b10001001 10010111 11101101 10111111 
D1 = 1060694383 	0x3f38e96f 	0b00111111 00111000 11101001 01101111 
D2 = 144798559 		0x8a1735f 	0b00001000 10100001 01110011 01011111 
D3 = 1114670029 	0x427083cd 	0b01000010 01110000 10000011 11001101 
D4 = 3546817942 	0xd3682596 	0b11010011 01101000 00100101 10010110 
D5 = 3017016069 	0xb3d40305 	0b10110011 11010100 00000011 00000101 
D6 = 157945861 		0x96a1005 	0b00001001 01101010 00010000 00000101 
D7 = 3531664314 	0xd280ebba 	0b11010010 10000000 11101011 10111010 
A0 = 1707790453 	0x65cad075 	0b01100101 11001010 11010000 01110101 
A1 = 3858677903 	0xe5fec08f 	0b11100101 11111110 11000000 10001111 
A2 = 3797006336 	0xe251b800 	0b11100010 01010001 10111000 00000000 
A3 = 2874897130 	0xab5b72ea 	0b10101011 01011011 01110010 11101010 
A4 = 3126142618 	0xba55269a 	0b10111010 01010101 00100110 10011010 
A5 = 271034980 		0x1027aa64 	0b00010000 00100111 10101010 01100100 
A6 = 2663102061 	0x9ebbb66d 	0b10011110 10111011 10110110 01101101 
SSP = 2048 		0x800 	0b00000000000000000000100000000000
USP = 2048 		0x800 	0b00000000000000000000100000000000
PC = 3076 		0xc04 	0b00000000000000000000110000000100
SR = 10009 		0x2719 	0b00000000000000000010011100011001
Prefetch: 60853, 63136
[MEMORY]
3079 = 160
3078 = 246
13367077 [0xCBF725] = 163
3077 = 181
3076 = 237

P.S. I asked this question on StackOverflow https://stackoverflow.com/questions/77305157/figuring-out-how-a-motorola-68k-test-case-with-add-b-and-full-extension-word-pas

65816: Emulation mode stack wrapping

Stack Operations Tests

Since all of these instructions (PLD, RTL, PHD, PER, PEI, PEA, JSL) are "new" instructions and deal with page wrapping in emulation mode, I've combined them all into a single issue. These tests check to see if the 2- or 3-byte value pushed in emulation mode page wraps or not. Each test shows the source code and the relevant memory dump(s) before and after each case is run. Each test indicates that these should not page wrap, contrary to the expected behavior of as of commit 96c2c8a. (Not wrapping is consistent with this source)
If you see a mistake in my testing, let me know and I can re-run the tests.

Test results for PLD

Test condition: "2b e xx"
Verdict: PLD does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; TEST: "2b e xx"
    ldx #$fe                    ; SP = $1fe
    txs
    lda #1
    sta |$101                   ; 1
    inc
    sta |$100                   ; 2
    inc
    sta |$ff                    ; 3
    inc
    sta |$201                   ; 4
    inc
    sta |$200                   ; 5
    inc
    sta |$1ff                   ; 6
    pld

    ldx #$f0                    ; "non-controversial" value (no stack wrapping)
    txs
    phd
    plx
    pla
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    stx $202                    ; Here's our value to look at
    sta $203
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 FE 9A  ..H.. ;....8....
000010: A9 01 8D 01 01 1A 8D 00  01 1A 8D FF 00 1A 8D 01  ................
000020: 02 1A 8D 00 02 1A 8D FF  01 2B A2 F0 9A 0B FA 68  .........+.....h
000030: 18 FB 8E 80 00 8D 81 00  C2 20 AF 00 10 00 1B 6B  ......... .....k
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
249
[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 FE 9A  ..H.. ;....8....
000010: A9 01 8D 01 01 1A 8D 00  01 1A 8D FF 00 1A 8D 01  ................
000020: 02 1A 8D 00 02 1A 8D FF  01 2B A2 F0 9A 0B FA 68  .........+.....h
000030: 18 FB 8E 80 00 8D 81 00  C2 20 AF 00 10 00 1B 6B  ......... .....k
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 06 05 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 03  ................
000100: 02 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 06  ................
0001F0: 05 00 00 00 00 00 00 00  00 00 00 00 00 00 00 06  ................
000200: 05 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test results for RTL

Test condition: "6b e xx"
Verdict: RTL does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; TEST: "6b e xx"
    ldx #$ff                    ; SP = $1ff
    txs
    lda #$20-1                  ; If rtl does not wrap, will return to $220
    sta |$200
    lda #$02
    sta |$201
    lda #0
    sta |$202
    lda #$10-1                  ; If rtl does wrap, will return to $110
    sta |$100
    lda #$01
    sta |$101
    lda #0
    sta |$102
    rtl
    
    ;; EXIT EMULATION MODE
cleanup:    
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    txa                         ; Get return value
    rtl                         ; MONITOR prints A on return

    .org $110
    .xs
    ldx #$1
    jmp cleanup

    .org $220
    .xs
    ldx #$2
    jmp cleanup

Hardware trace:

[ ZEDIAC ] > 0.220
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 FF 9A  ..H.. ;....8....
000010: A9 1F 8D 00 02 A9 02 8D  01 02 A9 00 8D 02 02 A9  ................
000020: 0F 8D 00 01 A9 01 8D 01  01 A9 00 8D 02 01 6B 18  ..............k.
000030: FB C2 20 AF 00 10 00 1B  8A 6B 00 00 00 00 00 00  .. ......k......
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: A2 01 4C 2F 00 00 00 00  00 00 00 00 00 00 00 00  ..L/............
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000210: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000220: A2 02 4C 2F 00 00 00 00  00 00 00 00 00 00 00 00  ..L/............

[ ZEDIAC ] > gosub 0 <-- JSL 0
2                    <-- Value in A

Test results for PHD

Test condition: "0b e 15"
Verdict: PHD does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    lda #$26
    sta $180
    lda #$d8
    sta $181
    ldx #$7f                    ; SP = $017f
    txs
    pld                         ; Get the D value
    ldx #$00
    txs
    phd                         ; 
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A9 26 8D  ..H.. ;....8..&.
000010: 80 01 A9 D8 8D 81 01 A2  7F 9A 2B A2 00 9A 0B 18  ..........+.....
000020: FB C2 20 AF 00 10 00 1B  6B 00 00 00 00 00 00 00  .. .....k.......
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
0
[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A9 26 8D  ..H.. ;....8..&.
000010: 80 01 A9 D8 8D 81 01 A2  7F 9A 2B A2 00 9A 0B 18  ..........+.....
000020: FB C2 20 AF 00 10 00 1B  6B 00 00 00 00 00 00 00  .. .....k.......
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 26  ...............&
000100: D8 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 26 D8 00 00 00 00 00 00  00 00 00 00 00 00 00 00  &...............
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test results for PER

Test condition: "62 e xx"
Verdict: PER does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; "62 e xx"
    ldx #$00
    txs
    per $76ae
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 00 9A  ..H.. ;....8....
000010: 62 AE 76 18 FB C2 20 AF  00 10 00 1B 6B 00 00 00  b.v... .....k...
000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
249
[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 00 9A  ..H.. ;....8....
000010: 62 AE 76 18 FB C2 20 AF  00 10 00 1B 6B 00 00 00  b.v... .....k...
000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 C1  ................
000100: 76 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  v...............
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test results for PEI

Test condition: "d4 e xx"
Verdict: PEI does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; "d4 e xx"
    lda #$30
    sta $f0
    lda #$56
    sta $f1
    
    ldx #$00
    txs
    pei ($f0)
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A9 30 85  ..H.. ;....8..0.
000010: F0 A9 56 85 F1 A2 00 9A  D4 F0 18 FB C2 20 AF 00  ..V.......... ..
000020: 10 00 1B 6B 00 00 00 00  00 00 00 00 00 00 00 00  ...k............
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
249
[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A9 30 85  ..H.. ;....8..0.
000010: F0 A9 56 85 F1 A2 00 9A  D4 F0 18 FB C2 20 AF 00  ..V.......... ..
000020: 10 00 1B 6B 00 00 00 00  00 00 00 00 00 00 00 00  ...k............
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 30  ...............0
000100: 56 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  V...............
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test results for PEA

Test condition: "f4 e 790"
Verdict: PEA does not page wrap

Source code:

stack_save  .equ $1000
    .as

    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; "f4 e 790"
    ldx #$00
    txs
    pea $648c
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 00 9A  ..H.. ;....8....
000010: F4 8C 64 18 FB C2 20 AF  00 10 00 1B 6B 00 00 00  ..d... .....k...
000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
249
[ ZEDIAC ] > 0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 00 9A  ..H.. ;....8....
000010: F4 8C 64 18 FB C2 20 AF  00 10 00 1B 6B 00 00 00  ..d... .....k...
000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 8C  ................
000100: 64 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  d...............
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test results for JSL

Test condition: "22 e xx"
Verdict: JSL does page wrap

Source code:

stack_save  .equ $1000
    .as

    .org $40000
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; "22 e xx"
    ldx #$01
    txs
    jsl $20134
    
    .org $134                   ; Will be placed into correct bank on load

    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 40000.40010
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
040000: A9 00 48 AB C2 20 3B 8F  00 10 00 38 FB A2 01 9A  ..H.. ;....8....
040010: 22 34 01 02 00 00 00 00  00 00 00 00 00 00 00 00  "4..............

[ ZEDIAC ] > 20134
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
020130: 00 00 00 00 18 FB C2 20  AF 00 10 00 1B 6B 00 00  ....... .....k..

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 40000
249
[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 13  ................
000100: 00 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Bad ADC test(s) for OP 0x69 (immediate addressing)

Given this test case:

{
    "name": "69 0a e1",
    "initial": {
      "pc": 23290,
      "s": 148,
      "a": 2,
      "x": 112,
      "y": 254,
      "p": 175,
      "ram": [
        [
          23290,
          105
        ],
        [
          23291,
          10
        ],
        [
          23292,
          225
        ]
      ]
    },
    "final": {
      "pc": 23292,
      "s": 148,
      "a": 19,
      "x": 112,
      "y": 254,
      "p": 44,
      "ram": [
        [
          23290,
          105
        ],
        [
          23291,
          10
        ],
        [
          23292,
          225
        ]
      ]
    },
    "cycles": [
      [
        23290,
        105,
        "read"
      ],
      [
        23291,
        10,
        "read"
      ]
    ]
  }

The accumulator should be set to ram[23291] + a + c, which is 10 + 2 + 0. Can someone explain why the expected value for the a register is 19 and not 12?

Info about 68000 test suite

Hi and first of all thanks for your hard work.
I'm using your tests for a 68000 emulator, and I'm testing ADD instruction.
In ADD.w.json.gz there are some tests that have some "strange" final state.
For example:

  • d850 [ADD.w (A0), D4] 32

Here PC starts from 3072 and finishes to 5120, and the transaction list suggests that some kind of pushes on the stack happened.
Can you explain me how this test must be interpreted ?

Other tests, like d244 [ADD.w D4, D1] 8065 don't have this behaviour.

Thanks in advance.

The 6502 tests assume the P register has bits 4 & 5.

It doesn't. They just don't exist. Bit 5 is hardwired to 1 where it matters, bit 4 to !irq_taken (only visible in the pushed P value in brk).

So any test that requires a result in P that has bits 4 or 5 unset in incorrect (and there's a lot of them). A or with 0x30 would clean them up (and doing that to the inputs too would be a decent idea).

68000: Suggestion for additional DIVS/DIVU test cases

I believe there are currently no test cases for either DIVS or DIVU where the quotient is zero. If I modify my 68k DIVS and DIVU implementations to hardcode the Z flag to false, it still passes all of the DIVS and DIVU test cases.

I noticed this because I had a silly bug in my implementation where I was setting the Z flag based on the final 32-bit value written back to the register, when as I understand it the correct behavior is to set the Z flag purely based on the 16-bit quotient.

As an example, here is a mostly hand-crafted test case for DIVU that failed in my implementation before the bugfix (minus the bus transactions which I don't currently have a way to generate easily):

{
  "name": "80c1 [DIVU D1, D0] xxxx",
  "initial": {
    "d0": 1,
    "d1": 5,
    "d2": 0,
    "d3": 0,
    "d4": 0,
    "d5": 0,
    "d6": 0,
    "d7": 0,
    "a0": 0,
    "a1": 0,
    "a2": 0,
    "a3": 0,
    "a4": 0,
    "a5": 0,
    "a6": 0,
    "usp": 2763053352,
    "ssp": 2048,
    "sr": 9985,
    "pc": 3072,
    "prefetch": [
      32961,
      40692
    ],
    "ram": [
      [
        3077,
        228
      ],
      [
        3076,
        74
      ]
    ]
  },
  "final": {
    "d0": 65536,
    "d1": 5,
    "d2": 0,
    "d3": 0,
    "d4": 0,
    "d5": 0,
    "d6": 0,
    "d7": 0,
    "a0": 0,
    "a1": 0,
    "a2": 0,
    "a3": 0,
    "a4": 0,
    "a5": 0,
    "a6": 0,
    "usp": 2763053352,
    "ssp": 2048,
    "sr": 9988,
    "pc": 3074,
    "prefetch": [
      40692,
      19098
    ],
    "ram": [
      [
        3077,
        228
      ],
      [
        3076,
        74
      ]
    ]
  },
  "length": 136,
  "transactions": []
}

8088 - F6.7 issues

I found some issues with F6.7. It's a long story, but basically I was using MartyPC to fill in the register state after divide exceptions since the test rig didn't handle them at the time, but MartyPC had a regression in 8 bit signed division. Here's the PR with the fix:

#73

6502 CMOS (rockwell and WDC) have incorrect tests for BBR/BBS?

I've been running the tests on my impl (https://github.com/jmchacon/rusty6502) and everything on the base 6502 and NES variant I have in 100% agreement and that also lines up with my understanding of the chips too.

CMOS is a different story. Specifically 0x0f and the corresponding copies for BBR0-7/BBS0-7. For this example let's look at the first entry for 0f.json:

wdc65c02/v1/0f.json

{ "name": "0f f4 b5", "initial": { "pc": 41715, "s": 119, "a": 58, "x": 163, "y": 251, "p": 225, "ram": [ [41715, 15], [41716, 244], [41717, 181], [244, 253], [41643, 230], [41718, 31]]}, "final": { "pc": 41718, "s": 119, "a": 58, "x": 163, "y": 251, "p": 225, "ram": [ [244, 253], [41643, 230], [41715, 15], [41716, 244], [41717, 181], [41718, 31]]}, "cycles": [ [41715, 15, "read"], [41716, 244, "read"], [244, 253, "read"], [244, 253, "write"], [41717, 181, "read"], [41643, 230, "read"]] },

This is

BBR0 0xf4,0xb5 which would jump if bit0 is clear at location 0xF4 which it's not since it's 0xFD. The final state seems to confirm that as the PC is set to the next instruction and didn't jump.

The cycles sequence doesn't make sense here though due to the write on cycle4. No part of this instruction ever writes back to RAM. It's a load instruction, not store or RMW. This appears to be accurate but just slipped a write in after the ZP read. Otherwise it's correct if I remove the write. Additionally a missed branch is 5 cycles, not 6 like this is claiming which is also confusing.

While I agree there are lots of errors in docs out there I'm basing this on

https://web.archive.org/web/20141129202001if_/http://archive.6502.org/datasheets/wdc_w65c02s_feb_2004.pdf

which on page 33 shows the sequence WDC documented for this instruction (9b) which lines up with other testing I've done (
Klaus Dormann's functional tests I can pass all the CMOS related ones which does test BBR/BBS).

So it looks like if I stripped all the extra write cycles from these instructions things work as I expect. Is this just a bug in the generation code?

More processors

This is a really interesting project. I'd love see some more processor variants. In particular, the 65C02 processors used in Apple II computers are not represented here. They used NCR and GTE vendor chips which do not include the Rockwell extensions. This looks like the feature set of Synertek but NCR/GTE undefined NOPs have different byte/cycle counts and SBC behaves differently with invalid BCD. Those processors would be very helpful for people working on Apple II emulators. Even MAME could use some assistance here.

It's also worth noting that there are two or three WDC variants, maybe more. WDC and 65C02 documentation in general is lacking and what exists is riddled with errors. The WDC currently in the collection appears to be a later W65C02S but I do not have one to verify this. Earlier versions do not include the Rockwell RMB/SMB/BBR/BBS instructions. It's unclear if there is WDC version without WAI/STP.

Some more information about your profiling method would welcome too. Maybe it can be reproduced and more profiles can be sourced. I have on hand a GTE, NCR, and what appears to be an early WDC (markings removed).

[68000] RTS tests broken

First of all, thank you very much for providing these tests. They are super helpful.

It seems the RTS test set contains a number of broken test instances, e.g. the following test where the cpu is in supervisor mode according to sr flags.

{
	"name": "4e75 [RTS] 2",
	"initial": {
		...
		"usp": 4079683792,
		"ssp": 2048,
		"sr": 10014,
		"pc": 3072,
		"prefetch": [20085, 25783],
		"ram": [
			[5123, 17],
			[5122, 64],
			[15, 0],
			[5121, 50],
			[12, 0],
			[14, 20],
			[5120, 11],
			[2051, 177],
			[2050, 57],
			[2049, 60],
			[13, 0],
			[2048, 82]
		]
	},
	"final": {
		...
		"usp": 4079683792,
		"ssp": 2038,
		"sr": 10014,
		"pc": 5120,
		"prefetch": [2866, 16401],
		"ram": [
			[13, 0],
			[12, 0],
			[5123, 17],
			[2041, 60],
			[5122, 64],
			[2040, 82],
			[5121, 50],
			[15, 0],
			[2039, 126],
			[2043, 177],
			[2042, 57],
			[2045, 117],
			[2044, 78],
			[2047, 30],
			[2046, 39],
			[2051, 173],
			[2050, 57],
			[5120, 11],
			[14, 20],
			[2038, 78],
			[2049, 60],
			[2048, 82]
		]
	},
	"length": 58,
	"transactions": [
		["r", 4, 5, 2048, ".w", 21052],
		["r", 4, 5, 2050, ".w", 14769],
		["n", 4],
		["w", 4, 5, 2050, ".w", 14765],
		["w", 4, 5, 2046, ".w", 10014],
		["w", 4, 5, 2048, ".w", 21052],
		["w", 4, 5, 2044, ".w", 20085],
		["w", 4, 5, 2042, ".w", 14769],
		["w", 4, 5, 2038, ".w", 20094],
		["w", 4, 5, 2040, ".w", 21052],
		["r", 4, 5, 12, ".w", 0],
		["r", 4, 5, 14, ".w", 5120],
		["r", 4, 6, 5120, ".w", 2866],
		["n", 2],
		["r", 4, 6, 5122, ".w", 16401]
	]
}

First observation is that the length of the ram list is different and RTS is only modifying stack, pipeline, and registers, but not memory. Second observation is that there are write operations on the bus, which is a bit puzzling since the RTS operation is defined as following:

RTS Return from subroutine
Operation: [PC] ← [M([SP])]; [SP] ← [SP] + 4

When RTS is executed in this example, it fetches a long word, ie. 32 bits, from the address given by sp = 2038. The four bytes [82, 60, 57, 177] resemble return address 1379678641 which is not in the defined list of bytes in RAM.

(updated) Also, the length field seems off. According to documents, RTS has a cycle length of 16 including four read and no write cycles.

68k: AS* mismatches

Hello,
I'm getting two mismatches on ASL.b

e502 [ASL.b Q, D2] 1583
00000c00   e502                    asl.b    #2,d2 -- ERROR
Before: M68kState{sr=2719, pc=c00, ssp=800, usp=8f96b0a8, dr=[1827813764, 213778177, -839155778, 1049586149, -1040763541, -258789033, 238544516, 1163355290], ar=[545868555, -701803095, -881996606, 1486947959, 563825081, -38659912, 9105645, 2048]}
Expect: M68kState{sr=2713, pc=c02, ssp=800, usp=8f96b0a8, dr=[1827813764, 213778177, 777929476, 1049586149, -1040763541, -258789033, 238544516, 1163355290], ar=[545868555, -701803095, -881996606, 1486947959, 563825081, -38659912, 9105645, 2048]}
Actual: M68kState{sr=270a, pc=c02, ssp=800, usp=8f96b0a8, dr=[1827813764, 213778177, -839155720, 1049586149, -1040763541, -258789033, 238544516, 1163355290], ar=[545868555, -701803095, -881996606, 1486947959, 563825081, -38659912, 9105645, 2048]}
e502 [ASL.b Q, D2] 1761
00000c00   e502                    asl.b    #2,d2 -- ERROR
Before: M68kState{sr=271d, pc=c00, ssp=800, usp=dd237ce8, dr=[488523955, 669019593, 1098677885, 1398387187, 2118766331, -553387108, -1665121616, -557413159], ar=[-143103158, -1628924744, -134659976, -257297366, -2099023861, -1070168898, 334647008, 2048]}
Expect: M68kState{sr=271b, pc=c02, ssp=800, usp=dd237ce8, dr=[488523955, 669019593, 1684132752, 1398387187, 2118766331, -553387108, -1665121616, -557413159], ar=[-143103158, -1628924744, -134659976, -257297366, -2099023861, -1070168898, 334647008, 2048]}
Actual: M68kState{sr=271b, pc=c02, ssp=800, usp=dd237ce8, dr=[488523955, 669019593, 1098678004, 1398387187, 2118766331, -553387108, -1665121616, -557413159], ar=[-143103158, -1628924744, -134659976, -257297366, -2099023861, -1070168898, 334647008, 2048]}

68000 CMPM address register updated before address error?

Consider this test case. A4 is odd, so there's an address error. Yet, the "final" value is incremented by 2, as if the post increment happened before or in parallel with the memory access. Is this known to be the case on real hardware?

{ "name": "b74c [CMP.w (A4)+, (A3)+] 6",
  "initial":
    {"d0": 3616035900,
     "d1": 4244842335,
     "d2": 3804844838,
     "d3": 2486760049,
     "d4": 2154476239,
     "d5": 2057425795,
     "d6": 3717306163,
     "d7": 806500645,
     "a0": 2013264249,
     "a1": 2727369354,
     "a2": 3820627603,
     "a3": 3490029285,
     "a4": 900360119,
     "a5": 1926964183,
     "a6": 2103704679,
     "usp": 882354928,
     "ssp": 2048,
     "sr": 9985,
     "pc": 3072,
     "prefetch": [46924, 41774],
     "ram": [[5123, 95], [5122, 244], [5121, 175], [5120, 52], [15, 0], [14, 20], [13, 0], [12, 0]]},
  "final":
    {"d0": 3616035900,
     "d1": 4244842335,
     "d2": 3804844838,
     "d3": 2486760049,
     "d4": 2154476239,
     "d5": 2057425795,
     "d6": 3717306163,
     "d7": 806500645,
     "a0": 2013264249,
     "a1": 2727369354,
     "a2": 3820627603,
     "a3": 3490029285,
     "a4": 900360121,
     "a5": 1926964183,
     "a6": 2103704679,
     "usp": 882354928,
     "ssp": 2034,
     "sr": 9985,
     "pc": 5120,
     "prefetch": [13487, 62559],
     "ram": [[13, 0], [2037, 170], [12, 0], [2036, 53], [2035, 85], [5121, 175], [15, 0], [2039, 183], [5120, 52], [14, 20], [2038, 103], [5123, 95], [2041, 76], [5122, 244], [2040, 183], [2034, 183], [2045, 0], [2044, 0], [2043, 1], [2042, 39], [2047, 0], [2046, 12]]},
  "length": 50,
  "transactions":
    [["n", 4],
     ["w", 4, 5, 2046, ".w", 3072],
     ["w", 4, 5, 2042, ".w", 9985],
     ["w", 4, 5, 2044, ".w", 0],
     ["w", 4, 5, 2040, ".w", 46924],
     ["w", 4, 5, 2038, ".w", 26551],
     ["w", 4, 5, 2034, ".w", 46933],
     ["w", 4, 5, 2036, ".w", 13738],
     ["r", 4, 5, 12, ".w", 0],
     ["r", 4, 5, 14, ".w", 5120],
     ["r", 4, 6, 5120, ".w", 13487],
     ["n", 2],
     ["r", 4, 6, 5122, ".w", 62559]]},

65816: (dp,x) emulation mode page wrapping

(dp,x) emulation mode page wrapping

According to this, the (dp,x) addressing mode should only page wrap "When the e flag is 1 and the DL register is $00 (both conditions must be met)." This behavior is supported by the hardware tests below.
The ProcessorTests (as of commit 96c2ca8) does not follow this logic. Take for example test "01 e 3". D=$d873 (DL=$73), X=$dd, and the dp index (operand) is $19. The address should not be wrapped since DL != 0, resulting in a pointer address of $d969. The test case, however page wraps and places the pointer at $d869. From what I can tell, this affects every instruction which allows the (dp,x) addressing mode.

Hardware test results for DL != 0

Test condition: "01 e xx"
Verdict: (dp,x) does not page wrap (resulting value for test in address $102 is $F5)

Source code:

DREG        .equ $70f1          ; From the "01 e 4" test case
;; DREG        .equ $7000
    
stack_save  .equ $1000

    .as
    .org 0
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #DREG
    pha
    pld
    lda #$0100                  ; Address
    sta DREG+$24+$fa            ; Assuming no bank wrapping
    lda #$0101                  ; Address
    sta {DREG & $ff00} | {{{DREG & $ff}+$24+$fa} & $ff} ; Assuming bank wrapping
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; TEST: "01 e xx"
    lda #$a0
    sta $100
    lda #$0a
    sta $101

    ldx #$fa

    lda #$55
    ora ($24,x)
    sta $102
    tax                         ; Save return value
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    lda >stack_save             ; Restore stack
    tcs
    txa                         ; Get return value
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0.3c
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 A9 F1 70 48 2B  ..H.. ;......pH+
000010: A9 00 01 8D 0F 72 A9 01  01 8D 0F 70 38 FB A9 A0  .....r.....p8...
000020: 8D 00 01 A9 0A 8D 01 01  A2 FA A9 55 01 24 8D 02  ...........U.$..
000030: 01 AA 18 FB C2 20 AF 00  10 00 1B 8A 6B 00 00 00  ..... ......k...

[ ZEDIAC ] > 100
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7000.7010
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
007010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7200.7210
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
007210: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
245
[ ZEDIAC ] > 100
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000100: A0 0A F5 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7000.7010
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 01  ................
007010: 01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7200.7210
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
007210: 01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Hardware test results for DL == 0

Test condition: "01 e xx"
Verdict: (dp,x) does page wrap (resulting value for test in address $102 is $5f)

Source code:
<same as above, except that DREG is set to $7000>

Hardware trace:

[ ZEDIAC ] > 0.3c
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 00 48 AB C2 20 3B 8F  00 10 00 A9 00 70 48 2B  ..H.. ;......pH+
000010: A9 00 01 8D 1E 71 A9 01  01 8D 1E 70 38 FB A9 A0  .....q.....p8...
000020: 8D 00 01 A9 0A 8D 01 01  A2 FA A9 55 01 24 8D 02  ...........U.$..
000030: 01 AA 18 FB C2 20 AF 00  10 00 1B 8A 6B 00 00 00  ..... ......k...

[ ZEDIAC ] > 100
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7010
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 7110
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 0
95
[ ZEDIAC ] > 100
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000100: A0 0A 5F 00 00 00 00 00  00 00 00 00 00 00 00 00  .._.............

[ ZEDIAC ] > 7010
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 01 01  ................

[ ZEDIAC ] > 7110
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
007110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 01  ................

65816: Incorrect IO cycles for branch instructions in emulation mode

For example, in test "80 e 10000", 2 stall cycles are expected at the end despite the target not crossing a page:

"cycles": [
    [10062147, 128, "dp-remx-"],
    [10062148, 114, "-p-remx-"],
    [10062148, null, "---remx-"],  (5) Add 1 cycle if branch is taken.
    [10062148, null, "---remx-"]  (6?) Add 1 cycle if branch is taken across page boundaries in 6502 emulation mode (E=1).
]

In that test, the initial PC is $8943, branch offset is $72, and final PC is $89b7, which AFAICU does
not constitute a crossing of the page boundary (($8943 & $ff00) == ($89b7 & $ff00)), which is also the case according
to the 65816 emulator cores I've checked (the ones in mesen2, bsnes, and snes9x).

Perhaps I am fundamentally misunderstanding how page crossing is determined, but this appears to affect ~75% of tests in 80.e.json:
image

EDIT: For reference, here's my code that handles branches:

exec_op2:
	if (opcode_ == 0x80 /* BRA */ || (opcode_ & 0b11111) == 0b10000 /* Bcc */) {
		uint8_t flag_bits[] = { flags::N, flags::V, flags::C, flags::Z };
		uint8_t flag = flag_bits[(opcode_ >> 6) & 0b11];
		bool taken = opcode_ == 0x80 || (!!(r_.flags & flag) == !!(opcode_ & (1 << 5)));

		if (taken) {
			int8_t off8 = uint8_t(target_addr_ - r_.pc);

			if (r_.e && (((r_.pc & 0xFF) + off8) & 0xFF00))
				enqueue(&&stall_last);

			r_.pc = target_addr_;

			enqueue(&&complete_op);
			goto stall_last;
		} else {
			goto complete_op;
		}
	}

65816: More emulation mode stack wrapping

More emulation mode stack wrapping

It seems issue #39 might have led to some confusion. Apologies as I should have included the value of the SP after each test.
Commit 5d28c5f references the SP as being treated as a 16-bit value. In emulation mode, this is true only for "new" instructions during execution. After the instruction completes, the high byte of the SP is forced to $01 and the low byte is not affected. (For instance, if a JSL is executed with SP=$0100, the last value pushed would be stored at $fe. Since the SP is post decremented, the SP would then be $00fc. If the CPU is in emulation mode, the SP then is forced to $01fc after the memory operations complete. In native mode, the SP stays as $00fc.)

Here's a reference for this behavior; stack addressing operations in emulation mode retain the high byte as $01 when the instruction completes.

As for how this affects the tests, I am not sure of a way to test this specifically on hardware. Take for example test "00 e 1" which starts out with the SP at $224b. As far as I know, there is not a way to set the high byte of the SP in emulation mode, meaning this particular case cannot be tested. From the emulator realm, I can see two possibilities: (1) the emulator assumes that the SP is always correct following an operation and that no outside forces will change its value, meaning that it does not need to perform extra checks on the SP's value or (2) every stack operation is checked against the emulation mode flag.

All the tests below start out in native mode and switch to emulation mode when necessary.

If there's an error in my testing or you need more info, let me know and I can correct or run other tests.

Test example (emulation mode)

Test condition: "22 e xx"

Source code:

stack_save  .equ $1000

    .as
    .org $00                    ; Actually $20000
    
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #$4567                  ; Set up direct page
    tcd
    .as
    sec                         ; Emulation mode
    xce
    .as
    .xs
    ;; ENTER EMULATION MODE

    ;; "22 e xx"
    ldx #$00
    txs
    jsl $20134
    
    .org $134                   ; Will be placed into correct bank on load

    phd                         ; Push the D reg
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    tsc                         ; Get the current SP
    sta |0                      ; Abs addressing
    
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 20000
249
[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: FB 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 17 00  ................  <-- JSL low byte = $17
000100: 02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 67 45 00 00  ............gE..  <-- PHD (D = $4567)
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test example (native mode)

Test condition: "22 n xx"

Source code:

stack_save  .equ $1000

    .as
    .org $00                    ; Actually $20000
    
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #$4567                  ; Set up direct page
    tcd

    .xl
    rep #$10

    ;; "22 n xx"
    ldx #$0100
    txs
    jsl $20134
    
    .org $134                   ; Will be placed into correct bank on load

    phd                         ; Push the D reg
    
    .al
    rep #$20
    tsc                         ; Get the current SP
    sta |0                      ; Abs addressing
    
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 20000
249
[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: FB 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 67 45 18 00  ............gE..  <-- JSL and PHD values
000100: 02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test example: stack switch from native to emulation mode

Test condition: ??

Shows that switching to emulation mode (from native mode) and back to native mode without any stack operations forces SP high to $01.

Source code:

stack_save  .equ $1000

    .as
    .org $00                    ; Actually $20000
    
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #$4567                  ; Set up SP
    tcs
    .as
    sec                         ; Emulation mode
    xce
    ;; ENTER EMULATION MODE

    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    tsc                         ; Get the current SP
    sta |0                      ; Abs addressing
    
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return
    

Hardware trace:

[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 20000
249
[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 67 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00  g...............

Test example: stack switch from native to emulation mode with "old" push

Test condition: ??

Shows that switching to emulation mode forces SP high byte to $01.

Source code:

stack_save  .equ $1000

    .as
    .org $00                    ; Actually $20000
    
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #$4567                  ; Set up SP
    tcs
    .as
    sec                         ; Emulation mode
    xce
    ;; ENTER EMULATION MODE

    pha
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    tsc                         ; Get the current SP
    sta |0                      ; Abs addressing
    
    lda >stack_save             ; Restore stack
    tcs
    rtl

Hardware trace:

[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 44f0.4600
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0044F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004500: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004510: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004520: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004530: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004540: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004550: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004560: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004570: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004580: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004590: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004600: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 20000
249
[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 66 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00  f...............

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 67  00 00 00 00 00 00 00 00  .......g........  <-- PHA value
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 44f0.4600
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0044F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004500: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004510: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004520: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004530: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004540: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004550: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004560: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004570: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004580: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004590: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004600: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

Test example: stack switch from native to emulation mode with "new" push

Test condition: ??

Source code:

stack_save  .equ $1000

    .as
    .org $00                    ; Actually $20000
    
    lda #0                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >stack_save
    lda #$4567                  ; Set up SP
    tcs
    lda #$789a
    tcd
    .as
    sec                         ; Emulation mode
    xce
    ;; ENTER EMULATION MODE

    phd                         ; Push the D reg
    
    ;; EXIT EMULATION MODE
    clc                         ; Back to Native mode
    xce
    
    .al
    rep #$20
    tsc                         ; Get the current SP
    sta |0                      ; Abs addressing
    
    lda >stack_save             ; Restore stack
    tcs
    rtl                         ; MONITOR prints A on return

Hardware trace:

[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 44f0.4600
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0044F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004500: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004510: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004520: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004530: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004540: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004550: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004560: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004570: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004580: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004590: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004600: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > gosub 20000
249
[ ZEDIAC ] > 0
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: 65 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00  e...............

[ ZEDIAC ] > f0.200
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000160: 00 00 00 00 00 00 9A 78  00 00 00 00 00 00 00 00  .......x........  <-- PHD value
000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0001F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000200: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

[ ZEDIAC ] > 44f0.4600
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
0044F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004500: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004510: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004520: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004530: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004540: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004550: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004560: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004570: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004580: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004590: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
0045F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
004600: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

NES 6502 Incorrect Cycles test

Reddit post:
https://www.reddit.com/r/EmuDev/comments/13vyfug/nes_test_lda_i_think_the_test_rom_is_wrong/

Basically the test:

{
	"name": "b5 6d 7e",
	"initial": {
		"pc": 27808,
		"s": 113,
		"a": 156,
		"x": 116,
		"y": 192,
		"p": 233,
		"ram": [
			[
				27808,
				181
			],
			[
				27809,
				109
			],
			[
				27810,
				126
			],
			[
				109,
				139
			],
			[
				225,
				49
			]
		]
	},
	"final": {
		"pc": 27810,
		"s": 113,
		"a": 49,
		"x": 116,
		"y": 192,
		"p": 105,
		"ram": [
			[
				109,
				139
			],
			[
				225,
				49
			],
			[
				27808,
				181
			],
			[
				27809,
				109
			],
			[
				27810,
				126
			]
		]
	},
	"cycles": [
		[
			27808,
			181,
			"read"
		],
		[
			27809,
			109,
			"read"
		],
		[
			109,
			139,
			"read"
		],
		[
			225,
			49,
			"read"
		]
	]
}

has 4 reads, while I have 3 reads.
If you do this by hand you'll see that indeed, the 0xB5 instruction should only read from 3 places: opcode, operand and the RAM[] where the RAM[] is what the A register should be. Nothing more.
Is this correct or am I wrong?

8088: Thoughts on division

A number of people who have used the 8088 tests have struggled validating division.
The main issue is the division exceptions that occur, which results in the flag register with several undefined flags getting pushed to the stack.

Even my own emulator doesn't implement all the undefined flags for division, which get set based on a temporary value within the division microcode loop, so aren't easily predictable. When I validate these tests myself, I detect the flag push and mask the flags on the stack. This of course adds complexity to using the tests, and I can't expect everyone to want to do it.

As a side effect of choosing random operands, a full 75% of the division tests end up being exceptions, which seems high, and if we're skipping exceptions due to the aforementioned annoyance then we really have far fewer arithmetic tests than desired.

A few possibilities here:

  • We could weight the random operands to hold exceptions to some maximum percentage of total tests, perhaps no more than 25%
  • We could publish alternate test files for division opcodes which have no exceptions at all.
  • We could do both

Interested to hear people's thoughts.

nes6502 - issue with mirrored memory

First thing, amazing project. Very useful for emulator development.

The CPU instructions I coded passed all the tests successfully with a simple memory management class.

#pragma once

#include <cstdint>

class MMU
{
public:
  uint8_t getByte(uint16_t address) {
    return this->memory[address];
  }

  void setByte(uint16_t address, uint8_t value) {
    this->memory[address] = value;
  }

private:
  uint8_t memory[0xFFFF] = {};
};

With that done, I started implementing the memory mirroring of the NES CPU and that's when my test started failing.

In the NESDEV wiki CPU memory map, we see that the memory at 0x0000–0x07FF and 0x2000–0x2007 are each repeated multiple times.

This means that multiple address should always have the same value (if I understand everything correctly). So:

  • 0x0001 should contain the same value as 0x0801, 0x1001 and 0x1801.
  • 0x2004 should contain the same value as 0x200C, 0x2014, 0x201C, ..., 0x3FFC.

Examples of the issue:

  • in 00 6f 9f, memory locations 308 and 4404 should have the same value (since 308 % 0x800 == 4404 % 0x800)
    • [308, 180]
    • [4404, 159]
  • in 00 88 2e, memory locations 12176 and 13352 should have the same value (since 12176 % 8 == 13352 % 8)
    • [12176, 136]
    • [13352, 196]

It would be nice not have to provide a different memory management class implementation in order to pass the tests.

Not sure how the test case are generated, but I could try making the change.

And if I'm wrong about this, sorry 😅 .

6502 0x20 opcode (Test 20 55 13) Incorrect?

I think there is an issue with test 20 55 13. My CPU emulator passes all tests apart from this one. I think the final status should be:

A:  158
P:  230
PC: 4949 (0x1355)
X:  137
Y:  52

N V - B D I Z C
1 1 - 0 0 1 1 0 


------
Memory
------
Address | Value
341     | AD (173)
379     | 20 (32)
380     | 7E (126)
381     | 01 (1)

6502 `02 58 f3` case doesn't match Visual 6502

{ "name": "02 35 44", "initial": { "pc": 1837, "s": 197, "a": 33, "x": 239, "y": 61, "p": 108, "ram": [ [1837, 2], [1838, 53], [1839, 68]]}, "final": { "pc": 1837, "s": 197, "a": 33, "x": 239, "y": 61, "p": 108, "ram": [ [1837, 2], [1838, 53], [1839, 68]]}, "cycles": [ [1837, 2, "read"], [1838, 53, "read"], [1838, 53, "read"]] }

It suggests there should be a read from the PC on the 3rd cycle, but the bus activity in Visual 6502 shows a read from $ffff:

cycle	ab	db	rw	Fetch	pc	a	x	y	s	p
0	0000	02	1	unknown	0000	aa	00	00	fd	nv‑BdIZc
0	0000	02	1	unknown	0000	aa	00	00	fd	nv‑BdIZc
1	0001	58	1		0001	aa	00	00	fd	nv‑BdIZc
1	0001	58	1		0001	aa	00	00	fd	nv‑BdIZc
2	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
2	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc

Then 2 reads from fffe, and then endless ffff.

cycle	ab	db	rw	Fetch	pc	a	x	y	s	p
3	fffe	00	1		0002	aa	00	00	fd	nv‑BdIZc
3	fffe	00	1		0002	aa	00	00	fd	nv‑BdIZc
4	fffe	00	1		0002	aa	00	00	fd	nv‑BdIZc
4	fffe	00	1		0002	aa	00	00	fd	nv‑BdIZc
5	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
5	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
6	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
6	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
7	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
7	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
8	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
8	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
9	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
9	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
10	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
10	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
11	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
11	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
12	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
12	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
13	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
13	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
14	ffff	00	1		0002	aa	00	00	fd	nv‑BdIZc
```

65816: missing coverage for zero flag in 16-bit adds

There are no tests that check if the Z-flag is set if the result of a 16-bit add (both decimal and non-decimal mode) is 0.

I had a bug in my CPU which passed your 65816 tests, but did show up in PeterLemons CPUTests.

Is there a bug in the 8088/v1 'adc word [es:bx+4E3Ch], sp' test?

This test initializes memory location 139040 with the value 64 and expects it to change to 66 but as far as I can tell, the adc instruction will never touch that memory location. Am I missing something or is this a bug in this particular test?

image

For reference, this test has the f96a6c0c0c44fbf9b0761b78214f1a76caa71ada8edb786aaa08d32b1e46f129 hash.

65816 Needs Edge-Case Tests

There are a lot of rare edge cases in 65816 that depend on an address being XXFF or FFFF and then adding an offset. For example, an operand might be at address 0x6BFFFF with the high byte on 0x6BFFFF+1.
They are handled in different ways. 0x6BFFFF+1 could become 0x6B0000, 0x6BFF00, or carry into the bank (6B): 0x6C0000.
Because of how rare this cases is, it simply isn’t tested in most tests, so both 0x6B0000 and 0x6C0000 implementations pass and it is impossible to know which is correct.

Either more tests need to be generated to be sure these edge cases are covered or some percentage of 10,000 tests should be biased toward (or guaranteed to be) these edges cases.

Opcode 9C/9E: nes6502 Result Inconsistent with Test ROM

If you write the result to the address as normal (write VALUE to (ADDR)) you will pass all of the JSON tests but you will fail the 07-abs_xy.nes test ROM. If you write VALUE to (ADDR & 0xFF) | (VALUE << 8) you will pass 07-abs_xy.nes but fail JSON.
Note: Always prefer to pass test ROM’s, which have been verified against the hardware.

8088 Test Suite

Hi Tom,

I'm working on generating JSON tests for the 8088 from hardware.

Here is an example test:

{
    "name": "add byte ds:[bx+si+C2h], al",
    "bytes": [0, 64, 194],
    "initial": {
        "regs": {
            "ax": 52773,
            "bx": 22214,
            "cx": 16054,
            "dx": 57938,
            "cs": 60492,
            "ss": 17184,
            "ds": 15619,
            "es": 60510,
            "sp": 56738,
            "bp": 13363,
            "si": 58400,
            "di": 31158,
            "ip": 16937,
            "flags": 62535
        },
        "ram": [
            [264920, 71],
            [984809, 0],
            [984810, 64],
            [984811, 194],
            [984812, 144],
            [984813, 144],
            [984814, 144],
            [984815, 144]
        ],
        "queue": []
    },
    "final": {
        "regs": {
            "ax": 52773,
            "bx": 22214,
            "cx": 16054,
            "dx": 57938,
            "cs": 60492,
            "ss": 17184,
            "ds": 15619,
            "es": 60510,
            "sp": 56738,
            "bp": 13363,
            "si": 58400,
            "di": 31158,
            "ip": 16940,
            "flags": 62470
        },
        "ram": [
            [264920, 108],
            [984809, 0],
            [984810, 64],
            [984811, 194],
            [984812, 144],
            [984813, 144],
            [984814, 144],
            [984815, 144]
        ],
        "queue": [144, 144, 144]
    },
    "cycles": [
        ["-", 984810, "CS", "R--", "---", 0, "CODE", "T2", "F", 0],
        ["-", 984810, "CS", "R--", "---", 64, "PASV", "T3", "-", 0],
        ["-", 984810, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 984811, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 984811, "CS", "R--", "---", 0, "CODE", "T2", "S", 64],
        ["-", 984811, "CS", "R--", "---", 194, "PASV", "T3", "-", 0],
        ["-", 984811, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 984812, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 984812, "CS", "R--", "---", 0, "CODE", "T2", "-", 0],
        ["-", 984812, "CS", "R--", "---", 144, "PASV", "T3", "-", 0],
        ["-", 984812, "CS", "---", "---", 0, "PASV", "T4", "S", 194],
        ["A", 984813, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 984813, "CS", "R--", "---", 0, "CODE", "T2", "-", 0],
        ["-", 984813, "CS", "R--", "---", 144, "PASV", "T3", "-", 0],
        ["-", 984813, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["-", 984813, "--", "---", "---", 0, "PASV", "Ti", "-", 0],
        ["-", 984813, "--", "---", "---", 0, "PASV", "Ti", "-", 0],
        ["A", 264920, "--", "---", "---", 0, "MEMR", "T1", "-", 0],
        ["-", 264920, "DS", "R--", "---", 0, "MEMR", "T2", "-", 0],
        ["-", 264920, "DS", "R--", "---", 71, "PASV", "T3", "-", 0],
        ["-", 264920, "DS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 984814, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 984814, "CS", "R--", "---", 0, "CODE", "T2", "-", 0],
        ["-", 984814, "CS", "R--", "---", 144, "PASV", "T3", "-", 0],
        ["-", 984814, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 984815, "--", "---", "---", 0, "CODE", "T1", "-", 0],
        ["-", 984815, "CS", "R--", "---", 0, "CODE", "T2", "-", 0],
        ["-", 984815, "CS", "R--", "---", 144, "PASV", "T3", "-", 0],
        ["-", 984815, "CS", "---", "---", 0, "PASV", "T4", "-", 0],
        ["A", 264920, "--", "---", "---", 0, "MEMW", "T1", "-", 0],
        ["-", 264920, "DS", "-A-", "---", 0, "MEMW", "T2", "-", 0],
        ["-", 264920, "DS", "-AW", "---", 108, "PASV", "T3", "-", 0]
    ]
}

From left to right the cycle fields are:
ALE line, address latch, segment status lines, memory status lines, IO status lines, data bus, bus status lines, t-state, queue status and queue byte read

Before I start generating these wholesale, I thought I'd request your feedback. Do you see any omissions or have any suggestions?

V1 of my test suite will execute all instructions fresh from a CPU reset; so the queue contents will always be empty at start, and all bytes after the instruction bytes are NOPs, so the queue will always contain nothing but NOPs at the end. The I and T flags are not exercised.

If V1 is well received, I plan to do a V2 which will capture instructions 'in-flight' with arbitrary starting queue contents, and exercise traps and interrupts, but I figure this V1 is a good start.

Document how test data is generated

Given the growing popularity of these tests, I have noticed a significant increase in questions regarding the accuracy and source of the test data. There are also known issues with some of the tests (e.g. #78 and #72).

Clearly declaring how each set of tests was generated is necessary to clear up any confusion regarding the accuracy (or lack there of) of this data, as well as to properly attribute any projects that were used in the process. It may also reveal why some errors exist, and would enable the emulation community easier access to improve the original source and/or the test data itself.

The 8088 tests contributed by @dbalsom and Folkert van Heusden already do this, which is greatly appreciated!

If the generation process is highly complex and thus may require a large amount of work/time to document, then at minimum write the source of the test data in each README, whether that be real hardware, an emulator/simulator, or anything else.

nes6502 README.md has incorrect sample

A minor issue: the README.md has a sample which is invalid. That was something I was stuck with for a day back when I started writing the emulator as instead of choosing a sample from a file I decided to use the one shown in the README (assumed it was correct, my mistake), then when I added more cases I noticed inconsistencies until I realized the original sample was wrong. Again, my mistake but I think it is simple to replace the one from the readme with any of the b1.json file which are all working correctly.

6502: JSR Overwriting Instruction

Thank you for this test suite! I've already found numerous issues in Ghidra (https://github.com/oberoisecurity/ghidra-6502-fixes). I'm trying to debug an issue with /6502/v1/20.json instruction 4044. All other unit tests in 20.json pass.

{ "name": "20 55 13",
"initial": { "pc": 379, "s": 125, "a": 158, "x": 137, "y": 52, "p": 230,
"ram": [ [379, 32], [380, 85], [381, 19], [341, 173]]},
"final": { "pc": 341, "s": 123, "a": 158, "x": 137, "y": 52, "p": 230,
"ram": [ [341, 173], [379, 32], [380, 125], [381, 1]]},
"cycles": [ [379, 32, "read"], [380, 85, "read"], [381, 19, "read"], [381, 1, "write"], [380, 125, "write"], [381, 1, "read"]] },`

From the looks of the unit test we are overwriting the instruction as we are executing it. I'm stumped as to what the correct behavior is here. The unit test says PC should be 341 but Ghidra is claiming 4949. How were your unit tests generated? On real hardware? Are you sure this is the correct behavior?

Correct 65816 transgressions

When posting the PC for internal operations, the posted value is one too high.

E.g.

ADC (d,x) 0x61 n has these for expected addresses:
1. 0xCD6365 (PC)
2. 0xCD6366 (PC+1)
3. 0xCD6367 (PC+2)

but on the official 65c816S PDF from WDC, page 39, it says that cycle 1 has PC, cycle 2 has PC+1, and cycle 3 is still PC+1, not +2.0xCD6367 (PC+2)


For RMW instructions such as 0x1c, in native mode, Write is not supposed to be asserted on the IO cycle. That only happens in Emulation mode.


Decimal arithmetic gives incorrect results for invalid decimal values.

65816: DBR should not be reset on BRK/COP in emulation mode

As of commit 96c2ca8, the BRK and COP instructions reset the DBR when in emulation mode (E=1). From what I could tell online and in Eyes & Lichty, only the PBR is reset and the DBR is left as-is. I have run a test on one of my 65816-based systems which confirms this behavior (of DBR not changing). If you see a mistake in my testing, let me know and I can re-run it.

Test program:

    .as

    .org 0
    lda #3                      ; Set the DBR to a known value
    pha
    plb
    .al
    rep #$20                    ; Save the stack so we can return to MONTIOR
    tsc
    sta >$20
    .as
    sec                         ; Emulation mode
    xce
    brk                         ; "Test subject"
    .byte 0

    ;; BRK/IRQ/COP vector
    .org $80
    pla                         ; Remove COP/BRK from stack
    pla
    pla
    phb                         ; Get the data bank
    plx
    clc                         ; Back to Native mode
    xce
    .al
    rep #$20
    lda >$20                    ; Restore stack
    tcs
    .as
    sep #$20
    txa
    rtl                         ; MONITOR prints A on return

Monitor trace on hardware:


[ ZEDIAC ] > 0.90    <-- Memory dump
        00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
000000: A9 03 48 AB C2 20 3B 8F  20 00 00 38 FB 00 00 00  ..H.. ;. ..8....
000010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000080: 68 68 68 8B FA 18 FB C2  20 AF 20 00 00 1B E2 20  hhh..... . ....
000090: 8A 6B 00 00 00 00 00 00  00 00 00 00 00 00 00 1A  .k..............

[ ZEDIAC ] > gosub 0 <-- JSL to 0
3                    <-- Value in A
[ ZEDIAC ] >

8088: some `name`s refer to `si` but should refer to `di`

Quite a few instructions seem to give a human-readable index of si despite actually using di.

Given the definition of name as a user-readable disassembly of the instruction, I think this is a valid criticism (if I've diagnosed it correctly) but to be explicit: it's an issue with the contents of name only, which are just human-friendly after-the-fact fields, so should be a mere clerical fix (again: if I'm not adrift here).

For example, the test add byte ss:[bp+si+0C67h], al from 00.json.gz:

  • has si in the name as per above;
  • begins with ss = 4978, bp = 2861, di = 47332, si = 57572, ;
  • therefore if the address in use were ss:[bp+si+0C67h] it'd be 143256; if it were instead ss:[bp+di+0C67h] it'd instead be 133016;
  • per both the bus activity and the listed RAM contents, 133016 is accessed, and 143256 isn't.

Furthermore, the second entry in bytes is 131, i.e. 0x83, which gives an rm field of 0x3, which is bp+di.

The full (hexadecimal) bytes sequence for that instruction is 00 83 67 0c which this online disassembler also believes is bp + di rather than + si (though as an aside, I've found that disassembler not to be entirely reliable — e.g. it seems always to assume a selector of ds regardless of the base).

@dbalsom can you confirm or deny that I've got an actual issue here, no matter how negligible?

Inconsistency of the negative flag in decimal mode across 6502 emulators

I'm curious what was the emulator used to create the tests for the 6502. I'm having a hard time understanding the negative flags in some of the tests in the ADC test file (69.json).

For example, take a look at the following test:

Name: "69 8d bc"

Initial State:
pc: 41966 (0xa3ee)
s: 163 (0xa3) (10100011)
a: 118 (0x76) (01110110)
x: 251 (0xfb) (11111011)
y: 160 (0xa0) (10100000)
p: 172 (0xac) (10101100)
[(a3ee , 69)(a3ef , 8d)(a3f0 , bc)]

Final State:
CPU:
pc: 41968 (0xa3f0)
s: 163 (0xa3) (10100011)
a: 105 (0x69) (01101001)
x: 251 (0xfb) (11111011)
y: 160 (0xa0) (10100000)
p: 45 (0x2d) (00101101)
[(a3ee , 69)(a3ef , 8d)(a3f0 , bc)]

The instruction was: ADC #$8D (Adding 8D to the Accumulator with carry not set)

According to the Mass:Werk Virtual 6502, the negative flag should be set at the end of this instruction, but not according to the test.

I've looked at some other emulators ([1], [2]) and found that the ADC operation with negative flag set is often very inconsistent when the accumulator or the operands hold undefined values (such as 0xFE or 0xA1, where one of the digits is larger than 0x9). This inconsistency happens at both the negative flag, as well as the actual accumulator value.

I'm building a 6502 emulator using these tests are a foundation, and I would really appreciate any highlight into how the negative flag is calculated when decimal mode is set.

I read somewhere that the negative flag is set regardless of the decimal mode, and it is set if the seventh bit of the accumulator is set.

But the following test shows something different:

"69 8f b3"
Initial State:
pc: 63001 (0xf619)
s: 130 (0x82) (10000010)
a: 227 (0xe3) (11100011)
x: 20 (0x14) (00010100)
y: 229 (0xe5) (11100101)
p: 111 (0x6f) (01101111)
[(f619 , 69)(f61a , 8f)(f61b , b3)]

Final State:
pc: 63003 (0xf61b)
s: 130 (0x82) (10000010)
a: 217 (0xd9) (11011001)
x: 20 (0x14) (00010100)
y: 229 (0xe5) (11100101)
p: 109 (0x6d) (01101101)
[(f619 , 69)(f61a , 8f)(f61b , b3)]

Here you can see that in the final state, the seventh bit of the accumulator is set, but the negative flag isn't.

Can anyone highlight to me how exactly the negative flag works in decimal mode?

Thank you very much!

Opcode 6B Respects D Flag on NES Tests

In nes6502, the opcode tests for 6B produce an incorrect result when the D flag is set. IE, for some reason this opcode, and only this opcode, respects the D flag on the NES tests.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.