Undocumented 6309 Behaviours - hoglet67/6809Decoder GitHub Wiki

Contents

Introduction

This page attempts to clarify the behaviour of particular 6309 instructions where the existing documentation is either unclear, or is inconsistent. For example, when the overflow (V) or half-carry flag (H) become undefined after an instruction, what actually happens?

There is a similar page covering the 6809 here.

In all cases these behaviours have been validated against original devices, by writing test cases that carefully (sometimes exhaustively) exercised the instruction, then exposed the resultant state by pushing it onto the stack.

References

The following 6309 references were used in the development of the 6809/6309 Bus Protocol decoder:

Undocumented M Register

The 6309 contains an undocumented 8-bit working register that we are calling the M register, because one of the uses of this is to hold the result written back to memory in read-modify-write instructions.

This register can be read by the following code sequence:

LDX #0
ADDR DP, X

Bits 7..0 of X now contain bits 7..0 of M.

The following instructions modify M:

  • Read-Modify-Write instructions (apart from AIM/EIM/OIM) - M takes the value of the result (written back to memory)
  • AIM/EIM/OIM/TIM - M takes the value of the 8-bit immediate constant
  • MUL - M takes the value of the B accumulator before the multiply
  • MULD - M takes the sign of the result (0x00 if positive, 0xFF if negative)
  • DIVD/DIVQ - M takes the sign of the quotient (0x00 if positive, 0xFF if negative)
  • BITMD - M takes the value of the 8-bit immediate constant
  • TFM - M takes the value of the last data byte copied (unchanged if W=0)

These cases were found with random testing and may not be exhaustive.

Illegal Instruction Trap

The following things generate an illegal instruction trap (through vector 0xFFF0)

  • All undefined opcodes (of which there are 330)
  • The following undefined index postbytes (0x92, 0xB2, 0xBF, 0xD2, 0xDF, 0xF2, 0xFF)
  • TFM with an illegal source or destination register (only D, X, Y, U, S are legal)

The following things do not generate an illegal instruction trap:

  • The directbit addressing mode with the register bits=11 (this appears to select the zero register)
  • Writing back to the zero register with EXN, TFR or a directbit instruction (no write occurs)

LIC Differences

In 6309 emulation mode, LIC occurs on the last cycle of the instruction, as per the 6809.

In 6309 native mode, LIC occurs on the first cycle of the instruction, rather like the 6502 Sync output does.

As you can imagine, it gets confusing when switching between modes.

When changing from emulation mode to native mode, the LDMD #&01 instruction takes 5 cycles, and none of the five cycles are marked with LIC.

When changing from native mode to emulation mode, the LDMD #&00 instruction takes 5 cycles, and both the first and last cycle are marked with LIC.

Half-Carry Flag

The Hitachi datasheet states the half-carry flag (H) becomes undefined after the following operations:

  • ASLA/ASLB/ASL
  • ASRA/ASRB/ASR
  • CMPA/CMPB
  • NEGA/NEGB/NEG
  • SBCA/SBCB
  • SUBA/SUBB

(Footnote 8 says: Value of half-carry flag is undefined)

In practice, in all these cases the half-carry flag is unaffected by the operation.

This applies in both emulation and native modes.

DAA

The DAA operation perform the decimal adjust by adding a correction factor:

ACCA = ACCA + correction

On the 6809 the correction factor is calcuated as expected in all cases, see Atkinson page 56 for details:

int correction = 0x00;
if (H == 1 || (ACCA & 0x0f) > 0x09) {
   correction |= 0x06;
}
if (C == 1 || (ACCA & 0xf0) > 0x90 || ((ACCA & 0xf0) > 0x80 && (ACCA & 0x0f) > 0x09)) {
   correction |= 0x60;
}

On the 6309 the correction factor differs from the 6809 when C=1 and ACCA is in the range 80..99:

