;***************************************************************************** ; TRDOS.ASM [ Draft for Kernel TRDOS.RTS ] ; Copyright (C) 2004 Erdogan TAN [ 17/01/2004 ] Last Update: 06/07/2004 ; ! Under Development ! Current Stage: INT 20h replacement, load&run files ; Currently, usable prompt line commands: 'CD', 'DIR', 'VER', 'EXIT', 'PROMPT' ; 'VOLUME', 'LONGNAME', 'DATE', 'TIME' ; ; (RUN command runs standalone com files with INT 20h termination, for now.) ; (RUN command is using temporary memory allocation, for now.) ; (RUN/external command will use tr-dos memory allocation procedures, later) ; ; NOTE: DOS Interrupts and INT 18h will be programmed at last. ; This stage is "embedded command.com" (simple equivalent of command.com) ; **************************************************************************** ; masm.bat -> masm trdos -> link /t trdos -> TRDOS.COM [ MASM v6.11 ] ; This is source code of TRDOS.COM file which succesfully runs in MS-DOS 7.1 ;***************************************************************************** ; ; Masterboot / Partition Table at Beginning+1BEh ptBootable equ 0 ptBeginHead equ 1 ptBeginSector equ 2 ptBeginCylinder equ 3 ptFileSystemName equ 4 ptEndHead equ 5 ptEndSector equ 6 ptEndCylinder equ 7 ptStartSector equ 8 ptSectors equ 12 ; Boot Sector Parameters at 7C00h DataArea1 equ -4 DataArea2 equ -2 BootStart equ 0h OemName equ 03h BytesPerSec equ 0Bh SecPerClust equ 0Dh ResSectors equ 0Eh FATs equ 10h RootDirEnts equ 11h Sectors equ 13h Media equ 15h FATsecs equ 16h SecPerTrack equ 18h Heads equ 1Ah Hidden1 equ 1Ch Hidden2 equ 1Eh HugeSec1 equ 20h HugeSec2 equ 22h DriveNumber equ 24h Reserved1 equ 25h bootsignature equ 26h VolumeID equ 27h VolumeLabel equ 2Bh FileSysType equ 36h Reserved2 equ 3Eh ; Starting cluster of P2000 ; FAT32 BPB Structure FAT32_FAT_Size equ 36 FAT32_RootFClust equ 44 FAT32_DrvNum equ 64 FAT32_Reserved1 equ 65 FAT32_BootSig equ 66 FAT32_VolID equ 67 FAT32_VolLab equ 71 FAT32_FilSysType equ 82 ; BIOS Disk Parameters DPDiskNumber equ 0h DPDType equ 1h DPReturn equ 2h DPHeads equ 3h DPCylinders equ 4h DPSecPerTrack equ 6h DPDisks equ 7h DPTableOff equ 8h DPTableSeg equ 0Ah DPNumOfSecs equ 0Ch ; BIOS INT 13h Extensions (LBA extensions) ; Just After DP Data (DPDiskNumber+) DAP_PacketSize equ 10h ; If extensions present, this byte will be >=10h DAP_Reserved1 equ 11h ; Reserved Byte DAP_NumOfBlocks equ 12h ; Value of this byte must be 0 to 127 DAP_Reserved2 equ 13h ; Reserved Byte DAP_Destination equ 14h ; Address of Transfer Buffer as SEGMENT:OFFSET DAP_LBA_Address equ 18h ; LBA=(C1*H0+H1)*S0+S1-1 ; C1= Selected Cylinder Number ; H0= Number Of Heads (Maximum Head Number + 1) ; H1= Selected Head Number ; S0= Maximum Sector Number ; S1= Selected Sector Number ; QUAD WORD ; DAP_Flat_Destination equ 20h ; 64 bit address, if value in 4h is FFFF:FFFFh ; QUAD WORD (Also, value in 0h must be 18h) ; TR-DOS will not use 64 bit Flat Address ; INT 13h Function 48h "Get Enhanced Disk Drive Parameters" ; Just After DP Data (DPDiskNumber+) GetDParams_48h equ 20h ; Word. Data Lenght, must be 26 (1Ah) for short data. GDP_48h_InfoFlag equ 22h ; Word ; Bit 1 = 1 -> The geometry returned in bytes 4-15 is valid. GDP_48h_NumOfPCyls equ 24h ; Double Word. Number physical cylinders. GDP_48h_NumOfPHeads equ 28h ; Double Word. Number of physical heads. GDP_48h_NumOfPSpT equ 2Ch ; Double word. Num of physical sectors per track. GDP_48h_LBA_Sectors equ 30h ; 8 bytes. Number of physical/LBA sectors. GDP_48h_BytesPerSec equ 38h ; Word. Number of bytes in a sector. ; TR-DOS Standalone Program Extensions to the DiskParams Block ; Just After DP Data (DPDiskNumber+) TRDP_CurrentSector equ 3Ah ; DX:AX (LBA) TRDP_SectorCount equ 3Eh ; CX (or Counter) ; DOS Logical Disks LD_Name equ 0 LD_DiskType equ 1 LD_PhyDrvNo equ 2 LD_FATType equ 3 LD_FSType equ 4 LD_LBAYes equ 5 LD_BPB equ 6 LD_FATBegin equ 96 LD_ROOTBegin equ 100 LD_DATABegin equ 104 LD_StartSector equ 108 LD_TotalSectors equ 112 LD_FreeSectors equ 116 LD_Clusters equ 120 LD_PartitionEntry equ 124 LD_DParamEntry equ 125 LD_MediaChanged equ 126 LD_CDirLevel equ 127 LD_CurrentDirectory equ 128 ; Valid FAT Types FS_FAT12 equ 1 FS_FAT16_CHS equ 2 FS_FAT32_CHS equ 3 FS_FAT16_LBA equ 4 FS_FAT32_LBA equ 5 ; Cursor Location CCCpointer equ 0450h ; BIOS data, current cursor column ; FAT Clusters EOC sign FAT12EOC equ 0FFFh FAT16EOC equ 0FFFFh ;FAT32EOC equ 0FFFFFFFh ; It is not direct usable for 8086 code ; BAD Cluster FAT12BADC equ 0FF7h FAT16BADC equ 0FFF7h ;FAT32BADC equ 0FFFFFF7h ; It is not direct usable for 8086 code ; MS-DOS FAT16 FS (Maximum Possible) Last Cluster Number= 0FFF6h Present segment Para 'code' assume CS:Present, DS:Present, ES:Present, SS:Present ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ;± ;± PROCEDURE proc_start ;± ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc_start proc far org 100h start: mov si, offset Starting_Msg call proc_printmsg xor dl,dl mov si, offset DiskParams dparam_read: call proc_dparam mov dl, byte ptr [SI][DPDisks] add si, 40h cmp dl, 2 jne short pass_floppy1 dec dl call proc_dparam pass_floppy1: mov dl, 80h add si, 40h call proc_dparam jnc short pass_hd_15h_error mov word ptr [si][DPNumOfSecs], 0 mov word ptr [si][DPNumOfSecs]+2,0 pass_hd_15h_error: mov ah, byte ptr [SI][DPDisks] mov byte ptr [HDCounter], ah next_hard_disk: dec byte ptr [HDCounter] cmp byte ptr [HDCounter], 0 jna short load_hd_partition_tables inc dl add si, 40h call proc_dparam jnc short next_hard_disk mov word ptr [si][DPNumOfSecs], 0 mov word ptr [si][DPNumOfSecs]+2,0 jmp short next_hard_disk load_hd_partition_tables: mov si, offset Disk_hd0 mov di, offset PTable_hd0 push ds pop es mov dl, 80h mov cx, 4 load_next_hd_partition_table: push cx push dx push si push di cmp byte ptr [SI]+1, 03h jne short pass_pt_this_hard_disk call proc_load_masterboot jc short pass_pt_this_hard_disk pop di push di mov si, offset PartitionTable mov cx, 32 rep movsw pass_pt_this_hard_disk: pop di pop si pop dx pop cx inc dl add si, 40h add di, 40h loop load_next_hd_partition_table load_extended_dos_partitions: mov si, Offset PTable_hd0 mov di, Offset PTable_ep0 mov byte ptr [HDCounter], 80h next_hd_extd_partition: push si mov cx, 4 hd_check_fs_id_05h: mov al, byte ptr [SI][ptFileSystemName] cmp al, 05h ; Is it an extended dos partition ? je short pass_hd_check_05h cmp al, 0Fh ; Is it an extended win4 (LBA mode) partition ? je short pass_hd_check_0Fh continue_to_check_ep: add si, 10h loop hd_check_fs_id_05h continue_check_ep_next_disk: pop si add si, 40h add di, 40h inc byte ptr [HDCounter] cmp byte ptr [HDCounter], 83h jna short next_hd_extd_partition jmp logical_drv_init pass_hd_check_05h: push cx mov ax, word ptr [SI][ptStartSector] mov dx, word ptr [SI][ptStartSector]+2 xor bh,bh mov bl, byte ptr [HDCounter] push bx sub bl, 80h shl bl, 1 shl bl, 1 mov word ptr [Val_StartSector][BX],ax mov word ptr [Val_StartSector][BX]+2,dx pop dx mov dh, byte ptr [SI][ptBeginHead] mov cx, word ptr [SI][ptBeginSector] mov ax, 0201h ; Read 1 sector mov bx, offset MasterBootBuff push ds pop es int 13h pop cx jc short continue_to_check_ep push si push di push cx mov si, offset PartitionTable mov cx, 32 rep movsw pop cx pop di pop si jmp short continue_check_ep_next_disk pop_di_check_next_ep: pop di jmp continue_to_check_ep pass_hd_check_0Fh: mov ax, word ptr [SI][ptStartSector] mov dx, word ptr [SI][ptStartSector]+2 xor bh,bh mov bl, byte ptr [HDCounter] sub bl, 80h push bx shl bl, 1 shl bl, 1 mov word ptr [Val_StartSector][BX],ax mov word ptr [Val_StartSector][BX]+2,dx pop ax push di mov ah, 40h mul ah mov di, offset Disk_hd0 add di, ax ep_mov_dap_parameters: push ds pop es cmp byte ptr [DI][DAP_PacketSize], 10h jne short pop_di_check_next_ep mov word ptr [DI][DAP_Destination], offset MasterBootBuff push ds pop word ptr [DI][DAP_Destination]+2 mov byte ptr [DI][DAP_NumOfBlocks],1 push si push di add si, ptStartSector add di, DAP_LBA_Address movsw movsw pop si add si, DAP_PacketSize ; DS:SI= DAP Location mov ah, 42h ; Extended Disk Read - LBA Read mov dl, byte ptr [HDCounter] int 13h pop si pop di jc continue_to_check_ep push di push si push cx mov si, offset PartitionTable mov cx, 32 rep movsw pop cx pop si pop di jmp continue_check_ep_next_disk logical_drv_init: mov byte ptr [Hard_Disk], 80h mov cx, 4 xor al, al mov si, offset PTable_Buffer mov di, offset Logical_DOSDisks + 200h mov byte ptr [Last_DOS_DiskNo], 1 ldrv_init_next_hdp: push si push cx push ax push di cmp byte ptr [SI][ptFileSystemName], 06h jne short pass_this_is_FAT16_CHS_disk mov byte ptr [DI][LD_DiskType], 2 mov dl, byte ptr [Hard_Disk] mov byte ptr [DI][LD_PhyDrvNo], dl mov byte ptr [DI][LD_FATType], 2 mov byte ptr [DI][LD_FSType], 06 mov bl, dl sub bl, 80h xor bh, bh mov ah, byte ptr [HD_LBAYes][BX] mov byte ptr [DI][LD_LBAYes], ah mov byte ptr [DI][LD_PartitionEntry],al mov ah, dl sub ah, 7Eh mov byte ptr [DI][LD_DParamEntry], ah mov dh, byte ptr [SI][ptBeginHead] mov cx, word ptr [SI][ptBeginSector] mov ax, 0201h ; Read 1 sector mov bx, offset DOSBootSectorBuff int 13h jc pass_this_is_FAT32_LBA_disk jmp hdp_boot_validation pass_this_is_FAT16_CHS_disk: cmp byte ptr [SI][ptFileSystemName], 0Eh jne pass_this_is_FAT16_LBA_disk mov byte ptr [DI][LD_DiskType], 2 mov dl, byte ptr [Hard_Disk] mov byte ptr [DI][LD_PhyDrvNo], dl mov byte ptr [DI][LD_FATType], 2 mov byte ptr [DI][LD_FSType], 0Eh mov byte ptr [DI][LD_LBAYes], 1 mov byte ptr [DI][LD_PartitionEntry],al mov ah, dl sub ah, 7Eh mov byte ptr [DI][LD_DParamEntry], ah mov al, 40h mul ah add ax, offset Disk_fd0 mov di, ax cmp byte ptr [DI][DAP_PacketSize], 10h jne pass_this_is_FAT32_LBA_disk mov word ptr [DI][DAP_Destination], offset DOSBootSectorBuff push ds pop word ptr [DI][DAP_Destination]+2 mov byte ptr [DI][DAP_NumOfBlocks],1 push di add si, ptStartSector add di, DAP_LBA_Address movsw movsw pop si add si, DAP_PacketSize ; DS:SI= DAP Location mov ah, 42h ; Extended Disk Read - LBA Read mov dl, byte ptr [Hard_Disk] int 13h jc pass_this_is_FAT32_LBA_disk hdp_boot_validation: cmp word ptr [BS_Validation], 0AA55h jne pass_this_is_FAT32_LBA_disk cmp byte ptr [BPB_Media], 0F8h jne pass_this_is_FAT32_LBA_disk cmp word ptr [BPB_FATSz16], 0 ja short pass_FAT32_BPB cmp byte ptr [BS_FAT32_BootSig], 29h jne pass_this_is_FAT32_LBA_disk mov cx, 45 jmp short loc_move_hd_BPB pass_FAT32_BPB: cmp byte ptr [BS_BootSig], 29h jne pass_this_is_FAT32_LBA_disk mov cx, 32 loc_move_hd_BPB: mov si, offset DOSBootSectorBuff pop di push di push di add di, LD_BPB rep movsw pop si pop di add di, 100h push di inc byte ptr [Last_DOS_DiskNo] mov al, 'A' add al, byte ptr [Last_DOS_DiskNo] mov byte ptr [SI][LD_Name], al cmp byte ptr [Now_EP_Drives], 0 jna short ld_StartSector_set1 cmp byte ptr [SI][LD_FsType], 0Bh jne short ld_StartSector_set1 mov ax, word ptr [SI][LD_StartSector] mov dx, word ptr [SI][LD_StartSector]+2 jmp short ld_StartSector_set2 ld_StartSector_set1: mov AX,Word Ptr [SI][LD_BPB][Hidden1] mov DX,Word Ptr [SI][LD_BPB][Hidden2] mov word ptr [SI][LD_StartSector],AX mov word ptr [SI][LD_StartSector]+2,DX ld_StartSector_set2: add AX,Word Ptr [SI][LD_BPB][ResSectors] adc DX,0 mov Word Ptr [SI][LD_FATBegin], AX mov Word Ptr [SI][LD_FATBegin]+2, DX cmp byte ptr [SI][LD_FATType], 3 jne short pass_FAT32_RootDirLoc mov ax, Word Ptr [SI][LD_BPB][FAT32_FAT_Size] mov dx, Word Ptr [SI][LD_BPB][FAT32_FAT_Size]+2 xor bh,bh mov bl,Byte Ptr [SI][LD_BPB][FATs] call proc_mul32 add ax, Word Ptr [SI][LD_FATBegin] adc dx, Word Ptr [SI][LD_FATBegin]+2 mov Word Ptr [SI][LD_DATABegin], AX mov Word Ptr [SI][LD_DATABegin]+2, DX mov Word Ptr [SI][LD_ROOTBegin], AX mov Word Ptr [SI][LD_ROOTBegin]+2, DX jmp short pass_FAT_FS_Locations pass_FAT32_RootDirLoc: mov AL,Byte Ptr [SI][LD_BPB][FATs] cbw mul Word Ptr [SI][LD_BPB][FATSecs] add AX,Word Ptr [SI][LD_FATBegin] adc DX,Word Ptr [SI][LD_FATBegin]+2 mov Word Ptr [SI][LD_ROOTBegin], AX mov Word Ptr [SI][LD_ROOTBegin]+2, DX mov Word Ptr [SI][LD_DATABegin], AX mov Word Ptr [SI][LD_DATABegin]+2, DX mov AX,20h ; Size of a directory entry mul Word Ptr [SI][LD_BPB][RootDirEnts] add AX,511 ; adc dx, 0 mov cx, 512 div cx add Word Ptr [SI][LD_DATABegin],AX adc Word Ptr [SI][LD_DATABegin]+2,0 pass_FAT_FS_Locations: mov ax,Word Ptr [SI][LD_BPB][HugeSec1] mov Word Ptr [SI][LD_TotalSectors], AX mov dx,Word Ptr [SI][LD_BPB][HugeSec2] mov Word Ptr [SI][LD_TotalSectors]+2, dx add ax,Word Ptr [SI][LD_StartSector] adc dx,Word Ptr [SI][LD_StartSector]+2 sub ax,Word Ptr [SI][LD_DATABegin] sbb dx,Word Ptr [SI][LD_DATABegin]+2 xor ch,ch mov cl,Byte Ptr [SI][LD_BPB][SecPerClust] call Rx_Dos_Div32 mov word ptr [SI][LD_Clusters], AX mov word ptr [SI][LD_Clusters]+2, DX ; Maximum Valid Cluster Number= DX:AX +1 ; with 2 reserved clusters= DX:AX +2 ;mov word ptr [SI][LD_FreeSectors],0 ;mov word ptr [SI][LD_FreeSectors]+2,0 ;BPB has been loaded, yet ;LD_MediaChanged= 1 is "New Boot, FAT is not read" mov byte ptr [SI][LD_MediaChanged],1 jmp pass_this_is_FAT32_LBA_disk pass_this_is_FAT16_LBA_disk: cmp byte ptr [SI][ptFileSystemName], 0Bh jne short pass_this_is_FAT32_CHS_disk mov byte ptr [DI][LD_DiskType], 2 mov bl, byte ptr [Hard_Disk] mov byte ptr [DI][LD_PhyDrvNo], bl mov byte ptr [DI][LD_FATType], 3 mov byte ptr [DI][LD_FSType], 0Bh sub bl, 80h xor bh, bh mov ah, byte ptr [HD_LBAYes][BX] mov byte ptr [DI][LD_LBAYes],ah mov byte ptr [DI][LD_PartitionEntry],al mov ah, bl add ah, 2 mov byte ptr [DI][LD_DParamEntry], ah mov ax, word ptr [SI][ptStartSector] mov dx, word ptr [SI][ptStartSector]+2 cmp byte ptr [Now_EP_Drives],0 jna short pass_0Bh_ext_part_start_fixup shl bl, 1 shl bl, 1 add ax, word ptr [Val_StartSector][BX] adc dx, word ptr [Val_StartSector][BX]+2 mov word ptr [DI][LD_StartSector], ax mov word ptr [DI][LD_StartSector]+2, dx pass_0Bh_ext_part_start_fixup: push ax mov ah, byte ptr [Hard_Disk] sub ah, 7Eh mov al, 40h mul ah add ax, offset Disk_fd0 mov di, ax pop ax cmp byte ptr [DI][DAP_PacketSize], 10h jne pass_this_is_FAT32_LBA_disk mov word ptr [DI][DAP_LBA_Address], ax mov word ptr [DI][DAP_LBA_Address]+2, dx jmp short loc_fixup_8GB_CHS_to_LBA pass_val_startsec_check: mov dh, byte ptr [SI][ptBeginHead] mov cx, word ptr [SI][ptBeginSector] mov ax, 0201h ; Read 1 sector mov bx, offset DOSBootSectorBuff int 13h jc pass_this_is_FAT32_LBA_disk jmp hdp_boot_validation pass_this_is_FAT32_CHS_disk: cmp byte ptr [SI][ptFileSystemName], 0Ch jne pass_this_is_FAT32_LBA_disk mov byte ptr [DI][LD_DiskType], 2 mov ah, byte ptr [Hard_Disk] mov byte ptr [DI][LD_PhyDrvNo], ah mov byte ptr [DI][LD_FATType], 3 mov byte ptr [DI][LD_FSType], 0Ch mov byte ptr [DI][LD_LBAYes], 1 mov byte ptr [DI][LD_PartitionEntry],al sub ah, 7Eh mov byte ptr [DI][LD_DParamEntry], ah mov al, 40h mul ah add ax, offset Disk_fd0 mov di, ax cmp byte ptr [DI][DAP_PacketSize], 10h jne pass_this_is_FAT32_LBA_disk push word ptr [SI][ptStartSector] pop word ptr [DI][DAP_LBA_Address] push word ptr [SI][ptStartSector]+2 pop word ptr [DI][DAP_LBA_Address]+2 loc_fixup_8GB_CHS_to_LBA: mov word ptr [DI][DAP_Destination], offset DOSBootSectorBuff push ds pop word ptr [DI][DAP_Destination]+2 mov byte ptr [DI][DAP_NumOfBlocks],1 push di pop si add si, DAP_PacketSize ; DS:SI= DAP Location mov ah, 42h ; Extended Disk Read - LBA Read mov dl, byte ptr [Hard_Disk] int 13h jnc hdp_boot_validation pass_this_is_FAT32_LBA_disk: pop di pop ax pop cx pop si add si, 10h inc al dec cx cmp cx, 0 ja ldrv_init_next_hdp cmp byte ptr [Hard_Disk], 83h jnb short pass_init_primary_dos_partitions mov cx, 4 inc byte ptr [Hard_Disk] jmp ldrv_init_next_hdp pass_init_primary_dos_partitions: cmp byte ptr [Now_EP_Drives], 0 ja short launch_current_dos_drive mov byte ptr [Now_EP_Drives], 1 mov si, offset PTable_ep0 mov byte ptr [Hard_Disk], 80h mov ah, byte ptr [Last_DOS_DiskNo] inc ah xor al,al mov di, offset Logical_DOSDisks add di, ax mov al, 16 mov cx, 4 jmp ldrv_init_next_hdp Now_EP_Drives: db 0 Val_StartSector: dd 0 dd 0 dd 0 dd 0 launch_current_dos_drive: push ds xor ax, ax mov ds, ax mov ax, word ptr DS:[084h] push ax pop word ptr CS:[INT21h_Offset] mov ax, word ptr DS:[086h] push ax pop word ptr CS:[INT21h_Segment] mov word ptr DS:[084h], offset trdos_int21h_routine mov ax, cs mov word ptr DS:[086h], ax pop ds trdos_mainprog: call proc_clear_screen mov al, 2 ; C: call proc_change_current_drive call proc_dos_prompt end_of_program: xor ax, ax mov ds, ax push word ptr CS:[INT21h_Offset] pop ax mov word ptr DS:[084h], ax push word ptr CS:[INT21h_Segment] pop ax mov word ptr DS:[086h], ax int 20h proc_start endp proc_clear_screen proc near mov ah, 0Fh int 10h mov ah, 0 int 10h retn proc_clear_screen endp proc_printmsg proc near loc_print: lodsb ; Load byte at DS:SI to AL and AL,AL je short loc_return ; If AL = 00h then return mov AH,0Eh mov BX,07h int 10h ; BIOS Service func ( ah ) = 0Eh ; Write char as TTY ;AL-char BH-page BL-color jmp short loc_print loc_return: retn proc_printmsg endp ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''; ; Rx_DOS 32 bit Divide ; ; (Special version by Erdogan Tan) ; ;- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -; ; ; ; input -> DX_AX = 32 bit dividend ; ; input -> CX = 16 bit divisor ; ; output -> DX_AX = 32 bit quotient ; ; output -> BX = 16 bit remainder ; ; ; ; This procedure divides the requested 32 bit number ; ; and gives the result in DX, AX and BX (remainder) ; ; ; ; Original Procedure by Michael Podanoffsky / Real Time DOS ; ; (c) Erdogan TAN 1999 [ RXDOSBIO.ASM ] ; ;............................................................; Rx_Dos_Div32 proc near mov bx, dx xchg ax, bx xor dx, dx div cx ; at first, divide DX xchg ax, bx ; remainder is in DX ; now, BX has quotient ; save remainder div cx ; so, DX_AX divided and ; AX has quotient ; DX has remainder xchg dx, bx ; finally, BX has remainder retn Rx_Dos_Div32 endp ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''; ; From binary (byte) to hexadecimal (character) converter ; ; ; ; input -> AL = byte (binary number) to be converted ; ; output -> AH = First character of hexadecimal number ; ; output -> AL = Second character of hexadecimal number ; ; ; ; (c) Erdogan TAN 1998 - 1999 ; ;............................................................; ; 1998 proc_hex proc near db 0D4h,10h ; Undocumented inst. AAM ; AH = AL / 10h ; AL = AL MOD 10h or AX,'00' ; Make it ZERO (ASCII) based xchg AH,AL ; 1999 cmp AL,'9' jna pass_cc_al add AL,7 pass_cc_al: cmp AH,'9' jna pass_cc_ah add AH,7 pass_cc_ah: ; 1998 retn proc_hex endp ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''; ; 32 bit Multiply ; ;- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -; ; ; ; input -> DX_AX = 32 bit multiplier ; ; input -> BX = 16 bit number to be multiplied by DX_AX ; ; output -> BX_DX_AX = 48 bit (16+32 bit) result number ; ; ; ; (c) Erdogan TAN 1999 ; ;............................................................; proc_mul32 proc near push cx mov cx, bx mov bx, dx mul cx xchg ax, bx push dx mul cx pop cx add ax, cx adc dx, 0 xchg bx, ax xchg dx, bx pop cx retn proc_mul32 endp proc_dparam proc near ; input ; dl = Disk Drive Number ; ds:si = Parameters Table Buffer ; output ; ah = error number (0 = No Error if C flag is ZERO) mov byte ptr [si][DPDiskNumber], dl mov byte ptr [si][DPDType], 0 push dx mov ah, 08h int 13h mov byte ptr [si][DPReturn], ah jnc short dparam_no_error pop dx retn dparam_no_error: mov byte ptr [si][DPDType], bl mov byte ptr [si][DPDisks], dl inc dh mov byte ptr [si][DPHeads], dh push cx and cl, 3Fh mov byte ptr [si][DPSecPerTrack], cl pop cx shr cl,1 shr cl,1 shr cl,1 shr cl,1 shr cl,1 shr cl,1 xchg ch,cl inc cx mov word ptr [si][DPCylinders], cx mov word ptr [si][DPTableOff], di push es pop word ptr [si][DPTableSeg] cmp byte ptr [si][DPDiskNumber], 80h jb short dparam_15h_return mov dl, byte ptr [si][DPDiskNumber] mov byte ptr [Hard_Disk], dl mov byte ptr [si][DPDType], 0 mov ah, 15h int 13h jc short dparam_15h_return mov byte ptr [si][DPDType], ah mov word ptr [si][DPNumOfSecs], cx mov word ptr [si][DPNumOfSecs]+2, dx dparam_15h_return: pop dx ; dl = Drive Number mov byte ptr [SI][DAP_PacketSize], 0 ; Reset (No DAP) mov ah, 41h ; Check Extensions Present mov bx, 55AAh int 13h jc short dparam_48h_return cmp bx, 0AA55h jne short dparam_48h_return test cx, 01h ; Fixed Disk Access Subset - is LBA ready ? jz short dparam_48h_return xor bh,bh mov bl, byte ptr [Hard_Disk] sub bl, 80h mov byte ptr [HD_LBAYes][BX],1 mov byte ptr [SI][DAP_PacketSize], 10h dparam_41h_return: push si add si, GetDParams_48h mov word ptr [SI], 0026 ; GDP Data Lenght - Set ; DS:SI= Address of Result Buffer ; DL (Drive Number) must be not changed before here... mov ah, 48h ; Get Enhanced Disk Drive Parameters int 13h pop si jc short dparam_48h_return mov word ptr [SI][GetDParams_48h], 0 ; GDP Data Lenght - Reset dparam_48h_return: xor ah,ah retn proc_dparam endp proc_load_masterboot proc near ; input -> dl = drive number xor ah,ah int 13h jnc short pass_reset_error harddisk_error: retn pass_reset_error: mov bx, offset MasterBootBuff mov ax,0201h mov cx,1 xor dh,dh push ds pop es int 13h jc short harddisk_error cmp word ptr [MBIDCode],0AA55h jnz short loc_not_masterboot retn loc_not_masterboot: stc retn proc_load_masterboot endp proc_CHS_read proc near push si ; INPUT -> DX:AX = Logical Block Address ; CX = Number of sectors to read ; DS:SI = Logical Dos Disk Table Offset (DRV) ; ES:BX = Destination Buffer ; OUTPUT -> clc or stc mov byte ptr [CHS_RetryCount], 4 loc_read_disk_chs: push CX ; # of FAT/FILE/DIR sectors push AX ; Linear sector # push DX ; DX_AX = Linear address (sectors) mov CX,Word Ptr [SI][LD_BPB][SecPerTrack] push BX call RX_DOS_DIV32 ; Special 32 bit divide !!! ; To fix large disk problem. ; (c) Erdogan Tan 1999 ; (October 20th, 1999) mov CX, BX ; Sector (zero based) inc CX ; To make it 1 based push CX mov CX,Word Ptr [SI][LD_BPB][Heads] call RX_DOS_DIV32 ; Convert track to head & cyl mov DH, BL ; BX = Head (max. FFh) pop CX ; AX=Cyl, DH=Head, CX=Sector pop BX ; ES:BX = Buffer mov DL,Byte Ptr [SI][LD_PhyDrvNo] mov CH,AL ror AH,1 ; Rotate right ror AH,1 or CL,AH mov AX,0201h int 13h ; BIOS Service func ( ah ) = 2 ; Read disk sectors ;AL-sec num CH-track CL-sec ; DH-head DL-drive ES:BX-buffer ;CF-flag AH-stat AL-sec read ; If CF = 1 then (If AH > 0) pop DX pop AX pop CX jnc short pass_read_disk_chs_error ; error code in AH sub byte ptr [CHS_RetryCount], 1 jnb short loc_read_disk_chs pop si retn pass_read_disk_chs_error: loop loc_read_next_sector pop si retn loc_read_next_sector: add AX,1 adc DX,0 add BX, 512 jmp short loc_read_disk_chs proc_CHS_read endp proc_LBA_read proc near push si ; INPUT -> DAP_Buffer ; OUTPUT -> clc or stc loc_read_disk_lba: mov si, offset DAP_Buffer ; DS:SI= DAP Location mov ah, 42h ; Extended Disk Read - LBA Read ;mov dl, byte ptr [DAP_BuffDisk] int 13h jnc short pass_read_disk_lba_error dec byte ptr [DAP_RetryCount] cmp byte ptr [DAP_RetryCount],1 jnb short loc_read_disk_lba pass_read_disk_lba_error: pop si retn proc_LBA_read endp proc_get_next_cluster proc near ; INPUT -> AX = Cluster Number, low 16 bit ; INPUT -> DX = Cluster Number, high 16 bit ; INPUT -> DS:SI = Logical Dos Drive Parameters Table ; OUTPUT -> clc -> No Error ; OUTPUT -> CX,BX will be destroyed ; AX: Next Cluster Number, low 16 bit ; DX: Next Cluster Number, high 16 bit ; stc -> Error mov word ptr [FAT_CurrentCluster], ax mov word ptr [FAT_CurrentCluster]+2, dx check_next_cluster_fat_type: cmp byte ptr [SI][LD_FATType], 2 jb short get_FAT12_next_cluster ja short get_FAT32_next_cluster get_FAT16_next_cluster: mov bx, 300h ;768 div bx ; AX = Count of 3 FAT sectors ; DX = Sector Offset shl dx, 1 ; Multiply by 2 push dx mov bx, 3 mul bx pop bx ; Sector Offset ; AX = FAT Sector ; DX = 0 mov cl, byte ptr [SI][LD_Name] cmp byte ptr [FAT_BuffValidData], 0 jna load_FAT_sectors0 cmp cl, byte ptr [FAT_BuffDrvName] jne load_FAT_sectors0 cmp ax, word ptr [FAT_BuffSector] jne load_FAT_sectors2 mov ax, word ptr [FAT_Buffer][BX] xor dx, dx retn get_FAT12_next_cluster: mov bx, 400h ;1024 div bx ; AX = Count of 3 FAT sectors ; DX = Buffer Entry Offset push ax mov ax, 3 mul dx ; Multiply by 3 shr ax, 1 ; Divide by 2 mov dx, ax pop ax push dx mov bx, 3 mul bx pop bx ; Buffer Byte Offset ; AX = FAT Beginning Sector ; DX = 0 mov cl, byte ptr [SI][LD_Name] cmp byte ptr [FAT_BuffValidData], 0 jna short load_FAT_sectors0 cmp cl, byte ptr [FAT_BuffDrvName] jne short load_FAT_sectors0 cmp ax, word ptr [FAT_BuffSector] jne short load_FAT_sectors2 mov cx, word ptr [FAT_CurrentCluster] shr cx, 1 mov ax, word ptr [FAT_Buffer][BX] jnc short get_FAT12_nc_even shr ax, 1 shr ax, 1 shr ax, 1 shr ax, 1 get_FAT12_nc_even: and ah,0Fh retn get_FAT32_next_cluster: mov cx, 180h ;384 call Rx_Dos_Div32 ; DX:AX = Count of 3 FAT sectors ; BX = Sector Offset shl bx, 1 shl bx, 1 ; Multiply by 4 push bx mov bx, 3 call proc_mul32 pop bx ; Sector Offset ; DX:AX = FAT Sector mov cl, byte ptr [SI][LD_Name] cmp byte ptr [FAT_BuffValidData], 0 jna short load_FAT_sectors0 cmp cl, byte ptr [FAT_BuffDrvName] jne short load_FAT_sectors0 cmp dx, word ptr [FAT_BuffSector]+2 jne short load_FAT_sectors1 cmp ax, word ptr [FAT_BuffSector] jne short load_FAT_sectors2 mov ax, word ptr [FAT_Buffer][BX] mov dx, word ptr [FAT_Buffer][BX]+2 and dh, 0Fh ; 28 bit Cluster retn load_FAT_sectors0: mov byte ptr [FAT_BuffDrvName], cl load_FAT_sectors1: mov word ptr [FAT_BuffSector]+2, dx load_FAT_sectors2: mov word ptr [FAT_BuffSector], ax add ax, word ptr [SI][LD_FATbegin] adc dx, word ptr [SI][LD_FATbegin]+2 cmp byte ptr [SI][LD_LBAYes], 0 ja short loc_load_lba_fat_sectors ;push ds ;pop es mov bx, offset FAT_Buffer mov cx, 3 call proc_CHS_read jnc short pass_FAT_sectors_load_error mov byte ptr [FAT_BuffValidData], 0 retn loc_load_lba_fat_sectors: ; mov byte ptr [DAP_BuffLBAyes], 1 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffPacketSize], 10h mov word ptr [DAP_BuffDestination], offset FAT_Buffer push ds pop word ptr [DAP_BuffDestination]+2 mov byte ptr [DAP_BuffNumOfBlocks], 3 mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_LBA_read return_from_fat_secs_read: jnc short pass_FAT_sectors_load_error mov byte ptr [FAT_BuffValidData], 0 retn pass_FAT_sectors_load_error: mov byte ptr [FAT_BuffValidData], 1 mov ax, word ptr [FAT_CurrentCluster] mov dx, word ptr [FAT_CurrentCluster]+2 jmp check_next_cluster_fat_type proc_get_next_cluster endp proc_load_root_directory proc near ; BL = Sector Offset ; BH = DRV mov byte ptr [DirBuff_ValidData],0 mov byte ptr [DirBuff_SectorOffset], bl mov byte ptr [DirBuff_LastEntry], 15 mov byte ptr [DirBuff_LastSector], 31 add bl,224 jc short ld_drv_root_failed xor bl,bl push si mov si, offset Logical_DOSDisks add si, bx cmp byte ptr [SI][LD_Name], 'A' jnb short pass_ld_drv_root_failed pop si ld_drv_root_failed: retn pass_ld_drv_root_failed: mov byte ptr [DirBuff_Drv], bh mov word ptr [DirBuff_DirCluster], 0 mov word ptr [DirBuff_DirCluster]+2, 0 mov word ptr [DirBuff_NextCluster], 0 mov word ptr [DirBuff_NextCluster]+2, 0 mov byte ptr [DirBuff_CurrentEntry],0 mov ax, word ptr [SI][LD_ROOTbegin] mov dx, word ptr [SI][LD_ROOTbegin]+2 xor bh, bh mov bl, byte ptr [DirBuff_SectorOffset] add ax, bx adc dx, 0 mov word ptr [DirBuff_DirSector], ax mov word ptr [DirBuff_DirSector]+2, dx cmp byte ptr [SI][LD_LBAYes], 0 ja short lba_read_root_dir_sector ; push ds ; pop es mov bx, offset Directory_Buffer mov cx, 1 call proc_CHS_read jnc short validate_RDirBuff_and_return pop si retn lba_read_root_dir_sector: mov byte ptr [DAP_BuffLBAyes], 1 mov byte ptr [DAP_BuffPacketSize], 10h mov word ptr [DAP_BuffDestination], offset Directory_Buffer push ds pop word ptr [DAP_BuffDestination]+2 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffNumOfBlocks], 1 mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_LBA_read jnc short validate_RDirBuff_and_return pop si retn validate_RDirBuff_and_return: mov byte ptr [DirBuff_ValidData], 1 pop si retn proc_load_root_directory endp proc_load_directory proc near ; DX:AX = Cluster Number ; BL = Sector Offset in cluster ; BH = DRV mov byte ptr [DirBuff_ValidData],0 mov byte ptr [DirBuff_SectorOffset], bl ; mov byte ptr [DirBuff_LastEntry], 0 ;[RESET] xor bl,bl push si mov si, offset Logical_DOSDisks add si, bx cmp byte ptr [SI][LD_Name], 'A' jnb short pass_ld_drv_failed pop si retn pass_ld_drv_failed: cmp byte ptr [SI][LD_FATType],2 ja short pass_ld_reset_dx xor dx,dx pass_ld_reset_dx: mov byte ptr [DirBuff_Drv], bh mov word ptr [DirBuff_DirCluster], ax mov word ptr [DirBuff_DirCluster]+2, dx mov word ptr [DirBuff_NextCluster], 0 mov word ptr [DirBuff_NextCluster]+2, 0 mov bl, byte ptr [SI][LD_BPB][SecPerClust] dec bl mov byte ptr [DirBuff_LastSector], bl cmp bl, byte ptr [DirBuff_SectorOffset] jnb short pass_ld_drv_secoff_failed pop si retn pass_ld_drv_secoff_failed: mov byte ptr [DirBuff_CurrentEntry],0 mov byte ptr [DirBuff_LastEntry], 15 sub ax, 2 sbb dx, 0 xor bh, bh mov bl, byte ptr [DirBuff_LastSector] inc bl call proc_mul32 add ax, word ptr [SI][LD_DATAbegin] adc dx, word ptr [SI][LD_DATAbegin]+2 ; xor bh, bh mov bl, byte ptr [DirBuff_SectorOffset] add ax, bx adc dx, 0 loc_read_directory_sector: mov word ptr [DirBuff_DirSector], ax mov word ptr [DirBuff_DirSector]+2, dx cmp byte ptr [SI][LD_LBAYes], 0 ja short lba_read_directory_sector ; push ds ; pop es mov bx, offset Directory_Buffer mov cx, 1 call proc_CHS_read jnc short validate_DirBuff_and_return pop si retn lba_read_directory_sector: mov byte ptr [DAP_BuffLBAyes], 1 mov byte ptr [DAP_BuffPacketSize], 10h mov word ptr [DAP_BuffDestination], offset Directory_Buffer push ds pop word ptr [DAP_BuffDestination]+2 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffNumOfBlocks], 1 mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_LBA_read jnc short validate_DirBuff_and_return pop si retn validate_DirBuff_and_return: mov byte ptr [DirBuff_ValidData], 1 pop si retn proc_load_directory endp proc_get_volume_name proc near mov byte ptr [DirBuff_SectorOffset], 0FFh loc_get_volume_next_sector: xor bl,bl mov bh, byte ptr [DirBuff_Drv] mov byte ptr [DirBuff_CurrentEntry], 0 mov si, offset Logical_DOSDisks add si, bx cmp byte ptr [SI][LD_FATType], 2 ja short get_FAT32_root_cluster loc_load_root_directory: inc byte ptr [DirBuff_SectorOffset] mov bl, byte ptr [DirBuff_SectorOffset] call proc_load_root_directory jnc short loc_get_volume_name retn get_FAT32_root_cluster: mov ax, word ptr [SI][LD_BPB][FAT32_RootFClust] mov dx, word ptr [SI][LD_BPB][FAT32_RootFClust]+2 call proc_load_directory jnc short loc_get_volume_name retn loc_get_volume_name: mov si, offset Directory_Buffer check_root_volume_name: cmp byte ptr [SI]+0Bh, 28h je short put_root_volume_name inc byte ptr [DirBuff_CurrentEntry] cmp byte ptr [DirBuff_CurrentEntry], 15 ja short pass_check_root_volume_name add si, 32 cmp byte ptr [SI], 0 ja short check_root_volume_name pass_check_root_volume_name: mov byte ptr [DirBuff_CurrentEntry], 0 mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp bl, byte ptr [DirBuff_LastSector] ja short pass_check_root_volume_name_2 jmp short loc_get_volume_next_sector pass_check_root_volume_name_2: mov si, offset Current_Path put_root_volume_name: mov al, byte ptr [DirBuff_Drv] add al, 'A' mov byte ptr [Dir_Drive_Name], al mov di, offset Vol_Name mov cx, 11 rep movsb mov al, byte ptr [Current_VolSerial1] call proc_hex mov word ptr [Vol_Serial1]+2, ax mov al, byte ptr [Current_VolSerial1]+1 call proc_hex mov word ptr [Vol_Serial1], ax mov al, byte ptr [Current_VolSerial2] call proc_hex mov word ptr [Vol_Serial2]+2, ax mov al, byte ptr [Current_VolSerial2]+1 call proc_hex mov word ptr [Vol_Serial2], ax clc retn proc_get_volume_name endp proc_dos_prompt proc near push ds pop es loc_TRDOS_prompt: mov DI, offset TextBuffer mov byte ptr [DI], "[" inc di mov si, offset TRDOSPromptLabel get_next_prompt_label_char: mov al, byte ptr [SI] cmp al, 20h jb short pass_prompt_label mov byte ptr [DI], al inc si inc di jmp short get_next_prompt_label_char pass_prompt_label: mov byte ptr [DI], "]" inc di mov byte ptr [DI], 20h inc di mov al, byte ptr [Current_DosDisk] add al, 'A' mov byte ptr [DI], al inc DI mov byte ptr [DI], ':' inc DI mov byte ptr [DI], 0 mov si, offset TextBuffer call proc_printmsg mov SI, offset Dir_Str_Root call proc_printmsg mov al, '>' mov ah, 0Eh mov bx, 07h int 10h mov al, 20h mov ah, 0Eh mov bx, 07h int 10h mov ah,03h mov bx,07h int 10h mov Byte Ptr [CursorColumn],dl loc_rw_char_again: call proc_rw_char mov Byte Ptr [CommandBuffer]+79,0 loc_move_command: mov CX, 8 xor SI, SI mov byte ptr [CmdArgStart],1 mov DI, offset CommandBuffer next_command_char: mov al, byte ptr [SI][CommandBuffer] inc si cmp al, 20h ja short pass_space_control jb short pass_move_command cmp cx, 8 jb short pass_move_command cmp si,79 jb short next_command_char jmp short pass_move_command pass_space_control: cmp al,61h jb short pass_capitalize cmp al,7Ah ja short pass_capitalize and al,0DFh pass_capitalize: stosb inc byte ptr [CmdArgStart] loop short next_command_char pass_move_command: mov byte ptr [DI],0 call command_interpreter mov cx,79 mov di,offset CommandBuffer xor al,al rep stosb cmp byte ptr [Program_Exit], 0 ja return_to_msdos mov al,0Dh mov ah, 0Eh int 10h mov al,0Ah int 10h jmp loc_TRDOS_prompt ; loop return_to_msdos: retn proc_dos_prompt endp proc_rw_char proc near push es xor cx,cx mov es,cx readnextchar: xor ah,ah int 16h and al,al jz short loc_arrow cmp al,0E0h jz short loc_arrow cmp al,08h jnz short char_return loc_back: cmp dl,Byte ptr [CursorColumn] ja short prev_column jmp short readnextchar prev_column: dec dl set_cursor_pos: mov ah,02h int 10h ; xor bh,bh mov bl,dl sub bl,byte ptr [CursorColumn] mov cx,1 mov ah,09h mov al,20h mov Byte Ptr [CommandBuffer][BX],al mov bl,7 loc_write_it: int 10h mov dl,Byte Ptr ES:[CCCpointer] jmp short readnextchar loc_arrow: cmp AH,4Bh jz short loc_back cmp AH,53h jz short loc_back cmp AH,4Dh jnz short readnextchar cmp dl,79 jnb short readnextchar inc dl jmp short set_cursor_pos char_return: mov bl,dl ; xor bh,bh sub bl,byte ptr [CursorColumn] mov ah,0Eh cmp al,20h jb short loc_escape mov Byte Ptr [CommandBuffer][BX],al mov bl,7 cmp dl,79 jb short loc_write_it jmp short readnextchar loc_escape: cmp al,1Bh jnz short pass_escape pop es retn pass_escape: cmp al,0Dh jnz short readnextchar int 10h mov al,0Ah int 10h pop es retn proc_rw_char endp proc_print_directory proc near mov word ptr [Dir_Count],0 mov word ptr [File_Count],0 mov word ptr [Total_FSize], 0 mov word ptr [Total_FSize]+2, 0 call proc_clear_screen mov si, offset Dir_Drive_Str call proc_printmsg mov si, offset Vol_Serial_Header call proc_printmsg mov ah, 0Eh mov bx, 07h mov al,0Dh int 10h mov al,0Ah int 10h mov al,0Dh int 10h mov al,0Ah int 10h call proc_change_prompt_dir_string push ds pop es mov byte ptr [DirBuff_CurrentEntry], 0 mov byte ptr [DirBuff_SectorOffset], 0 mov byte ptr [PrintDir_RowCounter], 16 xor bl,bl mov bh, byte ptr [DirBuff_Drv] mov si, offset Logical_DOSDisks add si, bx cmp byte ptr [SI][LD_FATType], 2 ja short print_FAT32_directory cmp byte ptr [Current_DirLevel], 0 ja short print_sub_directory print_FAT_root_directory: call proc_load_root_directory jc loc_dir_ok mov word ptr [DirBuff_EntryCounter], 512 mov si, offset Directory_Buffer jmp short check_dir_entry print_FAT32_directory: print_sub_directory: mov word ptr [DirBuff_EntryCounter], 0 mov ax, word ptr [Current_DirFCluster] mov dx, word ptr [Current_DirFCluster]+2 jmp short loc_cont_to_load_dir_2 loc_cont_to_load_dir_1: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 loc_cont_to_load_dir_2: call proc_load_directory jc loc_dir_ok mov si, offset Directory_Buffer check_dir_entry: cmp Byte Ptr [SI],0 ; Is it never used entry? jna loc_dir_ok cmp Byte Ptr [SI],0E5h ; Is it a deleted file? je loc_next_entry mov bl,Byte Ptr [SI]+0Bh test bl,08h ; Is it a volume name or long name entry? jnz loc_next_entry test bl, byte ptr [DirEntryAttr] jz loc_next_entry test bl, byte ptr [DirEntryAttr]+1 jnz loc_next_entry push si cmp byte ptr [DirEntryFilters], 0 jna short loc_dfname_use_this mov di, si mov si, offset Dir_File_Name mov cx, 8 loc_lodsb_dfname_1: lodsb cmp al, '*' je short loc_check_dfname_extension pass_dfname_everyc_check: cmp al, '?' je short loc_scasb_dfname_3 pass_dfname_anyc_check: cmp al, 20h jnb short loc_scasb_dfname loc_lodsb_dfname_2: cmp byte ptr [DI], 20h jnb short loc_dfname_next_entry jmp short loc_dfname_use_this loc_scasb_dfname: cmp al, byte ptr [DI] jne short loc_dfname_next_entry loc_scasb_dfname_3: inc di loop loc_lodsb_dfname_1 loc_check_dfname_extension: cmp byte ptr [DirEntryFilters]+1, 0 jna short loc_dfname_use_this pop di ; pushed si push di mov si, offset Dir_File_Name add si, 8 add di, 8 mov cx, 3 loc_lodsb_dfname_4: lodsb cmp al, '*' je short loc_dfname_use_this pass_dfname_everycext_check: cmp al, '?' je short loc_scasb_dfname_6 pass_dfname_anycext_check: cmp al, 20h jnb short loc_scasb_dfname_ext loc_lodsb_dfname_5: cmp byte ptr [DI], 20h jnb short loc_dfname_next_entry jmp short loc_dfname_use_this loc_scasb_dfname_ext: cmp al, byte ptr [DI] jne short loc_dfname_next_entry loc_scasb_dfname_6: inc di loop loc_lodsb_dfname_4 loc_dfname_use_this: pop si test bl,10h ; Is it a directory? jz short loc_not_dir inc word ptr [Dir_Count] push si mov cx, 10 mov si, offset Type_Dir ; '<DIR> ' mov di, offset Dir_Or_FileSize rep movsb ; move 10 bytes pop si jmp short loc_dir_attribute loc_dfname_next_entry: pop si jmp loc_next_entry loc_not_dir: inc word ptr [File_Count] mov ax, Word Ptr [SI]+1Ch ; File Size L mov dx, Word Ptr [SI]+1Eh ; File Size H add word ptr [Total_FSize], ax adc word ptr [Total_FSize]+2, dx mov di,9 loc_dir_rdivide: mov cx,10 ; 16 bit divisor call Rx_Dos_Div32 ; 32 bit divide add bl, '0' ; to make visible mov Byte Ptr [Dir_Or_FileSize][DI],bl dec di cmp ax,0 ja short loc_dir_rdivide cmp dx,0 ja short loc_dir_rdivide loc_dir_fill_space: mov Byte Ptr [Dir_Or_FileSize][DI],20h cmp di,0 jna short loc_dir_attribute dec di jmp short loc_dir_fill_space loc_dir_attribute: mov word ptr [File_Attribute], 2020h mov word ptr [File_Attribute]+2, 2020h mov bl, Byte Ptr [SI]+0Bh cmp bl, 20h ; Is it an archive file? jb short loc_dir_pass_arch mov Byte Ptr [File_Attribute]+3,'A' loc_dir_pass_arch: and bl,7 jz short loc_dir_file_name mov bh,bl and bl,3 cmp bh,bl jna short loc_dir_pass_s mov byte ptr [File_Attribute], 'S' loc_dir_pass_s: and bl,2 jz short loc_dir_pass_h mov byte ptr [File_Attribute]+1, 'H' loc_dir_pass_h: and bh,1 jz short loc_dir_file_name mov byte ptr [File_Attribute]+2, 'R' loc_dir_file_name: mov bx, word ptr [SI]+18h ; Date mov dx, word ptr [SI]+16h ; Time push si mov cx, 8 mov di, offset File_Name rep movsb ; move 8 bytes mov Byte Ptr [DI],20h inc di mov cx, 3 rep movsb ; move 3 bytes pop si Dir_Date_start: mov ax, bx ; Date and ax, 00011111b ; Day Mask aam ; Q([AL]/10)->AH ; R([AL]/10)->AL ; [AL]+[AH]= Day as BCD or ax, '00' ; Convert to ASCII xchg al,ah mov word ptr [File_Day],ax mov ax, bx mov cl, 5 shr ax, cl ; shift right 5 times and ax, 00001111b ; Month Mask aam or ax, '00' xchg ah,al mov word ptr [File_Month],ax mov ax, bx mov cl, 9 shr ax, cl and ax, 01111111b ; Result = Year - 1980 add ax, 1980 mov cl, 10 div cl ; Q -> AL, R -> AH or ah, '0' mov byte ptr [File_Year]+3,ah aam xchg ah, al or ah, '0' ; Convert to ASCII mov byte ptr [File_Year]+2,ah aam xchg al, ah or ax, '00' mov word ptr [File_Year],ax Dir_Time_start: mov ax, dx ; Time mov cl, 5 shr ax, cl ; shift right 5 times and ax, 0000111111b ; Minute Mask aam or ax, '00' xchg ah,al mov word ptr [File_Minute],ax mov al, dh shr al, 1 shr al, 1 shr al, 1 ; ax = hours aam or ax, '00' xchg ah, al mov word ptr [File_Hour],ax loc_show_line: push si mov si, offset File_Name mov cx, 46 mov ah, 0Eh mov bx, 07h loop_loc_dir_entry: lodsb int 10h loop loop_loc_dir_entry pop si mov al,0Dh int 10h mov al,0Ah int 10h sub byte ptr [PrintDir_RowCounter], 1 jna Pause_dir_scroll loc_next_entry: dec word ptr [DirBuff_EntryCounter] cmp word ptr [DirBuff_EntryCounter], 0 jna short loc_dir_ok add si, 32 inc byte ptr [DirBuff_CurrentEntry] cmp byte ptr [DirBuff_CurrentEntry], 15 jna check_dir_entry mov bh, byte ptr [DirBuff_Drv] xor bl, bl mov si, offset Logical_DOSDisks add si, bx mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp byte ptr [Current_DirLevel],0 ja short pass_load_next_rdir_sector cmp byte ptr [SI][LD_FATType],2 ja short pass_load_next_rdir_sector cmp bl, byte ptr [DirBuff_LastSector] jna print_FAT_root_directory jmp short loc_dir_ok pass_load_next_rdir_sector: cmp bl, byte ptr [DirBuff_LastSector] jna loc_cont_to_load_dir_1 load_next_dir_cluster: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 ; push si call proc_get_next_cluster ; pop si jc short loc_dir_ok cmp al, 0F6h jna short put_dirbuff_cluster_values cmp byte ptr [SI][LD_FATType],1 ja short loc_FAT16_eoc_check cmp ah, 0Fh jb short put_dirbuff_cluster_values jmp short loc_dir_ok loc_FAT16_eoc_check: cmp byte ptr [SI][LD_FATType],2 ja short loc_FAT32_eoc_check cmp ah, 0FFh jnb short loc_dir_ok put_dirbuff_cluster_values: xor bl, bl mov bh, byte ptr [DirBuff_Drv] ; mov word ptr [DirBuff_NextCluster], ax ; mov word ptr [DirBuff_NextCluster]+2, dx jmp loc_cont_to_load_dir_2 loc_FAT32_eoc_check: cmp ah, 0FFh jb short put_dirbuff_cluster_values cmp dx, 0FFFh jb short put_dirbuff_cluster_values loc_dir_ok: mov ax, word ptr [Dir_Count] mov di, offset Decimal_Dir_Count cmp ax, 10 jb short pass_ddc inc di cmp ax, 100 jb short pass_ddc inc di cmp ax, 1000 jb short pass_ddc inc di cmp ax, 10000 jb short pass_ddc inc di pass_ddc: mov byte ptr [DI]+1, 0 loc_ddc_rediv: xor dx, dx mov cx, 10 div cx add dl, "0" mov byte ptr [DI], dl dec DI cmp ax, 0 ja short loc_ddc_rediv mov ax, word ptr [File_Count] mov di, offset Decimal_File_Count cmp ax, 10 jb short pass_dfc inc di cmp ax, 100 jb short pass_dfc inc di cmp ax, 1000 jb short pass_dfc inc di cmp ax, 10000 jb short pass_dfc inc di pass_dfc: mov byte ptr [DI]+1, 0 loc_dfc_rediv: xor dx, dx mov cx, 10 div cx add dl, "0" mov byte ptr [DI], dl dec DI cmp ax, 0 ja short loc_dfc_rediv mov di, offset TFS_Dec_End mov byte ptr [DI], 0 mov ax, word ptr [Total_FSize] mov dx, word ptr [Total_FSize]+2 mov cx, 10 rediv_tfs_hex: call Rx_Dos_Div32 add bl, "0" dec DI mov byte ptr [DI], bl cmp ax, 0 ja short rediv_tfs_hex cmp dx, 0 ja short rediv_tfs_hex mov word ptr [TFS_Dec_Begin], DI mov si, offset Decimal_File_Count_Header call proc_printmsg mov si, offset str_files call proc_printmsg mov si, offset str_dirs call proc_printmsg mov si, word ptr [TFS_Dec_Begin] call proc_printmsg mov si, offset str_bytes call proc_printmsg retn Pause_dir_scroll: xor ah, ah int 16h cmp al,1Bh je loc_dir_ok mov byte ptr [PrintDir_RowCounter], 16 ; Reset counter jmp loc_next_entry File_Count: dw 0 Dir_Count: dw 0 Decimal_File_Count_Header: db 0Dh, 0Ah Decimal_File_Count: db 6 dup(0) str_files: db " file(s) & " Decimal_Dir_Count: db 6 dup(0) str_dirs: db " directory(s) ", 0Dh, 0Ah, 0 Total_FSize: dd 0 TFS_Dec_Begin: dw 0 db 10 dup(0) TFS_Dec_End: db 0 str_bytes: db " byte(s) in file(s)", 0Dh, 0Ah, 0 proc_print_directory endp proc_change_current_drive proc near ; INPUT al= logical dos drive number cmp al, 1 ja short loc_change_current_drv0 loc_init_drv_fd: mov dl, al call floppy_drv_init jnc short loc_change_current_drv1 retn loc_change_current_drv0: mov si, offset Logical_DOSdisks mov ah, al xor al, al add si, ax loc_change_current_drv1: mov al, byte ptr [SI][LD_Name] sub al, 'A' jc short loc_return_change_drive mov byte ptr [DirBuff_Drv], al mov byte ptr [Current_DirLevel], 0 mov byte ptr [Dir_Str], 0 cmp byte ptr [SI][LD_FATType], 2 ja short loc_get_FAT32_bs_volume_name push word ptr [SI][LD_BPB][VolumeID] pop word ptr [Current_VolSerial1] push word ptr [SI][LD_BPB][VolumeID]+2 pop word ptr [Current_VolSerial2] mov word ptr [Current_DirFCluster], 0 mov word ptr [Current_DirFCluster]+2, 0 mov word ptr [DirBuff_DirCluster], 0 mov word ptr [DirBuff_DirCluster]+2, 0 jmp short loc_init_ccd_volume loc_get_FAT32_bs_volume_name: push word ptr [SI][LD_BPB][FAT32_RootFClust] pop word ptr [Current_DirFCluster] push word ptr [SI][LD_BPB][FAT32_RootFClust]+2 pop word ptr [Current_DirFCluster]+2 mov word ptr [DirBuff_DirCluster], 0 mov word ptr [DirBuff_DirCluster]+2, 0 push word ptr [SI][LD_BPB][FAT32_VolID] pop word ptr [Current_VolSerial1] push word ptr [SI][LD_BPB][FAT32_VolID]+2 pop word ptr [Current_VolSerial2] loc_init_ccd_volume: call proc_get_volume_name mov al, byte ptr [DirBuff_Drv] mov byte ptr [Current_DosDisk], al clc loc_return_change_drive: retn proc_change_current_drive endp command_interpreter proc near cmp_cmd_dir: mov byte ptr [Program_Exit],0 mov cx,3 xor si,si mov di, offset Cmd_Dir get_char_dir: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne cmp_cmd_cd loop get_char_dir mov al, byte ptr [CommandBuffer][SI] cmp al, 20h ja loc_cmd_failed get_dfname_fchar: inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_dfname_fchar jb loc_print_dir_call_all cmp al, '-' jne pass_dir_attr_chars get_next_attr_char: mov word ptr [DirEntryFilters], 0 inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_next_attr_char jb loc_print_dir_call_flt and al, 0DFh cmp al, 'D' jne short pass_only_directories mov byte ptr [DirEntryAttr], 10h mov byte ptr [DirEntryAttr]+1, 0 jmp loc_print_dir_call_attr pass_only_directories: cmp al, 'F' jne short pass_only_files mov byte ptr [DirEntryAttr], 0FFh mov byte ptr [DirEntryAttr]+1, 10h jmp loc_print_dir_call_attr pass_only_files: mov byte ptr [DirEntryAttr], 0h mov byte ptr [DirEntryAttr]+1, 0h check_attr_s: cmp al, 'S' jne short pass_attr_s or byte ptr [DirEntryAttr], 4 inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h jna short loc_print_dir_call_attr and al, 0DFh pass_attr_s: cmp al, 'H' jne short pass_attr_h or byte ptr [DirEntryAttr], 2 inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h jna short loc_print_dir_call_attr and al, 0DFh jmp short check_attr_s pass_attr_h: cmp al, 'R' jne short pass_attr_r or byte ptr [DirEntryAttr], 1 inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h jna short loc_print_dir_call_attr and al, 0DFh jmp short check_attr_s pass_attr_r: cmp al, 'A' jne short loc_print_dir_call_attr or byte ptr [DirEntryAttr], 20h inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h jna short loc_print_dir_call_attr and al, 0DFh jmp short check_attr_s pass_dir_attr_chars: mov word ptr [DirEntryFilters], 1 add si, offset CommandBuffer mov di, offset Dir_File_Name call proc_convert_file_name mov byte ptr [DI], 0 sub di, offset Dir_File_Name cmp di, 8 jna short loc_print_dir_call_flt mov byte ptr [DirEntryFilters]+1, 1 jmp short loc_print_dir_call_flt loc_print_dir_call_all: mov word ptr [DirEntryFilters], 0 loc_print_dir_call_flt: mov byte ptr [DirEntryAttr], 0FFh mov byte ptr [DirEntryAttr]+1, 0 loc_print_dir_call_attr: call proc_print_directory jc loc_not_ready_read_err retn cmp_cmd_cd: mov ax, word ptr [CommandBuffer] cmp ax, 'DC' jne cmp_cmd_drive mov si, 2 cmp byte ptr [CommandBuffer][SI], 20h ja loc_cmd_failed get_char_cd: inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_char_cd jb loc_cmd_cd_return get_next_cd_char: mov ah, byte ptr [CommandBuffer][SI]+1 cmp ah, ':' jne short pass_drive_change mov ah, byte ptr [CommandBuffer][SI]+2 cmp ah, 20h ja loc_cmd_failed and al, 0DFh sub al, 'A' jc loc_cmd_failed cmp al, byte ptr [Last_Dos_DiskNo] ja short loc_cd_drive_not_ready call proc_change_current_drive jc short loc_cd_drive_not_ready jmp replace_current_dir_path loc_cd_drive_not_ready: mov si, offset Msg_Not_Ready_Read_Err call proc_printmsg retn pass_drive_change: cmp al, "." jne short pass_cd_dot_check cmp ah, 20h jna short loc_cmd_cd_return cmp ah, "." jne loc_cmd_failed cmp byte ptr [CommandBuffer][SI]+2, 20h ja loc_cmd_failed mov al, byte ptr [Current_DirLevel] cmp al, 0 jna short loc_cmd_cd_return dec al mov byte ptr [Last_DirLevel], al jmp short pass_cd_parse_dir_name pass_cd_dot_check: add si, offset CommandBuffer call proc_parse_dir_name pass_cd_parse_dir_name: call proc_change_current_directory xor bl,bl mov bh, byte ptr [DirBuff_Drv] mov di, offset Logical_DOSdisks add di, bx mov al, byte ptr [Current_DirLevel] mov byte ptr [DI][LD_CDirLevel],al mov si, offset Current_Path add di, LD_CurrentDirectory mov cx, 64 rep movsw call proc_change_prompt_dir_string loc_cmd_cd_return: retn cmp_cmd_drive: ; C:, D:, E: etc. mov ax, word ptr [CommandBuffer] cmp ah, ':' jne short cmp_cmd_ver mov ah, byte ptr [CommandBuffer]+2 cmp ah, 20h ja loc_cmd_failed and al, 0DFh sub al, 'A' jc loc_cmd_failed cmp al, byte ptr [Last_Dos_DiskNo] ja short loc_cd_drive_not_ready call proc_change_current_drive jc loc_cd_drive_not_ready replace_current_dir_path: xor bl, bl mov bh, byte ptr [DirBuff_Drv] mov si, offset Logical_DOSdisks add si, bx mov al, byte ptr [SI][LD_CDirLevel] mov byte ptr [Current_DirLevel],al mov byte ptr [Last_DirLevel],al add si, LD_CurrentDirectory mov di, offset Current_Path mov cx, 64 rep movsw cmp al, 0 jna short loc_cmd_cd_return jmp short pass_cd_parse_dir_name cmp_cmd_ver: mov cx,3 xor si,si mov di, offset Cmd_Ver get_char_ver: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_exit loop get_char_ver mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed mov si, offset Program_Version call proc_printmsg retn cmp_cmd_exit: mov cx,4 xor si,si mov di, offset Cmd_Exit get_char_exit: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_prompt loop get_char_exit mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed mov byte ptr [Program_Exit], 1 retn cmp_cmd_prompt: mov cx,6 xor si,si mov di, offset Cmd_Prompt get_char_prompt: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_volume loop get_char_prompt mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed get_prompt_name_fchar: inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_prompt_name_fchar ja short loc_change_prompt_label mov si, offset TRDOSPromptLabel mov word ptr [SI], "RT" inc si inc si mov word ptr [SI], "OD" inc si inc si mov byte ptr [SI], "S" inc si mov byte ptr [SI], 0 loc_cmd_prompt_return: retn loc_change_prompt_label: ; push ds ; pop es mov cx, 11 add si, offset CommandBuffer mov di, offset TRDOSPromptLabel put_char_new_prompt_label: lodsb cmp al, 20h jb short pass_put_new_prompt_label stosb loop put_char_new_prompt_label pass_put_new_prompt_label: mov byte ptr [DI], 0 retn cmp_cmd_volume: mov cx,6 xor si,si mov di, offset Cmd_Volume get_char_volume: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short check_vol_str loop get_char_volume mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed get_vol_drive_name_fchar: inc si get_vol_drive_name_fchar1: mov al, byte ptr [CommandBuffer][SI] cmp al, 20h ja short pass_vol_current_drive je short get_vol_drive_name_fchar mov al, byte ptr [DirBuff_Drv] jmp short loc_get_volume_size_info check_vol_str: cmp SI, 4 jne short cmp_cmd_longname cmp al,20h ja loc_cmd_failed jmp short get_vol_drive_name_fchar1 pass_vol_current_drive: cmp al, 'A' jb loc_cmd_failed cmp al, 'z' ja loc_cmd_failed cmp al, 'Z' jna short pass_vol_drv_capitalize cmp al, 'a' jb loc_cmd_failed and al, 0DFh pass_vol_drv_capitalize: inc si mov ah, byte ptr [CommandBuffer][SI] cmp ah, ":" jne loc_cmd_failed sub al, 'A' loc_get_volume_size_info: call proc_volume_total_free_space jc loc_cd_drive_not_ready retn cmp_cmd_longname: mov cx,8 xor si,si mov di, offset Cmd_LongName get_char_longname: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_date loop get_char_longname mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed get_longname_fchar: inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_longname_fchar jb short pass_find_longname add si, CommandBuffer call proc_find_longname pass_find_longname: retn cmp_cmd_date: mov cx,4 xor si,si mov di, offset Cmd_Date get_char_date: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_time loop get_char_date mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed call proc_show_date call proc_set_date retn cmp_cmd_time: mov cx,4 xor si,si mov di, offset Cmd_Time get_char_time: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne short cmp_cmd_run loop get_char_time mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed call proc_show_time call proc_set_time retn cmp_cmd_run: mov cx,3 xor si,si mov di, offset Cmd_Run get_char_run: mov al, byte ptr [CommandBuffer][SI] inc si scasb jne loc_cmd_failed loop get_char_run mov al, byte ptr [CommandBuffer][SI] cmp al,20h ja loc_cmd_failed get_runfile_fchar: inc si mov al, byte ptr [CommandBuffer][SI] cmp al, 20h je short get_runfile_fchar jnb short loc_find_runfile retn loc_find_runfile: add si, CommandBuffer push ds pop es mov di, offset Dir_File_Name call proc_convert_file_name cmp byte ptr [Dir_File_Name]+8, "C" jne short loc_check_exe_file cmp byte ptr [Dir_File_Name]+9, "O" jne short loc_check_exe_file cmp byte ptr [Dir_File_Name]+10, "M" jne loc_cmd_failed mov byte ptr [EXE_ID], 0 jmp short loc_find_load_executable_file loc_check_exe_file: cmp word ptr [Dir_File_Name]+8, "XE" jne loc_cmd_failed cmp byte ptr [Dir_File_Name]+10, "E" jne loc_cmd_failed mov byte ptr [EXE_ID], 'E' loc_find_load_executable_file: xor bl, bl mov bh, byte ptr [DirBuff_Drv] cmp byte ptr [Current_DirLevel], 0 ja short loc_find_runfile_next_sec1 cmp byte ptr [Current_FS], 2 ja short loc_find_runfile_next_sec1 call proc_load_root_directory jc loc_runfile_notfound jmp short loc_find_runfile_cont loc_find_runfile_next_sec1: mov ax, word ptr [Current_DirFCluster] mov dx, word ptr [Current_DirFCluster]+2 loc_find_runfile_next_sec2: call proc_load_directory jc loc_runfile_notfound loc_find_runfile_cont: mov si, offset Dir_File_Name xor ax, ax xor cx, cx mov bx, 1800h ; Except volume label and dirs call proc_find_direntry jnc loc_runfile_found xor bl, bl mov bh, byte ptr [DirBuff_Drv] cmp byte ptr [Current_DirLevel], 0 ja short pass_loc_rf_load_next_root_sector cmp byte ptr [Current_FS], 2 ja short pass_loc_rf_load_next_root_sector mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp bl, byte ptr [DirBuff_LastSector] ja short loc_runfile_notfound call proc_load_root_directory jc short loc_runfile_notfound jmp short loc_find_runfile_cont pass_loc_rf_load_next_root_sector: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp bl, byte ptr [DirBuff_LastSector] jna short loc_find_runfile_next_sec2 xor bl, bl call proc_get_next_cluster jc short loc_runfile_notfound cmp al, 0F6h jna short loc_find_runfile_next_sec2 cmp byte ptr [Current_FS], 1 ja short find_runfile_FAT16_eoc_check cmp ah, 0Fh jb short loc_find_runfile_next_sec2 jmp short loc_runfile_notfound find_runfile_FAT16_eoc_check: cmp byte ptr [Current_FS], 2 ja short find_runfile_FAT32_eoc_check cmp ah, 0FFh jnb short loc_runfile_notfound jmp loc_cd_find_dir_next_sec2 find_runfile_FAT32_eoc_check: cmp ah, 0FFh jb loc_find_runfile_next_sec2 cmp dx, 0FFFh jb loc_find_runfile_next_sec2 loc_runfile_notfound: mov si, offset Msg_File_Not_Found call proc_printmsg stc retn loc_runfile_found: mov al, 32 mul cl mov si, ax add si, offset Directory_Buffer mov ax, word ptr [SI]+28 ; FileSize Low Word mov dx, word ptr [SI]+30 ; FileSize High Word cmp dx, 0 ja loc_cmd_failed cmp ax, 0 jna loc_cmd_failed mov word ptr [Program_Size], ax mov word ptr [Program_Size]+2, dx mov ax, word ptr [SI]+26 ; First Cluster Low Word mov dx, word ptr [SI]+20 ; First Cluster High Word cmp dx, 0 ja short pass_runfile_fc_check cmp ax, 2 jb loc_cmd_failed pass_runfile_fc_check: push ax push dx xor dx, dx mov ax, offset RunFile_Buffer mov bx, 16 div bx mov bx, ds add ax, bx mov word ptr [Run_Segment], ax mov word ptr [Run_Offset], 100h pop dx pop ax xor bl,bl mov bh, byte ptr [DirBuff_Drv] mov di, word ptr [Run_Offset] push word ptr [Run_Segment] pop es call proc_load_file jc loc_not_ready_read_err xor bx, bx mov es, bx mov bx, word ptr ES:[80h] ; Int 20h Offset mov word ptr [INT20h_Offset], bx mov bx, word ptr ES:[82h] ; Int 20h Segment mov word ptr [INT20h_segment], bx mov si, offset Run_Com_INT20h_Handler mov di, 80h mov word ptr ES:[DI], si ; Temporary INT20h handler mov si, ds mov word ptr ES:[DI]+2, si ; Temporary INT20h handler mov es, word ptr [Run_Segment] ; Program segment to run mov word ptr [StackPointer], sp mov word ptr [BasePointer], bp xor bx,bx mov word ptr ES:[BX], 20CDh ; INT 20h (CD20h) for "RET" cmp byte ptr [EXE_ID], 0 jna short far_jump_to_com_file loc_relocate_exe_items: ; This code written by Erdogan Tan ; by using "Dissecting DOS" book by ; Michael Podanoffsky (Rx_DOS) ; and source code by ; Alexei A. Frounze (OS for Dummies Loader) mov ax, word ptr [Run_Segment] add ax, 10h mov es, ax add ax, word ptr ES:[08h] ;Size of header, in paragraphs mov cx, word ptr ES:[06h] ;Number of relocation items mov bx, word ptr ES:[18h] ;Relocation table offset jcxz short exe_hdr_relocation_done exe_hdr_relocation_cycle: mov di, word ptr ES:[BX] ;Item Offset mov dx, word ptr ES:[BX+2] ;Item Segment (Relative] add dx, ax ;Item Segment (Absolute) push es mov es, dx add word ptr ES:[DI], ax ;Fixup pop es add bx, 4 loop exe_hdr_relocation_cycle exe_hdr_relocation_done: mov bx, ax add bx, word ptr ES:[0Eh] ;Initial SS Value mov ss, bx mov sp, word ptr ES:[10h] ;Initial SP Value add ax, word ptr ES:[16h] ;Initial CS Value mov bx, word ptr [Run_Segment] mov word ptr [Run_Segment], ax mov ax, word ptr ES:[14h] ;Intial IP Value mov word ptr [Run_Offset], ax jmp short far_jump_to_exe_file far_jump_to_com_file: mov bx, word ptr [Run_Segment] mov ss, bx mov sp, 0FFFEh far_jump_to_exe_file: mov ds, bx mov es, bx push bx xor ax, ax push ax mov cx, word ptr [Program_Size] mov bx, word ptr [Program_Size]+2 xor si, si xor di, di jmp dword ptr CS:[Run_Offset] Run_Com_INT20h_Handler: ; CPU comes here via INT 20h ; pop ax ; IP ; pop ax ; CS ; pop ax ; Flags push cs pop ds push ds pop ss mov sp, word ptr [StackPointer] mov bp, word ptr [BasePointer] xor ax, ax mov es, ax push word ptr [INT20h_Offset] pop word ptr ES:[80h] push word ptr [INT20h_Segment] pop word ptr ES:[82h] push ds pop es sti retn Program_Size: dd 0 EXE_ID: db 0 StackPointer: dw 0 BasePointer: dw 0 INT20h_Offset: dw 0 INT20h_Segment: dw 0 Run_Offset: dw 0 Run_Segment: dw 0 loc_cmd_failed: cmp byte ptr [CommandBuffer], 20h jna short loc_cmd_return mov si, offset Msg_Bad_Command call proc_printmsg loc_cmd_return: retn loc_not_ready_read_err: mov si, offset Msg_Not_Ready_Read_err call proc_printmsg retn command_interpreter endp floppy_drv_init proc near mov si, offset Disk_fd0 mov di, offset Logical_DOSDisks xor dh, dh cmp dl, 0 jna short pass_drv_init_fd1 add si, 40h add di, 100h pass_drv_init_fd1: mov byte ptr [DI][LD_MediaChanged],0 ; cmp byte ptr [SI][DPDType], 0 ; jna short pass_fd_read_boot_sector0 read_fd_boot_sector: push ds pop es push dx mov cx, 4 ; Retry Count read_fd_boot_sector_again: push cx mov cx, 1 mov ax, 0201h ; Read 1 sector mov bx, offset DOSBootSectorBuff int 13h pop cx jnc short use_fd_boot_sector_params loop read_fd_boot_sector_again pass_fd_read_boot_sector0: stc pass_fd_read_boot_sector1: pop dx retn use_fd_boot_sector_params: cmp word ptr [BS_Validation], 0AA55h jne short pass_fd_read_boot_sector0 ; cmp byte ptr [BS_BootSig], 29h ; jne short pass_fd_read_boot_sector0 cmp byte ptr [BPB_Media], 0F0h jb short pass_fd_read_boot_sector1 mov si, offset DOSBootSectorBuff push di add di, LD_BPB mov cx, 32 rep movsw pop si xor ax, ax mov Word Ptr [SI][LD_StartSector], AX mov Word Ptr [SI][LD_StartSector]+2,0 add AX,Word Ptr [SI][LD_BPB][ResSectors] mov Word Ptr [SI][LD_FATBegin], AX mov Word Ptr [SI][LD_FATBegin]+2, 0 mov AL,Byte Ptr [SI][LD_BPB][FATs] cbw mul Word Ptr [SI][LD_BPB][FATSecs] add AX,Word Ptr [SI][LD_FATBegin] mov Word Ptr [SI][LD_ROOTBegin], AX mov Word Ptr [SI][LD_ROOTBegin]+2, 0 mov Word Ptr [SI][LD_DATABegin], AX mov Word Ptr [SI][LD_DATABegin]+2, 0 mov AX,20h ; Size of a directory entry mul Word Ptr [SI][LD_BPB][RootDirEnts] add AX,511 mov cx,512 div cx add Word Ptr [SI][LD_DATABegin], AX adc Word Ptr [SI][LD_DATABegin]+2, 0 mov AX,Word Ptr [SI][LD_BPB][Sectors] mov Word Ptr [SI][LD_TotalSectors], AX mov Word Ptr [SI][LD_TotalSectors]+2,0 sub ax,Word Ptr [SI][LD_DATABegin] xor dx,dx xor ch,ch mov cl,Byte Ptr [SI][LD_BPB][SecPerClust] div cx mov word ptr [SI][LD_Clusters], AX mov byte ptr [SI][LD_FATType], 1 mov byte ptr [SI][LD_FSType], 0 mov word ptr [SI][LD_Clusters]+2, 0 ; Maximum Valid Cluster Number= AX +1 ; with 2 reserved clusters= AX +2 pop ax mov byte ptr [SI][LD_DParamEntry], al mov byte ptr [SI][LD_PhyDrvNo], al add al, 'A' mov byte ptr [SI][LD_Name], al mov byte ptr [SI][LD_DiskType], 1 mov byte ptr [SI][LD_LBAYes], 0 mov byte ptr [SI][LD_PartitionEntry], 0 mov byte ptr [SI][LD_MediaChanged], 1 retn floppy_drv_init endp proc_parse_dir_name proc near ; DS:SI = Directory String cmp byte ptr [SI], "/" jne short pass_reset_parse_sd_levels xor ah, ah mov byte ptr [Last_DirLevel],0 mov byte ptr [Current_DirLevel],0 jmp short repeat_parse_sd_name0 pass_reset_parse_sd_levels: mov ah, byte ptr [Current_DirLevel] mov byte ptr [Last_DirLevel],ah jmp short repeat_parse_sd_name2 repeat_parse_sd_name0: inc si repeat_parse_sd_name1: cmp byte ptr [SI], "/" je short repeat_parse_sd_name0 repeat_parse_sd_name2: cmp byte ptr [SI], 20h ja short pass_reset_dir_level jb short end_of_parse_dir_name jmp short repeat_parse_sd_name0 pass_reset_dir_level: inc ah cmp ah, 7 ja short end_of_parse_dir_name mov byte ptr [Last_DirLevel],ah mov cx, 12 mov di, offset Dir_File_Name loc_get_subdir_name: lodsb mov byte ptr [DI], al cmp al, 20h jna short end_of_subdir_name cmp al, "/" je short end_of_subdir_name inc di loop loc_get_subdir_name end_of_subdir_name: mov byte ptr [DI], 0 push ax push si mov si, offset Dir_File_Name mov al, byte ptr [Last_DirLevel] mov ah, 16 mul ah mov di, offset Current_Path add di, ax mov word ptr [DI]+12, 0 mov word ptr [DI]+14, 0 call proc_convert_file_name pop si pop ax cmp al, 0Dh jna short end_of_parse_dir_name mov ah, byte ptr [Last_DirLevel] jmp short repeat_parse_sd_name1 end_of_parse_dir_name: retn proc_parse_dir_name endp proc_convert_file_name proc near ; INPUT -> DS:SI = Dot File Name Location ; INPUT -> ES:DI = Dir Entry Format File Name Location push di mov cx, 11 mov al, 20h rep stosb pop di mov cx, 12 mov al, 2Eh cmp byte ptr [SI], 2Eh je short pass_dot_space loc_get_fchar: mov al, byte ptr [SI] cmp al, 61h jb short pass_name_capitalize cmp al, 7Ah ja short pass_name_capitalize and al, 0DFh mov byte ptr [SI], al pass_name_capitalize: cmp al, 21h jb short stop_convert_file cmp al, 2Eh jne short pass_dot_space add_space: cmp cx, 4 jna short inc_and_loop mov byte ptr [DI], 20h inc di dec cx jmp short add_space pass_dot_space: mov byte ptr [DI], al inc di inc_and_loop: inc si loop loc_get_fchar stop_convert_file: retn proc_convert_file_name endp Last_DirLevel: db 0 Dir_File_Name: db 13 dup(0) proc_change_current_directory proc near xor bl, bl mov bh, byte ptr [DirBuff_Drv] mov di, offset Logical_DOSDisks add di, bx mov ah, byte ptr [DI][LD_FATType] mov byte ptr [Current_FS], ah cmp ah, 2 jna short pass_fat32_fs_rdfc push word ptr [DI][LD_BPB][FAT32_RootFClust] pop word ptr [Current_FS_RDFC] push word ptr [DI][LD_BPB][FAT32_RootFClust]+2 pop word ptr [Current_FS_RDFC]+2 jmp short pass_fat_fs_rdfc check_fat32_root_dir0: mov ax, word ptr [Current_FS_RDFC] mov dx, word ptr [Current_FS_RDFC]+2 call proc_load_directory jc short retn_find_sub_dir0 push word ptr [Current_FS_RDFC] pop word ptr [Current_DirFCluster] push word ptr [Current_FS_RDFC]+2 pop word ptr [Current_DirFCluster]+2 jmp short pass_fat16_root_dir_loading pass_fat32_fs_rdfc: mov word ptr [Current_FS_RDFC], 0 mov word ptr [Current_FS_RDFC]+2, 0 pass_fat_fs_rdfc: mov al, byte ptr [Current_DirLevel] cmp al, 0 ja short pass_cd_root_dir_fixup check_fat32_root_dir1: cmp byte ptr [Current_FS], 2 ja short check_fat32_root_dir0 check_fat16_root_dir: call proc_load_root_directory jc short retn_find_sub_dir0 mov word ptr [Current_DirFCluster], 0 mov word ptr [Current_DirFCluster]+2, 0 pass_fat16_root_dir_loading: mov si, offset Current_Path add si, 16 cmp byte ptr [Last_DirLevel], 0 ja short loc_cd_find_directory mov byte ptr [Dir_Str],0 retn pass_cd_root_dir_fixup: cmp byte ptr [Last_DirLevel], 0 ja short pass_return_to_root_dir mov byte ptr [Current_DirLevel], 0 jmp short check_fat32_root_dir1 retn_find_sub_dir0: mov si, offset Msg_dir_not_found call proc_printmsg stc retn_find_sub_dir1: retn pass_return_to_root_dir: cmp al, byte ptr [Last_DirLevel] jb short locate_next_level_dir je short reload_current_dir mov al, byte ptr [Last_Dirlevel] mov byte ptr [Current_DirLevel], al reload_current_dir: mov ah, 16 mul ah mov si, offset Current_Path add si, ax mov ax, word ptr [SI]+12 mov dx, word ptr [SI]+14 jmp update_cdir_fclust_exit locate_next_level_dir: mov ah, 16 mul ah mov si, offset Current_Path add si, ax cmp byte ptr [SI]+16, 20h jna stc_retn_find_sub_dir ; mov ax, word ptr [SI]+12 ; mov dx, word ptr [SI]+14 add si, 16 loc_cd_find_dir_next_sec0: mov ax, word ptr [Current_DirFCluster] mov dx, word ptr [Current_DirFCluster]+2 loc_cd_find_dir_next_sec1: xor bl, bl loc_cd_find_dir_next_sec2: push si mov bh, byte ptr [DirBuff_Drv] call proc_load_directory pop si jc short retn_find_sub_dir0 loc_cd_find_directory: xor ax, ax ; No Filters mov bx, 0810h ; Directory xor cx, cx call proc_find_direntry jnc loc_directory_found cmp byte ptr [Current_DirLevel], 0 ja short pass_loc_cd_load_next_root_sec1 push si xor bl, bl mov bh, byte ptr [DirBuff_Drv] mov si, offset Logical_DOSdisks add si, bx cmp byte ptr [SI][LD_FATType], 2 ja short pass_loc_cd_load_next_root_sec0 mov bl, byte ptr [DirBuff_SectorOffset] inc bl pop si cmp bl, byte ptr [DirBuff_LastSector] ja short pass_loc_cd_load_next_root_sec2 jmp check_fat16_root_dir pass_loc_cd_load_next_root_sec0: pop si pass_loc_cd_load_next_root_sec1: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp bl, byte ptr [DirBuff_LastSector] jna short loc_cd_find_dir_next_sec2 pass_loc_cd_load_next_root_sec2: push si xor bl, bl mov bh, byte ptr [DirBuff_Drv] mov si, Offset Logical_DOSdisks add si, bx call proc_get_next_cluster pop si jc short retn_find_sub_dir cmp al, 0F6h jna short loc_cd_find_dir_next_sec1 cmp byte ptr [Current_FS], 1 ja short find_dir_FAT16_eoc_check cmp ah, 0Fh jb short loc_cd_find_dir_next_sec1 jmp short stc_retn_find_sub_dir find_dir_FAT16_eoc_check: cmp byte ptr [Current_FS], 2 ja short find_dir_FAT32_eoc_check cmp ah, 0FFh jnb short stc_retn_find_sub_dir jmp loc_cd_find_dir_next_sec1 find_dir_FAT32_eoc_check: cmp ah, 0FFh jb loc_cd_find_dir_next_sec1 cmp dx, 0FFFh jb loc_cd_find_dir_next_sec1 stc_retn_find_sub_dir: mov si, offset Msg_Dir_Not_Found call proc_printmsg stc retn loc_directory_found: push ax push dx mov al, byte ptr [Current_DirLevel] inc al mov byte ptr [Current_DirLevel], al mov ah, 16 mul ah mov si, offset Current_Path add si, ax pop dx pop ax mov word ptr [SI]+12, ax mov word ptr [SI]+14, dx update_cdir_fclust_exit: mov word ptr [Current_DirFCluster], ax mov word ptr [Current_DirFCluster]+2,dx xor bl,bl mov bh, byte ptr [DirBuff_Drv] call proc_load_directory jc short retn_find_sub_dir mov al, byte ptr [Current_DirLevel] cmp al, byte ptr [Last_DirLevel] jb locate_next_level_dir retn_find_sub_dir: retn proc_change_current_directory endp proc_find_direntry proc near ; SI = Sub Dir or File Name Offset ; BL = Attributes (AND) ; BH = Negative Attributes (NAND) ; CL = Current Entry ; CH = 0 ; AL > 0 -> Use Name Filters ; AH > 0 -> Use Extension Filters ; * = Every Chars ; ? = Any One Char ; Return -> CLC -> BX= Attributes ; BL= Attribute ; BH= 0 ; CL= CurrentDirEntry (16=Invalid) ; CH= 0 mov word ptr [DirEntryAttr], bx mov word ptr [DirEntryFilters], ax ; push ds ; pop es mov byte ptr [DirBuff_CurrentEntry], cl mov di, offset Directory_Buffer cmp cl, 0 jna short check_find_dir_entry push ax mov al, 32 mul cl add di, ax pop ax check_find_dir_entry: xor bl,bl push si cmp Byte Ptr [DI],0 ; Is it never used entry? jna pop_si_loc_find_dir_ok cmp Byte Ptr [DI],0E5h ; Is it a deleted file? je loc_find_dir_next_entry mov bl, byte ptr [DI]+0Bh test bl, byte ptr [DirEntryAttr] jnz short pass_check_attr_Zero cmp byte ptr [DirEntryAttr], 0 ja loc_find_dir_next_entry pass_check_attr_zero: test bl, byte ptr [DirEntryAttr]+1 jnz loc_find_dir_next_entry cmp bl, 0Fh jne short loc_direntry_not_longname pop si xor ax, ax xor dx, dx xor bh, bh xor ch, ch mov cl, byte ptr [DirBuff_CurrentEntry] retn loc_direntry_not_longname: mov bx, di mov cx, 8 loc_lodsb_find_dir_1: lodsb cmp al, '*' jne short pass_everychar_check cmp byte ptr [DirEntryFilters], 0 ja short loc_check_dirent_extension jmp short loc_scasb_find_dir pass_everychar_check: cmp al, '?' jne short pass_anychar_check cmp byte ptr [DirEntryFilters], 0 ja short loc_scasb_find_dir_3 jmp short loc_scasb_find_dir pass_anychar_check: cmp al, 20h jnb short loc_scasb_find_dir loc_lodsb_find_dir_2: cmp byte ptr [BX], 20h jnb short loc_find_dir_next_entry jmp short loc_find_dir_use_clusters loc_scasb_find_dir: cmp al, byte ptr [BX] jne short loc_find_dir_next_entry loc_scasb_find_dir_3: inc bx loop loc_lodsb_find_dir_1 loc_check_dirent_extension: pop si push si add si, 8 mov bx, di add bx, 8 mov cx, 3 loc_lodsb_find_dir_4: lodsb cmp al, '*' jne short pass_everycharext_check cmp byte ptr [DirEntryFilters]+1, 0 ja short loc_find_dir_use_clusters jmp short loc_scasb_find_dir_ext pass_everycharext_check: cmp al, '?' jne short pass_anycharext_check cmp byte ptr [DirEntryFilters]+1, 0 ja short loc_scasb_find_dir_6 jmp short loc_scasb_find_dir_ext pass_anycharext_check: cmp al, 20h jnb short loc_scasb_find_dir_ext loc_lodsb_find_dir_5: cmp byte ptr [BX], 20h jnb short loc_find_dir_next_entry jmp short loc_find_dir_use_clusters loc_scasb_find_dir_ext: cmp al, byte ptr [BX] jne short loc_find_dir_next_entry loc_scasb_find_dir_6: inc bx loop loc_lodsb_find_dir_4 loc_find_dir_use_clusters: pop si mov ax, word ptr [DI]+1Ah mov dx, word ptr [DI]+14h and dh, 0Fh mov bl, byte ptr [DI]+0Bh xor bh, bh xor ch, ch mov cl, byte ptr [DirBuff_CurrentEntry] clc retn loc_find_dir_next_entry: mov byte ptr [PreviousAttr], bl ; LongName check pop si inc byte ptr [DirBuff_CurrentEntry] cmp byte ptr [DirBuff_CurrentEntry], 15 ja short loc_find_dir_ok add di, 32 jmp check_find_dir_entry pop_si_loc_find_dir_ok: pop si loc_find_dir_ok: xor bx, bx mov cl, 16 stc retn DirEntryAttr: dw 0 DirEntryFilters: dw 0 PreviousAttr: db 0 proc_find_direntry endp proc_change_prompt_dir_string proc near mov di, offset Dir_Str cmp byte ptr [Current_DirLevel],0 jna short pass_write_path mov al, byte ptr [Current_DirLevel] mov byte ptr [DirLevel_Count], al mov si, offset Current_Path mov di, offset Dir_Str add si, 16 mov bx, si loc_write_path: mov cx, 8 path_write_dirname1: lodsb cmp al, 20h jna short pass_write_dirname1 mov byte ptr [DI], al inc di cmp di, offset End_Of_Dir_Str jnb short pass_write_path loop path_write_dirname1 cmp byte ptr [SI], 20h jna short pass_write_dirname2 jmp short loc_put_dot_cont_ext pass_write_dirname1: cmp al, 0Dh jna short pass_write_dirname2 mov si, bx add si, 8 cmp byte ptr [SI], 20h jna short pass_write_dirname2 loc_put_dot_cont_ext: mov byte ptr [DI],"." mov cx, 3 loc_check_dir_name_ext: lodsb inc di cmp al, 20h jna short pass_write_dirname2 mov byte ptr [DI], al cmp di, offset End_Of_Dir_Str jnb short pass_write_path loop loc_check_dir_name_ext inc di pass_write_dirname2: dec byte ptr [DirLevel_Count] cmp byte ptr [DirLevel_Count], 0 jna short pass_write_path add bx, 16 mov si, bx mov byte ptr [DI],"/" inc di jmp short loc_write_path pass_write_path: mov byte ptr [DI],0 retn DirLevel_Count: db 0 proc_change_prompt_dir_string endp proc_volume_total_free_space proc near ; INPUT AL = DOS Drive Number mov word ptr [FreeClusterCount], 0 mov word ptr [FreeClusterCount]+2, 0 xor bl, bl mov bh, al mov si, offset Logical_DOSDisks add si, bx add al, 'A' cmp al, byte ptr [SI] je short pass_vol_drv_name_check stc retn pass_vol_drv_name_check: push si push bx mov byte ptr [Vol_Drv_Name], al cmp byte ptr [SI][LD_FATType],2 ja short loc_vol_get_FAT32_vol_name cmp byte ptr [SI][LD_BPB][BootSignature], 29h jne short loc_start_calc_vol_space add si, LD_BPB+VolumeLabel mov di, offset Vol_Vol_Name mov cx, 11 rep movsb mov si, offset Volume_in_drive call proc_printmsg jmp short loc_start_calc_vol_space loc_vol_get_FAT32_vol_name: ; cmp byte ptr [SI][LD_BPB][FAT32_Bootsig], 29h ; jne short loc_start_calc_vol_space add si, LD_BPB+FAT32_VolLab mov di, offset Vol_Vol_Name mov cx, 11 rep movsb mov si, offset Volume_in_drive call proc_printmsg loc_start_calc_vol_space: pop bx pop si mov ax, word ptr [SI][LD_TotalSectors] mov dx, word ptr [SI][LD_TotalSectors]+2 push bx mov bx, word ptr [SI][LD_BPB][BytesPerSec] cmp byte ptr [SI][LD_FATType],2 ja short pass_vol_size_bytes_calc push word ptr [SI][LD_Clusters] pop word ptr [LastCluster] inc word ptr [LastCluster] ; cmp dx, 127 ; ja short pass_vol_size_bytes_calc call proc_mul32 jmp short pass_volsize_overflow pass_vol_size_bytes_calc: cmp bx, 1024 jnb short loc_vol_ax_div_bx push ax push dx xor dx, dx mov ax, 1024 div bx mov cx, ax pop dx pop ax call Rx_Dos_Div32 jmp short pass_volsize_overflow loc_vol_ax_div_bx: push ax push dx xor dx, dx mov ax, 1024 xchg ax, bx div bx mov bx, ax pop dx pop ax call Proc_Mul32 pass_volsize_overflow: pop bx mov di, offset Vol_Tot_Sec_Str_End ; mov byte ptr [DI], 0 mov cx, 10 loc_vol_div32_1_again: call Rx_Dos_Div32 add bl, '0' dec di mov byte ptr [DI], bl cmp ax, 0 ja short loc_vol_div32_1_again cmp dx, 0 ja short loc_vol_div32_1_again mov word ptr [Vol_Tot_Sec_Str_Start], DI cmp byte ptr [SI][LD_FATType], 2 jna loc_get_FAT_freespace mov ax, word ptr [SI][LD_StartSector] mov dx, word ptr [SI][LD_StartSector]+2 cmp byte ptr [SI][LD_LBAYes], 0 jna short pass_load_fat32_fsinfo_sec_lba push ax push dx ; mov byte ptr [DAP_BuffLBAyes], 1 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffPacketSize], 10h mov word ptr [DAP_BuffDestination], offset DosBootSectorBuff push ds pop word ptr [DAP_BuffDestination]+2 mov byte ptr [DAP_BuffNumOfBlocks], 1 mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_LBA_read pop dx pop ax jc short retn_get_lba_fs_info_sec loc_get_lba_fs_info_sec: cmp word ptr [BS_Validation], 0AA55h jne short retn_get_lba_fs_info_stc add ax, word ptr [BPB_FSinfo] adc dx, 0 ; mov byte ptr [DAP_BuffLBAyes], 1 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffPacketSize], 10h mov word ptr [DAP_BuffDestination], offset DosBootSectorBuff push ds pop word ptr [DAP_BuffDestination]+2 mov byte ptr [DAP_BuffNumOfBlocks], 1 mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_lba_read jnc short loc_check_fsinfo_signs retn_get_lba_fs_info_sec: retn retn_get_lba_fs_info_stc: stc retn pass_load_fat32_fsinfo_sec_lba: mov bx, offset DOSBootSectorBuff push ax push dx mov cx, 1 call proc_chs_read pop dx pop ax jc short retn_get_lba_fs_info_sec pass_get_chs_fs_info_sec: cmp word ptr [BS_Validation], 0AA55h jne short retn_get_lba_fs_info_stc add ax, word ptr [BPB_FSinfo] adc dx, 0 mov bx, offset DOSBootSectorBuff mov cx, 1 call proc_chs_read jc short retn_get_lba_fs_info_sec loc_check_FSINFO_signs: cmp word ptr [DOSBootSectorBuff], 5252h jne short retn_get_lba_fs_info_stc mov word ptr [DOSBootSectorBuff]+2, 4161h jne short retn_get_lba_fs_info_stc mov bx, offset DOSBootSectorBuff add bx, 484 cmp word ptr [BX], 7272h jne short retn_get_lba_fs_info_stc mov word ptr [BX]+2, 6141h jne short retn_get_lba_fs_info_stc add bx, 4 push word ptr [BX] pop word ptr [FreeClusterCount] push word ptr [BX]+2 pop word ptr [FreeClusterCount]+2 xor ah, ah mov al, byte ptr [SI][LD_BPB][SecPerClust] mov dx, [SI][LD_BPB][BytesPerSec] mul dx ; cmp dx, 0 ; ja short retn_get_lba_fs_info_stc mov bx, 1024 cmp ax, bx jb short pass_fsinfo_freesize_div_1024 div bx mov bx, ax mov ax, word ptr [FreeClusterCount] mov dx, word ptr [FreeClusterCount]+2 call Proc_Mul32 jmp short loc_vol_decimal_fat32_freesize pass_fsinfo_freesize_div_1024: xchg ax, bx div bx mov cx, ax mov ax, word ptr [FreeClusterCount] mov dx, word ptr [FreeClusterCount]+2 call Rx_Dos_Div32 loc_vol_decimal_fat32_freesize: mov di, offset Vol_Free_Clust_Str_End ; mov byte ptr [DI], 0 mov cx, 10 loc_vol_div32_3_again: call Rx_Dos_Div32 add bl, '0' dec di mov byte ptr [DI], bl cmp ax, 0 ja short loc_vol_div32_3_again cmp dx, 0 ja short loc_vol_div32_3_again mov word ptr [Vol_Free_Clust_Str_Start], DI mov si, offset Vol_Total_Sector_Header call proc_printmsg mov si, word ptr [Vol_Tot_Sec_Str_Start] call proc_printmsg mov si, offset VolSize_KiloBytes call proc_printmsg mov si, offset Vol_Free_Clusters_Header call proc_printmsg mov si, word ptr [Vol_Free_Clust_Str_Start] call proc_printmsg mov si, offset VolSize_KiloBytes call proc_printmsg pass_write_fat32_free_clusters_calc: retn loc_get_fat_freespace: mov ax, 2 mov dx, 0 loc_get_fcc_next_cluster: push ax push dx call proc_get_next_cluster jnc short loc_calc_free_fat_clusters pop dx pop ax retn loc_calc_free_fat_clusters: cmp ax, 0 ja short pass_inc_free_cluster_count inc word ptr [FreeClusterCount] pass_inc_free_cluster_count: pop dx pop ax inc ax cmp ax, word ptr [LastCluster] jna short loc_get_fcc_next_cluster xor ah, ah mov al, byte ptr [SI][LD_BPB][SecPerClust] mov dx, word ptr [SI][LD_BPB][BytesPerSec] mul dx ; cmp dx, 0 ; ja retn_get_lba_fs_info_stc mov dx, word ptr [FreeClusterCount] mul dx mov di, offset Vol_Free_Clust_Str_End ; mov byte ptr [DI], 0 mov cx, 10 loc_vol_div32_2_again: call Rx_Dos_Div32 add bl, '0' dec di mov byte ptr [DI], bl cmp ax, 0 ja short loc_vol_div32_2_again cmp dx, 0 ja short loc_vol_div32_2_again mov word ptr [Vol_Free_Clust_Str_Start], DI mov si, offset Vol_Total_Sector_Header call proc_printmsg mov si, word ptr [Vol_Tot_Sec_Str_Start] call proc_printmsg mov si, offset VolSize_Bytes call proc_printmsg mov si, offset Vol_Free_Clusters_Header call proc_printmsg mov si, word ptr [Vol_Free_Clust_Str_Start] call proc_printmsg mov si, offset VolSize_Bytes call proc_printmsg retn LastCluster: dw 0 FreeClusterCount: dd 0 Vol_Free_Clust_Str_Start: dw 0 Vol_Free_Clust_Str: db 10 dup(0) Vol_Free_Clust_Str_End: db 0 Vol_Free_Clusters_Header: db "Free Space : ", 0 Vol_Tot_Sec_Str_Start: dw 0 Vol_Tot_Sec_Str: db 10 dup(0) Vol_Tot_Sec_Str_End: db 0 Vol_Total_Sector_Header: db 0Dh, 0Ah, "Volume Size : ", 0 VolSize_Unit: dw 0 VolSize_KiloBytes: db " kilobytes", 0Dh, 0Ah, 0 VolSize_Bytes: db " bytes", 0Dh, 0Ah, 0 Volume_in_drive: db 0Dh, 0Ah, "Volume in drive " Vol_Drv_Name: db 30h db ":" db " is " Vol_Vol_Name: db 11 dup (30h) db 0Dh, 0Ah, 0 proc_volume_total_free_space endp proc_find_longname proc near ; INPUT DS:SI = DOS short file name input ; for example: "filename.ext" mov cx, 33 mov di, Offset LongFileName mov ax, 0 rep stosw mov byte ptr [LongNameFound],0 ; mov byte ptr [PreviousAttr], 0 ; Reset LongName Flag ; above instruction is for: "find file ; and check if it has long name" (? PreviousAttr= 0Fh) ; It is not needed during long name search but ; it is useful for short name search for delete/rename mov di, offset Dir_File_Name call proc_convert_file_name mov si, offset Dir_File_Name call proc_calculate_checksum mov byte ptr [LFN_Checksum], al xor bl, bl mov bh, byte ptr [DirBuff_Drv] mov di, offset Logical_DOSDisks add di, bx mov ah, byte ptr [DI][LD_FATType] mov byte ptr [Current_FS], ah cmp ah, 2 jna short pass_ln_fat32_fs check_ln_sub_dir: mov ax, word ptr [Current_DirFCluster] mov dx, word ptr [Current_DirFCluster]+2 loc_load_ln_next_sector: call proc_load_directory jc short retn_find_longname_stc jmp short loc_find_longname_next pass_ln_fat32_fs: mov al, byte ptr [Current_DirLevel] cmp al, 0 ja short check_ln_sub_dir loc_load_ln_fat_next_root_sector: call proc_load_root_directory jc short retn_find_longname_stc jmp short loc_find_longname_next retn_find_longname_stc: mov si, offset Msg_Not_Ready_Read_Err call proc_printmsg stc retn loc_find_longname_next: mov cl, 0 check_ln_dirbuff_next_entry: cmp byte ptr [LongNameFound], 0 jna short pass_check_ln_short_name mov si, offset Directory_Buffer mov al, 32 mul cl add si, ax mov di, offset Dir_File_Name push cx mov cx, 11 loc_ln_sn_comp: cmpsb jne short pass_loop_ln_sn_comp loop loc_ln_sn_comp pass_loop_ln_sn_comp: cmp cl, 0 jna short loc_longname_found mov byte ptr [LongNameFound], 0 pop cx jmp short pass_check_ln_short_name loc_longname_found: pop cx mov si, offset Msg_LongName call proc_printmsg mov si, offset nextline call proc_printmsg retn pass_check_ln_short_name: ; xor ch, ch ; mov si, offset LFN_NameFlt mov bl, 0Fh ; LFN Attr mov bh, 30h ; Not Dir or Archive Attr ; mov ax, 0101h ; Use name and ext filters call proc_find_direntry jc short pass_longname_found_1 cmp bl, 0Fh jne short pass_longname_found_0 ; Output DI = DirEntry Location mov ch, byte ptr [DI]+0Dh ; Checksum cmp ch, byte ptr [LFN_Checksum] jne short pass_longname_found_0 mov ah, byte ptr [DI] cmp ah, 41h jb short pass_longname_lastpart cmp ah, 45h ja short pass_longname_found_0 sub ah, 40h pass_longname_lastpart: dec ah mov al, 13 mul ah mov cx, 5 mov si, di inc si push di mov di, offset LongFileName add di, ax get_lfn_first_5_chars: lodsw stosb loop get_lfn_first_5_chars pop si push si add si, 14 mov cx, 6 get_lfn_middle_6_chars: lodsw stosb loop get_lfn_middle_6_chars pop si add si, 28 lodsw stosb lodsw stosb cmp byte ptr [LongFileName], 0 jna short pass_longname_found_2 mov byte ptr [LongNameFound], 1 pass_longname_found_2: mov cl, byte ptr [DirBuff_CurrentEntry] pass_longname_found_0: ; xor ch, ch inc cl cmp cl, 16 jb check_ln_dirbuff_next_entry pass_longname_found_1: mov bh, byte ptr [DirBuff_Drv] mov bl, byte ptr [DirBuff_SectorOffset] inc bl cmp byte ptr [Current_DirLevel], 0 ja short pass_loc_ln_load_next_root_sec1 cmp bl, byte ptr [DirBuff_LastSector] jna loc_load_ln_fat_next_root_sector cmp byte ptr [Current_FS], 2 ja short pass_loc_ln_load_next_root_sec2 jmp short retn_find_longname_notfound pass_loc_ln_load_next_root_sec1: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 cmp bl, byte ptr [DirBuff_LastSector] ja short pass_loc_ln_load_next_root_sec3 jmp loc_load_ln_next_sector pass_loc_ln_load_next_root_sec2: mov ax, word ptr [DirBuff_DirCluster] mov dx, word ptr [DirBuff_DirCluster]+2 pass_loc_ln_load_next_root_sec3: push si xor bl, bl mov si, Offset Logical_DOSdisks add si, bx call proc_get_next_cluster pop si jc short retn_find_longname_notfound cmp al, 0F6h jna loc_load_ln_next_sector cmp byte ptr [Current_FS], 1 ja short find_ln_FAT16_eoc_check cmp ah, 0Fh jb loc_load_ln_next_sector jmp short retn_find_longname_notfound find_ln_FAT16_eoc_check: cmp byte ptr [Current_FS], 2 ja short find_ln_FAT32_eoc_check cmp ah, 0FFh jnb short retn_find_longname_notfound jmp loc_load_ln_next_sector find_ln_FAT32_eoc_check: cmp ah, 0FFh jb loc_load_ln_next_sector cmp dx, 0FFFh jb loc_load_ln_next_sector retn_find_longname_notfound: mov si, offset Msg_LongNameNotFound call proc_printmsg retn LFN_Checksum: db 0 Msg_LongName: LongFileName: db 66 dup(0) LongNameFound: db 0 Msg_LongNameNotFound: db "Long name not found!" NextLine: db 0Dh, 0Ah, 0 proc_find_longname endp proc_calculate_checksum proc near ; INPUT DS:SI = 11 byte Dos File Name location ; (in DOS Directory Entry Format) ; © Erdogan Tan [ 20-6-2004 ] ; This 8086 assembly code is an original code ; which is adapted from C code in ; Microsoft FAT32 File System Specification ; Version 1.03, December 6, 2000 ; Page 28 xor al, al mov cx, 11 loc_next_sum: xor ah, ah test al, 1 jz short pass_ah_80h mov ah, 80h pass_ah_80h: shr al, 1 add al, byte ptr [si] inc si add al, ah loop loc_next_sum ; al= 8 bit checksum (CRC) value retn proc_calculate_checksum endp proc_show_date proc near mov ah, 04h int 1Ah mov al, dl call proc_hex mov word ptr [Day], ax mov al, dh call proc_hex mov word ptr [Month], ax mov al, ch call proc_hex mov word ptr [Century], ax mov al, cl call proc_hex mov word ptr [Year], ax mov si, offset Msg_Show_Date call proc_printmsg retn Msg_Show_Date: db 'Current date is ' Day: db '0' db '0' db '/' Month: db '0' db '0' db '/' Century: db '0' db '0' Year: db '0' db '0' db 0Dh, 0Ah, 0 proc_show_date endp proc_set_date proc near mov si, offset Msg_Enter_Date call proc_printmsg loc_enter_day_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 13 je loc_set_date_retn cmp al, 27 je loc_set_date_retn mov byte ptr [Day], al cmp al, '0' jb loc_set_date_stc_0 cmp al, '3' ja loc_set_date_stc_0 mov ah, 0Eh int 10h loc_enter_day_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn mov byte ptr [Day]+1, al cmp al, '0' jb loc_set_date_stc_1 cmp al, '9' ja loc_set_date_stc_1 cmp byte ptr [Day], '3' jb short pass_set_day_31 cmp al, '1' ja loc_set_date_stc_1 pass_set_day_31: mov ah, 0Eh int 10h loc_enter_separator_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn cmp al, '-' je short pass_set_date_separator_1 cmp al, '/' jne loc_set_date_stc_2 pass_set_date_separator_1: mov ah, 0Eh int 10h loc_enter_month_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn mov byte ptr [Month], al cmp al, '0' jb loc_set_date_stc_3 cmp al, '1' ja loc_set_date_stc_3 mov ah, 0Eh int 10h loc_enter_month_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn mov byte ptr [Month]+1, al cmp al, '0' jb loc_set_date_stc_4 cmp al, '9' ja loc_set_date_stc_4 cmp byte ptr [Month], '1' jb short pass_set_month_12 cmp al, '2' ja loc_set_date_stc_4 pass_set_month_12: mov ah, 0Eh int 10h loc_enter_separator_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn cmp al, '-' je short pass_set_date_separator_2 cmp al, '/' jne loc_set_date_stc_5 pass_set_date_separator_2: mov ah, 0Eh int 10h loc_enter_year_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn mov byte ptr [Year], al cmp al, '0' jb loc_set_date_stc_6 cmp al, '9' ja loc_set_date_stc_6 mov ah, 0Eh int 10h loc_enter_year_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_date_retn mov byte ptr [Year]+1, al cmp al, '0' jb loc_set_date_stc_7 cmp al, '9' ja loc_set_date_stc_7 mov ah, 0Eh int 10h loc_set_date_get_lchar_again: xor ah, ah int 16h cmp al, 13 je short loc_set_date_progress cmp al, 27 je short loc_set_date_retn cmp ax, 0E08h je short loc_set_date_bs_8 cmp ax, 4BE0h je short loc_set_date_bs_8 cmp ax, 4B00h je short loc_set_date_bs_8 cmp ax, 53E0h je short loc_set_date_bs_8 jmp short loc_set_date_get_lchar_again loc_set_date_bs_8: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_year_2 loc_set_date_progress: ; Get Current Date mov ah, 04h int 1Ah mov ah, byte ptr [Year] sub ah, '0' mov al, 16 mul ah mov cl, al mov al, byte ptr [Year]+1 sub al, '0' add cl, al mov ah, byte ptr [Month] sub ah, '0' mov al, 16 mul ah mov dh, al mov al, byte ptr [Month]+1 sub al, '0' add dh, al mov ah, byte ptr [Day] sub ah, '0' mov al, 16 mul ah mov dl, al mov al, byte ptr [Day]+1 sub al, '0' add dl, al mov ah, 05h int 1Ah loc_set_date_retn: mov si, offset nextline call proc_printmsg retn loc_set_date_stc_0: mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_day_1 loc_set_date_stc_1: cmp ax, 0E08h je short loc_set_date_bs_1 cmp ax, 4BE0h je short loc_set_date_bs_1 cmp ax, 4B00h je short loc_set_date_bs_1 cmp ax, 53E0h je short loc_set_date_bs_1 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_day_2 loc_set_date_bs_1: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_day_1 loc_set_date_stc_2: cmp ax, 0E08h je short loc_set_date_bs_2 cmp ax, 4BE0h je short loc_set_date_bs_2 cmp ax, 4B00h je short loc_set_date_bs_2 cmp ax, 53E0h je short loc_set_date_bs_2 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_separator_1 loc_set_date_bs_2: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_day_2 loc_set_date_stc_3: cmp ax, 0E08h je short loc_set_date_bs_3 cmp ax, 4BE0h je short loc_set_date_bs_3 cmp ax, 4B00h je short loc_set_date_bs_3 cmp ax, 53E0h je short loc_set_date_bs_3 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_month_1 loc_set_date_bs_3: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_separator_1 loc_set_date_stc_4: cmp ax, 0E08h je short loc_set_date_bs_4 cmp ax, 4BE0h je short loc_set_date_bs_4 cmp ax, 4B00h je short loc_set_date_bs_4 cmp ax, 53E0h je short loc_set_date_bs_4 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_month_2 loc_set_date_bs_4: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_month_1 loc_set_date_stc_5: cmp ax, 0E08h je short loc_set_date_bs_5 cmp ax, 4BE0h je short loc_set_date_bs_5 cmp ax, 4B00h je short loc_set_date_bs_5 cmp ax, 53E0h je short loc_set_date_bs_5 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_separator_2 loc_set_date_bs_5: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_month_2 loc_set_date_stc_6: cmp ax, 0E08h je short loc_set_date_bs_6 cmp ax, 4BE0h je short loc_set_date_bs_6 cmp ax, 4B00h je short loc_set_date_bs_6 cmp ax, 53E0h je short loc_set_date_bs_6 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_year_1 loc_set_date_bs_6: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_separator_2 loc_set_date_stc_7: cmp ax, 0E08h je short loc_set_date_bs_7 cmp ax, 4BE0h je short loc_set_date_bs_7 cmp ax, 4B00h je short loc_set_date_bs_7 cmp ax, 53E0h je short loc_set_date_bs_7 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_year_2 loc_set_date_bs_7: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_year_1 Msg_Enter_Date: db 'Enter new date (dd-mm-yy): ' db 0 proc_set_date endp proc_show_time proc near mov ah, 02h int 1Ah mov al, ch call proc_hex mov word ptr [Hour], ax mov al, cl call proc_hex mov word ptr [Minute], ax mov al, dh call proc_hex mov word ptr [Second], ax mov si, offset Msg_Show_Time call proc_printmsg retn Msg_Show_Time: db 'Current time is ' Hour: db '0' db '0' db ':' Minute: db '0' db '0' db ':' Second: db '0' db '0' db 0Dh, 0Ah, 0 proc_show_time endp proc_set_time proc near mov si, offset Msg_Enter_Time call proc_printmsg loc_enter_hour_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 13 je loc_set_time_retn cmp al, 27 je loc_set_time_retn mov byte ptr [Hour], al cmp al, '0' jb loc_set_time_stc_0 cmp al, '2' ja loc_set_time_stc_0 mov ah, 0Eh int 10h loc_enter_hour_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_time_retn mov byte ptr [Hour]+1, al cmp al, '0' jb loc_set_time_stc_1 cmp al, '9' ja loc_set_time_stc_1 cmp byte ptr [Hour], '2' jb short pass_set_time_24 cmp al, '4' ja loc_set_time_stc_1 pass_set_time_24: mov ah, 0Eh int 10h loc_enter_time_separator_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_time_retn cmp al, ':' jne loc_set_time_stc_2 mov ah, 0Eh int 10h loc_enter_minute_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_time_retn mov byte ptr [Minute], al cmp al, '0' jb loc_set_time_stc_3 cmp al, '5' ja loc_set_time_stc_3 mov ah, 0Eh int 10h loc_enter_minute_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_time_retn mov byte ptr [Minute]+1, al cmp al, '0' jb loc_set_time_stc_4 cmp al, '9' ja loc_set_time_stc_4 mov ah, 0Eh int 10h loc_enter_time_separator_2: mov word ptr [Second], 3030h xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 13 je loc_set_time_progress cmp al, 27 je loc_set_time_retn cmp al, ':' jne loc_set_time_stc_5 mov ah, 0Eh int 10h loc_enter_second_1: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 13 je loc_set_time_progress cmp al, 27 je loc_set_time_retn mov byte ptr [Second], al cmp al, '0' jb loc_set_time_stc_6 cmp al, '5' ja loc_set_time_stc_6 mov ah, 0Eh int 10h loc_enter_second_2: xor ah, ah int 16h ; al = ASCII Code of the Character cmp al, 27 je loc_set_time_retn mov byte ptr [Second]+1, al cmp al, '0' jb loc_set_time_stc_7 cmp al, '9' ja loc_set_time_stc_7 mov ah, 0Eh int 10h loc_set_time_get_lchar_again: xor ah, ah int 16h cmp al, 13 je short loc_set_time_progress cmp al, 27 je short loc_set_time_retn cmp ax, 0E08h je short loc_set_time_bs_8 cmp ax, 4BE0h je short loc_set_time_bs_8 cmp ax, 4B00h je short loc_set_time_bs_8 cmp ax, 53E0h je short loc_set_time_bs_8 jmp short loc_set_time_get_lchar_again loc_set_time_bs_8: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_second_2 loc_set_time_progress: ; Get Current Time mov ah, 02h int 1Ah mov ah, byte ptr [Hour] sub ah, '0' mov al, 16 mul ah mov ch, al mov al, byte ptr [Hour]+1 sub al, '0' add ch, al mov ah, byte ptr [Minute] sub ah, '0' mov al, 16 mul ah mov cl, al mov al, byte ptr [Minute]+1 sub al, '0' add cl, al mov ah, byte ptr [Second] sub ah, '0' mov al, 16 mul ah mov dh, al mov al, byte ptr [Second]+1 sub al, '0' add dh, al mov ah, 03h int 1Ah loc_set_time_retn: mov si, offset nextline call proc_printmsg retn loc_set_time_stc_0: mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_hour_1 loc_set_time_stc_1: cmp ax, 0E08h je short loc_set_time_bs_1 cmp ax, 4BE0h je short loc_set_time_bs_1 cmp ax, 4B00h je short loc_set_time_bs_1 cmp ax, 53E0h je short loc_set_time_bs_1 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_hour_2 loc_set_time_bs_1: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_hour_1 loc_set_time_stc_2: cmp ax, 0E08h je short loc_set_time_bs_2 cmp ax, 4BE0h je short loc_set_time_bs_2 cmp ax, 4B00h je short loc_set_time_bs_2 cmp ax, 53E0h je short loc_set_time_bs_2 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_time_separator_1 loc_set_time_bs_2: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_hour_2 loc_set_time_stc_3: cmp ax, 0E08h je short loc_set_time_bs_3 cmp ax, 4BE0h je short loc_set_time_bs_3 cmp ax, 4B00h je short loc_set_time_bs_3 cmp ax, 53E0h je short loc_set_time_bs_3 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_minute_1 loc_set_time_bs_3: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_time_separator_1 loc_set_time_stc_4: cmp ax, 0E08h je short loc_set_time_bs_4 cmp ax, 4BE0h je short loc_set_time_bs_4 cmp ax, 4B00h je short loc_set_time_bs_4 cmp ax, 53E0h je short loc_set_time_bs_4 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_minute_2 loc_set_time_bs_4: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_minute_1 loc_set_time_stc_5: cmp ax, 0E08h je short loc_set_time_bs_5 cmp ax, 4BE0h je short loc_set_time_bs_5 cmp ax, 4B00h je short loc_set_time_bs_5 cmp ax, 53E0h je short loc_set_time_bs_5 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_time_separator_2 loc_set_time_bs_5: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_minute_2 loc_set_time_stc_6: cmp ax, 0E08h je short loc_set_time_bs_6 cmp ax, 4BE0h je short loc_set_time_bs_6 cmp ax, 4B00h je short loc_set_time_bs_6 cmp ax, 53E0h je short loc_set_time_bs_6 mov al, 07h mov ah, 0Eh int 10h mov word ptr [Second], 3030h jmp loc_enter_second_1 loc_set_time_bs_6: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_time_separator_2 loc_set_time_stc_7: cmp ax, 0E08h je short loc_set_time_bs_7 cmp ax, 4BE0h je short loc_set_time_bs_7 cmp ax, 4B00h je short loc_set_time_bs_7 cmp ax, 53E0h je short loc_set_time_bs_7 mov al, 07h mov ah, 0Eh int 10h jmp loc_enter_second_2 loc_set_time_bs_7: mov al, 08h mov ah, 0Eh int 10h mov al, 20h mov ah, 09h int 10h jmp loc_enter_second_1 Msg_Enter_Time: db 'Enter new time: ' db 0 proc_set_time endp proc_load_file proc near ; ES:DI = File Buffer ; DX:AX = First Cluster Number ; BL = 0 ; BH = DRV mov si, offset Logical_DOSDisks add si, bx cmp byte ptr [SI][LD_Name], 'A' jnb short pass_lf_drv_failed retn pass_lf_drv_failed: cmp byte ptr [SI][LD_FATType],2 ja short pass_lf_reset_dx xor dx,dx pass_lf_reset_dx: mov byte ptr [SourceFile_Drv], bh mov word ptr [SourceFile_BufferOff], di push es pop word ptr [SourceFile_BufferSeg] loc_load_file_next_cluster: mov word ptr [SourceFile_Cluster], ax mov word ptr [SourceFile_Cluster]+2, dx mov bl, byte ptr [SI][LD_BPB][SecPerClust] sub ax, 2 sbb dx, 0 xor bh, bh mov cx, bx call proc_mul32 add ax, word ptr [SI][LD_DATAbegin] adc dx, word ptr [SI][LD_DATAbegin]+2 ; xor bh, bh cmp byte ptr [SI][LD_LBAYes], 0 ja short lba_read_file_sectors call proc_CHS_read jnc short loc_cont_load_file retn lba_read_file_sectors: mov byte ptr [DAP_BuffLBAyes], 1 mov byte ptr [DAP_BuffPacketSize], 10h push word ptr [SourceFile_BufferOff] pop word ptr [DAP_BuffDestination] push word ptr [SourceFile_BufferSeg] pop word ptr [DAP_BuffDestination]+2 mov word ptr [DAP_BuffLBA_Address], ax mov word ptr [DAP_BuffLBA_Address]+2, dx mov byte ptr [DAP_BuffNumOfBlocks], cl mov byte ptr [DAP_RetryCount], 4 mov dl, byte ptr [SI][LD_PhyDrvNo] mov byte ptr [DAP_BuffDisk], dl call proc_LBA_read jnc short loc_cont_load_file loc_load_file_retn: retn loc_cont_load_file: mov ax, word ptr [SourceFile_Cluster] mov dx, word ptr [SourceFile_Cluster]+2 call proc_get_next_cluster jc short loc_load_file_retn push ax push dx xor bh, bh mov bl, byte ptr [SI][LD_BPB][SecPerClust] mov ax, 512 mul bx add word ptr [SourceFile_BufferOff], ax pop dx pop ax jnc short pass_load_file_es_change mov bx, es add bx, 1000h mov es, bx pass_load_file_es_change: cmp al, 0F6h jna loc_load_file_next_cluster cmp byte ptr [SI][LD_FATType],1 ja short loc_lf_FAT16_eoc_check cmp ah, 0Fh jb loc_load_file_next_cluster retn loc_lf_FAT16_eoc_check: cmp byte ptr [SI][LD_FATType],2 ja short loc_lf_FAT32_eoc_check cmp ah, 0FFh jb loc_load_file_next_cluster retn loc_lf_FAT32_eoc_check: cmp ah, 0FFh jb loc_load_file_next_cluster cmp dx, 0FFFh jb loc_load_file_next_cluster retn proc_load_file endp ; TRDOS Function Calls trdos_int21h_routine: cmp ah, 9 jne short pass_int21h_printstr loc_print_$: mov BX, DX mov AL, byte ptr DS:[BX] cmp AL,'$' je short loc_int21_9h_return ; AL = $ : end of string mov AH,0Eh mov BX,07h int 10h ; BIOS Service func ( ah ) = 0Eh ; Write char as TTY ;AL-char BH-page BL-color inc DX jmp short loc_print_$ loc_int21_9h_return: sti iret pass_int21h_printstr: cmp ah, 0 je terminate_process cmp ah, 4Ch je terminate_process cmp ah, 35h ja short loc_invalid_function_calll jmp dword ptr CS:[INT21h_Offset] ; Other Functions (invalid) loc_invalid_function_calll: pop word ptr CS:[INT_IP] pop word ptr CS:[INT_CS] pop word ptr CS:[INT_Flags] push sp push bp push ss push es push ds push cs pop ds push di push si push dx push cx push bx push ax call proc_hex mov word ptr [ValStr_AX]+2, ax pop ax mov al, ah call proc_hex mov word ptr [ValStr_AX], ax mov word ptr [ValStr_AH], ax mov al, 21h call proc_hex mov word ptr [ValStr_INT], ax mov al, byte ptr [INT_IP]+1 call proc_hex mov word ptr [ValStr_IP], ax mov al, byte ptr [INT_IP] call proc_hex mov word ptr [ValStr_IP]+2, ax mov al, byte ptr [INT_CS]+1 call proc_hex mov word ptr [ValStr_CS], ax mov al, byte ptr [INT_CS] call proc_hex mov word ptr [ValStr_CS]+2, ax mov al, byte ptr [INT_Flags]+1 call proc_hex mov word ptr [ValStr_Flags], ax mov al, byte ptr [INT_Flags] call proc_hex mov word ptr [ValStr_Flags]+2, ax pop bx mov al, bh call proc_hex mov word ptr [ValStr_BX], ax mov al, bl call proc_hex mov word ptr [ValStr_BX]+2, ax pop cx mov al, ch call proc_hex mov word ptr [ValStr_CX], ax mov al, cl call proc_hex mov word ptr [ValStr_CX]+2, ax pop dx mov al, dh call proc_hex mov word ptr [ValStr_DX], ax mov al, dl call proc_hex mov word ptr [ValStr_DX]+2, ax pop dx ; si mov al, dh call proc_hex mov word ptr [ValStr_SI], ax mov al, dl call proc_hex mov word ptr [ValStr_SI]+2, ax pop dx ; di mov al, dh call proc_hex mov word ptr [ValStr_DI], ax mov al, dl call proc_hex mov word ptr [ValStr_DI]+2, ax pop dx ; ds mov al, dh call proc_hex mov word ptr [ValStr_DS], ax mov al, dl call proc_hex mov word ptr [ValStr_DS]+2, ax pop dx ; es mov al, dh call proc_hex mov word ptr [ValStr_ES], ax mov al, dl call proc_hex mov word ptr [ValStr_ES]+2, ax pop dx ; ss mov al, dh call proc_hex mov word ptr [ValStr_SS], ax mov al, dl call proc_hex mov word ptr [ValStr_SS]+2, ax pop dx ; bp mov al, dh call proc_hex mov word ptr [ValStr_BP], ax mov al, dl call proc_hex mov word ptr [ValStr_BP]+2, ax pop dx ; sp mov al, dh call proc_hex mov word ptr [ValStr_SP], ax mov al, dl call proc_hex mov word ptr [ValStr_SP]+2, ax mov si, offset msg_invalid_function_call call proc_printmsg mov si, offset msg_function_registers call proc_printmsg jmp short terminate_process terminate_process: jmp run_com_int20h_handler INT21h_Offset: dw 0 INT21h_Segment: dw 0 INT_IP: dw 0 INT_CS: dw 0 INT_FLAGS: dw 0 msg_invalid_function_call: db 7 db 0Dh, 0Ah, 0Dh, 0Ah db "*** Invalid function call for TRDOS ! ***" db 0Dh, 0Ah, 0 msg_function_registers: db 0Dh, 0Ah db "INT " ValStr_INT: dw 3030h db "h" db " " db "Function AH = " ValStr_AH: dw 3030h db "h" db 0Dh, 0Ah, 0Dh,0Ah db "Registers: ", 0Dh, 0Ah db "AX = " ValStr_AX: dd 30303030h db "h " db "BX = " ValStr_BX: dd 30303030h db "h " db "CX = " ValStr_CX: dd 30303030h db "h " db "DX = " ValStr_DX: dd 30303030h db "h", 0Dh, 0Ah db "CS = " ValStr_CS: dd 30303030h db "h " db "IP = " ValStr_IP: dd 30303030h db "h " db "Flags = " ValStr_Flags: dd 30303030h db "h", 0Dh, 0Ah db "DS = " ValStr_DS: dd 30303030h db "h " db "ES = " ValStr_ES: dd 30303030h db "h " db "SI = " ValStr_SI: dd 30303030h db "h " db "DI = " ValStr_DI: dd 30303030h db "h", 0Dh, 0Ah db "SS = " ValStr_SS: dd 30303030h db "h " db "SP = " ValStr_SP: dd 30303030h db "h " db "BP = " ValStr_BP: dd 30303030h db "h", 0Dh, 0Ah, 0Dh, 0Ah, 0 ; End Of TRDOS Function Calls ; INTERNAL COMMANDS Cmd_Dir: db "DIR" ; Cmd_Cd: db "CD" ; Cmd_Drive: db "C:" ; D:, E: etc. Cmd_Ver: db "VER" Cmd_Exit: db "EXIT" Cmd_Prompt: db "PROMPT" Cmd_Volume: db "VOLUME" Cmd_LongName: db "LONGNAME" Cmd_Date: db "DATE" Cmd_Time: db "TIME" Cmd_Run: db "RUN" SourceFile_Drv: db 0 SourceFile_Cluster: dd 0 SourceFile_BufferOff: dw 0 SourceFile_BufferSeg: dw 0 HDCounter: db 1 Partition: db 0 FileSys_Names: ; 2003 (Valid FileSystems for TR-DOS Project in 2003) db " " db "TrDos FS1 " ; 01h (16 bit, 512 bytes per sec) ; Reserved for future TRDOS versions db "TrDos FS2 " ; 02h (32 bit, 512 bytes per sec) ; Reserved for future TRDOS versions db "TrDos FS3 " ; 03h (32 bit, 2048 bytes per sec) ; Reserved for future TRDOS versions db "DOS FAT16 " ; 04h = FAT16 < 32MB ; TRDOS doesn't use this FS for hard disks db "DOS EXT " ; 05h = Extended DOS Partition ; TRDOS uses DOS extended partitions db "DOS FAT16 " ; 06h = FAT16 > 32MB, CHS Mode ; TRDOS uses FAT16 Big CHS mode FS FS_NTFS: db "WINDOWS NT " ; 07h , WINDOWS 2000/XP NTFS Partition ; TRDOS doesn't use NTFS FS_WIN_32: db "WIN4 FAT32 " ; OBh = FAT32 CHS, 0Ch = FAT32 LBA ; TRDOS uses FAT32 CHS and LBA modes FS_WIN_P: db "WIN4 FAT16 " ; 0Eh = FAT16, LBA Mode ; TRDOS uses FAT16 LBA mode FS FS_WIN_EXT: db "WIN4 EXT " ; 0Fh = Extented Partition, LBA Mode ; TRDOS uses WINDOWS extended partitions FS_SCO: db "SCO Unix " ; 63h , SCO UNIX, UNIXWARE, OPENSERVER ; TR-MULTIX ATAPI device LBA FS RS_DATARANGER: db "DataRanger " ; A0h , (DataRanger Random Data Disk) LBA ; TR-DATARANGER Ranged Data Record System FS_Others: db "Non-DOS " ; Non DOS, Another or Unknown File Systems MasterBootBuff: MasterBootCode: db 1BEh dup (?) PartitionTable: db 64 dup (?) MBIDCode: dw ? PTable_Buffer: PTable_hd0: db 64 dup (0) PTable_hd1: db 64 dup (0) PTable_hd2: db 64 dup (0) PTable_hd3: db 64 dup (0) PTable_ep0: db 64 dup (0) PTable_ep1: db 64 dup (0) PTable_ep2: db 64 dup (0) PTable_ep3: db 64 dup (0) DiskParams: Disk_fd0: db 16 dup (0) DAP_fd0: db 16 dup(0) GDP_fd0: db 26 dup(0) TRDP_fd0: db 6 dup(0) Disk_fd1: db 16 dup (0) DAP_fd1: db 16 dup(0) GDP_fd1: db 26 dup(0) TRDP_fd1: db 6 dup(0) Disk_hd0: db 16 dup (0) DAP_hd0: db 16 dup(0) GDP_hd0: db 26 dup(0) TRDP_hd0: db 6 dup(0) Disk_hd1: db 16 dup (0) DAP_hd1: db 16 dup(0) GDP_hd1: db 26 dup(0) TRDP_hd1: db 6 dup(0) Disk_hd2: db 16 dup (0) DAP_hd2: db 16 dup(0) GDP_hd2: db 26 dup(0) TRDP_hd2: db 6 dup(0) Disk_hd3: db 16 dup (0) DAP_hd3: db 16 dup(0) GDP_hd3: db 26 dup(0) TRDP_hd3: db 6 dup(0) end_of_dparams_buff: DOSBootSectorBuff: BS_JmpBoot: db 3 dup (0) BS_OEMName: db 8 dup (0) BPB_BytsPerSec: dw 0 BPB_SecPerClust: db 0 BPB_RsvdSecCnt: dw 0 BPB_NumFATs: db 0 BPB_RootEntCnt: dw 0 BPB_TotalSec16: dw 0 BPB_Media: db 0 BPB_FATSz16: dw 0 BPB_SecPerTrk: dw 0 BPB_NumHeads: dw 0 BPB_HiddSec: dd 0 BPB_TotalSec32: dd 0 BPB_FATSz32: ; FAT32, 4 bytes BS_DrvNum: db 0 BS_Reserved1: db 0 BS_BootSig: db 0 BS_VolID: db 0 BPB_ExtFlags: ; FAT32, 2 bytes dw 0 BPB_FSVer: ; FAT32, 2 bytes db 0 BS_VolLab: db 0 BPB_RootClus: ; FAT32, 4 bytes dd 0 BPB_FSInfo: ; FAT 32, 2 bytes dw 0 BPB_BkBootSec: ; FAT32, 2 bytes dw 0 BPB_Reserved: ; FAT32, 12 bytes dw 0 BS_FilSysType: db 8 dup (0) BS_BootCode: dw 0 BS_FAT32_DrvNum: ; FAT32, 1 byte db 0 BS_FAT32_Reserved1: ; FAT32, 1 byte db 0 BS_FAT32_BootSig: ; FAT32, 1 byte db 0 BS_FAT32_VolID: ; FAT32, 4 bytes dd 0 BS_FAT32_VolLab: ; FAT32, 11 bytes db 11 dup (0) BS_FAT32_FilSysType: ; FAT32, 8 bytes db 8 dup (0) BS_FAT32_BootCode: db 420 dup (0) BS_Validation: dw 0 CHS_RetryCount: db 0 PrintDir_RowCounter: db 0 ; Disk Read Procedure Parameters DAP_RetryCount: db 4 DAP_BuffCDRV_BPB: dw 0 DAP_BuffDisk: db 0 DAP_BuffLBAyes: db 0 DAP_Buffer: DAP_BuffPacketSize: db 0 DAP_BuffReservd1: db 0 DAP_BuffNumOfBlocks: db 0 DAP_BuffReservd2: db 0 DAP_BuffDestination: dd 0 DAP_BuffLBA_Address: dd 0 DAP_BuffLBA_Addressq: dd 0 FAT_BuffDescriptor: FAT_CurrentCluster: dd 0 FAT_BuffValidData: db 0 FAT_BuffDrvName: db 0 FAT_BuffSector: dd 0 FAT_Buffer: db 1536 dup (0FFh) Directory_BuffDescriptor: DirBuff_ValidData: db 0 DirBuff_Drv: db 0 DirBuff_DirCluster: dd 0 DirBuff_NextCluster: dd 0 DirBuff_EntryCounter: dw 0 DirBuff_SectorOffset: db 0 DirBuff_LastSector: db 0 DirBuff_CurrentEntry: db 0 DirBuff_LastEntry: db 0 DirBuff_DirSector: dd 0 Directory_Buffer: db 512 dup (0) Current_DrvDescriptor: Current_Media: db 0 Current_PhyDisk: db 0 Current_VolSerial1: dw 0 Current_VolSerial2: dw 0 Current_DosDisk: db 0 Current_DirLevel: db 0 Current_DirFCluster: dd 0 Current_Path: db 11 dup(0) Current_FS: db 0 ; Byte Ptr [Current_Path]+11 Current_FS_RDFC: dd 0 Current_Path_L1_L7: db 112 dup(0) Current_File: db 11 dup(0) Current_File_FCluster: dd 0 Current_ClusterCount: dd 0 SectorBuffDescriptor: SectorBuff_BeginSector: dd 0 SectorBuff_LastSector: dd 0 SectorBuff_CurrentSector: dd 0 SectorBuff_CurrentByte: dw 0 SectorBuff_BytesPerSec: dw 0 SectorBuffer: db 2048 dup(0) TRDOSPromptLabel: db "TRDOS" db 0 db 5 dup(0) db 0 TextBuffer: db 80 dup(0) CommandBuffer: db 80 dup(0) CmdArgStart: db 0 CursorColumn: db 0 Program_Exit: db 0 File_Name: db 12 dup(20h) db 20h Dir_Or_FileSize: db 10 dup(20h) db 20h File_Attribute: db 4 dup(20h) db 20h File_Day: db 2 dup('0') db '/' File_Month: db 2 dup('0') db '/' File_Year: db 4 dup('0') db 20h File_Hour: db 2 dup('0') db ':' File_Minute: db 2 dup('0') db 0 Type_Dir: db '<DIR> ' Dir_Drive_Str: db "TR-DOS Drive " Dir_Drive_Name: db "0:" db 0Dh, 0Ah Vol_Str_Header: db "Volume Name: " Vol_Name: db 11 dup(0) db 0 Vol_Serial_Header: db 0Dh, 0Ah db "Volume Serial No: " Vol_Serial2: db "0000" db "-" Vol_Serial1: db "0000" db 0Dh, 0Ah Dir_Str_Header: db "Directory: " Dir_Str_Root: db "/" Dir_Str: db 64 dup (0) End_of_Dir_Str: db " ..." db 0 Starting_Msg: db 0Dh, 0Ah db "Starting TRDOS ..." db 0Dh, 0Ah, 0 Msg_Bad_Command: db "Bad command or file name!" db 0Dh, 0Ah, 0 Msg_Not_Ready_Read_Err: db "Drive not ready or read error!" db 0Dh, 0Ah, 0 Msg_Dir_Not_Found: db "Directory not found!" db 0Dh, 0Ah, 0 Msg_File_Name0: db 34 Msg_File_Name1: db 11 dup (20h) db 34, 0 Msg_File_Not_Found: db "File" Msg_Not_Found: db " not found!" db 0Dh, 0Ah, 0 Magic_Bytes: db 4 db 1 Program_Version: db 7 db "[TRDOS] Main Program v1.0" db 0Dh, 0Ah db "(c) Erdogan Tan 2004" db 0Dh, 0Ah, 0 HD_LBAYes: dd 0 Hard_Disk: db 80h Last_DOS_DiskNo: db 0 Logical_DOSDisks: dw 3328 dup(0) RunFile_BuffPrefix:db 16 dup (0) RunFile_Buffer: db 16384 dup(0) End_Of_Run_Buffer: db 0 Present ends end start