1 ; _____________________________________________ 2 ; | | 3 ; | Project: APPLER | 4 ; | File: FLOPPY.INC | 5 ; | Compiler: 16-bit TASM (2.5) | 6 ; | | 7 ; | Subject: Floppy Disk Emulation | 8 ; | | 9 ; | Author: Alexander Patalenski | 10 ; |_____________________________________________| 11 12 ; This file is included in EMULATE.ASM 13 14 ;-------------- Floppy emulation entries --------------------------------------- 15 16 assume CS:Emulate,DS:Apple,ES:Video,SS:Data 17 18 UseNextFreeSpace 19 C0E0r: 20 C0E1r: 21 C0E2r: 22 C0E3r: 23 C0E4r: 24 C0E5r: 25 C0E6r: 26 C0E7r: push cs 27 push di 28 jmp StepMotor 29 C0E0w: 30 C0E1w: 31 C0E2w: 32 C0E3w: 33 C0E4w: 34 C0E5w: 35 C0E6w: 36 C0E7w: Save ax 37 call StepMotor 38 Restore ax 39 sahf 40 DoNext 41 42 C0E8r: push cs 43 push di 44 jmp StopMotors 45 C0E8w: Save ax 46 call StopMotors 47 Restore ax 48 sahf 49 DoNext 50 51 C0E9r: push cs 52 push di 53 jmp StartMotors 54 C0E9w: Save ax 55 call StartMotors 56 Restore ax 57 sahf 58 DoNext 59 60 C0EAr: 61 C0EBr: push cs 62 push di 63 jmp DeviceSelect 64 C0EAw: 65 C0EBw: Save ax 66 call DeviceSelect 67 Restore ax 68 sahf 69 DoNext 70 CheckAddress 71 72 UseNextFreeSpace 73 C0ECr: push cs 74 push di 75 jmp ReadWriteBuf 76 C0ECw: Save ax 77 call ReadWriteBuf 78 Restore ax 79 sahf 80 DoNext 81 82 C0EDr: mov al,0FFh 83 mov bl,ch 84 jmp di 85 C0EDw: Save ax 86 mov al,bh 87 call WriteDataReg 88 Restore ax 89 sahf 90 DoNext 91 92 C0EEr: push cs 93 push di 94 call ReadMode 95 jmp WriteProtection 96 C0EEw: Save ax 97 call ReadMode 98 Restore ax 99 sahf 100 DoNext 101 102 C0EFr: push di 103 call WriteMode 104 mov al,0FFh 105 ret 106 C0EFw: Save ax 107 call WriteMode 108 Restore ax 109 sahf 110 DoNext 111 CheckAddress 112 113 ;-------------- Floppy emulation subroutines ----------------------------------- 114 115 Peripher segment public 116 assume CS:Peripher,DS:Nothing,ES:Nothing 117 118 FLAGS db 00000010b 119 even 120 BufferPTR dw 0 ; Byte pointer in the R/W buffer 121 WriteCNT dw 0 ; Written bytes between two reads 122 WriteREG db 0 ; Temporal write register 123 even 124 CurrentDrive Drive_S <0> ; Active Drive Attributes 125 OtherDrive Drive_S <1> 126 127 ; Entry: 128 ; bx - file handle 129 ; ds:si - header ptr 130 ; Action: 131 ; load track buffer 132 ; Exit: 133 ; CF: 0-ok, 1-error (don't close file) 134 FloppyLoad proc far 135 push ax cx dx ds 136 mov ax,seg Buffer1000h 137 mov ds,ax 138 mov dx,offset Buffer1000h 139 mov cx,1000h 140 mov ah,3Fh 141 int 21h 142 cmp ax,cx 143 pop ds dx cx ax 144 ret 145 FloppyLoad endp 146 147 ; Entry: 148 ; bx - file handle 149 ; es:di - header ptr 150 ; Action: 151 ; save track buffer 152 ; Exit: 153 ; CF: 0-ok, 1-error (don't close file) 154 FloppySave proc far 155 push ax cx dx ds 156 mov ax,seg Buffer1000h 157 mov ds,ax 158 mov dx,offset Buffer1000h 159 mov cx,1000h 160 mov ah,40h 161 int 21h 162 cmp ax,cx 163 pop ds dx cx ax 164 ret 165 FloppySave endp 166 assume ds:Nothing 167 168 FloppyINIT Proc near 169 call OpenDiskFile1 170 call OpenDiskFile2 171 ret 172 FloppyINIT Endp 173 174 FloppyTINI Proc near 175 call CloseDiskFile1 176 call CloseDiskFile2 177 ret 178 FloppyTINI Endp 179 180 ResetFloppy Proc near 181 call ReadMode 182 mov al,0 183 call DeviceSelect 184 call StopMotors 185 ret 186 ResetFloppy Endp 187 188 even 189 StartMotors Proc far 190 or FLAGS,00000011b 191 mov bl,ch 192 ret 193 StartMotors Endp 194 195 even 196 StopMotors Proc far 197 test FLAGS,00000010b 198 jz StopMotors5 199 and FLAGS,11111101b 200 mov bl,ch 201 ret 202 StopMotorsC: test FLAGS,00000010b 203 jnz StopMotors5 204 call WriteTrack 205 and FLAGS,11111100b 206 StopMotors5: mov bl,ch 207 ret 208 StopMotors Endp 209 210 even 211 DeviceSelect Proc far 212 and al,1b 213 xor al,CurrentDrive.ID 214 jz DeviceSelect20 215 call WriteTrack 216 Save si cx 217 mov si,offset CurrentDrive 218 mov cx,size Drive_S 219 DeviceSelect10: lods byte ptr CS:[SI] 220 xchg CS:OtherDrive.ID[SI-1]-CurrentDrive.ID,al 221 mov CS:[SI-1],al 222 loop DeviceSelect10 223 Restore si cx 224 DeviceSelect20: mov bl,ch 225 ret 226 DeviceSelect Endp 227 228 even 229 StepMotor Proc far 230 test FLAGS,00000001b 231 jz StepMotor8 232 Save cx 233 mov cl,al 234 and cl,00000110b 235 mov ah,CurrentDrive.Phase 236 ror ah,cl 237 ror ax,1 238 xor cl,00000111b 239 ror ah,cl 240 mov CurrentDrive.Phase,ah 241 mov cl,CurrentDrive.PhasePTR 242 ror ah,cl 243 mov ch,ah 244 mov bl,CurrentDrive.StepCounter 245 mov bh,bl 246 StepMotor5: mov ah,ch 247 xor al,al 248 shr ah,1 249 shr ah,1 250 rcl al,1 251 shr ah,1 252 rcl al,1 253 shr ah,1 254 rcl al,1 255 shr ah,1 256 cmp ah,al 257 je StepMotor20 258 ja StepMotor10 259 inc cl 260 ror ch,1 261 inc bl 262 jmp StepMotor5 263 StepMotor8: mov bl,ch 264 ret 265 StepMotor10: dec cl 266 rol ch,1 267 dec bl 268 jmp StepMotor5 269 StepMotor20: and cl,00000111b 270 mov CurrentDrive.PhasePTR,cl 271 xor bh,bl 272 and bh,11111100b 273 jz StepMotor25 274 call WriteTrack 275 StepMotor25: cmp bl,0F8h 276 jb StepMotor27 277 and bl,111b 278 StepMotor27: mov CurrentDrive.StepCounter,bl 279 shr bl,1 280 shr bl,1 281 mov CurrentDrive.Track,bl 282 StepMotor30: Restore cx 283 mov bl,ch 284 ret 285 StepMotor Endp 286 287 even 288 ReadMode Proc far 289 and FLAGS,10111111b 290 mov bx,BufferPTR 291 add bx,ReadAdd 292 cmp bx,TrackBufferLen 293 jb ReadMode10 294 sub bx,TrackBufferLen 295 ReadMode10: mov BufferPTR,bx 296 mov WriteCNT,0 297 mov bl,ch 298 ret 299 ReadMode Endp 300 301 even 302 WriteMode Proc far 303 or FLAGS,01000000b 304 mov bx,BufferPTR 305 add bx,WriteAdd 306 cmp bx,TrackBufferLen 307 jb WriteMode10 308 sub bx,TrackBufferLen 309 WriteMode10: mov BufferPTR,bx 310 test FLAGS,00000100b 311 jnz WriteMode20 312 mov BufferPTR,0 313 or FLAGS,00010100b 314 WriteMode20: or FLAGS,00001000b 315 mov bl,ch 316 ret 317 WriteMode Endp 318 319 even 320 ReadWriteBuf Proc far 321 mov ah,FLAGS 322 test ah,01000000b 323 jnz WriteBuff10 324 test ah,00000100b 325 jnz ReadBuff10 326 call ReadTrack 327 mov BufferPTR,0 328 or FLAGS,00000100b 329 and FLAGS,11100111b 330 mov ah,FLAGS 331 ReadBuff10: mov bx,BufferPTR 332 mov al,TrackBuffer[bx] 333 test ah,00000001b 334 jz ReadBuff30 335 inc bx 336 cmp bx,TrackBufferLen 337 jb ReadBuff20 338 xor bx,bx 339 ReadBuff20: mov BufferPTR,bx 340 ReadBuff30: mov bl,ch 341 ret 342 WriteBuff10: test ah,00000001b 343 jz Writebuff30 344 mov bx,BufferPTR 345 mov al,WriteREG 346 mov TrackBuffer[bx],al 347 inc bx 348 cmp bx,TrackBufferLen 349 jb WriteBuff20 350 xor bx,bx 351 WriteBuff20: mov BufferPTR,bx 352 mov bx,WriteCNT 353 inc bx 354 mov WriteCNT,bx 355 cmp bx,FormatLimit 356 jb WriteBuff30 357 or FLAGS,00010000b 358 Writebuff30: mov bl,ch 359 ret 360 ReadWriteBuf Endp 361 362 even 363 WriteDataReg Proc far 364 mov WriteREG,al 365 mov bl,ch 366 ret 367 WriteDataReg Endp 368 369 even 370 WriteProtection Proc far 371 mov al,CurrentDrive.WriteProtect 372 mov bl,ch 373 ret 374 WriteProtection Endp 375 376 ;------------------------------------------------------------------------------- 377 378 ReadTrack Proc far ; Saves all registers 379 SaveAll 380 cmp CurrentDrive.DiskType,0 381 mov ax,cs 382 mov ds,ax 383 mov si,offset TrackBuffer 384 mov di,TrackBufferLen 385 je ReadTrack10 386 mov ax,seg Buffer1000h 387 mov ds,ax 388 mov si,offset Buffer1000h 389 mov di,1000h 390 ReadTrack10: mov al,CurrentDrive.Track 391 cbw 392 mul di 393 mov cx,dx 394 mov dx,ax 395 mov bx,CurrentDrive.FileHandle 396 mov ax,4200h 397 int 21h 398 jc ReadTrack20 399 mov dx,si 400 mov cx,di 401 mov ah,3Fh 402 int 21h 403 jnc ReadTrack30 404 cmp ax,cx 405 je ReadTrack30 406 ReadTrack20: mov ax,cs 407 mov es,ax 408 mov di,offset TrackBuffer 409 mov cx,TrackBufferLen/2 410 mov ax,Gap1 411 rep stosw 412 jmp ReadTrack40 413 ReadTrack30: cmp CurrentDrive.DiskType,0 414 je ReadTrack40 415 call EncodeTrack 416 ReadTrack40: RestoreAll 417 ret 418 ReadTrack Endp 419 420 EncodeTrack Proc near ; Destroys all registers 421 cld 422 mov ax,cs 423 mov ds,ax 424 mov es,ax 425 assume ds:Peripher,es:Peripher 426 mov di,offset TrackBuffer 427 mov dl,0 428 mov ax,Gap1 429 mov cx,Gap1Len/2 430 Encode10: rep stosw 431 mov si,offset SectorImage.AddressProlog 432 movsb 433 movsw 434 lodsb 435 mov dh,al 436 mov al,CurrentDrive.Volume 437 xor dh,al 438 mov ah,al 439 shr al,1 440 or ax,0AAAAh 441 stosw 442 mov al,CurrentDrive.Track 443 xor dh,al 444 mov ah,al 445 shr al,1 446 or ax,0AAAAh 447 stosw 448 xor bx,bx 449 mov bl,dl 450 mov bl,PosToLogNumber[BX] 451 mov al,LogToPhisNumber[BX] 452 xor dh,al 453 mov ah,al 454 shr al,1 455 or ax,0AAAAh 456 stosw 457 mov al,dh 458 mov ah,al 459 shr al,1 460 or ax,0AAAAh 461 stosw 462 movsw 463 movsb 464 mov ax,Gap2 465 mov cx,Gap2Len/2 466 rep stosw 467 movsw 468 movsb 469 lodsb 470 mov dh,al 471 xchg bh,bl 472 add bx,offset Buffer1000h 473 mov si,bx 474 mov ax,seg Buffer1000h 475 mov ds,ax 476 assume ds:seg Buffer1000h 477 mov bx,offset EncodeTable 478 mov cx,56h 479 Encode15: xor ah,ah 480 mov al,DS:[SI+2*56h] 481 shr al,1 482 rcl ah,1 483 shr al,1 484 rcl ah,1 485 mov ES:[DI+3*56h],al 486 mov al,DS:[SI+56h] 487 shr al,1 488 rcl ah,1 489 shr al,1 490 rcl ah,1 491 mov ES:[DI+2*56h],al 492 lodsb 493 shr al,1 494 rcl ah,1 495 shr al,1 496 rcl ah,1 497 mov ES:[DI+56h],al 498 mov al,ah 499 xor al,dh 500 xor dh,al 501 xlat CS:[BX] 502 stosb 503 loop Encode15 504 mov si,di 505 mov ax,cs 506 mov ds,ax 507 assume ds:Peripher 508 mov cx,100h 509 Encode20: lodsb 510 xor al,dh 511 xor dh,al 512 xlat 513 stosb 514 loop Encode20 515 mov al,dh 516 xlat 517 stosb 518 mov si,offset SectorImage.DataEpilog 519 movsw 520 movsw 521 mov ax,Gap3 522 mov cx,Gap3Len/2 523 inc dl 524 cmp dl,10h 525 jnb Encode30 526 jmp Encode10 527 Encode30: mov ax,Gap1 528 mov cx,offset TrackBuffer2 529 sub cx,di 530 shr cx,1 531 rep stosw 532 adc cx,0 533 rep stosb 534 ret 535 assume ds:Nothing,es:Nothing 536 EncodeTrack Endp 537 538 FlushBuffer Proc far ; External entry 539 call WriteTrack ; (from Disk Manager) 540 ret 541 FlushBuffer Endp 542 543 WriteTrack Proc near ; Saves all registers 544 test FLAGS,00011000b 545 jz WriteTrack30 546 cmp CurrentDrive.WriteProtect,0 547 jne WriteTrack30 548 SaveAll 549 cmp CurrentDrive.DiskType,0 550 mov ax,cs 551 mov ds,ax 552 mov si,offset TrackBuffer 553 mov di,TrackBufferLen 554 je WriteTrack10 555 call DecodeTrackM 556 mov ax,seg Buffer1000h 557 mov ds,ax 558 mov si,offset Buffer1000h 559 mov di,1000h 560 WriteTrack10: 561 and FLAGS,11100111b 562 mov al,CurrentDrive.Track 563 cbw 564 mul di 565 mov cx,dx 566 mov dx,ax 567 mov bx,CurrentDrive.FileHandle 568 mov ax,4200h 569 int 21h 570 jc WriteTrack20 571 mov dx,si 572 mov cx,di 573 mov ah,40h 574 int 21h 575 WriteTrack20: RestoreAll 576 WriteTrack30: and FLAGS,11111011b 577 ret 578 WriteTrack Endp 579 580 DecodeTrackM Proc near 581 DecodeTrackM10: call DecodeTrack 582 jnc DecodeTrackM20 583 Save ax bx cx dx 584 mov bl,DecodedSector 585 and bx,0Fh 586 mov dl,PhisToLogNumber[BX] 587 pushf 588 pushf 589 pop cx 590 and cx,not(11b shl 8) 591 push cx 592 popf 593 call DMentry 594 lahf 595 popf 596 sahf 597 Restore ax bx cx dx 598 jnc DecodeTrackM10 599 DecodeTrackM20: ret 600 DecodeTrackM Endp 601 602 DecodeTrack Proc near ; Destroys all registers 603 assume ds:Peripher,es:Peripher 604 cld 605 mov ax,cs 606 mov ds,ax 607 mov es,ax 608 mov si,offset TrackBuffer 609 mov di,offset TrackBuffer2 610 FastMovs TrackBuffer2Len 611 mov di,offset SectorFlags 612 mov al,1 613 FastStos 10h 614 mov di,offset TrackBuffer 615 jmp Decode10 616 DecodeTrkErr_J: jmp DecodeTrackErr 617 DecodeTrkEnd_J: jmp DecodeTrackEnd 618 Decode10: mov cx,offset TrackBuffer2 619 sub cx,di 620 jbe DecodeTrkEnd_J 621 mov al,SectorImage.AddressProlog 622 repne scasb 623 jne DecodeTrkEnd_J 624 mov ax,ES:[DI] 625 xor ax,word ptr SectorImage .AddressProlog+1 626 and ax,word ptr SectorImageF.AddressProlog+1 627 jnz Decode10 628 lea si,[di+2] 629 mov dh,SectorImage .AddressCheckSum 630 call DecodeAdrField 631 and al,SectorImageF.AddressCheckSum 632 mov ah,e_BadAdrCheckSum 633 jnz DecodeTrkErr_J ; Bad Address CheckSum 634 lodsw 635 xor ax,word ptr SectorImage .AddressEpilog 636 and ax,word ptr SectorImageF.AddressEpilog 637 jnz Decode15 638 lodsb 639 xor al,SectorImage .AddressEpilog+2 640 and al,SectorImageF.AddressEpilog+2 641 Decode15: mov ah,e_BadAdrEpilog 642 jnz DecodeTrkErr_J ; Bad Address Epilog 643 mov al,DecodedTrack 644 cmp al,CurrentDrive.Track 645 mov ah,e_BadTrackNumber 646 jne DecodeTrkErr_J ; Bad Track Number 647 mov al,DecodedSector 648 cmp al,0Fh 649 mov ah,e_BadSectorNumber 650 ja DecodeTrkErr_J ; Bad Sector Number 651 mov di,si 652 mov cx,DataSearchLen 653 Decode20: mov al,SectorImage.DataProlog 654 repne scasb 655 mov ah,e_MissingDataField 656 jne DecodeTrkErr_J ; Data Field is Missing 657 mov ax,ES:[DI] 658 xor ax,word ptr SectorImage .DataProlog+1 659 and ax,word ptr SectorImageF.DataProlog+1 660 jnz Decode20 661 lea si,[di+2] 662 mov bl,DecodedSector 663 and bx,0Fh 664 mov bl,PhisToLogNumber[BX] 665 dec SectorFlags[BX] 666 mov al,bl 667 mov ah,e_DuplicateSector 668 jnz DecodeTrackErr ; Duplicate Sector 669 xchg bh,bl 670 add bx,offset Buffer1000h 671 mov di,bx 672 mov dh,SectorImage .DataCheckSum 673 call DecodeDataField 674 and al,SectorImageF.DataCheckSum 675 and al,3Fh 676 mov ah,e_BadDataCheckSum 677 jnz DecodeTrackErr ; Bad Data CheckSum 678 or bp,bp 679 mov ah,e_BadDataImage 680 jnz DecodeTrackErr ; Bad Data Image 681 lodsw 682 xor ax,word ptr SectorImage .DataEpilog 683 and ax,word ptr SectorImageF.DataEpilog 684 jnz Decode70 685 lodsb 686 xor al,SectorImage .DataEpilog+2 687 and al,SectorImageF.DataEpilog+2 688 Decode70: mov ah,e_BadDataEpilog 689 jnz DecodeTrackErr ; Bad Data Epilog 690 lodsb 691 mov ah,al 692 xor ah,SectorImage .EndByte 693 and ah,SectorImageF.EndByte 694 mov ah,e_BadEndByte 695 jnz DecodeTrackErr ; Bad End Byte 696 mov di,si 697 jmp Decode10 698 DecodeTrackErr: stc 699 jmp DecodeTrackExt 700 DecodeTrackEnd: mov bx,0Fh 701 mov ah,e_MissingSector 702 Decode80: mov al,bl 703 cmp SectorFlags[BX],0 704 jne DecodeTrackErr ; Sector is Missing 705 dec bx 706 jns Decode80 707 mov al,DecodedVolume 708 mov CurrentDrive.Volume,al 709 clc 710 DecodeTrackExt: ret 711 712 DecodeAdrField Proc near ; DS:SI - Source 713 lodsw ; DH - CheckSum Seed 714 rol al,1 715 and al,ah 716 mov DecodedVolume,al 717 xor dh,al 718 lodsw 719 rol al,1 720 and al,ah 721 mov DecodedTrack,al 722 xor dh,al 723 lodsw 724 rol al,1 725 and al,ah 726 mov DecodedSector,al 727 xor dh,al 728 lodsw 729 rol al,1 730 and al,ah 731 xor al,dh 732 ret 733 DecodeAdrField Endp ; AL - CheckSum Result 734 735 DecodeDataField Proc near ; SI,DI - Source,Destination 736 Save es ; DH - CheckSum Seed 737 mov ax,seg Buffer1000h 738 mov es,ax 739 assume es:seg Buffer1000h 740 Save di 741 mov bx,offset DecodeTable - 80h 742 shl dh,1 743 shl dh,1 744 xor bp,bp 745 mov cx,56h-2 746 DDF10: lodsb 747 xlat 748 shl al,1 749 adc bp,0 750 xor dh,al 751 mov al,dh 752 xor ah,ah 753 shl al,1 754 rcr ah,1 755 shl ax,1 756 rcl ah,1 757 mov ES:[DI+2*56h],ah 758 xor ah,ah 759 shl al,1 760 rcr ah,1 761 shl ax,1 762 rcl ah,1 763 mov ES:[DI+1*56h],ah 764 shl al,1 765 rcr ah,1 766 rol al,1 767 rol ax,1 768 stosb 769 loop DDF10 770 mov cx,2 771 DDF20: lodsb 772 xlat 773 shl al,1 774 adc bp,0 775 xor dh,al 776 mov al,dh 777 xor ah,ah 778 shl al,1 779 shl al,1 780 shl al,1 781 rcr ah,1 782 shl ax,1 783 rcl ah,1 784 mov ES:[DI+1*56h],ah 785 shl al,1 786 rcr ah,1 787 rol al,1 788 rol ax,1 789 stosb 790 loop DDF20 791 Restore di 792 mov cx,100h 793 DDF30: lodsb 794 xlat 795 shl al,1 796 adc bp,0 797 xor dh,al 798 or ES:[DI],dh 799 inc di 800 loop DDF30 801 lodsb 802 xlat 803 shl al,1 804 adc bp,0 805 xor al,dh 806 shr al,1 807 shr al,1 808 Restore es 809 assume es:Peripher 810 ret ; AL - CheckSum Result 811 DecodeDataField Endp ; BP - Bad Data Image flag 812 assume ds:Nothing,es:Nothing 813 DecodeTrack Endp ; Error: CF=1, AH-Code, AL-Data 814 815 ;------------------------------------------------------------------------------- 816 even 817 SectorImage SectorImage_S <> 818 SectorImageF SectorImageF_S <> 819 820 DecodedVolume db 0 821 DecodedTrack db 0 822 DecodedSector db 0 823 824 SectorFlags db 10h dup(0) 825 826 PosToLogNumber db 0Fh,0Eh,0Dh,0Ch,0Bh,0Ah,09h,08h ; Position-to-Logical 827 db 07h,06h,05h,04h,03h,02h,01h,00h ; number convert table 828 LogToPhisNumber db 00h,0Dh,0Bh,09h,07h,05h,03h,01h ; Logical-to-Phisical 829 db 0Eh,0Ch,0Ah,08h,06h,04h,02h,0Fh ; number convert table 830 PhisToLogNumber db 00h,07h,0Eh,06h,0Dh,05h,0Ch,04h ; Phisical-to-Logical 831 db 0Bh,03h,0Ah,02h,09h,01h,08h,0Fh ; number convert table 832 833 EncodeTable label byte ; 6&2 Encode Table 834 T1 = 80h 835 REPT 80h 836 T3 = (T1 and (T1 shl 1)) and 01111110b 837 T4 = not(T1 or (T1 shl 1)) and 01111110b 838 T4 = T4 and (T4 - 1) 839 IF (T3 GT 0) and (T4 EQ 0) 840 db T1 841 ENDIF 842 T1 = T1 + 1 843 ENDM 844 845 DecodeTable label byte ; 6&2 Decode Table 846 T1 = 80h 847 T2 = 0 848 REPT 80h 849 T3 = (T1 and (T1 shl 1)) and 01111110b 850 T4 = not(T1 or (T1 shl 1)) and 01111110b 851 T4 = T4 and (T4 - 1) 852 IF (T3 GT 0) and (T4 EQ 0) 853 db T2 shl 1 854 T2 = T2 + 1 855 ELSE 856 db 80h 857 ENDIF 858 T1 = T1 + 1 859 ENDM 860 861 TrackBuffer db TrackBufferLen dup(0) 862 TrackBuffer2 db TrackBuffer2Len dup(0) 863 864 Peripher ends