C=1 H=0 A=80 => DAA => 6809:A=E0  6309:A=00
C=1 H=0 A=81 => DAA => 6809:A=E1  6309:A=01
C=1 H=0 A=82 => DAA => 6809:A=E2  6309:A=02
C=1 H=0 A=83 => DAA => 6809:A=E3  6309:A=03
C=1 H=0 A=84 => DAA => 6809:A=E4  6309:A=04
C=1 H=0 A=85 => DAA => 6809:A=E5  6309:A=05
C=1 H=0 A=86 => DAA => 6809:A=E6  6309:A=06
C=1 H=0 A=87 => DAA => 6809:A=E7  6309:A=07
C=1 H=0 A=88 => DAA => 6809:A=E8  6309:A=08
C=1 H=0 A=89 => DAA => 6809:A=E9  6309:A=09
C=1 H=0 A=8A => DAA => 6809:A=F0  6309:A=10
C=1 H=0 A=8B => DAA => 6809:A=F1  6309:A=11
C=1 H=0 A=8C => DAA => 6809:A=F2  6309:A=12
C=1 H=0 A=8D => DAA => 6809:A=F3  6309:A=13
C=1 H=0 A=8E => DAA => 6809:A=F4  6309:A=14
C=1 H=0 A=8F => DAA => 6809:A=F5  6309:A=15
C=1 H=0 A=90 => DAA => 6809:A=F0  6309:A=00
C=1 H=0 A=91 => DAA => 6809:A=F1  6309:A=01
C=1 H=0 A=92 => DAA => 6809:A=F2  6309:A=02
C=1 H=0 A=93 => DAA => 6809:A=F3  6309:A=03
C=1 H=0 A=94 => DAA => 6809:A=F4  6309:A=04
C=1 H=0 A=95 => DAA => 6809:A=F5  6309:A=05
C=1 H=0 A=96 => DAA => 6809:A=F6  6309:A=06
C=1 H=0 A=97 => DAA => 6809:A=F7  6309:A=07
C=1 H=0 A=98 => DAA => 6809:A=F8  6309:A=00
C=1 H=0 A=99 => DAA => 6809:A=F9  6309:A=01

C=1 H=1 A=80 => DAA => 6809:A=E6  6309:A=06
C=1 H=1 A=81 => DAA => 6809:A=E7  6309:A=07
C=1 H=1 A=82 => DAA => 6809:A=E8  6309:A=08
C=1 H=1 A=83 => DAA => 6809:A=E9  6309:A=09
C=1 H=1 A=84 => DAA => 6809:A=EA  6309:A=0A
C=1 H=1 A=85 => DAA => 6809:A=EB  6309:A=0B
C=1 H=1 A=86 => DAA => 6809:A=EC  6309:A=0C
C=1 H=1 A=87 => DAA => 6809:A=ED  6309:A=0D
C=1 H=1 A=88 => DAA => 6809:A=EE  6309:A=0E
C=1 H=1 A=89 => DAA => 6809:A=EF  6309:A=0F
C=1 H=1 A=8A => DAA => 6809:A=F0  6309:A=10
C=1 H=1 A=8B => DAA => 6809:A=F1  6309:A=11
C=1 H=1 A=8C => DAA => 6809:A=F2  6309:A=12
C=1 H=1 A=8D => DAA => 6809:A=F3  6309:A=13
C=1 H=1 A=8E => DAA => 6809:A=F4  6309:A=14
C=1 H=1 A=8F => DAA => 6809:A=F5  6309:A=15
C=1 H=1 A=90 => DAA => 6809:A=F6  6309:A=06
C=1 H=1 A=91 => DAA => 6809:A=F7  6309:A=07
C=1 H=1 A=92 => DAA => 6809:A=F8  6309:A=08
C=1 H=1 A=93 => DAA => 6809:A=F9  6309:A=09
C=1 H=1 A=94 => DAA => 6809:A=FA  6309:A=0A
C=1 H=1 A=95 => DAA => 6809:A=FB  6309:A=0B
C=1 H=1 A=96 => DAA => 6809:A=FC  6309:A=0C
C=1 H=1 A=97 => DAA => 6809:A=FD  6309:A=0D
C=1 H=1 A=98 => DAA => 6809:A=FE  6309:A=00
C=1 H=1 A=99 => DAA => 6809:A=FF  6309:A=00

The 6309 behaviour is consistent in both emulation mode and in native mode. This is not strictly a bug, because these values are illegal inputs to DAA. This is because the largest legitimate value of ACCA with C=1 comes from the addition 0x99 + 0x99 + 1 = 0x33.

The following C code corrects the correction in these cases:

