{$A+,B-,D-,E+,F-,G+,I-,L-,N+,O-,P-,Q-,R-,S-,T-,V-,X+,Y-}
{$M 16384,0,655360}

{ Set the next definition to compile for 160x200 mode, and also set LOWRES }
{ to 1 in HAND_TIA.ASM                                                     }

{ DEFINE LOWRES}
Program Atari_2600_Emulator (Input,Output);
Uses Crt,Dos,HexWrite,Keyboard,AtariDbg,TIASound,Mouse,Time,_Globals,_XMS;

Const
  playback_freq : Word = 31400;
  sample_freq   : Word = 31400;
  num_bufs      : Word = 2;
  SoundBufSize  : Word = 4096;   { Default buffer size = 4k }

  SC_INDEX      = $3C4;   { Sequence Controller Index register   }
  GC_INDEX      = $3CE;   { Graphics Controller Index register   }
  CRTC_INDEX    = $3D4;   { CRT Controller Index register        }
  MISCELLANEOUS = 6;      { Moscellaneous register index in GC   }
  MEMORY_MODE   = 4;      { Memory Mode register index in SC     }
  GRAPHICS_MODE = 5;      { Graphics Mode register index in GC   }
  MAX_SCAN_LINE = 9;      { Maximum Scan Line reg index in CRTC  }
  UNDERLINE     = $14;    { Underline Location reg index in CRTC }
  MODE_CONTROL  = $17;    { Mode Control register index in CRTC  }
  MAP_MASK      = 2;      { Map Mask register index in SC        }

  HORZ_TOTAL         = 0; { CRTC registers }
  HORZ_DISPLAY_END   = 1;
  START_HORZ_BLANK   = 2;
  END_HORZ_BLANK     = 3;
  START_HORZ_RETRACE = 4;
  END_HORZ_RETRACE   = 5;
  VERT_TOTAL         = 6;
  OVERFLOW           = 7;
  START_VERT_RETRACE = $10;
  END_VERT_RETRACE   = $11;
  VERT_DISPLAY_END   = $12;
  CRTC_OFFSET        = $13;
  START_VERT_BLANK   = $15;
  END_VERT_BLANK     = $16;

  Version        = '1.5';
  ExtraAdd       = 2;
  Passes         = 50;
  SetLocDelay    = 4;
  Read_Delay     = 12500;
  _32BIT_OPERAND = $66;
  _32BIT_ADDRESS = $67;
  _Cycles        = 16384;
  AtariSegSize   = 65500;
  ConfigFile     = 'ATARI.CFG';
  SBPort         = $220;
  SBInt          = 7;
  SBDMA          = 1;
  FMChip         = $388;
  SoundDiv       = 5.9;
  Indy500Trans : Array[0..3] Of Byte = ($EF,$FF,$7F,$CF);
  FMDiv : Array[0..15] Of Word =
   (1,1,15,1,2,2,31,2,1,1,31,1,6,6,93,6);
  Coeff : Array[0..15] Of Word =
{   (0,13,120,32,2,2,62,62,1,62,69,0,6,6,186,64);}
{   (0,13,120,32,2,2,31,62,1,62,69,0,6,6,186,64);}
{   (0,13,8,32,1,1,1,31,1,62,2,0,1,1,2,11);}
   (0,13,8,32,1,1,1,31,1,62,1,0,1,1,1,11);

  { TIA write registers }

  VSYNC   = 0;
  VBLANK  = 1;
  WSYNC   = 2;
  RSYNC   = 3;
  NUSIZ0  = 4;
  NUSIZ1  = 5;
  COLUP0  = 6;
  COLUP1  = 7;
  COLUPF  = 8;
  COLUBK  = 9;
  CTRLPF  = $0A;
  REFP0   = $0B;
  REFP1   = $0C;
  PF0     = $0D;
  PF1     = $0E;
  PF2     = $0F;
  RESP0   = $10;
  RESP1   = $11;
  RESM0   = $12;
  RESM1   = $13;
  RESBL   = $14;
  AUDC0   = $15;
  AUDC1   = $16;
  AUDF0   = $17;
  AUDF1   = $18;
  AUDV0   = $19;
  AUDV1   = $1A;
  GRP0    = $1B;
  GRP1    = $1C;
  ENAM0   = $1D;
  ENAM1   = $1E;
  ENABL   = $1F;
  HMP0    = $20;
  HMP1    = $21;
  HMM0    = $22;
  HMM1    = $23;
  HMBL    = $24;
  VDELP0  = $25;
  VDELP1  = $26;
  VDELBL  = $27;
  RESMP0  = $28;
  RESMP1  = $29;
  HMOVE   = $2A;
  HMCLR   = $2B;
  CXCLR   = $2C;
  SWCHA1  = $280;
  SWACNT1 = $281;
  SWCHB1  = $282;
  SWBCNT1 = $283;
  INTTIM1 = $284;
  INTTIM3 = $285;
  TIM1T1  = $294;
  TIM2T1  = $295;
  TIM3T1  = $296;
  TIM4T1  = $297;
  SWCHA2  = $380;
  SWACNT2 = $381;
  SWCHB2  = $382;
  SWBCNT2 = $383;
  INTTIM2 = $384;
  TIM1T2  = $394;
  TIM2T2  = $395;
  TIM3T2  = $396;
  TIM4T2  = $397;

  TIA_Name : Array[0..$2C] Of String[6] =
   ('VSYNC' ,'VBLANK','WSYNC' ,'RSYNC' ,'NUSIZ0','NUSIZ1','COLUP0','COLUP1',
    'COLUPF','COLUBK','CTRLPF','REFP0' ,'REFP1' ,'PF0'   ,'PF1'   ,'PF2',
    'RESP0' ,'RESP1' ,'RESM0' ,'RESM1' ,'RESBL' ,'AUDC0' ,'AUDC1' ,'AUDF0',
    'AUDF1' ,'AUDV0' ,'AUDV1' ,'GRP0'  ,'GRP1'  ,'ENAM0' ,'ENAM1' ,'ENABL' ,
    'HMP0'  ,'HMP1'  ,'HMM0'  ,'HMM1'  ,'HMBL'  ,'VDELP0','VDELP1','VDELBL',
    'RESMP0','RESMP1','HMOVE' ,'HMCLR' ,'CXCLR');

  PIA_Name : Array[$280..$297] Of String[8] =
   ('SWCHA','SWACNT','SWCHB','SWBCNT','INTTIM','INTTIM','','','','','','','','',
    '','','','','','','TIM1T','TIM8T','TIM64T','TIM1024T');

  TIA_Read_Name : Array[0..$D] Of String[6] =
   ('CXM0P' ,'CXM1P', 'CXP0FB','CXP1FB','CXM0FB','CXM1FB','CXBLPF','CXPPMM',
    'INPUT0','INPUT1','INPUT2','INPUT3','INPUT4','INPUT5');

  P0CBase = $7D8F;
  P1CBase = $8D7F;
  M0CBase = $FE33;
  M1CBase = $32FF;
  PFCBase = $D7D5;
  BLCBase = $EBEB;

  P0COr   = P0CBase Xor $FFFF;
  P1COr   = P1CBase Xor $FFFF;
  M0COr   = M0CBase Xor $FFFF;
  M1COr   = M1CBase Xor $FFFF;
  PFCOr   = PFCBase Xor $FFFF;
  BLCOr   = BLCBase Xor $FFFF;

  Player0Set  = 2;
  Player1Set  = 4;
  Missile0Set = 8;
  Missile1Set = 16;
  BallSet     = 32;

  _FMReg : Array[0..17] Of Byte =
   ($00,$01,$02,$08,$09,$0A,$10,$11,$12,$03,$04,$05,$0B,$0C,$0D,$13,$14,$15);

  MissileSize: Array[0..3] Of Byte = (1,2,4,8);
  PlayerSize:  Array[0..7] Of Word = (7,23,39,39,71,15,71,31);
  SP1 : Array[0..7] Of Word = ($1000,$0000,$1000,$0000,$1000,$0800,$1000,$0800);
  SP2 : Array[0..7] Of Word = ($1800,$1800,$0000,$1000,$1800,$1800,$0800,$1000);

  { TIA read registers }

  INPUT0  = $8;
  INPUT1  = $9;
  INPUT2  = $A;
  INPUT3  = $B;
  INPUT4  = $C;
  INPUT5  = $D;

  { Execution times }

  Cycles : Array[0..255] Of Byte =
   (7,6,0,8,3,3,5,5, 3,2,2,2,4,4,6,6,  { 00-0F }
    2,5,0,8,4,4,6,6, 2,4,2,7,4,4,7,7,  { 10-1F }
    6,6,0,8,3,3,5,5, 4,2,2,2,4,4,6,6,  { 20-2F }
    2,5,0,8,4,4,6,6, 2,4,2,7,4,4,7,7,  { 30-3F }
    6,6,0,8,3,3,5,5, 3,2,2,2,3,4,6,6,  { 40-4F }
    2,5,0,8,4,4,6,6, 2,4,2,7,4,4,7,7,  { 50-5F }
    6,6,0,0,3,3,5,0, 4,2,2,0,5,4,6,0,  { 60-6F }
    2,5,0,0,4,4,6,0, 2,4,2,0,4,4,7,0,  { 70-7F }
    2,6,2,6,3,3,3,3, 2,2,2,2,4,4,4,4,  { 80-8F }
    2,6,0,6,4,4,4,4, 2,5,2,5,5,5,5,5,  { 90-9F }
    2,6,2,6,3,3,3,3, 2,2,2,2,4,4,4,4,  { A0-AF }
    2,5,0,5,4,4,4,4, 2,4,2,4,4,4,4,4,  { B0-BF }
    2,6,2,8,3,3,5,5, 2,2,2,2,4,4,6,6,  { C0-CF }
    2,5,0,8,4,4,6,6, 2,4,2,7,4,4,7,7,  { D0-DF }
    2,6,2,0,3,3,5,0, 2,2,2,0,4,4,6,0,  { E0-EF }
    2,5,0,0,4,4,6,0, 2,4,2,0,0,4,7,0); { F0-FF }

  Bytes : Array[0..255] Of Word =
   (1,2,1,2,2,2,2,2, 1,2,1,2,3,3,3,3,  { 00-0F }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { 10-1F }
    3,2,1,2,2,2,2,2, 1,2,1,2,3,3,3,3,  { 20-2F }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { 30-3F }
    1,2,1,2,2,2,2,2, 1,2,1,2,3,3,3,3,  { 40-4F }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { 50-5F }
    1,2,1,2,2,2,2,1, 1,2,1,1,3,3,3,1,  { 60-6F }
    2,2,1,1,2,2,2,1, 1,3,1,1,3,3,3,1,  { 70-7F }
    2,2,2,2,2,2,2,2, 1,1,1,2,3,3,3,3,  { 80-8F }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { 90-9F }
    2,2,2,1,2,2,2,2, 1,2,1,2,3,3,3,3,  { A0-AF }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { B0-BF }
    2,2,2,2,2,2,2,2, 1,2,1,2,3,3,3,3,  { C0-CF }
    2,2,1,2,2,2,2,2, 1,3,1,3,3,3,3,3,  { D0-DF }
    2,2,2,1,2,2,2,1, 1,2,1,1,3,3,3,1,  { E0-EF }
    2,2,1,1,2,2,2,1, 1,3,1,1,1,3,3,1); { F0-FF }
(*
  CyclesDec: Array[0..255] Of Byte =
   (7,6,0,0,0,3,5,0, 3,2,2,0,0,4,6,0,  { 00-0F }
    2,5,0,0,0,4,6,0, 2,4,0,0,0,4,7,0,  { 10-1F }
    6,6,0,0,3,3,5,0, 4,2,2,0,4,4,6,0,  { 20-2F }
    2,5,0,0,0,4,6,0, 2,4,0,0,0,4,7,0,  { 30-3F }
    6,6,0,0,0,3,5,0, 3,2,2,0,3,4,6,0,  { 40-4F }
    2,5,0,0,0,4,6,0, 2,4,0,0,0,4,7,0,  { 50-5F }
    6,7,0,0,0,4,5,0, 4,3,2,0,5,5,6,0,  { 60-6F }
    2,6,0,0,0,5,6,0, 2,5,0,0,0,5,7,0,  { 70-7F }
    0,6,0,0,3,3,3,0, 2,0,2,0,4,4,4,0,  { 80-8F }
    2,6,0,0,4,4,4,0, 2,5,2,0,0,5,0,0,  { 90-9F }
    2,6,2,0,3,3,3,0, 2,2,2,0,4,4,4,0,  { A0-AF }
    2,5,0,0,4,4,4,0, 2,4,2,0,4,4,4,0,  { B0-BF }
    2,6,0,0,3,3,5,0, 2,2,2,0,4,4,6,0,  { C0-CF }
    2,5,0,0,0,4,6,0, 2,4,0,0,0,4,7,0,  { D0-DF }
    2,7,0,0,3,4,5,0, 2,3,2,0,4,5,6,0,  { E0-EF }
    2,6,0,0,0,5,6,0, 2,5,0,0,4,5,7,0); { F0-FF }

  SPBank : Array[0..255] Of Byte =
   (0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 00-0F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 10-1F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 20-2F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 30-3F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 40-4F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 50-5F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 60-6F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 70-7F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 80-8F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { 90-9F }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,  { A0-AF }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,  { B0-BF }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,  { C0-CF }
    0,0,0,0,0,0,0,0, 0,1,0,0,0,1,0,0,  { D0-DF }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  { E0-EF }
    0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0); { F0-FF }

   (0,1,0,1,0,0,0,0, 0,0,0,0,0,1,1,1,  { 00-0F }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1,  { 10-1F }
    0,1,0,1,0,0,0,0, 0,0,0,0,1,1,1,1,  { 20-2F }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1,  { 30-3F }
    0,1,0,1,0,0,0,0, 0,0,0,0,0,1,1,1,  { 40-4F }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1,  { 50-5F }
    0,1,0,1,0,0,0,0, 0,0,0,0,0,1,1,1,  { 60-6F }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1,  { 70-7F }
    0,1,0,1,0,0,0,0, 0,0,0,0,1,1,1,1,  { 80-8F }
    0,1,0,1,0,0,0,0, 0,1,0,0,1,1,1,1,  { 90-9F }
    0,1,0,1,0,0,0,0, 0,0,0,0,1,1,1,1,  { A0-AF }
    0,1,0,1,0,0,0,0, 0,1,0,0,1,1,1,1,  { B0-BF }
    0,1,0,1,0,0,0,0, 0,0,0,0,1,1,1,1,  { C0-CF }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1,  { D0-DF }
    0,1,0,1,0,0,0,0, 0,0,0,0,1,1,1,1,  { E0-EF }
    0,1,0,1,0,0,0,0, 0,1,0,1,0,1,1,1); { F0-FF }
*)
  Mnem : Array[0..255] Of String[3] =
   ('BRK','ORA','   ','slo','skb','ORA','ASL','slo',   { 00-07 }
    'PHP','ORA','ASL','anc','skw','ORA','ASL','slo',   { 08-0F }
    'BPL','ORA','   ','slo','skb','ORA','ASL','slo',   { 10-17 }
    'CLC','ORA','NOP','slo','skw','ORA','ASL','slo',   { 18-1F }
    'JSR','AND','   ','rla','BIT','AND','ROL','rla',   { 20-27 }
    'PLP','AND','ROL','anc','BIT','AND','ROL','rla',   { 28-2F }
    'BMI','AND','   ','rla','skb','AND','ROL','rla',   { 30-37 }
    'SEC','AND','NOP','rla','skw','AND','ROL','rla',   { 38-3F }
    'RTI','EOR','   ','sre','skb','EOR','LSR','sre',   { 40-47 }
    'PHA','EOR','LSR','asr','JMP','EOR','LSR','sre',   { 48-4F }
    'BVC','EOR','   ','sre','skb','EOR','LSR','sre',   { 50-57 }
    'CLI','EOR','NOP','sre','skw','EOR','LSR','sre',   { 58-5F }
    'RTS','ADC','   ','   ','skb','ADC','ROR','   ',   { 60-67 }
    'PLA','ADC','ROR','   ','JMP','ADC','ROR','   ',   { 68-6F }
    'BVS','ADC','   ','   ','skb','ADC','ROR','   ',   { 70-77 }
    'SEI','ADC','NOP','   ','skw','ADC','ROR','   ',   { 78-7F }
    'skb','STA','skb','sax','STY','STA','STX','sax',   { 80-87 }
    'DEY','NOP','TXA','ane','STY','STA','STX','sax',   { 88-8F }
    'BCC','STA','   ','sha','STY','STA','STX','sax',   { 90-97 }
    'TYA','STA','TXS','shs','shy','STA','shx','sha',   { 98-9F }
    'LDY','LDA','LDX','lax','LDY','LDA','LDX','lax',   { A0-A7 }
    'TAY','LDA','TAX','lxa','LDY','LDA','LDX','lax',   { A8-AF }
    'BCS','LDA','   ','lax','LDY','LDA','LDX','lax',   { B0-B7 }
    'CLV','LDA','TSX','las','LDY','LDA','LDX','lax',   { B8-BF }
    'CPY','CMP','skb','dcp','CPY','CMP','DEC','dcp',   { C0-C7 }
    'INY','CMP','DEX','sbx','CPY','CMP','DEC','dcp',   { C8-CF }
    'BNE','CMP','   ','dcp','skb','CMP','DEC','dcp',   { D0-D7 }
    'CLD','CMP','NOP','dcp','skw','CMP','DEC','dcp',   { D8-DF }
    'CPX','SBC','skb','   ','CPX','SBC','INC','   ',   { E0-E7 }
    'INX','SBC','NOP','   ','CPX','SBC','INC','   ',   { E8-EF }
    'BEQ','SBC','   ','   ','skb','SBC','INC','   ',   { F0-F7 }
    'SED','SBC','NOP','   ','skw','SBC','INC','   ');  { F8-FF }

  ATyp : Array[0..255] Of String[3] =
   ('IMP','I.X','   ','I.X','IMP','Z.P','Z.P','Z.P',   { 00-07 }
    'IMP','IMM','ACC','IMM','IMP','ABS','ABS','ABS',   { 08-0F }
    'REL','I.Y','   ','I.Y','IMP','Z.X','Z.X','Z.X',   { 10-17 }
    'IMP','A.Y','IMP','A.Y','IMP','A.X','A.X','A.X',   { 18-1F }
    'ABS','I.X','   ','I.X','Z.P','Z.P','Z.P','Z.P',   { 20-27 }
    'IMP','IMM','ACC','IMM','ABS','ABS','ABS','ABS',   { 28-2F }
    'REL','I.Y','   ','I.Y','IMP','Z.X','Z.X','Z.X',   { 30-37 }
    'IMP','A.Y','IMP','A.Y','IMP','A.X','A.X','A.X',   { 38-3F }
    'IMP','I.X','   ','I.X','IMP','Z.P','Z.P','Z.P',   { 40-47 }
    'IMP','IMM','ACC','IMM','ABS','ABS','ABS','ABS',   { 48-4F }
    'REL','I.Y','   ','I.Y','IMP','Z.X','Z.X','Z.X',   { 50-57 }
    'IMP','A.Y','IMP','A.Y','IMP','A.X','A.X','A.X',   { 58-5F }
    'IMP','I.X','   ','   ','IMP','Z.P','Z.P','   ',   { 60-67 }
    'IMP','IMM','ACC','   ','IND','ABS','ABS','   ',   { 68-6F }
    'REL','I.Y','   ','   ','IMP','Z.X','Z.X','   ',   { 70-77 }
    'IMP','A.Y','IMP','   ','IMP','A.X','A.X','   ',   { 78-7F }
    'IMP','I.X','IMP','I.X','Z.P','Z.P','Z.P','Z.P',   { 80-87 }
    'IMP','IMP','IMP','IMM','ABS','ABS','ABS','ABS',   { 88-8F }
    'REL','I.Y','   ','I.Y','Z.X','Z.X','Z.Y','Z.Y',   { 90-97 }
    'IMP','A.Y','IMP','IMP','A.X','A.X','A.Y','A.Y',   { 98-9F }
    'IMM','I.X','IMM','I.X','Z.P','Z.P','Z.P','Z.P',   { A0-A7 }
    'IMP','IMM','IMP','I+A','ABS','ABS','ABS','ABS',   { A8-AF }
    'REL','I.Y','   ','I.Y','Z.X','Z.X','Z.Y','Z.Y',   { B0-B7 }
    'IMP','A.Y','IMP','ASY','A.X','A.X','A.Y','A.Y',   { B8-BF }
    'IMM','I.X','IMP','I.X','Z.P','Z.P','Z.P','Z.P',   { C0-C7 }
    'IMP','IMM','IMP','IMM','ABS','ABS','ABS','ABS',   { C8-CF }
    'REL','I.Y','   ','I.Y','IMP','Z.X','Z.X','Z.X',   { D0-D7 }
    'IMP','A.Y','IMP','A.Y','IMP','A.X','A.X','A.X',   { D8-DF }
    'IMM','I.X','IMP','   ','Z.P','Z.P','Z.P','   ',   { E0-E7 }
    'IMP','IMM','IMP','   ','ABS','ABS','ABS','   ',   { E8-EF }
    'REL','I.Y','   ','   ','IMP','Z.X','Z.X','   ',   { F0-F7 }
    'IMP','A.Y','IMP','   ','IMP','A.X','A.Y','   ');  { F8-FF }
  _Base = _Cycles + SizeOf(Cycles);

Type
  AtariSegment = Array[0..AtariSegSize - 1] Of Byte;  { The 64K segment }
  AtariSegPtr  = ^AtariSegment;
  Strng4       = String[4];
  TIA_RegList  = Array[0..$3F] Of Byte;
  ConfigRec    = Record
    UseJoystick1 : Boolean;
    UseJoystick2 : Boolean;
    DoSound      : Boolean;
    MinJoyX      : Word;
    MaxJoyX      : Word;
    MinJoyY      : Word;
    MaxJoyY      : Word;
    MinJoyX2     : Word;
    MaxJoyX2     : Word;
    MinJoyY2     : Word;
    MaxJoyY2     : Word;
    FrameRate    : Word;
    SoundBufSize : Word;
    JoyCenterX   : Word;
    JoyCenterY   : Word;
    JoyCenterX2  : Word;
    JoyCenterY2  : Word;
    Reserved     : Array[0..7] Of Byte;
  End;
  TSoundType = (stPureTone,stPolyphonic,stNoise);

Const
  _FMSoundType : Array[0..15] Of TSoundType =
   (stNoise,   stPolyphonic,stPolyphonic,stPolyphonic,
    stPureTone,stPureTone,  stPureTone,  stPolyphonic,
    stNoise,   stPolyphonic,stPureTone,  stNoise,
    stPureTone,stPureTone,  stPureTone,  stPolyphonic);

Var
  Dummy                          : Word; { Used to dword-align BitTest }
  BitTest                        : Array[0..127] Of LongInt;
  DispJump                       : LongInt;
  Player0Size160                 : LongInt;
  Player1Size160                 : LongInt;
  Missile0Size160                : LongInt;
  Missile1Size160                : LongInt;
  BallSize160                    : LongInt;
  Player0Size                    : LongInt;
  Player1Size                    : LongInt;
  Player0Size128                 : LongInt;
  Player1Size128                 : LongInt;
  Missile0Size                   : LongInt;
  Missile1Size                   : LongInt;
  Missile0SizeNum                : LongInt;
  Missile1SizeNum                : LongInt;
  Missile0Adjust                 : LongInt;
  Missile1Adjust                 : LongInt;
  BallAdjust                     : LongInt;
  BallSize                       : LongInt;
  TIA_Count                      : LongInt;
  Old_TIA_Count                  : LongInt;
  AddCycle                       : LongInt;
  CyclesDone                     : LongInt;
  TimerInterval                  : LongInt;
  TimerValue                     : LongInt;
  TIA_Scan                       : LongInt;
  LastScan                       : LongInt;
  NewScan                        : LongInt;
  ReadTime                       : LongInt;
  Write_TIA                      : LongInt;
  ObjectSet                      : LongInt;
  Limit                          : LongInt;
  CLW,CRW                        : LongInt;
  Addr                           : LongInt;
  Save_BX                        : LongInt;
  ColorOrBW                      : LongInt;
  Difficulty1                    : LongInt;
  Difficulty2                    : LongInt;
  PaddleGround                   : LongInt;
  Time0                          : Double;{LongInt;}
  TimeErr                        : Double;{LongInt;}
  KeyColumn                      : LongInt;
  Indy500                        : LongInt;
  ObjectLoc                      : Array[0..16] Of LongInt;
  ObjectPix                      : Array[0..16] Of LongInt;
  Locations                      : Array[0..255] Of Word;
  Handle_TIA_Jump                : Array[0..31] Of Word;
  ColorLum                       : Array[0..3] Of Word;
  Handle_IO_Loc                  : Array[0..TIM4T2] Of Word;
  Handle_IO_Loc_After            : Array[0..CXCLR] Of Word;
  TIA_Delay                      : Array[0..CXCLR] Of Word;
  AtariSeg                       : AtariSegPtr;
  OldAtariSeg                    : AtariSegPtr;
  ROMBackup                      : Pointer;
  ROMSize                        : LongInt;
  Lo_Seg,Lo_Ofs                  : Word;
  TimerDone                      : Boolean;
  GRP0Latch                      : Byte;
  GRP1Latch                      : Byte;
  BallLatch                      : Byte;
  CTRLPFLatch                    : Byte;
  CTRLPFScan                     : Integer;
  CTRLPFCount                    : Integer;
{  KBFlag                         : Byte;}
  BitSwap                        : Array[0..255] Of Byte;
  TIA_Regs                       : TIA_RegList;
  Input_Byte                     : Array[0..$F] Of Byte;
  Latched                        : Boolean;
  ByteShift                      : Array[0..2047] Of Byte;
  MissileTable                   : Array[0..128 * 32 - 1] Of Byte;
  Handle_IO_Set                  : Boolean;
  Handle_IO_Set_After            : Boolean;
  TimerNotSet                    : Word;
  ColorOrBWChange                : Boolean;
  Difficulty1Change              : Boolean;
  Difficulty2Change              : Boolean;
  Handle_TIA_Jump_Set            : Boolean;
  Debugger                       : Boolean;
  UseKBControllers               : Boolean;
  VideoTouchPad                  : Boolean;
  UseIndy500                     : Boolean;
  Work_Real                      : Real;
  FMReg                          : Array[0..17] Of Byte;
  FMChanOn                       : Array[0..9] Of Byte;
  FMFeedBack                     : Array[0..9] Of Byte;
  FMBaseLevel                    : Array[0..21] Of Word;
  FMScale                        : Array[0..8] Of Word;
  FMRealScale                    : Array[0..8] Of Word;
  FMVoc                          : Array[0..8] Of Byte;
  FMFreq                         : Array[0..8] Of Word;
  FMSoundType                    : Array[0..15] Of TSoundType;
  BankSwitch                     : TBankSwitch;
  VAddAdjust                     : Word;
  VAdd                           : Word;
  CurrentBank                    : Byte;
  BankStart                      : Word;
  BankSize                       : Word;
  LineStart                      : Word;
  JoyCenterX                     : Word;
  JoyCenterY                     : Word;
  JoyMinX                        : Word;
  JoyMinY                        : Word;
  JoyMaxX                        : Word;
  JoyMaxY                        : Word;
  JoyCenterX2                    : Word;
  JoyCenterY2                    : Word;
  JoyMinX2                       : Word;
  JoyMinY2                       : Word;
  JoyMaxX2                       : Word;
  JoyMaxY2                       : Word;
  OldStart                       : Word;

  _CTRLPF                        : Byte;

  Table                          : Array[0..511] Of Single;
  OldByte                        : Byte;
  SPBankNum                      : Byte;
  DoSound                        : Boolean;
  DoHMOVE                        : Boolean;
  ParkerBS                       : Boolean;
  Activision                     : Boolean;
  MNetwork                       : Boolean;
  Starpath                       : Boolean;
  CBS                            : Boolean;
  TopVBLANK                      : Boolean;
  LockXMS                        : Boolean;
  StarpathLastAddr               : Word;
  UseMenu                        : Boolean;
  Disasm                         : Boolean;
  Top                            : Integer;
  Sel                            : Integer;
  Config                         : ConfigRec;
  Div3                           : Array[0..228] Of Byte;
  Global_Save_DS                 : Word;

  PhysAddr                       : DWord;
  TotalFree                      : Word;
  LargestFree                    : Word;
  Handle                         : XMS_XmBlk;
  MovePacket                     : XMS_MovePacket;
  SoundBuf                       : Array[0..1] Of Pointer;
  PhysAddr0                      : DWord;
  PhysAddr1                      : DWord;
{ ------------------------------------------------------------------------- }
  Executed                       : Array[$1000..$1FFF] Of Boolean;
  Branched                       : Array[$1000..$1FFF] Of Boolean;
  _Intr_Num                      : Byte;
  _Voice_Status                  : Word;
  _IO_Addx                       : Word;
  _DMA                           : Word;
  Org_Int_Addx                   : Pointer;

{$F+}
Function _CTV_Card_Here: Word; External;
Function _CTV_Detect: Word;    External;
Function _CTV_Output(Buf: Pointer; BufLen,SampleRate: Word): Word; External;
Function _CTV_Halt: Word;      External;
Function _CTV_Uninstall: Word; External;
{$F-}
{$L CTV-ATA2.OBJ}

(*
Procedure Build_Table;
Var
  Freq  : Word;
  Kind  : Word;
  S3    : Single;
  Index : Word;

Begin
  Index := 0;
  Freq  := 0;
  While Freq < 32 Do
  Begin
    Kind := 0;
    While Kind < 16 Do
    Begin
      S3 := 0;
      If Coeff[Kind] <> 0 Then
      Begin
        S3 := 30000 / (Freq + 1);
        S3 := S3 / (Coeff[Kind] * FMDiv[Kind] * SoundDiv);
        If S3 > 1023 Then S3 := 1023;
      End;
      Table[Index] := S3;
      Inc(Index);
      Inc(Kind);
    End; { While }
    Inc(Freq);
  End; { While }
End; { Build_Table }


Procedure WriteFM(Reg,Data: Byte);
Var B: Byte;
Begin
  Port[FMChip] := Reg;
  B := Port[FMChip];
  Port[FMChip + 1] := Data;
  B := Port[FMChip];
  B := Port[FMChip];
  B := Port[FMChip];
  B := Port[FMChip];
End; { WriteFM }


Procedure InitFM;
Var I: Byte;
Begin
  For I := 1 To $F5 Do WriteFM(I,0);
  Build_Table;
End; { InitFM }
*)

