|
3 | 3 | // by Naomi Peori (naomi@peori.ca) |
4 | 4 | // |
5 | 5 |
|
| 6 | +#include <functional> |
6 | 7 | #include "MOS6502/MOS6502.h" |
7 | 8 |
|
8 | 9 | // |
@@ -62,47 +63,104 @@ void MOS6502::RunIllegal(BYTE opcode) { |
62 | 63 |
|
63 | 64 | // --------------------------------------------------------------- |
64 | 65 | // SHY — Store Y & (addr_high + 1), Absolute, X |
| 66 | + // On page-cross the effective address's high byte is corrupted to v. |
65 | 67 | // --------------------------------------------------------------- |
66 | 68 |
|
67 | 69 | case 0x9C: { |
68 | 70 | AB.l = Fetch(); |
69 | 71 | AB.h = Fetch(); |
70 | | - BYTE v = Y & (AB.h + 1); |
| 72 | + BYTE argHigh = AB.h; |
| 73 | + BYTE v = Y & (argHigh + 1); |
71 | 74 | AB = IdleOnPageAlways(AB, X); |
72 | 75 | PollInterrupts(); |
| 76 | + if (AB.h != argHigh) { AB.h = v; } |
73 | 77 | Store(AB.w, v); |
74 | 78 | break; |
75 | 79 | } |
76 | 80 |
|
77 | 81 | // --------------------------------------------------------------- |
78 | 82 | // SHX — Store X & (addr_high + 1), Absolute, Y |
| 83 | + // On page-cross the effective address's high byte is corrupted to v. |
79 | 84 | // --------------------------------------------------------------- |
80 | 85 |
|
81 | 86 | case 0x9E: { |
82 | 87 | AB.l = Fetch(); |
83 | 88 | AB.h = Fetch(); |
84 | | - BYTE v = X & (AB.h + 1); |
| 89 | + BYTE argHigh = AB.h; |
| 90 | + BYTE v = X & (argHigh + 1); |
85 | 91 | AB = IdleOnPageAlways(AB, Y); |
86 | 92 | PollInterrupts(); |
| 93 | + if (AB.h != argHigh) { AB.h = v; } |
87 | 94 | Store(AB.w, v); |
88 | 95 | break; |
89 | 96 | } |
90 | 97 |
|
91 | 98 | // --------------------------------------------------------------- |
92 | 99 | // TAS — S = A & X; store S & (addr_high + 1), Absolute, Y |
| 100 | + // On page-cross the effective address's high byte is corrupted to v. |
93 | 101 | // --------------------------------------------------------------- |
94 | 102 |
|
95 | 103 | case 0x9B: { |
96 | 104 | AB.l = Fetch(); |
97 | 105 | AB.h = Fetch(); |
| 106 | + BYTE argHigh = AB.h; |
98 | 107 | S = A & X; |
99 | | - BYTE v = S & (AB.h + 1); |
| 108 | + BYTE v = S & (argHigh + 1); |
100 | 109 | AB = IdleOnPageAlways(AB, Y); |
101 | 110 | PollInterrupts(); |
| 111 | + if (AB.h != argHigh) { AB.h = v; } |
102 | 112 | Store(AB.w, v); |
103 | 113 | break; |
104 | 114 | } |
105 | 115 |
|
| 116 | + // --------------------------------------------------------------- |
| 117 | + // SHA — Store A & X & (addr_high + 1) |
| 118 | + // On page-cross the effective address's high byte is corrupted to v. |
| 119 | + // --------------------------------------------------------------- |
| 120 | + |
| 121 | + case 0x9F: { // Absolute, Y |
| 122 | + AB.l = Fetch(); |
| 123 | + AB.h = Fetch(); |
| 124 | + BYTE argHigh = AB.h; |
| 125 | + BYTE v = A & X & (argHigh + 1); |
| 126 | + AB = IdleOnPageAlways(AB, Y); |
| 127 | + PollInterrupts(); |
| 128 | + if (AB.h != argHigh) { AB.h = v; } |
| 129 | + Store(AB.w, v); |
| 130 | + break; |
| 131 | + } |
| 132 | + |
| 133 | + case 0x93: { // Indirect, Y |
| 134 | + TB.w = Fetch(); |
| 135 | + AB.l = Load(TB.w); |
| 136 | + TB.l += 1; |
| 137 | + AB.h = Load(TB.w); |
| 138 | + BYTE argHigh = AB.h; |
| 139 | + BYTE v = A & X & (argHigh + 1); |
| 140 | + AB = IdleOnPageAlways(AB, Y); |
| 141 | + PollInterrupts(); |
| 142 | + if (AB.h != argHigh) { AB.h = v; } |
| 143 | + Store(AB.w, v); |
| 144 | + break; |
| 145 | + } |
| 146 | + |
| 147 | + // --------------------------------------------------------------- |
| 148 | + // ANE / XAA — A = (A | magic) & X & #imm (unstable on hardware) |
| 149 | + // LXA — A = X = (A | magic) & #imm (unstable on hardware) |
| 150 | + // The "magic" constant varies by die/temperature; 0xEE is the value |
| 151 | + // Blargg's test ROMs assume. |
| 152 | + // --------------------------------------------------------------- |
| 153 | + |
| 154 | + case 0x8B: |
| 155 | + PollInterrupts(); |
| 156 | + A = Flags((A | 0xEE) & X & Fetch()); |
| 157 | + break; |
| 158 | + |
| 159 | + case 0xAB: |
| 160 | + PollInterrupts(); |
| 161 | + A = X = Flags((A | 0xEE) & Fetch()); |
| 162 | + break; |
| 163 | + |
106 | 164 | // --------------------------------------------------------------- |
107 | 165 | // DCP — DEC, then CMP |
108 | 166 | // --------------------------------------------------------------- |
|
0 commit comments