if (cpu6309 && C == 1 && ACCA >= 0x80 && ACCA <= 0x99) {
                              // 6809 correction  6309 correction
   if (ACCA == 0x99) {
      correction = 0x68 - H;  // 0x60/0x66   ->   0x68/0x67
   } else if (ACCA == 0x98) {
      correction = 0x68;      // 0x60/0x66   ->   0x68/0x68
   } else if (ACCA >= 0x90) {
      correction += 0x10;     // 0x60/0x66   ->   0x70/0x76
   } else {
      correction += 0x20;     // 0x60/0x66   ->   0x80/0x86
   }
}

The Hitachi datasheet states the overflow flag (V) is cleared after DAA.

In practice the overflow flag is updated as follows:

V = (the C new value) XOR (the new bit 7 of ACCA)

This applies in both emulation and native modes.

DIVD

The cycle count of DIVD is more complex that has previously been documented:

Start with the base value for the addressing mode, for example for direct addressing mode:

DIVD <direct> (in native mode) = 26 cycles
DIVD <direct> (in emulation mode mode) = 27 cycles

If a division by zero occurs, the division is aborted and the current machine state is pushed to the stack. In emulation mode subtract 2 cycles. In native mode the base cycle count will be correct. No further corrections are needed.

If the dividend is negative, then add one cycle.

If the divisor is negative, then add one cycle.

If range-overflow occurs (the magnitude of the quotient exceeds 255) then subtract 13 cycles.

If twos-complement overflow occurs (magnitude of the quotient is 128..255) then subtract 1 cycle.

After a division by zero:

ACCA = unchanged
ACCB = unchanged
Z = 1
N = 0
V = 0
C = unchanged

After a range overflow:

ACCA, ACCB = 16-bit magnitude of the dividend
Z = 0
N = sign of the dividend
V = 1
C = 0

After a two's complement overflow:

ACCA = 8-bit two-complement remainer (which will be correct and will have the sign of the dividend)
ACCB = 8-bit magnitude of the quotient (which will be 128..255)
Z = 0
N = 0
V = 1
C = bit 0 of the magnitude of the quotient

DIVQ

The cycle count of DIVQ is more complex that has previously been documented:

Start with the base value for the addressing mode, for example for direct addressing mode:

DIVQ <direct> (in native mode) = 35 cycles
DIVQ <direct> (in emulation mode mode) = 36 cycles

If a division by zero occurs, the division is aborted and the current machine state is pushed to the stack. In emulation mode subtract 10 cycles. In native mode subtract 8 cyckes. No further corrections are needed.

If the dividend is negative, then add one cycle.

If the divisor is negative, then add one cycle.

If range-overflow occurs (the magnitude of the quotient exceeds 65535) then subtract 21 cycles.

If twos-complement overflow occurs (magnitude of the quotient is 32768..65536) no further correction is required.

After a division by zero:

ACCA = unchanged
ACCB = unchanged
ACCE = unchanged
ACCF = unchanged
Z = 1
N = 0
V = 0
C = unchanged

After a range overflow:

ACCA, ACCB, ACCE, ACCF = 32-bit magnitude of the dividend
Z = 0
N = sign of the dividend
V = 1
C = 0

After a two's complement overflow:

ACCA,ACCB = 16-bit two-complement remainer (which will be correct and will have the sign of the dividend)
ACCE,ACCF = 16-bit magnitude of the quotient (which will be 32768..65535)
Z = 0
N = 0
V = 1
C = bit 0 of the magnitude of the quotient

LDQ

Some documentation (e.g. Atkinson page 94) states that V is cleared by LDQ. This does not appear to be the case; V is unchanged by LDQ.

There is also a bug in LDQ where the Z flag is set based only on bits 31..16 of the result in Q (i.e. the part in A/B)

MULD

The cycle count of MULD is more complex that has previously been documented:

Start with the base value for the addressing mode, for example for direct addressing mode:

MULD <direct> (in native mode) = 29 cycles
MULD <direct> (in emulation mode mode) = 30 cycles

If either or both of the operands are negative, add two cycles.

This behaviour suggests that internally the multiple is implemented using unsigned arithemetic.

There is also a bug in MULD where the Z flag is set based only on bits 31..16 of the result in Q (i.e. the part in A/B)

TFM

The TFM instruction can be interrupted, and will be restarted after the RTI returns control to it.