Procedure Digital(Chan: Byte);
Var I1,T: LongInt;
Begin
  If Chan = 0 Then
  Begin
    Asm
      DB    _32BIT_OPERAND
      SUB   AX,AX
      DB    _32BIT_OPERAND
      SUB   BX,BX
      MOV   BX,WORD PTR SoundBufSize
      MOV   AL,BYTE PTR FMVoc
      SHL   AX,5
      ADD   AX,WORD PTR FMFreq
      DB    _32BIT_OPERAND
      MUL   BX
      DB    _32BIT_OPERAND
      MOV   WORD PTR I1,AX
    End; { Asm }

    { Handle channel 1 }

    If LockXMS Then XMS.RawMove(PhysAddr0,PhysAddr + I1,SoundBufSize) Else
    Begin
      MovePacket.Length     := SoundBufSize;
      MovePacket.srcHandle  := Handle.Handle;
      MovePacket.srcOffset  := I1;
      MovePacket.destHandle := 0;
      MovePacket.destOffset := DWord(SoundBuf[0]);
      XMS.MoveXM(MovePacket);
    End;
    Asm
      MOV   AL,BYTE PTR FMRealScale
      SHL   AL,3
      MOV   BX,0FFFFh
      LES   DI,DWORD PTR SoundBuf[0 * 4]
      MOV   CX,WORD PTR SoundBufSize
      SHR   CX,2
  @L1:
      DB    _32BIT_OPERAND
      MOV   DX,WORD PTR [ES:DI]
      DB    _32BIT_OPERAND
      OR    DX,DX
      JZ    @L2
      TEST  DL,BL
      JZ    @L3
      MOV   DL,AL
  @L3:
      TEST  DH,BL
      JZ    @L4
      MOV   DH,AL
  @L4:
      DB    _32BIT_OPERAND
      ROR   DX,16
      TEST  DL,BL
      JZ    @L5
      MOV   DL,AL
  @L5:
      TEST  DH,BL
      JZ    @L6
      MOV   DH,AL
  @L6:
      DB    _32BIT_OPERAND
      ROR   DX,16
      DB    _32BIT_OPERAND
      MOV   WORD PTR [ES:DI],DX
  @L2:
      ADD   DI,4
      DEC   CX
      JNZ   @L1
    End; { Asm }
  End
  Else
  Begin
    Asm
      DB    _32BIT_OPERAND
      SUB   AX,AX
      DB    _32BIT_OPERAND
      SUB   BX,BX
      MOV   BX,WORD PTR SoundBufSize
      MOV   AL,BYTE PTR FMVoc[1]
      SHL   AX,5
      ADD   AX,WORD PTR FMFreq[2]
      DB    _32BIT_OPERAND
      MUL   BX
      DB    _32BIT_OPERAND
      MOV   WORD PTR I1,AX
    End; { Asm }

    { Handle channel 2 }

    If LockXMS Then XMS.RawMove(PhysAddr1,PhysAddr + I1,SoundBufSize) Else
    Begin
      MovePacket.Length     := SoundBufSize;
      MovePacket.srcHandle  := Handle.Handle;
      MovePacket.srcOffset  := I1;
      MovePacket.destHandle := 0;
      MovePacket.destOffset := DWord(Ptr(Seg(SoundBuf[0]^),Ofs(SoundBuf[0]^) + SoundBufSize));
      XMS.MoveXM(MovePacket);
    End;
    Asm
      MOV   AL,BYTE PTR FMRealScale[2]
      SHL   AL,3
      MOV   BX,0FFFFh
      LES   DI,DWORD PTR SoundBuf[0 * 4]
      ADD   DI,WORD PTR SoundBufSize
      MOV   CX,WORD PTR SoundBufSize
      SHR   CX,2
  @L1:
      DB    _32BIT_OPERAND
      MOV   DX,WORD PTR [ES:DI]
      DB    _32BIT_OPERAND
      OR    DX,DX
      JZ    @L2
      TEST  DL,BL
      JZ    @L3
      MOV   DL,AL
  @L3:
      TEST  DH,BL
      JZ    @L4
      MOV   DH,AL
  @L4:
      DB    _32BIT_OPERAND
      ROR   DX,16
      TEST  DL,BL
      JZ    @L5
      MOV   DL,AL
  @L5:
      TEST  DH,BL
      JZ    @L6
      MOV   DH,AL
  @L6:
      DB    _32BIT_OPERAND
      ROR   DX,16
      DB    _32BIT_OPERAND
      MOV   WORD PTR [ES:DI],DX
  @L2:
      ADD   DI,4
      DEC   CX
      JNZ   @L1
    End; { Asm }
  End;
  Asm
    LES   DI,DWORD PTR SoundBuf[1 * 4]
    MOV   CX,WORD PTR SoundBufSize
    SHR   CX,2
    MOV   BX,WORD PTR SoundBufSize
    PUSH  DS
    LDS   SI,DWORD PTR SoundBuf[0 * 4]
@L1:
    DB    _32BIT_OPERAND
    MOV   AX,WORD PTR [SI]
    DB    _32BIT_OPERAND
    ADD   AX,WORD PTR [SI + BX]
    DB    _32BIT_OPERAND
    MOV   WORD PTR [ES:DI],AX
    ADD   SI,4
    ADD   DI,4
    DEC   CX
    JNZ   @L1
    POP   DS
  End; { Asm }
End; { Digital }
(*

Procedure SetFM(Chan: Byte; On: Boolean);
Begin
  FMChanOn[Chan] := FMChanOn[Chan] And $DF;
  If On Then FMChanOn[Chan] := FMChanOn[Chan] Or $20;
  WriteFM(Chan + $B0,FMChanOn[Chan]);
End; { SetFM }


Procedure SetFMVoice(Chan,Voc: Word);
Var B,C,Index,Len,Oct,Freq: Word;
  F         : Single;
Begin
  If Not DoSound Then Exit;

{  Voc := 8;}

  Voc := Voc And $F;
  FMVoc[Chan] := Voc;
  If FMSoundType[Voc] <> stNoise
   Then FMFeedback[Chan] := 0 Else FMFeedback[Chan] := 1;
  WriteFM(Chan + $C0,FMFeedBack[Chan]);

  { Operator 1 }

  B := FMReg[Chan];

  If FMSoundType[Voc] = stPureTone
   Then C := $3F - $0D
   Else C := $3F - 7;
  If FMFeedBack[Chan] <> 0 Then C := 0;
  FMBaseLevel[B] := C;



  F   := Table[(FMFreq[Chan] Shl 4) + FMVoc[Chan]];
  Oct := 7;
  While (F < 512) And (Oct > 0) Do
  Begin
    Dec(Oct);
    F := F + F;
  End; { While }
  Freq := Round(F);
  WriteFM(Chan + $A0,Freq And $FF);
  FMChanOn[Chan] := $20 Or ((((Freq Shr 8) And 3) Or (Oct Shl 2)) And $1F);
  WriteFM(Chan + $B0,FMChanOn[Chan]);



{  C := ($3F - ((FMScale[Chan] * C + 8) Div 15));}
{  C := $3F - (FMScale[Chan] Shl 2);}
  If FMScale[Chan] = 0 Then C := $3F Else C := 15 - FMScale[Chan];
  WriteFM(B + $20,$21);    { AM/Vib/EG/KSR/Multiple     }
  WriteFM(B + $40,C);      { Total level                }
  WriteFM(B + $60,$DF);    { Attack/decay rates         }
  WriteFM(B + $80,$0F);    { Sustain level/release rate }
  WriteFM(B + $E0,2);      { Wave select                }

  { Operator 2 }

  B := FMReg[Chan + $09];
  C := $3F;
  If FMFeedBack[Chan] <> 0 Then C := 0;
  FMBaseLevel[B] := C;
{  C := ($3F - ((FMScale[Chan] * C + 8) Div 15));}
{  C := $3F - (FMScale[Chan] Shl 2);}
  If FMScale[Chan] = 0 Then C := $3F Else C := 15 - FMScale[Chan];
  WriteFM(B + $20,$21);                { AM/Vib/EG/KSR/Multiple     }
  WriteFM(B + $40,C);                  { Total level                }
  WriteFM(B + $60,$DF);                { Attack/decay rates         }
  WriteFM(B + $80,$0F);                { Sustain level/release rate }
  If FMSoundType[Voc] = stPureTone
   Then WriteFM(B + $E0,0)             { Wave select                }
   Else WriteFM(B + $E0,1);            { Wave select                }
End; { SetFMVoice }


Procedure SetFMFreq(Chan: Byte; Freq: Word);
Var
  Index,Len : Word;
  F         : Single;
  Oct       : Word;

Begin
  If Not DoSound Then Exit;
  Freq := Freq And $1F;
  FMFreq[Chan] := Freq;
{
  If FMVoc[Chan] = 8 Then
  Begin
    Index := FMRealScale[Chan] + (Freq Shl 4);
    If SRec[Index].SampleLen >= 16 Then
    Begin
      Len := SRec[Index].SampleLen;
      _CTV_Halt;
      XMS.RawMove(SegOffToPhys(SoundBuf),PhysAddr + SRec[Index].SampleOfs,Even(Len));
      _CTV_Output(SoundBuf,SRec[Index].SampleLen,SRec[Index].SampleRate);
    End
    Else _CTV_Halt;
  End;
}
  F   := Table[(Freq Shl 4) + FMVoc[Chan]];

{  WriteLn(Freq,'  ',F:11:5,' (',Chan,')  ',FMVoc[Chan]);}

  Oct := 7;
  While (F < 512) And (Oct > 0) Do
  Begin
    Dec(Oct);
    F := F + F;
  End; { While }
  Freq := Round(F);
  WriteFM(Chan + $A0,Freq And $FF);
  FMChanOn[Chan] := $20 Or ((((Freq Shr 8) And 3) Or (Oct Shl 2)) And $1F);
  WriteFM(Chan + $B0,FMChanOn[Chan]);
End; { SetFMFreq }


Procedure SetFMScale(Chan,Scale: Word);
Var B,C,Index,Len: Word;
Begin
  If Not DoSound Then Exit;
  Scale := Scale And $F;
  FMRealScale[Chan] := Scale;
{  Scale := Round(15 * Sqrt(Sqrt(Sqrt(Scale / 15))));}
  If Scale > 15 Then Scale := 15;
  FMScale[Chan] := Scale;

  { Operator 1 }

  B := FMReg[Chan];
  C := FMBaseLevel[B];
{  C := ($3F - ((Scale * C + 8) Div 15));}
{  C := $3F - (Scale Shl 2);}
  If FMScale[Chan] = 0 Then C := $3F Else C := 15 - FMScale[Chan];

  If FMFeedBack[Chan] <> 0 Then C := $3F;

  WriteFM(B + $40,C);                   { Total level }

  { Operator 2 }

  B := FMReg[Chan + $09];
  C := FMBaseLevel[B];
{  C := ($3F - ((Scale * C + 8) Div 15));}
{  C := $3F - (Scale Shl 2);}
  If FMScale[Chan] = 0 Then C := $3F Else C := 15 - FMScale[Chan];

  If FMFeedBack[Chan] <> 0 Then C := $3F;

  WriteFM(B + $40,C);                     { Total level }
End; { SetFMScale }
*)

Procedure SetVoice(Chan,Voc: Word);
Begin
(*
  If {(Chan = 2) And} (Voc In [4,5,6,10,12,13,14]) Then
  Begin
    SetFMVoice(Chan,Voc);
{    Update_TIA_Sound($15 + Chan,Voc);}
    AUDV[Chan] := 0;
    OutVol[Chan] := 0;
{    If Not (FMVoc[Chan] In [4,5,6,10,12,13,14]) Then
    Begin}
      AUDV[Chan] := 0;
      OutVol[Chan] := 0;
      If Update_TIA_Sound($15 + Chan,Voc) Then FillBuffer;
{    End;}
  End
  Else
  Begin
    If FMVoc[Chan] In [4,5,6,10,12,13,14] Then SetFMScale(Chan,0);
    AUDF[Chan] := FMFreq[Chan] And $1F;
    AUDV[Chan] := (FMRealScale[Chan] And $0F) Shl 3;

    If Update_TIA_Sound($15 + Chan,Voc){ Or
       Update_TIA_Sound($17 + Chan,FMFreq[Chan]) Or
       Update_TIA_Sound($19 + Chan,FMRealScale[Chan])} Then FillBuffer;
  End;
*)
  If DoSound Then
  Begin
    FMVoc[Chan] := Voc And $F;
    Digital(Chan);
  End;
End; { SetVoice }


Procedure SetFrequency(Chan,Freq: Word);
Begin
(*
  If {(Chan = 2) And} (FMVoc[Chan] In [4,5,6,10,12,13,14]) Then
  Begin
    SetFMFreq(Chan,Freq);
{    Update_TIA_Sound($17 + Chan,Freq);}
    AUDV[Chan] := 0;
    OutVol[Chan] := 0;
{    If Not (FMVoc[Chan] In [4,5,6,10,12,13,14]) Then
    Begin
      Update_TIA_Sound($17 + Chan,Freq);
      AUDV[Chan] := 0;
      FillBuffer;
    End;}
  End
  Else
  Begin
{    SetFMScale(Chan,0);}
{    AUDC[Chan] := FMVoc[Chan];}
{    AUDV[Chan] := (FMRealScale[Chan] And $0F) Shl 3;}
    If {Update_TIA_Sound($15 + Chan,FMVoc[Chan]) Or}
       Update_TIA_Sound($17 + Chan,Freq) {Or
       Update_TIA_Sound($19 + Chan,FMRealScale[Chan])} Then FillBuffer;
  End;
*)
  If DoSound Then
  Begin
    FMFreq[Chan] := Freq And $1F;
    Digital(Chan);
  End;
End; { SetFrequency }


Procedure SetVolume(Chan,Scale: Word);
Begin
(*
  If {(Chan = 2) And} (FMVoc[Chan] In [4,5,6,10,12,13,14]) Then
  Begin
    SetFMScale(Chan,Scale);
{    Update_TIA_Sound($19 + Chan,Scale);}
    AUDV[Chan] := 0;
    OutVol[Chan] := 0;
{    If Not (FMVoc[Chan] In [4,5,6,10,12,13,14]) Then
    Begin
      Update_TIA_Sound($19 + Chan,Scale);
      AUDV[Chan] := 0;
      FillBuffer;
    End;}
  End
  Else
  Begin
{    SetFMScale(Chan,0);}
{    AUDC[Chan] := FMVoc[Chan];
    AUDF[Chan] := FMFreq[Chan];}
{    AUDV[Chan] := (FMRealScale[Chan] And $0F) Shl 3;}
    If {Update_TIA_Sound($15 + Chan,FMVoc[Chan]) Or
       Update_TIA_Sound($17 + Chan,FMFreq[Chan]) Or}
       Update_TIA_Sound($19 + Chan,Scale) Then FillBuffer;
  End;
*)
  If DoSound Then
  Begin
    FMRealScale[Chan] := Scale And $F;
    Digital(Chan);
  End;
End; { SetVolume }


Procedure JoyStatus; Assembler;
{ ------------------------------------------------------------------------- }
{ Returns:                                                                  }
{    BL - JoyStatus                                                         }
{    CX - X1  SI - X2                                                       }
{    DX - Y1  DI - Y2                                                       }
{ ------------------------------------------------------------------------- }
Asm
  SUB    BX,BX
  SUB    CX,CX
  SUB    SI,SI
  SUB    DI,DI
  MOV    DX,0201h
  CLI
  SUB    AH,AH

  { Reset delays }

@L2:
  INC    BX
  CMP    BX,8000
  JE     @L2A
  IN     AL,DX
  TEST   AL,0Fh
  JNZ    @L2
@L2A:
  SUB    BX,BX

  OUT    DX,AL
  JMP    @L1
@L1:
  AAA

  { Get coordinates }

@L3:
  IN     AL,DX
  TEST   AL,1            { Player 1 X coordinate }
  JZ     @L4
  INC    BX
  CMP    BX,1000h
  JA     @L6
@L4:
  TEST   AL,2            { Player 1 Y coordinate }
  JZ     @L5
  INC    CX
  JC     @L6
  CMP    CX,1000h
  JA     @L6
@L5:
  IN     AL,DX
  TEST   AL,4            { Player 2 X coordinate }
  JZ     @L4A
  INC    SI
  CMP    SI,1000h
  JA     @L6
@L4A:
  TEST   AL,8            { Player 2 Y coordinate }
  JZ     @L5A
  INC    DI
  JC     @L6
  CMP    DI,1000h
  JA     @L6
@L5A:
  MOV    AH,0Fh
  TEST   BYTE PTR Config.UseJoystick2[_Base],0FFh
  JNZ    @Use2
  MOV    AH,3
@Use2:
  TEST   AL,AH
  JNZ    @L3
@L6:
  STI
  MOV    DX,CX
  MOV    CX,BX
  MOV    BX,AX
  SUB    BH,BH
  SHR    BX,1
  SHR    BX,1
  SHR    BX,1
  SHR    BX,1
  XOR    BX,0Fh
End; { JoyStatus }

(*
Function HexByte(B: Byte): String;
Const Digit: String = '0123456789ABCDEF';
Begin
  HexByte := Digit[(B Shr 4) + 1] +
             Digit[(B And $F) + 1];
End; { HexByte }


Function HexWord(W: Word): String;
Const Digit: String = '0123456789ABCDEF';
Begin
  HexWord := Digit[((W Shr 12) And $F) + 1] +
             Digit[((W Shr 8) And $F) + 1] +
             Digit[((W Shr 4) And $F) + 1] +
             Digit[(W And $F) + 1];
End; { HexWord }
*)

Function Int2Str(L: LongInt): String;
Var St: String;
Begin
  Str(L,St);
  Int2Str := St;
End; {Int2Str }


Procedure Go_Mode(Mode: Byte);
Var Regs: Registers;
Begin
  Regs.AH := 0;
  Regs.AL := Mode;
  Intr($10,Regs);
End; { Go_Mode }


Function Timer: Real;
Begin
  Timer := (Mem[0:$46F] * 1677722.0 + Mem[0:$46E] * 65536.0 +
            Mem[0:$46D] * 256       + Mem[0:$46C]) / 18.20648;
End; { Timer }


Procedure Unassemble(PC: Word);
Var
  Addr     : Word;
  B        : Byte;
  Instr    : String[3];
  Opcode   : Byte;

Begin

  { Tally instructions }

  While Not Executed[PC] Do
  Begin
    Executed[PC] := True;
    Opcode := AtariSeg^[PC];
    Instr  := Mnem[Opcode];
    If (Instr = 'JSR') Or
       (Instr = 'BPL') Or
       (Instr = 'BMI') Or
       (Instr = 'BVC') Or
       (Instr = 'BVS') Or
       (Instr = 'BEQ') Or
       (Instr = 'BNE') Or
       (Instr = 'BCC') Or
       (Instr = 'BCS') Then
    Begin
      If Instr = 'JSR'
       Then Addr := MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + PC + 1] And $1FFF
       Else
       Begin
         B := AtariSeg^[PC + 1];
         Asm
           MOV   BX,WORD PTR PC
           ADD   BX,2
           MOV   AL,BYTE PTR B
           CBW
           ADD   BX,AX
           MOV   WORD PTR Addr,BX
         End; { Asm }
       End;
      Branched[Addr] := True;
      Unassemble(Addr);
    End;
    If Instr <> 'RTS' Then
    Begin
      If Instr = 'JMP' Then
      Begin
        If ATyp[Opcode] = 'ABS'
         Then PC := MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + PC + 1] And $1FFF
         Else PC := MemW[Seg(AtariSeg^):Ofs(AtariSeg^) +
                     MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + PC + 1] And $1FFF] And $1FFF;
        Branched[PC] := True;
      End
      Else Inc(PC,Bytes[Opcode]);
    End;
  End; { While }
End; { Unassemble }

{$F+}
Procedure Handle_TIA; Far; External;
{$L HAND_TIA.OBJ}
{$F-}

Procedure SwitchBank; Assembler;
Asm
  PUSH  DX
  PUSH  BX
  PUSH  AX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  PUSH  SI

  { Save the current bank to simulate RAM if necessary }

  TEST  BYTE PTR MNetwork[_Base],0FFh
  JZ    @NoCopyBack{CheckStarpath}
  MOV   AL,BYTE PTR CurrentBank[_Base]
  SUB   AH,AH
  SHL   AX,10
  MOV   SI,WORD PTR BankStart[_Base]
  LES   DI,DWORD PTR ROMBackup[_Base]
  ADD   DI,AX
  CLD
  MOV   CX,WORD PTR BankSize[_Base]
  DB    _32BIT_OPERAND
  REP   MOVSW
  JMP   @NoCopyBack
{@CheckStarpath:
  TEST  BYTE PTR Starpath[_Base],0FFh
  JZ    @NoCopyBack
  CMP   BX,1FF8h
  JNE   @NoCopyBack}


