]> Shamusworld >> Repos - stargem2/blob - src/v6808.cpp
e9c4253dce603a899047ad7a3d98b1729073590c
[stargem2] / src / v6808.cpp
1 //
2 // Virtual 6808 Emulator v1.2
3 //
4 // by James L. Hammons
5 // (c) 2006 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  06/15/2006  Added changelog ;-)
12 // JLH  06/15/2006  Scrubbed all BYTE, WORD & DWORD references from the code
13 //
14
15 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
16
17 //#define __DEBUG__
18
19 #include "v6808.h"
20
21 #ifdef __DEBUG__
22 #include "dis6808.h"
23 #include "log.h"
24 #endif
25
26 // Private global variables
27
28 static V6808REGS regs;
29 static uint16 addr;
30 static uint8 tmp;
31
32 static uint8 CPUCycles[256] = {
33         1,  2,  1,  1,  1,  1,  2,  2,  4,  4,  2,  2,  2,  2,  2,  2,
34         2,  2,  1,  1,  1,  1,  2,  2,  1,  2,  1,  2,  1,  1,  1,  1,
35         4,  1,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
36         4,  4,  4,  4,  4,  4,  4,  4,  1,  5,  1, 10,  1,  1,  9, 12,
37         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,
38         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,
39         7,  1,  1,  8,  7,  1,  7,  7,  7,  7,  7,  1,  7,  7,  4,  7,
40         6,  1,  1,  7,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,
41         2,  2,  2,  1,  2,  2,  2,  1,  2,  2,  2,  2,  3,  8,  3,  1,
42         3,  3,  3,  1,  3,  3,  3,  4,  3,  3,  3,  3,  4,  1,  4,  5,
43         5,  5,  5,  1,  5,  5,  5,  6,  5,  5,  5,  5,  6,  8,  6,  7,
44         4,  4,  4,  1,  4,  4,  4,  5,  4,  4,  4,  4,  5,  9,  5,  6,
45         2,  2,  2,  1,  2,  2,  2,  1,  2,  2,  2,  2,  1,  1,  3,  1,
46         3,  3,  3,  1,  3,  3,  3,  4,  3,  3,  3,  3,  1,  1,  4,  5,
47         5,  5,  5,  1,  5,  5,  5,  6,  5,  5,  5,  5,  1,  1,  6,  7,
48         4,  4,  4,  1,  4,  4,  4,  5,  4,  4,  4,  4,  1,  1,  5,  6
49 };
50
51 // Private function prototypes
52
53 static uint16 FetchW(void);
54 static uint16 RdMemW(uint16);
55 static void WrMemW(uint16, uint16);
56
57 //
58 // Fetch a word out of 6808 memory (little endian format)
59 // This is a leftover from when fetches were separated from garden variety reads...
60 //
61 static uint16 FetchW()
62 {
63         uint16 w = RdMemW(regs.pc);
64         regs.pc += 2;
65         return w;
66 }
67
68 //
69 // Read a word out of 6808 memory (little endian format)
70 //
71 static uint16 RdMemW(uint16 address)
72 {
73         return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
74 }
75
76 //
77 // Write a word into 6808 memory (little endian format)
78 //
79 static void WrMemW(uint16 address, uint16 w)
80 {
81         regs.WrMem(address + 0, w >> 8);
82         regs.WrMem(address + 1, w & 0xFF);
83 }
84
85 //
86 // Function to decode IDX data
87 //
88 inline uint16 DecodeIDX(uint8 code)
89 {
90         return regs.x + code;
91 }
92
93
94 //
95 // Opcode Functions (Mostly correct... Yikes!)
96 //
97
98 static void Op01(void)                                                  // NOP
99 {
100 }
101
102 static void Op06(void)                                                  // TAP
103 {
104         regs.cc = regs.a;
105 }
106
107 static void Op07(void)                                                  // TPA
108 {
109         regs.a = regs.cc;
110 }
111
112 static void Op08(void)                                                  // INX
113 {
114         regs.x++;
115
116         (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
117 }
118
119 static void Op09(void)                                                  // DEX
120 {
121         regs.x--;
122
123         (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
124 }
125
126 static void Op0A(void)                                                  // CLV
127 {
128         regs.cc &= ~FLAG_V;
129 }
130
131 static void Op0B(void)                                                  // SEV
132 {
133         regs.cc |= FLAG_V;
134 }
135
136 static void Op0C(void)                                                  // CLC
137 {
138         regs.cc &= ~FLAG_C;
139 }
140
141 static void Op0D(void)                                                  // SEC
142 {
143         regs.cc |= FLAG_C;
144 }
145
146 static void Op0E(void)                                                  // CLI
147 {
148         regs.cc &= ~FLAG_I;
149 }
150
151 static void Op0F(void)                                                  // SEI
152 {
153         regs.cc |= FLAG_I;
154 }
155
156 static void Op10(void)                                                  // SBA
157 {
158         uint8 as = regs.a; 
159         regs.a -= regs.b;
160
161         regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C);        // Clear NZVC
162
163         if (as < regs.b)
164                 regs.cc |= FLAG_C;
165
166         if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
167                 regs.cc |= FLAG_V;
168
169         if (regs.a == 0)
170                 regs.cc |= FLAG_Z;
171
172         if (regs.a & 0x80)
173                 regs.cc |= FLAG_N;
174 }
175
176 static void Op11(void)                                                  // CBA (Compare B to A)
177 {
178         tmp = regs.a - regs.b;
179
180         regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C);        // Clear NZVC
181
182         if (regs.a < regs.b)
183                 regs.cc |= FLAG_C;
184
185         if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
186                 regs.cc |= FLAG_V;
187
188         if (regs.a == 0)
189                 regs.cc |= FLAG_Z;
190
191         if (regs.a & 0x80)
192                 regs.cc |= FLAG_N;
193 }
194
195 static void Op16(void)                                                  // TAB
196 {
197         regs.b = regs.a;
198
199         regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);         // Clear NZV
200
201         if (regs.b == 0)
202                 regs.cc |= FLAG_Z;
203
204         if (regs.b & 0x80)
205                 regs.cc |= FLAG_N;
206 }
207
208 static void Op17(void)                                                  // TBA
209 {
210         regs.a = regs.b;
211
212         regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);         // Clear NZV
213
214         if (regs.a == 0)
215                 regs.cc |= FLAG_Z;
216
217         if (regs.a & 0x80)
218                 regs.cc |= FLAG_N;
219 }
220
221 static void Op19(void)                                                  // DAA
222 {
223   addr = regs.a;
224 //  if (regs.cc&0x20)              addr += 6;    // H set? adjust
225   if ((addr&0x000F) > 9)     addr += 6;
226   if (regs.cc&0x01)              addr += 0x60; // C set? adjust
227   if ((addr&0x00F0) > 0x90)  addr += 0x60;
228   regs.cc &= 0xFD;                             // CLV
229   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
230   regs.a = addr;
231   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag 
232   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag 
233 }
234
235 static void Op1B(void)                                                  // ABA
236 {
237   addr = regs.a + regs.b;
238   regs.cc &= 0xF0;
239   if (addr > 0xFF)  regs.cc |= 0x01;    // Set Carry flag
240   if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80)  regs.cc |= 0x02; // Set oVerflow 
241   regs.a = addr;                        // Set accumulator
242   if (regs.a == 0)      regs.cc |= 0x04;    // Set Zero flag
243   if (regs.a&0x80)      regs.cc |= 0x08;    // Set Negative flag
244 }
245
246 static void Op20(void)                                                  // BRA (BRanch Always)
247 {
248         regs.pc += (int16)(int8)regs.RdMem(regs.pc++);
249 }
250
251 static void Op22(void)                                                  // BHI
252 {
253         tmp = regs.RdMem(regs.pc++);
254
255         if (!(regs.cc & (FLAG_C | FLAG_Z)))
256                 regs.pc += (signed short int)(signed char)tmp;
257 }
258
259 static void Op23(void)                                                  // BLS
260 {
261         tmp = regs.RdMem(regs.pc++);
262
263         if (regs.cc & (FLAG_C | FLAG_Z))
264                 regs.pc += (signed short int)(signed char)tmp;
265 }
266
267 static void Op24(void)                                                  // BCC (BHS)
268 {
269   tmp = regs.RdMem(regs.pc++);
270   if (!(regs.cc&0x01))  regs.pc += (signed short int)(signed char)tmp;
271 }
272
273 static void Op25(void)                                                  // BCS (BLO)
274 {
275   tmp = regs.RdMem(regs.pc++);
276   if (regs.cc&0x01)  regs.pc += (signed short int)(signed char)tmp;
277 }
278
279 static void Op26(void)                                                  // BNE
280 {
281   tmp = regs.RdMem(regs.pc++);
282   if (!(regs.cc&0x04))  regs.pc += (signed short int)(signed char)tmp;
283 }
284
285 static void Op27(void)                                                  // BEQ
286 {
287   tmp = regs.RdMem(regs.pc++);
288   if (regs.cc&0x04)  regs.pc += (signed short int)(signed char)tmp;
289 }
290
291 static void Op28(void)                                                  // BVC
292 {
293   tmp = regs.RdMem(regs.pc++);
294   if (!(regs.cc&0x02))  regs.pc += (signed short int)(signed char)tmp;
295 }
296
297 static void Op29(void)                                                  // BVS
298 {
299   tmp = regs.RdMem(regs.pc++);
300   if (regs.cc&0x02)  regs.pc += (signed short int)(signed char)tmp;
301 }
302
303 static void Op2A(void)                                                  // BPL
304 {
305   tmp = regs.RdMem(regs.pc++);
306   if (!(regs.cc&0x08))  regs.pc += (signed short int)(signed char)tmp;
307 }
308
309 static void Op2B(void)                                                  // BMI
310 {
311   tmp = regs.RdMem(regs.pc++);
312   if (regs.cc&0x08)  regs.pc += (signed short int)(signed char)tmp;
313 }
314
315 static void Op2C(void)                                                  // BGE
316 {
317   tmp = regs.RdMem(regs.pc++);
318   if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += (signed short int)(signed char)tmp;
319 }
320
321 static void Op2D(void)                                                  // BLT
322 {
323   tmp = regs.RdMem(regs.pc++);
324   if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))  regs.pc += (signed short int)(signed char)tmp;
325 }
326
327 static void Op2E(void)                                                  // BGT
328 {
329   tmp = regs.RdMem(regs.pc++);
330   if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))))  regs.pc += (signed short int)(signed char)tmp;
331 }
332
333 static void Op2F(void)                                                  // BLE
334 {
335   tmp = regs.RdMem(regs.pc++);
336   if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))  regs.pc += (signed short int)(signed char)tmp;
337 }
338
339 static void Op30(void)                                                  // TSX
340 {
341   regs.x = regs.s;
342 }
343
344 static void Op31(void)                                                  // INS
345 {
346   regs.s++;
347 }
348
349 static void Op32(void)                                                  // PULA
350 {
351   regs.a  = regs.RdMem(regs.s++);
352 }
353
354 static void Op33(void)                                                  // PULB
355 {
356   regs.b  = regs.RdMem(regs.s++);
357 }
358
359 static void Op34(void)                                                  // DES
360 {
361   regs.s--;
362 }
363
364 static void Op35(void)                                                  // TXS
365 {
366   regs.s = regs.x;
367 }
368
369 static void Op36(void)                                                  // PSHA
370 {
371         regs.WrMem(--regs.s, regs.a);
372 }
373
374 static void Op37(void)                                                  // PSHB
375 {
376         regs.WrMem(--regs.s, regs.b);
377 }
378
379 static void Op39(void)                                                  // RTS
380 {
381         regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
382 }
383
384 static void Op3B(void)                                                  // RTI
385 {
386         regs.cc = regs.RdMem(regs.s++);
387         regs.a  = regs.RdMem(regs.s++);
388         regs.b  = regs.RdMem(regs.s++);
389         regs.x  = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
390         regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
391 }
392
393 static void Op3E(void)                                                  // WAI (wait for interrupt)
394 {
395         regs.cc &= regs.RdMem(regs.pc++);
396         regs.cc |= 0x80;//???Is this right???
397 }
398
399 static void Op3F(void)                                                  // SWI (software interrupt)
400 {
401 //Does this respect the I flag???
402         regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
403         regs.WrMem(--regs.s, regs.pc >> 8);
404         regs.WrMem(--regs.s, regs.x & 0xFF);
405         regs.WrMem(--regs.s, regs.x >> 8);
406         regs.WrMem(--regs.s, regs.b);
407         regs.WrMem(--regs.s, regs.a);
408         regs.WrMem(--regs.s, regs.cc);
409         regs.pc = RdMemW(0xFFFA);                                       // And do it!
410
411         regs.cc |= FLAG_I;                                                      // Also, set IRQ inhibit
412 }
413
414 static void Op40(void)                                                  // NEGA
415
416   regs.a = 256 - regs.a;  regs.cc &= 0xF0;
417   if (regs.a > 0x7F)   regs.cc |= 0x01;   // Set Carry
418   if (regs.a == 0x80)  regs.cc |= 0x02;   // Set oVerflow
419   if (regs.a == 0)     regs.cc |= 0x04;   // Set Zero flag
420   if (regs.a&0x80)     regs.cc |= 0x08;   // Set Negative flag
421 }
422
423 static void Op43(void)                                                  // COMA
424 {
425   regs.a ^= 0xFF;
426   regs.cc &= 0xF0;  regs.cc |= 0x01;                    // CLV, SEC
427   if (regs.a == 0)  regs.cc |= 0x04;                    // Set Zero flag
428   if (regs.a&0x80)  regs.cc |= 0x08;                    // Set Negative flag
429 }
430
431 static void Op44(void)                                                  // LSRA
432 {
433   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
434   regs.a >>= 1;
435   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
436   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
437 }
438
439 static void Op46(void)  // RORA
440 {
441   tmp = regs.a;  regs.a = (tmp>>1) + (regs.cc&0x01)*128;
442   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
443   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
444   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
445 }
446
447 static void Op47(void)  // ASRA
448 {
449   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
450   regs.a >>= 1;                               // Do the shift
451   if (regs.a&0x40)  regs.a |= 0x80;               // Set neg if it was set
452   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
453   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
454 }
455
456 static void Op48(void)  // LSLA (ASLA) [Keep checking from here...]
457 {
458   (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
459   regs.a <<= 1;
460   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
461   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
462 }
463
464 static void Op49(void)  // ROLA  
465 {
466   tmp = regs.a;  regs.a = (tmp<<1) + (regs.cc&0x01);
467   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
468   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
469   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
470 }
471
472 static void Op4A(void)  // DECA
473 {
474   regs.a--;
475   (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
476   (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
477   (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
478 }
479
480 static void Op4C(void)  // INCA
481 {
482 regs.a++;
483 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
484 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
485 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
486 }
487
488 static void Op4D(void)  // TSTA
489 {
490 regs.cc &= 0xFD;                            // Clear oVerflow flag
491 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
492 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
493 }
494
495 static void Op4F(void)  // CLRA
496 {
497   regs.a = 0;
498   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
499 }
500
501 static void Op50(void)  // NEGB
502
503 regs.b = 256 - regs.b;
504 //        ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
505 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
506 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
507 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
508 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
509 }
510
511 static void Op53(void)  // COMB
512 {
513 regs.b ^= 0xFF;
514 regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
515 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
516 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
517 }
518
519 static void Op54(void)  // LSRB
520 {
521 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
522 regs.b >>= 1;
523 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
524 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
525 }
526
527 static void Op56(void)  // RORB
528 {
529 tmp = regs.b;  regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
530 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
531 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
532 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
533 }
534
535 static void Op57(void)  // ASRB
536 {
537 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
538 regs.b >>= 1;                               // Do the shift
539 if (regs.b&0x40)  regs.b |= 0x80;               // Set neg if it was set
540 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
541 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
542 }
543
544 static void Op58(void)  // LSLB
545 {
546 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
547 regs.b <<= 1;
548 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
549 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
550 }
551
552 static void Op59(void)  // ROLB
553 {
554   tmp = regs.b;
555   regs.b = (tmp<<1) + (regs.cc&0x01);
556   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
557   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
558   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
559 }
560
561 static void Op5A(void)  // DECB
562 {
563 regs.b--;
564 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
565 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
566 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
567 }
568
569 static void Op5C(void)  // INCB
570 {
571 regs.b++;
572 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag 
573 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
574 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
575 }
576
577 static void Op5D(void)  // TSTB
578 {
579 regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
580 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
581 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
582 }
583
584 static void Op5F(void)  // CLRB
585 {
586 regs.b = 0;
587 regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
588 }
589
590 static void Op60(void)  // NEG IDX
591
592 addr = DecodeIDX(regs.RdMem(regs.pc++));
593 tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
594 regs.WrMem(addr, res);
595 //        ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
596 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
597 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
598 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
599 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
600 }
601
602 static void Op63(void)  // COM IDX
603 {
604 addr = DecodeIDX(regs.RdMem(regs.pc++));
605 tmp = regs.RdMem(addr) ^ 0xFF;
606 regs.WrMem(addr, tmp);
607 regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
608 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
609 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
610 }
611
612 static void Op64(void)  // LSR IDX
613 {
614 addr = DecodeIDX(regs.RdMem(regs.pc++));
615 tmp = regs.RdMem(addr);
616 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
617 tmp >>= 1;  regs.WrMem(addr, tmp);
618 regs.cc &= 0xF7;                             // CLN
619 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
620 }
621
622 static void Op66(void)  // ROR IDX
623 {
624 addr = DecodeIDX(regs.RdMem(regs.pc++));
625 tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
626 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
627 regs.WrMem(addr, tmp);
628 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
629 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
630 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
631 }
632
633 static void Op67(void)  // ASR IDX
634 {
635 addr = DecodeIDX(regs.RdMem(regs.pc++));
636 tmp = regs.RdMem(addr);
637 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
638 tmp >>= 1;
639 if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
640 regs.WrMem(addr, tmp);
641 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
642 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
643 }
644
645 static void Op68(void)  // LSL IDX
646 {
647 addr = DecodeIDX(regs.RdMem(regs.pc++));
648 tmp = regs.RdMem(addr);
649 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
650 tmp <<= 1;
651 regs.WrMem(addr, tmp);
652 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
653 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
654 }
655
656 static void Op69(void)  // ROL IDX
657 {
658   uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
659   tmp = (tmp2<<1) + (regs.cc&0x01);
660   regs.WrMem(addr, tmp);
661   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
662   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
663   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
664 }
665
666 static void Op6A(void)  // DEC IDX
667 {
668 uint8 tmp;  uint16 addr;
669 addr = DecodeIDX(regs.RdMem(regs.pc++));
670 tmp = regs.RdMem(addr) - 1;
671 regs.WrMem(addr, tmp);
672 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
673 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
674 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
675 }
676
677 static void Op6C(void)  // INC IDX
678 {       
679 addr = DecodeIDX(regs.RdMem(regs.pc++));
680 tmp = regs.RdMem(addr) + 1;
681 regs.WrMem(addr, tmp);
682 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
683 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
684 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
685 }
686
687 static void Op6D(void)  // TST IDX
688 {
689 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
690 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag 
691 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag 
692 }
693
694 static void Op6E(void)  // JMP IDX
695 {
696   regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
697 }
698
699 static void Op6F(void)  // CLR IDX
700 {
701   addr = DecodeIDX(regs.RdMem(regs.pc++));
702   regs.WrMem(addr, 0);
703   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
704 }
705
706 static void Op70(void)  // NEG ABS
707
708 addr = FetchW();
709 tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
710 regs.WrMem(addr, res);
711 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
712 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
713 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
714 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
715 }
716
717 static void Op73(void)  // COM ABS
718 {
719 addr = FetchW();
720 tmp = regs.RdMem(addr) ^ 0xFF;
721 regs.WrMem(addr, tmp);
722 regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
723 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
724 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
725 }
726
727 static void Op74(void)  // LSR ABS
728 {
729 addr = FetchW();
730 tmp = regs.RdMem(addr);
731 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into Carry
732 tmp >>= 1;  regs.WrMem(addr, tmp);
733 regs.cc &= 0xF7;                             // CLN
734 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
735 }
736
737 static void Op76(void)  // ROR ABS
738 {
739 uint8 tmp;  uint16 addr;
740 addr = FetchW();
741 tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
742 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
743 regs.WrMem(addr, tmp);
744 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
745 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
746 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
747 }
748
749 static void Op77(void)  // ASR ABS
750 {
751 uint8 tmp;  uint16 addr;
752 addr = FetchW();
753 tmp = regs.RdMem(addr);
754 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into Carry
755 tmp >>= 1;
756 if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
757 regs.WrMem(addr, tmp);
758 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
759 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
760 }
761
762 static void Op78(void)  // LSL ABS
763 {
764 uint8 tmp;  uint16 addr;
765 addr = FetchW();
766 tmp = regs.RdMem(addr);
767 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into Carry
768 tmp <<= 1;
769 regs.WrMem(addr, tmp);
770 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
771 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
772 }
773
774 static void Op79(void)  // ROL ABS
775 {
776   uint8 tmp2 = regs.RdMem(FetchW());
777   tmp = (tmp2<<1) + (regs.cc&0x01);
778   regs.WrMem(addr, tmp);
779   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
780   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
781   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
782 }
783
784 static void Op7A(void)  // DEC ABS
785 {
786 uint8 tmp;  uint16 addr;
787 addr = FetchW();
788 tmp = regs.RdMem(addr) - 1;
789 regs.WrMem(addr, tmp);
790 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
791 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
792 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
793 }
794
795 static void Op7C(void)                                                                  // INC ABS
796 {       
797         addr = FetchW();
798         tmp = regs.RdMem(addr) + 1;
799         regs.WrMem(addr, tmp);
800
801         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
802         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
803         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
804 }
805
806 static void Op7D(void)                                                                  // TST ABS
807 {
808         uint8 tmp = regs.RdMem(FetchW());
809
810         (tmp == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);               // Adjust Zero flag 
811         (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);               // Adjust Negative flag 
812 }
813
814 static void Op7E(void)                                                                  // JMP ABS
815 {
816         regs.pc = FetchW();
817 }
818
819 static void Op7F(void)  // CLR ABS
820 {
821 regs.WrMem(FetchW(), 0);
822 regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
823 }
824
825 static void Op80(void)  // SUBA #
826
827   uint8 tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a; 
828   regs.a -= tmp;
829   (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
830   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
831   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
832   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
833 }
834
835 static void Op81(void)  // CMPA #
836 {
837   tmp = regs.RdMem(regs.pc++);
838   uint8 db = regs.a - tmp;
839   (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
840   ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
841   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
842   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
843 }
844
845 static void Op82(void)  // SBCA #
846 {
847   tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a; 
848   regs.a = regs.a - tmp - (regs.cc&0x01);
849   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
850   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
851   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
852   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
853 }
854
855 static void Op84(void)  // ANDA #
856 {
857 regs.a &= regs.RdMem(regs.pc++);
858 regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
859 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
860 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
861 }
862
863 static void Op85(void)  // BITA #
864 {
865 tmp = regs.a & regs.RdMem(regs.pc++);
866 regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
867 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
868 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
869 }
870
871 static void Op86(void)  // LDAA #
872 {
873 regs.a = regs.RdMem(regs.pc++);
874 regs.cc &= 0xFD;                            // CLV
875 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
876 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
877 }
878
879 static void Op88(void)  // EORA #
880 {
881 regs.a ^= regs.RdMem(regs.pc++);
882 regs.cc &= 0xFD;                            // CLV
883 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
884 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
885 }
886
887 static void Op89(void)  // ADCA #
888 {
889   tmp = regs.RdMem(regs.pc++);
890   addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
891   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
892 //    ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half Carry
893   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
894   regs.a = addr & 0xFF;                       // Set accumulator
895   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
896   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
897 }
898
899 static void Op8A(void)  // ORAA #
900 {
901 regs.a |= regs.RdMem(regs.pc++);
902 regs.cc &= 0xFD;                            // CLV
903 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
904 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
905 }
906
907 static void Op8B(void)  // ADDA #
908 {       
909   tmp = regs.RdMem(regs.pc++);  addr = regs.a + tmp;
910   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
911   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
912   regs.a = addr & 0xFF;                       // Set accumulator
913   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
914   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
915 }
916
917 static void Op8C(void)  // CPX #
918 {
919         addr = FetchW();
920         uint16 dw = regs.x - addr;
921         (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
922         ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
923         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
924         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
925 }
926
927 static void Op8D(void)                                                                  // BSR
928 {
929         tmp = regs.RdMem(regs.pc++);
930
931         regs.s -= 2;
932         WrMemW(regs.s, regs.pc);
933
934         regs.pc += (signed short int)(signed char)tmp;
935 }
936
937 static void Op8E(void)  // LDS #
938 {
939 regs.s = FetchW();
940 regs.cc &= 0xFD;                              // CLV
941 (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
942 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
943 }
944
945 static void Op90(void)  // SUBA ZP
946
947   tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 as = regs.a; 
948   regs.a -= tmp;
949   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
950   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
951   (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
952   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
953 }
954
955 static void Op91(void)  // CMPA ZP
956 {
957 tmp = regs.RdMem(regs.RdMem(regs.pc++));
958 uint8 db = regs.a - tmp;
959 (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
960 (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
961 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
962 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
963 }
964
965 static void Op92(void)  // SBCA ZP
966 {
967   tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 as = regs.a; 
968   regs.a = regs.a - tmp - (regs.cc&0x01);
969   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
970   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
971   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
972   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
973 }
974
975 static void Op94(void)  // ANDA ZP
976 {
977   regs.a &= regs.RdMem(regs.RdMem(regs.pc++));
978   regs.cc &= 0xF1;                   // CLV CLZ CLN
979   if (regs.a == 0)  regs.cc |= 0x04;     // Adjust Zero flag
980   if (regs.a&0x80)  regs.cc |= 0x08;     // Adjust Negative flag
981 }
982
983 static void Op95(void)  // BITA ZP
984 {
985 tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++));
986 regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
987 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
988 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
989 }
990
991 static void Op96(void)  // LDAA ZP
992 {
993   regs.a = regs.RdMem(regs.RdMem(regs.pc++));
994   regs.cc &= 0xF1;                            // CLN CLZ CLV
995   if (regs.a == 0)  regs.cc |= 0x04;              // Set Zero flag
996   if (regs.a&0x80)  regs.cc |= 0x08;              // Set Negative flag
997 }
998
999 static void Op97(void)  // STAA ZP
1000 {
1001 regs.WrMem(regs.RdMem(regs.pc++), regs.a);
1002 regs.cc &= 0xFD;                            // CLV
1003 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1004 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1005 }
1006
1007 static void Op98(void)  // EORA ZP
1008 {
1009 regs.a ^= regs.RdMem(regs.RdMem(regs.pc++));
1010 regs.cc &= 0xFD;                            // CLV
1011 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1012 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1013 }
1014
1015 static void Op99(void)  // ADCA ZP
1016 {
1017   tmp = regs.RdMem(regs.RdMem(regs.pc++));
1018   addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1019   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
1020   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1021   regs.a = addr & 0xFF;                       // Set accumulator
1022   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
1023   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
1024 }
1025
1026 static void Op9A(void)  // ORAA ZP
1027 {
1028 regs.a |= regs.RdMem(regs.RdMem(regs.pc++));
1029 regs.cc &= 0xFD;                            // CLV
1030 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1031 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1032 }
1033
1034 static void Op9B(void)  // ADDA ZP
1035 {       
1036   tmp = regs.RdMem(regs.RdMem(regs.pc++));
1037   addr = (uint16)regs.a + (uint16)tmp;
1038   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1039   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1040   regs.a = addr & 0xFF;                       // Set accumulator
1041   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1042   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1043 }
1044
1045 static void Op9C(void)  // CPX ZP
1046 {
1047 addr = regs.RdMem(regs.pc++);
1048 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1049 uint16 dw = regs.x - adr2;
1050 (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1051 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1052 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1053 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1054 }
1055
1056 static void Op9E(void)                                                                  // LDS ZP
1057 {
1058         regs.s = RdMemW(regs.RdMem(regs.pc++));
1059
1060         regs.cc &= 0xFD;                              // CLV
1061         (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1062         (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1063 }
1064
1065 static void Op9F(void)                                                                  // STS ZP
1066 {
1067         WrMemW(regs.RdMem(regs.pc++), regs.s);
1068
1069         regs.cc &= 0xFD;                              // CLV
1070         (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1071         (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1072 }
1073
1074 static void OpA0(void)  // SUBA IDX
1075
1076 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a; 
1077 regs.a -= tmp;
1078 (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1079 (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1080 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1081 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1082 }
1083
1084 static void OpA1(void)  // CMPA IDX
1085 {
1086 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1087 uint8 db = regs.a - tmp;
1088 (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1089 (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1090 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1091 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1092 }
1093
1094 static void OpA2(void)  // SBCA IDX
1095 {
1096   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a; 
1097   regs.a = regs.a - tmp - (regs.cc&0x01);
1098   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1099   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1100   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1101   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1102 }
1103
1104 static void OpA4(void)  // ANDA IDX
1105 {
1106 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1107 regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
1108 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1109 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1110 }
1111
1112 static void OpA5(void)  // BITA IDX
1113 {
1114 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1115 regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
1116 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1117 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1118 }
1119
1120 static void OpA6(void)  // LDAA IDX
1121 {
1122   regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1123   regs.cc &= 0xF1;                        // CLV CLZ CLN
1124   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
1125   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
1126 }
1127
1128 static void OpA7(void)  // STAA IDX
1129 {
1130   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1131   regs.cc &= 0xF1;                        // CLV CLZ CLN
1132   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
1133   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
1134 }
1135
1136 static void OpA8(void)  // EORA IDX
1137 {
1138 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1139 regs.cc &= 0xFD;                            // CLV
1140 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1141 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1142 }
1143
1144 static void OpA9(void)  // ADCA IDX
1145 {
1146   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1147   addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1148   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1149   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1150   regs.a = addr & 0xFF;                       // Set accumulator
1151   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1152   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1153 }
1154
1155 static void OpAA(void)  // ORAA IDX
1156 {
1157   regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1158   regs.cc &= 0xFD;                            // CLV
1159   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1160   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1161 }
1162
1163 static void OpAB(void)  // ADDA IDX
1164 {       
1165   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1166   addr = (uint16)regs.a + (uint16)tmp;
1167   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1168   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1169   regs.a = addr & 0xFF;                       // Set accumulator
1170   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1171   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1172 }
1173
1174 static void OpAC(void)  // CPX IDX
1175 {
1176   addr = DecodeIDX(regs.RdMem(regs.pc++));
1177   uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1178   uint16 dw = regs.x - addr2;
1179   (dw == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1180   (dw&0x8000  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1181   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1182   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1183 }
1184
1185 static void OpAD(void)                                                                  // JSR IDX
1186 {
1187         addr = DecodeIDX(regs.RdMem(regs.pc++));
1188
1189         regs.s -= 2;
1190         WrMemW(regs.s, regs.pc);
1191
1192         regs.pc = addr;                                                                         // JSR directly to IDX ptr
1193 }
1194
1195 static void OpAE(void)                                                                  // LDS IDX
1196 {
1197         regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++)));
1198
1199         regs.cc &= ~FLAG_V;
1200         (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1201         (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1202 }
1203
1204 static void OpAF(void)                                                                  // STS IDX
1205 {
1206         WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s);
1207
1208         regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V);                         // Clear NZV
1209         if (regs.s & 0x8000)  regs.cc |= FLAG_N;                        // Set Negative flag
1210         if (regs.s == 0)      regs.cc |= FLAG_Z;                        // Set Zero flag
1211 }
1212
1213 static void OpB0(void)  // SUBA ABS
1214
1215 tmp = regs.RdMem(FetchW());  uint8 as = regs.a; 
1216 regs.a -= tmp;
1217 (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1218 (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1219 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1220 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1221 }
1222
1223 static void OpB1(void)  // CMPA ABS
1224 {
1225 tmp = regs.RdMem(FetchW());
1226 uint8 db = regs.a - tmp;
1227 (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1228 (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1229 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1230 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1231 }
1232
1233 static void OpB2(void)  // SBCA ABS
1234 {
1235   tmp = regs.RdMem(FetchW());  uint8 as = regs.a; 
1236   regs.a = regs.a - tmp - (regs.cc&0x01);
1237   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1238   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1239   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1240   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1241 }
1242
1243 static void OpB4(void)  // ANDA ABS
1244 {
1245   regs.a &= regs.RdMem(FetchW());
1246   regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
1247   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1248   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1249 }
1250
1251 static void OpB5(void)  // BITA ABS
1252 {
1253   tmp = regs.a & regs.RdMem(FetchW());
1254   regs.cc &= 0xFD;                             // Cleregs.a oVerflow flag
1255   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1256   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1257 }
1258
1259 static void OpB6(void)  // LDAA ABS
1260 {
1261   regs.a = regs.RdMem(FetchW());
1262   regs.cc &= 0xFD;                            // CLV
1263   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1264   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1265 }
1266
1267 static void OpB7(void)  // STAA ABS
1268 {
1269   regs.WrMem(FetchW(), regs.a);
1270   regs.cc &= 0xFD;                            // CLV
1271   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1272   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1273 }
1274
1275 static void OpB8(void)  // EORA ABS
1276 {
1277   regs.a ^= regs.RdMem(FetchW());
1278   regs.cc &= 0xFD;                            // CLV
1279   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1280   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1281 }
1282
1283 static void OpB9(void)  // ADCA ABS
1284 {
1285   tmp = regs.RdMem(FetchW());
1286   addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1287   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1288   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1289   regs.a = addr;                              // Set accumulator
1290   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1291   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1292 }
1293
1294 static void OpBA(void)  // ORAA ABS
1295 {
1296   regs.a |= regs.RdMem(FetchW());
1297   regs.cc &= 0xFD;                            // CLV
1298   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1299   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1300 }
1301
1302 static void OpBB(void)  // ADDA ABS
1303 {       
1304   tmp = regs.RdMem(FetchW());
1305   addr = (uint16)regs.a + (uint16)tmp;
1306   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1307   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1308   regs.a = addr & 0xFF;                       // Set accumulator
1309   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1310   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1311 }
1312
1313 static void OpBC(void)  // CPX ABS
1314 {
1315   addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1316   uint16 dw = regs.x - addr2;
1317   (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1318   (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1319   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1320   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1321 }
1322
1323 static void OpBD(void)                                                                  // JSR ABS
1324 {
1325         addr = FetchW();
1326
1327         regs.s -= 2;
1328         WrMemW(regs.s, regs.pc);
1329
1330         regs.pc = addr;                                                                         // Go to absolute address (Not indir)
1331 }
1332
1333 static void OpBE(void)  // LDS ABS
1334 {
1335   addr = FetchW();
1336   regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1337   regs.cc &= 0xFD;                              // CLV
1338   (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1339   (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1340 }
1341
1342 static void OpBF(void)  // STS ABS
1343 {
1344 addr = FetchW();
1345 regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
1346 regs.cc &= 0xFD;                              // CLV
1347 (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1348 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1349 }
1350
1351 static void OpC0(void)  // SUBB #
1352
1353 tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b; 
1354 regs.b -= tmp;
1355 (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1356 (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1357 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1358 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1359 }
1360
1361 static void OpC1(void)  // CMPB #
1362 {
1363 tmp = regs.RdMem(regs.pc++);
1364 uint8 db = regs.b - tmp;
1365 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1366 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1367 (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1368 (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1369 }
1370
1371 static void OpC2(void)  // SBCB #
1372 {
1373   tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b; 
1374   regs.b = regs.b - tmp - (regs.cc&0x01);
1375   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1376   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1377   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1378   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1379 }
1380
1381 static void OpC4(void)  // ANDB #
1382 {
1383 regs.b &= regs.RdMem(regs.pc++);
1384 regs.cc &= 0xFD;                            // Cleregs.a oVerflow flag
1385 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1386 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1387 }
1388
1389 static void OpC5(void)  // BITB #
1390 {
1391   tmp = regs.b & regs.RdMem(regs.pc++);
1392   regs.cc &= 0xF1;                             // CLV CLZ CLN
1393   if (tmp == 0)  regs.cc |= 0x04;              // Set Zero flag
1394   if (tmp&0x80)  regs.cc |= 0x08;              // Set Negative flag
1395 }
1396
1397 static void OpC6(void)  // LDAB #
1398 {
1399   regs.b = regs.RdMem(regs.pc++);
1400   regs.cc &= 0xF1;                             // CLV CLZ CLN
1401   if (regs.b == 0)  regs.cc |= 0x04;               // Set Zero flag
1402   if (regs.b&0x80)  regs.cc |= 0x08;               // Set Negative flag
1403 }
1404
1405 static void OpC8(void)  // EORB #
1406 {
1407 regs.b ^= regs.RdMem(regs.pc++);
1408 regs.cc &= 0xFD;                            // CLV
1409 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1410 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1411 }
1412
1413 static void OpC9(void)  // ADCB #
1414 {
1415   tmp = regs.RdMem(regs.pc++);
1416   addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1417   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1418   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1419   regs.b = addr & 0xFF;                       // Set accumulator
1420   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1421   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1422 }
1423
1424 static void OpCA(void)  // ORAB #
1425 {
1426 regs.b |= regs.RdMem(regs.pc++);
1427 regs.cc &= 0xFD;                            // CLV
1428 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1429 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1430 }
1431
1432 static void OpCB(void)  // ADDB #
1433 {       
1434   tmp = regs.RdMem(regs.pc++);  addr = regs.b + tmp;
1435   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1436   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1437   regs.b = addr & 0xFF;                       // Set accumulator
1438   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1439   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1440 }
1441
1442 static void OpCE(void)  // LDX #
1443 {
1444   regs.x = FetchW();
1445   regs.cc &= 0xFD;                              // CLV
1446   (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1447   (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1448 }
1449
1450 static void OpD0(void)  // SUBB ZP
1451
1452   tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 bs = regs.b; 
1453   regs.b -= tmp;
1454   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1455   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1456   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1457   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1458 }
1459
1460 static void OpD1(void)  // CMPB ZP
1461 {
1462   tmp = regs.RdMem(regs.RdMem(regs.pc++));
1463   uint8 db = regs.b - tmp;
1464   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1465   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1466   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1467   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1468 }
1469
1470 static void OpD2(void)  // SBCB ZP
1471 {
1472   tmp = regs.RdMem(regs.RdMem(regs.pc++));  uint8 bs = regs.b; 
1473   regs.b = regs.b - tmp - (regs.cc&0x01);
1474   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1475   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1476   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1477   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1478 }
1479
1480 static void OpD4(void)  // ANDB ZP
1481 {
1482 regs.b &= regs.RdMem(regs.RdMem(regs.pc++));
1483 regs.cc &= 0xFD;                            // Clear oVerflow flag
1484 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1485 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1486 }
1487
1488 static void OpD5(void)  // BITB ZP
1489 {
1490 tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++));
1491 regs.cc &= 0xFD;                             // Clear oVerflow flag
1492 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1493 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1494 }
1495
1496 static void OpD6(void)  // LDAB ZP
1497 {
1498   regs.b = regs.RdMem(regs.RdMem(regs.pc++));
1499   regs.cc &= 0xFD;                            // CLV
1500   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1501   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1502 }
1503
1504 static void OpD7(void)  // STAB ZP
1505 {
1506 regs.WrMem(regs.RdMem(regs.pc++), regs.b);
1507 regs.cc &= 0xFD;                            // CLV
1508 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1509 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1510 }
1511
1512 static void OpD8(void)  // EORB ZP
1513 {
1514 regs.b ^= regs.RdMem(regs.RdMem(regs.pc++));
1515 regs.cc &= 0xFD;                            // CLV
1516 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1517 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1518 }
1519
1520 static void OpD9(void)  // ADCB ZP
1521 {
1522   tmp = regs.RdMem(regs.RdMem(regs.pc++));
1523   addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1524   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1525   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1526   regs.b = addr;                              // Set accumulator
1527   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1528   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1529 }
1530
1531 static void OpDA(void)  // ORAB ZP
1532 {
1533 regs.b |= regs.RdMem(regs.RdMem(regs.pc++));
1534 regs.cc &= 0xFD;                            // CLV
1535 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1536 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1537 }
1538
1539 static void OpDB(void)  // ADDB ZP
1540 {       
1541   tmp = regs.RdMem(regs.RdMem(regs.pc++));
1542   addr = (uint16)regs.b + (uint16)tmp;
1543   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1544   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1545   regs.b = addr & 0xFF;                       // Set accumulator
1546   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1547   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1548 }
1549
1550 static void OpDE(void)  // LDX ZP
1551 {
1552   addr = regs.RdMem(regs.pc++);
1553   regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1554   regs.cc &= 0xFD;                              // CLV
1555   (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1556   (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1557 }
1558
1559 static void OpDF(void)  // STX ZP
1560 {
1561   addr = regs.RdMem(regs.pc++);
1562   regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
1563   regs.cc &= 0xFD;                              // CLV
1564   (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1565   (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1566 }
1567
1568 static void OpE0(void)  // SUBB IDX
1569
1570   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b; 
1571   regs.b -= tmp;
1572   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1573   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1574   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1575   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1576 }
1577
1578 static void OpE1(void)  // CMPB IDX
1579 {
1580   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1581   uint8 db = regs.b - tmp;
1582   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1583   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1584   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1585   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1586 }
1587
1588 static void OpE2(void)  // SBCB IDX
1589 {
1590   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b; 
1591   regs.b = regs.b - tmp - (regs.cc&0x01);
1592   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1593   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1594   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1595   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1596 }
1597
1598 static void OpE4(void)  // ANDB IDX
1599 {
1600 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1601 regs.cc &= 0xFD;                            // Clear oVerflow flag
1602 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1603 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1604 }
1605
1606 static void OpE5(void)  // BITB IDX
1607 {
1608 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1609 regs.cc &= 0xFD;                             // Clear oVerflow flag
1610 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1611 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1612 }
1613
1614 static void OpE6(void)  // LDB IDX
1615 {
1616 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1617 regs.cc &= 0xFD;                            // CLV
1618 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1619 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1620 }
1621
1622 static void OpE7(void)  // STB IDX
1623 {
1624   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
1625   regs.cc &= 0xF1;                            // CLV CLZ CLN
1626   if (regs.b == 0)  regs.cc |= 0x04;              // Adjust Zero flag
1627   if (regs.b&0x80)  regs.cc |= 0x08;              // Adjust Negative flag
1628 }
1629
1630 static void OpE8(void)  // EORB IDX
1631 {
1632 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1633 regs.cc &= 0xFD;                            // CLV
1634 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1635 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1636 }
1637
1638 static void OpE9(void)  // ADCB IDX
1639 {
1640   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1641   addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1642   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1643   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1644   regs.b = addr;                                  // Set accumulator
1645   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1646   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1647 }
1648
1649 static void OpEA(void)  // ORB IDX
1650 {
1651 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1652 regs.cc &= 0xFD;                            // CLV
1653 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1654 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1655 }
1656
1657 static void OpEB(void)  // ADDB IDX
1658 {       
1659   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1660   addr = (uint16)regs.b + (uint16)tmp;
1661   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1662   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow 
1663   regs.b = addr;                              // Set accumulator
1664   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1665   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1666 }
1667
1668 static void OpEE(void)  // LDX IDX
1669 {
1670   addr = DecodeIDX(regs.RdMem(regs.pc++));
1671   regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1672   regs.cc &= 0xF1;                              // CLV CLZ CLN
1673   if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
1674   if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
1675 }
1676
1677 static void OpEF(void)  // STX IDX
1678 {
1679   addr = DecodeIDX(regs.RdMem(regs.pc++));
1680   regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
1681   regs.cc &= 0xF1;                              // CLV CLZ CLN
1682   if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
1683   if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
1684 }
1685
1686 static void OpF0(void)  // SUBB ABS
1687
1688 tmp = regs.RdMem(FetchW());  uint8 bs = regs.b; 
1689 regs.b -= tmp;
1690 (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1691 (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1692 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1693 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1694 }
1695
1696 static void OpF1(void)  // CMPB ABS
1697 {
1698 tmp = regs.RdMem(FetchW());
1699 uint8 db = regs.b - tmp;
1700 (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1701 (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1702 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1703 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1704 }
1705
1706 static void OpF2(void)  // SBCB ABS
1707 {
1708   tmp = regs.RdMem(FetchW());  uint8 bs = regs.b; 
1709   regs.b = regs.b - tmp - (regs.cc&0x01);
1710   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1711   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1712   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1713   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1714 }
1715
1716 static void OpF4(void)  // ANDB ABS
1717 {
1718 regs.b &= regs.RdMem(FetchW());
1719 regs.cc &= 0xFD;                            // Clear oVerflow flag
1720 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1721 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1722 }
1723
1724 static void OpF5(void)  // BITB ABS
1725 {
1726 tmp = regs.b & regs.RdMem(FetchW());
1727 regs.cc &= 0xFD;                             // Clear oVerflow flag
1728 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1729 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1730 }
1731
1732 static void OpF6(void)  // LDB ABS
1733 {
1734 regs.b = regs.RdMem(FetchW());
1735 regs.cc &= 0xFD;                            // CLV
1736 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1737 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1738 }
1739
1740 static void OpF7(void)  // STB ABS
1741 {
1742 regs.WrMem(FetchW(), regs.b);
1743 regs.cc &= 0xFD;                            // CLV
1744 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1745 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1746 }
1747
1748 static void OpF8(void)  // EORB ABS
1749 {
1750 regs.b ^= regs.RdMem(FetchW());
1751 regs.cc &= 0xFD;                            // CLV
1752 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1753 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1754 }
1755
1756 static void OpF9(void)  // ADCB ABS
1757 {
1758   tmp = regs.RdMem(FetchW());
1759   addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1760   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1761   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1762   regs.b = addr & 0xFF;                       // Set accumulator
1763   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1764   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1765 }
1766
1767 static void OpFA(void)  // ORB ABS
1768 {
1769 regs.b |= regs.RdMem(FetchW());
1770 regs.cc &= 0xFD;                            // CLV
1771 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1772 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1773 }       
1774
1775 static void OpFB(void)  // ADDB ABS
1776 {       
1777   tmp = regs.RdMem(FetchW());
1778   addr = (uint16)regs.b + (uint16)tmp;
1779   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1780   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo 
1781   regs.b = addr & 0xFF;                       // Set accumulator
1782   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1783   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1784 }
1785
1786 static void OpFE(void)  // LDX ABS
1787 {
1788 addr = FetchW();
1789 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1790 regs.cc &= 0xFD;                              // CLV
1791 (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1792 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1793 }
1794
1795 static void OpFF(void)  // STX ABS
1796 {
1797 addr = FetchW();
1798 regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
1799 regs.cc &= 0xFD;                              // CLV
1800 (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1801 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1802 }
1803
1804 static void Op__(void)
1805 {
1806         regs.cpuFlags |= V6808_STATE_ILLEGAL_INST;
1807 }
1808
1809
1810 //
1811 // Ok, the exec_op[] array is globally defined here basically to save
1812 // a LOT of unnecessary typing.  Sure it's ugly, but hey, it works!
1813 //
1814 void (* exec_op[256])() = {
1815         Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F,
1816         Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__,
1817         Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
1818         Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, Op3E, Op3F,
1819         Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
1820         Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
1821         Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
1822         Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
1823         Op80, Op81, Op82, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
1824         Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F,
1825         OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
1826         OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
1827         OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__,
1828         OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF,
1829         OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF,
1830         OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF
1831 };
1832
1833
1834 //
1835 // Internal "memcpy" (so we don't have to link with any external libraries!)
1836 //
1837 static void myMemcpy(void * dst, void * src, uint32 size)
1838 {
1839         uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
1840
1841         for(uint32 i=0; i<size; i++)
1842                 d[i] = s[i];
1843 }
1844
1845 //int instCount[256];
1846 //
1847 // Function to execute 6808 for "cycles" cycles
1848 //
1849 void Execute6808(V6808REGS * context, uint32 cycles)
1850 {
1851         myMemcpy(&regs, context, sizeof(V6808REGS));
1852
1853         // Execute here...
1854         while (regs.clock < cycles)
1855         {
1856 #ifdef __DEBUG__
1857 Decode6808(regs.pc);
1858 #endif
1859                 uint8 opcode = regs.RdMem(regs.pc++);
1860
1861 //if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
1862 //instCount[opcode]++;
1863
1864                 exec_op[opcode]();                                                              // Execute that opcode...
1865                 regs.clock += CPUCycles[opcode];
1866 #ifdef __DEBUG__
1867 WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, regs.cc);
1868 #endif
1869
1870                 if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
1871                 {
1872                         regs.cc |= FLAG_I;                                                      // Set I
1873                         regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
1874
1875                         context->cpuFlags &= ~V6808_ASSERT_LINE_RESET;
1876                         regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET;
1877                 }
1878                 else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
1879                 {
1880                         regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
1881                         regs.WrMem(--regs.s, regs.pc >> 8);
1882                         regs.WrMem(--regs.s, regs.x & 0xFF);
1883                         regs.WrMem(--regs.s, regs.x >> 8);
1884                         regs.WrMem(--regs.s, regs.b);
1885                         regs.WrMem(--regs.s, regs.a);
1886                         regs.WrMem(--regs.s, regs.cc);
1887                         regs.pc = RdMemW(0xFFFC);                                       // And do it!
1888
1889                         regs.clock += 0;                                                        // How many???
1890                         context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
1891                         regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI;        // Reset the asserted line (NMI)...
1892                 }
1893                 else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
1894                 {
1895                         if (!(regs.cc & FLAG_I))                                        // Process an interrupt (I=0)?
1896                         {
1897                                 regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save all regs...
1898                                 regs.WrMem(--regs.s, regs.pc >> 8);
1899                                 regs.WrMem(--regs.s, regs.x & 0xFF);
1900                                 regs.WrMem(--regs.s, regs.x >> 8);
1901                                 regs.WrMem(--regs.s, regs.b);
1902                                 regs.WrMem(--regs.s, regs.a);
1903                                 regs.WrMem(--regs.s, regs.cc);
1904                                 regs.pc = RdMemW(0xFFF8);                       // And do it!
1905
1906                                 regs.clock += 0;                                                // How many???
1907                                 context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
1908                                 regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
1909                         }
1910                 }
1911         }
1912
1913         myMemcpy(context, &regs, sizeof(V6808REGS));
1914 }
1915
1916 //
1917 // Get the clock of the currently executing CPU
1918 //
1919 uint32 GetCurrentV6808Clock(void)
1920 {
1921         return regs.clock;
1922 }