The interruption happens after the [R0] read, but before the [R1] write. When restarted, the [R0] read happens a second time. This means that TFM cannot safely be used to read blocks of data from a I/O register, but can be safely used to write block of data to a I/O register.

TFM with an illegal source or destination register (only D, X, Y, U, S are legal) genrates an illegal instruction trap.

If TFM completes normally, then Z is set.

If TFM completes abnormally (because it is interrupted or it generates an illegal instruction trap), then Z is cleared.

TFM can be used with the source and destination register being the same register, so any emulation should handle this case. For example:

LDW  #$100
LDX  #$2000
TFM  X+,X+

This will read $2000, write $2001, read $2002, write $2003, ..., read $21fe, write $21ff.

On exit, W will be zero, and X will be $2200.

SYNC Bug

There appears to be a bug with SYNC in native mode. If the preceeding instruction executes in a single cycle, then it seems any flag changes are not reliably saved.

The clearest example was:

7E08 : B9 AC F2       : ADCA  $ACF2          :     4 : A=51 N=0 Z=0 V=0 C=1
7E0B : 4F             : CLRA                 :     1 : A=00 N=0 Z=1 V=0 C=0
7E0C : 13             : SYNC                 : 11413 : A=00 N=0 Z=1 V=0 C=0
7E0D :                : INTERRUPT !!         :    22 : A=00 N=0 Z=0 V=0 C=1 : Prediction failed for: Z,C

The flags pushed by the interrupt included:

N=0 Z=0 V=0 C=1 : Prediction failed for: Z,C

CLRA sets N=0 Z=1 V=0 C=0, so something has gone wrong here.

This only happens in native mode; in emulated mode the instruction takes 2-cycles and the flags are always correct.

Here are some example traces from the 6809 Decoder of this an other similar failures:

