"Fossies" - the Fresh Open Source Software Archive

Member "alec64-1.13/src/6502.c" (16 Aug 1996, 49416 Bytes) of package /linux/misc/old/alec64-1.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  *  The C64 emulator
    3  *
    4  *  Copyright 1992-96 by ALE.
    5  *  written by Lutz Sammer.
    6  *
    7  *  6502/6510 Emulation
    8  *-----------------------------------------------------------------------------
    9  * $Id: 6502.c,v 1.16 1996/07/03 02:19:32 johns Exp root $
   10  * $Log: 6502.c,v $
   11  * Revision 1.16  1996/07/03 02:19:32  johns
   12  * Correct cycles for branches page crossings, ADC and SBC new decimal mode.
   13  * JAM instruction dedection, more illegal opcodes.
   14  *
   15  * Revision 1.15  1996/06/16 00:35:43  johns
   16  * Fixed ADC/SBC decimal mode bug.
   17  *
   18  * Revision 1.14  1996/06/01 22:31:47  johns
   19  * NOCSE for linux-aout changed, new interrupt handling.
   20  *
   21  * Revision 1.13  1996/05/03 17:24:58  johns
   22  * Use of label references (GNU), more illegal opcodes, adc+sbc rewritten.
   23  * Start of cleanup.
   24  *
   25  * Revision 1.12  1995/02/13  11:27:22  ari
   26  * second linux port ( by ari ) integration
   27  *
   28  * Revision 1.11  1994/12/18  00:32:11  root
   29  * non-gcc feature macro support, icc support
   30  *
   31  * Revision 1.10  1994/06/02  14:54:24  johns
   32  * version 1.07 ci.
   33  *
   34  * Revision 1.9  1993/09/17  11:27:39  johns
   35  * support for wide ( > 80 char ) disassembly
   36  *
   37  * Revision 1.8  1993/08/31  20:30:03  johns
   38  * go32 initial support
   39  *
   40  * Revision 1.7  1993/06/13  12:26:30  johns
   41  * cleanup
   42  *
   43  * Revision 1.6  1993/01/05  12:41:24  johns
   44  * Checkin before applying wuebbel patches
   45  *
   46  * Revision 1.5  1992/07/28  19:43:33  johns
   47  * Macros for local register and Sparc written.
   48  *
   49  * Revision 1.4  1992/07/20  04:15:46  johns
   50  * All inline functions becomes macros. Macros for local variables inserted.
   51  *
   52  * Revision 1.3  1992/07/13  04:36:26  johns
   53  * FetchOpcode Macro, Read reset vector after hardware reset.
   54  *
   55  * Revision 1.2  1992/07/11  21:52:24  johns
   56  * asm now macro
   57  *
   58  * Revision 1.1  1992/07/11  17:45:54  johns
   59  * Initial revision
   60  *
   61  *-----------------------------------------------------------------------------
   62  */
   63 
   64 #include "c64.h"
   65 #include "vic.h"
   66 #include <stdio.h>
   67 
   68 #ifdef M_UNIX
   69 # ifdef __ICC
   70 #   define NOCSE(str)
   71 # else
   72 #   define NOCSE(str) asm("/ " str)
   73 # endif
   74 #endif
   75 #ifdef __linux__
   76 # ifdef __ELF__
   77 #   define NOCSE(str) asm("/ " str)
   78 # else
   79 #   define NOCSE(str) asm("\n/ " str)
   80 # endif
   81 #endif
   82 #ifdef PCSOLARIS
   83 #   define NOCSE(str) asm("/" str)
   84 #endif
   85 #ifdef SPARC
   86 #   define NOCSE(str) asm("!" str)
   87 #endif
   88 #ifdef __GO32__
   89 #   define NOCSE(str) asm("/* " str " */")
   90 #endif
   91 
   92 /*
   93 **  Int:    0000-0000 0000-0000 0000-000C VVVV-VVVV
   94 **
   95 **  C:      Carry
   96 **  VVVV-VVVV   Last value for testing on zero
   97 */
   98 static union reg6502 GlobalLastVal; /* Delayed flags calculation */
   99 
  100 #ifdef BIG_ENDIAN           /* sparc */
  101 #   define LastValZero  (LastVal.Byte[3])
  102 #   define LastValCarry (LastVal.Byte[2])
  103 #endif
  104 #ifdef LITTLE_ENDIAN            /* i386/i486 */
  105 #   define LastValZero  (LastVal.Byte[0])
  106 #   define LastValCarry (LastVal.Byte[1])
  107 #endif
  108 
  109 static union reg6502 GlobalNegativeFlag;/* Last result negative flag */
  110 
  111 union reg6502   GlobalRegA;     /* 6502 Register A */
  112 union reg6502   GlobalRegX;     /* 6502 Register X */
  113 union reg6502   GlobalRegY;     /* 6502 Register Y */
  114 union reg6502   GlobalRegP;     /* 6502 Register Flags */
  115 union reg6502   GlobalRegS;     /* 6502 Register Stack pointer */
  116 unsigned    GlobalRegPC;        /* 6502 Processor counter */
  117 
  118 int     IrqLine;        /* Interupt line state */
  119 unsigned    Cycle;          /* Current 6502 cycle */
  120 unsigned    Action;         /* Next hardware action */
  121 #ifdef NEW_ACTION
  122 unsigned    HwAction;       /* Next hardware action */
  123 #endif
  124 void        (*ActionFunction)(void);/* Hardware action function */
  125 
  126 /*---------------------------------------------------------------------------*/
  127 
  128 #define RegP        GlobalRegP
  129 #define RegS        GlobalRegS
  130 #define RegPC       GlobalRegPC
  131 #define LastVal     GlobalLastVal
  132 #define NegativeFlag    GlobalNegativeFlag
  133 
  134 /*---------------------------------------------------------------------------*/
  135 
  136 #define noNEW_OPCODE            /* little improvements */
  137 
  138 #ifdef NEW_OPCODE
  139 
  140 static unsigned (*FetchFunc)(void);
  141 
  142 static unsigned RamFetch(void)
  143 {
  144     return *(unsigned long*)(Ram+RegPC);
  145 }
  146 
  147 static unsigned BasicFetch(void)
  148 {
  149     return *(unsigned long*)(BasicRom-ADR_BASIC+RegPC);
  150 }
  151 
  152 static unsigned KernelFetch(void)
  153 {
  154     return *(unsigned long*)(KernelRom-ADR_KERNEL+RegPC);
  155 }
  156 
  157 static unsigned IOFetch(void)
  158 {
  159     return RBMem(RegPC+0)|(RBMem(RegPC+1)<<8)|(RBMem(RegPC+2)<<16);
  160 }
  161 
  162 #define NewPC() \
  163 do{                     \
  164     if( Config[RegPC]==C_RW_RAM )       \
  165     FetchFunc=RamFetch;         \
  166     else if( Config[RegPC]==C_KROM )        \
  167     FetchFunc=KernelFetch;          \
  168     else if( Config[RegPC]==C_BROM )        \
  169     FetchFunc=BasicFetch;           \
  170     else                    \
  171     FetchFunc=IOFetch;          \
  172 }while( 0 )
  173 
  174 #else
  175 
  176 #define NewPC()
  177 
  178 #endif
  179 
  180 /*---------------------------------------------------------------------------*/
  181 
  182 
  183 /*
  184 **  Returns the cached flags like flag register.
  185 */
  186 #define CurrentFlags() \
  187     (((LowByte(RegP)&~(FLAG_NEGATIVE|FLAG_ZERO|FLAG_CARRY))     \
  188         | LastValCarry              /* Carry */ \
  189         | (LowByte(NegativeFlag)&FLAG_NEGATIVE) /* Negative */  \
  190         | ((LastValZero==0)<<1)         /* Zero */  \
  191         | (FLAG_BREAK|FLAG_UNDEFINED))&0xFF)    /* Always set */
  192 
  193 /*
  194 **  Called if we need the cached flags in flag register.
  195 */
  196 void UpdateFlags(void)
  197 {
  198     LowByte(RegP)=CurrentFlags();
  199 }
  200 
  201 /*-----------------------------------------------------------------------------
  202  *  6502/6510 Vectors
  203  *---------------------------------------------------------------------------*/
  204 
  205 /*
  206 **  Handle CPU reset line.
  207 */
  208 #define DoReset() \
  209     do{                     \
  210     IrqLine=0;              \
  211     Cycle=6;                \
  212     HardwareReset();            \
  213     /* FIXME: Is this wrong ?? */       \
  214     RegP.Int&=FLAG_DECIMAL;         \
  215     RegP.Int|=FLAG_INTERRUPT;       \
  216     RegPC=RWVec(RST_VECTOR);        \
  217     NewPC();                \
  218     }while( 0 )
  219 
  220 /*
  221 **  Handle CPU NMI line.
  222 */
  223 #define DoNmi() \
  224     do{                     \
  225     PushW(RegPC);               \
  226     PushB(CurrentFlags());          \
  227     RegP.Int|=FLAG_INTERRUPT;       \
  228     RegPC=RWVec(NMI_VECTOR);        \
  229     NewPC();                \
  230     Cycle+=7;               \
  231     }while( 0 )
  232 
  233 /*
  234 **  Handle CPU IRQ line.
  235 */
  236 #define DoIrq() \
  237     do{\
  238     PushW(RegPC);               \
  239     PushB((CurrentFlags()&~FLAG_BREAK));    \
  240     RegP.Int|=FLAG_INTERRUPT;       \
  241     RegPC=RWVec(IRQ_VECTOR);        \
  242     NewPC();                \
  243     Cycle+=7;               \
  244     }while( 0 )
  245 
  246 /*---------------------------------------------------------------------------*/
  247 
  248 /*
  249 **  Handle reset pin.
  250 */
  251 void Reset(void)
  252 {
  253     DoReset();
  254 }
  255 
  256 /*
  257 **  Handle nmi pin.
  258 */
  259 void Nmi(void)
  260 {
  261 #if defined(X11) && defined(DEBUG) && 0
  262     printf("NMI at $%04X\n",RegPC);
  263 #endif
  264     DoNmi();
  265 }
  266 
  267 /*
  268 **  Handle irq pin.
  269 **      The IRQ pin is level triggert.
  270 */
  271 void Irq(void)
  272 {
  273     IrqLine=1;
  274     if( Integer(RegP)&FLAG_INTERRUPT ) {/* interrupts disabled */
  275     return;
  276     }
  277     DoIrq();
  278 }
  279 
  280 #undef RegP
  281 #undef RegS
  282 #undef RegPC
  283 #undef LastVal
  284 #undef NegativeFlag
  285 
  286 /*---------------------------------------------------------------------------*/
  287 
  288 /*
  289  *  Locals for 6502 registers.
  290  *
  291  *  ILL02:  Before  Move local register -> global
  292  *      After   Move global register -> local
  293  *  Main loop:
  294  *      Cycle and Action are used in read & write functions
  295  *  Hardware emulation:
  296  *      Cycle, Action, RegP, RegPC, RegS local register -> global
  297  *      If monitor is on, all local registers are needed.
  298  */
  299 
  300 #ifdef SPARC    /* { */
  301 
  302 /*
  303 **  THIS IS NOT CORRECT: IT'S A VERY OLD VERSION!!!
  304 **  MANY READ-WRITE FUNCTIONS CAN NOW CHANGE REGISTERS.
  305 */
  306 
  307 #   define LocalRegs    \
  308     register union reg6502  LocalLastVal;       \
  309     register union reg6502  LocalNegativeFlag;  \
  310     register union reg6502  LocalRegA;      \
  311     register union reg6502  LocalRegX;      \
  312     register union reg6502  LocalRegY;      \
  313     register union reg6502  LocalRegP;      \
  314     register union reg6502  LocalRegS;      \
  315     register unsigned   LocalRegPC;     \
  316     register unsigned*  ActionPointer;      \
  317     register unsigned*  CyclePointer
  318 
  319 #   define LoadLocalRegs()  \
  320     LocalRegA   =GlobalRegA;            \
  321     LocalRegX   =GlobalRegX;            \
  322     LocalRegY   =GlobalRegY;            \
  323     LocalRegP   =GlobalRegP;            \
  324     LocalRegS   =GlobalRegS;            \
  325     LocalRegPC  =GlobalRegPC;           \
  326     LocalLastVal    =GlobalLastVal;         \
  327     LocalNegativeFlag=GlobalNegativeFlag;       \
  328     ActionPointer   =&Action;           \
  329     CyclePointer    =&Cycle
  330 
  331 #   define SaveLocalRegs()  \
  332     GlobalRegA  =LocalRegA;         \
  333     GlobalRegX  =LocalRegX;         \
  334     GlobalRegY  =LocalRegY;         \
  335     GlobalRegP  =LocalRegP;         \
  336     GlobalRegS  =LocalRegS;         \
  337     GlobalRegPC =LocalRegPC;            \
  338     GlobalLastVal   =LocalLastVal;          \
  339     GlobalNegativeFlag=LocalNegativeFlag
  340 
  341 #   define LoadLocalRegsEmulTrap()          \
  342     LocalRegPC=GlobalRegPC
  343 
  344 #   define SaveLocalRegsEmulTrap()          \
  345     GlobalRegA=LocalRegA
  346 
  347 #ifdef MONITOR
  348 
  349 #   define LoadLocalRegsHardware()          \
  350     LoadLocalRegs()
  351 
  352 #   define SaveLocalRegsHardware()          \
  353     SaveLocalRegs()
  354 
  355 #else   /* }{ MONITOR */
  356 
  357 #   define LoadLocalRegsHardware()          \
  358     LocalRegP=GlobalRegP;               \
  359     LocalRegS=GlobalRegS;               \
  360     LocalRegPC=GlobalRegPC;             \
  361     LocalLastVal=GlobalLastVal;         \
  362     LocalNegativeFlag=GlobalNegativeFlag
  363 
  364 #   define SaveLocalRegsHardware()          \
  365     GlobalRegP=LocalRegP;               \
  366     GlobalRegS=LocalRegS;               \
  367     GlobalRegPC=LocalRegPC;             \
  368     GlobalLastVal=LocalLastVal;         \
  369     GlobalNegativeFlag=LocalNegativeFlag
  370 
  371 #endif  /* } !MONITOR */
  372 
  373 #   define LastVal  LocalLastVal
  374 #   define NegativeFlag LocalNegativeFlag
  375 #   define RegA     LocalRegA
  376 #   define RegX     LocalRegX
  377 #   define RegY     LocalRegY
  378 #   define RegP     LocalRegP
  379 #   define RegS     LocalRegS
  380 #   define RegPC    LocalRegPC
  381 #if 0
  382 #   define Cycle    (*CyclePointer)
  383 #   define Action   (*ActionPointer)
  384 #endif
  385 
  386 #endif  /* } SPARC */
  387 
  388 #ifndef LocalRegs
  389 #   define LastVal  GlobalLastVal
  390 #   define NegativeFlag GlobalNegativeFlag
  391 #   define RegA     GlobalRegA
  392 #   define RegX     GlobalRegX
  393 #   define RegY     GlobalRegY
  394 #   define RegP     GlobalRegP
  395 #   define RegS     GlobalRegS
  396 #   define RegPC    GlobalRegPC
  397 
  398 #   define LocalRegs
  399 #   define LoadLocalRegs()
  400 #   define SaveLocalRegs()
  401 #   define LoadLocalRegsEmulTrap()
  402 #   define SaveLocalRegsEmulTrap()
  403 #   define LoadLocalRegsHardware()
  404 #   define SaveLocalRegsHardware()
  405 #endif
  406 
  407 /*-----------------------------------------------------------------------------
  408  *  Opcode and operands fetch
  409  *---------------------------------------------------------------------------*/
  410 
  411 #if 1
  412 
  413 #ifdef BIG_ENDIAN   /* { */
  414 
  415 static unsigned char Opcode[3];
  416 
  417 /*
  418  *  Fetch 3 bytes for complete opcode and operands
  419  */
  420 #define FetchOpcode()   R3Mem(RegPC,Opcode)
  421 /*
  422  *  Get opcode
  423  */
  424 #define RBOpc()     (Opcode[0])
  425 /*
  426  *  Get byte operand
  427  */
  428 #define RBIns()     (Opcode[1])
  429 /*
  430  *  Get word operand
  431  */
  432 #define RWIns()     (Opcode[1]|(Opcode[2]<<8))
  433 
  434 #endif  /* } BIG_ENDIAN */
  435 
  436 #ifdef LITTLE_ENDIAN    /* { */
  437 
  438 //static unsigned Opcode;       /* slower on pentium */
  439 
  440 #ifdef NEW_OPCODE
  441 
  442 //#define FetchOpcode() Opcode=FetchFunc()
  443 
  444 #define FetchOpcode()   Opcode=(long*)RegPC
  445 
  446 #else
  447 
  448 /*
  449 **  Fetch 3 bytes for complete opcode and operands
  450 */
  451 #define FetchOpcode()   RLMem(RegPC,Opcode)
  452 
  453 #endif
  454 
  455 /*
  456 **  Get opcode
  457 */
  458 #define RBOpc()     (Opcode&0xFF)
  459 /*
  460 **  Get byte operand
  461 */
  462 #define RBIns()     ((Opcode>>8)&0xFF)
  463 /*
  464 **  Get word operand
  465 */
  466 #define RWIns()     ((Opcode>>8)&0xFFFF)
  467 
  468 #endif  /* } LITTLE_ENDIAN */
  469 
  470 #else
  471 
  472 /*
  473 **  Fetch 3 bytes for complete opcode and operands
  474 */
  475 #define FetchOpcode()
  476 
  477 /*
  478 **  Get opcode
  479 */
  480 #define RBOpc()     RBMem(RegPC)
  481 
  482 /*
  483 **  Get byte operand
  484 */
  485 #define RBIns()     RBMem(RegPC+1)
  486 
  487 /*
  488 **  Get word operand
  489 */
  490 #define RWIns()     ((RBMem(RegPC+1))|(RBMem(RegPC+2)<<8))
  491 
  492 #endif
  493 
  494 /*-----------------------------------------------------------------------------
  495  * Addressing modes
  496  *---------------------------------------------------------------------------*/
  497 
  498 /*
  499  *  FIXME:  cross page boundary AX,AY,IY +1 Cycle
  500  *      Cycle+=(RBIns()+RegX.Int>>8);
  501  *  FIXME:  error incorrect read by AX,AY by page cross.
  502  *  DONE:   cross 64K AX,AY,IY, Memory emulator does it for us.
  503  *  DONE:   read-modify-write writes first unmodified.
  504  *      Memory interface does it for us.
  505  */
  506 #define IM() RBIns()            /* Immediate: #$00 */
  507 #define AB() RWIns()            /* Absolute: $0000 */
  508 #define DP() RBIns()            /* Direct Page: $00 */
  509 #define AX() (RWIns()+RegX.Int)     /* Absolute Indexed,X: $0000,X */
  510 #define AY() (RWIns()+RegY.Int)     /* Absolute Indexed,Y: $0000,Y */
  511 #define DX() ((RBIns()+RegX.Int)&0xFF)  /* DP Indexed,X: $00,X */
  512 #define DY() ((RBIns()+RegY.Int)&0xFF)  /* DP Indexed,Y: $00,Y */
  513 #define IX() RWDP((RBIns()+RegX.Int)&0xFF) /* DP Indexed Indirect,X: ($00,X) */
  514 #define IY() (RWDP(RBIns())+RegY.Int)   /* DP Indirect Indexed,Y: ($00),Y */
  515 
  516 /*---------------------------------------------------------------------------*/
  517 
  518 /*
  519 **  Sets NEGATIVE and ZERO flags.
  520 */
  521 #define FlagNZ(v) \
  522     (LowByte(NegativeFlag)=LastValZero=(v))
  523 
  524 /*
  525 **  Sets NEGATIVE and ZERO and CARRY flags.
  526 */
  527 #define FlagNZC(v) \
  528     LowByte(NegativeFlag)=LastVal.Int=(v)+1;
  529 
  530 #if 0
  531 /*
  532 **  Relative branch.
  533 */
  534 #define Branch() \
  535     (RegPC+=2+(char)RBIns()); \
  536     Cycle+=3
  537 
  538 /* FIXME: Branch Page boundary crossed cycle 1+
  539     if( (RegPC&0xFF00)==((RegPC+d)&0xFF00) ) {
  540     } else {
  541     Cycle+=4;
  542     }
  543 */
  544 #endif
  545 
  546 #if 0
  547 /* 308%
  548 **  Relative branch. (with correct cycles)
  549 */
  550 #define Branch() \
  551     {                   \
  552     int o;              \
  553     o=RegPC;            \
  554     RegPC+=2+(char)RBIns();     \
  555     if( (o^RegPC)&0xFF00 ) {    \
  556         printf("%0x %0x\n",o,RegPC);\
  557         Cycle+=4;           \
  558     } else {            \
  559         Cycle+=3;           \
  560     }               \
  561     }
  562 #endif
  563 
  564 /* 312%
  565 **  Relative branch. (with correct cycles) RISC version
  566 */
  567 #define Branch() \
  568     {                   \
  569     int o;              \
  570     o=RegPC+2;          \
  571     RegPC=o+(char)RBIns();      \
  572     NewPC();            \
  573     Cycle+=3+((o^RegPC)>>8);    \
  574     }
  575 
  576 /*---------------------------------------------------------------------------*/
  577 
  578 /*
  579 **  Add with carry, decimal and normal mode.
  580 */
  581 #define Adc(w) \
  582 {                                   \
  583     unsigned v;                             \
  584     unsigned i;                             \
  585                                     \
  586     v=(w);                              \
  587     i=v+Integer(RegA)+LastValCarry; /* + CARRY */           \
  588                                     \
  589     LowByte(RegP)=(RegP.Int&~FLAG_OVERFLOW)             \
  590     | ((( (RegA.Int^~v) & (RegA.Int^i) )>>1) & FLAG_OVERFLOW);  \
  591                                     \
  592     if( RegP.Int&FLAG_DECIMAL ) {   /* HELPME/FIXME: Decimal mode */\
  593     if( (v&0xF)+(Integer(RegA)&0xF)+LastValCarry>0x9 )      \
  594         i+=0x06;            /* Overflow low bcd nibble */   \
  595     if( i>0x99 )                            \
  596         i+=0x60;            /* Overflow high bcd nibble */  \
  597     }                                   \
  598     LastVal.Int=i;          /* ZERO/CARRY */        \
  599     LowByte(NegativeFlag)=LowByte(RegA)=i;              \
  600 }
  601 
  602 /*
  603 **  Sub with carry, decimal and normal mode.
  604 */
  605 #define Sbc(w)  \
  606 {                                   \
  607     unsigned v;                             \
  608     unsigned i;                             \
  609                                     \
  610     v=((w)^0xFF);                           \
  611     i=v+Integer(RegA)+LastValCarry; /* - CARRY */           \
  612                                     \
  613     LowByte(RegP)=(RegP.Int&~FLAG_OVERFLOW)             \
  614     | ((( (RegA.Int^~v) & (RegA.Int^i) )>>1) & FLAG_OVERFLOW);  \
  615                                     \
  616     if( RegP.Int&FLAG_DECIMAL ) {   /* HELPME/FIXME: Decimal mode */\
  617     /*printf("%x ",(v&0xF)+(Integer(RegA)&0xF)+LastValCarry);*/ \
  618     if( (((v&0xF)+(Integer(RegA)&0xF)+LastValCarry)&0xF)>9 )    \
  619         i-=0x06;            /* Underflow low bcd nibble */  \
  620     if( (i&0xF0)>0x90 ) {                       \
  621         i-=0x60;            /* Underflow high bcd nibble */ \
  622     }                               \
  623     /*printf("%x\n",i);*/   \
  624     }                                   \
  625     LastVal.Int=i;          /* ZERO/CARRY */        \
  626     LowByte(NegativeFlag)=LowByte(RegA)=i;              \
  627 }
  628 
  629 #ifdef __GNUC__
  630 #define Asl(w)  \
  631 ({                                  \
  632     unsigned v;                             \
  633                                     \
  634     LastVal.Int=v=(w)<<1;       /* Carry = Bit 7 */     \
  635     LowByte(NegativeFlag)=v;                        \
  636     v;                                  \
  637 })
  638 #else
  639 static unsigned __utmpvar__;
  640 #define Asl(w)  \
  641     (LastVal.Int=__utmpvar__=(w)<<1,                \
  642      LowByte(NegativeFlag)=__utmpvar__,             \
  643      __utmpvar__)
  644 #endif
  645 
  646 #ifdef __GNUC__
  647 #define Lsr(w)  \
  648 ({                                  \
  649     unsigned v;                             \
  650                                     \
  651     v=(w);                              \
  652     LastValCarry=v&1;           /* Carry = Bit 0 */     \
  653     LowByte(NegativeFlag)=LastValZero=v>>=1;                \
  654     v;                                  \
  655 })
  656 #else
  657 #define Lsr(w)  \
  658     (__utmpvar__=(w),                       \
  659     LastValCarry=__utmpvar__&1,                 \
  660     LowByte(NegativeFlag)=LastValZero=__utmpvar__>>=1,      \
  661     __utmpvar__)
  662 #endif
  663 
  664 #ifdef __GNUC__
  665 #define Rol(w)  \
  666 ({                                  \
  667     unsigned v;                             \
  668                                     \
  669     v=((w)<<1)|LastValCarry;        /* Carry -> Bit 0 */        \
  670     LastVal.Int=v;          /* Carry = Bit 7 */     \
  671     LowByte(NegativeFlag)=v;                        \
  672     v;                                  \
  673 })
  674 #else
  675 #define Rol(w)  \
  676     (__utmpvar__=((w)<<1)|LastValCarry,             \
  677     LastVal.Int=__utmpvar__,                    \
  678     LowByte(NegativeFlag)=__utmpvar__,              \
  679     __utmpvar__)
  680 #endif
  681 
  682 #ifdef __GNUC__
  683 #define Ror(w)  \
  684 ({                                  \
  685     unsigned v;                             \
  686                                     \
  687     v=(w)|(LastVal.Int&0x0100);     /* Carry -> Bit 7 after shift */\
  688     LastValCarry=v&1;           /* Carry = Bit 0 */     \
  689     LowByte(NegativeFlag)=LastValZero=v>>=1;                \
  690     v;                                  \
  691 })
  692 #else
  693 #define Ror(w)  \
  694     (__utmpvar__=(w)|(LastVal.Int&0x0100),              \
  695     LastValCarry=__utmpvar__&1,                 \
  696     LowByte(NegativeFlag)=LastValZero=__utmpvar__>>=1,      \
  697     __utmpvar__)
  698 #endif
  699 
  700 #define Bit(w)  \
  701 {                                   \
  702     unsigned v;                             \
  703                                     \
  704     v=(w);                              \
  705     LowByte(NegativeFlag)=v;                        \
  706     LastValZero=v&RegA.Int;                     \
  707     LowByte(RegP)=(RegP.Int&~FLAG_OVERFLOW)|(v&FLAG_OVERFLOW);      \
  708 }
  709 
  710 /*----------------------------------------------------------------------------*/
  711 
  712 #ifdef __GNUC__ /* { */
  713 
  714 #define JumpTable   \
  715     static CONST void *CONST Labels[256] = {                \
  716     &&_BRK,     &&_ORA_IX,  &&_ILL02,   &&_ILL03,   \
  717     &&_ILL04,   &&_ORA_D,   &&_ASL_D,   &&_ILL07,   \
  718     &&_PHP,     &&_ORA_IM,  &&_ASL,     &&_ILL0B,   \
  719     &&_ILL0C,   &&_ORA_A,   &&_ASL_A,   &&_ILL0F,   \
  720     &&_BPL,     &&_ORA_IY,  &&_ILL12,   &&_ILL13,   \
  721     &&_ILL14,   &&_ORA_DX,  &&_ASL_DX,  &&_ILL17,   \
  722     &&_CLC,     &&_ORA_AY,  &&_ILL1A,   &&_ILL1B,   \
  723     &&_ILL1C,   &&_ORA_AX,  &&_ASL_AX,  &&_ILL1F,   \
  724     &&_JSR,     &&_AND_IX,  &&_ILL22,   &&_ILL23,   \
  725     &&_BIT_D,   &&_AND_D,   &&_ROL_D,   &&_ILL27,   \
  726     &&_PLP,     &&_AND_IM,  &&_ROL,     &&_ILL2B,   \
  727     &&_BIT_A,   &&_AND_A,   &&_ROL_A,   &&_ILL2F,   \
  728     &&_BMI,     &&_AND_IY,  &&_ILL32,   &&_ILL33,   \
  729     &&_ILL34,   &&_AND_DX,  &&_ROL_DX,  &&_ILL37,   \
  730     &&_SEC,     &&_AND_AY,  &&_ILL3A,   &&_ILL3B,   \
  731     &&_ILL3C,   &&_AND_AX,  &&_ROL_AX,  &&_ILL3F,   \
  732     &&_RTI,     &&_EOR_IX,  &&_ILL42,   &&_ILL43,   \
  733     &&_ILL44,   &&_EOR_D,   &&_LSR_D,   &&_ILL47,   \
  734     &&_PHA,     &&_EOR_IM,  &&_LSR,     &&_ILL4B,   \
  735     &&_JMP_A,   &&_EOR_A,   &&_LSR_A,   &&_ILL4F,   \
  736     &&_BVC,     &&_EOR_IY,  &&_ILL52,   &&_ILL53,   \
  737     &&_ILL54,   &&_EOR_DX,  &&_LSR_DX,  &&_ILL57,   \
  738     &&_CLI,     &&_EOR_AY,  &&_ILL5A,   &&_ILL5B,   \
  739     &&_ILL5C,   &&_EOR_AX,  &&_LSR_AX,  &&_ILL5F,   \
  740     &&_RTS,     &&_ADC_IX,  &&_ILL62,   &&_ILL63,   \
  741     &&_ILL64,   &&_ADC_D,   &&_ROR_D,   &&_ILL67,   \
  742     &&_PLA,     &&_ADC_IM,  &&_ROR,     &&_ILL6B,   \
  743     &&_JMP_AI,  &&_ADC_A,   &&_ROR_A,   &&_ILL6F,   \
  744     &&_BVS,     &&_ADC_IY,  &&_ILL72,   &&_ILL73,   \
  745     &&_ILL74,   &&_ADC_DX,  &&_ROR_DX,  &&_ILL77,   \
  746     &&_SEI,     &&_ADC_AY,  &&_ILL7A,   &&_ILL7B,   \
  747     &&_ILL7C,   &&_ADC_AX,  &&_ROR_AX,  &&_ILL7F,   \
  748     &&_ILL80,   &&_STA_IX,  &&_ILL82,   &&_ILL83,   \
  749     &&_STY_D,   &&_STA_D,   &&_STX_D,   &&_ILL87,   \
  750     &&_DEY,     &&_ILL89,   &&_TXA,     &&_ILL8B,   \
  751     &&_STY_A,   &&_STA_A,   &&_STX_A,   &&_ILL8F,   \
  752     &&_BCC,     &&_STA_IY,  &&_ILL92,   &&_ILL93,   \
  753     &&_STY_DX,  &&_STA_DX,  &&_STX_DY,  &&_ILL97,   \
  754     &&_TYA,     &&_STA_AY,  &&_TXS,     &&_ILL9B,   \
  755     &&_ILL9C,   &&_STA_AX,  &&_ILL9E,   &&_ILL9F,   \
  756     &&_LDY_IM,  &&_LDA_IX,  &&_LDX_IM,  &&_ILLA3,   \
  757     &&_LDY_D,   &&_LDA_D,   &&_LDX_D,   &&_ILLA7,   \
  758     &&_TAY,     &&_LDA_IM,  &&_TAX,     &&_ILLAB,   \
  759     &&_LDY_A,   &&_LDA_A,   &&_LDX_A,   &&_ILLAF,   \
  760     &&_BCS,     &&_LDA_IY,  &&_ILLB2,   &&_ILLB3,   \
  761     &&_LDY_DX,  &&_LDA_DX,  &&_LDX_DY,  &&_ILLB7,   \
  762     &&_CLV,     &&_LDA_AY,  &&_TSX,     &&_ILLBB,   \
  763     &&_LDY_AX,  &&_LDA_AX,  &&_LDX_AY,  &&_ILLBF,   \
  764     &&_CPY_IM,  &&_CMP_IX,  &&_ILLC2,   &&_ILLC3,   \
  765     &&_CPY_D,   &&_CMP_D,   &&_DEC_D,   &&_ILLC7,   \
  766     &&_INY,     &&_CMP_IM,  &&_DEX,     &&_ILLCB,   \
  767     &&_CPY_A,   &&_CMP_A,   &&_DEC_A,   &&_ILLCF,   \
  768     &&_BNE,     &&_CMP_IY,  &&_ILLD2,   &&_ILLD3,   \
  769     &&_ILLD4,   &&_CMP_DX,  &&_DEC_DX,  &&_ILLD7,   \
  770     &&_CLD,     &&_CMP_AY,  &&_ILLDA,   &&_ILLDB,   \
  771     &&_ILLDC,   &&_CMP_AX,  &&_DEC_AX,  &&_ILLDF,   \
  772     &&_CPX_IM,  &&_SBC_IX,  &&_ILLE2,   &&_ILLE3,   \
  773     &&_CPX_D,   &&_SBC_D,   &&_INC_D,   &&_ILLE7,   \
  774     &&_INX,     &&_SBC_IM,  &&_NOP,     &&_ILLEB,   \
  775     &&_CPX_A,   &&_SBC_A,   &&_INC_A,   &&_ILLEF,   \
  776     &&_BEQ,     &&_SBC_IY,  &&_ILLF2,   &&_ILLF3,   \
  777     &&_ILLF4,   &&_SBC_DX,  &&_INC_DX,  &&_ILLF7,   \
  778     &&_SED,     &&_SBC_AY,  &&_ILLFA,   &&_ILLFB,   \
  779     &&_ILLFC,   &&_SBC_AX,  &&_INC_AX,  &&_ILLFF    \
  780     };
  781 
  782 #define Switch(x)   goto *Labels[x];
  783 #define Case(x)     _##x:
  784 #define Default
  785 #define Break       goto break_label;
  786 #define BreakLabel  break_label:
  787 
  788 #else   /* }{ __GNUC__ */
  789 
  790 #define JumpTable
  791 #define Switch(x)   switch( x )
  792 #define Case(x)     case x:
  793 #define Default     default:
  794 #define Break       break;
  795 #define BreakLabel
  796 
  797 #endif  /* } !__GNUC__ */
  798 
  799 /*----------------------------------------------------------------------------*/
  800 
  801 /*
  802 **  BREAK in emulation switch.
  803 */
  804 #define BREAK(x) \
  805     if( Cycle<Action )  \
  806     continue;   \
  807     NOCSE(x);       \
  808     Break;
  809 
  810 /*
  811 **  6502/6510 Emulator loop
  812 */
  813 void Emul6502Loop(void)
  814 {
  815     unsigned int Opcode;
  816     JumpTable;              /* LABEL POINTERS */
  817     LocalRegs;              /* LOCAL REGISTERS */
  818 
  819     LoadLocalRegs();
  820     for( ;; ) {
  821     /*
  822     **  6502 Emulator
  823     */
  824     register unsigned a;
  825 #ifdef JOHNS
  826     if( LastValCarry&~1 ) abort(); 
  827 #endif
  828 
  829 #ifdef _1541_
  830     if( 0 ) {
  831         static int _flg_=0;
  832 
  833         if( _flg_ ) {
  834         if( RegPC==0xFE84 )
  835             _flg_=0; //abort();
  836         R1541Reg();
  837         } else if( RegPC==0xFE67 ) {
  838         _flg_=1;
  839         R1541Reg();
  840         }
  841     }
  842     if( 0 ) {
  843         if( RegPC<0x800 ) {
  844         R1541Reg();
  845         }
  846     }
  847 #endif
  848 
  849     FetchOpcode();
  850     Switch( RBOpc() ) {
  851 
  852         Case( ADC_IM )      /* ADC #$xx */
  853         Adc(IM());
  854         RegPC+=2;
  855         Cycle+=2;
  856         BREAK("ADC_IM");
  857         Case( ADC_A )
  858         Adc(RBMem(AB()));
  859         RegPC+=3;
  860         Cycle+=4;
  861         BREAK("ADC_A");
  862         Case( ADC_D )
  863         Adc(RBDP(DP()));
  864         RegPC+=2;
  865         Cycle+=3;
  866         BREAK("ADC_D");
  867         Case( ADC_AX )
  868         Adc(RBMem(AX()));
  869         RegPC+=3;
  870         Cycle+=4;
  871         BREAK("ADC_AX");
  872         Case( ADC_AY )
  873         Adc(RBMem(AY()));
  874         RegPC+=3;
  875         Cycle+=4;
  876         BREAK("ADC_AY");
  877         Case( ADC_DX )
  878         Adc(RBDP(DX()));
  879         RegPC+=2;
  880         Cycle+=4;
  881         BREAK("ADC_DX");
  882         Case( ADC_IX )
  883         Adc(RBMem(IX()));
  884         RegPC+=2;
  885         Cycle+=6;
  886         BREAK("ADC_IX");
  887         Case( ADC_IY )
  888         Adc(RBMem(IY()));
  889         RegPC+=2;
  890         Cycle+=5;
  891         BREAK("ADC_IY");
  892 
  893         Case( AND_IM )
  894         FlagNZ(LowByte(RegA)&=IM());
  895         RegPC+=2;
  896         Cycle+=2;
  897         BREAK("AND_IM");
  898         Case( AND_A )
  899         FlagNZ(LowByte(RegA)&=RBMem(AB()));
  900         RegPC+=3;
  901         Cycle+=4;
  902         BREAK("AND_A");
  903         Case( AND_D )
  904         FlagNZ(LowByte(RegA)&=RBDP(DP()));
  905         RegPC+=2;
  906         Cycle+=3;
  907         BREAK("AND_D");
  908         Case( AND_AX )
  909         FlagNZ(LowByte(RegA)&=RBMem(AX()));
  910         RegPC+=3;
  911         Cycle+=4;
  912         BREAK("AND_AX");
  913         Case( AND_AY )
  914         FlagNZ(LowByte(RegA)&=RBMem(AY()));
  915         RegPC+=3;
  916         Cycle+=4;
  917         BREAK("AND_AY");
  918         Case( AND_DX )
  919         FlagNZ(LowByte(RegA)&=RBDP(DX()));
  920         RegPC+=2;
  921         Cycle+=4;
  922         BREAK("AND_DX");
  923         Case( AND_IX )
  924         FlagNZ(LowByte(RegA)&=RBMem(IX()));
  925         RegPC+=2;
  926         Cycle+=6;
  927         BREAK("AND_IX");
  928         Case( AND_IY )
  929         FlagNZ(LowByte(RegA)&=RBMem(IY()));
  930         RegPC+=2;
  931         Cycle+=5;
  932         BREAK("AND_IY");
  933 
  934         Case( ASL )
  935         LowByte(RegA)=Asl(RegA.Int);
  936         RegPC++;
  937         Cycle+=2;
  938         BREAK("ASL");
  939         Case( ASL_A )
  940         a=AB();
  941         WBMem(a,Asl(RBMem(a)));
  942         RegPC+=3;
  943         Cycle+=6;
  944         BREAK("ASL_A");
  945         Case( ASL_D )
  946         a=DP();
  947         WBDP(a,Asl(RBDP(a)));
  948         RegPC+=2;
  949         Cycle+=5;
  950         BREAK("ASL_D");
  951         Case( ASL_AX )
  952         a=AX();
  953         WBMem(a,Asl(RBMem(a)));
  954         RegPC+=3;
  955         Cycle+=7;
  956         BREAK("ASL_AX");
  957         Case( ASL_DX )
  958         a=DX();
  959         WBDP(a,Asl(RBDP(a)));
  960         RegPC+=2;
  961         Cycle+=6;
  962         BREAK("ASL_DX");
  963 
  964         Case( BCC )
  965         if( LastValCarry ) {
  966             RegPC+=2;
  967             Cycle+=2;
  968             BREAK("BCC_0");
  969         } else {
  970             Branch();
  971             BREAK("BCC_1");
  972         }
  973         Case( BCS )
  974         if( LastValCarry ) {
  975             Branch();
  976             BREAK("BCS_0");
  977         } else {
  978             RegPC+=2;
  979             Cycle+=2;
  980             BREAK("BCS_1");
  981         }
  982         Case( BEQ )
  983         if( LastValZero ) {
  984             RegPC+=2;
  985             Cycle+=2;
  986             BREAK("BEQ_0");
  987         } else {
  988             Branch();
  989             BREAK("BEQ_1");
  990         }
  991 
  992         Case( BIT_A )
  993         Bit(RBMem(AB()));
  994         RegPC+=3;
  995         Cycle+=4;
  996         BREAK("BIT_A");
  997         Case( BIT_D )
  998         Bit(RBDP(DP()));
  999         RegPC+=2;
 1000         Cycle+=3;
 1001         BREAK("BIT_D");
 1002 
 1003         Case( BMI )
 1004         if( NegativeFlag.Int&FLAG_NEGATIVE ) {
 1005             Branch();
 1006             BREAK("BMI_0");
 1007         } else {
 1008             RegPC+=2;
 1009             Cycle+=2;
 1010             BREAK("BMI_1");
 1011         }
 1012         Case( BNE )
 1013         if( LastValZero ) {
 1014             Branch();
 1015             BREAK("BNE_0");
 1016         } else {
 1017             RegPC+=2;
 1018             Cycle+=2;
 1019             BREAK("BNE_1");
 1020         }
 1021         Case( BPL )
 1022         if( NegativeFlag.Int&FLAG_NEGATIVE ) {
 1023             RegPC+=2;
 1024             Cycle+=2;
 1025             BREAK("BPL_0");
 1026         } else {
 1027             Branch();
 1028             BREAK("BPL_1");
 1029         }
 1030 
 1031         Case( BRK )
 1032         a=RBOpc();
 1033         a=RegPC+2;
 1034         PushW(a);
 1035         PushB(CurrentFlags());
 1036         Integer(RegP)|=FLAG_INTERRUPT;
 1037         RegPC=RWVec(IRQ_VECTOR);
 1038         NewPC();
 1039         Cycle+=7;
 1040         BREAK("BRK");
 1041 
 1042         Case( BVC )
 1043 #ifdef _1541_
 1044         RegPC+=2;
 1045         Cycle+=2;
 1046         BREAK("BVC_0");
 1047 #else
 1048         if( RegP.Int&FLAG_OVERFLOW ) {
 1049             RegPC+=2;
 1050             Cycle+=2;
 1051             BREAK("BVC_0");
 1052         } else {
 1053             Branch();
 1054             BREAK("BVC_1");
 1055         }
 1056 #endif
 1057         Case( BVS )
 1058 #ifdef _1541_
 1059         Branch();
 1060         BREAK("BVS_0");
 1061 #else
 1062         if( RegP.Int&FLAG_OVERFLOW ) {
 1063             Branch();
 1064             BREAK("BVS_0");
 1065         } else {
 1066             RegPC+=2;
 1067             Cycle+=2;
 1068             BREAK("BVS_1");
 1069         }
 1070 #endif
 1071 
 1072         Case( CLC )
 1073         LastValCarry=0;
 1074         ++RegPC;
 1075         Cycle+=2;
 1076         BREAK("CLC");
 1077         Case( CLD )
 1078         RegP.Int&=~FLAG_DECIMAL;
 1079         ++RegPC;
 1080         Cycle+=2;
 1081         BREAK("CLD");
 1082         Case( CLI )
 1083         RegP.Int&=~FLAG_INTERRUPT;
 1084         ++RegPC;
 1085         Cycle+=2;
 1086         if( IrqLine ) {     /* serve pending interrupts */
 1087             DoIrq();
 1088         }
 1089         BREAK("CLI");
 1090         Case( CLV )
 1091         RegP.Int&=~FLAG_OVERFLOW;
 1092 #ifdef _1541_
 1093         RegP.Int|=FLAG_OVERFLOW;/* Connected to DATA READY! */
 1094 #endif
 1095         ++RegPC;
 1096         Cycle+=2;
 1097         BREAK("CLV");
 1098 
 1099         Case( CMP_IM )
 1100         FlagNZC(RegA.Int+(IM()^0xFF));
 1101         RegPC+=2;
 1102         Cycle+=2;
 1103         BREAK("CMP_IM");
 1104         Case( CMP_A )
 1105         FlagNZC(RegA.Int+(RBMem(AB())^0xFF));
 1106         RegPC+=3;
 1107         Cycle+=4;
 1108         BREAK("CMP_A");
 1109         Case( CMP_D )
 1110         FlagNZC(RegA.Int+(RBDP(DP())^0xFF));
 1111         RegPC+=2;
 1112         Cycle+=3;
 1113         BREAK("CMP_D");
 1114         Case( CMP_AX )
 1115         FlagNZC(RegA.Int+(RBMem(AX())^0xFF));
 1116         RegPC+=3;
 1117         Cycle+=4;
 1118         BREAK("CMP_AX");
 1119         Case( CMP_AY )
 1120         FlagNZC(RegA.Int+(RBMem(AY())^0xFF));
 1121         RegPC+=3;
 1122         Cycle+=4;
 1123         BREAK("CMP_AY");
 1124         Case( CMP_DX )
 1125         FlagNZC(RegA.Int+(RBDP(DX())^0xFF));
 1126         RegPC+=2;
 1127         Cycle+=4;
 1128         BREAK("CMP_DX");
 1129         Case( CMP_IX )
 1130         FlagNZC(RegA.Int+(RBMem(IX())^0xFF));
 1131         RegPC+=2;
 1132         Cycle+=6;
 1133         BREAK("CMP_IX");
 1134         Case( CMP_IY )
 1135         FlagNZC(RegA.Int+(RBMem(IY())^0xFF));
 1136         RegPC+=2;
 1137         Cycle+=5;
 1138         BREAK("CMP_IY");
 1139 
 1140         Case( CPX_IM )
 1141         FlagNZC(RegX.Int+(IM()^0xFF));
 1142         RegPC+=2;
 1143         Cycle+=2;
 1144         BREAK("CPX_IM");
 1145         Case( CPX_A )
 1146         FlagNZC(RegX.Int+(RBMem(AB())^0xFF));
 1147         RegPC+=3;
 1148         Cycle+=4;
 1149         BREAK("CPX_A");
 1150         Case( CPX_D )
 1151         FlagNZC(RegX.Int+(RBDP(DP())^0xFF));
 1152         RegPC+=2;
 1153         Cycle+=3;
 1154         BREAK("CPX_D");
 1155 
 1156         Case( CPY_IM )
 1157         FlagNZC(RegY.Int+(IM()^0xFF));
 1158         RegPC+=2;
 1159         Cycle+=2;
 1160         BREAK("CPY_IM");
 1161         Case( CPY_A )
 1162         FlagNZC(RegY.Int+(RBMem(AB())^0xFF));
 1163         RegPC+=3;
 1164         Cycle+=4;
 1165         BREAK("CPY_A");
 1166         Case( CPY_D )
 1167         FlagNZC(RegY.Int+(RBDP(DP())^0xFF));
 1168         RegPC+=2;
 1169         Cycle+=3;
 1170         BREAK("CPY_D");
 1171 
 1172         Case( DEC_A )
 1173         a=AB();
 1174         WBMem(a,FlagNZ((RBMem(a)-1)&0xFF));
 1175         RegPC+=3;
 1176         Cycle+=6;
 1177         BREAK("DEC_A");
 1178         Case( DEC_D )
 1179         a=DP();
 1180         WBDP(a,FlagNZ((RBDP(a)-1)&0xFF));
 1181         RegPC+=2;
 1182         Cycle+=5;
 1183         BREAK("DEC_D");
 1184         Case( DEC_AX )
 1185         a=AX();
 1186         WBMem(a,FlagNZ((RBMem(a)-1)&0xFF));
 1187         RegPC+=3;
 1188         Cycle+=7;
 1189         BREAK("DEC_AX");
 1190         Case( DEC_DX )
 1191         a=DX();
 1192         WBDP(a,FlagNZ((RBDP(a)-1)&0xFF));
 1193         RegPC+=2;
 1194         Cycle+=6;
 1195         BREAK("DEC_DX");
 1196 
 1197         Case( DEX )
 1198         FlagNZ(--LowByte(RegX));
 1199         ++RegPC;
 1200         Cycle+=2;
 1201         BREAK("DEX");
 1202         Case( DEY )
 1203         FlagNZ(--LowByte(RegY));
 1204         ++RegPC;
 1205         Cycle+=2;
 1206         BREAK("DEY");
 1207 
 1208         Case( EOR_IM )
 1209         LowByte(RegA)^=IM();
 1210         FlagNZ(RegA.Int);
 1211         RegPC+=2;
 1212         Cycle+=2;
 1213         BREAK("EOR_IM");
 1214         Case( EOR_A )
 1215         LowByte(RegA)^=RBMem(AB());
 1216         FlagNZ(RegA.Int);
 1217         RegPC+=3;
 1218         Cycle+=4;
 1219         BREAK("EOR_A");
 1220         Case( EOR_D )
 1221         LowByte(RegA)^=RBDP(DP());
 1222         FlagNZ(RegA.Int);
 1223         RegPC+=2;
 1224         Cycle+=3;
 1225         BREAK("EOR_D");
 1226         Case( EOR_AX )
 1227         LowByte(RegA)^=RBMem(AX());
 1228         FlagNZ(RegA.Int);
 1229         RegPC+=3;
 1230         Cycle+=4;
 1231         BREAK("EOR_AX");
 1232         Case( EOR_AY )
 1233         LowByte(RegA)^=RBMem(AY());
 1234         FlagNZ(RegA.Int);
 1235         RegPC+=3;
 1236         Cycle+=4;
 1237         BREAK("EOR_AY");
 1238         Case( EOR_DX )
 1239         LowByte(RegA)^=RBDP(DX());
 1240         FlagNZ(RegA.Int);
 1241         RegPC+=2;
 1242         Cycle+=4;
 1243         BREAK("EOR_DX");
 1244         Case( EOR_IX )
 1245         LowByte(RegA)^=RBMem(IX());
 1246         FlagNZ(RegA.Int);
 1247         RegPC+=2;
 1248         Cycle+=6;
 1249         BREAK("EOR_IX");
 1250         Case( EOR_IY )
 1251         LowByte(RegA)^=RBMem(IY());
 1252         FlagNZ(RegA.Int);
 1253         RegPC+=2;
 1254         Cycle+=5;
 1255         BREAK("EOR_IY");
 1256 
 1257         Case( INC_A )
 1258         a=AB();
 1259         WBMem(a,FlagNZ((RBMem(a)+1)&0xFF));
 1260         RegPC+=3;
 1261         Cycle+=6;
 1262         BREAK("INC_A");
 1263         Case( INC_D )
 1264         a=DP();
 1265         WBDP(a,FlagNZ((RBDP(a)+1)&0xFF));
 1266         RegPC+=2;
 1267         Cycle+=5;
 1268         BREAK("INC_D");
 1269         Case( INC_AX )
 1270         a=AX();
 1271         WBMem(a,FlagNZ((RBMem(a)+1)&0xFF));
 1272         RegPC+=3;
 1273         Cycle+=7;
 1274         BREAK("INC_AX");
 1275         Case( INC_DX )
 1276         a=DX();
 1277         WBDP(a,FlagNZ((RBDP(a)+1)&0xFF));
 1278         RegPC+=2;
 1279         Cycle+=6;
 1280         BREAK("INC_DX");
 1281 
 1282         Case( INX )
 1283         FlagNZ(++LowByte(RegX));
 1284         ++RegPC;
 1285         Cycle+=2;
 1286         BREAK("INX");
 1287         Case( INY )
 1288         FlagNZ(++LowByte(RegY));
 1289         ++RegPC;
 1290         Cycle+=2;
 1291         BREAK("INY");
 1292 
 1293         Case( JMP_A )
 1294         RegPC=AB();
 1295         NewPC();
 1296         Cycle+=3;
 1297         BREAK("JMP_A");
 1298         Case( JMP_AI )
 1299         a=AB();
 1300         /* This code for xxFF 6502 bug */
 1301         RegPC=RBMem(a)|(RBMem((a&0xFF00)|((a+1)&0x00FF))<<8);
 1302         NewPC();
 1303         Cycle+=5;
 1304         BREAK("JMP_AI");
 1305 
 1306         Case( JSR )
 1307         a=RegPC+2;
 1308         PushW(a);
 1309         RegPC=AB();
 1310         NewPC();
 1311         Cycle+=6;
 1312         BREAK("JSR");
 1313 
 1314         Case( LDA_IM )
 1315         FlagNZ(LowByte(RegA)=IM());
 1316         RegPC+=2;
 1317         Cycle+=2;
 1318         BREAK("LDA_IM");
 1319         Case( LDA_A )
 1320         LowByte(RegA)=RBMem(AB());
 1321         FlagNZ(RegA.Int);
 1322         RegPC+=3;
 1323         Cycle+=4;
 1324         BREAK("LDA_A");
 1325         Case( LDA_D )
 1326         FlagNZ(LowByte(RegA)=RBDP(DP()));
 1327         RegPC+=2;
 1328         Cycle+=3;
 1329         BREAK("LDA_D");
 1330         Case( LDA_AX )
 1331         LowByte(RegA)=RBMem(AX());
 1332         FlagNZ(RegA.Int);
 1333         RegPC+=3;
 1334         Cycle+=4;
 1335         BREAK("LDA_AX");
 1336         Case( LDA_AY )
 1337         LowByte(RegA)=RBMem(AY());
 1338         FlagNZ(RegA.Int);
 1339         RegPC+=3;
 1340         Cycle+=4;
 1341         BREAK("LDA_AY");
 1342         Case( LDA_DX )
 1343         LowByte(RegA)=RBDP(DX());
 1344         FlagNZ(RegA.Int);
 1345         RegPC+=2;
 1346         Cycle+=4;
 1347         BREAK("LDA_DX");
 1348         Case( LDA_IX )
 1349         LowByte(RegA)=RBMem(IX());
 1350         FlagNZ(RegA.Int);
 1351         RegPC+=2;
 1352         Cycle+=6;
 1353         BREAK("LDA_IX");
 1354         Case( LDA_IY )
 1355         LowByte(RegA)=RBMem(IY());
 1356         FlagNZ(RegA.Int);
 1357         RegPC+=2;
 1358         Cycle+=5;
 1359         BREAK("LDA_IY");
 1360 
 1361         Case( LDX_IM )
 1362         FlagNZ(LowByte(RegX)=IM());
 1363         RegPC+=2;
 1364         Cycle+=2;
 1365         BREAK("LDX_IM");
 1366         Case( LDX_A )
 1367         FlagNZ(LowByte(RegX)=RBMem(AB()));
 1368         RegPC+=3;
 1369         Cycle+=4;
 1370         BREAK("LDX_A");
 1371         Case( LDX_D )
 1372         FlagNZ(LowByte(RegX)=RBDP(DP()));
 1373         RegPC+=2;
 1374         Cycle+=3;
 1375         BREAK("LDX_D");
 1376         Case( LDX_AY )
 1377         FlagNZ(LowByte(RegX)=RBMem(AY()));
 1378         RegPC+=3;
 1379         Cycle+=4;
 1380         BREAK("LDX_AY");
 1381         Case( LDX_DY )
 1382         FlagNZ(LowByte(RegX)=RBDP(DY()));
 1383         RegPC+=2;
 1384         Cycle+=4;
 1385         BREAK("LDX_DY");
 1386 
 1387         Case( LDY_IM )
 1388         FlagNZ(LowByte(RegY)=IM());
 1389         RegPC+=2;
 1390         Cycle+=2;
 1391         BREAK("95");
 1392         Case( LDY_A )
 1393         FlagNZ(LowByte(RegY)=RBMem(AB()));
 1394         RegPC+=3;
 1395         Cycle+=4;
 1396         BREAK("96");
 1397         Case( LDY_D )
 1398         FlagNZ(LowByte(RegY)=RBDP(DP()));
 1399         RegPC+=2;
 1400         Cycle+=3;
 1401         BREAK("97");
 1402         Case( LDY_AX )
 1403         FlagNZ(LowByte(RegY)=RBMem(AX()));
 1404         RegPC+=3;
 1405         Cycle+=4;
 1406         BREAK("98");
 1407         Case( LDY_DX )
 1408         FlagNZ(LowByte(RegY)=RBDP(DX()));
 1409         RegPC+=2;
 1410         Cycle+=4;
 1411         BREAK("99");
 1412 
 1413         Case( LSR )
 1414         LowByte(RegA)=Lsr(RegA.Int);
 1415         ++RegPC;
 1416         Cycle+=2;
 1417         BREAK("100");
 1418         Case( LSR_A )
 1419         a=AB();
 1420         WBMem(a,Lsr(RBMem(a)));
 1421         RegPC+=3;
 1422         Cycle+=6;
 1423         BREAK("101");
 1424         Case( LSR_D )
 1425         a=DP();
 1426         WBDP(a,Lsr(RBDP(a)));
 1427         RegPC+=2;
 1428         Cycle+=5;
 1429         BREAK("LSR_D");
 1430         Case( LSR_AX )
 1431         a=AX();
 1432         WBMem(a,Lsr(RBMem(a)));
 1433         RegPC+=3;
 1434         Cycle+=7;
 1435         BREAK("103");
 1436         Case( LSR_DX )
 1437         a=DX();
 1438         WBDP(a,Lsr(RBDP(a)));
 1439         RegPC+=2;
 1440         Cycle+=6;
 1441         BREAK("LSR_DX");
 1442 
 1443         Case( NOP )
 1444         ++RegPC;
 1445         Cycle+=2;
 1446         BREAK("NOP");
 1447 
 1448         Case( ORA_IM )
 1449         LowByte(RegA)|=IM();
 1450         FlagNZ(RegA.Int);
 1451         RegPC+=2;
 1452         Cycle+=2;
 1453         BREAK("ORA_IM");
 1454         Case( ORA_A )
 1455         LowByte(RegA)|=RBMem(AB());
 1456         FlagNZ(RegA.Int);
 1457         RegPC+=3;
 1458         Cycle+=4;
 1459         BREAK("107");
 1460         Case( ORA_D )
 1461         LowByte(RegA)|=RBDP(DP());
 1462         FlagNZ(RegA.Int);
 1463         RegPC+=2;
 1464         Cycle+=3;
 1465         BREAK("108");
 1466         Case( ORA_AX )
 1467         LowByte(RegA)|=RBMem(AX());
 1468         FlagNZ(RegA.Int);
 1469         RegPC+=3;
 1470         Cycle+=4;
 1471         BREAK("109");
 1472         Case( ORA_AY )
 1473         LowByte(RegA)|=RBMem(AY());
 1474         FlagNZ(RegA.Int);
 1475         RegPC+=3;
 1476         Cycle+=4;
 1477         BREAK("110");
 1478         Case( ORA_DX )
 1479         LowByte(RegA)|=RBDP(DX());
 1480         FlagNZ(RegA.Int);
 1481         RegPC+=2;
 1482         Cycle+=4;
 1483         BREAK("111");
 1484         Case( ORA_IX )
 1485         LowByte(RegA)|=RBMem(IX());
 1486         FlagNZ(RegA.Int);
 1487         RegPC+=2;
 1488         Cycle+=6;
 1489         BREAK("ORA_IX");
 1490         Case( ORA_IY )
 1491         LowByte(RegA)|=RBMem(IY());
 1492         FlagNZ(RegA.Int);
 1493         RegPC+=2;
 1494         Cycle+=5;
 1495         BREAK("ORA_IY");
 1496 
 1497         Case( PHA )
 1498         PushB(RegA.Int);
 1499         ++RegPC;
 1500         Cycle+=3;
 1501         BREAK("PHA");
 1502         Case( PHP )
 1503         PushB(CurrentFlags());
 1504         ++RegPC;
 1505         Cycle+=3;
 1506         BREAK("PHP");
 1507         Case( PLA )
 1508         PopB(LowByte(RegA));
 1509         FlagNZ(RegA.Int);
 1510         ++RegPC;
 1511         Cycle+=4;
 1512         BREAK("PLA");
 1513         Case( PLP )
 1514         PopB(LowByte(RegP));
 1515         LowByte(NegativeFlag)=RegP.Int;
 1516         LastValCarry=RegP.Int&FLAG_CARRY;
 1517         LastValZero=(RegP.Int&FLAG_ZERO)^FLAG_ZERO;
 1518         ++RegPC;
 1519         Cycle+=4;
 1520         if( IrqLine && !(Integer(RegP)&FLAG_INTERRUPT) ) {
 1521             DoIrq();
 1522         }
 1523         BREAK("PLP");
 1524 
 1525         Case( ROL )
 1526         LowByte(RegA)=Rol(RegA.Int);
 1527         ++RegPC;
 1528         Cycle+=2;
 1529         BREAK("ROL");
 1530         Case( ROL_A )
 1531         a=AB();
 1532         WBMem(a,Rol(RBMem(a)));
 1533         RegPC+=3;
 1534         Cycle+=6;
 1535         BREAK("119");
 1536         Case( ROL_D )
 1537         a=DP();
 1538         WBDP(a,Rol(RBDP(a)));
 1539         RegPC+=2;
 1540         Cycle+=5;
 1541         BREAK("120");
 1542         Case( ROL_AX )
 1543         a=AX();
 1544         WBMem(a,Rol(RBMem(a)));
 1545         RegPC+=3;
 1546         Cycle+=7;
 1547         BREAK("121");
 1548         Case( ROL_DX )
 1549         a=DX();
 1550         WBDP(a,Rol(RBDP(a)));
 1551         RegPC+=2;
 1552         Cycle+=6;
 1553         BREAK("122");
 1554 
 1555         Case( ROR )
 1556         LowByte(RegA)=Ror(RegA.Int);
 1557         ++RegPC;
 1558         Cycle+=2;
 1559         BREAK("ROR");
 1560         Case( ROR_A )
 1561         a=AB();
 1562         WBMem(a,Ror(RBMem(a)));
 1563         RegPC+=3;
 1564         Cycle+=6;
 1565         BREAK("ROR_A");
 1566         Case( ROR_D )
 1567         a=DP();
 1568         WBDP(a,Ror(RBDP(a)));
 1569         RegPC+=2;
 1570         Cycle+=5;
 1571         BREAK("ROR_D");
 1572         Case( ROR_AX )
 1573         a=AX();
 1574         WBMem(a,Ror(RBMem(a)));
 1575         RegPC+=3;
 1576         Cycle+=7;
 1577         BREAK("ROR_AX");
 1578         Case( ROR_DX )
 1579         a=DX();
 1580         WBDP(a,Ror(RBDP(a)));
 1581         RegPC+=2;
 1582         Cycle+=6;
 1583         BREAK("ROR_DX");
 1584 
 1585         Case( RTI )
 1586         a=RBOpc();      /* 6502 fetches the next byte */
 1587         PopB(LowByte(RegP));
 1588         LowByte(NegativeFlag)=RegP.Int;
 1589         LastValCarry=RegP.Int&FLAG_CARRY;
 1590         LastValZero=(RegP.Int&FLAG_ZERO)^FLAG_ZERO;
 1591         PopW(RegPC);
 1592         NewPC();
 1593         Cycle+=6;
 1594         if( IrqLine && !(RegP.Int&FLAG_INTERRUPT) ) {
 1595             DoIrq();
 1596         }
 1597         BREAK("RTI");
 1598         Case( RTS )
 1599         a=RBOpc();      /* 6502 fetches the next byte */
 1600         PopW(a);
 1601         RegPC=a+1;
 1602         NewPC();
 1603         Cycle+=6;
 1604         BREAK("RTS");
 1605 
 1606         Case( SBC_IM )
 1607         Sbc(IM());
 1608         RegPC+=2;
 1609         Cycle+=2;
 1610         BREAK("SBC_IM");
 1611         Case( SBC_A )
 1612         Sbc(RBMem(AB()));
 1613         RegPC+=3;
 1614         Cycle+=4;
 1615         BREAK("SBC_A");
 1616         Case( SBC_D )
 1617         Sbc(RBDP(DP()));
 1618         RegPC+=2;
 1619         Cycle+=3;
 1620         BREAK("SBC_D");
 1621         Case( SBC_AX )
 1622         Sbc(RBMem(AX()));
 1623         RegPC+=3;
 1624         Cycle+=4;
 1625         BREAK("SBC_AX");
 1626         Case( SBC_AY )
 1627         Sbc(RBMem(AY()));
 1628         RegPC+=3;
 1629         Cycle+=4;
 1630         BREAK("SBC_AY");
 1631         Case( SBC_DX )
 1632         Sbc(RBDP(DX()));
 1633         RegPC+=2;
 1634         Cycle+=4;
 1635         BREAK("SBC_DX");
 1636         Case( SBC_IX )
 1637         Sbc(RBMem(IX()));
 1638         RegPC+=2;
 1639         Cycle+=6;
 1640         BREAK("SBC_IX");
 1641         Case( SBC_IY )
 1642         Sbc(RBMem(IY()));
 1643         RegPC+=2;
 1644         Cycle+=5;
 1645         BREAK("SBC_IY");
 1646 
 1647         Case( SEC )
 1648         LastValCarry=1;
 1649         ++RegPC;
 1650         Cycle+=2;
 1651         BREAK("SEC");
 1652 
 1653         Case( SED )
 1654         RegP.Int|=FLAG_DECIMAL;
 1655         ++RegPC;
 1656         Cycle+=2;
 1657         BREAK("SED");
 1658 
 1659         Case( SEI )
 1660         RegP.Int|=FLAG_INTERRUPT;
 1661         ++RegPC;
 1662         Cycle+=2;
 1663         BREAK("SEI");
 1664 
 1665         Case( STA_A )
 1666         WBMem(AB(),RegA.Int);
 1667         RegPC+=3;
 1668         Cycle+=4;
 1669         BREAK("STA_A");
 1670         Case( STA_D )
 1671         WBDP(DP(),RegA.Int);
 1672         RegPC+=2;
 1673         Cycle+=3;
 1674         BREAK("STA_D");
 1675         Case( STA_AX )
 1676         WBMem(AX(),RegA.Int);
 1677         RegPC+=3;
 1678         Cycle+=5;
 1679         BREAK("STA_AX");
 1680         Case( STA_AY )
 1681         WBMem(AY(),RegA.Int);
 1682         RegPC+=3;
 1683         Cycle+=5;
 1684         BREAK("STA_AY");
 1685         Case( STA_DX )
 1686         WBDP(DX(),RegA.Int);
 1687         RegPC+=2;
 1688         Cycle+=4;
 1689         BREAK("STA_DX");
 1690         Case( STA_IX )
 1691         WBMem(IX(),RegA.Int);
 1692         RegPC+=2;
 1693         Cycle+=6;
 1694         BREAK("STA_IX");
 1695         Case( STA_IY )
 1696         WBMem(IY(),RegA.Int);
 1697         RegPC+=2;
 1698         Cycle+=6;
 1699         BREAK("STA_IY");
 1700 
 1701         Case( STX_A )
 1702         WBMem(AB(),RegX.Int);
 1703         RegPC+=3;
 1704         Cycle+=4;
 1705         BREAK("148");
 1706         Case( STX_D )
 1707         WBDP(DP(),RegX.Int);
 1708         RegPC+=2;
 1709         Cycle+=3;
 1710         BREAK("149");
 1711         Case( STX_DY )
 1712         WBDP(DY(),RegX.Int);
 1713         RegPC+=2;
 1714         Cycle+=4;
 1715         BREAK("150");
 1716 
 1717         Case( STY_A )
 1718         WBMem(AB(),RegY.Int);
 1719         RegPC+=3;
 1720         Cycle+=4;
 1721         BREAK("151");
 1722         Case( STY_D )
 1723         WBDP(DP(),RegY.Int);
 1724         RegPC+=2;
 1725         Cycle+=3;
 1726         BREAK("152");
 1727         Case( STY_DX )
 1728         WBDP(DX(),RegY.Int);
 1729         RegPC+=2;
 1730         Cycle+=4;
 1731         BREAK("153");
 1732 
 1733         Case( TAX )
 1734         FlagNZ(RegX.Int=RegA.Int);
 1735         ++RegPC;
 1736         Cycle+=2;
 1737         BREAK("154");
 1738         Case( TAY )
 1739         FlagNZ(LowByte(RegY)=RegA.Int);
 1740         ++RegPC;
 1741         Cycle+=2;
 1742         BREAK("155");
 1743         Case( TSX )
 1744         FlagNZ(LowByte(RegX)=Integer(RegS));
 1745         ++RegPC;
 1746         Cycle+=2;
 1747         BREAK("156");
 1748         Case( TXA )
 1749         FlagNZ(LowByte(RegA)=RegX.Int);
 1750         ++RegPC;
 1751         Cycle+=2;
 1752         BREAK("157");
 1753         Case( TXS )
 1754         LowByte(RegS)=RegX.Int;
 1755         ++RegPC;
 1756         Cycle+=2;
 1757         BREAK("158");
 1758         Case( TYA )
 1759         FlagNZ(LowByte(RegA)=RegY.Int);
 1760         ++RegPC;
 1761         Cycle+=2;
 1762         BREAK("159");
 1763 
 1764         /*
 1765         **  Illegal 6502 instructions emulation:
 1766         */
 1767 
 1768         Case( ILL02 )       /* EMULATOR TRAP CODE */
 1769         if( RBIns() ) {
 1770             SaveLocalRegsEmulTrap();
 1771             EmulatorTrap(RBIns());
 1772             LoadLocalRegsEmulTrap();
 1773         } else {
 1774             SaveLocalRegs();
 1775             return;
 1776         }
 1777         Cycle+=3;
 1778         BREAK("ILL02");
 1779 
 1780         Case( ILL12 ) Case( ILL22 ) Case( ILL32 ) Case( ILL42 )
 1781         Case( ILL52 ) Case( ILL62 ) Case( ILL72 ) Case( ILL92 )
 1782         Case( ILLB2 ) Case( ILLD2 ) Case( ILLF2 )
 1783 #ifdef X11
 1784         printf("Illegal instruction at $%04X: $%02X\n",RegPC,RBOpc());
 1785 #endif
 1786         { char buf[40];
 1787 #ifdef _1541_
 1788         sprintf(buf,"1541: JAM inst at %04X",RegPC);
 1789 #else
 1790         sprintf(buf,"JAM inst at %04X",RegPC);
 1791 #endif
 1792         VicMessage(buf,FRAMES_PER_SECOND*3);
 1793         }
 1794         DoReset();
 1795         BREAK("ILL12...");
 1796 
 1797         Case( ILL1A )       /* NOP 1 Byte */
 1798         Case( ILL3A ) Case( ILL5A ) Case( ILL7A ) Case( ILLDA )
 1799         Case( ILLFA )
 1800         ++RegPC;
 1801         Cycle+=2;
 1802         BREAK("ILL1A...");
 1803         Case( ILL80 )       /* NOP 2 Byte 2 clocks */
 1804         Case( ILL82 ) Case( ILL89 ) Case( ILLC2 ) Case( ILLE2 )
 1805         RegPC+=2;
 1806         Cycle+=2;
 1807         BREAK("ILL80...");
 1808         Case( ILL04 )       /* NOP 2 Byte 3 clocks */
 1809         Case( ILL44 ) Case( ILL64 )
 1810         RegPC+=2;
 1811         Cycle+=3;
 1812         BREAK("ILL04...");
 1813         Case( ILL14 )       /* NOP 2 Byte 4 clocks */
 1814         Case( ILL34 ) Case( ILL54 ) Case( ILL74 ) Case( ILLD4 )
 1815         Case( ILLF4 )
 1816         RegPC+=2;
 1817         Cycle+=4;
 1818         BREAK("ILL14...");
 1819 
 1820         Case( ILL0C )       /* NOP 3 Byte 4 clocks */
 1821         RegPC+=3;
 1822         Cycle+=4;
 1823         BREAK("ILL0C");
 1824         Case( ILL1C )       /* NOP 3 Byte 5 clocks */
 1825         Case( ILL3C ) Case( ILL5C ) Case( ILL7C ) Case( ILLDC )
 1826         Case( ILLFC )
 1827         RegPC+=3;
 1828         Cycle+=5;
 1829         BREAK("ILL1C...");
 1830 
 1831         Case( ILL03 )       /* ASL ORA (,X) */
 1832         a=IX();
 1833         WBMem(a,Asl(RBMem(a)));
 1834         LowByte(RegA)|=RBMem(a);
 1835         FlagNZ(RegA.Int);
 1836         RegPC+=2;
 1837         Cycle+=8;
 1838         BREAK("168");
 1839         Case( ILL13 )       /* ASL ORA (,Y) */
 1840         a=IY();
 1841         WBMem(a,Asl(RBMem(a)));
 1842         LowByte(RegA)|=RBMem(a);
 1843         FlagNZ(RegA.Int);
 1844         RegPC+=2;
 1845         Cycle+=8;
 1846         BREAK("169");
 1847         Case( ILL0F )       /* ASL ORA $XXXX */
 1848         a=AB();
 1849         WBMem(a,Asl(RBMem(a)));
 1850         LowByte(RegA)|=RBMem(a);
 1851         FlagNZ(RegA.Int);
 1852         RegPC+=3;
 1853         Cycle+=6;
 1854         BREAK("170");
 1855         Case( ILL1F )       /* ASL ORA $XXXX,X */
 1856         a=AX();
 1857         WBMem(a,Asl(RBMem(a)));
 1858         LowByte(RegA)|=RBMem(a);
 1859         FlagNZ(RegA.Int);
 1860         RegPC+=3;
 1861         Cycle+=7;
 1862         BREAK("171");
 1863         Case( ILL1B )       /* ASL ORA $XXXX,Y */
 1864         a=AY();
 1865         WBMem(a,Asl(RBMem(a)));
 1866         LowByte(RegA)|=RBMem(a);
 1867         FlagNZ(RegA.Int);
 1868         RegPC+=3;
 1869         Cycle+=7;
 1870         BREAK("172");
 1871         Case( ILL07 )       /* ASL ORA $XX */
 1872         a=DP();
 1873         WBDP(a,Asl(RBDP(a)));
 1874         LowByte(RegA)|=RBDP(a);
 1875         FlagNZ(RegA.Int);
 1876         RegPC+=2;
 1877         Cycle+=5;
 1878         BREAK("173");
 1879         Case( ILL17 )       /* ASL ORA $XX,X */
 1880         a=DX();
 1881         WBDP(a,Asl(RBDP(a)));
 1882         LowByte(RegA)|=RBDP(a);
 1883         FlagNZ(RegA.Int);
 1884         RegPC+=2;
 1885         Cycle+=6;
 1886         BREAK("174");
 1887 
 1888         Case( ILL23 )       /* ROL AND (,X) */
 1889         a=IX();
 1890         WBMem(a,Rol(RBMem(a)));
 1891         LowByte(RegA)&=RBMem(a);
 1892         FlagNZ(RegA.Int);
 1893         RegPC+=2;
 1894         Cycle+=8;
 1895         BREAK("175");
 1896         Case( ILL33 )       /* ROL AND (,Y) */
 1897         a=IY();
 1898         WBMem(a,Rol(RBMem(a)));
 1899         LowByte(RegA)&=RBMem(a);
 1900         FlagNZ(RegA.Int);
 1901         RegPC+=2;
 1902         Cycle+=8;
 1903         BREAK("176");
 1904         Case( ILL2F )       /* ROL AND $XXXX */
 1905         a=AB();
 1906         WBMem(a,Rol(RBMem(a)));
 1907         LowByte(RegA)&=RBMem(a);
 1908         FlagNZ(RegA.Int);
 1909         RegPC+=3;
 1910         Cycle+=6;
 1911         BREAK("177");
 1912         Case( ILL3F )       /* ROL AND $XXXX,X */
 1913         a=AX();
 1914         WBMem(a,Rol(RBMem(a)));
 1915         LowByte(RegA)&=RBMem(a);
 1916         FlagNZ(RegA.Int);
 1917         RegPC+=3;
 1918         Cycle+=7;
 1919         BREAK("178");
 1920         Case( ILL3B )       /* ROL AND $XXXX,Y */
 1921         a=AY();
 1922         WBMem(a,Rol(RBMem(a)));
 1923         LowByte(RegA)&=RBMem(a);
 1924         FlagNZ(RegA.Int);
 1925         RegPC+=3;
 1926         Cycle+=7;
 1927         BREAK("179");
 1928         Case( ILL27 )       /* ROL AND $XX */
 1929         a=DP();
 1930         WBDP(a,Rol(RBDP(a)));
 1931         LowByte(RegA)&=RBDP(a);
 1932         FlagNZ(RegA.Int);
 1933         RegPC+=2;
 1934         Cycle+=5;
 1935         BREAK("180");
 1936         Case( ILL37 )       /* ROL AND $XX,X */
 1937         a=DX();
 1938         WBDP(a,Rol(RBDP(a)));
 1939         LowByte(RegA)&=RBDP(a);
 1940         FlagNZ(RegA.Int);
 1941         RegPC+=2;
 1942         Cycle+=6;
 1943         BREAK("181");
 1944 
 1945         Case( ILL43 )       /* LSR EOR (,X) */
 1946         a=IX();
 1947         WBMem(a,Lsr(RBMem(a)));
 1948         LowByte(RegA)^=RBMem(a);
 1949         FlagNZ(RegA.Int);
 1950         RegPC+=2;
 1951         Cycle+=8;
 1952         BREAK("182");
 1953         Case( ILL53 )       /* LSR EOR (,Y) */
 1954         a=IY();
 1955         WBMem(a,Lsr(RBMem(a)));
 1956         LowByte(RegA)^=RBMem(a);
 1957         FlagNZ(RegA.Int);
 1958         RegPC+=2;
 1959         Cycle+=8;
 1960         BREAK("183");
 1961         Case( ILL4F )       /* LSR EOR $XXXX */
 1962         a=AB();
 1963         WBMem(a,Lsr(RBMem(a)));
 1964         LowByte(RegA)^=RBMem(a);
 1965         FlagNZ(RegA.Int);
 1966         RegPC+=3;
 1967         Cycle+=6;
 1968         BREAK("184");
 1969         Case( ILL5F )       /* LSR EOR $XXXX,X */
 1970         a=AX();
 1971         WBMem(a,Lsr(RBMem(a)));
 1972         LowByte(RegA)^=RBMem(a);
 1973         FlagNZ(RegA.Int);
 1974         RegPC+=3;
 1975         Cycle+=7;
 1976         BREAK("185");
 1977         Case( ILL5B )       /* LSR EOR $XXXX,Y */
 1978         a=AY();
 1979         WBMem(a,Lsr(RBMem(a)));
 1980         LowByte(RegA)^=RBMem(a);
 1981         FlagNZ(RegA.Int);
 1982         RegPC+=3;
 1983         Cycle+=7;
 1984         BREAK("186");
 1985         Case( ILL47 )       /* LSR EOR $XX */
 1986         a=DP();
 1987         WBDP(a,Lsr(RBDP(a)));
 1988         LowByte(RegA)^=RBDP(a);
 1989         FlagNZ(RegA.Int);
 1990         RegPC+=2;
 1991         Cycle+=5;
 1992         BREAK("ILL47");
 1993         Case( ILL57 )       /* LSR EOR $XX,X */
 1994         a=DX();
 1995         WBDP(a,Lsr(RBDP(a)));
 1996         LowByte(RegA)^=RBDP(a);
 1997         FlagNZ(RegA.Int);
 1998         RegPC+=2;
 1999         Cycle+=6;
 2000         BREAK("188");
 2001 
 2002         Case( ILL63 )       /* ROR ADC (,X) */
 2003         a=IX();
 2004         WBMem(a,Ror(RBMem(a)));
 2005         Adc(RBMem(a));
 2006         FlagNZ(RegA.Int);
 2007         RegPC+=2;
 2008         Cycle+=8;
 2009         BREAK("189");
 2010         Case( ILL73 )       /* ROR ADC (,Y) */
 2011         a=IY();
 2012         WBMem(a,Ror(RBMem(a)));
 2013         Adc(RBMem(a));
 2014         FlagNZ(RegA.Int);
 2015         RegPC+=2;
 2016         Cycle+=8;
 2017         BREAK("190");
 2018         Case( ILL6F )       /* ROR ADC $XXXX */
 2019         a=AB();
 2020         WBMem(a,Ror(RBMem(a)));
 2021         Adc(RBMem(a));
 2022         FlagNZ(RegA.Int);
 2023         RegPC+=3;
 2024         Cycle+=6;
 2025         BREAK("191");
 2026         Case( ILL7F )       /* ROR ADC $XXXX,X */
 2027         a=AX();
 2028         WBMem(a,Ror(RBMem(a)));
 2029         Adc(RBMem(a));
 2030         FlagNZ(RegA.Int);
 2031         RegPC+=3;
 2032         Cycle+=7;
 2033         BREAK("192");
 2034         Case( ILL7B )       /* ROR ADC $XXXX,Y */
 2035         a=AY();
 2036         WBMem(a,Ror(RBMem(a)));
 2037         Adc(RBMem(a));
 2038         FlagNZ(RegA.Int);
 2039         RegPC+=3;
 2040         Cycle+=7;
 2041         BREAK("193");
 2042         Case( ILL67 )       /* ROR ADC $XX */
 2043         a=DP();
 2044         WBDP(a,Ror(RBDP(a)));
 2045         Adc(RBDP(a));
 2046         FlagNZ(RegA.Int);
 2047         RegPC+=2;
 2048         Cycle+=5;
 2049         BREAK("194");
 2050         Case( ILL77 )       /* ROR ADC $XX,X */
 2051         a=DX();
 2052         WBDP(a,Ror(RBDP(a)));
 2053         Adc(RBDP(a));
 2054         FlagNZ(RegA.Int);
 2055         RegPC+=2;
 2056         Cycle+=6;
 2057         BREAK("ILL77");
 2058 
 2059         Case( ILLC3 )       /* DEC CMP (,X) */
 2060         a=IX();
 2061         WBMem(a,RBMem(a)-1);
 2062         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2063         RegPC+=2;
 2064         Cycle+=8;
 2065         BREAK("ILLC3");
 2066         Case( ILLD3 )       /* DEC CMP (,Y) */
 2067         a=IY();
 2068         WBMem(a,RBMem(a)-1);
 2069         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2070         RegPC+=2;
 2071         Cycle+=8;
 2072         BREAK("ILLD3");
 2073         Case( ILLCF )       /* DEC CMP $XXXX */
 2074         a=AB();
 2075         WBMem(a,RBMem(a)-1);
 2076         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2077         RegPC+=3;
 2078         Cycle+=6;
 2079         BREAK("ILLCF");
 2080         Case( ILLDF )       /* DEC CMP $XXXX,X */
 2081         a=AX();
 2082         WBMem(a,RBMem(a)-1);
 2083         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2084         RegPC+=3;
 2085         Cycle+=7;
 2086         BREAK("ILLDF");
 2087         Case( ILLDB )       /* DEC CMP $XXXX,Y */
 2088         a=AY();
 2089         WBMem(a,RBMem(a)-1);
 2090         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2091         RegPC+=3;
 2092         Cycle+=7;
 2093         BREAK("200");
 2094         Case( ILLC7 )       /* DEC CMP $XX */
 2095         a=DP();
 2096         WBDP(a,RBDP(a)-1);
 2097         FlagNZC(RegA.Int+(RBDP(a)^0xFF));
 2098         RegPC+=2;
 2099         Cycle+=5;
 2100         BREAK("ILLC7");
 2101         Case( ILLD7 )       /* DEC CMP $XX,X */
 2102         a=DX();
 2103         WBDP(a,RBDP(a)-1);
 2104         FlagNZC(RegA.Int+(RBMem(a)^0xFF));
 2105         RegPC+=2;
 2106         Cycle+=6;
 2107         BREAK("ILLD7");
 2108 
 2109         Case( ILLE3 )       /* INC SBC (,X) */
 2110         a=IX();
 2111         WBMem(a,RBMem(a)+1);
 2112         Sbc(RBMem(a));
 2113         RegPC+=2;
 2114         Cycle+=8;
 2115         BREAK("ILLE3");
 2116         Case( ILLF3 )       /* INC SBC (,Y) */
 2117         a=IY();
 2118         WBMem(a,RBMem(a)+1);
 2119         Sbc(RBMem(a));
 2120         RegPC+=2;
 2121         Cycle+=8;
 2122         BREAK("ILLF3");
 2123         Case( ILLEF )       /* INC SBC $XXXX */
 2124         a=AB();
 2125         WBMem(a,RBMem(a)+1);
 2126         Sbc(RBMem(a));
 2127         RegPC+=3;
 2128         Cycle+=6;
 2129         BREAK("ILLEF");
 2130         Case( ILLFF )       /* INC SBC $XXXX,X */
 2131         a=AX();
 2132         WBMem(a,RBMem(a)+1);
 2133         Sbc(RBMem(a));
 2134         RegPC+=3;
 2135         Cycle+=7;
 2136         BREAK("ILLFF");
 2137         Case( ILLFB )       /* INC SBC $XXXX,Y */
 2138         a=AY();
 2139         WBMem(a,RBMem(a)+1);
 2140         Sbc(RBMem(a));
 2141         RegPC+=3;
 2142         Cycle+=7;
 2143         BREAK("ILLFB");
 2144         Case( ILLE7 )       /* INC SBC $XX */
 2145         a=DP();
 2146         WBDP(a,RBDP(a)+1);
 2147         Sbc(RBDP(a));
 2148         RegPC+=2;
 2149         Cycle+=5;
 2150         BREAK("ILLE7");
 2151         Case( ILLF7 )       /* INC SBC $XX,X */
 2152         a=DX();
 2153         WBDP(a,RBDP(a)+1);
 2154         Sbc(RBDP(a));
 2155         RegPC+=2;
 2156         Cycle+=6;
 2157         BREAK("ILLF7");
 2158 
 2159         Case( ILLA3 )       /* LDA TAX (,X) */
 2160         LowByte(RegX)=LowByte(RegA)=RBMem(IX());
 2161         FlagNZ(RegX.Int);
 2162         RegPC+=2;
 2163         Cycle+=6;
 2164         BREAK("ILLA3");
 2165         Case( ILLB3 )       /* LDA TAX (),Y */
 2166         LowByte(RegX)=LowByte(RegA)=RBMem(IY());
 2167         FlagNZ(RegX.Int);
 2168         RegPC+=2;
 2169         Cycle+=5;
 2170         BREAK("ILLB3");
 2171         Case( ILLAF )       /* LDA TAX $XXXX */
 2172         LowByte(RegX)=LowByte(RegA)=RBMem(AB());
 2173         FlagNZ(RegX.Int);
 2174         RegPC+=3;
 2175         Cycle+=4;
 2176         BREAK("ILLAF");
 2177         Case( ILLBF )       /* LDA TAX $XXXX,Y */
 2178         LowByte(RegX)=LowByte(RegA)=RBMem(AY());
 2179         FlagNZ(RegX.Int);
 2180         RegPC+=3;
 2181         Cycle+=5;
 2182         BREAK("ILLBF");
 2183         Case( ILLA7 )       /* LDA TAX DP */
 2184         LowByte(RegX)=LowByte(RegA)=RBDP(DP());
 2185         FlagNZ(RegX.Int);
 2186         RegPC+=2;
 2187         Cycle+=3;
 2188         BREAK("ILLA7");
 2189         Case( ILLB7 )       /* LDA TAX DP,Y */
 2190         LowByte(RegX)=LowByte(RegA)=RBDP(DY());
 2191         FlagNZ(RegX.Int);
 2192         RegPC+=2;
 2193         Cycle+=4;
 2194         BREAK("ILLB7");
 2195 
 2196         Case( ILL0B )       /* AND #$xx N -> C */
 2197         FlagNZ(LowByte(RegA)&=IM());
 2198         // LowByte(NegativeFlag)=LastValCarry<<7;
 2199         LastValCarry=Integer(NegativeFlag)>>7;
 2200         RegPC+=2;
 2201         Cycle+=2;
 2202         BREAK("ILL0B");
 2203 
 2204         Case( ILL2B )       /* AND #$xx N -> C */
 2205         FlagNZ(LowByte(RegA)&=IM());
 2206         // LowByte(NegativeFlag)=LastValCarry<<7;
 2207         LastValCarry=Integer(NegativeFlag)>>7;
 2208         RegPC+=2;
 2209         Cycle+=2;
 2210         BREAK("ILL2B");
 2211 
 2212         Case( ILL4B )       /* AND #$xx LSR */
 2213         Lsr(RegA.Int&RBMem(IM()));
 2214         RegPC+=2;
 2215         Cycle+=2;
 2216         BREAK("ILL4B");
 2217 
 2218         /* Store A/X */
 2219         Case( ILL83 )       /* AND X STA ($XX,X) */
 2220         WBMem(IX(),RegA.Int&RegX.Int);
 2221         // proved to be incorrect: FlagNZ(RegA.Int&RegX.Int);
 2222         RegPC+=2;
 2223         Cycle+=6;
 2224         BREAK("ILL83");
 2225 
 2226         Case( ILL87 )       /* AND X STA $XX */
 2227         WBDP(DP(),RegA.Int&RegX.Int);
 2228         // proved to be incorrect: FlagNZ(RegA.Int&RegX.Int);
 2229         RegPC+=2;
 2230         Cycle+=3;
 2231         BREAK("ILL87");
 2232 
 2233         Case( ILL8F )       /* AND X STA $XXXX */
 2234         WBMem(AB(),RegA.Int&RegX.Int);
 2235         // proved to be incorrect: FlagNZ(RegA.Int&RegX.Int);
 2236         RegPC+=3;
 2237         Cycle+=4;
 2238         BREAK("ILL8F");
 2239 
 2240         Case( ILL93 )       /* SHA (xx),Y */
 2241 #if defined(X11) && defined(DEBUG)
 2242         printf("ILL93: $%04X\n",RegPC);
 2243 #endif
 2244         WBDP(IY(),RegA.Int&RegX.Int);
 2245         RegPC+=2;
 2246         Cycle+=6;
 2247         BREAK("ILL93");
 2248 
 2249         Case( ILL97 )       /* AND X STA $XX,Y */
 2250         WBDP(DY(),RegA.Int&RegX.Int);
 2251         // proved to be incorrect: FlagNZ(RegA.Int&RegX.Int);
 2252         RegPC+=2;
 2253         Cycle+=4;
 2254         BREAK("ILL97");
 2255 
 2256         Case( ILL9B )       /* SHS $xxYY,y  A&X&xx+1 -> SP */
 2257 #if defined(X11) && defined(DEBUG)
 2258         printf("ILL9B: $%04X\n",RegPC);
 2259 #endif
 2260         // FIXME: proved to be incorrect!
 2261         // LowByte(RegS)=Integer(RegA)&Integer(RegX)&((RWIns()>>8)+1);
 2262         LowByte(RegS)=Integer(RegA)&Integer(RegX);
 2263         WBMem(AY(),Integer(RegS));
 2264         RegPC+=3;
 2265         Cycle+=5;
 2266         BREAK("ILL9B");
 2267 
 2268         Case( ILL9C )       /* AND Y AND #$xx+1 $xxYY,X */
 2269         WBMem(AX(),Integer(RegA)&Integer(RegY)&((RWIns()>>8)+1));
 2270         RegPC+=3;
 2271         Cycle+=5;
 2272         BREAK("ILL9C");
 2273 
 2274         Case( ILL9E )       /* SHX $xxYY,Y Store X&xx+1 */
 2275 #if defined(X11) && defined(DEBUG)
 2276         printf("ILL9E: $%04X\n",RegPC);
 2277 #endif
 2278         WBMem(AY(),RegX.Int&((RWIns()>>8)+1));
 2279         /* FIXME:
 2280         if( ((RWIns()&0xFF)+RegY.Int)>0xFF ) {
 2281             a=RegX.Int&((RWIns()>>8)+1));
 2282         } else {
 2283             a=AB();
 2284         }
 2285         WBMem(a+RegY.Int,RegX.Int&((RWIns()>>8)+1));
 2286         */
 2287         RegPC+=3;
 2288         Cycle+=5;
 2289         BREAK("ILL9E");
 2290 
 2291         Case( ILL9F )       /* AND X AND #$xx+1 $xxYY,Y */
 2292 #if defined(X11) && defined(DEBUG)
 2293         printf("ILL9F: $%04X\n",RegPC);
 2294 #endif
 2295         WBMem(AY(),RegA.Int&RegX.Int&((RWIns()>>8)+1));
 2296         RegPC+=3;
 2297         Cycle+=5;
 2298         BREAK("ILL9F");
 2299 
 2300         Case( ILLAB )       /* AND #$XX TAX */
 2301         /* RANDOM OPCODE */
 2302 #if defined(X11) && defined(DEBUG)
 2303         printf("Random opcode ILLAB: $%04X\n",RegPC);
 2304 #endif
 2305         LowByte(RegX)=LowByte(RegA)=RegA.Int&IM()&Cycle;
 2306         FlagNZ(RegX.Int);
 2307         RegPC+=2;
 2308         Cycle+=2;
 2309         BREAK("ILLAB");
 2310 
 2311         Case( ILLCB )       /* SBX A AND X - #$XX */
 2312         FlagNZC(LowByte(RegX)=(RegA.Int&RegX.Int)-IM());
 2313         RegPC+=2;
 2314         Cycle+=2;
 2315         BREAK("ILLCB");
 2316 
 2317         Case( ILLEB )       /* SBC #$XX */
 2318         Sbc(IM());
 2319         RegPC+=2;
 2320         Cycle+=2;
 2321         BREAK("ILLEB");
 2322 
 2323         Case( ILLBB )       /* LAS $xxYY,y AND SP */
 2324         FlagNZ(
 2325             LowByte(RegS)=
 2326             LowByte(RegX)=
 2327             LowByte(RegA)=RBMem(AY())&RegA.Int);
 2328         RegPC+=3;
 2329         Cycle+=4;
 2330         BREAK("ILLBB");
 2331 
 2332         Case( ILL8B )       /* LDA #xx AND A OR EE AND X */
 2333         FlagNZ(
 2334             LowByte(RegA)=((Integer(RegA)|0xEE) &IM()&Integer(RegX))
 2335         );
 2336         RegPC+=2;
 2337         Cycle+=2;
 2338         BREAK("ILL8B");
 2339 
 2340         Case( ILL6B )       /* ROR #xx AND A */
 2341         LowByte(RegA)=Ror(Integer(RegA)|IM());
 2342         RegPC+=2;
 2343         Cycle+=2;
 2344         BREAK("ILL6B");
 2345 
 2346         Default         /* should now never happen */
 2347         Cleanup();
 2348         printf("Illegal instruction at $%04X: $%02X\n",
 2349             RegPC,RBOpc());
 2350         Dis(RegPC);
 2351         printf("\n");
 2352         abort();
 2353     }
 2354 BreakLabel
 2355 
 2356     SaveLocalRegsHardware();    /* LOCAL -> GLOBAL */
 2357 
 2358     /*
 2359     ** Hardware emulation:
 2360     **
 2361     **  FIXME:  6502:   Interrupts. (Should be made??)
 2362     **  CIA1:   Timer A,Timer B,TOD,SERIAL PORT.
 2363     **  CIA2:   Timer A,Timer B,TOD,SERIAL PORT.
 2364     **  VIC:    Displayline, Irq rasterline.
 2365     **      Each VIC frame: Keyboard, Joystick, SID.
 2366     **  Monitor: Single Step, Breakpoint.
 2367     */
 2368     do {
 2369 #ifdef _1541_
 2370         if( !ActionFunction ) { /* 1541: enough cycles emulated */
 2371         SaveLocalRegs();
 2372         return;
 2373         }
 2374 #endif
 2375         (*ActionFunction)();
 2376     } while( Cycle>=Action );   /* until no more hardware actions */
 2377 
 2378     LoadLocalRegsHardware();    /* GLOBAL -> LOCAL */
 2379     }
 2380 }