@NoCopyBack:

  { Find out which bank we're switching to }

  MOV   CX,AX  { Save X and Y }
  MOV   WORD PTR BankStart[_Base],1000h
  MOV   AL,BYTE PTR BankSwitch[BX + _Base]
  CMP   AL,16
  JBE   @OneToFour

  { 17/21 means toggle between banks 1 and 2 }

  CMP   AL,0E0h
  JAE   @ParkerBros
  CMP   AL,0D0h
  JAE   @MNetwork

  CMP   AL,070h
  JAE   @Starpath
{
  CMP   AL,060h
  JAE   @Pitfall2
}
  CMP   AL,040h
  JAE   @SuperChip
  CMP   AL,20h
  JAE   @CBS
{
  CMP   AL,21
  JE    @Act1
  CMP   AL,17
  JE    @Act1
  SUB   AL,AL
  DEC   BYTE PTR BankSwitch[BX + _Base]
  JMP   @Act2
@Act1:
}
  XOR   BYTE PTR BankSwitch[BX + _Base],4
  SUB   AL,17
  XOR   AL,4
{
  JNZ   @Act2
  MOV   BYTE PTR BankSwitch[BX + _Base],19
@Act2:
}
  INC   AL
  JMP   @OneToFour

  { Handle Starpath Supercharger }

@Starpath:
(*  CMP   BYTE PTR [DI],0CDh   { Look for CMP abs/abs. x/abs. y }
  JE    @SPYes
  CMP   BYTE PTR [DI],0D9h
  JE    @SPYes
  CMP   BYTE PTR [DI],0DDh
  JE    @SPYes
  POP   SI
  POP   DS
  JMP   @NoDebug
@SPYes:*)
{  CMP   BX,11FEh
  JA    @Write}
{  CMP   WORD PTR StarpathLastAddr[_Base],0
  JNE   @Write}
{@NoWrite:}

{  CMP   WORD PTR [DI + 1],0EFF0h
  JB    @NotRAM
  CMP   WORD PTR [DI + 1],0F0FFh
  JA    @Write
  JMP   @NoWrite}

  MOV   AL,BYTE PTR [DI]
  PUSH  DS
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  MOV   SI,AX
  AND   SI,0FFh
{  MOV   AH,BYTE PTR SPBank[SI]}
  SHL   SI,2
  MOV   DX,WORD PTR ATyp[SI + 1]
  MOV   AL,BYTE PTR ATyp[SI + 3]
  POP   DS
{  TEST  AH,0FFh
  JZ    @NotRAM}


  CMP   DL,'I'
  JE    @SPContI
  CMP   DL,'A'
  JE    @SPContA
  JMP   @NotRAM
@SPContA:
  CMP   DH,'C'
  JE    @NotRAM
  JMP   @SPCont1
@SPContI:
  CMP   DH,'.'
  JNE   @NotRAM
@SPCont1:


  CMP   BX,01000h
  JB    @NotRAM
  CMP   BX,010FFh
  JBE   @NoWrite
  CMP   BX,011FEh
  JA    @Write




  CMP   DL,'I'
  JE    @Indirect
  CMP   DL,'A'
  JNE   @NotRAM
  CMP   DH,'B'            { ABS/A.X/A.Y/ACC }
  JE    @Write
  CMP   DH,'C'
  JE    @NotRAM
  CMP   AL,'Y'
  JE    @SubY
  SUB   CH,CH
  MOV   SI,BX
  SUB   SI,CX
  CMP   SI,010FFh
  JA    @Write
  JMP   @NoWrite
@Indirect:                { IMP/I.X/I.Y/IMM/I+A }
  CMP   DH,'.'
  JNE   @NotRAM
  CMP   AL,'X'
  JE    @Write
@SubY:
  MOV   CL,CH
  SUB   CH,CH
  MOV   SI,BX
  SUB   SI,CX
  CMP   SI,010FFh
  JA    @Write
  JMP   @NoWrite




@NoWrite:
  MOV   WORD PTR StarpathLastAddr[_Base],BX
@NotRAM:
  POP   SI
  POP   DS
  JMP   @NoDebug
@Write:
  CMP   WORD PTR StarPathLastAddr[_Base],0
  JE    @NotRAM
  CMP   BX,1FF8h
  JE    @SPCont
  TEST  BYTE PTR SPBankNum[_Base],2{[1FF8h],2}
  JZ    @NotRAM
  MOV   AL,BYTE PTR StarpathLastAddr[_Base]
  MOV   BYTE PTR [BX],AL
  MOV   WORD PTR StarPathLastAddr[_Base],0
  POP   SI
  POP   DS
  JMP   @NoDebug
@SPCont:

  { Copy back to ROM backup to simulate RAM }

  PUSH  DI
  PUSH  BX

  TEST  BYTE PTR Debugger[_Base],0FFh
  JZ    @NoDebugA
  MOV   BX,WORD PTR OldStart[_Base]
  CMP   BX,1000h
  JL    @NoDebugA
  MOV   AL,BYTE PTR OldByte[_Base]
  MOV   BYTE PTR [BX],AL
@NoDebugA:

  MOV   BL,BYTE PTR SPBankNum[_Base]{[1FF8h]}
  SHR   BL,1
  AND   BL,0Eh
  SUB   BH,BH
  MOV   AX,WORD PTR SP1[BX + _Base]
  MOV   CX,200h
  MOV   SI,1000h
  LES   DI,DWORD PTR ROMBackup[_Base]
  ADD   DI,AX
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW

  MOV   AX,WORD PTR SP2[BX + _Base]
  MOV   CX,200h
  MOV   SI,1800h
  LES   DI,DWORD PTR ROMBackup[_Base]
  ADD   DI,AX
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW

  POP   BX
  POP   DI

  { Copy in the new banks }

  MOV   BX,DS
  MOV   ES,BX
  MOV   BL,BYTE PTR StarpathLastAddr[_Base]
  MOV   DL,BL
  SHR   BL,1
  AND   BL,0Eh
  SUB   BH,BH

  MOV   AX,WORD PTR SP1[BX + _Base]
  MOV   CX,200h
  MOV   DI,1000h
  PUSH  DS
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW
  POP   DS

  MOV   AX,WORD PTR SP2[BX + _Base]
  MOV   CX,200h
  MOV   DI,1800h
  PUSH  DS
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW
  POP   DS

  MOV   BYTE PTR SPBankNum[_Base],DL{[1FF8h],DL}
  MOV   WORD PTR StarPathLastAddr[_Base],0
  JMP   @GetOut
(*
  { Handle Pitfall II }

@Pitfall2:
  SUB   AL,060h
  DEC   AL
  MOV   BYTE PTR CurrentBank[_Base],AL
  SUB   AH,AH
  SHL   AX,10
  MOV   BX,DS
  MOV   ES,BX
  MOV   DI,WORD PTR BankStart[_Base]
  ADD   DI,80h

  MOV   CX,WORD PTR BankSize[_Base]
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  ADD   SI,80h
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW

  MOV   CX,WORD PTR BankSize[_Base]
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  ADD   SI,880h
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW

  JMP   @GetOut
*)
  { Handle 16K Atari super chip }

@SuperChip:

  CMP   AL,50h
  JB    @SwitchSC

  { Copy RAM write area to the read area }

  MOV   AL,BYTE PTR [BX]
  MOV   BYTE PTR [BX + 80h],AL
  JMP   @GetOut

  { Switch the bank, but don't copy over the RAM area }

@SwitchSC:
  SUB   AL,040h
  DEC   AL
  MOV   BYTE PTR CurrentBank[_Base],AL
  SUB   AH,AH
  SHL   AX,10
  MOV   BX,DS
  MOV   ES,BX
  MOV   DI,WORD PTR BankStart[_Base]
  ADD   DI,100h
  MOV   CX,WORD PTR BankSize[_Base]
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  ADD   SI,100h
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW
  JMP   @GetOut

  { Handle Parker Brothers special bank switching }

@ParkerBros:
  SUB   AL,0E0h
  MOV   BL,AL
  AND   AL,7
  INC   AL
  AND   BX,18h
  SHL   BX,7
  ADD   BX,1000h
  MOV   WORD PTR BankStart[_Base],BX
  JMP   @OneToFour

  { Handle M-Network bank switching }

@MNetwork:
  SUB   AL,0D0h
  AND   AL,7
  CMP   AL,7
  JB    @LoadROM
  INC   AL
@LoadROM:
  SHL   AL,1
  INC   AL
  JMP   @OneToFour

  { Handle CBS RAM-Plus bank switching }

@CBS:
  CMP   AL,30h
  JB    @Switch

  { Copy RAM write area to the read area }

  MOV   AL,BYTE PTR [BX]
  MOV   BYTE PTR [BX + 100h],AL
  JMP   @GetOut

  { Switch the bank, but don't copy over the RAM area }

@Switch:
  SUB   AL,020h
  DEC   AL
  MOV   BYTE PTR CurrentBank[_Base],AL
  SUB   AH,AH
  SHL   AX,10
  MOV   BX,DS
  MOV   ES,BX
  MOV   DI,WORD PTR BankStart[_Base]
  ADD   DI,200h
  MOV   CX,WORD PTR BankSize[_Base]
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  ADD   SI,200h
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW
  JMP   @GetOut

  { Copy in the new bank }

@OneToFour:
  DEC   AL
  MOV   BYTE PTR CurrentBank[_Base],AL
  SUB   AH,AH
  SHL   AX,10
  MOV   BX,DS
  MOV   ES,BX
  MOV   DI,WORD PTR BankStart[_Base]
  MOV   CX,WORD PTR BankSize[_Base]
  LDS   SI,DWORD PTR ROMBackup[_Base]
  ADD   SI,AX
  CLD
  DB    _32BIT_OPERAND
  REP   MOVSW
@GetOut:
  POP   SI
  POP   DS
  TEST  BYTE PTR Debugger[_Base],0FFh
  JZ    @NoDebug
  MOV   BX,WORD PTR OldStart[_Base]
  CMP   BX,1000h
  JL    @NoDebug
  MOV   AL,BYTE PTR [BX]
  MOV   BYTE PTR OldByte[_Base],AL
  MOV   BYTE PTR [BX],0FFh
@NoDebug:
  POP   DI
  POP   CX
  POP   AX
  POP   BX
  POP   DX
End; { SwitchBank }


Procedure CheckKBController; Assembler;
Asm
  TEST  BYTE PTR UseKBControllers[_Base],0FFh
  JNZ   @CheckKB
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @CheckKB
  JMP   @GetOut
@CheckKB:
  MOV   BL,BYTE PTR [SWCHA1]
  MOV   AX,1001h
  MOV   CX,4
  MOV   BH,BYTE PTR [VBLANK]
@KeyLoop1:
  TEST  BL,AL
  JNZ   @NoTest

  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @Row4

  TEST  BYTE PTR KeyColumn[0 + _Base],AH
  JZ    @Off1
  TEST  BH,80h
  JNZ   @Off1
  AND   BYTE PTR Input_Byte[INPUT0 + _Base],7Fh
  JMP   @Row2
@Off1:
  OR    BYTE PTR Input_Byte[INPUT0 + _Base],80h
@Row2:

  TEST  BYTE PTR KeyColumn[1 + _Base],AH
  JZ    @Off2
  TEST  BH,80h
  JNZ   @Off2
  AND   BYTE PTR Input_Byte[INPUT1 + _Base],7Fh
  JMP   @Row3
@Off2:
  OR    BYTE PTR Input_Byte[INPUT1 + _Base],80h
@Row3:

  TEST  BYTE PTR KeyColumn[2 + _Base],AH
  JZ    @Off3
  AND   BYTE PTR Input_Byte[INPUT4 + _Base],7Fh
  JMP   @Row4
@Off3:
  OR    BYTE PTR Input_Byte[INPUT4 + _Base],80h
@Row4:

  TEST  BYTE PTR KeyColumn[0 + _Base],AL
  JZ    @Off4
  TEST  BH,80h
  JNZ   @Off4
  AND   BYTE PTR Input_Byte[INPUT2 + _Base],7Fh
  JMP   @Row5
@Off4:
  OR    BYTE PTR Input_Byte[INPUT2 + _Base],80h
@Row5:

  TEST  BYTE PTR KeyColumn[1 + _Base],AL
  JZ    @Off5
  TEST  BH,80h
  JNZ   @Off5
  AND   BYTE PTR Input_Byte[INPUT3 + _Base],7Fh
  JMP   @Row6
@Off5:
  OR    BYTE PTR Input_Byte[INPUT3 + _Base],80h
@Row6:

  TEST  BYTE PTR KeyColumn[2 + _Base],AL
  JZ    @Off6
  AND   BYTE PTR Input_Byte[INPUT5 + _Base],7Fh
  JMP   @NoTest
@Off6:
  OR    BYTE PTR Input_Byte[INPUT5 + _Base],80h

@NoTest:
  ADD    AL,AL
  ADD    AH,AH
  DEC    CX
  JNZ    @KeyLoop1
@GetOut:
End; { CheckKBController }


Procedure Handle_Input; Assembler;
{ ---------------------------------------------------------------------- }
{ Any variables this accesses must either be global or contained here!!! }
{ ---------------------------------------------------------------------- }
{ Joy ---- BL }
{ X ------ CX }
{ Y ------ DX }
{  Joy := JoyStatus(X,Y);}
Asm
  SUB   BX,BX
{  MOV   CX,50
  MOV   DX,50}

  { If the keyboard controllers are being used, don't check the joysticks }

  TEST  BYTE PTR UseKBControllers[_Base],0FFh
  JNZ   @CheckDone2

  { Check joysticks }

  TEST  BYTE PTR Config.UseJoystick1[_Base],0FFh
  JNZ   @CheckJoy
{  OR    BYTE PTR [SWCHA1],0FFh}
  JMP   @CheckDone2
@CheckJoy:
  CALL  JoyStatus
  MOV   AL,BL

  { Look at fire buttons }

  TEST  BYTE PTR Latched[_Base],1
  JNZ   @Latched
  XOR   AL,0FFh
  ROR   AL,1
  MOV   AH,AL
  AND   AH,80h
  MOV   BYTE PTR Input_Byte[INPUT4 + _Base],AH
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @NextTest
  ROR   AL,2
  AND   AL,80h
  MOV   BYTE PTR Input_Byte[INPUT5 + _Base],AL
  JMP   @NextTest
@Latched:
  TEST  AL,1
  JZ    @Button2
  AND   BYTE PTR Input_Byte[INPUT4 + _Base],7Fh
@Button2:
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @NextTest
  TEST  AL,4
  JZ    @NextTest
  AND   BYTE PTR Input_Byte[INPUT5 + _Base],7Fh
@NextTest:

  { Emulate Indy 500 controllers }

  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @CheckJoysticks
  TEST  BYTE PTR UseIndy500[_Base],0FFh
  JZ    @CheckJoysticks

  { Player 1 }

  CMP   CX,WORD PTR JoyMinX[_Base]
  JGE   @LeftFalseI500
  DEC   WORD PTR Indy500[_Base]
  JMP   @CheckDoneI500
@LeftFalseI500:
  CMP   CX,WORD PTR JoyMaxX[_Base]
  JLE   @CheckDoneI500
  INC   WORD PTR Indy500[_Base]
@CheckDoneI500:

  { Player 2 }

  CMP   SI,WORD PTR JoyMinX2[_Base]
  JGE   @LeftFalseI500A
  DEC   WORD PTR Indy500[_Base + 2]
  JMP   @CheckDoneI500A
@LeftFalseI500A:
  CMP   SI,WORD PTR JoyMaxX2[_Base]
  JLE   @CheckDoneI500A
  INC   WORD PTR Indy500[_Base + 2]
@CheckDoneI500A:

  PUSH  SI
  OR    BYTE PTR [SWCHA1],0FFh
  MOV   SI,WORD PTR Indy500[_Base]
  AND   SI,3
  MOV   AL,BYTE PTR Indy500Trans[SI + _Base]
  MOV   SI,WORD PTR Indy500[_Base + 2]
  AND   SI,3
  MOV   AH,BYTE PTR Indy500Trans[SI + _Base]
  ROR   AH,4
  AND   AL,AH
  AND   BYTE PTR [SWCHA1],AL
  POP   SI
  JMP   @CheckDone2

@CheckJoysticks:

  { Check player 1's joystick }

{  MOV   AL,BYTE PTR [SWACNT1]
  XOR   AL,0FFh
  AND   AL,0Fh
  OR    BYTE PTR [SWCHA1],AL}

  MOV   AH,BYTE PTR [SWACNT1]
{  TEST  AH,10h
  JNZ   @CheckDown}
  CMP   DX,WORD PTR JoyMinY[_Base]
  JGE   @UpFalse
  AND   BYTE PTR [SWCHA1],0EFh
  JMP   @CheckDown
@UpFalse:
  OR    BYTE PTR [SWCHA1],10h
@CheckDown:
{  TEST  AH,20h
  JNZ   @CheckLeft}
  CMP   DX,WORD PTR JoyMaxY[_Base]
  JLE   @DownFalse
  AND   BYTE PTR [SWCHA1],0DFh
  JMP   @CheckLeft
@DownFalse:
  OR    BYTE PTR [SWCHA1],20h
@CheckLeft:
{  TEST  AH,40h
  JNZ   @CheckRight}
  CMP   CX,WORD PTR JoyMinX[_Base]
  JGE   @LeftFalse
  AND   BYTE PTR [SWCHA1],0BFh
  JMP   @CheckRight
@LeftFalse:
  OR    BYTE PTR [SWCHA1],40h
@CheckRight:
{  TEST  AH,80h
  JNZ   @CheckDone}
  CMP   CX,WORD PTR JoyMaxX[_Base]
  JLE   @RightFalse
  AND   BYTE PTR [SWCHA1],07Fh
  JMP   @CheckDone
@RightFalse:
  OR    BYTE PTR [SWCHA1],80h
@CheckDone:

  { Check player 2's joystick }

  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @CheckDone2
  TEST  BYTE PTR Config.UseJoystick2[_Base],0FFh
  JZ    @CheckDone2

  MOV   AH,BYTE PTR [SWACNT1]
  TEST  AH,1
  JNZ   @CheckDown2
  CMP   DI,WORD PTR JoyMinY2[_Base]
  JGE   @UpFalse2
  AND   BYTE PTR [SWCHA1],0FEh
  JMP   @CheckDown2
@UpFalse2:
  OR    BYTE PTR [SWCHA1],1
@CheckDown2:
  TEST  AH,2
  JNZ   @CheckLeft2
  CMP   DI,WORD PTR JoyMaxY2[_Base]
  JLE   @DownFalse2
  AND   BYTE PTR [SWCHA1],0FDh
  JMP   @CheckLeft2
@DownFalse2:
  OR    BYTE PTR [SWCHA1],2
@CheckLeft2:
  TEST  AH,4
  JNZ   @CheckRight2
  CMP   SI,WORD PTR JoyMinX2[_Base]
  JGE   @LeftFalse2
  AND   BYTE PTR [SWCHA1],0FBh
  JMP   @CheckRight2
@LeftFalse2:
  OR    BYTE PTR [SWCHA1],4
@CheckRight2:
  TEST  AH,8
  JNZ   @CheckDone2
  CMP   SI,WORD PTR JoyMaxX2[_Base]
  JLE   @RightFalse2
  AND   BYTE PTR [SWCHA1],0F7h
  JMP   @CheckDone2
@RightFalse2:
  OR    BYTE PTR [SWCHA1],8
@CheckDone2:

  { Copy info }

  MOV   AL,BYTE PTR [SWCHA1]
  MOV   BYTE PTR [SWCHA2],AL

  MOV   AL,BYTE PTR [SWCHB1]
  AND   AL,7
  OR    AL,BYTE PTR ColorOrBW[_Base]
  OR    AL,BYTE PTR Difficulty1[_Base]
  OR    AL,BYTE PTR Difficulty2[_Base]
  OR    AL,3
  AND   AL,0CFh

  TEST  BYTE PTR CBS[_Base],0FFh
  JNZ   @BoosterGrip

  TEST  BL,2
  JZ    @Button3
  AND   AL,0FEh
@Button3:
  TEST  BL,8
  JZ    @ButtonDone
  AND   AL,0FDh
  JMP   @ButtonDone
@BoosterGrip:
  TEST  BL,2
  JZ    @Button3A
  AND   BYTE PTR Input_Byte[INPUT0 + _Base],07Fh
@Button3A:
  TEST  BL,8
  JZ    @ButtonDone
  AND   BYTE PTR Input_Byte[INPUT1 + _Base],07Fh
@ButtonDone:

  OR    AL,14h      { Bits 2 and 4 are always 1 }
  MOV   AH,AL       { Bit 5 mirrors bit 6       }
  SHR   AH,1
  AND   AH,20h
  OR    AL,AH


  MOV   BYTE PTR [SWCHB1],AL
  MOV   BYTE PTR [SWCHB2],AL

  { Check function keys And CBS Booster-Grip keys }

  TEST  BYTE PTR ES:Key[kLBRACE],0FFh
  JZ    @CheckRBrace
  AND   BYTE PTR Input_Byte[INPUT0 + _Base],07Fh
@CheckRBrace:
  TEST  BYTE PTR ES:Key[kLBRACE],0FFh
  JZ    @CheckF2
  AND   BYTE PTR Input_Byte[INPUT1 + _Base],07Fh
@CheckF2:
  TEST  BYTE PTR ES:Key[kF2],0FFh
  JZ    @CheckF4
  AND   BYTE PTR [SWCHB1],0FEh
@CheckF4:
  TEST  BYTE PTR ES:Key[kF4],0FFh
  JZ    @CheckF5
  AND   BYTE PTR [SWCHB1],0FDh
@CheckF5:
  TEST  BYTE PTR ES:Key[kF5],0FFh
  JZ    @PreCheckF6
  TEST  BYTE PTR ColorOrBWChange[_Base],0FFh
  JZ    @CheckF6
  XOR   BYTE PTR ColorOrBW[_Base],8
  MOV   BYTE PTR ColorOrBWChange[_Base],0
  JMP   @CheckF6
@PreCheckF6:
  MOV   BYTE PTR ColorOrBWChange[_Base],1
@CheckF6:
  TEST  BYTE PTR ES:Key[kF6],0FFh
  JZ    @PreCheckF7
  TEST  BYTE PTR Difficulty1Change[_Base],0FFh
  JZ    @CheckF7
  XOR   BYTE PTR Difficulty1[_Base],40h
  MOV   BYTE PTR Difficulty1Change[_Base],0
  JMP   @CheckF7
@PreCheckF7:
  MOV   BYTE PTR Difficulty1Change[_Base],1
@CheckF7:
  TEST  BYTE PTR ES:Key[kF7],0FFh
  JZ    @PreCheckUp
  TEST  BYTE PTR Difficulty2Change[_Base],0FFh
  JZ    @CheckUp
  XOR   BYTE PTR Difficulty2[_Base],80h
  MOV   BYTE PTR Difficulty2Change[_Base],0
  JMP   @CheckUp
@PreCheckUp:
  MOV   BYTE PTR Difficulty2Change[_Base],1
@CheckUp:

  { Check keyboard }

  TEST  BYTE PTR UseKBControllers[_Base],0FFh
  JNZ   @KeyCont
  TEST  BYTE PTR Config.UseJoystick1[_Base],0FFh
  JNZ   @CheckP2Fire{@KeyCont}

  { Player 1 fire button }

  TEST  BYTE PTR Latched[_Base],1
  JNZ   @Latched1

  MOV   AL,BYTE PTR ES:Key[kSPACE]
  OR    AL,BYTE PTR ES:Key[kEENTER]
  DB    0Fh,94h,0C0h    { SETZ AL }
  ROR   AL,1
  MOV   BYTE PTR Input_Byte[INPUT4 + _Base],AL
  JMP   @CheckP2Fire
@Latched1:
  MOV   AL,BYTE PTR ES:Key[kSPACE]
  OR    AL,BYTE PTR ES:Key[kEENTER]
  JZ    @CheckP2Fire
  MOV   BYTE PTR Input_Byte[INPUT4 + _Base],0
@CheckP2Fire:

  { Player 2 fire button }

  TEST  BYTE PTR Config.UseJoystick2[_Base],0FFh
  JNZ   @CheckI500Keys
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @CheckKeys
  TEST  BYTE PTR Latched[_Base],1
  JNZ   @Latched1A
  TEST  BYTE PTR ES:Key[kENTER],0FFh
  DB    0Fh,94h,0C0h    { SETZ AL }
  ROR   AL,1
  MOV   BYTE PTR Input_Byte[INPUT5 + _Base],AL
  JMP   @CheckI500Keys
@Latched1A:
  TEST  BYTE PTR ES:Key[kENTER],0FFh
  JZ    @CheckI500Keys
  MOV   BYTE PTR Input_Byte[INPUT5 + _Base],0

@CheckI500Keys:

  { Emulate Indy 500 controllers }

  TEST  BYTE PTR UseIndy500[_Base],0FFh
  JZ    @CheckKeys

  { Player 1 }

  TEST  BYTE PTR Config.UseJoystick1[_Base],0FFh
  JNZ   @CheckKeys
  MOV   AL,BYTE PTR ES:Key[kLF]
  OR    AL,BYTE PTR ES:Key[kP4]
  JZ    @LeftFalseI500K
  DEC   WORD PTR Indy500[_Base]
  JMP   @CheckDoneI500K
@LeftFalseI500K:
  MOV   AL,BYTE PTR ES:Key[kRT]
  OR    AL,BYTE PTR ES:Key[kP6]
  JZ    @CheckDoneI500K
  INC   WORD PTR Indy500[_Base]
@CheckDoneI500K:

  { Player 2 }

  TEST  BYTE PTR ES:Key[kJ],0FFh
  JZ    @LeftFalseI500KA
  DEC   WORD PTR Indy500[_Base + 2]
  JMP   @CheckDoneI500KA
@LeftFalseI500KA:
  TEST  BYTE PTR ES:Key[kL],0FFh
  JZ    @CheckDoneI500KA
  INC   WORD PTR Indy500[_Base + 2]
@CheckDoneI500KA:

  PUSH  SI
  OR    BYTE PTR [SWCHA1],0FFh
  MOV   SI,WORD PTR Indy500[_Base]
  AND   SI,3
  MOV   AL,BYTE PTR Indy500Trans[SI + _Base]
  MOV   SI,WORD PTR Indy500[_Base + 2]
  AND   SI,3
  MOV   AH,BYTE PTR Indy500Trans[SI + _Base]
  ROR   AH,4
  AND   AL,AH
  AND   BYTE PTR [SWCHA1],AL
  POP   SI
  JMP   @GetOut

@CheckKeys:

  { Player 1 }

  TEST  BYTE PTR Config.UseJoystick1[_Base],0FFh
  JNZ   @CheckDone1
  OR    BYTE PTR [SWCHA1],0F0h
  MOV   AL,BYTE PTR ES:Key[kUP]
  OR    AL,BYTE PTR ES:Key[kP8]
  JZ    @CheckLeft1
  AND   BYTE PTR [SWCHA1],0EFh
@CheckLeft1:
  MOV   AL,BYTE PTR ES:Key[kLF]
  OR    AL,BYTE PTR ES:Key[kP4]
  JZ    @CheckRight1
  AND   BYTE PTR [SWCHA1],0BFh
@CheckRight1:
  MOV   AL,BYTE PTR ES:Key[kRT]
  OR    AL,BYTE PTR ES:Key[kP6]
  JZ    @CheckDown1
  AND   BYTE PTR [SWCHA1],07Fh
@CheckDown1:
  MOV   AL,BYTE PTR ES:Key[kDN]
  OR    AL,BYTE PTR ES:Key[kP2]
  JZ    @CheckDone1
  AND   BYTE PTR [SWCHA1],0DFh
@CheckDone1:
  MOV   AL,BYTE PTR [SWCHA1]
  MOV   BYTE PTR [SWCHA2],AL

  { Player 2 }

  TEST  BYTE PTR Config.UseJoystick2[_Base],0FFh
  JNZ   @KeyCont
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @KeyCont
  OR    BYTE PTR [SWCHA1],0Fh
  TEST  BYTE PTR ES:Key[kI],0FFh
  JZ    @CheckLeft1A
  AND   BYTE PTR [SWCHA1],0FEh
@CheckLeft1A:
  TEST  BYTE PTR ES:Key[kJ],0FFh
  JZ    @CheckRight1A
  AND   BYTE PTR [SWCHA1],0FBh
@CheckRight1A:
  TEST  BYTE PTR ES:Key[kL],0FFh
  JZ    @CheckDown1A
  AND   BYTE PTR [SWCHA1],0F7h
@CheckDown1A:
  TEST  BYTE PTR ES:Key[kK],0FFh
  JZ    @CheckDone1A
  AND   BYTE PTR [SWCHA1],0FDh
@CheckDone1A:
  MOV   AL,BYTE PTR [SWCHA1]
  MOV   BYTE PTR [SWCHA2],AL

  { Check keyboard controllers }

@KeyCont:
  TEST  BYTE PTR UseKBControllers[_Base],0FFh
  JNZ   @CheckKBCont
  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @CheckKBCont
  JMP   @GetOut
@CheckKBCont:
  DB    _32BIT_OPERAND
  SUB   AX,AX
  MOV   BL,0FFh

  { Left controller }

  TEST  BYTE PTR VideoTouchPad[_Base],0FFh
  JNZ   @Check4
  TEST  BYTE PTR ES:Key[kN1],BL
  JZ    @CheckQ
  OR    AX,10h
@CheckQ:
  TEST  BYTE PTR ES:Key[kQ],BL
  JZ    @CheckA
  OR    AX,20h
@CheckA:
  TEST  BYTE PTR ES:Key[kA],BL
  JZ    @CheckZ
  OR    AX,40h
@CheckZ:
  TEST  BYTE PTR ES:Key[kZ],BL
  JZ    @Check2
  OR    AX,80h
@Check2:

  TEST  BYTE PTR ES:Key[kN2],BL
  JZ    @CheckW
  OR    AX,1000h
@CheckW:
  TEST  BYTE PTR ES:Key[kW],BL
  JZ    @CheckS
  OR    AX,2000h
@CheckS:
  TEST  BYTE PTR ES:Key[kS],BL
  JZ    @CheckX
  OR    AX,4000h
@CheckX:
  TEST  BYTE PTR ES:Key[kX],BL
  JZ    @Check3
  OR    AX,8000h
@Check3:

  TEST  BYTE PTR ES:Key[kN3],BL
  JZ    @CheckE
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    10h
@CheckE:
  TEST  BYTE PTR ES:Key[kE],BL
  JZ    @CheckD
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    20h
@CheckD:
  TEST  BYTE PTR ES:Key[kD],BL
  JZ    @CheckC
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    40h
@CheckC:
  TEST  BYTE PTR ES:Key[kC],BL
  JZ    @Check4
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    80h
@Check4:

  { Right controller }

  TEST  BYTE PTR ES:Key[kN4],BL
  JZ    @CheckR
  OR    AX,1
@CheckR:
  TEST  BYTE PTR ES:Key[kR],BL
  JZ    @CheckF
  OR    AX,2
@CheckF:
  TEST  BYTE PTR ES:Key[kF],BL
  JZ    @CheckV
  OR    AX,4
@CheckV:
  TEST  BYTE PTR ES:Key[kV],BL
  JZ    @Check5
  OR    AX,8
@Check5:

  TEST  BYTE PTR ES:Key[kN5],BL
  JZ    @CheckT
  OR    AX,100h
@CheckT:
  TEST  BYTE PTR ES:Key[kT],BL
  JZ    @CheckG
  OR    AX,200h
@CheckG:
  TEST  BYTE PTR ES:Key[kG],BL
  JZ    @CheckB
  OR    AX,400h
@CheckB:
  TEST  BYTE PTR ES:Key[kB],BL
  JZ    @Check6
  OR    AX,800h
@Check6:

  TEST  BYTE PTR ES:Key[kN6],BL
  JZ    @CheckY
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    1
@CheckY:
  TEST  BYTE PTR ES:Key[kY],BL
  JZ    @CheckH
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    2
@CheckH:
  TEST  BYTE PTR ES:Key[kH],BL
  JZ    @CheckN
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    4
@CheckN:
  TEST  BYTE PTR ES:Key[kN],BL
  JZ    @CheckKBDone
  DB    _32BIT_OPERAND
  OR    AX,0
  DW    8

@CheckKBDone:
  DB    _32BIT_OPERAND
  MOV   WORD PTR KeyColumn[_Base],AX

  CALL  CheckKBController

@GetOut:
End; { Handle_Input }


Procedure GetMouseInfo;
Var MX,MY,MB: Integer;
Begin
  GetMousePosition(Word(MX),Word(MY),Word(MB));
  PaddleGround := Round(3.1{2.05} * 6.4 * (640 - MX));
  If (MB And 1) <> 0 Then AtariSeg^[SWCHA1] := AtariSeg^[SWCHA1] And $7F;

{  For MY := 0 To 199 Do Mem[$A000:MY * 320 + (MX Div 2)] := $F;}

End; { GetMouseInfo }


Procedure SlowDown;
Var
  T{,I} : LongInt;
  R   : Double;

Begin
{  R := Time0 + (TimeErr / 1000) + (1000 / Config.FrameRate);}
  R := Time0{ - TimeErr} + (500 / Config.FrameRate);
{  I := Round(R);}
  Repeat
    T := Clock;
  Until (T >= R) Or (T < Time0);
  Time0   := R;{T;}
{  TimeErr := Round(1000 * (T - R)) Mod 1000;}
{  TimeErr := T - R;}
End; { SlowDown }


Procedure Handle_IO; Assembler;
{ ---------------------------------------------------------------------- }
{ On entry:                                                                 }
{ BX = Save_BX[_Base]                                                       }
{ ---------------------------------------------------------------------- }
Label LVSYNC,LVBLANK,LWSYNC,LRSYNC,LAUDV0,LAUDC0,LAUDF0,
      LAUDV1,LAUDC1,LAUDF1,
      LRESP0,LRESP1,LRESM0,LRESM1,LRESBL,LGRP0,LGRP1,LENABL,LCTRLPF,
      LHMCLR,{LCXCLR,}LSWCHA1,LSWACNT1,LSWCHB1,LSWBCNT1,
      LINTTIM1,LINTTIM3,LTIM1T1,LTIM2T1,LTIM3T1,LTIM4T1,LSWCHA2,LSWACNT2,LSWCHB2,
      LSWBCNT2,LINTTIM2,LTIM1T2,LTIM2T2,LTIM3T2,LTIM4T2,GetOut;
Asm
  TEST  BYTE PTR Handle_IO_Set[_Base],0FFh
  JNZ   @L2
  MOV   AX,OFFSET GetOut
  MOV   CX,TIM4T2
  SUB   BX,BX
@L1:
  MOV   WORD PTR Handle_IO_Loc[BX + _Base],AX
  ADD   BX,2
  LOOP  @L1

  MOV   WORD PTR Handle_IO_Loc[GRP0    * 2 + _Base],OFFSET LGRP0
  MOV   WORD PTR Handle_IO_Loc[GRP1    * 2 + _Base],OFFSET LGRP1
  MOV   WORD PTR Handle_IO_Loc[ENABL   * 2 + _Base],OFFSET LENABL

  MOV   WORD PTR Handle_IO_Loc[AUDV0   * 2 + _Base],OFFSET LAUDV0
  MOV   WORD PTR Handle_IO_Loc[AUDC0   * 2 + _Base],OFFSET LAUDC0
  MOV   WORD PTR Handle_IO_Loc[AUDF0   * 2 + _Base],OFFSET LAUDF0
  MOV   WORD PTR Handle_IO_Loc[AUDV1   * 2 + _Base],OFFSET LAUDV1
  MOV   WORD PTR Handle_IO_Loc[AUDC1   * 2 + _Base],OFFSET LAUDC1
  MOV   WORD PTR Handle_IO_Loc[AUDF1   * 2 + _Base],OFFSET LAUDF1

  MOV   WORD PTR Handle_IO_Loc[CTRLPF  * 2 + _Base],OFFSET LCTRLPF

  MOV   WORD PTR Handle_IO_Loc[VSYNC   * 2 + _Base],OFFSET LVSYNC
  MOV   WORD PTR Handle_IO_Loc[VBLANK  * 2 + _Base],OFFSET LVBLANK
  MOV   WORD PTR Handle_IO_Loc[WSYNC   * 2 + _Base],OFFSET LWSYNC
  MOV   WORD PTR Handle_IO_Loc[RSYNC   * 2 + _Base],OFFSET LRSYNC
  MOV   WORD PTR Handle_IO_Loc[RESP0   * 2 + _Base],OFFSET LRESP0
  MOV   WORD PTR Handle_IO_Loc[RESP1   * 2 + _Base],OFFSET LRESP1
  MOV   WORD PTR Handle_IO_Loc[RESM0   * 2 + _Base],OFFSET LRESM0
  MOV   WORD PTR Handle_IO_Loc[RESM1   * 2 + _Base],OFFSET LRESM1
  MOV   WORD PTR Handle_IO_Loc[RESBL   * 2 + _Base],OFFSET LRESBL
  MOV   WORD PTR Handle_IO_Loc[HMCLR   * 2 + _Base],OFFSET LHMCLR
{  MOV   WORD PTR Handle_IO_Loc[CXCLR   * 2 + _Base],OFFSET LCXCLR}
  MOV   WORD PTR Handle_IO_Loc[SWCHA1  * 2 + _Base],OFFSET LSWCHA1
  MOV   WORD PTR Handle_IO_Loc[SWACNT1 * 2 + _Base],OFFSET LSWACNT1
  MOV   WORD PTR Handle_IO_Loc[SWCHB1  * 2 + _Base],OFFSET LSWCHB1
  MOV   WORD PTR Handle_IO_Loc[SWBCNT1 * 2 + _Base],OFFSET LSWBCNT1
  MOV   WORD PTR Handle_IO_Loc[INTTIM1 * 2 + _Base],OFFSET LINTTIM1
  MOV   WORD PTR Handle_IO_Loc[INTTIM3 * 2 + _Base],OFFSET LINTTIM3
  MOV   WORD PTR Handle_IO_Loc[TIM1T1  * 2 + _Base],OFFSET LTIM1T1
  MOV   WORD PTR Handle_IO_Loc[TIM2T1  * 2 + _Base],OFFSET LTIM2T1
  MOV   WORD PTR Handle_IO_Loc[TIM3T1  * 2 + _Base],OFFSET LTIM3T1
  MOV   WORD PTR Handle_IO_Loc[TIM4T1  * 2 + _Base],OFFSET LTIM4T1
  MOV   WORD PTR Handle_IO_Loc[SWCHA2  * 2 + _Base],OFFSET LSWCHA2
  MOV   WORD PTR Handle_IO_Loc[SWACNT2 * 2 + _Base],OFFSET LSWACNT2
  MOV   WORD PTR Handle_IO_Loc[SWCHB2  * 2 + _Base],OFFSET LSWCHB2
  MOV   WORD PTR Handle_IO_Loc[SWBCNT2 * 2 + _Base],OFFSET LSWBCNT2
  MOV   WORD PTR Handle_IO_Loc[INTTIM2 * 2 + _Base],OFFSET LINTTIM2
  MOV   WORD PTR Handle_IO_Loc[TIM1T2  * 2 + _Base],OFFSET LTIM1T2
  MOV   WORD PTR Handle_IO_Loc[TIM2T2  * 2 + _Base],OFFSET LTIM2T2
  MOV   WORD PTR Handle_IO_Loc[TIM3T2  * 2 + _Base],OFFSET LTIM3T2
  MOV   WORD PTR Handle_IO_Loc[TIM4T2  * 2 + _Base],OFFSET LTIM4T2
  MOV   BYTE PTR Handle_IO_Set[_Base],1
  MOV   BX,WORD PTR Save_BX[_Base]
@L2:
  CMP   BX,TIM4T2
  JA    GetOut
  CMP   BX,2Ch
  JA    @NotTIA
  MOV   BYTE PTR Write_TIA[_Base],1
@NotTIA:
  ADD   BX,BX
  JMP   WORD PTR Handle_IO_Loc[BX + _Base]

LAUDC0:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDC0]
  AND   AX,0Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  0
  PUSH  AX
  CALL  SetVoice
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LAUDV0:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDV0]
  AND   AX,0Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  0
  PUSH  AX
  CALL  SetVolume
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LAUDF0:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDF0]
  AND   AX,1Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  0
  PUSH  AX
  CALL  SetFrequency
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LAUDC1:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDC1]
  AND   AX,0Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  1
  PUSH  AX
  CALL  SetVoice
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LAUDV1:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDV1]
  AND   AX,0Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  1
  PUSH  AX
  CALL  SetVolume
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LAUDF1:

  PUSH  AX
  PUSH  DX
  PUSH  CX
  PUSH  DI
  PUSH  DS
  MOV   AL,BYTE PTR [AUDF1]
  AND   AX,1Fh
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  PUSH  1
  PUSH  AX
  CALL  SetFrequency
  POP   DS
  POP   DI
  POP   CX
  POP   DX
  POP   AX
  JMP   GetOut

LCTRLPF:
  MOV   AL,BYTE PTR [CTRLPF]
  MOV   AH,BYTE PTR TIA_Regs[CTRLPF + _Base]
  MOV   BYTE PTR CTRLPFLatch[_Base],AL
  MOV   BYTE PTR [CTRLPF],AH
  MOV   AX,WORD PTR TIA_Scan[_Base]
  MOV   WORD PTR CTRLPFScan[_Base],AX
  MOV   AX,WORD PTR TIA_Count[_Base]
  MOV   WORD PTR CTRLPFCount[_Base],AX
  JMP   GetOut

LVSYNC:
(*
  MOV   AL,BYTE PTR [VSYNC]  { This works for Bowling and Codebreaker, but turns off CubiColor }
  TEST  AL,07Fh
  JNZ   @NotGoingOff
*)
{
  CMP   WORD PTR TIA_Scan[_Base],190
  JGE   @Cont}
{  MOV   AL,BYTE PTR [VSYNC]}  { This turns off Bowling and Codebreaker }
{  TEST  AL,2}{07Eh}
{  JNZ   @NotGoingOff}{JZ @NotGoingOff}
{  CMP   WORD PTR TIA_Scan[_Base],0
  JE    @Cont}
{  CMP   WORD PTR TIA_Scan[_Base],200
  JB    @NotGoingOff}





  TEST  BYTE PTR [VBLANK],2
  JNZ   @Cont
  CMP   WORD PTR TIA_Scan[_Base],222
  JAE   @Cont
  MOV   AL,BYTE PTR [VSYNC]
  TEST  AL,2
  JZ   @NotGoingOff
  CMP   WORD PTR TIA_Scan[_Base],0
  JL    @Cont1
  CMP   WORD PTR TIA_Scan[_Base],200
  JGE   @Cont1
  JMP   @NotGoingOff
@Cont1:
  TEST  BYTE PTR [VBLANK],2
  JZ    @NotGoingOff


{  TEST  BYTE PTR [VBLANK],2
  JZ    @Cont
  CMP   WORD PTR TIA_Scan[_Base],215
  JAE   @Cont}
  TEST  BYTE PTR TIA_Regs[VSYNC + _Base],2
  JNZ   @NotGoingOff
{  TEST  BYTE PTR [VBLANK],2
  JZ    @NotGoingOff}
{  CMP   WORD PTR TIA_Scan[_Base],200
  JB    @NotGoingOff}
{  CMP   WORD PTR TIA_Scan[_Base],215
  JB    @NotGoingOff}


{  TEST  BYTE PTR TIA_Regs[VSYNC + _Base],2
  JZ    @NotGoingOff}



{  TEST  BYTE PTR TIA_Regs[VSYNC + _Base],2
  JZ    @NotGoingOff}

@Cont:

{  CMP   WORD PTR TIA_Scan[_Base],190
  JB    @NotGoingOff}
{  TEST  BYTE PTR [VBLANK],2
  JZ    @NotGoingOff}

  MOV   BX,WORD PTR TIA_Scan[_Base]
  CMP   BX,100
  JL    @NoAdd
  CMP   BX,222
  JL    @Add2
  CMP   BX,230
  JG    @Add1
  JMP   @NoAdd
@Add2:
{  CMP   WORD PTR VAddAdjust[_Base],-1
  JE    @NoAdd}
  MOV   WORD PTR VAddAdjust[_Base],1
  JMP   @Add3
@Add1:
{  CMP   WORD PTR VAddAdjust[_Base],1
  JE    @NoAdd}
  MOV   WORD PTR VAddAdjust[_Base],-1
@Add3:
  MOV   AX,WORD PTR VAddAdjust[_Base]
  CMP   WORD PTR VAdd[_Base],60
  JGE   @NoAdd
  CMP   WORD PTR VAdd[_Base],-60
  JLE   @NoAdd
  ADD   WORD PTR VAdd[_Base],AX
@NoAdd:

  MOV   AL,BYTE PTR [VSYNC]
  MOV   BYTE PTR TIA_Regs[VSYNC + _Base],AL
  CALL  Handle_TIA
  MOV   BYTE PTR Write_TIA[_Base],0


  MOV   WORD PTR TIA_Scan[_Base],-37

  MOV   AX,WORD PTR VAdd[_Base]
  ADD   WORD PTR TIA_Scan[_Base],AX

  MOV   WORD PTR LineStart[_Base],0
{  MOV   WORD PTR TIA_Count[_Base],-68
  MOV   WORD PTR Old_TIA_Count[_Base],-68}
  MOV   WORD PTR Addr[_Base],0

  { Handle slowdown if necessary }

  CMP   WORD PTR Config.FrameRate[_Base],0
  JZ    @NoSlowDown
  PUSH  DS
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  CALL  SlowDown
  POP   DS
@NoSlowDown:
  JMP   GetOut
@NotGoingOff:
  MOV   BYTE PTR TIA_Regs[VSYNC + _Base],AL
{  TEST  AL,2
  JZ    @LVSYNC1
  CALL  Handle_TIA
  MOV   BYTE PTR Write_TIA[_Base],0
@LVSYNC1:}
  JMP   GetOut

LENABL:

  MOV   AL,BYTE PTR [ENABL]
  MOV   BL,BYTE PTR TIA_Regs[ENABL + _Base]
  MOV   BYTE PTR [ENABL],BL
  MOV   BYTE PTR BallLatch[_Base],AL
(*
  MOV   BL,BYTE PTR BallLatch[_Base]
  MOV   BYTE PTR [ENABL],BL
  MOV   BYTE PTR BallLatch[_Base],AL
  TEST  BYTE PTR [VDELBL],1
  JNZ   @DelayedBL
@NotDelayedBL:
  MOV   BYTE PTR [ENABL],AL
@DelayedBL:
  MOV   AL,BYTE PTR [ENABL]
*)
  JMP   GetOut

LGRP0:
  MOV   AL,BYTE PTR [GRP0]
  MOV   BL,BYTE PTR TIA_Regs[GRP0 + _Base]
  MOV   BYTE PTR [GRP0],BL
  MOV   BYTE PTR GRP0Latch[_Base],AL
  JMP   GetOut

LGRP1:
  MOV   AL,BYTE PTR [GRP1]
  MOV   BL,BYTE PTR TIA_Regs[GRP1 + _Base]
  MOV   BYTE PTR [GRP1],BL
  MOV   BYTE PTR GRP1Latch[_Base],AL
  JMP   GetOut

LVBLANK:
  MOV   AH,BYTE PTR [VBLANK]
  TEST  AH,80h
  JZ    @NoGround1
  MOV   WORD PTR Input_Byte[INPUT0 + _Base],0
  MOV   WORD PTR Input_Byte[INPUT2 + _Base],0
@NoGround1:
  TEST  BYTE PTR TIA_Regs[VBLANK + _Base],80h
  JZ    @NoGround
  DB    _32BIT_OPERAND
  SUB   BX,BX
  DB    _32BIT_OPERAND
  MOV   WORD PTR PaddleGround[_Base],BX
  MOV   WORD PTR Input_Byte[INPUT0 + _Base],0
  MOV   WORD PTR Input_Byte[INPUT2 + _Base],0
  PUSH  DS
  MOV   DS,WORD PTR Global_Save_DS[_Base]
  CALL  GetMouseInfo
  DB    _32BIT_OPERAND
  MOV   BX,WORD PTR PaddleGround
  POP   DS
  DB    _32BIT_OPERAND
  MOV   WORD PTR PaddleGround[_Base],BX
@NoGround:
  AND   AH,40h
  ROL   AH,2
  MOV   BYTE PTR Latched[_Base],AH
  TEST  AH,1
  JZ    @NotLatched
@NotLatched:


  TEST  BYTE PTR [VBLANK],2
  JNZ   @NotOff
  TEST  BYTE PTR TIA_Regs[VBLANK + _Base],2
  JZ    @NotOff
{  CMP   WORD PTR TIA_Scan[_Base],-11
  JL    @Resync
  CMP   WORD PTR TIA_Scan[_Base],11
  JG    @NotOff
  SUB   CX,CX
  JMP   @RS2}

  CMP   WORD PTR TIA_Scan[_Base],-11
  JGE   @NotOff
{  CMP   WORD PTR TIA_Scan[_Base],-45
  JL    @NotOff}


(*  TEST  BYTE PTR [VBLANK],2
  JNZ   @NotOff
  TEST  BYTE PTR TIA_Regs[VBLANK + _Base],2
  JZ    @NotOff
{  CMP   WORD PTR TIA_Scan[_Base],100
  JGE   @Resync}

  CMP   WORD PTR TIA_Scan[_Base],223
  JE    @Below
  CMP   WORD PTR TIA_Scan[_Base],200
  JGE   @Resync

@Below:
  CMP   WORD PTR TIA_Scan[_Base],-25
  JL    @NotOff
  CMP   WORD PTR TIA_Scan[_Base],25
  JG    @NotOff*)
@Resync:
{  MOV   CX,WORD PTR TIA_Scan[_Base]}
{  MOV   CX,WORD PTR VAdd[_Base]
  CMP   CX,0
  JL    @RS1
  ADD   CX,8
  AND   CX,0FFF0h
  JMP   @RS2
@RS1:
  NEG   CX
  ADD   CX,8
  AND   CX,0FFF0h
  NEG   CX
@RS2:}

  MOV   CX,WORD PTR TIA_Scan[_Base]
  ADD   CX,WORD PTR VAdd[_Base]


{
  SUB   CX,CX
  CMP   WORD PTR TIA_Scan[_Base],-11
  JGE   @RS1
  MOV   CX,WORD PTR TIA_Scan[_Base]
  NEG   CX
  SHR   CX,3
  MOV   BX,WORD PTR TIA_Scan[_Base]
  NEG   BX
  AND   BX,0FFF0h
  NEG   BX
  ADD   CX,BX
@RS1:}
  MOV   BYTE PTR TopVBLANK[_Base],0
(*  MOV   AX,WORD PTR TIA_Scan[_Base]
  MOV   BH,AL
  SUB   BL,BL
  SHL   AX,6
  ADD   AX,BX
  MOV   BX,WORD PTR Addr[_Base]
  SUB   BX,AX
  MOV   WORD PTR TIA_Scan[_Base],CX{0}
  MOV   WORD PTR Addr[_Base],BX*)
@NotOff:
  JMP   GetOut

LWSYNC:


    MOV   BX,160
    SUB   BX,WORD PTR TIA_Count[_Base]
    MOV   BL,BYTE PTR Div3[BX + _Base]
    SUB   BX,WORD PTR AddCycle[_Base]
    JLE   @GetOut
{
    JG    @EOLOk
    ADD   BX,228
@EOLOk:
}
{    CMP   WORD PTR TimerInterval[_Base],0
    JE    @GetOut}

    TEST  BYTE PTR TimerDone[_Base],0FFh
    JNZ   @LTimerDone
    MOV   SI,WORD PTR TimerInterval[_Base]
    ADD   WORD PTR TimerValue[_Base],BX
@DoAgain:
    MOV   BX,WORD PTR TimerValue[_Base]
    CMP   BX,SI
    JL    @GetOut
    MOV   WORD PTR TimerValue[_Base],0
    SUB   BX,SI
    SUB   WORD PTR [INTTIM1],1
    JC    @Done
    ADD   WORD PTR TimerValue[_Base],BX
    JMP   @DoAgain
@Done:
    MOV   BYTE PTR TimerDone[_Base],1
@LTimerDone:
    SUB   BYTE PTR [INTTIM1],BL
@GetOut:

  MOV   AX,160
  MOV   WORD PTR TIA_Count[_Base],AX
  MOV   BYTE PTR Write_TIA[_Base],2
  JMP   GetOut

LRSYNC:
{
  MOV   WORD PTR TIA_Count[_Base],160
  CALL  Handle_TIA
  MOV   AL,BYTE PTR [RSYNC]
  MOV   BYTE PTR TIA_Regs[RSYNC + _Base],AL
  SUB   WORD PTR Addr[_Base],320
  MOV   BYTE PTR Write_TIA[_Base],0
  MOV   WORD PTR TIA_Count[_Base],-68
  MOV   WORD PTR Old_TIA_Count[_Base],-68
}
  JMP   GetOut

LRESP0:

  OR    BYTE PTR ObjectSet[_Base],Player0Set
  JMP   GetOut

LRESP1:

  OR    BYTE PTR ObjectSet[_Base],Player1Set
  JMP   GetOut

LRESM0:

  TEST  BYTE PTR [RESMP0],2
  JZ    @Missile0Ok
  MOV   AL,BYTE PTR ObjectLoc[Player0Set * 2 + _Base]
  MOV   AH,BYTE PTR Player0Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],AL
  JMP   GetOut