7E14 : F7 86 82       : STB   $8682          :   4 : A=00 B=BF E=C9 F=C0 X=C9D0 Y=DF56 U=C0E7 S=0205 DP=CA T=4567 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E17 : 57             : ASRB                 :   1 : A=00 B=DF E=C9 F=C0 X=C9D0 Y=DF56 U=C0E7 S=0205 DP=CA T=4567 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E18 : 13             : SYNC                 :32633 : A=00 B=DF E=C9 F=C0 X=C9D0 Y=DF56 U=C0E7 S=0205 DP=CA T=4567 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E19 :                : INTERRUPT !!         :  22 : A=00 B=DF E=C9 F=C0 X=C9D0 Y=DF56 U=C0E7 S=01F7 DP=CA T=4567 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: N
--
7E76 : A1 CC 34       : CMPA  $34,PCR        :   5 : A=54 B=6B E=E0 F=F3 X=0000 Y=0000 U=4CC7 S=0200 DP=6A T=0000 E=0 F=0 H=0 I=0 N=1 Z=0 V=1 C=1 DZ=0 IL=1 FM=0 NM=1
7E79 : 47             : ASRA                 :   1 : A=2A B=6B E=E0 F=F3 X=0000 Y=0000 U=4CC7 S=0200 DP=6A T=0000 E=0 F=0 H=0 I=0 N=0 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E7A : 13             : SYNC                 :32120 : A=2A B=6B E=E0 F=F3 X=0000 Y=0000 U=4CC7 S=0200 DP=6A T=0000 E=0 F=0 H=0 I=0 N=0 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E7B :                : INTERRUPT !!         :  22 : A=2A B=6B E=E0 F=F3 X=0000 Y=0000 U=4CC7 S=01F2 DP=6A T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=1 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: C
--
7E2B : EC 69          : LDD   $09,S          :   6 : A=F4 B=0A E=95 F=72 X=7E80 Y=3496 U=7DFE S=0200 DP=00 T=7CFF E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E2D : 44             : LSRA                 :   1 : A=7A B=0A E=95 F=72 X=7E80 Y=3496 U=7DFE S=0200 DP=00 T=7CFF E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E2E : 13             : SYNC                 :32457 : A=7A B=0A E=95 F=72 X=7E80 Y=3496 U=7DFE S=0200 DP=00 T=7CFF E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E2F :                : INTERRUPT !!         :  22 : A=7A B=0A E=95 F=72 X=7E80 Y=3496 U=7DFE S=01F2 DP=00 T=7CFF E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: C
--
7E03 : E7 C3          : STB   ,--U           :   6 : A=0E B=00 E=00 F=00 X=7E80 Y=0000 U=FFFE S=0200 DP=00 T=0209 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E05 : 1D             : SEX                  :   1 : A=00 B=00 E=00 F=00 X=7E80 Y=0000 U=FFFE S=0200 DP=00 T=0209 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E06 : 13             : SYNC                 :32662 : A=00 B=00 E=00 F=00 X=7E80 Y=0000 U=FFFE S=0200 DP=00 T=0209 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E07 :                : INTERRUPT !!         :  22 : A=00 B=00 E=00 F=00 X=7E80 Y=0000 U=FFFE S=01F2 DP=00 T=0209 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: Z
--
7E22 : 91 44          : CMPA  $44            :   3 : A=00 B=B9 E=A6 F=84 X=7E80 Y=8481 U=3A2B S=0200 DP=8B T=0000 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E24 : 4D             : TSTA                 :   1 : A=00 B=B9 E=A6 F=84 X=7E80 Y=8481 U=3A2B S=0200 DP=8B T=0000 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E25 : 13             : SYNC                 :32475 : A=00 B=B9 E=A6 F=84 X=7E80 Y=8481 U=3A2B S=0200 DP=8B T=0000 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E26 :                : INTERRUPT !!         :  22 : A=00 B=B9 E=A6 F=84 X=7E80 Y=8481 U=3A2B S=01F2 DP=8B T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: Z
--
7E0E : A5 FC 13       : BITA  [$13,PCR]      :   8 : A=C0 B=77 E=C0 F=D8 X=7E80 Y=DC81 U=10FC S=0200 DP=00 T=DC81 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E11 : 58             : ASLB                 :   1 : A=C0 B=EE E=C0 F=D8 X=7E80 Y=DC81 U=10FC S=0200 DP=00 T=DC81 E=1 F=1 H=0 I=1 N=1 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E12 : 13             : SYNC                 :32593 : A=C0 B=EE E=C0 F=D8 X=7E80 Y=DC81 U=10FC S=0200 DP=00 T=DC81 E=1 F=1 H=0 I=1 N=1 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E13 :                : INTERRUPT !!         :  22 : A=C0 B=EE E=C0 F=D8 X=7E80 Y=DC81 U=10FC S=01F2 DP=00 T=DC81 E=1 F=1 H=0 I=1 N=0 Z=0 V=1 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: N,C
--
7E08 : 74 8A 92       : LSR   $8A92          :   6 : A=ED B=FF E=00 F=00 X=7E80 Y=A97C U=0000 S=0200 DP=D8 T=01FE E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E0B : 5A             : DECB                 :   1 : A=ED B=FE E=00 F=00 X=7E80 Y=A97C U=0000 S=0200 DP=D8 T=01FE E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E0C : 13             : SYNC                 :32659 : A=ED B=FE E=00 F=00 X=7E80 Y=A97C U=0000 S=0200 DP=D8 T=01FE E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E0D :                : INTERRUPT !!         :  22 : A=ED B=FE E=00 F=00 X=7E80 Y=A97C U=0000 S=01F2 DP=D8 T=01FE E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: N
--
C0C7 : 3B             : RTI                  :  17 : A=A9 B=C0 E=FF F=FE X=7E7E Y=9115 U=0000 S=01F9 DP=13 T=0000 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E7A : 56             : RORB                 :   1 : A=A9 B=60 E=FF F=FE X=7E7E Y=9115 U=0000 S=01F9 DP=13 T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E7B : 13             : SYNC                 :16437 : A=A9 B=60 E=FF F=FE X=7E7E Y=9115 U=0000 S=01F9 DP=13 T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E7C :                : INTERRUPT !!         :  22 : A=A9 B=60 E=FF F=FE X=7E7E Y=9115 U=0000 S=01EB DP=13 T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: C
--
7E3A : A0 AC 37       : SUBA  $37,PCR        :   5 : A=4A B=CD E=F5 F=0C X=7F5A Y=7DFD U=D07B S=0200 DP=62 T=0228 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E3D : 49             : ROLA                 :   1 : A=95 B=CD E=F5 F=0C X=7F5A Y=7DFD U=D07B S=0200 DP=62 T=0228 E=1 F=1 H=0 I=1 N=1 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E3E : 13             : SYNC                 :32403 : A=95 B=CD E=F5 F=0C X=7F5A Y=7DFD U=D07B S=0200 DP=62 T=0228 E=1 F=1 H=0 I=1 N=1 Z=0 V=1 C=0 DZ=0 IL=1 FM=0 NM=1
7E3F :                : INTERRUPT !!         :  22 : A=95 B=CD E=F5 F=0C X=7F5A Y=7DFD U=D07B S=01F2 DP=62 T=0228 E=1 F=1 H=0 I=1 N=1 Z=0 V=1 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: C
--
C0C7 : 3B             : RTI                  :  17 : A=7C B=14 E=C9 F=C0 X=7E80 Y=C0D8 U=2469 S=0200 DP=F4 T=0909 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E04 : 57             : ASRB                 :   1 : A=7C B=0A E=C9 F=C0 X=7E80 Y=C0D8 U=2469 S=0200 DP=F4 T=0909 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E05 : 13             : SYNC                 :32625 : A=7C B=0A E=C9 F=C0 X=7E80 Y=C0D8 U=2469 S=0200 DP=F4 T=0909 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E06 :                : INTERRUPT !!         :  22 : A=7C B=0A E=C9 F=C0 X=7E80 Y=C0D8 U=2469 S=01F2 DP=F4 T=0909 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: C
--
7E08 : B9 AC F2       : ADCA  $ACF2          :   4 : A=51 B=6B E=76 F=5D X=7E80 Y=0002 U=FF80 S=0200 DP=CA T=FF80 E=1 F=1 H=1 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E0B : 4F             : CLRA                 :   1 : A=00 B=6B E=76 F=5D X=7E80 Y=0002 U=FF80 S=0200 DP=CA T=FF80 E=1 F=1 H=1 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E0C : 13             : SYNC                 :11413 : A=00 B=6B E=76 F=5D X=7E80 Y=0002 U=FF80 S=0200 DP=CA T=FF80 E=1 F=1 H=1 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E0D :                : INTERRUPT !!         :  22 : A=00 B=6B E=76 F=5D X=7E80 Y=0002 U=FF80 S=01F2 DP=CA T=FF80 E=1 F=1 H=1 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: Z,C
--
7E02 : BB F4 E2       : ADDA  $F4E2          :   4 : A=A8 B=7B E=75 F=50 X=7E80 Y=01FF U=012D S=0200 DP=35 T=D7D7 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1
7E05 : 53             : COMB                 :   1 : A=A8 B=84 E=75 F=50 X=7E80 Y=01FF U=012D S=0200 DP=35 T=D7D7 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E06 : 13             : SYNC                 :32672 : A=A8 B=84 E=75 F=50 X=7E80 Y=01FF U=012D S=0200 DP=35 T=D7D7 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=0 IL=1 FM=0 NM=1
7E07 :                : INTERRUPT !!         :  22 : A=A8 B=84 E=75 F=50 X=7E80 Y=01FF U=012D S=01F2 DP=35 T=D7D7 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=0 NM=1 : Prediction failed for: N,C

