{$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