@Missile0Ok:
  OR    BYTE PTR ObjectSet[_Base],Missile0Set
  JMP   GetOut

LRESM1:

  TEST  BYTE PTR [RESMP1],2
  JZ    @Missile1Ok
  MOV   AL,BYTE PTR ObjectLoc[Player1Set * 2 + _Base]
  MOV   AH,BYTE PTR Player1Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],AL
  JMP   GetOut
@Missile1Ok:
  OR    BYTE PTR ObjectSet[_Base],Missile1Set
  JMP   GetOut

LRESBL:

  OR    BYTE PTR ObjectSet[_Base],BallSet
  JMP   GetOut

LHMCLR:

  DB    _32BIT_OPERAND
  SUB   AX,AX
  DB    _32BIT_OPERAND
  MOV   WORD PTR [HMP0],AX
  MOV   BYTE PTR [HMBL],AL
  DB    _32BIT_OPERAND
  MOV   WORD PTR TIA_Regs[HMP0 + _Base],AX
  MOV   BYTE PTR TIA_Regs[HMBL + _Base],AL
  MOV   BYTE PTR Write_TIA[_Base],0
  JMP   GetOut
(*
LCXCLR:

  DB    _32BIT_OPERAND
  SUB   AX,AX
  DB    _32BIT_OPERAND
  MOV   WORD PTR Input_Byte[0 + _Base],AX
  DB    _32BIT_OPERAND
  MOV   WORD PTR Input_Byte[4 + _Base],AX
  MOV   AL,BYTE PTR [CXCLR]
  MOV   BYTE PTR TIA_Regs[CXCLR + _Base],AL
  MOV   BYTE PTR Write_TIA[_Base],0
  JMP   GetOut
*)
LSWCHA1:

{  MOV   BYTE PTR UseKBControllers[_Base],1}
  MOV   AL,BYTE PTR [SWACNT1]
  MOV   BL,BYTE PTR [SWCHA1]
  MOV   BH,BYTE PTR [SWCHA2]
  MOV   CX,BX
  MOV   AH,AL
  NOT   AL
  AND   BH,AL
  AND   BL,AH
  OR    BH,BL
  MOV   BYTE PTR [SWCHA2],BH
  AND   CL,AH
  AND   CH,AL
  OR    CL,CH
  MOV   BYTE PTR [SWCHA1],CL

  { If we're writing to this port, we must be attempting to use the  }
  { keyboard controllers.  Turn on the respective bits of INPUT0/1/4 }

  CALL  CheckKBController
  JMP   GetOut

LSWACNT1:

  MOV   AL,BYTE PTR [SWACNT1]
  MOV   BYTE PTR [SWACNT2],AL
  JMP   GetOut

LSWCHB1:

  MOV   AL,BYTE PTR [SWCHB2]
  MOV   BYTE PTR [SWCHB1],AL
  JMP   GetOut

LSWBCNT1:

  MOV   AL,BYTE PTR [SWBCNT2]
  MOV   BYTE PTR [SWBCNT1],AL
  JMP   GetOut

LINTTIM1:
  JMP   GetOut

LINTTIM3:

  MOV   AL,BYTE PTR [INTTIM3]
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR [INTTIM2],AL
  JMP   GetOut

LTIM1T1:

  MOV   AL,BYTE PTR [TIM1T1]
  MOV   BYTE PTR [TIM1T2],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],1
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM2T1:

  MOV   AL,BYTE PTR [TIM2T1]
  MOV   BYTE PTR [TIM2T2],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],8
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM3T1:

  MOV   AL,BYTE PTR [TIM3T1]
  MOV   BYTE PTR [TIM3T2],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],64
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM4T1:

  MOV   AL,BYTE PTR [TIM4T1]
  MOV   BYTE PTR [TIM4T2],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],1024
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LSWCHA2:

{  MOV   BYTE PTR UseKBControllers[_Base],1}
  MOV   AL,BYTE PTR [SWACNT1]
  MOV   BL,BYTE PTR [SWCHA2]
  MOV   BH,BYTE PTR [SWCHA1]
  MOV   CX,BX
  MOV   AH,AL
  NOT   AL
  AND   BH,AL
  AND   BL,AH
  OR    BH,BL
  MOV   BYTE PTR [SWCHA1],BH
  AND   CL,AH
  AND   CH,AL
  OR    CL,CH
  MOV   BYTE PTR [SWCHA2],CL

  { If we're writing to this port, we must be attempting to use the  }
  { keyboard controllers.  Turn on the respective bits of INPUT0/1/4 }

  CALL  CheckKBController
  JMP   GetOut

LSWACNT2:

  MOV   AL,BYTE PTR [SWACNT2]
  MOV   BYTE PTR [SWACNT1],AL
  JMP   GetOut

LSWCHB2:

  MOV   AL,BYTE PTR [SWCHB1]
  MOV   BYTE PTR [SWCHB2],AL
  JMP   GetOut

LSWBCNT2:

  MOV   AL,BYTE PTR [SWBCNT1]
  MOV   BYTE PTR [SWBCNT2],AL
  JMP   GetOut

LINTTIM2:

  MOV   AL,BYTE PTR [INTTIM2]
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR [INTTIM3],AL
  JMP   GetOut

LTIM1T2:

  MOV   AL,BYTE PTR [TIM1T2]
  MOV   BYTE PTR [TIM1T1],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],1
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM2T2:

  MOV   AL,BYTE PTR [TIM2T2]
  MOV   BYTE PTR [TIM2T1],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],8
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM3T2:

  MOV   AL,BYTE PTR [TIM3T2]
  MOV   BYTE PTR [TIM3T1],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],64
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0
  JMP   GetOut

LTIM4T2:

  MOV   AL,BYTE PTR [TIM4T2]
  MOV   BYTE PTR [TIM4T1],AL
  MOV   BYTE PTR [INTTIM1],AL
  MOV   BYTE PTR TimerDone[_Base],0
  MOV   WORD PTR TimerInterval[_Base],1024
  MOV   AX,WORD PTR AddCycle[_Base]
  NEG   AX
  MOV   WORD PTR TimerValue[_Base],AX
  MOV   WORD PTR TimerNotSet[_Base],0

GetOut:
End; { Handle_IO }


Procedure Handle_IO_After; Assembler;
{ ------------------------------------------------------------------------- }
{ On entry:                                                                 }
{ BX = Save_BX[_Base]                                                       }
{ ------------------------------------------------------------------------- }
Label LVBLANK,LGRP0,LGRP1,LENAM0,LENAM1,LENABL,LRESMP0,LRESMP1,
      LNUSIZ0,LNUSIZ1,LCOLUP0,LCOLUP1,LCOLUPF,LCOLUBK,LCTRLPF,LREFP0,LREFP1,
      LCXCLR,LHMOVE,GetOut;
Asm
  TEST  BYTE PTR Handle_IO_Set_After[_Base],0FFh
  JNZ   @L2

  MOV   AX,OFFSET GetOut
  MOV   CX,CXCLR
  SUB   BX,BX
@L1:
  MOV   WORD PTR Handle_IO_Loc_After[BX + _Base],AX
  ADD   BX,2
  LOOP  @L1

  MOV   WORD PTR Handle_IO_Loc_After[VBLANK  * 2 + _Base],OFFSET LVBLANK
  MOV   WORD PTR Handle_IO_Loc_After[GRP0    * 2 + _Base],OFFSET LGRP0
  MOV   WORD PTR Handle_IO_Loc_After[GRP1    * 2 + _Base],OFFSET LGRP1
  MOV   WORD PTR Handle_IO_Loc_After[ENAM0   * 2 + _Base],OFFSET LENAM0
  MOV   WORD PTR Handle_IO_Loc_After[ENAM1   * 2 + _Base],OFFSET LENAM1
  MOV   WORD PTR Handle_IO_Loc_After[ENABL   * 2 + _Base],OFFSET LENABL
  MOV   WORD PTR Handle_IO_Loc_After[RESMP0  * 2 + _Base],OFFSET LRESMP0
  MOV   WORD PTR Handle_IO_Loc_After[RESMP1  * 2 + _Base],OFFSET LRESMP1

  MOV   WORD PTR Handle_IO_Loc_After[NUSIZ0  * 2 + _Base],OFFSET LNUSIZ0
  MOV   WORD PTR Handle_IO_Loc_After[NUSIZ1  * 2 + _Base],OFFSET LNUSIZ1
  MOV   WORD PTR Handle_IO_Loc_After[COLUP0  * 2 + _Base],OFFSET LCOLUP0
  MOV   WORD PTR Handle_IO_Loc_After[COLUP1  * 2 + _Base],OFFSET LCOLUP1
  MOV   WORD PTR Handle_IO_Loc_After[COLUPF  * 2 + _Base],OFFSET LCOLUPF
  MOV   WORD PTR Handle_IO_Loc_After[COLUBK  * 2 + _Base],OFFSET LCOLUBK
  MOV   WORD PTR Handle_IO_Loc_After[CTRLPF  * 2 + _Base],OFFSET LCTRLPF
  MOV   WORD PTR Handle_IO_Loc_After[REFP0   * 2 + _Base],OFFSET LREFP0
  MOV   WORD PTR Handle_IO_Loc_After[REFP1   * 2 + _Base],OFFSET LREFP1
  MOV   WORD PTR Handle_IO_Loc_After[HMOVE   * 2 + _Base],OFFSET LHMOVE
  MOV   WORD PTR Handle_IO_Loc_After[CXCLR   * 2 + _Base],OFFSET LCXCLR
  MOV   BYTE PTR Handle_IO_Set_After[_Base],1
  MOV   BX,WORD PTR Save_BX[_Base]
@L2:
  ADD   BX,BX
  JMP   WORD PTR Handle_IO_Loc_After[BX + _Base]

LCXCLR:
  DB    _32BIT_OPERAND
  SUB   AX,AX
  DB    _32BIT_OPERAND
  MOV   WORD PTR Input_Byte[0 + _Base],AX
  DB    _32BIT_OPERAND
  MOV   WORD PTR Input_Byte[4 + _Base],AX
  MOV   AL,BYTE PTR [CXCLR]
  MOV   BYTE PTR TIA_Regs[CXCLR + _Base],AL
  JMP   GetOut

LVBLANK:
{  AND   BYTE PTR DispJump[_Base],0FDh
  TEST  BYTE PTR [ENABL],2
  JZ    @LVBLANKA
  OR    BYTE PTR DispJump[_Base],2
@LVBLANKA:}
  TEST  BYTE PTR [VBLANK],80h
  JZ    @NoGround
  MOV   WORD PTR Input_Byte[INPUT0 + _Base],0
  MOV   WORD PTR Input_Byte[INPUT2 + _Base],0
@NoGround:

  MOV   BX,WORD PTR TIA_Scan[_Base]
  TEST  BYTE PTR [VBLANK],2
  JZ    @NoClear
{  CMP   BX,WORD PTR LastScan[_Base]
  JGE   @ClearExit
  CMP   BX,200
  JGE   @ClearExit
  MOV   DX,WORD PTR LastScan[_Base]
  CMP   DX,200
  JL    @ContBlank
  MOV   DX,200

@ContBlank:
  SUB   DX,BX
  MOV   AX,0A000h
  MOV   ES,AX
  MOV   DI,BX
  MOV   AX,DI
  SHL   DI,6
  SHL   AX,8
  ADD   DI,AX
  DB    _32BIT_OPERAND
  SUB   AX,AX
  CLD
@ClearLoop:}
{  MOV   CX,80
  DB    _32BIT_OPERAND
  REP   STOSW
  DEC   DX
  JNZ   @ClearLoop}
@ClearExit:
  MOV   WORD PTR LastScan[_Base],BX
@NoClear:



  JMP   GetOut

LGRP0:
  TEST  BYTE PTR [VDELP0],1
  JNZ   @DelayedP0
@NotDelayedP0:
  MOV   AL,BYTE PTR GRP0Latch[_Base]
  MOV   BYTE PTR [GRP0],AL
  MOV   BYTE PTR TIA_Regs[GRP0 + _Base],AL
@DelayedP0:
  MOV   BL,BYTE PTR GRP1Latch[_Base]
  MOV   BYTE PTR [GRP1],BL
  MOV   BYTE PTR TIA_Regs[GRP1 + _Base],BL
  MOV   BL,BYTE PTR TIA_Regs[GRP1 + _Base]
  AND   BYTE PTR DispJump[_Base],0F7h
  TEST  BL,0FFh
  JZ    @LGRP0B
  OR    BYTE PTR DispJump[_Base],8
@LGRP0B:
  AND   BYTE PTR DispJump[_Base],0DFh
  TEST  BYTE PTR TIA_Regs[GRP0 + _Base],0FFh  { New }
  JZ    @LGRP0A
  OR    BYTE PTR DispJump[_Base],20h
@LGRP0A:
  JMP   GetOut

LGRP1:
  TEST  BYTE PTR [VDELP1],1
  JNZ   @DelayedP1
@NotDelayedP1:
  MOV   AL,BYTE PTR GRP1Latch[_Base]
  MOV   BYTE PTR [GRP1],AL
  MOV   BYTE PTR TIA_Regs[GRP1 + _Base],AL
@DelayedP1:
  MOV   BL,BYTE PTR GRP0Latch[_Base]
  MOV   BYTE PTR [GRP0],BL
  MOV   BYTE PTR TIA_Regs[GRP0 + _Base],BL
  MOV   BL,BYTE PTR TIA_Regs[GRP0 + _Base]
  AND   BYTE PTR DispJump[_Base],0DFh
  TEST  BL,0FFh
  JZ    @LGRP1B
  OR    BYTE PTR DispJump[_Base],20h
@LGRP1B:
  MOV   BL,BYTE PTR BallLatch[_Base]
  MOV   BYTE PTR [ENABL],BL
  MOV   BYTE PTR TIA_Regs[ENABL + _Base],BL

  AND   BYTE PTR DispJump[_Base],0FDh
  TEST  BL,2h
  JZ    @LGRP1C
  OR    BYTE PTR DispJump[_Base],2h
@LGRP1C:

  AND   BYTE PTR DispJump[_Base],0F7h
  TEST  BYTE PTR TIA_Regs[GRP1 + _Base],0FFh
  JZ    @LGRP1A
  OR    BYTE PTR DispJump[_Base],8
@LGRP1A:
  JMP   GetOut

LENAM0:

  AND   BYTE PTR DispJump[_Base],0EFh
  TEST  BYTE PTR [ENAM0],2
  JZ    @LENAM0A
  TEST  BYTE PTR [RESMP0],2
  JNZ   @LENAM0A
  OR    BYTE PTR DispJump[_Base],10h
@LENAM0A:
  JMP   GetOut

LENAM1:

  AND   BYTE PTR DispJump[_Base],0FBh
  TEST  BYTE PTR [ENAM1],2
  JZ    @LENAM1A
  TEST  BYTE PTR [RESMP1],2
  JNZ   @LENAM1A
  OR    BYTE PTR DispJump[_Base],4
@LENAM1A:
  JMP   GetOut

LENABL:

  TEST  BYTE PTR [VDELBL],1
  JNZ   @DelayedBL
  MOV   AL,BYTE PTR BallLatch[_Base]
  MOV   BYTE PTR [ENABL],AL
  MOV   BYTE PTR TIA_Regs[ENABL + _Base],AL
@DelayedBL:
  AND   BYTE PTR DispJump[_Base],0FDh
  TEST  BYTE PTR [ENABL],2
  JZ    @LENABLA
  OR    BYTE PTR DispJump[_Base],2
@LENABLA:
  JMP   GetOut

LRESMP0:

  TEST  BYTE PTR [RESMP0],2
  JZ    @Missile0Ok
  MOV   AL,BYTE PTR ObjectLoc[Player0Set * 2 + _Base]
  MOV   AH,BYTE PTR Player0Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],AL
@Missile0Ok:

  AND   BYTE PTR DispJump[_Base],0EFh
  TEST  BYTE PTR [ENAM0],2
  JZ    @LRESMP0A
  TEST  BYTE PTR [RESMP0],2
  JNZ   @LRESMP0A
  OR    BYTE PTR DispJump[_Base],10h
@LRESMP0A:
  JMP   GetOut

LRESMP1:

  TEST  BYTE PTR [RESMP1],2
  JZ    @Missile1Ok
  MOV   AL,BYTE PTR ObjectLoc[Player1Set * 2 + _Base]
  MOV   AH,BYTE PTR Player1Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],AL
@Missile1Ok:

  AND   BYTE PTR DispJump[_Base],0FBh
  TEST  BYTE PTR [ENAM1],2
  JZ    @LRESMP1A
  TEST  BYTE PTR [RESMP1],2
  JNZ   @LRESMP1A
  OR    BYTE PTR DispJump[_Base],4
@LRESMP1A:
  JMP   GetOut

LNUSIZ0:

  MOV   BL,BYTE PTR TIA_Regs[NUSIZ0 + _Base]

  MOV   AL,BL
  MOV   AH,AL
  SHR   AL,1
  AND   AX,0718h
  OR    AL,AH
  AND   AH,0
  SHL   AX,7
  MOV   WORD PTR Missile0SizeNum[_Base],AX

  MOV   SI,BX
  SHR   SI,4
  AND   SI,3
  MOV   CL,BYTE PTR MissileSize[SI + _Base]
  SUB   CH,CH
  MOV   WORD PTR Missile0Size[_Base],CX
  MOV   DX,CX

  DEC   CX
  SHR   CX,1
  MOV   WORD PTR Missile0Adjust[_Base],CX

  SUB   DX,160
  MOV   WORD PTR Missile0Size160[_Base],DX
  AND   BX,7
  ADD   BX,BX
  MOV   AX,BX
  SHL   AX,7
  MOV   CL,BYTE PTR TIA_Regs[REFP0 + _Base]
  SHL   CL,4
  AND   CL,80h
  OR    AL,CL
  MOV   WORD PTR Player0Size128[_Base],AX
  MOV   AX,WORD PTR PlayerSize[BX + _Base]
  MOV   WORD PTR Player0Size[_Base],AX
  SUB   AX,160
  MOV   WORD PTR Player0Size160[_Base],AX
  JMP   GetOut

LNUSIZ1:

  MOV   BL,BYTE PTR TIA_Regs[NUSIZ1 + _Base]

  MOV   AL,BL
  MOV   AH,AL
  SHR   AL,1
  AND   AX,0718h
  OR    AL,AH
  AND   AH,0
  SHL   AX,7
  MOV   WORD PTR Missile1SizeNum[_Base],AX

  MOV   SI,BX
  SHR   SI,4
  AND   SI,3
  MOV   CL,BYTE PTR MissileSize[SI + _Base]
  SUB   CH,CH
  MOV   WORD PTR Missile1Size[_Base],CX
  MOV   DX,CX

  DEC   CX
  SHR   CX,1
  MOV   WORD PTR Missile1Adjust[_Base],CX

  SUB   DX,160
  MOV   WORD PTR Missile1Size160[_Base],DX
  AND   BX,7
  ADD   BX,BX
  MOV   AX,BX
  SHL   AX,7
  MOV   CL,BYTE PTR TIA_Regs[REFP1 + _Base]
  SHL   CL,4
  AND   CL,80h
  OR    AL,CL
  MOV   WORD PTR Player1Size128[_Base],AX
  MOV   AX,WORD PTR PlayerSize[BX + _Base]
  MOV   WORD PTR Player1Size[_Base],AX
  SUB   AX,160
  MOV   WORD PTR Player1Size160[_Base],AX
  JMP   GetOut

LCOLUP0:

  MOV   AL,BYTE PTR TIA_Regs[COLUP0 + _Base]
  MOV   AH,AL
  MOV   WORD PTR ColorLum[0 + _Base],AX
  MOV   BX,WORD PTR ColorLum[4 + _Base]
  MOV   DX,WORD PTR ColorLum[2 + _Base]
  TEST  BYTE PTR TIA_Regs[CTRLPF + _Base],2
  JZ    @LP01
  MOV   WORD PTR CLW[_Base],AX
  MOV   WORD PTR CLW[_Base + 2],AX
  MOV   WORD PTR CRW[_Base],DX
  MOV   WORD PTR CRW[_Base + 2],DX
  JMP   @LP02
@LP01:
  MOV   WORD PTR CLW[_Base],BX
  MOV   WORD PTR CLW[_Base + 2],BX
  MOV   WORD PTR CRW[_Base],BX
  MOV   WORD PTR CRW[_Base + 2],BX
@LP02:
  JMP   GetOut

LCOLUP1:

  MOV   AL,BYTE PTR TIA_Regs[COLUP1 + _Base]
  MOV   AH,AL
  MOV   WORD PTR ColorLum[2 + _Base],AX
  MOV   BX,WORD PTR ColorLum[4 + _Base]
  MOV   CX,WORD PTR ColorLum[0 + _Base]
  TEST  BYTE PTR TIA_Regs[CTRLPF + _Base],2
  JZ    @LP11
  MOV   WORD PTR CLW[_Base],CX
  MOV   WORD PTR CLW[_Base + 2],CX
  MOV   WORD PTR CRW[_Base],AX
  MOV   WORD PTR CRW[_Base + 2],AX
  JMP   @LP12
@LP11:
  MOV   WORD PTR CLW[_Base],BX
  MOV   WORD PTR CLW[_Base + 2],BX
  MOV   WORD PTR CRW[_Base],BX
  MOV   WORD PTR CRW[_Base + 2],BX
@LP12:
  JMP   GetOut

LCOLUPF:

  MOV   AL,BYTE PTR TIA_Regs[COLUPF + _Base]
  MOV   AH,AL
  MOV   WORD PTR ColorLum[4 + _Base],AX
  MOV   CX,WORD PTR ColorLum[0 + _Base]
  MOV   DX,WORD PTR ColorLum[2 + _Base]
  TEST  BYTE PTR TIA_Regs[CTRLPF + _Base],2
  JZ    @LPF1
  MOV   WORD PTR CLW[_Base],CX
  MOV   WORD PTR CLW[_Base + 2],CX
  MOV   WORD PTR CRW[_Base],DX
  MOV   WORD PTR CRW[_Base + 2],DX
  JMP   @LPF2