All occur on single-cycle instructions; I have never seen a multi-cycle instruction fail in this way.

SWI Bug

There appears to be a bug with SWI in native mode, if it is interrupted with an NMI.

The first example was found in 20220728a/random0-E.bin:

7E05 : 6C 38          : INC   -$08,Y         :   7 : A=55 B=63 E=2E F=4D X=7E80 Y=3502 U=0000 S=0200 DP=30 M=7F T=D7D7 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=? DZ=? IL=1 FM=1 NM=1
memory modelling failed at   F7FB: expected D7 actual D8
04167B68 00 3F 1 1 00 7
04167B69 01 4A 1 0 00 8
04167B6A 02 4A 1 0 00 8
04167B6B 03 08 0 0 00 F
04167B6C 04 7E 0 0 00 E
04167B6D 05 00 0 0 00 D
04167B6E 06 00 0 0 00 C
04167B6F 07 02 0 0 00 B
04167B70 08 35 0 0 00 A
04167B71 09 80 0 0 00 9
04167B72 0A 7E 0 0 00 8
04167B73 0B 30 0 0 00 7
04167B74 0C 4D 0 0 00 6
04167B75 0D 2E 0 0 00 5
04167B76 0E 63 0 0 00 4
04167B77 0F 55 0 0 00 3
04167B78 10 D1 0 0 00 2
04167B79 11 4A 1 0 00 F
04167B7A 12 C0 1 0 10 C
04167B7B 13 D8 1 0 10 D
04167B7C 14 D8 1 0 00 F
7E07 : 3F             : SWI                  :  21 : A=55 B=63 E=2E F=4D X=7E80 Y=3502 U=0000 S=01F2 DP=30 M=7F T=D7D7 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=? IL=1 FM=1 NM=1 : Prediction failed for: AddrPointer,Memory,Vector
memory modelling failed at   C0D8: expected 7E actual D8
04167B7D 00 D8 1 1 00 F
04167B7E 01 C0 1 0 00 9
04167B7F 02 00 1 0 00 0
C0D8 : D8 C0          : EORB  $C0            :   3 : A=55 B=63 E=2E F=4D X=7E80 Y=3502 U=0000 S=01F2 DP=30 M=7F T=D7D7 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=? IL=1 FM=1 NM=1 : Prediction failed for: AddrInstr,Memory
04167B80 00 00 1 1 00 A
04167B81 01 7E 1 0 00 B
04167B82 02 10 1 0 00 E
04167B83 03 10 1 0 00 F
04167B84 04 F0 0 0 00 E
C0DA : 00 7E          : NEG   $7E            :   5 : A=55 B=63 E=2E F=4D X=7E80 Y=3502 U=0000 S=01F2 DP=30 M=F0 T=D7D7 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=1 DZ=? IL=1 FM=1 NM=1

The second example was found in 20220728b/random4-E.bin:

0085 : 13             : SYNC                 :   4 : A=6E B=00 E=2C F=1F X=7E80 Y=0200 U=6C00 S=01FC DP=00 M=E4 T=0000 E=1 F=1 H=1 I=1 N=1 Z=0 V=0 C=1 DZ=? IL=1 FM=? NM=1
memory modelling failed at   F7FB: expected E3 actual E5
038ABD2F 00 3F 1 1 00 6
038ABD30 01 13 1 0 00 7
038ABD31 02 13 1 0 00 7
038ABD32 03 87 0 0 00 B
038ABD33 04 00 0 0 00 A
038ABD34 05 00 0 0 00 9
038ABD35 06 6C 0 0 00 8
038ABD36 07 00 0 0 00 7
038ABD37 08 02 0 0 00 6
038ABD38 09 80 0 0 00 5
038ABD39 0A 7E 0 0 00 4
038ABD3A 0B 00 0 0 00 3
038ABD3B 0C 1F 0 0 00 2
038ABD3C 0D 2C 0 0 00 1
038ABD3D 0E 00 0 0 00 0
038ABD3E 0F 6E 0 0 00 F
038ABD3F 10 F9 0 0 00 E
038ABD40 11 13 1 0 00 F
038ABD41 12 C0 1 0 10 C
038ABD42 13 E5 1 0 10 D
038ABD43 14 E5 1 0 00 F
0086 : 3F             : SWI                  :  21 : A=6E B=00 E=2C F=1F X=7E80 Y=0200 U=6C00 S=01EE DP=00 M=E4 T=0000 E=1 F=1 H=1 I=1 N=1 Z=0 V=0 C=1 DZ=? IL=1 FM=? NM=1 : Prediction failed for: AddrPointer,Memory,Vector
memory modelling failed at   C0E5: expected 12 actual E5
038ABD44 00 E5 1 1 00 F
038ABD45 01 7E 1 0 00 6
038ABD46 02 C0 1 0 00 7
038ABD47 03 C0 1 0 00 F
038ABD48 04 00 1 0 00 C
C0E5 : E5 7E          : BITB  -$02,S         :   5 : A=6E B=00 E=2C F=1F X=7E80 Y=0200 U=6C00 S=01EE DP=00 M=E4 T=0000 E=1 F=1 H=1 I=1 N=0 Z=1 V=0 C=1 DZ=? IL=1 FM=? NM=1 : Prediction failed for: AddrInstr,Memory
038ABD49 00 C0 1 1 00 7
038ABD4A 01 00 1 0 00 8
C0E7 : C0 00          : SUBB  #$00           :   2 : A=6E B=00 E=2C F=1F X=7E80 Y=0200 U=6C00 S=01EE DP=00 M=E4 T=0000 E=1 F=1 H=1 I=1 N=0 Z=1 V=0 C=0 DZ=? IL=1 FM=? NM=1