@LPF1:
  MOV   WORD PTR CLW[_Base],AX
  MOV   WORD PTR CLW[_Base + 2],AX
  MOV   WORD PTR CRW[_Base],AX
  MOV   WORD PTR CRW[_Base + 2],AX
@LPF2:
  JMP   GetOut

LCOLUBK:

  MOV   AL,BYTE PTR TIA_Regs[COLUBK + _Base]
  MOV   AH,AL
  MOV   WORD PTR ColorLum[6 + _Base],AX
  JMP   GetOut

LCTRLPF:
{  MOV   AL,BYTE PTR _CTRLPF[_Base]
  MOV   BYTE PTR TIA_Regs[CTRLPF + _Base],AL}

{  MOV   AL,BYTE PTR TIA_Regs[CTRLPF + _Base]
  MOV   SI,AX
  SHR   SI,4
  AND   SI,3
  MOV   CL,BYTE PTR MissileSize[SI + _Base]
  SUB   CH,CH
  MOV   WORD PTR BallSize[_Base],CX

  MOV   DX,CX
  DEC   DX
  SHR   DX,1
  MOV   WORD PTR BallAdjust[_Base],DX

  SUB   CX,160
  MOV   WORD PTR BallSize160[_Base],CX
  MOV   CX,WORD PTR ColorLum[0 + _Base]
  MOV   DX,WORD PTR ColorLum[2 + _Base]
  MOV   BX,WORD PTR ColorLum[4 + _Base]
  TEST  AL,2
  JZ    @LCPF1
  MOV   WORD PTR CLW[_Base],CX
  MOV   WORD PTR CLW[_Base + 2],CX
  MOV   WORD PTR CRW[_Base],DX
  MOV   WORD PTR CRW[_Base + 2],DX
  JMP   @LCPF2
@LCPF1:
  MOV   WORD PTR CLW[_Base],BX
  MOV   WORD PTR CLW[_Base + 2],BX
  MOV   WORD PTR CRW[_Base],BX
  MOV   WORD PTR CRW[_Base + 2],BX
@LCPF2:}

  JMP   GetOut

LREFP0:

  MOV   CL,BYTE PTR TIA_Regs[REFP0 + _Base]
  MOV   BL,BYTE PTR TIA_Regs[NUSIZ0 + _Base]
  AND   BX,7
  ADD   BX,BX
  MOV   AX,BX
  SHL   AX,7
  SHL   CL,4
  AND   CL,80h
  OR    AL,CL
  MOV   WORD PTR Player0Size128[_Base],AX
  MOV   AX,WORD PTR PlayerSize[BX + _Base]
  MOV   WORD PTR Player0Size[_Base],AX
  SUB   AX,160
  MOV   WORD PTR Player0Size160[_Base],AX
  JMP   GetOut

LREFP1:

  MOV   CL,BYTE PTR TIA_Regs[REFP1 + _Base]
  MOV   BL,BYTE PTR TIA_Regs[NUSIZ1 + _Base]
  AND   BX,7
  ADD   BX,BX
  MOV   AX,BX
  SHL   AX,7
  SHL   CL,4
  AND   CL,80h
  OR    AL,CL
  MOV   WORD PTR Player1Size128[_Base],AX
  MOV   AX,WORD PTR PlayerSize[BX + _Base]
  MOV   WORD PTR Player1Size[_Base],AX
  SUB   AX,160
  MOV   WORD PTR Player1Size160[_Base],AX
  JMP   GetOut
(*
LVDELBL:

  TEST  BYTE PTR TIA_Regs[VDELBL + _Base],1
  DB    0Fh,94h,0C0h   { SETZ  AL }

  AND   BYTE PTR DispJump[_Base],0FDh
  TEST  BYTE PTR [ENABL],2
  JZ    @LVDELBLA
{  TEST  AL,1
  JNZ   @LVDELBLA}
  OR    BYTE PTR DispJump[_Base],2
@LVDELBLA:
  JMP   GetOut
*)
LHMOVE:
  MOV   BYTE PTR DoHMOVE[_Base],1
  MOV   AL,BYTE PTR TIA_Regs[HMP0 + _Base]
  SAR   AL,4
  SUB   BYTE PTR ObjectLoc[Player0Set * 2 + _Base],AL
  MOV   CX,160
  OR    AL,AL
  JNS   @P0
  NEG   CX
@P0:
  CMP   BYTE PTR ObjectLoc[Player0Set * 2 + _Base],160
  JB    @P0Ok
  ADD   BYTE PTR ObjectLoc[Player0Set * 2 + _Base],CL
@P0Ok:
  MOV   AL,BYTE PTR TIA_Regs[HMP1 + _Base]
  SAR   AL,4
  SUB   BYTE PTR ObjectLoc[Player1Set * 2 + _Base],AL
  MOV   CX,160
  OR    AL,AL
  JNS   @P1
  NEG   CX
@P1:
  CMP   BYTE PTR ObjectLoc[Player1Set * 2 + _Base],160
  JB    @P1Ok
  ADD   BYTE PTR ObjectLoc[Player1Set * 2 + _Base],CL
@P1Ok:
  TEST  BYTE PTR [RESMP0],2
  JZ    @Missile0OkA
  MOV   AL,BYTE PTR ObjectLoc[Player0Set * 2 + _Base]
  MOV   AH,BYTE PTR Player0Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],AL
  JMP   @M0Ok
@Missile0OkA:
  MOV   AL,BYTE PTR TIA_Regs[HMM0 + _Base]
  SAR   AL,4
  SUB   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],AL
  MOV   CX,160
  OR    AL,AL
  JNS   @M0
  NEG   CX
@M0:
  CMP   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],160
  JB    @M0Ok
  ADD   BYTE PTR ObjectLoc[Missile0Set * 2 + _Base],CL
@M0Ok:
  TEST  BYTE PTR [RESMP1],2
  JZ    @Missile1OkA
  MOV   AL,BYTE PTR ObjectLoc[Player1Set * 2 + _Base]
  MOV   AH,BYTE PTR Player1Size[_Base]
  SHR   AH,1
  ADD   AL,AH
  MOV   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],AL
  JMP   @M1Ok
@Missile1OkA:
  MOV   AL,BYTE PTR TIA_Regs[HMM1 + _Base]
  SAR   AL,4
  SUB   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],AL
  MOV   CX,160
  OR    AL,AL
  JNS   @M1
  NEG   CX
@M1:
  CMP   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],160
  JB    @M1Ok
  ADD   BYTE PTR ObjectLoc[Missile1Set * 2 + _Base],CL
@M1Ok:
  MOV   AL,BYTE PTR TIA_Regs[HMBL + _Base]
  SAR   AL,4
  SUB   BYTE PTR ObjectLoc[BallSet * 2 + _Base],AL
  MOV   CX,160
  OR    AL,AL
  JNS   @BL
  NEG   CX
@BL:
  CMP   BYTE PTR ObjectLoc[BallSet * 2 + _Base],160
  JB    @BLOk
  ADD   BYTE PTR ObjectLoc[BallSet * 2 + _Base],CL
@BLOk:
GetOut:
End; { Handle_IO_After }