The third example was found in 20220728c/random5-E.bin, and affects CWAI rather than SWI:

7E27 : 13             : SYNC                 :   4 : A=D8 B=FF E=00 F=00 X=0000 Y=0000 U=3FFE S=D2D2 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=1 Z=0 V=0 C=0 DZ=0 IL=1 FM=? NM=1
03E354CB 00 54 1 ? 00 8
7E28 : 54             : LSRB                 :   1 : A=D8 B=7F E=00 F=00 X=0000 Y=0000 U=3FFE S=D2D2 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=? NM=1
03E354CC 00 5A 1 ? 00 9
7E29 : 5A             : DECB                 :   1 : A=D8 B=7E E=00 F=00 X=0000 Y=0000 U=3FFE S=D2D2 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=1 DZ=0 IL=1 FM=? NM=1
03E354CD 00 3C 1 ? 00 A
03E354CE 01 CC 1 ? 00 B
03E354CF 02 09 1 ? 00 C
03E354D0 03 09 1 ? 00 F
03E354D1 04 2C 0 ? 00 1
03E354D2 05 7E 0 ? 00 0
03E354D3 06 FE 0 ? 00 F
03E354D4 07 3F 0 ? 00 E
03E354D5 08 00 0 ? 00 D
03E354D6 09 00 0 ? 00 C
03E354D7 0A 00 0 ? 00 B
03E354D8 0B 00 0 ? 00 A
03E354D9 0C 00 0 ? 00 9
03E354DA 0D 00 0 ? 00 8
03E354DB 0E 00 0 ? 00 7
03E354DC 0F 7E 0 ? 00 6
03E354DD 10 D8 0 ? 00 5
03E354DE 11 C0 0 ? 00 4
03E354DF 12 00 1 ? 00 F
03E354E0 13 C0 1 ? 10 C
03E354E1 14 E5 1 ? 10 D
03E354E2 15 E5 1 ? 00 F
7E2A : 3C CC          : CWAI  #$CC           :  22 : A=D8 B=7E E=00 F=00 X=0000 Y=0000 U=3FFE S=D2C4 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=? NM=1
memory modelling failed at   C0E5: expected 12 actual E5
03E354E3 00 E5 1 ? 00 F
03E354E4 01 7E 1 ? 00 6
03E354E5 02 C0 1 ? 00 7
03E354E6 03 C0 1 ? 00 F
03E354E7 04 00 1 ? 00 2
C0E5 : E5 7E          : BITB  -$02,S         :   5 : A=D8 B=7E E=00 F=00 X=0000 Y=0000 U=3FFE S=D2C4 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=0 Z=1 V=0 C=0 DZ=0 IL=1 FM=? NM=1 : Prediction failed for: AddrInstr,Memory
03E354E8 00 C0 1 ? 00 7
03E354E9 01 00 1 ? 00 8
C0E7 : C0 00          : SUBB  #$00           :   2 : A=D8 B=7E E=00 F=00 X=0000 Y=0000 U=3FFE S=D2C4 DP=00 M=FF T=0000 E=1 F=1 H=0 I=1 N=0 Z=0 V=0 C=0 DZ=0 IL=1 FM=? NM=1

What appears to be happening in each case:

  • all three examples captures so-far have been in native mode
  • the PC that is pushed is that of the following instruction (so the current instruction will not be re-executed).
  • the vector fetch is always FFFC/FFFD which is the NMI vector (C0D8 in the first example, C0E5 in the others)
  • the first byte of the NMI handler is not fetched correctly - it looks like the bus cycle is a dummy one, and so the data bus remains at the low byte of the vector
  • there is strong evidence that the CPU actually executes the vector LSB on the floating data bus as the first instruction of the NMI handler.

The correct NMI handler is:

C0E5                  NMI_HANDLER
C0E5  12                    NOP
C0E6  7EC000                JMP RESET

This is a pretty nasty bug - at worst it will cause a crash. At best it will cause the SWI to be skipped.

A work around for the crash would be to place the NMI handler at such an address that the LSB of the vector matches the first byte of of the NMI handler.

⚠️ **GitHub.com Fallback** ⚠️