Procedure InitEmulator;
Begin
  VAdd                := 0;
  VAddAdjust          := 0;
  CTRLPFLatch         := 0;
  CTRLPFScan          := -37;
  CTRLPFCount         := -68;
  Indy500             := 0;
  LastScan            := 0;
  NewScan             := 0;
  PaddleGround        := 0;
  GRP0Latch           := 0;
  GRP1Latch           := 0;
  BallLatch           := 0;
  TIA_Scan            := -40;
  DoHMOVE             := False;
  LineStart           := 0;
  TimerDone           := False;
  TimerInterval       := 1024{0};
  TimerValue          := 0;
  AtariSeg^[INTTIM1]  := $14;
  ColorOrBW           := 8;
  Difficulty1         := 0;
  Difficulty2         := 0;
  ColorOrBWChange     := True;
  Difficulty1Change   := True;
  Difficulty2Change   := True;
  TopVBLANK           := True;
  AtariSeg^[SWCHB1]   := ColorOrBW Or Difficulty1 Or Difficulty2 Or 3;
  AtariSeg^[SWCHB2]   := ColorOrBW Or Difficulty1 Or Difficulty2 Or 3;
  TIA_Count           := -68;
  Old_TIA_Count       := -68;
  FillChar(ObjectLoc,SizeOf(ObjectLoc),#0);
  Addr                := 0;
  Latched             := False;
  ReadTime            := 1;
  Write_TIA           := 0;
  Handle_IO_Set       := False;
  Handle_IO_Set_After := False;
  TimerNotSet         := 1;
  AddCycle            := 0;
  Player0Size         := 7;
  Player1Size         := 7;
  Player0Size160      := -153;
  Player1Size160      := -153;
  Player0Size128      := 0;
  Player1Size128      := 0;
  Missile0Size        := 1;
  Missile1Size        := 1;
  Missile0Size160     := -159;
  Missile1Size160     := -159;
  BallSize            := 1;
  BallSize160         := -159;
  ObjectSet           := 0;
  Handle_TIA_Jump_Set := False;
  DispJump            := 0;
  FillChar(Input_Byte,SizeOf(Input_Byte),#0);
  Input_Byte[INPUT4]  := $80;
  Input_Byte[INPUT5]  := $80;
  Input_Byte[$E]      := $F;
  Input_Byte[$F]      := $F;
  Missile0Adjust      := 0;
  Missile1Adjust      := 0;
  BallAdjust          := 0;
  FillChar(Handle_IO_Loc,SizeOf(Handle_IO_Loc),#0);
  FillChar(Handle_IO_Loc_After,SizeOf(Handle_IO_Loc_After),#0);
  FillChar(ColorLum,SizeOf(ColorLum),#0);
  FillChar(TIA_Delay,SizeOf(TIA_Delay),#0);
  TIA_Delay[GRP0] := 1;
  TIA_Delay[GRP1] := 1;
  TIA_Delay[PF0]  := 4;
  TIA_Delay[PF1]  := 4;
  TIA_Delay[PF2]  := 4;
End; { InitEmulator }


Procedure Interpret(Var _Start: Word; Var _P,_A,_X,_Y,_S: Byte);
Var
  Lo        : Word;
  Save_DS   : Word;
  P,A,X,Y,S : Byte;
  Start     : Word;

Label DoNothing,EmulateLoop,NoReadTime,DoneReadTime,BackToLoop,
      L00,L01,L02,L03,L04,L05,L06,L07,L08,L09,L0A,L0B,L0C,L0D,L0E,L0F,
      L10,L11,L12,L13,L14,L15,L16,L17,L18,L19,L1A,L1B,L1C,L1D,L1E,L1F,
      L20,L21,L22,L23,L24,L25,L26,L27,L28,L29,L2A,L2B,L2C,L2D,L2E,L2F,
      L30,L31,L32,L33,L34,L35,L36,L37,L38,L39,L3A,L3B,L3C,L3D,L3E,L3F,
      L40,L41,L42,L43,L44,L45,L46,L47,L48,L49,L4A,L4B,L4C,L4D,L4E,L4F,
      L50,L51,L52,L53,L54,L55,L56,L57,L58,L59,L5A,L5B,L5C,L5D,L5E,L5F,
      L60,L61,L62,L63,L64,L65,L66,L67,L68,L69,L6A,L6B,L6C,L6D,L6E,L6F,
      L70,L71,L72,L73,L74,L75,L76,L77,L78,L79,L7A,L7B,L7C,L7D,L7E,L7F,
      L80,L81,L82,L83,L84,L85,L86,L87,L88,L89,L8A,L8B,L8C,L8D,L8E,L8F,
      L90,L91,L92,L93,L94,L95,L96,L97,L98,L99,L9A,L9B,L9C,L9D,L9E,L9F,
      LA0,LA1,LA2,LA3,LA4,LA5,LA6,LA7,LA8,LA9,LAA,LAB,LAC,LAD,LAE,LAF,
      LB0,LB1,LB2,LB3,LB4,LB5,LB6,LB7,LB8,LB9,LBA,LBB,LBC,LBD,LBE,LBF,
      LC0,LC1,LC2,LC3,LC4,LC5,LC6,LC7,LC8,LC9,LCA,LCB,LCC,LCD,LCE,LCF,
      LD0,LD1,LD2,LD3,LD4,LD5,LD6,LD7,LD8,LD9,LDA,LDB,LDC,LDD,LDE,LDF,
      LE0,LE1,LE2,LE3,LE4,LE5,LE6,LE7,LE8,LE9,LEA,LEB,LEC,LED,LEE,LEF,
      LF0,LF1,LF2,LF3,LF4,LF5,LF6,LF7,LF8,LF9,LFA,LFB,LFC,LFD,LFE,LFF;

Begin

  { AL - X reg            AH - Y reg    }
  { BL - work             BH - work     }
  { CL - Accumulator      CH - Flags    }
  { DL - work             DH - Stack    }
  { SI - unused           DI - PC Reg   }
  { BP - used             SP - not used }

  P                   := _P;
  A                   := _A;
  X                   := _X;
  Y                   := _Y;
  S                   := _S;
  Start               := _Start;
  Lo                  := Lo_Seg;
  Move(AtariSeg^,TIA_Regs,SizeOf(TIA_Regs));
  Move(Cycles,AtariSeg^[_Cycles],SizeOf(Cycles));

  { Load locations here }

  Asm
    JMP   @Fill
@FillStart:
    DW    OFFSET L00
    DW    OFFSET L01
    DW    OFFSET DoNothing
    DW    OFFSET L03
    DW    OFFSET L04
    DW    OFFSET L05
    DW    OFFSET L06
    DW    OFFSET L07
    DW    OFFSET L08
    DW    OFFSET L09
    DW    OFFSET L0A
    DW    OFFSET L0B
    DW    OFFSET L0C
    DW    OFFSET L0D
    DW    OFFSET L0E
    DW    OFFSET L0F

    DW    OFFSET L10
    DW    OFFSET L11
    DW    OFFSET DoNothing
    DW    OFFSET L13
    DW    OFFSET L14
    DW    OFFSET L15
    DW    OFFSET L16
    DW    OFFSET L17
    DW    OFFSET L18
    DW    OFFSET L19
    DW    OFFSET DoNothing
    DW    OFFSET L1B
    DW    OFFSET L1C
    DW    OFFSET L1D
    DW    OFFSET L1E
    DW    OFFSET L1F

    DW    OFFSET L20
    DW    OFFSET L21
    DW    OFFSET DoNothing
    DW    OFFSET L23
    DW    OFFSET L24
    DW    OFFSET L25
    DW    OFFSET L26
    DW    OFFSET L27
    DW    OFFSET L28
    DW    OFFSET L29
    DW    OFFSET L2A
    DW    OFFSET L2B
    DW    OFFSET L2C
    DW    OFFSET L2D
    DW    OFFSET L2E
    DW    OFFSET L2F

    DW    OFFSET L30
    DW    OFFSET L31
    DW    OFFSET DoNothing
    DW    OFFSET L33
    DW    OFFSET L34
    DW    OFFSET L35
    DW    OFFSET L36
    DW    OFFSET L37
    DW    OFFSET L38
    DW    OFFSET L39
    DW    OFFSET DoNothing
    DW    OFFSET L3B
    DW    OFFSET L3C
    DW    OFFSET L3D
    DW    OFFSET L3E
    DW    OFFSET L3F

    DW    OFFSET L40
    DW    OFFSET L41
    DW    OFFSET DoNothing
    DW    OFFSET L43
    DW    OFFSET L44
    DW    OFFSET L45
    DW    OFFSET L46
    DW    OFFSET L47
    DW    OFFSET L48
    DW    OFFSET L49
    DW    OFFSET L4A
    DW    OFFSET L4B
    DW    OFFSET L4C
    DW    OFFSET L4D
    DW    OFFSET L4E
    DW    OFFSET L4F

    DW    OFFSET L50
    DW    OFFSET L51
    DW    OFFSET DoNothing
    DW    OFFSET L53
    DW    OFFSET L54
    DW    OFFSET L55
    DW    OFFSET L56
    DW    OFFSET L57
    DW    OFFSET L58
    DW    OFFSET L59
    DW    OFFSET DoNothing
    DW    OFFSET L5B
    DW    OFFSET L5C
    DW    OFFSET L5D
    DW    OFFSET L5E
    DW    OFFSET L5F

    DW    OFFSET L60
    DW    OFFSET L61
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET L64
    DW    OFFSET L65
    DW    OFFSET L66
    DW    OFFSET DoNothing
    DW    OFFSET L68
    DW    OFFSET L69
    DW    OFFSET L6A
    DW    OFFSET DoNothing
    DW    OFFSET L6C
    DW    OFFSET L6D
    DW    OFFSET L6E
    DW    OFFSET DoNothing

    DW    OFFSET L70
    DW    OFFSET L71
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET L74
    DW    OFFSET L75
    DW    OFFSET L76
    DW    OFFSET DoNothing
    DW    OFFSET L78
    DW    OFFSET L79
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET L7C
    DW    OFFSET L7D
    DW    OFFSET L7E
    DW    OFFSET DoNothing

    DW    OFFSET L80
    DW    OFFSET L81
    DW    OFFSET L82
    DW    OFFSET L83
    DW    OFFSET L84
    DW    OFFSET L85
    DW    OFFSET L86
    DW    OFFSET L87
    DW    OFFSET L88
    DW    OFFSET DoNothing
    DW    OFFSET L8A
    DW    OFFSET L8B
    DW    OFFSET L8C
    DW    OFFSET L8D
    DW    OFFSET L8E
    DW    OFFSET L8F

    DW    OFFSET L90
    DW    OFFSET L91
    DW    OFFSET DoNothing
    DW    OFFSET L93
    DW    OFFSET L94
    DW    OFFSET L95
    DW    OFFSET L96
    DW    OFFSET L97
    DW    OFFSET L98
    DW    OFFSET L99
    DW    OFFSET L9A
    DW    OFFSET L9B
    DW    OFFSET L9C
    DW    OFFSET L9D
    DW    OFFSET L9E
    DW    OFFSET L9F

    DW    OFFSET LA0
    DW    OFFSET LA1
    DW    OFFSET LA2
    DW    OFFSET LA3
    DW    OFFSET LA4
    DW    OFFSET LA5
    DW    OFFSET LA6
    DW    OFFSET LA7
    DW    OFFSET LA8
    DW    OFFSET LA9
    DW    OFFSET LAA
    DW    OFFSET LAB
    DW    OFFSET LAC
    DW    OFFSET LAD
    DW    OFFSET LAE
    DW    OFFSET LAF

    DW    OFFSET LB0
    DW    OFFSET LB1
    DW    OFFSET DoNothing
    DW    OFFSET LB3
    DW    OFFSET LB4
    DW    OFFSET LB5
    DW    OFFSET LB6
    DW    OFFSET LB7
    DW    OFFSET LB8
    DW    OFFSET LB9
    DW    OFFSET LBA
    DW    OFFSET LBB
    DW    OFFSET LBC
    DW    OFFSET LBD
    DW    OFFSET LBE
    DW    OFFSET LBF

    DW    OFFSET LC0
    DW    OFFSET LC1
    DW    OFFSET LC2
    DW    OFFSET LC3
    DW    OFFSET LC4
    DW    OFFSET LC5
    DW    OFFSET LC6
    DW    OFFSET LC7
    DW    OFFSET LC8
    DW    OFFSET LC9
    DW    OFFSET LCA
    DW    OFFSET LCB
    DW    OFFSET LCC
    DW    OFFSET LCD
    DW    OFFSET LCE
    DW    OFFSET LCF

    DW    OFFSET LD0
    DW    OFFSET LD1
    DW    OFFSET DoNothing
    DW    OFFSET LD3
    DW    OFFSET LD4
    DW    OFFSET LD5
    DW    OFFSET LD6
    DW    OFFSET LD7
    DW    OFFSET LD8
    DW    OFFSET LD9
    DW    OFFSET DoNothing
    DW    OFFSET LDB
    DW    OFFSET LDC
    DW    OFFSET LDD
    DW    OFFSET LDE
    DW    OFFSET LDF

    DW    OFFSET LE0
    DW    OFFSET LE1
    DW    OFFSET LE2
    DW    OFFSET DoNothing
    DW    OFFSET LE4
    DW    OFFSET LE5
    DW    OFFSET LE6
    DW    OFFSET DoNothing
    DW    OFFSET LE8
    DW    OFFSET LE9
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET LEC
    DW    OFFSET LED
    DW    OFFSET LEE
    DW    OFFSET DoNothing

    DW    OFFSET LF0
    DW    OFFSET LF1
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET LF4
    DW    OFFSET LF5
    DW    OFFSET LF6
    DW    OFFSET DoNothing
    DW    OFFSET LF8
    DW    OFFSET LF9
    DW    OFFSET DoNothing
    DW    OFFSET DoNothing
    DW    OFFSET LFC
    DW    OFFSET LFD
    DW    OFFSET LFE
    DW    OFFSET LFF
@Fill:
    MOV   CX,100h
    SUB   BX,BX
    MOV   SI,OFFSET @FillStart
    CLD
@FillLoop:
    MOV   AX,WORD PTR CS:[SI]
    MOV   WORD PTR Locations[BX],AX
    ADD   SI,2
    ADD   BX,2
    LOOP  @FillLoop
  End; { Asm }
  Global_Save_DS := DSeg;
  Move(Mem[DSeg:0],AtariSeg^[_Base],AtariSegSize - _Base{Ofs(Executed)});
  Asm
    MOV   DI,WORD PTR Start
    MOV   Save_DS,DS
    MOV   DS,WORD PTR Lo
    MOV   AL,BYTE PTR X
    MOV   AH,BYTE PTR Y
    MOV   CL,BYTE PTR A
    MOV   CH,BYTE PTR P
    MOV   DH,BYTE PTR S
    DEC   DI
DoNothing:
    INC   DI
EmulateLoop:
    DEC   WORD PTR ReadTime[_Base]
    JNZ   NoReadTime
    PUSH  AX
    PUSH  DX
    PUSH  CX
    PUSH  DI
    MOV   ES,WORD PTR Save_DS
    CALL  Handle_Input
    MOV   WORD PTR ReadTime[_Base],Read_Delay
@CheckEsc:
    TEST  BYTE PTR ES:Key[kESC],0FFh
    JZ    BackToLoop

    DB    _32BIT_OPERAND
    MOV   SI,WORD PTR AtariSeg[_Base]

    MOV   DS,WORD PTR Save_DS
    POP   DI
    POP   CX
    POP   DX
    POP   AX

    MOV   BYTE PTR X,AL
    MOV   BYTE PTR Y,AH
    MOV   BYTE PTR A,CL
    MOV   BYTE PTR P,CH
    MOV   BYTE PTR S,DH
    MOV   WORD PTR Start,DI

    DB    _32BIT_OPERAND
    MOV   WORD PTR AtariSeg,SI

  End; { Asm }
  Move(AtariSeg^[_Base],Mem[DSeg:0],AtariSegSize - _Base{Ofs(Executed)});
  _P     := P;
  _A     := A;
  _X     := X;
  _Y     := Y;
  _S     := S;
  _Start := Start;
  Exit;
BackToLoop:

  Asm
    MOV   AL,BYTE PTR [SWCHA1]
    MOV   BYTE PTR [SWCHA2],AL
    MOV   AL,BYTE PTR [SWCHB1]
    MOV   BYTE PTR [SWCHB2],AL
    POP   DI
    POP   CX
    POP   DX
    POP   AX
NoReadTime:
{    CMP   WORD PTR TimerInterval[_Base],0
    JE    @GetOut}
    MOV   BX,WORD PTR AddCycle[_Base]
    TEST  BYTE PTR TimerDone[_Base],0FFh
    JNZ   @LTimerDone
    MOV   SI,WORD PTR TimerInterval[_Base]
    ADD   WORD PTR TimerValue[_Base],BX
    MOV   BX,WORD PTR TimerValue[_Base]
    CMP   BX,SI
    JL    @GetOut
    MOV   WORD PTR TimerValue[_Base],0
    SUB   BX,SI
    SUB   BYTE PTR [INTTIM1],1
    JC    @Done
    ADD   WORD PTR TimerValue[_Base],BX
    JMP   @GetOut
@Done:
    MOV   BYTE PTR TimerDone[_Base],1
@LTimerDone:
    SUB   BYTE PTR [INTTIM1],BL
@GetOut:

    { The write cycle is the last of the instruction cycles; add the }
    { instruction cycles first.                                      }

    DB    _32BIT_OPERAND
    MOV   BX,WORD PTR AddCycle[_Base]
    DB    _32BIT_ADDRESS,8Dh,1Ch,5Bh   { LEA BX,[EBX + EBX * 2] }
    ADD   WORD PTR TIA_Count[_Base],BX
(*
    DB    _32BIT_OPERAND
    ADD   WORD PTR CyclesDone[_Base],BX  { BH = 0 here }
*)
    { Now handle a write to the TIA }

    TEST  BYTE PTR Write_TIA[_Base],0FFh
    JZ    @NoWriteTIA

    { If the write was to WSYNC, then Handle_IO has already properly set }
    { TIA_Count, don't add the instruction time to it.                   }

    CMP   BYTE PTR Write_TIA[_Base],2
    JNE   @NotWSYNC
    SUB   WORD PTR TIA_Count[_Base],BX
@NotWSYNC:
    PUSH  AX
    PUSH  DX
    PUSH  CX
    PUSH  DI



    MOV   BX,WORD PTR Save_BX[_Base]
    ADD   BX,BX
    MOV   BX,WORD PTR TIA_Delay[BX + _Base]

    CMP   BX,4
    JNE   @No
{    MOV   SI,WORD PTR TIA_Count[_Base]
    AND   SI,3
    SUB   BX,SI}
    SUB   BX,WORD PTR TIA_Count[_Base]
    DEC   BX
    AND   BX,3
    INC   BX

@No:

    MOV   SI,WORD PTR TIA_Count[_Base]
    ADD   WORD PTR TIA_Count[_Base],BX
    PUSH  SI
    CALL  Handle_TIA
    POP   SI
    MOV   WORD PTR TIA_Count[_Base],SI


{    MOV   WORD PTR Old_TIA_Count[_Base],SI}
{    SUB   WORD PTR TIA_Count[_Base],BX}
{
    CMP   BX,GRP0
    JB    @NormalTIA
    CMP   BX,GRP1
    JA    @NormalTIA
    INC   WORD PTR TIA_Count[_Base]
    CALL  Handle_TIA
    DEC   WORD PTR TIA_Count[_Base]
    JMP   @Continue
@NormalTIA:
    CALL  Handle_TIA
@Continue:
}
    MOV   BX,WORD PTR Save_BX[_Base]
    MOV   AL,BYTE PTR [BX]
    MOV   BYTE PTR TIA_Regs[BX + _Base],AL
    CALL  Handle_IO_After
    POP   DI
    POP   CX
    POP   DX
    POP   AX

    { See if an object's position has been reset }

    TEST  WORD PTR ObjectSet[_Base],0FFh
    JZ    @L1
    MOV   SI,WORD PTR TIA_Count[_Base]
    CMP   SI,4
    JNE   @NoExtraAdd
    TEST  BYTE PTR DoHMOVE[_Base],0FFh
    JZ    @NoExtraAdd
    ADD   SI,ExtraAdd
@NoExtraAdd:
    ADD   SI,SetLocDelay         { Delay when setting object positions }
    MOV   BX,WORD PTR ObjectSet[_Base]
    CMP   BX,Player1Set
    JA    @NotPlayerSet
    INC   SI
@NotPlayerSet:
    ADD   BX,BX

    { If the object was placed in a negative x position, force it to zero. }

    CMP   SI,160
    JB    @SignOk
    SUB   SI,SI
@SignOk:

    MOV   WORD PTR ObjectLoc[BX + _Base],SI
    MOV   WORD PTR ObjectSet[_Base],0
@L1:

    { If the write was to WSYNC, then the delay time has already been     }
    { figured into the correct TIA_Count.  Don't subtract the delay time. }

    CMP   BYTE PTR Write_TIA[_Base],2
    JE    @WSYNC
@WSYNC:
    MOV   BYTE PTR Write_TIA[_Base],0
@NoWriteTIA:

    TEST  BYTE PTR Input_Byte[INPUT0 + _Base],80h
    JNZ   @NoPaddle
    TEST  BYTE PTR [VBLANK],80h
    JNZ   @NoPaddle
    DB    _32BIT_OPERAND
    PUSH  BX
    DB    _32BIT_OPERAND
    MOV   BX,WORD PTR AddCycle[_Base]
    DB    _32BIT_OPERAND
    SUB   WORD PTR PaddleGround[_Base],BX
    JNC   @NoPaddle1
    MOV   BYTE PTR Input_Byte[INPUT0 + _Base],80h
@NoPaddle1:
    DB    _32BIT_OPERAND
    POP   BX
@NoPaddle:

    { Get the next instruction here to avoid a Pentium AGI }
    { (Address Generation Interlock)                       }

    MOV   SI,WORD PTR [DI]   {U}
    MOV   BX,160             {V}   { This sets BH to ZERO (IMPORTANT!) }
    AND   SI,0FFh            {U}

    { Check to see if we've reached the end of the scan line }

    CMP   WORD PTR TIA_Count[_Base],BX         {U}
    JL    @NoNewLine                           {V}

    CMP   WORD PTR Old_TIA_Count[_Base],BX
    JL    @NoOldAdjust
    MOV   WORD PTR Old_TIA_Count[_Base],BX
@NoOldAdjust:



    DB    _32BIT_OPERAND
    MOV   BX,228
    DW    0
    DB    _32BIT_OPERAND
    ADD   WORD PTR CyclesDone[_Base],BX
    PUSH  AX
    PUSH  DX
    PUSH  CX
    PUSH  DI
    PUSH  SI
    CALL  Handle_TIA

    MOV   BX,WORD PTR TIA_Scan[_Base]         { Ensure that BH = 0! }
    CMP   BX,250{222}
    JGE   @DoneLines
    INC   BX
@DoneLines:

    CMP   BX,200
    JAE   @Negative
    MOV   AX,BX
    SHL   AX,6
    ADD   AH,BL
    MOV   WORD PTR Addr[_Base],AX
    MOV   WORD PTR LineStart[_Base],AX
    MOV   BYTE PTR DoHMOVE[_Base],0
@Negative:
(*
    PUSH  BX
  MOV   AL,BYTE PTR [CTRLPF]
  MOV   BYTE PTR TIA_Regs[CTRLPF + _Base],AL
  MOV   BYTE PTR _CTRLPF[_Base],AL
  MOV   AL,BYTE PTR TIA_Regs[CTRLPF + _Base]
  MOV   SI,AX
  SHR   SI,4
  AND   SI,3
  MOV   CL,BYTE PTR MissileSize[SI + _Base]
  SUB   CH,CH
  MOV   WORD PTR BallSize[_Base],CX

  MOV   DX,CX
  DEC   DX
  SHR   DX,1
  MOV   WORD PTR BallAdjust[_Base],DX

  SUB   CX,160
  MOV   WORD PTR BallSize160[_Base],CX
  MOV   CX,WORD PTR ColorLum[0 + _Base]
  MOV   DX,WORD PTR ColorLum[2 + _Base]
  MOV   BX,WORD PTR ColorLum[4 + _Base]
  TEST  AL,2
  JZ    @LCPF1
  MOV   WORD PTR CLW[_Base],CX
  MOV   WORD PTR CLW[_Base + 2],CX
  MOV   WORD PTR CRW[_Base],DX
  MOV   WORD PTR CRW[_Base + 2],DX
  JMP   @LCPF2
@LCPF1:
  MOV   WORD PTR CLW[_Base],BX
  MOV   WORD PTR CLW[_Base + 2],BX
  MOV   WORD PTR CRW[_Base],BX
  MOV   WORD PTR CRW[_Base + 2],BX
@LCPF2:
    POP   BX
*)

    MOV   AL,BYTE PTR GRP0Latch[_Base]
    MOV   BYTE PTR [GRP0],AL
    AND   BYTE PTR DispJump[_Base],0DFh
    TEST  AL,0FFh
    JZ    @LGRP0A
    OR    BYTE PTR DispJump[_Base],20h
@LGRP0A:

    MOV   AL,BYTE PTR GRP1Latch[_Base]
    MOV   BYTE PTR [GRP1],AL
    AND   BYTE PTR DispJump[_Base],0F7h
    TEST  AL,0FFh
    JZ    @LGRP1A
    OR    BYTE PTR DispJump[_Base],8
@LGRP1A:

    MOV   AL,BYTE PTR BallLatch[_Base]
    MOV   BYTE PTR [ENABL],AL
    AND   BYTE PTR DispJump[_Base],0FDh
    TEST  AL,2
    JZ    @LVDELBL
    OR    BYTE PTR DispJump[_Base],2h
@LVDELBL:


    MOV   AX,WORD PTR [GRP0]
    MOV   WORD PTR TIA_Regs[GRP0 + _Base],AX

    SUB   WORD PTR TIA_Count[_Base],228
{    SUB   WORD PTR Old_TIA_Count[_Base],228}
    MOV   WORD PTR Old_TIA_Count[_Base],-68
{
    JL    @DoneLines
    MOV   BX,-41
    MOV   WORD PTR Addr[_Base],0
@DoneLines:
    INC   BX
}
{
    CMP   BX,200
    JAE   @Negative
    MOV   AX,BX
    SHL   AX,6
    ADD   AH,BL
    MOV   WORD PTR Addr[_Base],AX
@Negative:
}
{
    CMP   BX,200
    JGE   @DoneLines
    INC   BX
@DoneLines:
    OR    BX,BX
    JS    @Negative
    MOV   AX,BX
    SHL   AX,6
    ADD   AH,BL
    MOV   WORD PTR Addr[_Base],AX
@Negative:
}
    POP   SI
    POP   DI
    POP   CX
    POP   DX
    POP   AX
    MOV   WORD PTR TIA_Scan[_Base],BX                              {U}
{    OR    BX,BX
    JNS   @Positive}
    SUB   BH,BH                                                    {V}
{@Positive:}
    AND   BYTE PTR DispJump[_Base],0FDh      { Turn ball off }     {U}
    TEST  BYTE PTR [ENABL],2                                       {U}
    JZ    @NoNewLine                                               {V}
    OR    BYTE PTR DispJump[_Base],2         { Display the ball }  {U}
@NoNewLine:
    MOV   DL,BYTE PTR [SI + _Cycles]                               {U}
    ADD   SI,SI                                                    {V}
    MOV   BYTE PTR AddCycle[_Base],DL                              {U}
    JMP   WORD PTR Locations[SI + _Base]                           {U}
  End; { Asm }

{ --------------------------- Assembly emulator --------------------------- }

L00:                 { BRK }

  Asm
    DEC    DH
    MOV    BL,DH
{    MOV    BH,1}            { A 6502 would have this, but not an Atari }

    ADD    DI,2

    MOV    WORD PTR [BX],DI
    DEC    BL
    MOV    BYTE PTR [BX],CH
    SUB    DH,2
    OR     CH,014h
    MOV    DI,[1FFEh]        { 6502: [0FFFEh] }
    AND    DI,01FFFh         { Atari can only address 8K }
    JMP    EmulateLoop
  End; { Asm }

L01:                 { ORA ind. x }

 Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L02:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L03:                 { SLO ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }
    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L04:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L05:                 { ORA zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    AND    CH,07Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L06:                 { ASL zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L07:                 { SLO zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L08:                 { PHP }

  Asm
    MOV    BL,DH
{    MOV    BH,1}

    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CH
    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    DEC    DH
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L09:                 { ORA immediate }

  Asm
    OR     CL,BYTE PTR [DI+1]
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L0A:                 { ASL accum. }

  Asm
    OR     CH,3
    ADD    CL,CL
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L0B:                 { ANC immediate - UNDOCUMENTED }

  Asm
    AND    CL,BYTE PTR [DI+1]
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L0C:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L0D:                { ORA absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L0E:                 { ASL absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L0F:                 { SLO absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L10:                 { BPL }

  Asm
    TEST   CH,80h
    JNZ    @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L11:                 { ORA ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
{    ADC    BH,0}
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L12:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L13:                 { SLO ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    MOV    BL,BYTE PTR [DI+1]
    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L14:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L15:                 { ORA z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L16:                 { ASL z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L17:                 { SLO z. page x - UNDOCUMENTED }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    MOV    BL,BYTE PTR [DI+1]
    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L18:                 { CLC }

  Asm
    AND    CH,0FEh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L19:                 { ORA abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L1A:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L1B:                 { SLO abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L1C:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L1D:                 { ORA abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    OR     CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    OR     CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L1E:                 { ASL abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L1F:                 { SLO abs. x - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,07Ch
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2
    OR     CH,1
  @L2:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,BYTE PTR [BX]
    RCL    DL,1
    JNC    @L2a
    OR     CH,1
  @L2a:
    OR     DL,CL
    MOV    BYTE PTR [BX],DH
    JZ     @L1
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L20:                 { JSR }

  Asm
    DEC    DH
    MOV    BL,DH
{    MOV    BH,1}
    MOV    WORD PTR [BX],DI
    ADD    WORD PTR [BX],2
    DEC    DH

    MOV    DI,WORD PTR [DI+1]
{    AND    DI,1FFFh}          { Atari can only address 8K }
(*
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }
    PUSH   BX
    SUB    BH,BH
    MOV    BL,DH
    INC    BL
*)
    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoActivision
    TEST   DI,2000h
    JZ     @Act1
    CMP    BYTE PTR CurrentBank[_Base],0
    JNE    @Act1a
    MOV    BYTE PTR BankSwitch[BX + _Base + 100h],1     { Already at 1 }
    JMP    @Act2
@Act1A:
    MOV    BYTE PTR BankSwitch[BX + _Base + 100h],21    { Switching to 1 }
    JMP    @Act2

@Act1:
    CMP    BYTE PTR CurrentBank[_Base],4
    JNE    @Act2a
    MOV    BYTE PTR BankSwitch[BX + _Base + 100h],5     { Already at 2 }
    JMP    @Act2
@Act2a:
    MOV    BYTE PTR BankSwitch[BX + _Base + 100h],17    { Switching to 2 }
@Act2:
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoActivision:
    AND    DI,1FFFh          { Atari can only address 8K }
(*
    CMP    DI,103Fh
    JA     @NoSwitch1
    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:
    TEST   BYTE PTR BankSwitch[BX + _Base + 101h],0FFh
    JZ     @NoSwitch1
    ADD    BX,101h
    CALL   SwitchBank
    SUB    BX,101h
@NoSwitch1:
*)
{    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:
    TEST   BYTE PTR BankSwitch[BX + _Base + 101h],0FFh
    JZ     @NoSwitch1
    CALL   SwitchBank
@NoSwitch1:}
{
    POP    BX
    MOV    DI,BX
}
    JMP    EmulateLoop
  End; { Asm }

L21:                 { AND ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End;{ Asm }

L22:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L23:                 { RLA ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L24:                 { BIT zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    BL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    MOV    DL,BL
    AND    DL,CL
    JZ     @L1
    AND    CH,3Dh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BL,BYTE PTR [BX]
    MOV    DL,BL
    AND    DL,CL
    JZ     @L1
    AND    CH,3Dh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    AND    CH,3Fh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L25:                 { AND zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L26:                 { ROL zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L27:                 { RLA zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L28:                 { PLP }

  Asm
    INC    DH
    MOV    BL,DH
{    MOV    BH,1}

    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:

    MOV    CH,BYTE PTR [BX]
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L29:                 { AND immediate }

  Asm
    AND    CL,BYTE PTR [DI+1]
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L2A:                 { ROL accum. }

  Asm
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    CL,1
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L2B:                 { ANC immediate - UNDOCUMENTED }

  Asm
    AND    CL,BYTE PTR [DI+1]
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L2C:                 { BIT absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    BL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    MOV    DL,BL
    AND    DL,CL
    JZ     @L1
    AND    CH,3Dh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    BL,BYTE PTR [BX]
    MOV    DL,BL
    AND    DL,CL
    JZ     @L1
    AND    CH,3Dh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    AND    CH,3Fh
    AND    BL,0C0h
    OR     CH,BL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L2D:                 { AND absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L2E:                 { ROL absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L2F:                 { RLA absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L30:                 { BMI }

  Asm
    TEST   CH,80h
    JZ     @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L31:                 { AND ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L32:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L33:                 { RLA ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L34:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L35:                 { AND z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L36:                 { ROL z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L37:                 { RLA z. page x - UNDOCUMENTED }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L38:                 { SEC }

  Asm
    OR     CH,01h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L39:                 { AND abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L3A:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L3B:                 { RLA abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:

    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L3C:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L3D:                 { AND abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    AND    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    AND    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L3E:                 { ROL abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L3F:                 { RLA abs. x - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCL    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCL    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    AND    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L40:                 { RTI }

  Asm
    INC    DH
    MOV    BL,DH
{    MOV    BH,1}
    MOV    CH,BYTE PTR [BX]
    INC    BL
    MOV    DI,WORD PTR [BX]
    AND    DI,01FFFh         { Atari can only address 8K }
    ADD    DH,2
    JMP    EmulateLoop
  End; { Asm }

L41:                 { EOR ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L42:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L43:                 { SRE ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L44:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L45:                 { EOR zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    AND    CH,07Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L46:                 { LSR zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L47:                 { SRE zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L48:                 { PHA }

  Asm
    MOV    BL,DH
{    MOV    BH,1}

    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL
    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    DEC    DH
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L49:                 { EOR immediate }

  Asm
    XOR    CL,BYTE PTR [DI+1]
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L4A:                 { LSR accum. }

  Asm
    OR     CH,3
    SHR    CL,1
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    INC    DI
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L4B:                 { ASR immediate - UNDOCUMENTED }

  Asm
    XOR    CL,BYTE PTR [DI+1]
    OR     CH,3
    SHR    CL,1
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    ADD    DI,2
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    OR     CH,02h
    JMP    EmulateLoop
  End; { Asm }

L4C:                 { JMP absolute }

  Asm
    MOV    DI,WORD PTR [DI+1]
    AND    DI,1FFFh          { Atari can only address 8K }
    JMP    EmulateLoop
  End; { Asm }

L4D:                 { EOR absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L4E:                 { LSR absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L4F:                 { SRE absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    MOV    Dl,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L50:                 { BVC }

  Asm
    TEST   CH,040h
    JNZ    @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L51:                 { EOR ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L52:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L53:                 { SRE ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L54:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L55:                 { EOR z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L56:                 { LSR z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L57:                 { SRE z. page x - UNDOCUMENTED }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L58:                 { CLI }

  Asm
    AND    CH,0FBh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L59:                 { EOR abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L5A:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L5B:                 { SRE abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L5C:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L5D:                 { EOR abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    XOR    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    XOR    CL,BYTE PTR [BX]
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L5E:                 { LSR abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L5F:                 { SRE abs. x - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    OR     CH,3
    SHR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    XOR    CL,DL
    MOV    DL,CL
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L60:                 { RTS }

  Asm
    INC    DH
    MOV    BL,DH
{    MOV    BH,1}



{    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:
    TEST   BYTE PTR BankSwitch[BX + _Base + 101h],0FFh
    JZ     @NoSwitch1
    INC    BX
    CALL   SwitchBank
    DEC    BX
@NoSwitch1:}

    MOV    DI,WORD PTR [BX]
    INC    DI
    AND    DI,01FFFh         { Atari can only address 8K }
{
    CMP    DI,103Fh
    JA     @NoSwitch1
}
    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:
    TEST   BYTE PTR BankSwitch[BX + _Base + 101h],0FFh
    JZ     @NoSwitch1
    ADD    BX,101h
    CALL   SwitchBank
    SUB    BX,101h
@NoSwitch1:



    INC    DH
    JMP    EmulateLoop
  End; { Asm }

L61:                 { ADC ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L62:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L63:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L64:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L65:                 { ADC zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L66:                 { ROR zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCR    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L67:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L68:                 { PLA }

  Asm
    INC    DH
    AND    CH,7Dh
    MOV    BL,DH
{    MOV    BH,1}

    TEST   BYTE PTR BankSwitch[BX + _Base + 100h],0FFh
    JZ     @NoSwitch
    ADD    BX,100h
    CALL   SwitchBank
    SUB    BX,100h
@NoSwitch:

    MOV    CL,BYTE PTR [BX]
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    INC    DI
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L69:                 { ADC immediate }

  Asm
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    OR     CH,3
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    ADC    CL,BYTE PTR [DI+1]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    ADC    AL,BYTE PTR [DI+1]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L6A:                 { ROR accum. }

  Asm
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCR    CL,1
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L6B:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L6C:                 { JMP indirect }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh              { Atari can only address 8K }
    MOV    DL,BYTE PTR [BX]
    INC    BL
    MOV    BH,BYTE PTR [BX]
    MOV    BL,DL
    MOV    DI,BX
    AND    DI,1FFFh              { Atari can only address 8K }
    JMP    EmulateLoop
  End; { Asm }

L6D:                 { ADC absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L6E:                 { ROR absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCR    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L6F:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L70:                 { BVS }

  Asm
    TEST   CH,40h
    JZ     @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L71:                 { ADC ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L72:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L73:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L74:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L75:                 { ADC z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L76:                 { ROR z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCR    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L77:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L78:                 { SEI }

  Asm
    OR     CH,04h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L79:                 { ADC abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L7A:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L7B:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L7C:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L7D:                 { ADC abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    POPF
    ADC    CL,BYTE PTR [BX]
    PUSHF
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    ADC    AL,BYTE PTR Input_Byte[BX + _Base]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6a
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    ADC    AL,BYTE PTR [BX]
    DAA
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JNC    @L6
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L7E:                 { ROR abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh
    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    MOV    DL,BYTE PTR Input_Byte[BX + _Base]
    RCR    DL,1
    JC     @L2a
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    DL,CH
    OR     CH,3
    SHR    DL,1
    RCR    BYTE PTR [BX],1
    MOV    DL,BYTE PTR [BX]
    JC     @L2
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L7F:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L80:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L81:                 { STA ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh        { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L82:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L83:                 { SAX ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh        { Atari can only address 8K }
    MOV    DL,CL
    AND    DL,AL

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],DL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L84:                 { STY zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    CMP    BX,02Ch
    JA     @NotCrit
    MOV    BYTE PTR [BX],AH
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BYTE PTR [BX],AH
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L85:                 { STA zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    CMP    BX,02Ch
    JA     @NotCrit
    MOV    BYTE PTR [BX],CL
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BYTE PTR [BX],CL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L86:                 { STX zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    CMP    BX,02Ch
    JA     @NotCrit
    MOV    BYTE PTR [BX],AL
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BYTE PTR [BX],AL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L87:                 { SAX zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    DL,CL
    AND    DL,AL
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    CMP    BX,02Ch
    JA     @NotCrit
    MOV    BYTE PTR [BX],DL
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BYTE PTR [BX],DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L88:                 { DEY }

  Asm
    DEC    AH
    JZ     @L1
    MOV    DL,AH
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

L89:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L8A:                 { TXA }

  Asm
    MOV    CL,AL
    OR     BH,AL   { BH = 0 at start }
    JZ     @L1
    AND    BH,80h
    AND    CH,7Dh
    ADD    CH,BH
    INC    DI
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

L8B:                 { ANE immediate - UNDOCUMENTED }

  Asm
    OR     CL,0EEh
    AND    CL,AL
    AND    CL,BYTE PTR [DI+1]
    AND    CH,7Dh
    OR     BH,CL
    JZ     @L1
    AND    BH,80h
    ADD    DI,2
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L8C:                 { STY absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],AH

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L8D:                 { STA absolute }
  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L8E:                 { STX absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],AL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L8F:                 { SAX absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }
    MOV    DL,CL
    AND    DL,AL

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],DL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L90:                 { BCC }

  Asm
    TEST   CH,01
    JNZ    @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L91:                 { STA ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
{    ADC    BH,0}
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L92:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L93:                 { SHA ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    MOV    DL,BH
    INC    DL
    AND    DL,AL
    AND    DL,CL
    JNC    @L1
    INC    BYTE PTR AddCycle[_Base]
    MOV    BH,DL
@L1:
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L94:                 { STY z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],AH
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L95:                 { STA z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L96:                 { STX z. page y }

  Asm
    MOV    BL,AH
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],AL
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L97:                 { SAX z. page y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AH
    MOV    DL,CL
    AND    DL,AL
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    CMP    BX,02Ch
    JA     @NotCrit
    MOV    BYTE PTR [BX],DL
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    BYTE PTR [BX],DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L98:                 { TYA }

  Asm
    MOV    CL,AH
    OR     BH,AH   { BH = 0 at start }
    JZ     @L1
    AND    BH,80h
    AND    CH,7Dh
    ADD    CH,BH
    INC    DI
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

L99:                 { STA abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L9A:                 { TXS }

  Asm
    MOV    DH,AL
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

L9B:                 { SHS ind. y - UNDOCUMENTED }

  Asm
    MOV    DH,AL
    AND    DH,CL
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    MOV    DL,BH
    INC    DL
    AND    DL,DH
    JNC    @L1
    INC    BYTE PTR AddCycle[_Base]
    MOV    BH,DL
@L1:
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

L9C:                 { SHY abs. x - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    MOV    DL,BH
    INC    DL
    AND    DL,AH
    JNC    @L1
    INC    BYTE PTR AddCycle[_Base]
    MOV    BH,DL
@L1:
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L9D:                 { STA abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L9E:                 { SHX abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    MOV    DL,BH
    INC    DL
    AND    DL,AL
    JNC    @L1
    INC    BYTE PTR AddCycle[_Base]
    MOV    BH,DL
@L1:
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

L9F:                 { SHA abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    MOV    DL,BH
    INC    DL
    AND    DL,AL
    AND    DL,CL
    JNC    @L1
    INC    BYTE PTR AddCycle[_Base]
    MOV    BH,DL
@L1:
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    MOV    BYTE PTR [BX],CL

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
@NotCrit:
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LA0:                 { LDY immediate }

  Asm
    MOV    AH,BYTE PTR [DI+1]
    AND    CH,7Dh
    OR     BH,AH
    JZ     @L1
    AND    BH,80h
    ADD    DI,2
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA1:                 { LDA ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA2:                 { LDX immediate }

  Asm
    MOV    AL,BYTE PTR [DI+1]
    AND    CH,7Dh
    OR     BH,AL
    JZ     @L1
    AND    BH,80h
    ADD    DI,2
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA3:                 { LAX ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA4:                 { LDY zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AH,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    AH,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA5:                 { LDA zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA6:                 { LDX zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    AL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA7:                 { LAX zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LA8:                 { TAY }

  Asm
    MOV    AH,CL
    AND    CH,7Dh
    OR     BH,AH
    JZ     @L1
    AND    BH,80h
    INC    DI
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LA9:                 { LDA immediate }

  Asm
    MOV    CL,BYTE PTR [DI+1]
    AND    CH,7Dh
    OR     BH,CL
    JZ     @L1
    AND    BH,80h
    ADD    DI,2
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LAA:                 { TAX }

  Asm
    MOV    AL,CL
    AND    CH,7Dh
    OR     BH,AL
    JZ     @L1
    AND    BH,80h
    INC    DI
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LAB:                 { LXA immed + a - UNDOCUMENTED }

  Asm
    ADD    CL,BYTE PTR [DI+1]
    MOV    AL,CL
    AND    CH,7Dh
    OR     BH,CL
    JZ     @L1
    AND    BH,80h
    ADD    DI,2
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LAC:                 { LDY absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AH,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    AH,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LAD:                 { LDA absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LAE:                 { LDX absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    AL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LAF:                 { LAX absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LB0:                 { BCS }

  Asm
    TEST   CH,01
    JZ     @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB1:                 { LDA ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    PUSHF
    ADC    BH,0
    POPF
    ADC    WORD PTR AddCycle[_Base],0
{    ADC    WORD PTR AddCycle[_Base],0
    ADD    BH,BYTE PTR AddCycle[_Base]}
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB2:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LB3:                 { LAX ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    PUSHF
    ADC    BH,0
    POPF
    ADC    WORD PTR AddCycle[_Base],0
{    ADC    WORD PTR AddCycle[_Base],0
    ADD    BH,BYTE PTR AddCycle[_Base]}
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB4:                 { LDY z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AH,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    AH,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB5:                 { LDA z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB6:                 { LDX z. page y }

  Asm
    MOV    BL,AH
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    AL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB7:                 { LAX z. page y - UNDOCUMENTED }

  Asm
    MOV    BL,AH
    ADD    BL,BYTE PTR [DI+1]
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LB8:                 { CLV }

  Asm
    AND    CH,0BFh
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LB9:                 { LDA abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LBA:                 { TSX }

  Asm
    MOV    AL,DH
    AND    CH,7Dh
    OR     BH,AL
    JZ     @L1
    AND    BH,80h
    INC    DI
    ADD    CH,BH
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LBB:                 { LAS (abs. y) and s - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    AND    CL,DH
    MOV    AL,CL
    MOV    DH,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LBC:                 { LDY abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AH,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    AH,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AH,AH
    JZ     @L1
    MOV    DL,AH
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LBD:                 { LDA abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LBE:                 { LDX abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,BYTE PTR Input_Byte[BX + _Base]

    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    AL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     AL,AL
    JZ     @L1
    MOV    DL,AL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LBF:                 { LAX abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    CALL   Handle_TIA
    POP    CX
    POP    BX
    MOV    CL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    DX
    POP    AX
    MOV    AL,CL

    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    MOV    CL,BYTE PTR [BX]
    AND    CH,7Dh
    OR     CL,CL
    JZ     @L1
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LC0:                 { CPY immediate }

  Asm
    MOV    DL,AH
    OR     CH,3
    SUB    DL,BYTE PTR [DI+1]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC1:                 { CMP ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC2:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC3:                 { DCP ind. x - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC4:                 { CPY zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    DL,AH
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC5:                 { CMP zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC6:                 { DEC zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    DEC    BYTE PTR [BX]
    PUSHF
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC7:                 { DCP zero page - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LC8:                 { INY }

  Asm
    INC    AH
    JZ     @L1
    MOV    DL,AH
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

LC9:                 { CMP immediate }

  Asm
    MOV    DL,CL
    OR     CH,3
    SUB    DL,BYTE PTR [DI+1]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LCA:                 { DEX }

  Asm
    DEC    AL
    JZ     @L1
    MOV    DL,AL
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

LCB:                 { SBX immediate - UNDOCUMENTED }

  Asm
    MOV    DL,CL
    AND    DL,AL
    OR     CH,3
    SUB    DL,BYTE PTR [DI+1]
    MOV    AL,DL
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LCC:                 { CPY absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,AH
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LCD:                 { CMP absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LCE:                 { DEC absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    DEC    BYTE PTR [BX]
    PUSHF
    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LCF:                 { DCP absolute - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LD0:                 { BNE }

  Asm
    TEST   CH,02
    JNZ    @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD1:                 { CMP ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    PUSHF
    ADC    BH,0
    POPF
    ADC    WORD PTR AddCycle[_Base],0
{    ADC    WORD PTR AddCycle[_Base],0
    ADD    BH,BYTE PTR AddCycle[_Base]}
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD2:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LD3:                 { DCP ind. y - UNDOCUMENTED }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    PUSHF
    ADC    BH,0
    POPF
    ADC    WORD PTR AddCycle[_Base],0
{    ADC    WORD PTR AddCycle[_Base],0
    ADD    BH,BYTE PTR AddCycle[_Base]}
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD4:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD5:                 { CMP z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD6:                 { DEC z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    DEC    BYTE PTR [BX]
    PUSHF
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD7:                 { DCP z. page x - UNDOCUMENTED }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LD8:                 { CLD }

  Asm
    AND    CH,0F7h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LD9:                 { CMP abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LDA:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LDB:                 { DCP abs. y - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LDC:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LDD:                 { CMP abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LDE:                 { DEC abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    TEST   BX,0FC00h
    JNZ    @NotCrit
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    DEC    BYTE PTR [BX]
    JZ     @L1a
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1a:
    PUSH   AX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    AX
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LDF:                 { DCP abs. x - UNDOCUMENTED }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,CL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    DEC    BYTE PTR Input_Byte[BX + _Base]
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    DEC    BYTE PTR [BX]
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LE0:                 { CPX immediate }

  Asm
    MOV    DL,AL
    OR     CH,3
    SUB    DL,BYTE PTR [DI+1]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE1:                 { SBC ind. x }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    ADD    BL,AL
    MOV    BX,WORD PTR [BX]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE2:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE3:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LE4:                 { CPX zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    DL,AL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE5:                 { SBC zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE6:                 { INC zero page }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    INC    BYTE PTR [BX]
    PUSHF
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LE7:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LE8:                 { INX }

  Asm
    INC    AL
    JZ     @L1
    MOV    DL,AL
    AND    CH,7Dh
    AND    DL,80h
    INC    DI
    ADD    CH,DL
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    INC    DI
    OR     CH,2
    JMP    EmulateLoop
  End; { Asm }

LE9:                 { SBC immediate }
  Asm
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    OR     CH,3
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    SBB    CL,BYTE PTR [DI+1]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    SBB    AL,BYTE PTR [DI+1]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LEA:                 { NOP }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LEB:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LEC:                 { CPX absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    MOV    DL,AL
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   DI
    PUSH   BX
    PUSH   CX
    PUSH   DX
    CALL   Handle_TIA
    POP    DX
    POP    CX
    POP    BX
    SUB    DL,BYTE PTR Input_Byte[BX + _Base]
    POP    DI
    POP    AX

    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    SUB    DL,BYTE PTR [BX]
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     DL,DL
    JZ     @L1
    AND    CH,7Dh
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LED:                 { SBC absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LEE:                 { INC absolute }

  Asm
    MOV    BX,WORD PTR [DI+1]
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    INC    BYTE PTR [BX]
    PUSHF
    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,2
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LEF:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LF0:                 { BEQ }

  Asm
    TEST   CH,02
    JZ     @L1
    DB     0Fh,0BEh,05Dh,01h    { MOVSX BX,BYTE PTR [DI+1] }
    ADD    DI,2
{    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]}
    PUSH   AX
    MOV    AX,DI
    ADD    DI,BX
    INC    WORD PTR AddCycle[_Base]
    MOV    BX,DI
    CMP    BH,AH
    JE     @L2
    INC    WORD PTR AddCycle[_Base]
  @L2:
    POP    AX
    JMP    EmulateLoop
  @L1:
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LF1:                 { SBC ind. y }

  Asm
    MOV    BL,BYTE PTR [DI+1]
    MOV    BX,WORD PTR [BX]
    ADD    BL,AH
    PUSHF
    ADC    BH,0
    POPF
    ADC    WORD PTR AddCycle[_Base],0
{    ADC    WORD PTR AddCycle[_Base],0
    ADD    BH,BYTE PTR AddCycle[_Base]}
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LF2:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LF3:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LF4:                 { SKB Quasi-Opcode }

  Asm
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LF5:                 { SBC z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,2
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LF6:                 { INC z. page x }

  Asm
    MOV    BL,AL
    ADD    BL,BYTE PTR [DI+1]
    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    INC    BYTE PTR [BX]
    PUSHF
    CMP    BX,02Ch
    JA     @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,2
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,2
    JMP    EmulateLoop
  End; { Asm }

LF7:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LF8:                 { SED }

  Asm
    OR     CH,08h
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LF9:                 { SBC abs. y }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AH
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
    POPF
    SBB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{     INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LFA:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LFB:                 { Nothing }

  Asm
    INC    DI
    JMP    EmulateLoop
  End; { Asm }

LFC:                 { SKW Quasi-Opcode }

  Asm
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LFD:                 { SBC abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    DB     0Fh,92h,0C2h              { SETC DL }
    ADD    BH,DL
    ADD    BYTE PTR AddCycle[_Base],DL
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,284h           { There are multiple timer copies }
    JB     @NotPIA
    CMP    BX,400h
    JAE    @NotPIA
    AND    BX,284h
@NotPIA:
    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    TEST   CH,8
    JNZ    @BCD
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    SBB    CL,0
{    PUSHF}
    OR     CH,3
    CMP    BX,80h
    JAE    @NotCrit
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

{    POPF}
    SUB    CL,BYTE PTR Input_Byte[BX + _Base]
    PUSHF
    JNC    @L2a              { Note the difference! }
    AND    CH,0FEh
  @L2a:
    OR     CH,40h
    POPF
    JO     @L4a
    AND    CH,0BFh
  @L4a:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit:
{    POPF}
    SUB    CL,BYTE PTR [BX]
    PUSHF
    JNC    @L2               { Note the difference! }
    AND    CH,0FEh
  @L2:
    OR     CH,40h
    POPF
    JO     @L4
    AND    CH,0BFh
  @L4:
    OR     CL,CL
    JZ     @L1
    AND    CH,7Dh
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    AND    CH,7Fh
    ADD    DI,3
    JMP    EmulateLoop
  @BCD:
{    INC    WORD PTR AddCycle[_Base]}

    PUSH   AX
    MOV    AL,CL
    MOV    DL,CH
    XOR    DL,1
    DB     0C0h,0EAh,1       { SHR   DL,imm8 is only 2 cycles on 486 }
    PUSHF
    CMP    BX,80h
    JAE    @NotCrit1
    AND    BX,0Fh

    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    CALL   Handle_TIA
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX

    POPF
    SBB    AL,BYTE PTR Input_Byte[BX + _Base]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6a              { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6a:
    JNO    @L7a
    OR     CH,40h
  @L7a:
    OR     CL,CL
    JNZ    @L8a
    OR     CH,2
  @L8a:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
@NotCrit1:
    POPF
    SBB    AL,BYTE PTR [BX]
    DAS
    MOV    CL,AL
    POP    AX
    PUSHF
    AND    CH,03Ch
    POPF
    JC     @L6               { Note the difference! }
    PUSHF
    OR     CH,1
    POPF
  @L6:
    JNO    @L7
    OR     CH,40h
  @L7:
    OR     CL,CL
    JNZ    @L8
    OR     CH,2
  @L8:
    MOV    DL,CL
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LFE:                 { INC abs. x }

  Asm
    MOV    BX,WORD PTR [DI+1]
    ADD    BL,AL
    ADC    BH,0
    AND    BX,1FFFh          { Atari can only address 8K }

    CMP    BX,200h
    JAE    @NotStack
    SUB    BH,BH
@NotStack:

    TEST   BYTE PTR BankSwitch[BX + _Base],0FFh
    JZ     @NoSwitch
    CALL   SwitchBank
@NoSwitch:

    AND    CH,7Dh
    CMP    BX,80h
    JAE    @NotTIA
    AND    BX,3Fh
@NotTIA:
    INC    BYTE PTR [BX]
    PUSHF
    TEST   BX,0FC00h
    JNZ    @NotCrit
    PUSH   AX
    PUSH   BX
    PUSH   CX
    PUSH   DX
    PUSH   DI
    MOV    WORD PTR Save_BX[_Base],BX
    CALL   Handle_IO
    POP    DI
    POP    DX
    POP    CX
    POP    BX
    POP    AX
@NotCrit:
    POPF
    JZ     @L1
    MOV    DL,BYTE PTR [BX]
    AND    DL,80h
    ADD    CH,DL
    ADD    DI,3
    JMP    EmulateLoop
  @L1:
    OR     CH,02h
    ADD    DI,3
    JMP    EmulateLoop
  End; { Asm }

LFF:                 { Nothing }

  Asm
    DB    _32BIT_OPERAND
    MOV   SI,WORD PTR AtariSeg[_Base]

    MOV   DS,WORD PTR Save_DS
    MOV   BYTE PTR X,AL
    MOV   BYTE PTR Y,AH
    MOV   BYTE PTR A,CL
    MOV   BYTE PTR P,CH
    MOV   BYTE PTR S,DH
    MOV   WORD PTR Start,DI

    DB    _32BIT_OPERAND
    MOV   WORD PTR AtariSeg,SI
  End; { Asm }
  Move(AtariSeg^[_Base],Mem[DSeg:0],AtariSegSize - _Base{Ofs(Executed)});
  _P     := P;
  _A     := A;
  _X     := X;
  _Y     := Y;
  _S     := S;
  _Start := Start;
End; { Interpret }

(*
Procedure Test;
Var
  I,J,K,L,M                      : Word;
  Iterations                     : Word;
  RR,T,UU,V                      : Real;
  A,X,Y,P,S                      : Byte;
  Clock                          : Boolean;
  Clock_Ticks                    : Integer;
  Number_Bytes                   : Integer;
  Work_Byte                      : Array[1..100] Of Byte;

Begin
  Write('How many bytes for test opcode: ');
  ReadLn(Number_Bytes);
  Write('How many normal clock ticks per iteration: ');
  ReadLn(Clock_Ticks);
  For I := 1 To Number_Bytes Do
  Begin
    Write('Enter test opcode #',I,': ');
    ReadLn(Work_Byte[I]);
  End;
  Iterations := 65530 Div Number_Bytes;
  WriteLn(Iterations,' iterations x ',Passes,' passes.');
  For I := 0 To Iterations - 1 Do
  Begin
    J := I * Number_Bytes;
    If (I And $F) = 0 Then
    Begin
      GotoXY(37,12);
      Write(J);
    End;
    For K := 1 To Number_Bytes Do
     Mem[Lo_Seg:J + K - 1] := Work_Byte[K];
  End; { For I }
  WriteLn;
{  FillChar(C64LoSeg^,-4,Chr(Work_Byte));} { Fill with 10000 NOP's for time test }
  I := Iterations * Number_Bytes;
  Mem[Lo_Seg:I] := $FF;
  MemW[Lo_Seg:I + 1] := $4350;
  WriteLn('Speed check...');

  Clock := True;   { I am shutting off the clock to achieve speed }

  P := 0;          { set up registers }
  X := 0;
  Y := 0;
  S := 0;
  A := 0;

{  InLine($FA);}                     { CLI }
  RR := Timer;
{  For I := 1 To Passes Do Interpret(0,0,0,0,0,0);}   { (0,P,A,X,Y,S) }

{ ------------------------------------------------------------------------- }

  FillChar(AtariSeg^,SizeOf(AtariSeg^),0);  { Blank area with nulls again }

{ ------------------------------------------------------------------------- }

  UU := Timer;
{  InLine($FB);}                     { STI }

  T := (UU - RR) / (Passes + 1);     { To account for call and loop, }
                                     { add 1 for every 50 passes }
  WriteLn;
  If Clock Then
  Begin
    V := (Clock_Ticks * Iterations) / T;
    Work_Real := (V / 1022727.0) * 100;
    WriteLn('Effective clock speed is ',V:10:2,' Hz.');
    WriteLn('Commodore 64 runs at     1022727    Hz.');
    WriteLn('You are runnning at ',Work_Real:6:2,'% of true speed.');
    WriteLn;
    WriteLn('Elapsed time is ',(UU - RR):6:2,' seconds.');
  End
  Else WriteLn('Clock was shut off.  Rate incalculable.');
  WriteLn;
  { each NOP is 2 clock cycles, so it is 20000 / time taken }
  FillChar(AtariSeg^,SizeOf(AtariSeg^),0);  { Blank area with nulls }
End; { Test }
*)

Procedure Emulate;
Type
  RGB = Record
    R,G,B: Byte;
  End;

Var
  F         : File;
{  TextFile  : Text;}
  Pal       : Array[0..127] Of RGB;
  I,J       : Word;
  St        : String[80];
  St1       : String[80];
  Start     : Word;
  T1,T2     : Real;
  P,A,X,Y,S : Byte;
  Buffer    : Pointer;
  Loaded    : LongInt;
  FP        : LongInt;
  WorkCh    : Char;
  Blaster   : String;

  Procedure Disassemble;
  Var
    I,J     : Word;
    Start   : Word;
    Listing : Text;
    Opcode  : Byte;
    DBStart : Word;
    B       : Byte;
    OTyp    : String[3];

    Function TransWordWrite(Addr: Word): String;
    Begin
      If Addr < $80 Then Addr := Addr And $3F;
      Case Addr Of
        0..$2C: TransWordWrite := TIA_Name[Addr];
    $280..$297: TransWordWrite := PIA_Name[Addr];
    $380..$397: TransWordWrite := PIA_Name[Addr - $100];
      Else TransWordWrite := HexWord(Addr);
      End; { Case }
    End; { TransWordWrite }


    Function TransWordRead(Addr: Word): String;
    Begin
      Case Addr Of
        0..$7F: TransWordRead := TIA_Read_Name[Addr And $F];
    $280..$297: TransWordRead := PIA_Name[Addr];
    $380..$397: TransWordRead := PIA_Name[Addr - $100];
      Else TransWordRead := HexWord(Addr);
      End; { Case }
    End; { TransWordRead }


    Function TransByteRead(Addr: Word): String;
    Begin
      Case Addr Of
        0..$7F: TransByteRead := TIA_Read_Name[Addr And $F];
    $280..$297: TransByteRead := PIA_Name[Addr];
    $380..$397: TransByteRead := PIA_Name[Addr - $100];
       Else TransByteRead := HexByte(Addr);
       End; { Case }

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
    End; { TransByteRead }


    Function TransByteWrite(Addr: Word): String;
    Begin
      If Addr < $80 Then Addr := Addr And $3F;
      Case Addr Of
        0..$2C: TransByteWrite := TIA_Name[Addr];
      Else TransByteWrite := HexByte(Addr);
      End; { Case }
    End; { TransByteWrite }


    Function TransWord(Addr: Word): String;
    Var Instr: String[3];
    Begin
      Instr := Mnem[Opcode];
      If (Addr < $80) And (Copy(Instr,1,2) = 'RO')
       Then TransWord := TransWordRead(Addr)
       Else
        If (Instr           = 'ADC') Or
           (Instr           = 'DEC') Or
           (Instr           = 'INC') Or
           (Instr           = 'SBC') Or
           (Copy(Instr,1,2) = 'PH')  Or
           (Copy(Instr,1,2) = 'RO')  Or
           (Copy(Instr,1,2) = 'ST')
         Then TransWord := TransWordWrite(Addr)
         Else TransWord := TransWordRead(Addr);
    End; { TransWord }


    Function TransByte(Addr: Word): String;
    Var Instr: String[3];
    Begin
      Instr := Mnem[Opcode];
      If (Addr < $80) And (Copy(Instr,1,2) = 'RO')
       Then TransByte := TransByteRead(Addr)
       Else
        If (Instr           = 'ADC') Or
           (Instr           = 'DEC') Or
           (Instr           = 'INC') Or
           (Instr           = 'SBC') Or
           (Copy(Instr,1,2) = 'PH')  Or
           (Copy(Instr,1,2) = 'RO')  Or
           (Copy(Instr,1,2) = 'ST')
         Then TransByte := TransByteWrite(Addr)
         Else TransByte := TransByteRead(Addr);
    End; { TransByte }

  Begin
    FillChar(Executed,SizeOf(Executed),#0);
    FillChar(Branched,SizeOf(Branched),#0);
    Start := MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + $1FFC] And $1FFF;
    Branched[Start] := True;
    Unassemble(Start);

    { Output listing }

    Assign(Listing,'LISTING.ASM');
    Rewrite(Listing);
    WriteLn(Listing,'; Listing for ',ParamStr(1));
    WriteLn(Listing);

    I       := $1000;
    DBStart := 0;
    While I <= $1FFF Do
    Begin
      Opcode := AtariSeg^[I];

{      Write(HexWord(I),' ');}

      If Not Executed[I] Then
      Begin

        { Tally the byte }

        If DBStart = 0 Then DBStart := I;
        Inc(I);
      End
      Else
      Begin

        { Output any accumulated data }

        If DBStart <> 0 Then
        Begin
          For J := DBStart To I - 1 Do
          Begin
            If ((J - DBStart) And $7) = 0 Then Write(Listing,HexWord(J),'            DB    ');
            Write(Listing,HexByte(AtariSeg^[J]),'h');
            If (J < I - 1) And (((J - DBStart) And $7) <> $7) Then Write(Listing,',');
            If (J < I - 1) And (((J - DBStart) And $7) =  $7) Then WriteLn(Listing);
          End;
          WriteLn(Listing);
          DBStart := 0;
        End;

        { Output the instruction }

        If Branched[I]
         Then Write(Listing,HexWord(I),'  ')
         Else Write(Listing,'      ');
        For J := 1 To 5 Do
         If Bytes[Opcode] >= J
          Then Write(Listing,HexByte(AtariSeg^[I + J - 1]))
          Else Write(Listing,'  ');
        Write(Listing,Mnem[Opcode]);
        OTyp := ATyp[Opcode];
        If OTyp = 'ABS' Then Write(Listing,'   ',TransWord(MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + I + 1] And $1FFF));
        If OTyp = 'A.X' Then Write(Listing,'   ',TransWord(MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + I + 1] And $1FFF),',X');
        If OTyp = 'A.Y' Then Write(Listing,'   ',TransWord(MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + I + 1] And $1FFF),',Y');
        If OTyp = 'ASY' Then Write(Listing,'   (',TransWord(MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + I + 1] And $1FFF),',Y) & S');
        If OTyp = 'IND' Then Write(Listing,'   (',HexWord(MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + I + 1] And $1FFF),')');
        If OTyp = 'I.X' Then Write(Listing,'   (',HexByte(AtariSeg^[I + 1]),',X)');
        If OTyp = 'I.Y' Then Write(Listing,'   (',HexByte(AtariSeg^[I + 1]),'),Y');
        If OTyp = 'ACC' Then Write(Listing,'   A');
        If OTyp = 'IMM' Then Write(Listing,'   #',HexByte(AtariSeg^[I + 1]));
        If OTyp = 'Z.P' Then Write(Listing,'   ',TransByte(AtariSeg^[I + 1]));
        If OTyp = 'Z.X' Then Write(Listing,'   ',TransByte(AtariSeg^[I + 1]),',X');
        If OTyp = 'Z.Y' Then Write(Listing,'   ',TransByte(AtariSeg^[I + 1]),',Y');
        If OTyp = 'I+A' Then Write(Listing,'   #',HexByte(AtariSeg^[I + 1]),' + A');
        If OTyp = 'REL' Then
        Begin
          B := AtariSeg^[I + 1];
          Asm
            MOV   BX,WORD PTR I
            ADD   BX,2
            MOV   AL,BYTE PTR B
            CBW
            ADD   BX,AX
            MOV   WORD PTR J,BX
          End; { Asm }
          Write(Listing,'   ',HexWord(J));
        End;
        WriteLn(Listing);
        Inc(I,Bytes[Opcode]);
      End;
    End; { While }

    { Output any accumulated data }

    If DBStart <> 0 Then
    Begin
      For J := DBStart To I - 1 Do
      Begin
        If ((J - DBStart) And $7) = 0 Then Write(Listing,HexWord(J),'            DB    ');
        Write(Listing,HexByte(AtariSeg^[J]),'h');
        If (J < I - 1) And (((J - DBStart) And $7) <> $7) Then Write(Listing,',');
        If (J < I - 1) And (((J - DBStart) And $7) =  $7) Then WriteLn(Listing);
      End;
      WriteLn(Listing);
      DBStart := 0;
    End;
    Close(Listing);
  End; { Disassemble }

  Procedure InitSound;
  Var I,J,FP: LongInt;
  Begin
    TIA_Sound_Init(Sample_Freq,Playback_Freq);
    GetMem(SoundBuf[0],SoundBufSize * 2);
    GetMem(SoundBuf[1],SoundBufSize);
    PhysAddr0 := SegOffToPhys(SoundBuf[0]);
    PhysAddr1 := SegOffToPhys(Ptr(Seg(SoundBuf[0]^),Ofs(SoundBuf[0]^) + SoundBufSize));
    FillChar(SoundBuf[0]^,SoundBufSize * 2,#0);
    FillChar(SoundBuf[1]^,SoundBufSize,#0);
    If XMS.Init Then
    Begin
      DoSound := False;
      Exit;
    End;
    If XMS.GetFreeXM(TotalFree,LargestFree) Then
    Begin
      DoSound := False;
      Exit;
    End;
    If Handle.AllocXM(32 * 16 * 4) Then
    Begin
      DoSound := False;
      Exit;
    End;
    LockXMS := Not Handle.LockXM(PhysAddr);
    Update_TIA_Sound(AUDV0,15);
    For I := 0 To 15 Do
    Begin
      Update_TIA_Sound(AUDC0,I);
      For J := 0 To 31 Do
      Begin
        Update_TIA_Sound(AUDF0,J);
        ProcessSound(SoundBuf[0],SoundBufSize);
{        TIA_Process1(SoundBuf[0],SoundBufSize);}
        FP := (I * 32 + J) * SoundBufSize;
        If LockXMS Then XMS.RawMove(PhysAddr + FP,SegOffToPhys(SoundBuf[0]),Even(SoundBufSize)) Else
        Begin
          MovePacket.Length     := SoundBufSize;
          MovePacket.srcHandle  := 0;
          MovePacket.srcOffset  := DWord(SoundBuf[0]);
          MovePacket.destHandle := Handle.Handle;
          MovePacket.destOffset := FP;
          XMS.MoveXM(MovePacket);
        End;
      End; { For J }
    End; { For I }
    Update_TIA_Sound(AUDV0,0);
    Update_TIA_Sound(AUDC0,0);
    Update_TIA_Sound(AUDF0,0);
    FillChar(SoundBuf[0]^,SoundBufSize * 2,#0);
    FillChar(SoundBuf[1]^,SoundBufSize,#0);
  End; { InitSound }

  Function Menu: String;
  Type
    PFileListType = ^TFileListType;
    TFileListType = Record
      Name : String[12];
      Size : LongInt;
      Next : PFileListType;
      Prev : PFileListType;
    End;

  Var
    I       : Word;
    Head    : PFileListType;
    Tail    : PFileListType;
    Work    : PFileListType;
    Work1   : PFileListType;
    Temp    : TFileListType;
    S       : SearchRec;
    Ch,C    : Char;
    MaxX    : Integer;
    MaxY    : Integer;
    Cols    : Integer;
    Rows    : Integer;
    Num     : Integer;
    Show    : Boolean;
    J       : Integer;
    JoyX1   : Word;
    JoyY1   : Word;
    JoyX2   : Word;
    JoyY2   : Word;
    CJoyX   : Word;
    CJoyY   : Word;
    JoyX1_2 : Word;
    JoyY1_2 : Word;
    JoyX2_2 : Word;
    JoyY2_2 : Word;
    JoyB    : Byte;
    F       : File;
    Path    : String[79];

    Procedure Display;
    Var
      I,J : Integer;
      W   : PFileListType;
      St  : String;
      Row : Integer;
      Col : Integer;

      Procedure FastWrite(X,Y: Integer; Color: Byte; Var S: String);
      Var Addr: Word;
      Begin
        Addr := ((Y - 1) * MaxX + X - 1) * 2;
        Asm
          CLI
          CLD
          MOV   AX,0B800h
          MOV   ES,AX
          MOV   DI,WORD PTR Addr
          MOV   AH,BYTE PTR Color
          PUSH  DS
          LDS   SI,DWORD PTR S
          MOV   CL,BYTE PTR [SI]
          SUB   CH,CH
          INC   SI
  @L1:
          LODSB
          STOSW
          LOOP  @L1
          POP   DS
          STI
        End; { Asm }
      End; { FastWrite }

    Begin
      I   := Rows * Cols;
      W   := Work1;
      Row := 1;
      Col := 1;
      While (W <> Nil) And (I <> 0) Do
      Begin
        If W = Work Then
        Begin
          TextColor(Black);
          TextBackGround(LightGray);
        End
        Else
        Begin
          Case W^.Size Of
  2048,4096:Begin
            TextColor(LightGray);
            TextBackGround(Blue);
          End; { Case }
    8192: Begin
            TextColor(White);
            TextBackGround(Blue);
          End;
    8448: Begin
            TextColor(LightRed);
            TextBackGround(Blue);
          End;
   16384: Begin
            TextColor(Yellow);
            TextBackGround(Blue);
          End;
          Else
            TextColor(Black);
            TextBackGround(Blue);
          End; { Case }
        End;
        St := W^.Name;
        J  := Pos('.',St);
        If J <> 0 Then
         While J < 9 Do
         Begin
           Insert(' ',St,J);
           Inc(J);
         End; { While }
        While Length(St) < 16 Do St := St + ' ';


  {        TextAttr := $1F;}


        FastWrite((Col - 1) * 16 + 1,Row + 1,TextAttr,St);
        Inc(Row);
        If (Row = Rows + 1) And (W^.Next <> Nil) And (I <> 1) Then
        Begin
          Row := 1;
          Inc(Col);
        End;
        Dec(I);
        W := W^.Next;
      End; { While }
      TextColor(LightGray);
      TextBackGround(Blue);
      While Row <= Rows Do
      Begin
        St := '                ';
        FastWrite((Col - 1) * 16 + 1,Row + 1,TextAttr,St);
        Inc(Row);
      End; { While }
      TextColor(Black);
      TextBackGround(LightGray);
      GotoXY(1,1);
      ClrEol;
      GotoXY(1,MaxY);
      ClrEol;

      St := 'PCAE ' + Version;
      FastWrite(2,1,TextAttr,St);
      St := Work^.Name;
      FastWrite(22,1,TextAttr,St);
      Str(Work^.Size,St);
      FastWrite(40,1,TextAttr,St);
      St := 'F1=Help    Esc=Quit';
      FastWrite(60,1,TextAttr,St);
      Str(Num,St);
      St := St + ' Files';
      FastWrite(2,MaxY,TextAttr,St);
      St := 'F/S/J/K/B/I/V/Z <P>arker Bros. <A>ctiVision <M>Network Supe<R>chip';
      FastWrite(15,MaxY,TextAttr,St);
    End; { Display }

    Procedure FindTop;
    Var I: Integer;
    Begin
      I     := Top;
      Work1 := Head;
      While (Work1 <> Nil) And (I > 0) Do
      Begin
        Work1 := Work1^.Next;
        Dec(I);
      End; { While }
    End;

    Procedure FindSel;
    Var I: Integer;
    Begin
      I     := Sel;
      Work  := Head;
      While (Work <> Nil) And (I > 0) Do
      Begin
        Work := Work^.Next;
        Dec(I);
      End; { While }
    End; { FindSel }

    Procedure _Up;
    Begin
      If Sel > 0 Then
      Begin
        If Sel = Top Then
        Begin
          Dec(Top);
          Work1 := Work^.Prev;
        End;
        Dec(Sel);
        Work := Work^.Prev;
        Show := True;
      End;
    End; { _Up }

    Procedure _Down;
    Begin
      If Sel < Num - 1 Then
      Begin
        If Sel = Top + Cols * Rows - 1 Then
        Begin
          Inc(Top);
          Work1 := Work1^.Next;
        End;
        Inc(Sel);
        Work := Work^.Next;
        Show := True;
      End;
    End; { _Down }

    Procedure _Left;
    Begin
      If Sel >= Rows Then
      Begin
        Show := True;
        Dec(Sel,Rows);
        If Sel < Top Then Dec(Top,Rows);
        If Top < 0 Then Top := 0;
        FindTop;
        FindSel;
      End;
    End; { _Left }

    Procedure _Right;
    Begin
      If Sel < Num - Rows Then
      Begin
        Show := True;
        Inc(Sel,Rows);
        If Sel >= Top + Cols * Rows Then Inc(Top,Rows);
        FindTop;
        FindSel;
      End;
    End; { _Right }

    Procedure Popup(St: String);
    Var I,J,X,Y: Integer;
    Begin
      TextColor(Black);
      TextBackground(LightGray);
      I := Length(St);
      X := (MaxX Div 2) - ((I + 4) Div 2);
      Y := MaxY Div 2;
      GotoXY(X,Y);
      Write('É');
      J := I + 2;
      While J > 0 Do
      Begin
        Write('Í');
        Dec(J);
      End; { While }
      Write('»');
      GotoXY(X,Y + 1);
      Write('º ' + St + ' º');
      GotoXY(X,Y + 2);
      Write('È');
      J := I + 2;
      While J > 0 Do
      Begin
        Write('Í');
        Dec(J);
      End; { While }
      Write('¼');
      Sound(880);
      Delay(10);
      NoSound;
      Delay(1000);
      TextColor(LightGray);
      TextBackGround(Blue);
      ClrScr;
      Show := True;
    End; { Popup }

  Begin
    TextColor(LightGray);
    TextBackGround(Blue);
    ClrScr;

    { Locate all the .BIN files }

    Head := Nil;
    Tail := Nil;
    Num  := 0;
    If ParamCount > 0 Then
    Begin
      Path := ParamStr(1);
      If (Path <> '') And Not (Path[Length(Path)] In [':','\']) Then Path := Path + '\';
    End
    Else Path := '';
    FindFirst(Path + '*.BIN',Archive,S);
    While DosError = 0 Do
    Begin
      If Head = Nil Then
      Begin
        New(Head);
        Tail := Head;
        Tail^.Prev := Nil;
      End
      Else
      Begin
        New(Tail^.Next);
        Tail^.Next^.Prev := Tail;
        Tail := Tail^.Next;
      End;
      Inc(Num);
      Tail^.Name := S.Name;
      Tail^.Size := S.Size;
      Tail^.Next := Nil;
      FindNext(S);
    End; { While }

    { Sort the list in ascending alphabetical order }

    Work := Head;
    While Work <> Nil Do
    Begin
      Work1 := Work^.Next;
      While Work1 <> Nil Do
      Begin
        If Work1^.Name < Work^.Name Then
        Begin
          Temp.Name   := Work1^.Name;
          Temp.Size   := Work1^.Size;
          Work1^.Name := Work^.Name;
          Work1^.Size := Work^.Size;
          Work^.Name  := Temp.Name;
          Work^.Size  := Temp.Size;
        End;
        Work1 := Work1^.Next;
      End; { Work1 }
      Work := Work^.Next;
    End; { While }

    { Main loop }

    If Head = Nil Then
    Begin
      Menu := '';
      Exit;
    End;
    FindTop;
    FindSel;
    MaxX  := Mem[$0:$44A];         { Max screen columns }
    MaxY  := Mem[$0:$484] + 1;     { Max screen rows    }
    If MaxY = 1 Then MaxY := 25;
    Cols  := MaxX Div 16;
    Rows  := MaxY - 2;
    Show  := True;
    Repeat
      If Show Then
      Begin
        Display;
        Show := False;
      End;
      Ch := #0;
      If Config.UseJoystick1 Then
      Begin
        Asm
          CALL  JoyStatus
          MOV   BYTE PTR JoyB,BL
          MOV   WORD PTR JoyX1,CX
          MOV   WORD PTR JoyY1,DX
        End; { Asm }
        If JoyY1 < JoyMinY Then
        Begin
          _Up;
          Delay(30);
        End;
        If JoyY1 > JoyMaxY Then
        Begin
          _Down;
          Delay(30);
        End;
        If JoyX1 < JoyMinX Then
        Begin
          _Left;
          Delay(30);
        End;
        If JoyX1 > JoyMaxX Then
        Begin
          _Right;
          Delay(30);
        End;
        If (JoyB And 1) <> 0 Then
        Begin
          Ch := #13;

          { Wait until button is released }

          Repeat
            Asm
              CALL  JoyStatus
              MOV   BYTE PTR JoyB,BL
              MOV   WORD PTR JoyX1,CX
              MOV   WORD PTR JoyY1,DX
            End; { Asm }
          Until (JoyB And 1) = 0;
        End;
      End;
      If KeyPressed Then
      Begin
        Ch := UpCase(ReadKey);
        If Ch = #0 Then
        Begin
          C := ReadKey;
          Case C Of
            #59: Begin                     { F1 }
                   TextColor(LightGray);
                   TextBackGround(Blue);
                   ClrScr;
                   GotoXY(3,1);  Write('Configuration options');

                   GotoXY(5,3);  Write('D ................................ Toggle integrated debugger');
                   GotoXY(5,4);  Write('J ................................ Calibrate and use joystick');
                   GotoXY(5,5);  Write('K ................................ Use keyboard only');
                   GotoXY(5,6);  Write('S ................................ Toggle sound');
                   GotoXY(5,7);  Write('F ................................ Set emulation frames-per-second limit');
                   GotoXY(5,8);  Write('B ................................ Toggle Atari keyboard controllers');
                   GotoXY(5,9);  Write('I ................................ Toggle Indy 500 controllers');
                   GotoXY(5,10); Write('V ................................ Toggle Video Touch Pad');
                   GotoXY(5,11); Write('Z ................................ Adjust sound buffer size/quality');
                   GotoXY(3,13); Write('Run options');
                   GotoXY(5,14); Write('<Esc> ............................ Quit');
                   GotoXY(5,15); Write('Arrow keys or Joystick ........... Move selection');
                   GotoXY(5,16); Write('<Enter> or Joystick button 1 ..... Run 2K/4K/Atari 8K/Atari 16K cart');
                   GotoXY(5,17); Write('A ................................ Run Activision 16K cart');
                   GotoXY(5,18); Write('M ................................ Run M-Network 8K RAM cart');
                   GotoXY(5,19); Write('P ................................ Run Parker Bros. 8K cart');
                   GotoXY(5,20); Write('R ................................ Run Atari super-chip cart');
                   GotoXY(3,21); Write('Game options');
                   GotoXY(5,22); Write('F2 ............................... Reset game');
                   GotoXY(5,23); Write('F4 ............................... Select game');
                   GotoXY(5,24); Write('F5 ............................... Color/BW switch');
                   GotoXY(5,25); Write('F6/F7 ............................ Player 1/2 difficulty');
                   ReadKey;
                   ClrScr;
                   GotoXY(3,1);  Write('Command-line options');

                   GotoXY(2,3);  Write('Use: ATARI filename [BANK|BANK16|BANKA|BANKM|BANKP|BANKC|BANKSC|BANKSP][DEBUG]');
                   GotoXY(2,4);  Write('                    [DISASM][FRAMExx][KB][INDY500][VTP]');
                   GotoXY(5,5);  Write('BANK ............................. Run Atari 8K cart');
                   GotoXY(5,6);  Write('BANK16 ........................... Run Atari 16K cart');
                   GotoXY(5,7);  Write('BANKA ............................ Run Activision 16K cart');
                   GotoXY(5,8);  Write('BANKM ............................ Run M-Network 8K RAM cart');
                   GotoXY(5,9);  Write('BANKP ............................ Run Parker Bros. 8K cart');
                   GotoXY(5,10); Write('BANKC ............................ Run CBS RAM-Plus 12K cart');
                   GotoXY(5,11); Write('BANKSC ........................... Run Atari super-chip cart');
                   GotoXY(5,12); Write('BANKSP ........................... Run Starpath Supercharger cart');
                   GotoXY(5,13); Write('DEBUG ............................ Use intregrated debugger');
                   GotoXY(5,14); Write('DISASM ........................... Disassemble 4k cart to LISTING.ASM');
                   GotoXY(5,15); Write('FRAMExx .......................... Limit emulation to xx frames/second');
                   GotoXY(5,16); Write('KB ............................... Run Atari keyboard controller game');
                   GotoXY(5,17); Write('INDY500 .......................... Emulate Indy 500 controllers');
                   GotoXY(5,18); Write('VTP .............................. Emulate Video Touch Pad');
{                   GotoXY(3,19); Write('Integrated debugger options');
                   GotoXY(5,20); Write('<Space> .......................... Display game screen');
                   GotoXY(5,21); Write('Arrow keys ....................... Scroll instruction display');
                   GotoXY(5,22); Write('G ................................ Execute until <Esc> pressed');
                   GotoXY(5,23); Write('H ................................ Execute until selected instruction');
                   GotoXY(5,24); Write('S ................................ Skip over next instruction');
                   GotoXY(5,25); Write('T ................................ Trace to next instruction');}

                   ReadKey;
                   TextColor(LightGray);
                   TextBackGround(Blue);
                   ClrScr;
                   Show := True;
                 End;
            #71: Begin                     { Home }
                   If Sel <> 0 Then Show := True;
                   Top   := 0;
                   Sel   := 0;
                   Work1 := Head;
                   Work  := Head;
                 End;
            #72: _Up;                      { Up }
            #73: Begin                     { PgUp }
                   If Sel >= Cols * Rows Then
                   Begin
                     TextColor(LightGray);
                     TextBackGround(Blue);
                     ClrScr;
                     Show := True;
                     Dec(Sel,Cols * Rows);
                     Dec(Top,Cols * Rows);
                     If Top < 0 Then Top := 0;
                     FindTop;
                     FindSel;
                   End;
                 End;
            #75: _Left;                    { Left }
            #77: _Right;                   { Right }
            #79: Begin                     { End }
                   If Sel <> Num - 1 Then Show := True;
                   Sel := Num - 1;
                   I   := Top;
                   Top := Sel - Cols * Rows + 1;
                   If Top < 0 Then Top := 0;
                   If I <> Top Then Show := True;
                   Work  := Tail;
                   FindTop;
                 End;
            #80: _Down;                    { Down }
            #81: Begin                     { PgDn }
                   If Sel < Num - Cols * Rows Then
                   Begin
                     TextColor(LightGray);
                     TextBackGround(Blue);
                     ClrScr;
                     Show := True;
                     Inc(Sel,Cols * Rows);
                     Inc(Top,Cols * Rows);
                     FindTop;
                     FindSel;
                   End;
                 End;
          End; { Case }
        End;
        If Ch = 'Z' Then
        Begin
          ClrScr;

          Handle.UnlockXM;
          Handle.FreeXM;
          FreeMem(SoundBuf[1],SoundBufSize);
          FreeMem(SoundBuf[0],SoundBufSize * 2);

          WriteLn('Sound buffer size adjustment');
          WriteLn('(larger buffer sizes might give better sound quality, but require more');
          WriteLn(' processing power)');
          WriteLn;
          Write('Buffer size (256-10000) [',SoundBufSize,']: ');
          ReadLn(I);
          If (I >= 256) And (I <= 10000) Then
          Begin
            SoundBufSize := I And $FFFC;
            Config.SoundBufSize := SoundBufSize;
            Assign(F,ConfigFile);
            ReWrite(F,1);
            BlockWrite(F,Config,SizeOf(Config));
            Close(F);
          End;
          InitSound;
          TextColor(LightGray);
          TextBackGround(Blue);
          ClrScr;
          Show := True;
        End;
        If Ch = 'F' Then
        Begin
          ClrScr;
          Write('Enter frames-per-second limit (or 0 for no limit): ');
          ReadLn(Config.FrameRate);
          If Config.FrameRate < 0 Then Config.FrameRate := 0;
          Assign(F,ConfigFile);
          ReWrite(F,1);
          BlockWrite(F,Config,SizeOf(Config));
          Close(F);
          TextColor(LightGray);
          TextBackGround(Blue);
          ClrScr;
          Show := True;
        End;
        If Ch = 'J' Then
        Begin
          ClrScr;
          WriteLn('Move joystick 1 to upper left and press any key, or <Esc> to exit:');
          Repeat
            Asm
              CALL  JoyStatus
              MOV   BYTE PTR JoyB,BL
              MOV   WORD PTR JoyX1,CX
              MOV   WORD PTR JoyY1,DX
            End; { Asm }
          Until KeyPressed;
          C := ReadKey;
          If C <> #27 Then
          Begin
            WriteLn('Center joystick 1 and press any key, or <Esc> to exit:');
            Repeat
              Asm
                CALL  JoyStatus
                MOV   BYTE PTR JoyB,BL
                MOV   WORD PTR CJoyX,CX
                MOV   WORD PTR CJoyY,DX
              End; { Asm }
            Until KeyPressed;
            C := ReadKey;
            If C <> #27 Then
            Begin
              WriteLn('Move joystick 1 to lower right and press any key, or <Esc> to exit:');
              Repeat
                Asm
                  CALL  JoyStatus
                  MOV   BYTE PTR JoyB,BL
                  MOV   WORD PTR JoyX2,CX
                  MOV   WORD PTR JoyY2,DX
                End; { Asm }
              Until KeyPressed;
              C := ReadKey;
              If C <> #27 Then
              Begin
                If (JoyX1 < JoyX2) And (JoyY1 < JoyY2) Then
                Begin
                  Config.UseJoystick1 := True;
                  Config.MinJoyX      := JoyX1;
                  Config.MinJoyY      := JoyY1;
                  Config.MaxJoyX      := JoyX2;
                  Config.MaxJoyY      := JoyY2;
                  Config.JoyCenterX   := CJoyX;
                  Config.JoyCenterY   := CJoyY;
                  Assign(F,ConfigFile);
                  ReWrite(F,1);
                  BlockWrite(F,Config,SizeOf(Config));
                  Close(F);
                  JoyCenterX := CJoyX;
                  JoyCenterY := CJoyY;
                  JoyMinX    := (JoyCenterX + JoyX1) Div 2;
                  JoyMinY    := (JoyCenterY + JoyY1) Div 2;
                  JoyMaxX    := (JoyCenterX + JoyX2) Div 2;
                  JoyMaxY    := (JoyCenterY + JoyY2) Div 2;

                  WriteLn('Move joystick 2 to upper left and press any key, or <Esc> to exit:');
                  Repeat
                    Asm
                      CALL  JoyStatus
                      MOV   BYTE PTR JoyB,BL
                      MOV   WORD PTR JoyX1_2,SI
                      MOV   WORD PTR JoyY1_2,DI
                    End; { Asm }
                  Until KeyPressed;
                  C := ReadKey;
                  If C <> #27 Then
                  Begin
                    WriteLn('Center joystick 2 and press any key, or <Esc> to exit:');
                    Repeat
                      Asm
                        CALL  JoyStatus
                        MOV   BYTE PTR JoyB,BL
                        MOV   WORD PTR CJoyX,SI
                        MOV   WORD PTR CJoyY,DI
                      End; { Asm }
                    Until KeyPressed;
                    C := ReadKey;
                    If C <> #27 Then
                    Begin
                      WriteLn('Move joystick 2 to lower right and press any key, or <Esc> to exit:');
                      Repeat
                        Asm
                          CALL  JoyStatus
                          MOV   BYTE PTR JoyB,BL
                          MOV   WORD PTR JoyX2_2,SI
                          MOV   WORD PTR JoyY2_2,DI
                        End; { Asm }
                      Until KeyPressed;
                      C := ReadKey;
                      If C <> #27 Then
                      Begin
                        If (JoyX1_2 < JoyX2_2) And (JoyY1_2 < JoyY2_2) Then
                        Begin
                          Config.UseJoystick2 := True;
                          Config.MinJoyX2     := JoyX1_2;
                          Config.MinJoyY2     := JoyY1_2;
                          Config.MaxJoyX2     := JoyX2_2;
                          Config.MaxJoyY2     := JoyY2_2;
                          Config.JoyCenterX2  := CJoyX;
                          Config.JoyCenterY2  := CJoyY;
                          Assign(F,ConfigFile);
                          ReWrite(F,1);
                          BlockWrite(F,Config,SizeOf(Config));
                          Close(F);
                          JoyCenterX2 := CJoyX;
                          JoyCenterY2 := CJoyY;
                          JoyMinX2    := (JoyCenterX2 + JoyX1_2) Div 2;
                          JoyMinY2    := (JoyCenterY2 + JoyY1_2) Div 2;
                          JoyMaxX2    := (JoyCenterX2 + JoyX2_2) Div 2;
                          JoyMaxY2    := (JoyCenterY2 + JoyY2_2) Div 2;
                        End
                        Else
                        Begin
                          WriteLn;
                          WriteLn('Error in calibration.  Press a key to return.');
                          ReadKey;
                          Config.UseJoystick2 := False;
                        End;
                      End;
                    End
                    Else
                    Begin
                      Config.UseJoystick2 := False;
                      Assign(F,ConfigFile);
                      ReWrite(F,1);
                      BlockWrite(F,Config,SizeOf(Config));
                      Close(F);
                    End;
                  End
                  Else
                  Begin
                    Config.UseJoystick2 := False;
                    Assign(F,ConfigFile);
                    ReWrite(F,1);
                    BlockWrite(F,Config,SizeOf(Config));
                    Close(F);
                  End;
                End
                Else
                Begin
                  WriteLn;
                  WriteLn('Error in calibration.  Press a key to return.');
                  ReadKey;
                  Config.UseJoystick1 := False;
                  Config.UseJoystick2 := False;
                  Assign(F,ConfigFile);
                  ReWrite(F,1);
                  BlockWrite(F,Config,SizeOf(Config));
                  Close(F);
                End;
              End
              Else
              Begin
                Config.UseJoystick1 := False;
                Config.UseJoystick2 := False;
                Assign(F,ConfigFile);
                ReWrite(F,1);
                BlockWrite(F,Config,SizeOf(Config));
                Close(F);
              End;
            End
            Else
            Begin
              Config.UseJoystick1 := False;
              Config.UseJoystick2 := False;
              Assign(F,ConfigFile);
              ReWrite(F,1);
              BlockWrite(F,Config,SizeOf(Config));
              Close(F);
            End;
          End
          Else
          Begin
            Config.UseJoystick1 := False;
            Config.UseJoystick2 := False;
            Assign(F,ConfigFile);
            ReWrite(F,1);
            BlockWrite(F,Config,SizeOf(Config));
            Close(F);
          End;
          TextColor(LightGray);
          TextBackGround(Blue);
          ClrScr;
          Show := True;
        End;
        If Ch In ['B','I','V'] Then
        Begin
          Case Ch Of
            'B': Begin
                   UseKBControllers := Not UseKBControllers;
                   If UseKBControllers
                    Then Popup('Keyboard controllers ACTIVE')
                    Else Popup('Keyboard controllers INACTIVE');
                 End;
            'I': Begin
                   UseIndy500 := Not UseIndy500;
                   If UseIndy500
                    Then Popup('Indy 500 controllers ACTIVE')
                    Else Popup('Indy 500 controllers INACTIVE');
                 End;
            'V': Begin
                   VideoTouchPad := Not VideoTouchPad;
                   If VideoTouchPad
                    Then Popup('Video Touch Pad ACTIVE')
                    Else Popup('Video Touch Pad INACTIVE');
                 End;
          End; { Case }
        End;
        If Ch = 'D' Then
        Begin
          Debugger := Not Debugger;
          If Debugger
           Then Popup('Debugger is ON')
           Else Popup('Debugger is OFF');
        End;
        If Ch = 'K' Then
        Begin
          Config.UseJoystick1 := False;
          Config.UseJoystick2 := False;
          Assign(F,ConfigFile);
          ReWrite(F,1);
          BlockWrite(F,Config,SizeOf(Config));
          Close(F);
          Popup('Switching to keyboard-only');
        End;
        If Ch = 'S' Then
        Begin
          Config.DoSound := Not Config.DoSound;
          DoSound        := Config.DoSound;
          Assign(F,ConfigFile);
          ReWrite(F,1);
          BlockWrite(F,Config,SizeOf(Config));
          Close(F);
          If DoSound
           Then Popup('Sound is ON')
           Else Popup('Sound is OFF');
        End;
      End;
    Until Ch In [#13,#27,'A','R','P','M'];
    If Ch In [#13,'A','R','P','M'] Then
    Begin
      UseMenu := True;
      Menu    := Path + Work^.Name;
      Case Ch Of
 'A': Begin
        BankSwitch[$01FE] := 17;
        Activision := True;
      End;
 'R': Begin
        BankSwitch[$1FF6] := 1  + $40;
        BankSwitch[$1FF7] := 5  + $40;
        BankSwitch[$1FF8] := 9  + $40;
        BankSwitch[$1FF9] := 13 + $40;
        For J := $1000 To $107F Do BankSwitch[J] := $50;
        BankSize := 1024 - 64{32};    { Size in dwords }
      End;
 'P': Begin
        For J := $1FE0 To $1FF7 Do BankSwitch[J] := J And $FF;
        ParkerBS := True;
      End;
 'M': Begin
        For J := $1FE0 To $1FE7 Do BankSwitch[J] := (J And $FF) - $10;
        MNetwork := True;
      End;
      Else
        If Work^.Size = 8192 Then
        Begin
          BankSwitch[$1FF8] := 1;
          BankSwitch[$1FF9] := 5;
        End;
        If Work^.Size = 8448 Then
        Begin
          For J := $1000 To $1FFF Do BankSwitch[J] := $70;
          BankSwitch[$1FF8] := $70;
          StarPath          := True;
        End;
        If Work^.Size = 12288 Then
        Begin
          BankSwitch[$1FF8] := $21;
          BankSwitch[$1FF9] := $25;
          BankSwitch[$1FFA] := $29;
          For J := $1000 To $10FF Do BankSwitch[J] := $30;
          BankSize := 1024 - 128{64};    { Size in dwords }
          CBS      := True;
        End;
        If Work^.Size = 16384 Then
        Begin
          BankSwitch[$1FF6] := 1;
          BankSwitch[$1FF7] := 5;
          BankSwitch[$1FF8] := 9;
          BankSwitch[$1FF9] := 13;
        End;
      End; { Case }
    End
    Else
    Begin
      Menu    := '';
      UseMenu := False;
    End;

    { Kill the file list }

    Work := Head;
    While Work <> Nil Do
    Begin
      Work1 := Work^.Next;
      Dispose(Work);
      Work := Work1;
    End; { While }
    TextColor(LightGray);
    TextBackGround(Black);
    ClrScr;
  End; { Menu }


  Procedure SetPalette;
  Var I: Integer;
  Begin
    Port[$3C8] := 0;
    For I := 0 To 127 Do
    Begin
      Port[$3C9] := Pal[I].B Shr 2;
      Port[$3C9] := Pal[I].G Shr 2;
      Port[$3C9] := Pal[I].R Shr 2;

      { Duplicate the colors here to avoid having to worry about bit 0 }

      Port[$3C9] := Pal[I].B Shr 2;
      Port[$3C9] := Pal[I].G Shr 2;
      Port[$3C9] := Pal[I].R Shr 2;
    End; { For I }
  End; { SetPalette }

Begin
  UseKBControllers := False;
  UseIndy500       := False;
  VideoTouchPad    := False;
  LockXMS          := False;
  MouseInit;
  If MouseVisible Then ToggleMouseVisibility;
  Top           := 0;
  Sel           := 0;

  { Load the config file }

  Config.UseJoystick1 := False;
  Config.UseJoystick2 := False;
  Config.DoSound      := True;
  Config.MinJoyX      := 10;
  Config.MaxJoyX      := 100;
  Config.MinJoyY      := 10;
  Config.MaxJoyY      := 100;
  Config.MinJoyX2     := 10;
  Config.MaxJoyX2     := 100;
  Config.MinJoyY2     := 10;
  Config.MaxJoyY2     := 100;
  Config.JoyCenterX   := 50;
  Config.JoyCenterY   := 50;
  Config.JoyCenterX2  := 50;
  Config.JoyCenterY2  := 50;
  Config.FrameRate    := 0;
  Config.SoundBufSize := SoundBufSize;
  If Exist(ConfigFile) Then
  Begin
    Assign(F,ConfigFile);
    Reset(F,1);
    If FileSize(F) = SizeOf(Config) Then
    Begin
      BlockRead(F,Config,SizeOf(Config));
      Close(F);
    End
    Else
    Begin
      Close(F);
      Assign(F,ConfigFile);
      ReWrite(F,1);
      BlockWrite(F,Config,SizeOf(Config));
      Close(F);
    End;
  End;
  SoundBufSize := Config.SoundBufSize;
  DoSound      := Config.DoSound;
{  Assign(F,ConfigFile);
  ReWrite(F,1);
  BlockWrite(F,Config,SizeOf(Config));
  Close(F);}
  JoyCenterX  := Config.JoyCenterX;
  JoyCenterY  := Config.JoyCenterY;
  JoyMinX     := (JoyCenterX      + Config.MinJoyX) Div 2;
  JoyMinY     := (JoyCenterY      + Config.MinJoyY) Div 2;
  JoyMaxX     := (JoyCenterX      + Config.MaxJoyX) Div 2;
  JoyMaxY     := (JoyCenterY      + Config.MaxJoyY) Div 2;
  JoyCenterX2 := Config.JoyCenterX2;
  JoyCenterY2 := Config.JoyCenterY2;
  JoyMinX2    := (JoyCenterX2     + Config.MinJoyX2) Div 2;
  JoyMinY2    := (JoyCenterY2     + Config.MinJoyY2) Div 2;
  JoyMaxX2    := (JoyCenterX2     + Config.MaxJoyX2) Div 2;
  JoyMaxY2    := (JoyCenterY2     + Config.MaxJoyY2) Div 2;
  Asm
    CLI
    SUB   DX,DX
@L1:
    MOV   AX,DX
    MOV   BX,DX
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    RCR   AL,1
    RCL   AH,1
    MOV   BYTE PTR BitSwap[BX],AH
    INC   DX
    CMP   DX,256
    JL    @L1
    STI
  End; { Asm }
  For I := 0 To 228 Do Div3[I] := I Div 3;
  For I := 0 To 19 Do
  Begin
    BitTest[I]      := $80000 Shr I;
    BitTest[I + 20] := $80000 Shr I;
    BitTest[I + 64] := $80000 Shr I;
    BitTest[I + 84] := LongInt(1) Shl I;  { Need the type cast!!! }
  End; { For I }

  FillChar(MissileTable,SizeOf(MissileTable),#0);
  For I := 0 To 31 Do
  Begin
    Case (I Shr 3) Of
      0: J := 1;
      1: J := 2;
      2: J := 4;
      3: J := 8;
    End; { Case }
    FillChar(MissileTable[(I Shl 7)],J,#255);
    Case (I And 7) Of
      1: FillChar(MissileTable[(I Shl 7) + 16],J,#255);
      2: FillChar(MissileTable[(I Shl 7) + 32],J,#255);
      3: Begin
           FillChar(MissileTable[(I Shl 7) + 16],J,#255);
           FillChar(MissileTable[(I Shl 7) + 32],J,#255);
         End;
      4: FillChar(MissileTable[(I Shl 7) + 64],J,#255);
      6: Begin
           FillChar(MissileTable[(I Shl 7) + 32],J,#255);
           FillChar(MissileTable[(I Shl 7) + 64],J,#255);
         End;
    End; { Case }
  End; { For I }

  FillChar(ByteShift,SizeOf(ByteShift),#0);
  For I := 0 To 7 Do
  Begin
    For J := 0 To 71 Do
    Begin
      If (J <= 7) And (I In [0..4,6]) Then
      Begin
        ByteShift[(I Shl 8) + J + 128] := 1   Shl J;
        ByteShift[(I Shl 8) + J]       := $80 Shr J;
      End;
      Case I Of
        1: Case J Of
             16..23:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 16);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 16);
             End;
           End;
        2: Case J Of
             32..39:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 32);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 32);
             End;
           End; { Case }
        3: Case J Of
             16..23:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 16);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 16);
             End;
             32..39:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 32);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 32);
             End;
           End; { Case }
        4: Case J Of
             64..71:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 64);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 64);
             End;
           End; { Case }
        5: If J <= 15 Then
           Begin
             ByteShift[(I Shl 8) + J + 128] := 1   Shl (J Shr 1);
             ByteShift[(I Shl 8) + J]       := $80 Shr (J Shr 1);
           End;
        6: Case J Of
             32..39:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 32);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 32);
             End;
             64..71:
             Begin
               ByteShift[(I Shl 8) + J + 128] := 1   Shl (J - 64);
               ByteShift[(I Shl 8) + J]       := $80 Shr (J - 64);
             End;
           End; { Case }
        7: If J <= 31 Then
           Begin
             ByteShift[(I Shl 8) + J + 128] := 1   Shl (J Shr 2);
             ByteShift[(I Shl 8) + J]       := $80 Shr (J Shr 2);
           End;
      End; { Case }
    End; { For J }
  End; { For I }
  InitSound;
  Blaster := GetEnv('BLASTER');
  If Blaster <> '' Then
  Begin
    For I := 1 To Length(Blaster) Do Blaster[I] := UpCase(Blaster[I]);
    While (Blaster <> '') And (Blaster[1] = ' ') Do Blaster := Copy(Blaster,2,Length(Blaster) - 1);
    While (Blaster <> '') And (Blaster[Length(Blaster)] = ' ') Do Blaster := Copy(Blaster,1,Length(Blaster) - 1);
  End;
  If Blaster <> '' Then
  Begin

    { Get the port number }

    I := Pos('A',Blaster) + 1;
    St := '';
    Repeat
      WorkCh := Blaster[I];
      Inc(I);
      If WorkCh <> ' ' Then St := St + WorkCh;
    Until (WorkCh = ' ') Or (I > Length(Blaster));
    I := 1;
    _IO_Addx := 0;
    For J := 1 To Length(St) Do
    Begin
      WorkCh := UpCase(St[Length(St) - (J - 1)]);
      If WorkCh In ['0'..'9']
       Then _IO_Addx := _IO_Addx + I * (Ord(WorkCh) - Ord('0'))
       Else _IO_Addx := _IO_Addx + I * (Ord(WorkCh) - Ord('A') + 10);
      I := I * 16;
    End; { For J }

    { Get the IRQ }

    I := Pos('I',Blaster) + 1;
    St := '';
    Repeat
      WorkCh := Blaster[I];
      Inc(I);
      If WorkCh <> ' ' Then St := St + WorkCh;
    Until (WorkCh = ' ') Or (I > Length(Blaster));
    Val(St,_Intr_Num,I);

    { Get the DMA }

    I := Pos('D',Blaster) + 1;
    St := '';
    Repeat
      WorkCh := Blaster[I];
      Inc(I);
      If WorkCh <> ' ' Then St := St + WorkCh;
    Until (WorkCh = ' ') Or (I > Length(Blaster));
    Val(St,_DMA,I);
  End
  Else
  Begin
    _IO_Addx      := SBPort;
    _Intr_Num     := SBInt;
    _DMA          := SBDMA;
  End;

  UseMenu := False;
  T1      := 0;
  T2      := 0;

  Repeat
    CurrentBank := 0;
    BankStart   := $1000;
    BankSize    := 1024;    { Size in dwords }
    ParkerBS    := False;
    Activision  := False;
    MNetwork    := False;
    Starpath    := False;
    CBS         := False;
    Debugger    := False;
    FillChar(AtariSeg^,SizeOf(AtariSeg^),#0);  { Blank them with nulls }
    FillChar(BankSwitch,SizeOf(BankSwitch),#0);
    ClrScr;
    If (ParamCount = 0) Or
       ((ParamCount > 0) And Not Exist(ParamStr(1)))
     Then St := Menu{(Config,Top,Sel,JoyCenterX,JoyCenterY,JoyMinX,JoyMinY,
                     JoyMaxX,JoyMaxY,JoyCenterX2,JoyCenterY2,JoyMinX2,
                     JoyMinY2,JoyMaxX2,JoyMaxY2,BankSize,UseKBControllers,
                     Debugger,DoSound,UseMenu,Activision,ParkerBS,MNetwork,
                     BankSwitch)}
     Else St := ParamStr(1);





    If (St <> '') And Exist(St) Then
    Begin
      Disasm := False;
      If ParamCount > 1 Then
      Begin
        For I := 2 To ParamCount Do
        Begin
          If ToUpper(ParamStr(I)) = 'DISASM' Then Disasm := True;
          If ToUpper(ParamStr(I)) = 'BANK'   Then
          Begin
            BankSwitch[$1FF8] := 1;
            BankSwitch[$1FF9] := 5;
          End;
          If ToUpper(ParamStr(I)) = 'BANKC' Then
          Begin
            BankSwitch[$1FF8] := 1 + 32;
            BankSwitch[$1FF9] := 5 + 32;
            BankSwitch[$1FFA] := 9 + 32;
            For J := $1000 To $10FF Do BankSwitch[J] := $30;
            BankSize := 1024 - 128{64};    { Size in dwords }
            CBS      := True;
          End;
          If ToUpper(ParamStr(I)) = 'BANK16'   Then
          Begin
            BankSwitch[$1FF6] := 1;
            BankSwitch[$1FF7] := 5;
            BankSwitch[$1FF8] := 9;
            BankSwitch[$1FF9] := 13;
          End;
          If ToUpper(ParamStr(I)) = 'BANKSC'   Then
          Begin
            BankSwitch[$1FF6] := 1  + $40;
            BankSwitch[$1FF7] := 5  + $40;
            BankSwitch[$1FF8] := 9  + $40;
            BankSwitch[$1FF9] := 13 + $40;
            For J := $1000 To $107F Do BankSwitch[J] := $50;
            BankSize := 1024 - 64{32};    { Size in dwords }
          End;
          If ToUpper(ParamStr(I)) = 'BANKSP'   Then
          Begin
            For J := $1000 To $1FFF Do BankSwitch[J] := $70;
            BankSwitch[$1FF8] := $70;
            StarPath          := True;
          End;
          If ToUpper(ParamStr(I)) = 'BANKA'   Then
          Begin
            BankSwitch[$01FE] := 17;
            Activision := True;
          End;
          If ToUpper(ParamStr(I)) = 'BANKP'   Then
          Begin
            For J := $1FE0 To $1FF7 Do BankSwitch[J] := J And $FF;
            ParkerBS := True;
          End;
          If ToUpper(ParamStr(I)) = 'BANKM'   Then
          Begin
            For J := $1FE0 To $1FE7 Do BankSwitch[J] := (J And $FF) - $10;
            ParkerBS := True;
          End;
          If ToUpper(ParamStr(I)) = 'DEBUG'   Then Debugger         := True;
          If ToUpper(ParamStr(I)) = 'KB'      Then UseKBControllers := True;
          If ToUpper(ParamStr(I)) = 'INDY500' Then UseIndy500       := True;
          If ToUpper(ParamStr(I)) = 'VTP'     Then VideoTouchPad    := True;
          If Copy(ToUpper(ParamStr(I)),1,5) = 'FRAME' Then
          Begin
            St1 := ParamStr(I);
            St1 := Copy(St1,6,Length(St1) - 5);
            Val(St1,Config.FrameRate,J);
            If J <> 0 Then Config.FrameRate := 0;
            If Config.FrameRate < 0 Then Config.FrameRate := 0;
          End;
        End;
      End;
      Assign(F,St);
      Reset(F,1);
      ROMSize := FileSize(F);
      If MNetwork Then GetMem(ROMBackup,ROMSize + 2048) Else GetMem(ROMBackup,ROMSize);
      BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1000],FileSize(F));
      If ROMSize < 4096 Then
      Begin
        Seek(F,0);
        BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1000 + ROMSize],FileSize(F));
      End;
      If (ROMSize >= 8192) And ParkerBS Then
      Begin
        Seek(F,7168);
        BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1C00],1024);
        BankSize := 256;    { Size in dwords }
      End;
{
      If Activision Then
      Begin
        Seek(F,4096);
        BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1000],4096);
      End;
}
      If (ROMSize >= 16384) And MNetwork Then
      Begin
        Seek(F,14 * 1024);
        BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1800],2048);
        BankSize := 512;    { Size in dwords }
      End;

      { Load 2nd 4k for SuperChip }

      If (ROMSize >= 16384) And (BankSize = 1024 - 64) Then
      Begin
        Seek(F,4 * 1024);
        BlockRead(F,Mem[Seg(AtariSeg^):Ofs(AtariSeg^) + $1000],4096);
      End;

      Seek(F,0);
      BlockRead(F,ROMBackup^,ROMSize);
      Close(F);
      If Disasm Then Disassemble;
      Go_Mode($13);
      Assign(F,'ATARI.PAL');
      Reset(F,1);
      BlockRead(F,Pal,SizeOf(Pal));
      Close(F);
      SetPalette;

      Move(_FMSoundType,FMSoundType,SizeOf(FMSoundType));
      Move(_FMReg,FMReg,SizeOf(FMReg));
      FillChar(FMChanOn,SizeOf(FMChanOn),#0);
      FillChar(FMFeedBack,SizeOf(FMFeedBack),#0);
      FillChar(FMBaseLevel,SizeOf(FMBaseLevel),#0);
      FillChar(FMScale,SizeOf(FMScale),#0);
      FillChar(FMFreq,SizeOf(FMFreq),#0);
      FillChar(FMRealScale,SizeOf(FMRealScale),#0);
      FillChar(FMVoc,SizeOf(FMVoc),#0);
{      InitFM;
      SetFM(1,True);
      SetFM(2,True);
      WriteFM(1,$20);}
      If Not StarPath
       Then Start := MemW[Seg(AtariSeg^):Ofs(AtariSeg^) + $1FFC] And $1FFF
       Else Start := MemW[Seg(ROMBackup^):Ofs(ROMBackup^) + $2000] And $1FFF;
      If StarPath Then
      Begin
        Asm
          LES   DI,DWORD PTR ROMBackup
          MOV   BL,ES:[DI+2002h]
          LES   DI,DWORD PTR AtariSeg
          MOV   BYTE PTR ES:[DI+80h],BL
          MOV   DL,BL
          MOV   BH,0F0h
          MOV   WORD PTR StarpathLastAddr,0 {BX}
          SHR   BL,1
          AND   BL,0Eh
          SUB   BH,BH

          MOV   AX,WORD PTR SP1[BX]
          MOV   CX,200h
          LES   DI,DWORD PTR AtariSeg
          PUSH  DS
          LDS   SI,DWORD PTR ROMBackup
          ADD   DI,1000h
          ADD   SI,AX
          CLD
          DB    _32BIT_OPERAND
          REP   MOVSW
          POP   DS

          MOV   AX,WORD PTR SP2[BX]
          MOV   CX,200h
          LES   DI,DWORD PTR AtariSeg
          PUSH  DS
          LDS   SI,DWORD PTR ROMBackup
          ADD   DI,1800h
          ADD   SI,AX
          CLD
          DB    _32BIT_OPERAND
          REP   MOVSW
          POP   DS

{          LES   DI,DWORD PTR AtariSeg}
          MOV   BYTE PTR SPBankNum,DL{ES:[DI+1FF8h],DL}
        End; { Asm }
      End;
      CyclesDone := 0;
      P := 0;
      A := 0;
      X := 0;
      Y := 0;
      S := 0;
      InitEmulator;
      OldByte  := AtariSeg^[Start];
      OldStart := Start;
      Repeat
        If OldStart <> 0 Then
        Begin
          OldByte  := AtariSeg^[OldStart];
          If Debugger Then AtariSeg^[OldStart] := $FF;
        End;
{        KBFlag  := Mem[0:$417];}
        InitKeyboard;
        If DoSound Then
        Begin
{          Tia_sound_init(sample_freq,playback_freq);}
{          OpenSB(playback_freq,num_bufs,SoundBufSize);}

          _CTV_Card_Here;
          _CTV_Detect;
(*
          { Reset the Sound Blaster }

          Port[_IO_Addx + 6] := 1;
          Delay(1);
          Port[_IO_Addx + 6] := 0;
          J := 0;
          Repeat
            Repeat
            Until (Port[_IO_Addx + $E] And $80) <> 0;
            I := Port[_IO_Addx + $A];
            Inc(J);
          Until (I = $AA) Or (J > 100);
          Delay(2);
*)
          _Voice_Status := 0;
          _CTV_Output(SoundBuf[1],SoundBufSize,Playback_Freq);
        End;
        Time0   := Clock;
        TimeErr := 0;

{$IFDEF LOWRES}
        Set160Cols;
{$ENDIF}

        Interpret(Start,P,A,X,Y,S);   { (0,P,A,X,Y,S) }

{$IFDEF LOWRES}
        Asm
          MOV   AX,93h
          INT   10h
        End; { Asm }
        SetPalette;
{$ENDIF}

{        If DoSound Then CloseSB;}
        If DoSound Then
        Begin
          _CTV_Halt;
          _CTV_Uninstall;
        End;
        Key[kESC] := 0;
        ExitKeyboard;
        If OldStart <> 0 Then AtariSeg^[OldStart] := OldByte;
{$IFDEF LOWRES}
      Until (Not Debugger) Or Not
       Debug(AtariSeg,Start,P,A,X,Y,S,TIA_Scan,TIA_Count,0,Addr,OldStart,{OldByte,}
        @BankSwitch,ROMBackup,@TIA_Regs,@Input_Byte,@ObjectLoc,True);
{$ELSE}
      Until (Not Debugger) Or Not
       Debug(AtariSeg,Start,P,A,X,Y,S,TIA_Scan,TIA_Count,0,Addr,OldStart,{OldByte,}
        @BankSwitch,ROMBackup,@TIA_Regs,@Input_Byte,@ObjectLoc,False);
{$ENDIF}
{      InitFM;
      SetFM(1,False);
      SetFM(2,False);}
      If MNetwork Then FreeMem(ROMBackup,ROMSize + 2048) Else FreeMem(ROMBackup,ROMSize);
      TextMode(C80);
    End;
  Until Not UseMenu;
  If LockXMS Then Handle.UnlockXM;
  Handle.FreeXM;
  FreeMem(SoundBuf[1],SoundBufSize);
  FreeMem(SoundBuf[0],SoundBufSize * 2);
End; { Emulate }


Begin
  FileMode := 0;
  New(OldAtariSeg);   { Create both halves of the segment }
  AtariSeg := OldAtariSeg;
  ClrScr;
  TextMode(C80);
  TextColor(LightGray);
  WriteLn('Atari 2600 Emulator');
  WriteLn;
  WriteLn('Setting up system');
  WriteLn;
  Lo_Seg := Seg(AtariSeg^); Lo_Ofs := Ofs(AtariSeg^);
  If Lo_Ofs > 0 Then
  Begin
    WriteLn('Warning: Segment 1 is not on a paragraph boundary');
    Lo_Seg := Lo_Seg + Lo_Ofs Div 16;
    Lo_Ofs := 0;
    AtariSeg := Ptr(Lo_Seg,Lo_Ofs);
  End;
  Emulate;
  Dispose(OldAtariSeg);
{
  WriteLn('BitTest at ',HexWord(Ofs(BitTest[0])));
  WriteLn('Executed at ',HexWord(Ofs(Executed)));
  WriteLn('BankSwitch ends at ',HexWord(Ofs(BankSwitch[8191])));
  WriteLn('DSeg=',HexWord(DSeg));
  WriteLn('Coeff at ',HexWord(Seg(Coeff)),':',HexWord(Ofs(Coeff)));
  WriteLn('Interpret at  ',HexWord(Ofs(Interpret)));
  WriteLn('Handle_TIA at ',HexWord(Ofs(Handle_TIA)));
  WriteLn('Handle_IO at  ',HexWord(Ofs(Handle_IO)));
  WriteLn('Handle_IO_After at ',HexWord(Ofs(Handle_IO_After)));
}
End.