From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/SYS/MAKEFILE | 46 + v4.0/src/CMD/SYS/SYS.LNK | 2 + v4.0/src/CMD/SYS/SYS.SKL | 48 + v4.0/src/CMD/SYS/SYS1.ASM | 3710 +++++++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/SYS/SYS2.ASM | 2622 ++++++++++++++++++++++++++++++ v4.0/src/CMD/SYS/SYSHDR.INC | 427 +++++ v4.0/src/CMD/SYS/SYSSR.ASM | 82 + 7 files changed, 6937 insertions(+) create mode 100644 v4.0/src/CMD/SYS/MAKEFILE create mode 100644 v4.0/src/CMD/SYS/SYS.LNK create mode 100644 v4.0/src/CMD/SYS/SYS.SKL create mode 100644 v4.0/src/CMD/SYS/SYS1.ASM create mode 100644 v4.0/src/CMD/SYS/SYS2.ASM create mode 100644 v4.0/src/CMD/SYS/SYSHDR.INC create mode 100644 v4.0/src/CMD/SYS/SYSSR.ASM (limited to 'v4.0/src/CMD/SYS') diff --git a/v4.0/src/CMD/SYS/MAKEFILE b/v4.0/src/CMD/SYS/MAKEFILE new file mode 100644 index 0000000..08a7fea --- /dev/null +++ b/v4.0/src/CMD/SYS/MAKEFILE @@ -0,0 +1,46 @@ +#************************** makefile for cmd\... *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h +boot =..\..\boot +here =..\cmd\sys + +# +####################### dependencies begin here. ######################### +# + +all: sys.com + +$(inc)\boot.inc: $(boot)\msboot.asm $(msg)\$(COUNTRY).msg + cd $(boot) + nmake + cd $(here) + +sys.ctl: sys.skl $(msg)\$(COUNTRY).msg + +sys1.obj: sys1.asm $(inc)\dossym.inc $(inc)\dosmac.inc \ + $(inc)\bpb.inc $(inc)\buffer.inc $(inc)\sysvar.inc \ + $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc \ + $(inc)\curdir.inc $(inc)\cpmfcb.inc $(inc)\find.inc \ + $(inc)\pdb.inc $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc \ + $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \ + $(inc)\bootform.inc $(inc)\boot.inc syshdr.inc + +sys2.obj: sys2.asm $(inc)\dossym.inc $(inc)\dosmac.inc \ + $(inc)\bpb.inc $(inc)\buffer.inc $(inc)\sysvar.inc \ + $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc \ + $(inc)\curdir.inc $(inc)\cpmfcb.inc $(inc)\find.inc \ + $(inc)\pdb.inc $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc \ + $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \ + $(inc)\bootform.inc $(inc)\boot.inc syshdr.inc + +syssr.obj: syssr.asm $(inc)\parse.asm \ + $(inc)\psdata.inc $(inc)\msgserv.asm $(inc)\sysmsg.inc \ + sys.ctl sys.cl1 sys.cl2 sys.cla sys.clb sys.clc sys.cld + +sys.com: sys.ctl sys1.obj syssr.obj sys1.obj sys2.obj + link @sys.lnk + exe2bin sys.exe sys.com + del sys.exe diff --git a/v4.0/src/CMD/SYS/SYS.LNK b/v4.0/src/CMD/SYS/SYS.LNK new file mode 100644 index 0000000..fd12b9d --- /dev/null +++ b/v4.0/src/CMD/SYS/SYS.LNK @@ -0,0 +1,2 @@ +SYS1+SYS2+SYSSR,sys,sys.map /m; + \ No newline at end of file diff --git a/v4.0/src/CMD/SYS/SYS.SKL b/v4.0/src/CMD/SYS/SYS.SKL new file mode 100644 index 0000000..c9cebd9 --- /dev/null +++ b/v4.0/src/CMD/SYS/SYS.SKL @@ -0,0 +1,48 @@ +;================================================ +; Message Skeleton File +;================================================ + +:util SYS + +:class 1 + +:use EXTEND15 ; INVALID DRIVE + +:class 2 + +:use PARSE1 ;1 - Too many operands +:use PARSE2 ;2 - Required operand missing + ;3 - Not in switch list provided + ;4 - Not in keyword list provided + ;5 - (reserved) + ;6 - Out of range specified + ;7 - Not in value list provided + ;8 - Not in string list provided +:use PARSE9 ;9 - Invalid Parameter + +:class A + +:use 1 COMMON1 + +:class B + +:def 7 "No room for system on destination disk",CR,LF ; Old +:def 8 "Incompatible system size",CR,LF ; Old +:use 9 COMMON30 ; System transferred Old +:def 10 "No system on default drive",CR,LF ; Old +:def 11 "Can not specify default drive",CR,LF ; New +:def 12 "Write failure, diskette unusable",CR,LF ; New + +:class C + +:use 13 COMMON12 ; Cannot %1 to a Network drive Old +:def 14 "Insert system disk in drive %1",CR,LF ; Old +:use 15 COMMON19 ; Insert destination disk in drive %1 - Old +:def 16 "Not able to SYS to %1 file system",CR,LF ; New +:use 18 COMMON14 ; Cannot %1 a SUBSTed or ASSIGNed drive - NEW + +:class D + +:use 17 COMMON28 ; Press any key to continue. .; Old + +:end diff --git a/v4.0/src/CMD/SYS/SYS1.ASM b/v4.0/src/CMD/SYS/SYS1.ASM new file mode 100644 index 0000000..5d5db9d --- /dev/null +++ b/v4.0/src/CMD/SYS/SYS1.ASM @@ -0,0 +1,3710 @@ + TITLE SYS-1- Program + INCLUDE SYSHDR.INC + include version.inc + page 80,132 + +false = 0 + +DATA SEGMENT PARA PUBLIC + + public TargDrvNum, TargSpec, bio_owns_it, DOS_VER + public packet, packet_sectors, packet_buffer + extrn THIS_DPB:dword, BUF:word, DIR_SECTOR:word, first_dir_sector:word + +; $SALUT (4,25,30,41) + +DOS_VER DB 0 ; DOS Version - 0 = current + ; 1 = 3.2 or 3 +DEFALT DB 0 ; Default Drive (source - NUMBER +TargDrvNum DB 0 ; Target Drive (destination) - NUMBER +TargDrv DB 0 ; Target Drive (destination) - LETTER +TargSpec DB "A:\",0 ; z string for target name +IF IBMCOPYRIGHT +BIOSName DB "A:\IBMBIO.COM",0 ; z string for target name +DOSName DB "A:\IBMDOS.COM",0 ; z string for target name +ELSE +BIOSName DB "A:\IO.SYS",0 +DOSName DB "A:\MSDOS.SYS",0 +ENDIF + +SourceBIOSName LABEL WORD +SourceSpec DB "A:" + DB 53 dup (0) +IF IBMCOPYRIGHT +SourceBIOS DB "\IBMBIO.COM",0 +ELSE +SourceBIOS DB "\IO.SYS",0 +ENDIF + +IF IBMCOPYRIGHT +NameLen equ $ - SourceBios +ELSE +BiosNameLen equ $ - SourceBios +ENDIF + +SourceDOSName DB "A:" + DB 53 dup (0) +IF IBMCOPYRIGHT +SourceDOS DB "\IBMDOS.COM",0 +ELSE +SourceDOS DB "\MSDOS.SYS",0 +ENDIF + +IF IBMCOPYRIGHT +ELSE +DosNameLen equ $ - SourceDOS +ENDIF + +SourceSize dw 2 +Spec_flag db 0 + +IBMBIO_LOW DW 0 ;length of IBMBIO on disk +IBMBIO_HIGH DW 0 +IBMDOS_LOW DW 0 ;length of old IBMDOS on disk +IBMDOS_HIGH DW 0 + +SIZE_OLD_HIGH DW 0 +SIZE_OLD_LOW DW 0 + +NEWBIO_SIZE_LOW DW 0 +NEWBIO_SIZE_HIGH DW 0 +NEWDOS_SIZE_LOW DW 0 +NEWDOS_SIZE_HIGH DW 0 + + +Need_Clusters dw 0 +Bytes_Per_Cluster dw 0 +Number_Free_Clusters dw 0 + +; $SALUT (4,9,17,41) + ;--------------------------------------- + ; SRORAGE FOR COMMAND LINE PARAMETERS + ;--------------------------------------- + +PARMS LABEL WORD + DW OFFSET PARMSX ; POINTER TO PARMS STRUCTURE + DB 0 ; NO DELIMITER LIST FOLLOWS + DB 0 ; NUMBER OF ADDITIONAL DELIMITERS + + ;--------------------------------------- + ; STRUCTURE TO DEFINE SYS SYNTAX REQUIREMENT + ;--------------------------------------- + +PARMSX LABEL BYTE +PAR_MIN DB 1 ; MINIMUM POSITIONAL PARAMETERS = 1 ;AC021; + DB 2 ; MAXIMUM PARAMETERS = 2 ;AC021; + DW OFFSET POS1 ; POINTER TO POSITIONAL DEFINITION + DW OFFSET POS1 ; POINTER TO SAME POSITIONAL DEFINITION;AC021; + DB 0 ; THERE ARE NO SWITCHES + DB 0 ; THERE ARE NO KEYWORDS IN PRINT SYNTAX + + ;--------------------------------------- + ; STRUCTURE TO DEFINE THE POSITIONAL PARAMETER (Drive ID) + ;--------------------------------------- + +POS1 LABEL WORD +POSREP DB reqd ; MATCH FLAG LOW ;AC021; +POSTYP DB f_spec + drv_id ; MATCH FLAG HIGH ;AC021; + DW 0001H ; CAPS BY FILE TABLE + DW OFFSET POS_BUFF ; PLACE RESULT IN POSITIONAL BUFFER + DW OFFSET NOVALS ; NO VALUES LIST REQUIRED + DB 0 ; NO KEYWORDS + +reqd equ 0 +f_spec equ 2 +drv_id equ 1 + ;--------------------------------------- + ; VALUE LIST FOR POSITIONAL + ;--------------------------------------- + +NOVALS LABEL WORD + DB 0 ; NO VALUES + +; $SALUT (4,25,30,41) + + ;--------------------------------------- + ; RETURN BUFFER FOR POSITIONAL INFORMATION + ;--------------------------------------- +POS_BUFF LABEL BYTE +POS_TYPE DB ? ; TYPE RETURNED +POS_ITEM_TAG DB ? ; SPACE FOR ITEM TAG +POS_SYN DW ? ; POINTER TO LIST ENTRY +POS_OFF LABEL WORD +POS_DRV_ID DB ? ; SPACE FOR DRIVE NUMBER (1=A, 2=B, ect) + DB ? ; ;AC021; +POS_SEG DW ? ; ;AC021; + + +failopen equ 0 ; extended open 'does not exist action +openit equ 1 ; extended open 'exists' action +replaceit equ 2 ; extended open 'exists' action - replace + +OPEN_PARMS label dword + +open_off dw ? ; name pointer offset +open_seg dw ? ; name pointer segment + +PACKET dw 0,0 ; CONTROL PACKET ;AN001; +packet_sectors dw 0 ; COUNT ;AN001; +PACKET_BUFFER dw 0,0 ; BUFFER ADDRESS ;AN001; + + ;--------------------------------------- + ; Buffer for IOCtl Get/Set Media + ;--------------------------------------- + +IOCTL_BUF LABEL BYTE + +IOCtl_Level DW 0 ; INFO LEVEL (SET ON INPUT) +IOCtl_Ser_No_Low DW ? ; SERIAL # +IOCtl_Ser_No_Hi DW ? ; SERIAL # +IOCtl_Vol_ID DB "NO NAME " ; VOLUME LABEL - 11 bytes +IOCTL_File_Sys DB 8 DUP(' ') ; FILE SYSTEM TYPE + +IOCTL_Ser_Vol_Sys equ $ - IOCtl_Ser_No_Low +file_sys_size equ $ - IOCtl_File_Sys + +File_Sys_End LABEL WORD + + db 0 ; safety + +fat_12 DB "FAT12 " ; 12 bit FAT +FAT_len equ $ - fat_12 +fat_16 DB "FAT16 " ; 16 or 32 bit FAT + + ;--------------------------------------- + ; SUBLIST for Message call + ;--------------------------------------- + +.xlist + include sysmsg.inc + + MSG_UTILNAME ; ;AN000; + + MSG_SERVICES ; ;AN000; +.list + +SUBLIST LABEL DWORD + + DB sub_size ; size of sublist + DB 0 ; reserved +insert_ptr_off DW ? ; pointer to insert - offset +insert_ptr_seg DW ? ; pointer to insert - segment +insert_number DB 1 ; number of insert + DB Char_Field_ASCIIZ ;type flag +insert_max DB 3 ; maximum field size (limited to 3) + ; - this handles - SYS + ; - and - D:\ + DB 1 ; minimum field size + DB " " ; pad character + +sub_size equ $ - SUBLIST ; size of sublist + +sys_ptr db "SYS",0 + +bio_owns_it db 0 +EntryFree db 0 ; for create file + +;*** WARNING *** +; KEEP THE FOLLOWING ITEMS IN THE EXACT ORDER BELOW!!! +DOSEntFree DB 1 +BIOSEntFree DB 1 + +Xfer_data STRUC + +InFH DW ? ; file handle of source +LenLow DW ? ; 32-bit length of source +LenHigh DW ? +FTime DW ? ; place to store time of write +FDate DW ? ; place to store date of write +OutFH DW ? ; fh of destination + +Xfer_data ENDS + +BIOSInFH DW ? ; file handle of source BIOS +BIOSLenLow DW ? ; 32-bit length of BIOS +BIOSLenHigh DW ? +BIOSTime DW 2 DUP (?) ; place to store time of BIOS write +BIOSOutFH DW ? ; fh of BIOS destination +BIOSPos dw 0,0 ;AN001;lseek position into file + +DOSInFH DW ? ; file handle of source DOS +DOSLenLow DW ? ; 32-bit length of DOS +DOSLenHigh DW ? +DOSTime DW 2 DUP (?) ; place to store time of DOS write +DOSOutFH DW ? ; fh of DOS destination +DOSPos dw 0,0 ;AN001;lseek position into file + +IF IBMCOPYRIGHT +FCBDOS DB "IBMDOS COM" +FCBBIO DB "IBMBIO COM" +ELSE +FCBDOS DB "MSDOS SYS" +FCBBIO DB "IO SYS" +ENDIF + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; The following is a Extended FCB +ExtFCB db 0FFh + db 5 dup (0) + db DOS_volume_atrib +ExtFCB_Drive db 0 +ExtFCB_Name db "???????????" + db 24 dup (0) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +DOS_BUFFER DB 80h DUP (?) +cbBuf DW ? ; number of bytes in buffer +pDOS DW ? ; offset of beginning of DOS in buffer +pDOSEnd DW ? ; offset of end of DOS in buffer + + +public boot +BOOT LABEL BYTE +.xlist + INCLUDE BOOT.INC +.list + ; + ; Following structure used by Generic IOCTL call Get Device Parameters to get + ; the BPB of a hard disk. It 'overflows' into area of BUF. + ; +DeviceParameters a_DeviceParameters <1,DEV_HARDDISK> + +DATA ENDS + +CODE SEGMENT PARA PUBLIC + + EXTRN SYSLOADMSG:near, SYSDISPMSG:near, SYSPARSE:near + EXTRN Data_Space:WORD, Find_DPB:near, + EXTRN Move_DIR_Entry:near, Free_Cluster:near, Direct_Access:near + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Main +;******************************************************************************* +; +;Description: Main control routine. Subroutines are structured so that they +; will pass back an error return code (message number) and set +; the fail flag (CF) if there was a fatal error. +; +; NOTES: +; +; 1 - This program uses its own internal stack. The stack space provided +; by DOS is used as an input buffer for transfering IBMBIO and IBMDOS. +; +; SYS is linked with the CODE segment followed by the DATA segment. The +; last symbol in DATA is BUF. It marks the end end of data and the +; start of the BUFfer. The BUFfer extends from here to SP. The first +; 6.5Kb (13 sectors) in BUFfer are used for up to 12 sectors of the FAT +; or the directory. In Main, the remaining space is set +; as follows: +; cdBuf = SP - ( FAT_BUF + BUF ) +; +; 2 - The main line program calls 1 routine that loops until specific +; requirements are met. It is: +; Get_System_Files - if default drive has replaceable +; media this routine loops until +; a diskette with the correct system +; files is inserted. +; +; 3 - Great effort is expended to keep the number of open files to a minimum. +; This is required in case output is directed to NULL. (See DOS 4.00 +; PTR P71) +; +;Called Procedures: Init_Input_Output +; Validate_Target_Drive +; Get_System_Files +; Check_SYS_Conditions +; Do_SYS +; Message +; +;Input: Command line input in PSP +; +;Ouput: no error - System transfered to target media +; error - Appropriate error message displayed +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Main +; +; setup messages and parsing (CALL Init_Input_Output) +; if there is no error and +; verify target drive is valid (CALL Validate_Target_Drive) +; if there is no error and +; get system files loaded (CALL Get_System_Files) +; if there is no error and +; verify target drive is SYSable (Check_SYS_Conditions) +; if there is no error and +; perform SYS operation (CALL Do_SYS) +; if no error and +; clean up loose ends (CALL Do_End) +; if no error +; load return code (System transfered) +; endif +; display message (CALL Message) +; ret +; +; END Main +; +;******************- END OF PSEUDOCODE -************************************** + + ASSUME CS:CODE,DS:NOTHING,ES:NOTHING + + ORG 80H + +PSP_PRAM DB 128 DUP(?) + +START: JMP BEGIN + + DB " - SYS - Utility " + DB 01Ah + + even + + db 510 dup(0) ; stack + +EOS EQU BYTE PTR $ + + DW 0 ; RETURN OFFSET + + +public Begin + +BEGIN PROC NEAR + +; $SALUT (4,4,9,41) + + mov ax,OFFSET Data_Space + add ax,15 ; round up to next segment + mov cl,4 ; convert to segment value + shr ax,cl + mov cx,ds + add ax,cx ; generate DATA segment value + mov ds,ax + + ASSUME DS:DATA,ES:NOTHING + + mov cx,sp ; get lowest available spot + mov sp,OFFSET EOS ; set up internal stack + sub cx,FAT_BUF + (OFFSET BUF) ; leave room for: + ; CODE + + ; DATA + + ; FAT_BUF (12 sectors of FAT) + + mov cbBuf,cx ; store length of Xfer buffer + + mov dx,OFFSET DOS_BUFFER ; set up DTA + mov ah,SET_DMA + INT 21h + + call Init_Input_Output ; setup messages and parsing ;AN000; + +; $if nc,and ; there is no error and ;AN000; + JC $$IF1 + + call Validate_Target_Drive ; verify target drive is valid ;AN000; + +; $if nc,and ; there is no error ;AN000; + JC $$IF1 + + call Get_System_Files ; get system files loaded ;AN000; + +; $if nc,and ; there is no error ;AN000; + JC $$IF1 + + call Check_SYS_Conditions ; verify target drive is SYSable ;AN000; + +; $if nc,and ; there is no error ;AN000; + JC $$IF1 + + call Do_SYS ; perform SYS operation ;AN000; + +; $if nc,and ; no error and ;AN000; + JC $$IF1 + + call Do_End ; clean up loose ends ;AN000; + +; $if nc ; no error ;AN000; + JC $$IF1 + + mov ax,(util_B shl 8) + done ; load return code (System transfered) ;AN000; + +; $endif ; ;AN000; +$$IF1: + + call Message ; display message ;AN000; + + mov ah,exit ; just set function - RC set by MAIN + int 21h ; if version is < DOS 2.0 the int 21 + + ret ; ret if version < 2.00 + +BEGIN ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Init_Input_Output +;******************************************************************************* +; +;Description: Initialize messages and Parse command line. +; +;Called Procedures: Preload_Messages +; Parse_Command_Line +; +;Input: PSP command line at 81h and length at 80h +; +;Output: no error - CF = 0 AX = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Init_Input_Output +; +; load messages (CALL Preload_Messages) +; if no error +; get DOS version +; if not = current and +; set not current flag +; if not = current - 1 +; load incorrect DOS version message +; set fail flag +; else +; if no error and +; parse the saved command line (CALL Parse_Command_Line) +; if no error +; load return code (success) +; endif +; endif +; endif +; ret +; +; END Init_Input_Output +; +;******************- END OF PSEUDOCODE -************************************** + +public Init_Input_Output + + Init_Input_Output PROC NEAR + + call SysLoadMsg ; preload all error messages ;AN000; + +; $if c ; if error - set to Utility ;AN000; + JNC $$IF3 + mov ah,0bh ; ;AN000; +; $else ; ;AN019; + JMP SHORT $$EN3 +$$IF3: + mov ax,(GET_VERSION shl 8) ; ;AN019; + int 21h ; ;AN019; + xchg al,ah ; ;AN019; + cmp ax,(major_version shl 8) + minor_version ; ;AN019; +; $if ne ; ;AN019; + JE $$IF5 + mov DOS_VER,0ffh ; keep track that DOS is down a level ;AN019; + ; 0 = current (default) +; $endif ; ff = down one level ;AN021; +$$IF5: +; $if be,and ; ;AN019; + JNBE $$IF7 + cmp ax,DOS_low ; ;AC023; +; $if ae ; ;AN019; + JNAE $$IF7 + + + +cmp ax,(3 shl 8) + 40 ;;;; to +; $if e ;;;; cover + JNE $$IF8 +mov DOS_VER,0 ;;;; 4.00 +; $endif ;;;; this must be remover +$$IF8: + + + + + clc ; ;AN019; +; $else ; ;AN019; + JMP SHORT $$EN7 +$$IF7: + mov ax,(util shl 8) + DOS_error ; ;AN019; + stc ; ;AN019; +; $endif ; ;AN019; +$$EN7: + +; $if nc,and ; no error and ;AN000; + JC $$IF12 + + xor cx,cx ; zero out # of parms processed so far ;AN000; + mov si,command_line ; move here to loop thru twice ;AN000; + call Parse_Command_Line ; parse the saved command line ;AN000; + +; $if nc ; no error ;AN000; + JC $$IF12 + + mov al,noerror ; load return code (success) ;AN000; + +; $endif ; ;AN000; +$$IF12: +; $endif ; ;AC019; +$$EN3: + + ret ; ;AN000; + + ENDPROC Init_Input_Output + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Parse_Command_Line +;******************************************************************************* +; +;Description: Parse the command line. Check for errors, loading return code and +; setting fail flag if found. Use parse error messages except in +; case of no parameters, which has its own message. +; +;Called Procedures: SysParse +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (Parse error + error #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Parse_Command_Line +; +; parse command line (Call Do_Parse) +; if parse error +; call GetError to find out what happened +; (fail flag set) +; else +; if filespec found +; set up to move filespec into SourceBIOSName +; call Move_It to do the move +; save size of filespec +; set source spec flag +; else +; call Set_Target to process drive id (only other non error +; endif +; turn off filespec as valid input +; if first parm was NOT a filespec (ie a drive id) +; turn on optional bit +; else +; force required parms to 2 +; endif +; call Do_Parse +; if no errors +; call Set_Target to initialize drive id +; call Do_Parse to look for EOF or error +; if eol +; clear error flag +; else +; call Get_Error to see what went wrong +; endif +; else +; if not EOL +; call Get_Error to see what went wrong +; else +; clear error flag +; endif +; endif +; endif +; +; ret +; +; END Parse_Command_Line +; +;******************- END OF PSEUDOCODE -************************************** + +public Parse_Command_Line + + Parse_Command_Line PROC NEAR + ;--------------------------------------- + ; Parse Equates + ;--------------------------------------- +; $SALUT (4,27,34,41) + +eol equ -1 ; Indicator for End-Of-Line ;AN000; +noerror equ 0 ; Return Indicator for No Errors ;AN000; +command_line equ 081H ; offset of command line in PSP ;AN000; +Syntax_Error equ 9 ; PARSE syntax error ;AN000; + +; $SALUT (4,4,9,41) + + ;--------------------------------------- + ; Get address of command line + ;--------------------------------------- + + push ds ; ;AN000; + pop es ; ;AN000; + lea di,PARMS ; ;AC021: + + call Do_Parse ; ;AC021: + + cmp ax,0 ; did we find our required parm? ;AN000; + +; $if ne ; no -check what happened ;AN000; + JE $$IF15 + + call Get_Error ; ;AC021; + +; $else ; ;AC021; + JMP SHORT $$EN15 +$$IF15: + + cmp POS_TYPE,5 ; is it a file spec? ;AN021; +; $if e ; if it is a file spec ;AN021; + JNE $$IF17 + push ds ; copy spec into source ;AN021; + push di ; ;AN021; + push si ; ;AN021; + lea di,SourceSpec ; ;AN021; + mov si,word ptr POS_OFF ; ;AN021; + mov ax,POS_SEG ; ;AN021; + mov ds,ax ; ;AN021; + + ASSUME ds:nothing,es:DATA + + xor bx,bx ; ;AN021; + + call Move_Source ; ;AN021; + + pop si ; ;AN021; + pop di ; ;AN021; + pop ds ; ;AN021; + + ASSUME ds:DATA,es:nothing + + mov SourceSize,bx ; ;AN021; + mov Spec_Flag,1 ; set spec flag ;AN021; +; $else ; must be a drive id ;AN021; + JMP SHORT $$EN17 +$$IF17: + call Set_Target ; initialize target just in case ;AN021; + mov SourceSpec,al ; save Source Spec ;AN000; + ; remember that the colon and size +; $endif ; ;AN021; +$$EN17: + and POSTYP,drv_id ; off filespec bit - on drive bit ;AN021; + cmp Spec_Flag,0 ; do we have a source spec ? ;AN021; +; $if e ; if spec flag not set ;AN021; + JNE $$IF20 + inc POSREP ; turn on optional ;AN021; +; $else ; ;AN021; + JMP SHORT $$EN20 +$$IF20: + inc PAR_MIN ; must have the second parm. ;AN021; +; $endif ; ;AN021; +$$EN20: + + call Do_Parse ; ;AN021; + + cmp ax,0 ; no parse errors? ;AN000; + +; $if e ; if no error - must be a drive id ;AN021; + JNE $$IF23 + call Set_Target ; initialize target ;AN021; + cmp Spec_Flag,0 ; do we have a source spec ? ;AN021; +; $if e ; if spec flag not set ;AN021; + JNE $$IF24 + inc Spec_Flag ; turn it on ;AN021; +; $endif ; ;AN021; +$$IF24: + + call Do_Parse ; make sure there are no extra parms. ;AN021; + cmp ax,eol ; ;AN021; +; $if e ; ;AN021; + JNE $$IF26 + clc ; ;AN021; +; $else ; ;AN021; + JMP SHORT $$EN26 +$$IF26: + call Get_Error ; ;AN021; +; $endif ; ;AN021; +$$EN26: +; $else ; could be EOL or error ;AN021; + JMP SHORT $$EN23 +$$IF23: + cmp ax,eol ; is it EOL ? ;AN021; +; $if ne ; if it is not eol ;AN021; + JE $$IF30 + call Get_Error ; error - make sure it makes sense ;AN021; +; $else ; ;AN021; + JMP SHORT $$EN30 +$$IF30: + clc ; ;AN021; +; $endif ; ;AN021; +$$EN30: +; $endif ; ;AN021; +$$EN23: +; $endif ; ;AN000; +$$EN15: + + ret ; ;AN000; + + + Move_Source PROC NEAR + +; $search ; ;AN021; +$$DO35: + lodsb ; ;AN021; + stosb ; ;AN021; + inc bl ; ;AN021; + cmp bl,54 ; are we past the maximum? ;AN021; +; $exitif a ; ;AN021; + JNA $$IF35 + mov ax,(util_B SHL 8) + bad_path ; Invalid path ;AN021; + stc ; ;AN021; +; $orelse ; ;AN021; + JMP SHORT $$SR35 +$$IF35: + or al,al ; ;AN021; +; $endloop z ; ;AN021; + JNZ $$DO35 + dec bl ; ;AN021; + clc ; ;AN021; +; $endsrch ; ;AN021; +$$SR35: + + ret ; ;AN021; + + ENDPROC Move_Source + + Do_Parse PROC NEAR + + mov insert_ptr_off,si ; save it in case of error ;AN024; + push cs ; ;AN000; + pop ds ; ;AN000; + xor dx,dx ; ;AN021; + + ASSUME ds:nothing,es:DATA + + call SysParse ; parse command line ;AN000; + + push es ; ;AN000; + pop ds ; ;AN000; + + ASSUME ds:DATA,es:nothing + + + ret ; ;AN021; + + ENDPROC Do_Parse + + Set_Target PROC NEAR + + mov al,byte ptr pos_drv_id ; initalize drive id ;AN000; + mov TargDrvNum,al ; save it for later ;AN000; + mov ExtFCB_Drive,al ; save it for finding VOL id ;AN000; + or al,num_2_letter ; convert to a drive letter ;AC000; + mov TargSpec,al ; save it for later ;AN000; + mov TargDrv,al ; ;AC000; + ret ; ;AN021; + + ENDPROC Set_Target + + Get_Error PROC NEAR + + lea bx,Parse_Ret_Code ; error - make sure it makes sense ;AN000; + xlat cs:[bx] ; ;AN000; + mov ah,parse_error ; indicate parse error CLASS ;AN000; + stc ; set fail flag ;AN000; + ret ; ;AN021; + + ENDPROC Get_Error + +Parse_Ret_Code label byte + + db 0 ; Ret Code 0 - ;AN000; + db 1 ; Ret Code 1 - Too many operands ;AN000; + db 2 ; Ret Code 2 - Required operand missing;AC002; + db 9 ; Ret Code 3 - Not in switch list provided ;AC002; + db 9 ; Ret Code 4 - Not in keyword list provided;AC002; + db 9 ; Ret Code 5 - (not used) ;AN000; + db 9 ; Ret Code 6 - Out of range specified ;AN000; + db 9 ; Ret Code 7 - Not in value list provided + db 9 ; Ret Code 8 - Not in string list provided + db 9 ; Ret Code 9 - Syntax error + + ENDPROC Parse_Command_Line + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Validate_Target_Drive +;******************************************************************************* +; +;Description: Verify that target drive was specified, is not default drive, +; is a valid drive letter, and is not a network drive +; +;Called Procedures: Check_Default_Drive +; Check_Target_Drive +; Check_For_Network +; +;Input: None +; +;Output: no error - CF = 0 AX = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Validate_Target_Drive +; +; can't have target as default (CALL Check_Default_Drive) +; if no error and +; can't have target as network (CALL Check_For_Network) +; if no error +; see if valid drive letter (CALL Check_Target_Drive) +; ret +; +; END Validate_Target_Drive +; +;******************- END OF PSEUDOCODE -************************************** + +public Validate_Target_Drive + + Validate_Target_Drive PROC NEAR + + call Check_Default_Drive ; can't have target as default ;AN000; + +; $if nc,and ; no error and ;AN000; + JC $$IF40 + + call Check_For_Network ; can't have target as network ;AC022; + +; $if nc ; no error ;AN000; + JC $$IF40 + + call Check_Target_Drive ; see if valid drive letter ;AC022; + +; $endif ; ;AN000; +$$IF40: + + ret ; ;AN000; + + ENDPROC Validate_Target_Drive + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_Default_Drive +;******************************************************************************* +; +;Description: Check to see if drive specified is default drive. If it is, +; load return code and set fail flag. +; +;Called Procedures: None +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 AX = 16d - Can not specify default drive +; +;Change History: Created 5/01/87 FG +;Change History: Ax021 2/22/88 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_Default_Drive +; +; initialize BIO and DOS found flags +; if source specified +; copy source into SourceDOSName from SourceBIOName +; else +; get_default_drive (INT21 Get_Default_Drive + 00 <1900>) +; if target drive = default drive +; load return code (Can not specify default drive) +; set fail flag +; else +; initialize SourceBIOName and SourceDOSName +; reset fail flag +; endif +; endif +; remove blanks in \IBMBIO.COM +; remove blanks in \IBMDOS.COM +; ret +; +; END Check_Default_Drive +; +;******************- END OF PSEUDOCODE -************************************** + +public Check_Default_Drive + + Check_Default_Drive PROC NEAR + + push ds + pop es + + ASSUME DS:DATA,ES:DATA + + mov DOSEntFree,1 ; set to not found ;AC021; + mov BIOSEntFree,1 ; set to not found ;AC021; + cmp Spec_Flag,1 ; was a source specified ? ;AN021; +; $if e ; if a source was specified ;AN021; + JNE $$IF42 + lea si,SourceSpec ; copy source for IBMDOS.COM ;AN021; + mov al,[si] ; get the drive ID ;AN025; + sub al,num_2_letter ; convert it to a 1 base number ;AN025; + mov DEFALT,al ; save it in case its removable ;AN025; + lea di,SourceDOSName ; ;AN021; + mov cx,SourceSize ; set up size to move ;AN021; + rep movsb ; move it! ;AN021; + +; $else ; figure out what the default is ;AN021; + JMP SHORT $$EN42 +$$IF42: + + mov ax,(Get_Default_Drive shl 8) + not_used ; get_default_drive + INT 21h ; Get_Default_Drive <1900> + inc al ; turn from phys drive to logical drive + mov DEFALT,al ; save default for later + mov SourceSpec,al + or SourceSpec,num_2_letter ; covert number to letter + cmp al,TargDrvNum ; is target drive = default drive +; $if e ; if it is the same - we have a problem;AC000; + JNE $$IF44 + + mov ax,(util_B shl 8) + not_on_default ; load return code + ; - Can not specify default drive + stc ; set fail flag + +; $else ; it wasn't = so its ok ;AC000; + JMP SHORT $$EN44 +$$IF44: + + ; initalize SourceBIOSNane, SourceDOSName + mov al,DEFALT + or al,num_2_letter ; turn into letter + mov byte ptr SourceBIOSName,AL ; twiddle source name + mov SourceDOSName,AL ; twiddle source name + clc ; reset fail flag ;AN000; + +; $endif ; ;AC000; +$$EN44: +; $endif ; ;AN021; +$$EN42: +; $if nc ; if no error to this point ;AN021; + JC $$IF48 + cld ; ;AN021; + + IF IBMCOPYRIGHT + mov bx,NameLen ; ;AN021; + mov cx,bx ; ;AN021; + ELSE + mov cx,BIOSNameLen + ENDIF + + lea di,SourceBiosName ; move IBMBIO.COM into place ;AN021; + add di,SourceSize ; move to end of specified part ;AN021; + lea si,SourceBIOS ; point to system file name ;AN021; + rep movsb ; ;AN021; + + IF IBMCOPYRIGHT + mov cx,bx ; ;AN021; + ELSE + mov cx,DosNameLen + ENDIF + + lea di,SourceDOSName ; move IBMDOS.COM into place ;AN021; + add di,SourceSize ; move to end of specified part ;AN021; + lea si,SourceDOS ; point to system file name ;AN021; + rep movsb ; ;AN021; +; $endif ; ;AN021; +$$IF48: + + ret ; ;AN000; + + ENDPROC Check_Default_Drive + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_Target_Drive +;******************************************************************************* +; +;Description: Determine if target drive is valid. To do this, we will make an +; IOCTL - check media ID call. +; +;Called Procedures: +; +;Input: Default_Drive +; +;Output: no error - CF = 0 +; error - CF = 1 AX = 16d - Can not specify default drive +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_Target_Drive +; +; Check media ID (INT21 IOCTL + IOCTL_CHANGEABLE? <4408>) +; if no error +; if invalid drive +; set return code +; set fail flag +; else +; clear fail flag +; else +; reset fail flag +; endif +; if no error +; if ASSIGNed or SUBSTd drive +; set return code +; set fail flag +; else +; clear fail flag +; else +; reset fail flag +; endif +; ret +; +; END Check_Target_Drive +; +;******************- END OF PSEUDOCODE -************************************** + +public Check_Target_Drive + + Check_Target_Drive PROC NEAR + + mov bl,TargDrvNum ; get the target drive number ;AN000; + mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check ;AC000; + INT 21h ; IOCtl + 08 <4408> ;AC000; + + cmp ax,0fh ; is it invalid - al = F (CF may be set;AC000; + +; $if e ; ;AC000; + JNE $$IF50 + + mov ax,(DOS_error shl 8) + extended_15 ; load return code ;AC000; + ; - invalid drive + stc ; ;AC000; + +; $else ; if valid device so far - make sure ;AN012; + JMP SHORT $$EN50 +$$IF50: + ; its not ASSIGNed or SUBSTed drive + mov si,offset TargSpec ; point to Target Spec ;AN012; + mov di,offset DIR_SECTOR ; point at output buffer ;AN012; + mov ax,(xNameTrans SHL 8) ; check for name translation ;AN012; + int 21h ; get real path ;AN012; +; $if nc ; ;AC012; + JC $$IF52 + mov bl,byte ptr [TargSpec] ; get drive letter from path ;AN012; + cmp bl,byte ptr DIR_SECTOR ; did drive letter change? ;AN012; +; $if ne ; if not the same, it be bad ;AN012; + JE $$IF53 + lea si,sys_ptr ; set insert pointer in SUBLIST ;AN012; + mov [insert_ptr_off],si ; ;AN012; + mov [insert_ptr_seg],ds ; ;AN012; + lea si,sublist ; set pointer to SUBLIST ;AN012; + mov ax,(util_C shl 8) + cant_assign ; load ret cd (Cannot..SUB);AN012; + stc ; tell user ;AN012; +; $else ; - its ok ;AN012; + JMP SHORT $$EN53 +$$IF53: + clc ; keep going ;AN012; +; $endif ; ;AN012; +$$EN53: +; $else ; - its a critical error ;AN012; + JMP SHORT $$EN52 +$$IF52: + xor ah,ah ; set up for extended error call ;AN012; + inc ah ; ;AN012; +; $endif ; ;AN012; +$$EN52: +; $endif ; ;AN012; +$$EN50: + + ret ; ;AC000; + + ENDPROC Check_Target_Drive + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_For_Network +;******************************************************************************* +; +;Description: Verify that the target drive is local, and not a shared drive. +; If shared,load return code and set fail flag. +; +; NOTE: This is a design point on how to determine net +; +;CALLed Procedures: None +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code = 7 - Cannot SYS to a Network drive +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_For_Network +; +; IOCtl call to see if target drive is local +; if target drive not local (INT21 IOCtl + 09 <4409>) and +; if return code indicates network drive (test 1200h) +; set insert pointer in SUBLIST +; set pointer to SUBLIST +; load return code (Cannot SYS to a Network drive) +; set fail flag +; else +; reset fail flag +; endif +; ret +; +; END Check_For_Network +; +;******************- END OF PSEUDOCODE -************************************** + +public Check_For_Network + + Check_For_Network PROC NEAR + + ; IOCtl call to see if target drive is local + mov bl,TargDrvNum ; x = IOCTL (getdrive, Drive+1) ;AC022; + mov ax,(IOCTL SHL 8) + dev_local + INT 21h ; IOCtl + dev_local <4409> + +; $if nc,and ; target drive local and ;AC000; + JC $$IF59 + + test dx,1200H ; check if (x & 0x1000) + ; (redirected or shared) +; $if nz ; return code indicates network drive ;AC000; + JZ $$IF59 + + lea si,sys_ptr ; set insert pointer in SUBLIST ;AN000; + mov [insert_ptr_off],si ; ;AN000; + mov [insert_ptr_seg],ds ; ;AN000; + lea si,sublist ; set pointer to SUBLIST ;AN000; + mov ax,(util_C shl 8) + cant_network ; load return code (Cannot SYS to.;AC000; + stc ; set fail flag ;AN000; + +; $else ; ;AC000; + JMP SHORT $$EN59 +$$IF59: + + clc ; reset fail flag ;AC000; + +; $endif ; ;AC000; +$$EN59: + + ret ; ;AN000; + + ENDPROC Check_For_Network + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Get_System_Files +;******************************************************************************* +; +;Description: Ensure that the the files IBMBIO and IBMDOS are available +; on the source media. If they are not on the source media, +; and the media is removeable, a prompt will be issued to +; insert a new source. +; +;Called Procedures: Prompt_For_Media Open_File +; Check_Removable Fill_Memory +; +;Input: IBMBIO and IBMDOS on source media +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; Major change 1/07/88 FG Ax019 now makes SYS check +; for the CORRECT version +; of IBMBIO ! +; IBMBIO looks like this: +; +; 1 2 3 4 5 +; ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄ +; ³ JMP ³ LO ³ HI ³extected_version³ +; ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄ +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Get_System_Files +; +; initalize SourceBIOSNane, SourceDOSName +; do +; find IBMBIOS +; if found and +; open file (CALL Open_File) +; if no error and +; find IBMDOS +; if found and +; open file (CALL Open_File) +; if no error and +; load memory with files (CALL Fill_Memory) +; if no error and +; if correct version of IBMBIO +; reset fail flag +; load success return code +; else +; check if source media replaceable (CALL Check_Removeable) +; if fail flag reset (replaceable) +; load message number (Insert system disk....) +; and class (utility) +; set up pointer to insert (drive id) +; prompt for source media (CALL Prompt_For_Media) +; if fail flag reset +; load return code (try again) +; endif +; endif +; endif +; leave if success return code +; leave if fail flag set +; enddo +; ret +; +; END Get_System_Files +; +;******************- END OF PSEUDOCODE -************************************** + +public Get_System_Files + + Get_System_Files PROC NEAR + cld + +; $search ; ;AC018; +$$DO62: + + lea si,DOS_BUFFER ; set up addressability + mov dx,OFFSET SourceBIOSName ; look on source for IBMBIOS + mov CX,DOS_system_atrib ; its an 'everything' file + mov ah,Find_First ; do a find first INT21 + INT 21h ; Find_First <4Exx> + +; $if nc,and ; if found and..................... ;AC000; + JC $$IF63 + mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000; + mov WORD PTR NEWBIO_SIZE_LOW,AX ; from DTA + mov ax,ds:[si].find_buf_size_h ; to ;AC000; + mov WORD PTR NEWBIO_SIZE_HIGH,AX ; SYS data space + mov dx,OFFSET SourceBIOSName ; point to source name + mov di,OFFSET BIOSInFH ; pointer to block of data + + call Open_File ; open file + +; $if nc,and ; if no error and.................... ;AC000; + JC $$IF63 + + mov dx,OFFSET SourceDOSName ; look on source for IBMDOS + mov CX,DOS_system_atrib ; its an 'everything' file + mov ah,Find_First ; do a find first INT21 + INT 21h ; Find_First <4Exx> + +; $if nc,and ; if found and....................... ;AC000; + JC $$IF63 + + mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000; + mov WORD PTR NEWDOS_SIZE_LOW,AX ; from DTA + mov ax,ds:[si].find_buf_size_h ; to ;AC000; + mov WORD PTR NEWDOS_SIZE_HIGH,AX ; SYS data space + mov dx,OFFSET SourceDOSName ; pointer to source of DOS + mov di,OFFSET DOSInFH ; pointer to block of data + + call Open_File ; open file + +; $if nc,and ; if no error and......................;AC000; + JC $$IF63 + + call Fill_Memory ; load memory with files + +; $if nc,and ; if no error..................: ;AC019; + JC $$IF63 + + cmp WORD PTR BUF+FAT_BUF+3,expected_version ; point to beginning ;AN019; + ; of buffer + near jump instruction + +; $if e ; if correct version of IBMBIO ;AN019; + JNE $$IF63 + + clc ; reset fail flag ;AN019: + mov al,noerror ; load success return code ;AN000; + +; $else ; ELSE - something wrong with source ;AC000; + JMP SHORT $$EN63 +$$IF63: + + mov bl,defalt ;; specify drive ;;dcl ;AN001; + call Check_Removeable ; check if source media replaceable ;AC000; + +; $if nc ; fail flag reset (replaceable) ;AC000; + JC $$IF65 + + mov ax,(util_C shl 8) + sys_disk ; load message number ;AC000; + ; - Insert system disk.... + lea si,SourceSpec ; set insert pointer to DRIVE ID ;AC000; + mov bx,SourceSize ; only display correct path length ;AN025; + + call Prompt_For_Media ; prompt for source media ;AN000; + +; $if nc ; fail flag reset ;AC000; + JC $$IF66 + + mov ax,error_RC ; load return code (try again) ;AN000; + +; $endif ; ;AC000; +$$IF66: + +; $endif ; ;AC000; +$$IF65: + +; $endif ; ;AC000; +$$EN63: + +; $leave c ; if fail flag set ;AC018; + JC $$EN62 + + cmp al,noerror ; is it an error return code? ;AC018; + +; $exitif e ; quit if success return code ;AC018; + JNE $$IF62 + + mov bx,BIOSInFH ; ;AC018; + mov ah,Close ; ;AC018; + int 21h ; ;AC018; + + mov bx,DOSInFH ; ;AC018; + mov ah,Close ; ;AC018; + int 21h ; ;AC018; + +; $orelse ; ;AN018; + JMP SHORT $$SR62 +$$IF62: + +; $endloop long ; ;AC018; + JMP $$DO62 +$$EN62: +; $endsrch ; ;AN018; +$$SR62: + + + + ret ; ;AN000; + + ENDPROC Get_System_Files + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Prompt_For_Media +;******************************************************************************* +; +;Description: Make call to Message to display: +; +; Insert system disk in drive %1 +; and strike any key when ready +; +;Called Procedures: Message +; +;Input: (AL) = message # +; (BL) = drive/path length +; (SI) = insert pointer +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (DOS error) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Prompt_For_Media +; +; set up for message call +; call Message - display first line +; if no error +; clear insert indicator +; load Message #x - Press any key to continue +; ask for keystroke response (direct CON in no echo) +; call Message - display second line +; endif +; if error +; load return code (DOS extended error) +; endif +; ret +; +; END Prompt_For_Media +; +;******************- END OF PSEUDOCODE -************************************** + +public Prompt_For_Media + + Prompt_For_Media PROC NEAR + + mov [insert_ptr_off],si ; set up for message call ;AN000; + mov [insert_ptr_seg],ds + mov insert_max,bl ; only display correct path length ;AN025; + lea si,sublist ; set pointer to SUBLIST ;AN000; + + call Message ; display first line ;AN000; + +; $if nc ; if no error ;AN000; + JC $$IF75 + + mov ax,(util_D shl 8) + press_key ; load Message ;AN000; + ; - Press any key to continue + ; the class will signal to ask for + ; keystroke response + ; (direct CON in no echo) + call Message ; display second line ;AN000; + +; $endif ; ;AN000; +$$IF75: + +; $if c ; if an error occured ;AN000; + JNC $$IF77 + + mov ah,DOS_error ; load return code (DOS extended error);AN000; + +; $endif ; ;AN000; +$$IF77: + + ret ; ;AN000; + + ENDPROC Prompt_For_Media + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_Removeable +;******************************************************************************* +; +;Description: Make IOCtl call to see if media in the drive indicated in +; BX is removable +; +;Called Procedures: None +; +;Input: BX has drive (0=default, 1=A) +; +;Output: removeable - CF = 0 +; nonremovable or error - CF = 1 +; AX = 11d - No system on default drive +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_Removeable +; +; if source not specified +; do an IOCTL changeable check (INT21 IOCtl + 08 <4408>) +; if no error +; test if removeable +; if removeable +; reset fail flag +; else +; load return code (No system on default drive) +; set fail flag +; endif +; endif +; else +; load return code (No system on specified path) +; set fail flag +; endif +; ret +; +; END Check_Removeable +; +;******************- END OF PSEUDOCODE -************************************** + +public Check_Removeable + + Check_Removeable PROC NEAR + + mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check + INT 21h ; IOCtl + 08 <4408> + ; cy set if remote or invalid device ;;dcl;; +; $if nc ; + JC $$IF79 + cmp ax,0 ; +; $if e ; + JNE $$IF80 + clc ; +; $else ; + JMP SHORT $$EN80 +$$IF80: + cmp Spec_Flag,1 ; ;AC025; +; $if ne ; ;AC025; + JE $$IF82 + mov ax,(util_B shl 8) + no_sys_on_def ; No system on... ;AC000; +; $else ; ;AC025; + JMP SHORT $$EN82 +$$IF82: + mov ax,(util_B shl 8) + system_not_found ; Invalid path or Sy..;AN021; +; $endif ; ;AC025; +$$EN82: + stc ; +; $endif ; +$$EN80: +; $endif ; +$$IF79: + + ret ; ;AN021; + + ENDPROC Check_Removeable + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Open_File +;***************************************************************************** +; +;Description: Opens file and gets size and date +; +;Called Procedures: None +; +;Input: ES:DI = Data space for DOS operations +; +;Output: no error - CF = 0 +; error - CF = 1 AX = DOS extended errors +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Open_File +; +; open file for read (INT21 Read + 00 <3D00>) +; if no error +; save handle +; find End Of File (INT21 LSeak + 02 <4202>) +; zero offsets +; get offsets (INT21) +; save low part of size +; save high part of size +; find start of file (INT21 LSeak + 00 <4200>) +; find last write time(INT21 File_Times + 00 <5700>) +; save time +; save date +; else +; load return code (DOS extended errors) +; endif +; ret +; +; END Open_File +; +;******************- END OF PSEUDOCODE -************************************** + +public open_file + + Open_File PROC NEAR + + mov ax,(OPEN SHL 8) + not_used ; open file for read + INT 21h ; Read + not_used <3D00> + +; $if nc ; no error ;AC000; + JC $$IF87 + + mov es:[di].InFH,ax ; save file handle ;AC000; + mov bx,ax ; get ready for seeks + mov ax,(LSeek SHL 8) + LSeek_EOF ; seek relative to eof + xor cx,cx ; zero offset + xor dx,dx ; zero offset + INT 21h ; find End Of File to get offsets + ; LSeak + LSeek_EOF <4202> + mov es:[di].LenLow,ax ; save low part of size ;AC000; + mov es:[di].LenHigh,dx ; save high part of size ;AC000; + xor dx,dx ; zero offset + mov ax,(LSeek SHL 8) + LSeek_Start ; seek relative to beginning + INT 21h ; LSeak + LSeek_Start <4200> + mov ax,(File_Times SHL 8) + 0 ; find last write time + INT 21h ; File_Times + not_used <5700> + mov es:[di].FTime,cx ; save time ;AC000; + mov es:[di].FDate,dx ; save date ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN87 +$$IF87: + + mov ah,DOS_error ; load return code (DOS extended error);AC000; + +; $endif ; ;AC000; +$$EN87: + + ret + + ENDPROC Open_File + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Fill_Memory +;******************************************************************************* +; +;Description: Read in as much of IBMBIOS and IBMDOS as room permits +; +;Called Procedures: None +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Fill_Memory +; +; get length of buffer +; get BIOS source handle +; point to beginning of buffer +; save total buffer length +; if < 64k to read and +; if amount to read < buffer +; set length to IBMBIO length +; endif +; if amount to read > 0 +; read the file (INT21 read +00 <3F00>) +; else +; set size to zero +; clear error flag (CF) +; endif +; if error or +; if not all of file read +; recover size +; set fail flag +; else +; update pointer for dos read +; recover size +; calculate remainder +; get DOS source handle +; if < 64k to read and +; if amount to read < buffer +; set length to IBMBIO length +; endif +; read the file (INT21 read +00 <3F00>) +; if no error and +; if all of file read +; update pointer for DOS read +; reset fail flag +; endif +; endif +; ret +; +; END Fill_Memory +; +;******************- END OF PSEUDOCODE -************************************** + +public fill_memory + + Fill_Memory PROC NEAR + + mov ax,4200h ; LSEEK to end of last read ;AN001; + mov bx,BIOSInFH ; ;AN001; + mov cx,BIOSPos[2] ; ;AN001; + mov dx,BIOSPos[0] ; ;AN001; + int 21h ; ;AN001; + mov ax,4200h ; LSEEK to end of last read ;AN001; + mov bx,DOSInFH ; ;AN001; + mov cx,DOSPos[2] ; ;AN001; + mov dx,DOSPos[0] ; ;AN001; + int 21h ; ;AN001; + + mov cx,cbBuf ; get length of buffer + mov bx,BIOSInFH ; get bios source handle + mov dx,OFFSET BUF+FAT_BUF ; point to beginning of buffer + ; past area to read in boot rec + push cx ; save away total length + cmp BIOSLenHigh,0 ; is there < 64K to read? + +; $if e,and ; if so - or................... ;AC000; + JNE $$IF90 + ; : + cmp BIOSLenLow,cx ; more left to read? : + ; ie: is amount to read < buffer +; $if b ; if amount to read < buffer..: ;AC000; + JNB $$IF90 + + mov cx,BIOSLenLow ; set length to IBMBIO length + +; $endif ; ;AC000; +$$IF90: + + cmp cx,0 ; is there anything to read? + +; $if a ; if so - read it + JNA $$IF92 + + mov ah,Read ; read the file + int 21h ; read + not_used <3F00>) + +; $else ; don't bother + JMP SHORT $$EN92 +$$IF92: + + xor ax,ax + clc + +; $endif +$$EN92: + +; $if c,or ; if error or.................. ;AC000; + JC $$LL95 + + cmp ax,cx ; Did we get it all? : + +; $if nz ; if not all of file read.....: ;AC000; + JZ $$IF95 +$$LL95: + + pop cx ; recover size + stc ; set fail flag + +; $else ; ;AC000; + JMP SHORT $$EN95 +$$IF95: + + add BIOSPos[0],ax ; save amount read for later lseek ;AN001; + adc BIOSPos[2],0 ; save amount read for later lseek ;AN001; + + add dx,ax ; update pointer for DOS Read + mov pDOS,dx ; point to beginning of DOS + sub BIOSLenLow,ax ; decrement remaining + sbb BIOSLenHigh,0 ; do 32 bit + pop cx ; get original length + sub cx,ax ; this much is left + mov bx,DOSInFH ; get bios source handle + cmp DOSLenHigh,0 ; > 64K to read? +; $if e,and ; if < 64k to read and.......... ;AC000; + JNE $$IF97 + cmp DOSLenLow,cx ; is amount to read < buffer : + +; $if b ; if its less .................: ;AC000; + JNB $$IF97 + + mov cx,DOSLenLow ; set length to IBMDOS length + +; $endif ; ;AC000; +$$IF97: + + mov ah,Read ; read the file + INT 21h ; read + not_used <3F00>) + +; $if nc,and ; no error and................... ;AC000; + JC $$IF99 + + cmp ax,cx ; is all of file read ? : + +; $if z ; all of file read..............: ;AC000; + JNZ $$IF99 + + add DOSPos[0],ax ; save amount read for later lseek ;AN001; + adc DOSPos[2],0 ; save amount read for later lseek ;AN001; + + add dx,ax ; update pointer for DOS Read + mov pDOSEnd,DX ; point to End of dos DOS + sub DOSLenLow,AX ; decrement remaining + sbb DOSLenHigh,0 ; do 32 bit arithmetic + clc ; reset fail flag + +; $endif ; ;AC000; +$$IF99: + +; $endif ; ;AC000; +$$EN95: + + ret + + ENDPROC Fill_Memory + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_SYS_Conditions +;******************************************************************************* +; +;Description: Verify that the target disk is in a state that a SYS to it will +; be allowed. If an error occurs in any of the called routines, +; the return code will already be loaded by the failing routine. +; +;Called Procedures: Verify_File_System +; Read_Directory +; Verify_File_Location +; Determine_Free_Space +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_SYS_Conditions +; +; verify target is a FAT file system (CALL Verify_File_System) +; if no error and +; load root directory of target (CALL Read_Directory) +; if no error and +; check that IBMBIO,IBMDOS are in right place (CALL Verify_File_Location) +; if no error and +; check for sufficient space for system files (CALL Determine_Free_Space) +; if no error +; load return code (success) +; reset fail flag +; endif +; ret +; +; END Check_SYS_Conditions +; +;******************- END OF PSEUDOCODE -************************************** + +public Check_SYS_Conditions + + Check_SYS_Conditions PROC NEAR + + call Verify_File_System ; verify target is a FAT file system ;AN000; + +; $if nc,and ; no error and ;AN000; + JC $$IF102 + + call Read_Directory ; load root directory of target ;AN000; + +; $if nc,and ; no error and ;AN000; + JC $$IF102 + + call Verify_File_Location ; check that IBMBIO,IBMDOS are in right;AN000; + ; place +; $if nc ; no error and ;AN000; + JC $$IF102 + + call Determine_Free_Space ; check if enough space for system file;AN000; + +; $endif ; ;AN000; +$$IF102: + + ret ; ;AN000; + + ENDPROC Check_SYS_Conditions + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Verify_File_System +;******************************************************************************* +; +;Description: Get the file system for the specified drive, then compare to +; FAT. If not, issue message and exit. Must ensure that target +; drive has media in it before this routine is called +; +;Note: This routine contains code that is specifically required for +; operation on DOS 3.3. This code must be removed for later releases +; of DOS. +; +;Called Procedures: None +; +;Input: Drive Number (0=default, 1=A, 2=B) in BL +; +;Output: no error - CF = 0 +; error - CF = 1 +; AX = return code +; AH = utility messages +; AL = 15d - Not able to SYS to xxx file system +; CX = 1 - only one substitution +; DS:SI = sublist for substitution +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Verify_File_System +; +; if dos = current +; load drive id (BL) +; get_extended_device_parameters (INT21 IOCtl + 0Dh <440D> CX=086E) for drive +; if error - check if old version destination +; find out what the error was (CALL Get_DOS_Error) +; if not old version error +; load return code (DOS Extended Error Class) +; set fail flag +; else +; reset fail flag +; endif +; else +; if returned file system type = "FAT12 " or +; if returned file system type = "FAT16 " +; reset fail flag +; else +; indicate insert required +; set up pointer for insert - sublist +; load return code (Unable to SYS to xxxxxxxx file system) +; set fail flag +; endif +; endif +; endif +; +; ret +; +; END Verify_File_System +; +;******************- END OF PSEUDOCODE -************************************** + +public Verify_File_System + + Verify_File_System PROC NEAR + + cmp DOS_VER,0 ; running on current DOS ? ;AN019; +; $if e ; if we are ;AN019; + JNE $$IF104 + mov bl,TargDrvNum ; load drive id (BL) ;AN000; + lea dx,IOCtl_Buf ; point to output buffer ;AN000; + mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and filetype ;AC019; + INT 21h ; INT 21 GetSetMediaID request <6900> ;AC019; + +; $if c ; error - check if old version dest ;AN000; + JNC $$IF105 + + call Get_DOS_Error ; find out what the error was ;AN000; + + cmp al,old_type_media ; is it IBM but < 4.0 ? ;AN000; + +; $if ne ; not old version error ;AN000; + JE $$IF106 + + mov ah,DOS_error ; load return code (DOS Extended Error);AN000; + stc ; set fail flag ;AN000; + +; $else ; ;AN000; + JMP SHORT $$EN106 +$$IF106: + + clc ; reset fail flag ;AN000; + +; $endif ; ;AN000; +$$EN106: + +; $else ; ELSE it is => 4.00 ;AN000; + JMP SHORT $$EN105 +$$IF105: + + lea si,IOCtl_File_Sys ; see if file type is fat12 ;AN000; + lea di,fat_12 ; ;AN000; + mov cx,file_sys_size ; ;AN000; + cld ; ;AN000; + repe cmpsb ; ;AN000; + cmp cx,3 ; did it fail at the 2 in fat12 ? ;AN000; + +; $if e,and ; if it did and............ ;AN000; + JNE $$IF110 + + cmp BYTE PTR ds:[si-1],"6" ; was it a 6 ? : ;AN000; + +; $if e ; if it was...............: ;AN000; + JNE $$IF110 + + repe cmpsb ; then keep going ;AN000; + +; $endif ; ;AN000; +$$IF110: + + cmp cx,0 ; did we reach the end ? ;AN000; + +; $if e ; if we did it was "FAT12 " or ;AN000; + JNE $$IF112 + ; "FAT16 " so its OK to SYS + + clc ; reset fail flag ;AN000; + +; $else ; ;AN000; + JMP SHORT $$EN112 +$$IF112: + + lea di,File_Sys_End ; set up pointer to end of insert ;AN000; + dec di ; back up to last character ;AN000; + mov cx,file_sys_size ; strip off trailing blanks ;AN017; + mov al," " ; strip off trailing blanks ;AN017; + std ; scan backwards ;AN017; + repe scas IOCTL_File_Sys ; ;AN017; + cld ; stops at 2 past last " " ;AN017; + inc di ; 1 past ;AN017; + inc di ; last (first) blank ;AN017; + xor al,al ; make it an ASCIIZ ;AN017; + stos IOCTL_File_Sys ; ;AN017; + lea si,IOCTL_File_Sys ; set up pointer to the insert ;AN000; + mov [insert_ptr_off],si ; ;AN017; + mov [insert_ptr_seg],ds ; ;AN017; + lea si,sublist ; set pointer to SUBLIST ;AN017; + mov ax,(util_C shl 8) + cant_sys ; load return code ;AN000; + ; - Unable to SYS to xxx file system + stc ; set fail flag ;AN000; + +; $endif ; ;AN000; +$$EN112: + +; $endif ; ;AN000; +$$EN105: + +; $else ; not running on current DOS ;AN019; + JMP SHORT $$EN104 +$$IF104: + + clc ; keep going ;AN019; + +; $endif ; running on current DOS ;AN019; +$$EN104: + + ret ; ;AN000; + + ENDPROC Verify_File_System + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Read_Directory +;******************************************************************************* +; +;Description: Read in first sector of directory. The reason that we do the +; direct read of the directory is the find first/next or search +; first/next do an exclusive search for volume labels. By using +; these CALLs, there is no way to determine if a volume label +; occupies the first location in the directory. Hence we get sleazy +; and read the directory directly (no pun intended) to get this +; info. Only read in the first sector of directory. Also, this +; ensures there is a media in the drive. +; +;CALLed Procedures: Prompt_for_Media, Find_DPB +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Read_Directory +; +; set up drive letter in destignation filespecs +; call Find_DPB to get directory location +; load first DIR sector number +; point at buffer for directory +; read first sector of directory (INT 25h) +; ret +; +; END Read_Directory +; +;******************- END OF PSEUDOCODE -************************************** + + public Read_Directory + + Read_Directory PROC NEAR + + mov al,TargDrv ; set up drive letter in destignation filespecs + mov BIOSName,al ; point names at destination drive + mov DOSName,al ; + + MOV DL,TargDrvNum ; load drive + PUSH DS ; save register + call Find_DPB ; initalize DPB parameters + POP AX + mov ds,ax + mov es,ax + xor ax,ax ; request a read + mov dx,[first_dir_sector] ; read starting dir sector + mov [packet],dx ; get starting dir sector ;AN001; + mov bx,offset DIR_SECTOR + mov PACKET_BUFFER[0],bx ; ;AN001; + mov PACKET_BUFFER[2],ds ; ;AN001; + mov word ptr [packet_sectors],1 ; ;AN001; + call Direct_Access ; to read the sector + + mov ax, (util_B shl 8) + write_fail ; load message ;AC000; + ; - Write failure, diskette unuseable + ; in case an error occured + ret + + ENDPROC Read_Directory + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Verify_File_Location +;******************************************************************************* +; +;Last Update: 09/22/87 +; +;Description: Determines if IBMBIO and IBMDOS are the first two directory +; entries, or if these entries are empty. If so, find the size +; of the files if they exist. If spaces not empty and don't +; contain IBMBIO and IBMDOS, set fail flag and load return code. +; Also determines if existing IBMBIO starts in cluster 2. If not +; set fail flag and load return code. +; +;CALLed Procedures: None +; +;Input: DIR in BUFFER +; +;Output: no error - CF = 0 +; error - CF = 1 +; AX = return code +; AH = utility essages +; AL = 8 - No room for system on destination disk +; 9 - Incompatible system size +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Verify_File_Location +; +; if all files deleted (Dir_Name in dir is 00h) +; reset fail flag +; else +; if first file deleted (Dir_Name is 0E5h) +; reset fail flag +; else +; if first file IBMBIO.COM +; get IBMBIO Size +; indicate we found IBMBIO +; clear error flag +; else +; call Move_DIR_Entry +; call Free_Cluster +; endif +; endif +; if no error so far and +; if IBMBIO found +; call Free_Cluster +; endif +; if no error so far +; if all files deleted starting at second location or +; if second file deleted (Dir_Name is 0E5h) +; reset fail flag +; else +; if second file IBMDOS.COM +; get IBMDOS size +; indicate we found IBMDOS +; reset fail flag +; else +; call Move_DIR_Entry +; endif +; endif +; endif +; endif +; +; ret +; +; END Verify_File_Location +;******************- END OF PSEUDOCODE -************************************** + + public Verify_File_Location + + Verify_File_Location PROC NEAR + ;--------------------------------------- + ; Now see if the first two directory + ; entries are available... + ; First check for being free: + ;--------------------------------------- + mov bp,OFFSET DIR_SECTOR + mov si,bp + cmp BYTE PTR [si],empty ; empty dir? + +; $if e,or ; if all files deleted ;AC012; + JE $$LL118 + ; (Dir_Name in dir is 00h) + + cmp BYTE PTR [si],deleted ; is first file deleted ? + +; $if e ; if it is ;AC012; + JNE $$IF118 +$$LL118: + ; (Dir_Name is 0E5h)................: + clc ; clear error flag ;AN003; + call Free_Cluster ; check the cluster chain just in case ;AC012; + +; $else long ; not empty ;AC000; + JMP $$EN118 +$$IF118: + ;--------------------------------------- + ; The first entry is not free. See if + ; the BIOS is there. + ;--------------------------------------- + mov di,OFFSET FCBBIO ; pointer to name + mov cx,file_spec_length ; length of name + cld ; go forward + rep cmpsb ; check it + +; $if e ; first file IBMBIO.COM ;AC000; + JNE $$IF120 + + dec BIOSEntFree ; indicate we found IBMBIO ( = 0) + mov si,bp + mov ax,word ptr ds:[si].dir_size_l ; Get the size of IBMBIO ;AC000; + mov word ptr IBMBIO_Low,ax + mov ax,word ptr ds:[si].dir_size_h ; ;AC000; + mov word ptr IBMBIO_High,ax + cmp ds:[si].dir_first,2 ; does IBMBIO own Clust 2? ;AC005; +; $if e ; if so ;AC005; + JNE $$IF121 + inc [bio_owns_it] ; - keep track ;AC005; +; $endif ; ;AC005; +$$IF121: + + call Free_Cluster ; ;AN003; + +; $else ; its not IBMBIO ;AC000; + JMP SHORT $$EN120 +$$IF120: + + mov si,bp ; restore pointer to start of entry ;AN003; + call Move_DIR_Entry ; move the entry out of the way ;AN003; + +; $if nc,and ; ;AN003; + JC $$IF124 + + call Free_Cluster ; make sure reqd. clusters are free ;AN003; + +; $if nc ; ;AC000; + JC $$IF124 + + xor ax,ax ; + +; $else ; ;AC000; + JMP SHORT $$EN124 +$$IF124: + + mov ax,(util_B shl 8) + no_room ; load return code in case we fail;AN000; + stc ; - No room for system on dest... ;AC000; + +; $endif ; ;AC000; +$$EN124: + +; $endif ; ;AC000; +$$EN120: + +; $endif ; ;AC000; +$$EN118: + + ;--------------------------------------- + ; Check the second entry + ;--------------------------------------- + +; $if nc ; if no errors so far ;AC000; + JC $$IF129 + + ; ensure that the first sector of root ;AN003; + ; is loaded ;AN003; + mov ax,[first_dir_sector] ; get starting dir sector ;AN001; + mov packet,ax ; ;AN001; + mov [packet_buffer],offset DIR_SECTOR ; ;AN001; + mov word ptr [packet_sectors],1 ; ;AN001; + xor ax,ax ; request a read + call Direct_Access ; to read the root + +; $if nc ; ;AC000; + JC $$IF130 + + add bp,TYPE dir_entry ; ;AC000; + mov si,bp ; ;AC000; + mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AC000; + ; - No room for system on dest.. + cmp BYTE PTR [si],empty ; empty dir entry? + +; $if e,or ; if deleted starting at 2nd entry or. ;AC000; + JE $$LL131 + + cmp BYTE PTR [si],deleted ; deleted ? : + +; $if e ; if deleted (0E5h)...................:;AC000; + JNE $$IF131 +$$LL131: + + clc ; reset fail flag + +; $else ; ;AC000; + JMP SHORT $$EN131 +$$IF131: + + ; This entry is not free. + mov di,OFFSET FCBDOS ; see if it is IBMDOS + mov cx,file_spec_length ; length of name + rep cmpsb ; compare it + mov si,bp ; restore pointer to start ;AC000; + +; $if e ; if second file is IBMDOS.COM. ;AC000; + JNE $$IF133 + + dec DOSEntFree ; indicate we found IBMDOS + mov ax,word ptr ds:[si].dir_size_l ; Get the size of ;AC000; + mov word ptr IBMDOS_Low,ax ; file for IBMDOS + mov ax,word ptr ds:[si].dir_size_h ; ;AC000; + mov word ptr IBMDOS_High,ax + clc ; reset fail flag ;AN000; + +; $else ; error condition ;AC000; + JMP SHORT $$EN133 +$$IF133: + + call Move_DIR_Entry ; ;AN003; + +; $endif ; ;AC000; +$$EN133: + +; $endif ; ;AC000; +$$EN131: + +; $else ; ;AC000; + JMP SHORT $$EN130 +$$IF130: + mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AN000; +; $endif ; ;AC000; +$$EN130: + +; $endif ; ;AC000; +$$IF129: + + ret ; ;AN000; + + ENDPROC Verify_File_Location + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Determine_Free_Space +;******************************************************************************* +; +;Last Update: 3/18/87 +; +;Description: Determine if there is enough space on the disk, given the free +; space and the space taken up by IBMBIO and IBMDOS to install the +; new IBMBIO and IBMDOS. Routine will set fail flag and load return +; code if there is not enough room. +; +; Here we make some VERY IMPORTANT assumptions. +; +; 1) If IBMBIO exists on the disk currently, we assume it is in the +; correct place, i.e. at the front of the data area & contiguous. +; 2) The stub loader portion of IBMBIO is less than 2048 bytes long. +; This number comes about by assuming we will never overlay +; anything smaller than 1920 bytes (DOS 1.10 IBMBIO size). This +; can be expanded to 2048 if we also assume the smallest possible +; cluster length is 512 bytes. +; +; Therefore, if we have an empty disk or IBMBIO exists, then we have +; enough contiguous room to install the portion of IBMBIO that +; requires itself to be contiguous. +; +;CALLed Procedures: None +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 +; AX = return code +; AH = utility messages +; AL = 8d - No room for system on destination disk +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Determine_Free_Space +; +; get disk free space (INT21 Get_Drive_Freespace + 00 <3600>) +; compute Bytes/Cluster (32bit math required) +; convert current IBMBIO into cluster size (CALL Get_Cluster) +; convert current IBMDOS into cluster size (CALL Get_Cluster) +; get total number of clusters available +; convert new IBMBIO into cluster size (CALL Get_Cluster) +; convert new IBMDOS into cluster size (CALL Get_Cluster) +; get total number of clusters needed +; if available clusters < needed clusters +; load return code (No room for system on destination disk) +; set fail flag +; else +; reset fail flag +; endif +; ret +; +; END Determine_Free_Space +; +;******************- END OF PSEUDOCODE -************************************** + + public Determine_Free_Space + + Determine_Free_Space PROC NEAR + + mov ah,Get_Drive_Freespace ; get disk free space + mov dl,TargDrvNum ; get the drive number + INT 21h ; Get_Drive_Freespace <36xx> + ; compute Bytes/Cluster - 16 bit math ok + ; AX = sectors / cluster + ; CX = bytes / sector + ; BX = available clusters + mul cx ; get bytes/cluster + ; result left in AX + mov Bytes_Per_Cluster,ax ; save this value for Get_Clusters + mov Number_Free_Clusters,bx ; save available space + + mov ax,IBMBIO_Low ; low result in AX, High result in DX + mov dx,IBMBIO_High + call Get_Cluster ; convert old IBMBIO into cluster size + + add Number_Free_Clusters,ax ; add it to available space + + mov ax,IBMDOS_Low ; low result in AX, High result in DX + mov dx,IBMDOS_High + call Get_Cluster ; convert old IBMDOS into cluster size + + add Number_Free_Clusters,AX ; get total number of clusters available + + mov ax,NEWBIO_Size_Low ; find total size of new DOS and BIOS + mov dx,NEWBIO_Size_High + + call Get_Cluster ; convert new IBMBIO into cluster size + + mov Need_Clusters,ax ;save new BIO clusters + + mov ax,NEWDOS_Size_Low + mov dx,NEWDOS_Size_High + + call Get_Cluster ; convert new IBMDOS into cluster size + + add AX,Need_Clusters ; get total number of clusters needed + + cmp AX,Number_Free_Clusters ;Now see if there is enough room + ; for all of it on the disk +; $if a ; if needed > available clusters ;AC000; + JNA $$IF140 + + mov ax,(util_B shl 8) + no_room ; load return code ;AC000; + ; - No room for system on dest.. + stc ; set fail flag + +; $else ; ;AC000; + JMP SHORT $$EN140 +$$IF140: + + clc ; reset fail flag + +; $endif ; ;AC000; +$$EN140: + + ret ; ;AN000; + + ENDPROC Determine_Free_Space + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Get_Cluster +;******************************************************************************* +; +;Description: Convert bytes to clusters, rounding up to the next +; cluster size if needed. +; +;Called Procedures: None +; +;Input: (AX) = Number of bytes +; Bytes_Per_Cluster = # of bytes per cluster +; +;Output: (AX) = Number of clusters +; +;Registers used: AX BX DX +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Get_Cluster +; +; divide size by bytes_per_cluster +; if there is a remainder +; round up to next cluster +; endif +; ret +; +; END Get_Cluster +; +;******************- END OF PSEUDOCODE -************************************** + + public Get_Cluster + + Get_Cluster PROC NEAR + + mov bx,Bytes_Per_Cluster ; Bytes/cluster + div bx ; divide size by bytes_per_cluster + cmp dx,0 ; is there a remainder in DX? + +; $if ne ; if there is a remainder ;AC000; + JE $$IF143 + ; we have another cluster to round up + inc ax ; round up to next cluster + +; $endif ; ;AC000; +$$IF143: + + ret + + ENDPROC Get_Cluster + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Do_SYS +;******************************************************************************* +; +;Description: Control routine to handle the transfer of system files from +; memory to target drive. +; +;Called Procedures: Create_System +; Fill_Memory +; Dump_Memory +; +;Input: IBMBIO_Size_Loaded +; IBMDOS_Size_Loaded +; +;Output: no error - CF = 0 +; error - CF = 1 AX = return code (message #) +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Do_SYS +; +; create new IBMBIO and IBMDOS, in place if exist (CALL CREATE_SYSTEM) +; if no error +; search +; write out contents of memory to file (CALL Dump_Memory) +; load error return code (assume error) +; leave if error +; exit if if all files copied +; reset fail flag +; orelse +; read in file from source (CALL Fill_Memory) +; load error return code (assume error) +; leave if error +; endloop +; set fail flag +; endsearch +; endif +; ret +; +; END Do_SYS +; +;******************- END OF PSEUDOCODE -************************************** + + public Do_SYS + + Do_SYS PROC NEAR + + call CREATE_SYSTEM ; create IBMBIO and IBMDOS, in place ;AN000; + +; $if nc ; no error ;AC000; + JC $$IF145 + + push ds + lds bx,THIS_DPB ; set up pointer to DPB ;AC000; + mov [bx.dpb_next_free],2 ; reset Allocation to start of disk ;AC000; + pop ds ; so BIOS goes in right place! + +; $search ; ;AC000; +$$DO146: + + call Dump_Memory ; write out contents of memory to file + + mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000; + +; $leave c ; quit if error ;AC000; + JC $$EN146 + + mov ax,DOSLenHigh ; more DOS to move ? + or AX,DOSLenLow ; more low dos + or AX,BIOSLenHigh ; more high BIOS + or AX,BIOSLenLow ; more low BIOS + +; $exitif z ; if all files copied ;AC000; + JNZ $$IF146 + + clc ; reset fail flag ;AC000; + +; $orelse ; ;AC000; + JMP SHORT $$SR146 +$$IF146: + + call get_rest_of_system + + mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000; + +; $leave c ; if error ;AC000; + JC $$EN146 + +; $endloop ; ;AC000; + JMP SHORT $$DO146 +$$EN146: + +; $endsrch ; ;AC000; +$$SR146: + +; $endif ; ;AC000; +$$IF145: + + ret ; ;AN000; + + ENDPROC Do_SYS + + PUBLIC Get_Rest_of_System + + Get_Rest_of_System Proc near + + pushf ; ;AN001; + + mov bx,BIOSOutFH ; ;AN001; + mov ah,Close ; ;AN001; + int 21h ; ;AN001; + + mov bx,DOSOutFH ; ;AN001; + mov ah,Close ; ;AN001; + int 21h ; ;AN001; + + mov dx,offset SourceBIOSName ; ;AN001; + mov ax,(OPEN SHL 8) + not_used ; open file for read + int 21h ; ;AN001; + mov biosinfh,ax + + mov dx,offset SourceDOSName ; ;AN001; + mov ax,(OPEN SHL 8) + not_used ; open file for read + int 21h ; ;AN001; + mov dosinfh,ax + + call Fill_Memory ; read in file from source + + mov bx,BIOSInFH ; ;AN001; + mov ah,Close ; ;AN001; + int 21h ; ;AN001; + + mov bx,DOSInFH ; ;AN001; + mov ah,Close ; ;AN001; + int 21h ; ;AN001; + + mov dx,offset BIOSName ; ;AN001; + mov ax,(Open shl 8) + 2 ; Open file + INT 21h + mov BIOSOutFH,ax + + mov dx,offset DOSName ; ;AN001; + mov ax,(Open shl 8) + 2 ; Open file + INT 21h + mov DOSOutfh,ax + + popf ; ;AN001; + + RET + + endproc get_rest_of_system + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Create_System +;******************************************************************************* +; +;Description: +; +;Called Procedures: Create_File +; +;Input: None +; +;Output: IBMBIO_Handle +; IBMDOS_Handle +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Create_System +; +; create IBMBIO (CALL Create_File) +; if no error and +; save handle to IBMBIO_Handle +; create IBMDOS (CALL Create_File) +; if no error +; save handle to IBMDOS_Handle +; reset fail flag +; endif +; ret +; +; END Create_System +; +;******************- END OF PSEUDOCODE -************************************** + + public Create_System + + Create_System PROC NEAR + + mov [open_seg],ds + mov dx,OFFSET BIOSName ; point to IBMBIO ASCIIZ string + mov al,[BIOSEntFree] ; get status of IBMBIO ;AN006; + mov [EntryFree],al ; update file status (0 = found,1 = not;AN006; + + call Create_File ; create IBMBIO ;AN000; + +; $if nc,and ; no error and ;AC000; + JC $$IF154 + + mov BIOSOutFH,ax ; save handle to IBMBIO_Handle + mov dx,OFFSET DOSName ; pointer to IBMDOS ASCIIZ string + mov al,[DOSEntFree] ; get status of IBMDOS ;AN006; + mov [EntryFree],al ; update file status (0 = found,1 = not;AN006; + + call Create_File ; create IBMDOS ;AN000; + +; $if nc ; no error ;AC000; + JC $$IF154 + + mov DOSOutFH,ax ; save handle to IBMDOS_Handle + +; $endif ; ;AC000; +$$IF154: + + ret ; ;AN000; + + ENDPROC Create_System + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Create_File +;******************************************************************************* +; +;Last Update: 9/23/87 +; +;Description: Remove the read only attribute from IBMBIO and IBMDOS. If +; file not found error occurs, it is okay, because it just +; means the file was not there. Do create with read-only +; hidden, and system file attributes. This is an in place +; create if the file exists already. +; +; +;Called Procedures: None +; +;Input: DS:DX = pointer to ASCIIZ string for file create +; +;Output: no error - CF = 0 +; AX = file handle +; error - CF = 1 +; AX = return code +; AH = extended DOS errors +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Create_File +; +; set file attributes to 0 (INT21 CHMod + SetAtrib <4301>) +; if no error or +; if error = file not found and +; ext Open file with attributes of 7 (INT21 ExtOpen + SetAtrib <6C12> CX=7) +; if no error +; reset fail flag +; else +; load return code (DOS Extended Error) +; set fail flag +; endif +; ret +; +; END Create_File +; +;******************- END OF PSEUDOCODE -************************************** + + public Create_File + + Create_File PROC NEAR + + mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0 + xor cx,cx ; set attributes to 0 + mov [open_off],dx ; save pointer to ASCIIZ for OPEN + INT 21h ; CHMod + SetAtrib <4301>) + +; $if nc ; no error ;AC000; + JC $$IF156 + + cmp [EntryFree],0 ; is file in the correct spot? ;AN006; +; $if ne ; if it is not - we have a problem ;AN006; + JE $$IF157 + mov dx,[open_off] ; get pointer to ASCIIZ for UNLINK ;AN006; + mov ax,(UNLINK shl 8) ; UNLINK the file + INT 21h ; UNLINK <4100>) ;AN006; +; $endif ; ;AN006; +$$IF157: +; $else ; - check the error ;AN006; + JMP SHORT $$EN156 +$$IF156: + call Get_DOS_Error ; find out what went wrong ;AN000; + cmp al,file_not_found ; not there? + +; $if e ; IBMBIO was not there ;AC000; + JNE $$IF160 + clc ; ok to open ;AC000; +; $else ; ;AC000; + JMP SHORT $$EN160 +$$IF160: + stc ; some other error - quit ;AC000; +; $endif ; ;AC000; +$$EN160: +; $endif ; ;AC000; +$$EN156: +; $if nc ; if no error ;AC006; + JC $$IF164 + + lds si,OPEN_PARMS ; ;AC005; + xor cx,cx ; DOS system file atributes ;AC005; + cmp DOS_VER,0 ; running on current DOS ? ;AN019; + +; $if ne ; if on old DOS ;AN019; + JE $$IF165 + mov dx,si ; DS:DX - file name ;AN019; + mov ax,(Creat shl 8) + 0 ; Create file <3D00> ;AN019; +; $else ; ;AN019; + JMP SHORT $$EN165 +$$IF165: + mov di,cx ; ;AC005; + dec di ; ;AC005; + mov bx,open_mode ; set up for mode ;AN000; + mov dx,(openit shl 4) + replaceit ; create if does not exist, ;AN000; + ; replace it if it does + mov ax,(ExtOpen shl 8) + 0 ; ext Open file with attributes of 0 ;AN000; + ; ExtOpen + SetAtrib <6C12> CX=0 +; $endif ; ;AN019; +$$EN165: + + INT 21h ; do the open + +; $endif ; ;AC000; +$$IF164: + +; $if c ; if error ;AN000; + JNC $$IF169 + + call Get_DOS_Error ; find out what went wrong ;AN000; + mov ah,DOS_error ; load return code (DOS Extended Error);AN000; + stc ; ;AN006; + +; $endif ; ;AN000; +$$IF169: + + ret ; ;AC000; + + ENDPROC Create_File + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Dump_Memory +;******************************************************************************* +; +;Description: Write out as much of IBMBIOS and IBMDOS as is in memory. +; +;Called Procedures: None +; +;Input: None +; +;Output: no error - CF = 0 +; error - CF = 1 +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Dump_Memory +; +; get pointer to start of buffer +; subtract the start of IBMDOS +; if lenght is non-zero and . . . . . . . . . . . . . . . . +; load IBMBIOS handle : +; write out IBMBIOS (INT21 Write + 00 <4000>) : +; if no error and . . . . . . . . . . . . . . . . . . . . : +; if not all data written . . . . . . . . . . . . . . . . : +; set fail flag +; endif +; if no error so far +; get beginning of dos +; subtract end of dos +; if lenght is non-zero and +; load IBMDOS handle +; write out IBMDOS (INT21 Write + 00 <4000>) +; if no error and +; if not all data written . . . . . . . . . . . . . . . . : +; set fail flag +; endif +; endif +; ret +; +; END Dump_Memory +; +;******************- END OF PSEUDOCODE -************************************** + + public Dump_Memory + + Dump_Memory PROC NEAR + + mov ax,4202h ; LSEEK to end of file ;AN001; + mov bx,BIOSOutFH ; ;AN001; + xor cx,cx ; ;AN001; + xor dx,dx ; ;AN001; + int 21h ; ;AN001; + mov ax,4202h ; LSEEK to end of file ;AN001; + mov bx,DOSOutFH ; ;AN001; + xor cx,cx ; ;AN001; + xor dx,dx ; ;AN001; + int 21h ; ;AN001; + + mov dx,OFFSET BUF+FAT_BUF ; get pointer to start of buffer + mov cx,pDOS ; beginning of next guy + sub cx,dx ; difference is length + +; $if nz,and ; if lenght is non-zero and....... ;AC000; + JZ $$IF171 + + mov bx,BIOSOutFH ; load IBMBIOS handle : + mov ah,Write ; write out IBMBIOS : + INT 21h ; Write + 00 <4000> : + +; $if nc,and ; if no error and.................: ;AC000; + JC $$IF171 + + cmp ax,cx ; Did it work? : + +; $if ne ; all data written................: ;AC000; + JE $$IF171 + + stc ; set fail flag + +; $endif ; ;AC000; +$$IF171: + +; $if nc ; if no error so far ;AC000; + JC $$IF173 + + mov dx,pDOS ; get beginning of dos + mov cx,pDOSEnd ; subtract end of dos + sub cx,dx ; difference is length + +; $if nz,and ; if lenght is non-zero and........ ;AC000; + JZ $$IF174 + + mov bx,DOSOutFH ; load IBMDOS handle : + mov ah,Write ; write out IBMDOS : + INT 21h ; Write + 00 <4000> : + +; $if nc,and ; if no error.....................: ;AC000; + JC $$IF174 + + cmp ax,cx ; Did it work? : + +; $if ne ; all data written................: ;AC000; + JE $$IF174 + + stc ; set fail flag + +; $endif ; ;AC000; +$$IF174: + +; $endif ; ;AC000; +$$IF173: + + ret + + ENDPROC Dump_Memory + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Do_End +;******************************************************************************* +; +;Description: Finish off with IBMBIOS and IBMDOS +; +;Called Procedures: Close_File +; Write_Boot_Record +; +;Input: None +; +;Output: no error - CF = 0 +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Do_End +; +; finish off and close IBMBIOS and IBMDOS (CALL Close_Files) +; update boot record (CALL Write_Boot_Record) +; ret +; +; END Do_End +; +;******************- END OF PSEUDOCODE -************************************** + + public Do_End + + Do_End PROC NEAR + + call Close_File ; finish off & close IBMBIOS and IBMDOS;AN000; + + call Write_Boot_Record ; update boot record ;AN000; + + ret ; ;AN000; + + ENDPROC Do_End + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Close_File +;******************************************************************************* +; +;Description: Set date and time on IBMBIOS and IBMDOS and close +; them. +; +;Called Procedures: None +; +;Input: BIOSTime, BIOSOutFH, DOSTime. DOSOutFH +; +;Output: IBMBIOS and IBMDOS closed +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Close_File +; +; load IBMBIOS time and date +; load IBMBIOS handle +; update file times (INT21 File_Times + 01 <5701>) +; close file (INT21 Close + 00 <3E00>) +; load IBMDOS time and date +; load IBMDOS handle +; update file times (INT21 File_Times + 01 <5701>) +; close file (INT21 Close + 00 <3E00>) +; ret +; +; END Close_File +; +;******************- END OF PSEUDOCODE -************************************** + + public Close_File + + Close_File PROC NEAR + + mov cx,BIOSTime ; load IBMBIOS time and date + mov dx,BIOSTime+2 + mov bx,BIOSOutFH ; load IBMBIOS handle + mov ax,(File_Times SHL 8) + set ; update file times + INT 21h ; File_Times + 01 <5701> + mov ah,Close ; close file IBMBIO + INT 21h ; Close + not_used <3Exx> + mov cx,DOSTime ; load IBMDOS time and date + mov dx,DOSTime+2 + mov bx,DOSOutFH ; load IBMDOS handle + mov ax,(File_Times SHL 8) + set ; update file times + INT 21h ; File_Times + 01 <5701> + mov ah,Close ; close file IBMDOS + INT 21h ; Close + not_used <3Exx> + + mov dx,offset BIOSName ; ;AN001; + mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0 + mov cx,DOS_system_atrib ; DOS system file atributes + INT 21h ; CHMod + SetAtrib <4301>) + + mov dx,offset DOSName ; ;AN001; + mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0 + mov cx,DOS_system_atrib ; DOS system file atributes + INT 21h ; CHMod + SetAtrib <4301>) + + ret ; ;AN000; + + ENDPROC Close_File + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Write_Boot_Record +;******************************************************************************* +; +;Description: Get a best guess EBPB and get the Media ID or fill the +; information in manually. Write out the canned boot record +; and then make IOCtl calls to set the EBPB and Media ID. +; +;Called Procedures: Create_Serial_ID +; +;Input: None +; +;Output: Boot record on destination media is installed. +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Write_Boot_Record +; +; get BPB using IOCtl Get Device Parameters (INT21 IOCtl + 0Dh <440d> CX=0860) +; get volid, ser# and file type using IOCtl Get Media ID (INT21 IOCtl + 0Dh <440d> CX=086E) +; if error and +; get Extended error +; if 'unknown media' - set fields manually +; compute serial id and put in field (CALL Create_Serial_ID) +; copy in volume label if available +; set pointer to FAT1x (CALL FAT_Size) +; move file system string into Boot_System_ID field +; else +; set fail flag +; load return code (DOS error) +; endif +; if no fail flag +; if fixed media +; fill in Ext_PhyDrv in canned boot record +; endif +; set BPB using data from GET BPB IOCTL +; write out canned boot record (INT26) +; set volid, ser# and file type using Set Media ID (INT21 SetID <6900> CX=084E) +; endif +; ret +; +; END Write_Boot_Record +; +;******************- END OF PSEUDOCODE -************************************** + + public Write_Boot_Record + + Write_Boot_Record PROC NEAR + + mov bl,TargDrvNum ; Drive number ;AN000; + mov dx,offset DeviceParameters ; ;AN000; + mov cx,(rawio shl 8) + get_device_parameters ; Generic IOCtl Request ;AN000; + ; CX=0860 + mov ax,(IOCtl shl 8) + generic_ioctl ; get BPB using Set Device Parm ;AN000; + INT 21h ; IOCtl + gen_IOCtl_request <440d> ;AN000; + + cmp DOS_VER,0ffh ; is it DOS 3.3? ;AN019; +; $if ne ; only do a GET if DOS 4.00 ;AN019; + JE $$IF177 + lea dx,IOCtl_Buf ; point to output buffer ;AN000; + mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and file type ;AC008; + INT 21h ; GetSetMediaID + 0 INT 21 <6900> ;AC008; + +; $if c ; error - see if its 'unknown media' ;AN000; + JNC $$IF178 + + call Get_DOS_Error ; get error ;AN000; + cmp al,old_type_media ; ;AN000; + +; $if e ; ;AN019; + JNE $$IF179 + stc ; do it all manually ;AN019; +; $else ; ;AN019; + JMP SHORT $$EN179 +$$IF179: + clc ; some other dos error occured - le ;AN019; +; $endif ; it go by ;AN019; +$$EN179: + +; $endif ; ;AN019; +$$IF178: +; $else ; ;AN019; + JMP SHORT $$EN177 +$$IF177: + stc ; do it all manually ;AN019; +; $endif ; ;AN019; +$$EN177: + +; $if c ; if it is pre 4.00 IBM format ;AN000; + JNC $$IF185 + + call Create_Serial_ID ; compute serial id and put in field ;AN000; + + ; find first with type = VOLUME ID + + mov dx,OFFSET ExtFCB ; set up for FCB call ;AN019; + mov ah,Dir_Search_First ; do a find first INT21 ;AN019; + + INT 21h ; Find_First <11xx> ;AN000; + + cmp al,0 ; was a match found? al = 0 yes ;AN019; + ; al = ff no +; $if e ; if so - copy it in ;AN000; + JNE $$IF186 + + lea si,DOS_BUFFER + 8 ; source id is in DTA ;AN019; + lea di,IOCtl_Vol_ID ; destination is in IOCtl_Buf ;AN000; + mov cx,file_spec_length ; move 11 bytes worth ;AN000; + cld ; copy it in ;AN000; + rep movsb ; ;AN000; + +; $else + JMP SHORT $$EN186 +$$IF186: + + clc ; leave it as default - NO NAME + +; $endif ; endif ;AN000; +$$EN186: + + ; NOTE: + ; since the GET MEDIA ID failed - its + ; pre 32 bit fat - so no 32 bit math + ; is required. + call FAT_Size ; set pointer to FAT1x ;AN000; + + mov cx,FAT_len ; move file system string into ;AN000; + ; Boot_System_ID field + lea di,IOCTL_File_Sys ; update buffer ;AN000; + cld ; ;AN000; + rep movsb ; ;AN000; +; $endif +$$IF185: + +; $if nc ; ;AN000; + JC $$IF190 + + lea si,DeviceParameters.DP_BPB + lea di,boot.EXT_BOOT_BPB + mov cx,type EXT_BPB_INFO + cld + rep movsb + + cmp DeviceParameters.DP_BPB.BPB_MediaDescriptor,hard_drive ; is it Hard drive?;AC000; + +; $if e ; if its a hard drive ;AC000; + JNE $$IF191 + + ; NOTE: The physical hard drive number + ; is placed in the third byte from + ; the end in the boot sector in + ; DOS 3.2. This is a change from + ; the previous DOS versions. + + ; fill in PhyDrv in canned boot record + mov al,80h ; (set physical hard drive number) ;AC016; +; $else + JMP SHORT $$EN191 +$$IF191: + xor al,al ; (set physical drive number to zero) ;AC016; +; $endif ; ;AC000; +$$EN191: + + mov BOOT.EXT_PHYDRV,al ; (set physical hard drive number) ;AC016; + + cmp DOS_VER,0 ; ;AN019; +; $if ne ; copy IOCTL stuff into boot record ;AN019; + JE $$IF194 + ; (no set ID available for 3.3) + lea si,IOCtl_Ser_No_Low ; point to source buffer (IOCTL) ;AN000; + lea di,BOOT.EXT_BOOT_SERIAL ; point to target buffer (BOOT record) ;AN000; + + mov cx,IOCTL_Ser_Vol_SyS ; move serial # , Volid , System ;AN019; + cld ; ;AN019; + rep movsb ; ;AN019; +; $endif ; ;AN019; +$$IF194: + + xor cx,cx ; Sector 0 ;AN019; + mov [packet],cx ; set starting sector as 0 ;AN019; + mov bx,offset BOOT ; ;AN019; + mov packet_buffer[0],bx ; ;AN019; + mov word ptr [packet_sectors],1 ; ;AN019; + mov ah,1 ; request a write ;AN019; + call Direct_Access ; ;AN019; + +; $if c ; ;AC000; + JNC $$IF196 +; $endif ; ;AC000; +$$IF196: + + cmp DOS_VER,0 ; ;AN019 +; $if e ; only do a SET if DOS 4.00 + JNE $$IF198 + mov bl,TargDrvNum ; Drive number ;AN000; + lea dx,IOCtl_Buf ; point to output buffer ;AN000; + mov ax,(GetSetMediaID shl 8) + 1 ; set volid, ser# and filetype ;AC008; + INT 21h ; GetSetMediaID + 1 INT 21 <6901> ;AC008; +; $endif ;AN019; +$$IF198: + +; $endif ; ;AC000; +$$IF190: + + ret + + ENDPROC Write_Boot_Record + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: FAT_Size +;******************************************************************************* +; +;Description: Determine FAT Type (12 or 16) +; +; NOTE: This routine is only called if the IOCtl call for +; Get Media Type FAILS with an extended error of +; 'Unknown media type'. This indicates it is a +; pre DOS 4.00 media (ie: it MUST be a 12 or old style +; 16 bit FAT +; +; This is the same algorithm used by FORMAT +; +; Algorithm: +; +; UsedSectors = number of reserved sectors +; + number of FAT Sectors ( Number of FATS * Sectors Per FAT ) +; + number of directory sectors ( 32* Root Entries / bytes Per Sector ) +; +; t_clusters = ( (Total Sectors - Used Sector) / Sectors Per Cluster) +; +; if T_Clusters <= 4086 then it a FAT12 - else - its a FAT16 +; +;Called Procedures: None +; +;Input: EBPB of Target media in memory +; +;Output: SI: points to "FAT12 " +; or "FAT16 " +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START FAT_Size +; +; Calculate the number of directory sectors +; Calculate and add the number of FAT sectors +; Add in the number of boot sectors +; subtract used sectors from total sectors +; if <= FAT THRESHOLD then +; set pointer to FAT12 +; else +; set pointer to FAT12 +; endif +; +; ret +; +; END FAT_Size +; +;******************- END OF PSEUDOCODE -************************************** + + public FAT_Size + + FAT_Size PROC NEAR + + ;-------------------------- + ; Calculate UsedSectors + ;--------------------------- + + ; Calculate the number of directory sectors + + mov ax, deviceParameters.DP_BPB.BPB_RootEntries ; ;AN000; + mov bx, TYPE dir_entry ; ;AN000; + mul bx ; ;AN000; + add ax, deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000; + dec ax ; ;AN000; + xor dx,dx ; ;AN000; + div deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000; + mov cx,ax ; ;AN000; + + ; Calculate the number of FAT sectors + + mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AN000; + mul deviceParameters.DP_BPB.BPB_NumberOfFATs ; ;AN000; + + ; Add in the number of boot sectors + + add ax, deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AN000; + add cx,ax ; ;AN000; + + ;-------------------------- + ; Calculate t_clusters + ;-------------------------- + + mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AN000; + + sub ax,cx ;Get sectors in data area ;AN000; + xor dx,dx ; ;AN000; + xor bx,bx ; ;AN000; + mov bl,deviceParameters.DP_BPB.BPB_SectorsPerCluster ; ;AN000; + div bx ;Get total clusters ;AN000; + cmp ax,BIG_FAT_THRESHOLD ;Is clusters < 4086? ;AN000; + +; $if be ; if less then its a FAT12 ;AN000; + JNBE $$IF201 + lea si,FAT_12 ; ;AN000; +; $else ; ;AN000; + JMP SHORT $$EN201 +$$IF201: + lea si,FAT_16 ; ;AN000; +; $endif ; ;AN000; +$$EN201: + + clc ; leave cleanly + + return ; ;AN000; + + ENDPROC FAT_Size + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Create_Serial_ID +;******************************************************************************* +; +;Description: Create unique 32 bit serial number by getting current date +; and time and then scrambling it around +; +;Called Procedures: None +; +;Input: None +; +;Output: serial number installed in Boot_Serial +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Create_Serial_ID +; +; Get date (INT21 Get_Date + 00 <2A00>) +; Get time (INT21 Get_Time + 00 <2C00>) +; Boot_Serial+0 = DX reg date + DX reg date +; Boot_Serial+2 = CX reg time + CX reg time +; ret +; +; END Create_Serial_ID +; +;******************- END OF PSEUDOCODE -************************************** + + public Create_Serial_ID + + Create_Serial_ID PROC NEAR + + mov ax,(Get_Date shl 8) + not_used ; Get date ;AN000; + INT 21h ; Get_Date + not_used <2A00> ;AN000; + mov ax,(Get_Time shl 8) + not_used ; Get time ;AN000; + INT 21h ; Get_Time + not_used <2C00> ;AN000; + add dx,dx ; Boot_Serial+0 = DX (date) + DX (date);AN000; + add cx,cx ; Boot_Serial+2 = CX (time) + CX (time);AN000; + mov IOCtl_Ser_No_Low,dx ; SERIAL # - low ;AN000; + mov IOCtl_Ser_No_Hi,cx ; SERIAL # - hi ;AN000; + + ret ; ;AN000; + + ENDPROC Create_Serial_ID + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Message +;******************************************************************************* +; +;Description: Display a message +; +;Called Procedures: SYSDISPMSG, Get_DOS_Error +; +;Input: (AL) message number +; (AH) message class +; = C - DS:SI points to sublist +; +;Output: no error AX = 0 +; error - AX = error exit code +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Message +; +; if DOS error +; call Get_DOS_error +; endif +; move message class into place +; reset insert (CX) +; reset response (DL) +; set output handle (BX) +; if CLASS requires insert +; load insert required +; if CLASS requires response +; flush keystroke buffer +; load response required (Dir CON in no echo) +; endif +; call SysDispMsg to display message +; if error or +; call Get_DOS_error +; call SysDispMsg to try again +; if not success message +; load error exit code +; else +; load success exit code +; endif +; ret +; +; END Message +; +;******************- END OF PSEUDOCODE -************************************** + + public Message + + Message PROC NEAR + + xor dx,dx ; reset response (DL) ;AN000; + xor cx,cx ; reset insert (CX) ;AC024; + dec dh ; assume CLASS is Utility ;AN000; + + cmp ah,PARSE_Error ; ;AN000; + +; $if be,and ; if DOS or PARSE error ;AN000; + JNBE $$IF204 + + mov dh,ah ; ;AN000; + +; $if e,and ; if PARSE error ;AN024; + JNE $$IF204 + cmp al,reqd_missing ; ;AC024; +; $if ne ; and if theres something there ;AC024; + JE $$IF204 + + push cs ; set up for insert ;AN024; + pop [insert_ptr_seg] ; (offset set by parse routine) ;AN024; + mov cs:[si],dl ; make it an ASCIIZ string ;AN024; + mov insert_number,dl ; zero out for %0 + mov insert_max,030h ; set length to something reasonable ;AN024; + inc cx ; there's an insert ;AC024; + lea si,SUBLIST ; point to the sublist ;AC024; + +; $endif ; ;AN024; +$$IF204: + + + cmp ah,DOS_Error ; ;AN000; + +; $if be ; if DOS error ;AC019; + JNBE $$IF206 + + call Get_DOS_error ; to find out what message to display ;AN000; + mov dh,DOS_Error ; ensure message type is DOS_Error ;AN019; + +; $endif ; ;AN000; +$$IF206: + + mov bx,STDERR ; set output handle (BX) ;AN000; + + cmp ah,util_C ; is it CLASS C ;AN000; + +; $if e ; CLASS C requires insert ;AN000; + JNE $$IF208 + + inc cx ; load insert required ;AN000; + +; $endif ; ;AN000; +$$IF208: + + cmp ah,util_D ; is it CLASS D ;AN000; + +; $if e ; CLASS D requires response ;AN000; + JNE $$IF210 + + mov dl,DOS_CON_INP ; load response required - con: input ;AN000; + +; $endif ; ;AN000; +$$IF210: + + xor ah,ah ; ;AN000; + + + call SysDispMsg ; to display message ;AN000; + +; $if c,and ; error and............... ;AN000; + JNC $$IF212 + + call SysDispMsg ; to try again : ;AN000; + +; $if c ; if reaaly bad .........: ;AN000; + JNC $$IF212 + + mov ax,return_error ; load error exit code ;AN000; + +; $else ; ;AN000; + JMP SHORT $$EN212 +$$IF212: + + mov ax,success ; load success exit code ;AN000; + +; $endif ; ;AN000; +$$EN212: + + ret ; ;AN000; + + ENDPROC Message + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Get_DOS_Error +;******************************************************************************* +; +;Description: Call DOS to obtain DOS extended error # +; +;Called Procedures: None +; +;Input: None +; +;Output: AX = error number +; +;Change History: Created 5/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Get_DOS_Error +; +; call DOS for extended error (INT21 GetExtendedError + 00 <5900>) +; set up registers for return +; ret +; +; END Get_DOS_Error +; +;******************- END OF PSEUDOCODE -************************************** + + public Get_DOS_Error + + Get_DOS_Error PROC NEAR + + push bx + mov ax,(GetExtendedError shl 8) + not_used ; call DOS for extended error ;AN000; + xor bx,bx + push es ; ;AN000; + INT 21h ; GetExtendedError + not_used <5900>;AN000; + pop es + pop bx ; ;AN000; + xor cx,cx ; reset insert (CX) ;AC024; + + ret ; ;AN000; + + ENDPROC Get_DOS_Error + + CODE ENDS + + include msgdcl.inc + + END START + + \ No newline at end of file diff --git a/v4.0/src/CMD/SYS/SYS2.ASM b/v4.0/src/CMD/SYS/SYS2.ASM new file mode 100644 index 0000000..6c96070 --- /dev/null +++ b/v4.0/src/CMD/SYS/SYS2.ASM @@ -0,0 +1,2622 @@ + TITLE SYS-2- Program + include version.inc + INCLUDE SYSHDR.INC + + page 80,132 + BREAK +;******************+ START OF PSEUDOCODE +************************************** +; Ä Ä Ä Ä Ä Ä Ä Ä¿ ÚÄÄÄÄÄÄÄÄÄ¿ +; Read_Directory ÃÄÄÄÄÄÄ´Find_DPB ³ +; Ä Ä Ä Ä Ä Ä Ä ÄÙ ÀÄÄÄÄÄÄÄÄÄÙ +; Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÄ¿ +; Verify_File_LocationÃÄ¿ +; Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÄÙ ³ +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿ +; ÃÄ´Move_DIR_EntryÃÄÄ´Find_Empty_Entry ÃÄÄ´Direct_Access³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Direct_Access³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄ¿ +; ÀÄ´Free_ClusterÃÄÄÄÄ´Is_It_EmptyÃÄÄÄÄÄÄÄÄ´Unpack ³ +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿ +; ôSearch_FATÃÄÄÄÄÄÄÄÄ´Unpack ³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÙ ³À Ä Ä Ä Ù +; ³ ³ÚÄÄÄÄÄÄ¿ +; ³ ôPack ³ +; ³ ³ÀÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿ +; ³ ôFind_Empty_Cluster³ÄÄ´Unpack ³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù +; ³ ³ÚÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿ +; ³ ôXfer_DataÃÄÄÄÄÄÄÄÄÄÄÄ´Direct_Access³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù +; ³ ³Ú Ä Ä Ä Ä Ä Ä ¿ +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À´Direct_Access³ +; ³ À Ä Ä Ä Ä Ä Ä Ù +; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿ +; À´Search_DIRÃÄÄÄÄ´Search_LoopÃÄÄÄÄÄ´Unpack ³ +; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ³À Ä Ä Ä Ù +; ³ÚÄÄÄÄÄÄ¿ +; ôPack ³ Direct_Access +; ³ÀÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿ +; ôFind_Empty_Cluster³ÄÄ´Unpack ³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿ +; ôSub_DIR_Loop³ÄÄ´Unpack ³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù +; ³ÚÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿ +; ôXfer_DataÃÄÄÄÄÄÄÄÄÄÄÄ´Direct_Access³ +; ³ÀÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù +; ³Ú Ä Ä Ä Ä Ä Ä ¿ +; À´Direct_Access³ +; À Ä Ä Ä Ä Ä Ä Ù +; +;******************+ END OF PSEUDOCODE +***************************************** + BREAK + + DATA SEGMENT PARA PUBLIC + + extrn TargDrvNum:BYTE, TargSpec:WORD, bio_owns_it:BYTE, DOS_VER:BYTE + extrn packet_sectors:WORD, packet_buffer:WORD, packet:WORD + + public THIS_DPB, BUF, DIR_SECTOR, first_dir_sector + + +; $SALUT (4,25,30,41) + +first_dir_sector dw ? +current_dir_sector dw ? +last_dir_sector dw ? +entries_per_sector db ? +current_entry db 3 +source_ptr dw ? +ibmbio_status db ? +ibmdos_status db ? +FAT_sectors dw FAT_sect_size ; initailize it to 12 sectors +FAT_changed db 0 ; FAT must be written - its packed +FAT_2 db 0 ; if non zero, [packet] points at FAT 2 +cluster_count dw ? ; number of clusters that must be free +last_cluster dw 0 ; cluster pointing to [current_cluster] +current_cluster dw 2 ; start at cluster 2 +next_cluster dw 0 ; cluster [current_cluster] points at +empty_cluster dw 0 ; newly aquired cluster +cluster_low dw 0 +cluster_high dw clusters_loaded + +l_sector_offset dw ? ; this is the value required to convert + ; a sector from a cluster # to a + ; logical sector # for INT 25 & 26 + +DIR_cluster dw 0 ; Sub DIR cluster being processed + ; = 0 - not processing s Sub DIR + ; = 1 - starting to process + ; (set by Search_Loop) + ; = n - Sub DIR cluster now being + ; processed. (set by Xfer_Data) +present_cluster dw ? ; current cluster for DIR search +sector_offset dw ? ; current sector in present_cluster +entry_number db ? ; DIR entry in current sector +FRAME_ptr dw ? +dir_sector_low dw ? +dir_sector_hi dw ? +DIR_offset dw ? +sector_count db 1 + +FRAME STRUC + +p_cluster dw ? ; current cluster for DIR search +s_offset dw ? ; current sector in present_cluster +e_number db ? ; DIR entry in current sector + +FRAME ENDS + +BIGFAT DB 0 ;0=12 bit FAT, NZ=16bit FAT +EOFVAL DW 0FF8H ;0FF8 for 12 bit FAT,0FFF8 for 16 bit +BADVAL DW 0FF7H ;0FF7 for 12 bit FAT,0FFF7 for 16 bit + +THIS_DPB DD ? ;Pointer to drive DPB +CSIZE DW ? ;Sectors per cluster +SSIZE DW ? ;bytes per sector +DSIZE DW ? ;# alloc units on disk +FSIZE DW ? ;# sectors in 1 FAT +first_FAT DW ? ; first cluster of first FAT +num_of_FATS db ? ; number of FATS +MCLUS DW ? ;DSIZE + 1 +; +; The following is used as the source/destination for a name trans +; +ENTRY_BUF DB size dir_entry DUP (?) +DIR_BUF DB ( 34 * size frame) DUP (?) ; space for DIR frames - see Search_DIR +DIR_SECTOR DB 512 DUP (?) ; space for 1 DIR sector + +BUF LABEL BYTE ; beginning of area for file reads + + DATA ENDS + +; $SALUT (4,4,9,41) + + CODE SEGMENT PARA PUBLIC + + ASSUME cs:CODE, ds:nothing, es:nothing + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Find_DPB +;******************************************************************************* +; +;Description: Find_DPB gets the pointer to the Target DPB and initializes all +; local valiables required by Move_DIR_Entry and Free_Cluster. +; +;NOTE: This routine contains code that is specific for DOS 3.3. It +; must be removed for subsequent releases. In and before +; DOS 3.3 the DPB was one byte smaller. The field dpb_FAT_size +; was changed from a byte to a word in DOS 4.00. +; +; +;Entry: Called by Verify_File_Location +; +;Called Procedures: +; +; INT 21 - 32h +; +;Input: al = Drive number +; +;Output: All local variables initalized +; DS:BX = pointer to DPB +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Find_DPB +; +; get DPB pointer (INT 21 - 32h) +; initalize first_dir_sector +; initalize current_dir_sector +; initalize current_cluster (0 for root) +; calculate # of clusters required by IBMBIO +; initalize [cluster_count] +; calculate # of dir sectors +; initalize [dir_sectors] +; initalize [current_entry] to #3 +; allocate memory for FAT + 32 DIR frames +; allocate memory for data sectors +; +; ret +; +; END Find_DPB +; +;******************- END OF PSEUDOCODE -************************************** + + + PUBLIC Find_DPB + + Find_DPB PROC NEAR + + MOV AH,GET_DPB ;Get the DPB ;AN004; + INT 21H + + mov ax,(disk_reset shl 8) ; reset the disk to protect all INT 26's + INT 21h ; that follow + + + ; initalize current_entry to #3 + + ASSUME ds:nothing,es:DATA + + MOV WORD PTR [THIS_DPB+2],DS ; ;AN004; + push es ; ;AN004; + pop ds ; ;AN004; + + ASSUME ds:DATA + + mov WORD PTR [THIS_DPB],bx ; ;AN004; + lds bx,[THIS_DPB] ; ;AN004; + + ASSUME ds:nothing + + mov ax,[bx.dpb_sector_size] ; ;AN004; + mov [SSIZE],ax ;Sector size in bytes ;AN004; + + xor ax,ax ; ;AN004; + mov al,[bx.dpb_cluster_mask] ; ;AN004; + inc al ; ;AN004; + mov [CSIZE],ax ;Sectros per cluster ;AN004; + + mov ax,[BX.dpb_first_FAT] ;First sector of FAT ;AN004; + mov [first_FAT],ax ; ;AN004; + + mov al,[BX.dpb_FAT_count] ;Number of FATs ;AN004; + mov [num_of_FATS],al ; ;AN004; + + mov ax,[bx.dpb_max_cluster] ; ;AN004; + mov [MCLUS],ax ;Bound for FAT searching ;AN004; + + cmp ax,4096-10 ;Big or little FAT? ;AN004; +; $if ae ; ;AN004; + JNAE $$IF1 + inc [BIGFAT] ; ;AN004; + mov [EOFVAL],0FFF8h ; ;AN004; + mov [BADVAL],0FFF7h ; ;AN004; +; $endif ; ;AN004; +$$IF1: + dec ax ; ;AN004; + mov [DSIZE],ax ;Total data clusters on disk ;AN004; + + ;-------------------------------------- + ; calculate # of dir sectors and + ; initalize last_dir_sector + ;-------------------------------------- + mov ax,[bx.dpb_root_entries] ; max # of entries in the root ;AN004; + mov cx,size dir_entry ; size of each entry ;AN004; + mul cx ; size of root directory in bytes ;AN004; + ; in AX:DX ;AN004; + mov cx,[SSIZE] ; # of bytes per sector ;AN004; + div cx ; = # of root directory sectors ;AN004; + cmp dx,0 ; any remainder ? ;AN004; +; $if nz ; ;AN004; + JZ $$IF3 + inc ax ; ;AN004; +; $endif ; ;AN004; +$$IF3: + mov [first_dir_sector],ax ; save for last directory sector calc. ;AN004; + + mov ax,[bx.dpb_FAT_size] ;Sectors for one fat ;AN004; + cmp DOS_VER,0 ; running on current version? ;AN019; + +; $if ne ; BANG! - we'er running on DOS 3.3 ;AN019; + JE $$IF5 + ; dpb_FAT_size is only a BYTE + ; so ajust it to a word + xor ah,ah ;AN019; + dec bx ; BACK UP the index into the DPB ;AN019; + mov WORD PTR [THIS_DPB],bx ; save it for later (dpb_next_free) ;AN021; + ; Now everything else lines up ! +; $endif +$$IF5: + + mov [FSIZE],ax ; ;AN004; + + mov ax,[SSIZE] ; ;AN004; + mov cx,SIZE dir_entry ; ;AN004; + div cx ; ;AN004; + dec ax ; first entry number is zero ;AN004; + mov [entries_per_sector],al ; ;AN004; + cmp [BIGFAT],0 ; is it a big fat ? ;AN004; + +; $if e ; if not ;AN004; + JNE $$IF7 + mov ax,[FSIZE] ; ;AN004; + mov [FAT_sectors],ax ; bring it down to the actual size ;AN004; +; $endif ; ;AN004; +$$IF7: + ;-------------------------------------- + ; initalize first_dir_sector + ; and current_dir_sector + ;-------------------------------------- + mov ax,[bx.dpb_dir_sector] ; first dir sector ;AN004; + mov [current_dir_sector],ax ; save it for later ;AN004; + xchg [first_dir_sector],ax ; save it and recover # of dir sectors ;AN004; + + add ax,[first_dir_sector] ; # of last directory sector ;AN004; + mov [l_sector_offset],ax ; ;AN004; + dec ax ; ;AN004; + mov [last_dir_sector],ax ; save it for later ;AN004; + + ret ; ;AN004; + + Find_DPB ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Move_DIR_Entry +;******************************************************************************* +; +;Description: Move_DIR_Entry will move the entry pointed to by the caller into +; the first available location in the root, if one exists. +; +;Entry: Called by Verify_File_Location +; +;Called Procedures: +; +; Find_Empty_Entry - find an available entry +; Direct_Access - do an INT 25 & INT 26 +; +;Input: first_dir_sector +; current_dir_sector +; last_dir_sector +; current_entry +; pointer set to source entry to be moved +; +;Output: CF = 0 - DIR entry moved to first available entry +; CF = 1 - Error, not able to free up entry +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Move_DIR_Entry +; +; set dest = entry_buffer +; save source pointer +; copy input entry to buffer +; if no error and +; call Find_Empty_Entry to find hole in directory +; if no error +; set source to entry_buffer +; set dest to hole pointer +; copy buffer to enpty entry +; if first_dir_sector != current_dir_sector +; set up for write +; call Direct_Access to write it out +; if no error +; set up for first_dir_sector +; set up for read +; call Direct_Access to read it in +; endif +; if no error +; recover source pointer +; null out entry being processed +; set up for write +; call Direct_Access to update the root +; endif +; endif +; +; ret +; +; END Move_DIR_Entry +; +;******************- END OF PSEUDOCODE -************************************** + + + PUBLIC Move_DIR_Entry + + Move_DIR_Entry PROC NEAR + + ASSUME ds:DATA ; must ensure this is true xxxxxxxxxxxxxxxxx + + ; source = source entry (#1 or #2) DS:SI + lea di,ENTRY_BUF ; dest = entry_buffer ;AN004; + mov [source_ptr],si ; save source pointer ;AN004; + mov ax,size dir_entry ; ;AN004; + mov cx,ax ; ;AN004; + rep movsb ; copy directory entry into entry buffer;AN004; + lea si,DIR_SECTOR ; start at beginning of directory ;AN004; + mov di,si ; save start for end calculation ;AN004; + shl ax,1 ; set pointer for current entry to #3 ;AN004; + add ax,si ; ;AN004; + mov si,ax ; ;AN004; + add di,[SSIZE] ; calculate end of directory ;AN004; + call Find_Empty_Entry ; find hole in directory ;AN004; +; $if nc ; if no error and ;AN004; + JC $$IF9 + mov di,si ; dest = hole pointer ;AN004; + lea si,ENTRY_BUF ; source = entry_buffer ;AN004; + mov cx,size dir_entry ; ;AN004; + rep movsb ; copy buffer to DTA ;AN004; + mov ax,[first_dir_sector] ; ;AN004; + cmp ax,[current_dir_sector] ; ;AN004; +; $if ne ; if first_dir_sector != current_dir_sector;AN004; + JE $$IF10 + mov ah,-1 ; set up for write ;AN004; + call Direct_Access ; write it out ;AN004; +; $if nc ; if no error ;AN004; + JC $$IF11 + mov ax,[first_dir_sector] ; set up for first_dir_sector ;AN004; + mov [current_dir_sector],ax ; update current_dir_sector ;AN004; + mov [packet],ax ; ;AN004; + xor ah,ah ; set up for read ;AN004; + call Direct_Access ; read it in ;AN004; +; $endif ; ;AN004; +$$IF11: +; $endif ; ;AN004; +$$IF10: +; $if nc ; if no error ;AN004; + JC $$IF14 + mov si,[source_ptr] ; recover source pointer ;AN004; + mov BYTE PTR [si],deleted ; delete entry being processed ;AN004; + mov BYTE PTR [si.dir_first],0 ; null out cluster # ;AN004; + cmp si,offset DIR_SECTOR ; are we at the first entry ? ;AN010; +; $if e,and ; if so - ;AN010; + JNE $$IF15 + cmp BYTE PTR [si + size DIR_ENTRY],0 ; is second one a null entry? ;AN010; +; $if e ; if so - ;AN010; + JNE $$IF15 + mov BYTE PTR [si + size DIR_ENTRY],deleted ; make it deleted ;AN010; +; $endif ; ;AN010; +$$IF15: + mov ah,-1 ; set up for write ;AN004; + call Direct_Access ; write it out ;AN004; +; $endif ; ;AN004; +$$IF14: +; $endif ; ;AN004; +$$IF9: + + ret ; ;AN004; + + Move_DIR_Entry ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Find_Empty_Entry +;******************************************************************************* +; +;Description: Find_Empty_Entry scans all root directory sectors looking for +; an empty entry. +; +; NOTE; It is assumed that each DIRectory entry is 32 bytes long +; +;Called Procedures: +; +; Direct_Acces - do INT 25 +; +;Input: current_dir_sector +; last_dir_sector +; first_dir_sector in DTA buffer +; DS:SI set for first entry to check +; DS:DI set to end of directory (sector) +; +;Output: success pointer set to hole +; CF = 0 current_entry updated +; current_dir_sector updated +; +; fail message # set +; CF = 1 +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Find_Empty_Entry +; +; search all available sectors +; search for hole (leaves pointer set to the hole) +; leave if empty +; leave if deleted +; advace to next entry +; exitif past end of sector +; set carry +; orelse +; endloop +; clear carry +; save current_entry +; endsrch +; exitif hole found (no CF) +; update current_entry +; orelse +; if not at end (current <= last) +; set for read +; call Direct_Access to read in next sector +; else +; load error message (no room for system files) +; set error (CF) +; endif +; leave if error (CF) +; update current_DIR_sector +; update current_entry +; endif +; endloop +; endsrch +; +; ret +; +; END Find_Empty_Entry +; +;******************- END OF PSEUDOCODE -************************************** + + PUBLIC Find_Empty_Entry + + Find_Empty_Entry PROC NEAR + +; $search ; for sectors available ;AN004; +$$DO19: + ; ;AN004; +; $search ; for hole - this leaves pointer set at;AN004; +$$DO20: + ; the hole ;AN004; + cmp BYTE PTR [si],empty ; empty ? ;AN004; +; $leave e ; ;AN004; + JE $$EN20 + cmp BYTE PTR [si],deleted ; deleted ? ;AN004; +; $leave e ; ;AN004; + JE $$EN20 + add ax,size dir_entry ; advace to next entry ;AN004; + mov si,ax ; ;AN004; + cmp ax,di ; past end of sector ? ;AN004; +; $exitif ae ; at end ;AN004; + JNAE $$IF20 + stc ; set carry ;AN004; +; $orelse ; ;AN004; + JMP SHORT $$SR20 +$$IF20: +; $endloop ; ;AN004; + JMP SHORT $$DO20 +$$EN20: + clc ; clear carry ;AN004; +; $endsrch ; ;AN004; +$$SR20: +; $exitif nc ; hole is found ;AN004; + JC $$IF19 +; $orelse ; ;AN004; + JMP SHORT $$SR19 +$$IF19: + inc [current_dir_sector] ; advance to next sector ;AN004; + mov ax,[current_dir_sector] ; ;AN004; + cmp ax,[last_dir_sector] ; past last_dir_sector ? ;AN004; +; $leave a ; if at end (current <= last) ;AN004; + JA $$EN19 + lea si,DIR_SECTOR ; start at start of next sector ;AN004; + mov [packet],ax ; ;AN004; + xor ah,ah ; set for read ;AN004; + call Direct_Access ; read in next sector ;AN004; +; $if c ; if error ;AN004; + JNC $$IF30 + dec [current_dir_sector] ; restore curren_dir_sector ;AN004; +; $endif ; ;AN004; +$$IF30: +; $leave c ; error ;AN004; + JC $$EN19 + mov ax,si ; reset pointer to start ;AN004; +; $endloop a ; past last_dir_sector ;AN004; + JNA $$DO19 +$$EN19: + mov ax,(util shl 8) + no_room ; set message# and class ;AN004; + stc ; ensure carry still set ;AN004; +; $endsrch ; ;AN004; +$$SR19: + + ret ; ;AN004; + + Find_Empty_Entry ENDP + + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Direct_Access +;******************************************************************************* +; +;Description: Direct_Access +; +;Called Procedures: +; +; INT 25 +; INT 26 +; +;Input: ah = 0 - read +; ah = -1 - write +; +;Output: CF = 0 - Sectors moved +; CF = 1 - Message and class in AX +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Direct_Access +; +; save registers +; if read +; INT 25 +; else +; zero ah +; INT 26 +; endif +; save return flag +; clear stack +; if error +; set message# and class +; endif +; restore registers +; +; ret +; +; END Direct_Access +; +;******************- END OF PSEUDOCODE -************************************** + + public Direct_Access + + Direct_Access PROC NEAR + + push si ; save registers ;AN004; + push bp ; save registers ;AN004; + cmp DOS_VER,0 ; ;AN019; + +; $if e ; ;AN019; + JNE $$IF35 + + mov cx,-1 ; set up for INT ;AN004; + mov bx,offset packet ; ;AN004; + +; $else ; ;AN019; + JMP SHORT $$EN35 +$$IF35: + ; If running on DOS 3.3 the INT 25 + ; interface is: + ; al = drive number + ; bx = buffer for read data + ; cx = # of sectors + ; dx = start sector + mov cx,word ptr [packet_sectors] ; ;AN019; + mov dx,[packet] ; get starting dir sector ;AN019; + mov bx,PACKET_BUFFER[0] ; ;AN019; + +; $endif ; ;AN019; +$$EN35: + + mov al,TargDrvNum ; set up drive number ;AN004; + dec al ; ;AN004; + cmp ah,0 ; ;AN004; +; $if e ; if read ;AN004; + JNE $$IF38 + INT 25h ; INT 25 ;AN004; +; $else ; else ;AN004; + JMP SHORT $$EN38 +$$IF38: + xor ah,ah ; zero ah ;AN004; + INT 26h ; INT 26 ;AN004; +; $endif ; endif ;AN004; +$$EN38: +;; ? ; save return flag ;AN004; + pop ax ; clear stack ;AN004; + pop bp ; ;AN004; + pop si ; ;AN004; + + ret ; ;AN004; + + Direct_Access ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Free_Cluster processor +;******************************************************************************* +; +;Description: IBMBIO MUST have at lease cluster 2 as its first cluster. This +; routine ensures that cluster 2 and any additional clusters (if +; needed) ARE available. If they are chained, their data is copied +; into the first available cluster, and the needed cluster is +; is replaced by this cluster in the FAT +; +;Entry: Called by Verify_File_Location +; +;Called Procedures: +; +; Is_It_Empty - see if Cluster is empty +; Search_FAT - scan FAT to see if the cluster is chained +; Search_DIR - use FAT to walk directories looking for the cluster +; +; NOTES: Check_FAT and Check_DIR will do the processing requred to move +; data out of the cluster and fix up the FAT and the Dir (if needed). +; +;Input: All local DBP values initalized by Get_DPB +; +;Ouput: CF = 0 - Cluster available +; CF = 1 - Cluster not available +; +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Free_Cluster +; +; initialize [cluster_count] +; do until all copies of FAT attempted +; load FAT into memory (INT 25) +; leave if successful +; enddo +; do until [cluster_count] = 0 +; call Is_It_Empty +; if not found and +; if no errors and +; call Search_FAT +; if not found and +; if no errors +; call Search_DIR +; endif +; leave if error +; enddo +; +; ret +; +; END Free_Cluster +; +;******************- END OF PSEUDOCODE -************************************** + + public Free_Cluster + + Free_Cluster PROC NEAR + + mov ax,IBMLOADSIZE ; calculate # of clusters reqd ;AN004; + xor cx,cx ; ;AN004; + mov di,cx ; ;AN004; + dec di ; ;AN004; + mov cx,[CSIZE] ; by IBMLOAD (consecutive clusters ;AN004; + div cl ; for IBMBIO) ;AN004; + cmp ah,0 ; ;AN004; +; $if ne ; ;AN004; + JE $$IF41 + inc al ; ;AN004; + xor ah,ah ; ;AN004; +; $endif ; ;AN004; +$$IF41: + inc ax ; will be decrimenter immediately upon ;AN004; + ; entering complex do below + mov [cluster_count],ax ; save for later ;AN004; + mov ax,[FAT_sectors] ;only read needed sectors ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov cl,[num_of_FATS] ;Number of FATs ;AN004; + mov ax,[first_FAT] ;First sector of FAT ;AN004; + mov [packet],ax ; ;AN004; + mov [packet_buffer],OFFSET BUF ; point to FAT buffer ;AN004; + call Load_FAT ; ;AN004; +; $if nc ; no error so far....... ;AN004; + JC $$IF43 +; $do complex ; ;AN004; + JMP SHORT $$SD44 +$$DO44: + mov [cluster_count],cx ; ;AN004; + call Is_It_Empty ; ;AN004; +; $leave c ; ;AN014; + JC $$EN44 + cmp al,not_found ; ( -1 ?) ;AN004; +; $if e ; if not found ;AN004; + JNE $$IF46 + call Search_FAT ; scan FAT to see if cluster chained ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN46 +$$IF46: + clc ; ;AN004; +; $endif ; ;AN004; +$$EN46: +; $leave c ; ;AN004; + JC $$EN44 + cmp al,not_found ; if still not found ;AN004; +; $if e ; ;AN004; + JNE $$IF50 + call Search_DIR ; scan DIR to see who starts with #2 ;AN004; +; $else ; ;AC013; + JMP SHORT $$EN50 +$$IF50: + clc ; ensure carry is still clear ;AC013; +; $endif ; ;AN004; +$$EN50: +; $leave c ; ;AN004; + JC $$EN44 + inc [current_cluster] ; ;AN004; +; $strtdo ; ;AN004; +$$SD44: + mov cx,[cluster_count] ; ;AN004; +; $enddo LOOP ; ;AN004; + LOOP $$DO44 +$$EN44: +; $endif ; ;AN004; +$$IF43: +; $if c ; ;AN004; + JNC $$IF57 + mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN014; +; $endif ; ;AN004; +$$IF57: + + ret ; ;AN004; + + Free_Cluster ENDP + + public Load_FAT + + Load_FAT PROC NEAR + + lea bx,[packet] ; ;AN004; + +; $search ; ;AN004; +$$DO59: + xchg cx,di ; ;AN004; + push cx ; ;AN004; + push di ; ;AN004; + push dx ; ;AN004; + push bx ; ;AN004; + xor ah,ah ; ;AN004; + mov al,TargDrvNum ; set up drive number ;AN004; + dec al ; ;AN004; + cmp DOS_VER,0 ; if DOS 3.3 ;AN019; + +; $if ne ; load registers for old style INT 25 ;AN019; + JE $$IF60 + mov bx,[packet_buffer] ; ;AN019; + mov cx,[packet_sectors] ; ;AN019; + mov dx,[packet] ; ;AN019; +; $endif ; ;AN019; +$$IF60: + + push bp ; ;AN019; + int 25h ;Read in the FAT ;AN004; + pop ax ;Flags ;AN004; + pop bp ; ;AN019; +; $exitif nc ; error - set up for next fat ;AN004; + JC $$IF59 + add sp,8 ;Clean up stack ;AN004; + mov ax,1 ; ;AN004; +; mov [packet],ax ; reset to first FAT ;AN004; +; $orelse ; ;AN004; + JMP SHORT $$SR59 +$$IF59: + pop bx ; ;AN004; + pop dx ; ;AN004; + pop cx ; ;AN004; + pop di ; ;AN004; + add [packet],dx ; point to start of next FAT ;AN004; + inc [FAT_2] ; ;AN004; +; $endloop LOOP ;Try next FAT ;AN004; + LOOP $$DO59 + mov ax,(util shl 8) + no_room ; set message# and class ;AN004; +; $endsrch ; ;AN004; +$$SR59: + + ret + + Load_FAT ENDP + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Is_It_Empty +;******************************************************************************* +; +;Description: Is_It_Empty looks directly into the FAT to see if a specified +; cluster is allocated. +; +;Entry: Called by Free_Cluster +; +;Called Procedures: +; +; Unpack - unpack a FAT cluster number (CF set on error) +; +;Input: CX = cluster to check +; 12 sectors of FAT in BUF +; +;Output: CF = 0 AL = 0 - cluster 2 found empty +; AL =-1 - not found & no error +; CF = 1 - critical error +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Is_It_Empty +; +; set up for call to Unpack +; set cluster # to [cluster_number] +; call Unpack +; if no error +; if cluster is not empty +; if bad cluster +; set error flag +; else +; if cluster belongs to IBMBIO +; if next cluster is not contiguous +; reset ownership flag +; endif +; set cluster empty (ax = 0) +; else +; save cluster number +; set cluster used (ax = -1) +; endif +; else +; set cluster empty (ax = 0) +; endif +; endif +; +; ret +; +; END Is_It_Empty +; +;******************- END OF PSEUDOCODE -************************************** + + public Is_It_Empty + + Is_It_Empty PROC NEAR + + mov si,[current_cluster] ; set up for call to Unpack ;AN004; + call Unpack ; to find the value ;AN004; +; $if nc ; if no error ;AN004; + JC $$IF66 +; $if nz ; cluster is not empty ;AN004; + JZ $$IF67 + mov ax,di ; ;AN004; + cmp al,bad_sector ; ;AN004; +; $if e ; ;AN004; + JNE $$IF68 + stc ; ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN68 +$$IF68: + cmp [bio_owns_it],0 ; is it owned by IBMBIO ? ;AN004; +; $if ne ; if it is ;AN004; + JE $$IF70 + dec ax ; ;AN004; + cmp ax,[current_cluster] ; ;AN004; +; $if ne ; ;AC011; + JE $$IF71 + dec [bio_owns_it] ; its not the owner form here on ;AC011; +; $endif ; ;AC011; +$$IF71: + xor ax,ax ; ;AN004; + clc ; its IBMBIO's anyway ;AC011; +; $else ; ;AN004; + JMP SHORT $$EN70 +$$IF70: + mov [next_cluster],di ; ;AN004; + xor ax,ax ; reset fail flag ;AN004; + dec ax ; - its not empty ;AN014; +; $endif ; ;AN004; +$$EN70: +; $endif ; ;AN004; +$$EN68: +; $else ; its empty ! ;AN005; + JMP SHORT $$EN67 +$$IF67: + xor ax,ax ; its empty - and no error ;AN014; +; $endif ; ;AN014; +$$EN67: +; $endif ; ;AN004; +$$IF66: + + ret ; ;AN004; + + Is_It_Empty ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Search_FAT +;******************************************************************************* +; +;Description: Search_FAT for a [cluster_number]. If it is listed in the FAT, +; then its chained into a file. The data in the [cluster_number] is +; then buffered, and copied into an empty cluster, and the FAT is +; updated +; +;Called Procedures: +; +; Unpack - to find a FAT entry for a Cluster # +; Pack - to set a FAT entry for a Cluster # +; Find_Empty_Cluster - find an unused cluster +; Xfer_Data - transfere data from one cluster to another +; Direct_Access - absolute disk i/o +; +;Input: FAT in BUF +; [cluster_number] of specified cluster +; +;Output: CF = 0 - AX = 0 if cluster found +; = -1 if cluster not found +; CF = 1 if critical error +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Search_FAT +; +; set cluster # to [cluster_number] +; search till at end of FAT +; call Unpack +; exitif cluster found +; save [last_cluster] +; clear CF +; orelse +; advance to next cluster +; endloop if past last cluster in fat +; set CF +; endsrch +; if cluster found +; call Find_Empty_Cluster +; endif +; +; if empty cluster available and +; +; call Xfer_Data +; +; if no errors +; +; set taget cluster as one pointing to [cluster_number] +; set value to that of empty cluster +; call Pack to update FAT +; set target cluster as [cluster_number] +; set cluster value to empty +; call Pack to update FAT +; set destination to first sector of first FAT +; set count to # of fat sectors +; set up for write +; do until all FATS written +; call Direct_Access +; advace to next FAT (ignore errors) +; enddo +; +; endif +; +; if no errors +; update DPB first cluster and total empty clusters +; endif +; +; ret +; +; END Search_FAT +; +;******************- END OF PSEUDOCODE -************************************** + + public Search_FAT + + Search_FAT PROC NEAR + + mov si,[current_cluster] ; set cluster # to [cluster_number] ;AN004; +; $search ; till at end of FAT ;AN004; +$$DO79: + call Unpack ; ;AN004; +; $leave c ; quit on an error ;AN004; + JC $$EN79 + cmp di,[current_cluster] ; is it [current_cluster] ? ;AN004; +; $exitif e ; it is ;AN004; + JNE $$IF79 + mov [last_cluster],si ; save number for later ;AN004; + xor ax,ax ; ;AN004; + clc ; clear error flag (found) ;AN004; +; $orelse ; ;AN004; + JMP SHORT $$SR79 +$$IF79: + inc si ; advance to next cluster ;AN004; + xor ax,ax ; ;AN004; + dec ax ; ;AN004; + cmp si,[MCLUS] ; at the end ? ;AN004; +; $endloop e ; if past last cluster ;AN004; + JNE $$DO79 +$$EN79: + stc ; ;AN014; +; $endsrch ; ;AN004; +$$SR79: +; $if nc ; if cluster found ;AN004; + JC $$IF85 + call Find_Empty_Cluster ; to move data to ;AN004; +; $endif ; ;AN004; +$$IF85: +; $if nc,and ; empty cluster available and ;AN004; + JC $$IF87 + call Xfer_Data ; to move data to new cluster ;AN004; +; $if nc,and ; no errors ;AN004; + JC $$IF87 + mov si,[last_cluster] ; set target [last_cluster] ;AN004; + mov dx,[empty_cluster] ; set value to [empty_cluster] ;AN004; + call Pack ; to update FAT ;AN004; +; $if nc,and ; no errors ;AN004; + JC $$IF87 + mov si,[empty_cluster] ; set target [empty_cluster] ;AN004; + mov dx,[next_cluster] ; set value to [next_cluster] ;AN004; + call Pack ; to update FAT ;AN004; +; $if nc,and ; no errors ;AN004; + JC $$IF87 + mov si,[current_cluster] ; set target [current_cluster] ;AN004; + xor dx,dx ; set cluster value to empty ;AN004; + call Pack ; to update FAT ;AN004; +; $if nc ; no errors ;AN004; + JC $$IF87 + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; + mov ax,[FSIZE] ; ;AN004; + cmp [FAT_2],0 ; ;AN004; +; $if e ; ;AN004; + JNE $$IF88 + add [packet],ax ; ;AN004; + inc [FAT_2] ; packet points to FAT #2 ;AC006; +; $else ; ;AN004; + JMP SHORT $$EN88 +$$IF88: + sub [packet],ax ; ;AN004; + mov [FAT_2],0 ; reset - packet points to FAT #1 ;AN004; +; $endif ; ;AN004; +$$EN88: + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; + mov [FAT_changed],0 ; FAT now cleared ;AN004; + push es ; update DPB first cluster ;AN004; + mov bx,ds ; ;AN004; + mov es,bx ; ;AN004; + lds bx,[THIS_DPB] ; ;AN004; + + ASSUME ds:nothing,es:DATA + + mov [bx.dpb_next_free],2 ; ;AN004; + mov ax,es ; ;AN004; + mov ds,ax ; ;AN004; + pop es ; ;AN004; + xor ax,ax ; signal success (ax = 0 , cf = 0) ;AN004; + + ASSUME DS:data, es:nothing + +; $endif ; ;AN004; +$$IF87: +; $if c ; ;AN004; + JNC $$IF92 + cmp ax,-1 ; ;AN004; +; $if e ; ;AN004; + JNE $$IF93 + clc ; not a critical error - keep trying ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN93 +$$IF93: + stc ; major problem - critical error ;AN004; +; $endif ; ;AN004; +$$EN93: +; $endif ; ;AN004; +$$IF92: + + ret ; ;AN000; + + Search_FAT ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Find_Empty_Cluster +;******************************************************************************* +; +;Description: Find_Empty_Cluster finds the first available empty cluster +; +;Called Procedures: +; +; Unpack - find next cluster number +; +;Input: none +; +;Output: CF = 0 - empty cluster found (# in [empty_cluster]) +; CF = 1 - no empty clusters (ax = message) +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Find_Empty_Cluster +; +; search till at end of FAT +; call Unpack +; exitif cluster is empty (ZF) +; save empty cluster number +; clear CF +; orelse +; advance to next cluster +; endloop if past last cluster +; load ax message # - no room for sys files +; set CF +; endsrch +; +; ret +; +; END Find_Empty_Cluster +; +;******************- END OF PSEUDOCODE -************************************** + + public Find_Empty_Cluster + + Find_Empty_Cluster PROC NEAR + + mov si,[current_cluster] ; ;AN004; + mov ax,[cluster_count] ; ;AN004; + add si,ax ; look past required space ;AN004; +; $search ; till at end of FAT ;AN004; +$$DO97: + call Unpack ; to convert # to value ;AN004; +; $exitif z ; cluster is empty ;AN004; + JNZ $$IF97 + mov [empty_cluster],si ; save it for later ;AN004; + clc ; clear error flag ;AN004; +; $orelse ; ;AN004; + JMP SHORT $$SR97 +$$IF97: + inc si ; advance to next cluster ;AN004; + cmp si,[MCLUS] ; past the end ? ;AN004; +; $endloop e ; if past last cluster ;AN004; + JNE $$DO97 + stc ; set error flag ;AN004; + mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN014; +; $endsrch ; ;AN004; +$$SR97: + + ret ; ;AN004; + + Find_Empty_Cluster ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Xfer_Data +;******************************************************************************* +; +;Description: Xfer_Data moves the data from [cluster_number] into the cluster +; number passed in ax. +; +;Called Procedures: +; +; Direct_Access - do disk i/o +; +;Input: [current_cluster] +; [empty_cluster] +; +;Output: CF = 0 - data transfered +; CF = 1 - error - message in AX +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Xfer_Data +; +; save active FAT starting sector +; set source to first sector of [current_cluster] +; set count to # of sectors per cluster +; set up for read +; call Direct_Access to read data +; if no errors +; set source to first sector of [empty_cluster] +; set up for write +; call Direct_Access to write data +; endif +; restore Fat starting sector +; set count to FAT_sectors +; set up for read +; call Direct_Access to restore the FAT copy +; +; endif +; +; ret +; +; END Xfer_Data +; +;******************- END OF PSEUDOCODE -************************************** + + public Xfer_Data + + Xfer_Data PROC NEAR + + push [packet] ; save active FAT starting sector ;AN004; + push [packet+2] ; ;AN004; + push [packet_sectors] ; ;AN004; + mov ax,[CSIZE] ; ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov ax,[current_cluster] ; set source to [current_cluster] ;AN004; + call cluster_2_sector ; convert Cluster to sector # ;AN004; + mov [packet],ax ; low sector word ;AN004; + mov [packet+2],dx ; high sector word ;AN004; + xor ah,ah ; set up for read ;AN004; + call Direct_Access ; to read data ;AN004; +; $if nc ; no errors ;AN004; + JC $$IF102 + mov ax,[empty_cluster] ; set destination to [empty_cluster] ;AN004; + cmp [DIR_cluster],0 ; have we just loaded a directory? ;AN007; +; $if ne ; if so - ;AN007; + JE $$IF103 + mov [DIR_cluster],ax ; save the new cluster ;AN007; + lea bx,BUF ; ;AN007; + mov [bx.dir_first],ax ; update the '.' entry start cluster ;AN007; +; $endif ; ;AN007; +$$IF103: + call cluster_2_sector ; conver to logical sector ;AN004; + mov [packet],ax ; low word ;AN004; + mov [packet+2],dx ; high word ;AN004; + xor ah,ah ; set up for write ;AN004; + dec ah ; ;AN004; + call Direct_Access ; to write data ;AN004; +; $endif ; ;AN004; +$$IF102: + pop [packet_sectors] ; ;AN004; + pop [packet+2] ; restore starting sector ;AN004; + pop [packet] ; ;AN004; + xor ah,ah ; set up for read ;AN004; + call Direct_Access ; to restore the FAT copy ;AN004; + + ret ; ;AN004; + + Xfer_Data ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: cluster_2_sector +;******************************************************************************* +; +;Description: cluster_2_sector +; +; +;Called Procedures: +; +; none +; +;Input: AX - cluster number +; +;Output: AX - low word of sector +; DX - high word of sector +; CX - sectors per cluster +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START cluster_2_sector +; +; ret +; +; END cluster_2_sector +; +;******************- END OF PSEUDOCODE -************************************** + + public cluster_2_sector + + cluster_2_sector PROC NEAR + + dec ax ; of [current_cluster] ;AN004; + dec ax ; ;AN004; + mov cx,[CSIZE] ; ;AN004; + mul cx ; ;AN004; + add ax,[l_sector_offset] ; ;AN004; + + ret ; ;AN004; + + cluster_2_sector ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Search_DIR +;******************************************************************************* +; +;Description: Search_DIR walks the directory tree looking for the file that +; starts with [cluster_number]. If found, the data is moved to the +; first empty cluster (if available), and the directory entry is +; updated. +; +; This routine walks the DIR tree by creating a 'FRAME' for each +; Sub DIR it encounters. It saves all the data needed to continue +; the search once the Sub DIR has been checked. +; +; FRAME ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ present_cluster # ³sector_offset ³ entry_number ³ +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; byte 1 2 3 4 +; +; There is space in DIR_BUF for 32 frames (current DOS maximum +; level of nesting). +; +;Called Procedures: +; +; Search_Loop - scan the directory +; +;Input: [current_cluster] - # of cluster to be freed +; +;Output: CF = 0 cluster now available +; CF = 1 error - ax = message # +; +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Search_DIR +; +; set up for first_dir_sector of root DIR +; set up for read +; call Direct_Access to read first root sector +; if no error +; set [current_sector] +; set [sector_count] = #_dir_sectors +; set [current_entry] = 1 +; set [sub_dir_level] = 0 +; do until cluster free (NC) +; call Search_Loop +; if SubDir +; save [current_cluster] in frame +; save [current_sector]in frame +; save [current_entry] in frame +; save [sector_count] in frame +; incriment [sub_dir_level] (frame) +; zero ax +; set error flag (CF) +; else +; if end of DIR (CF + 00) and +; if [dir_count] > 0 +; recover [current_cluster] from frame +; recover [current_sector] from frame +; recover [current_entry] from frame +; recover [sector_count] from frame +; decriment [sub_dir_level] +; zero ax +; set error flag (CF) +; else +; load error message - no room to sys +; endif +; set error flag (CF) (ax = message) +; endif +; leave if error (ax > 0) +; enddo +; endif +; +; ret +; +; END Search_DIR +; +;******************- END OF PSEUDOCODE -************************************** + + public Search_DIR + + Search_DIR PROC NEAR + + mov ax,[first_dir_sector] ; set up for first_dir_sector of root ;AN004; + mov [packet],ax ; ;AN004; + mov [packet+2],0 ; zero out high word ;AN004; + mov [packet_sectors],1 ; only process 1 sector at a time ;AN004; + mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004; + xor ah,ah ; set up for read ;AN004; + call Direct_Access ; to read first root sector ;AN004; +; $if nc,long ; no error ;AN004; + JNC $$XL1 + JMP $$IF106 +$$XL1: + xor ax,ax ; ;AN004; + mov [present_cluster],ax ; set [present_cluster] = 0 (root) ;AN004; + mov [entry_number],al ; set [entry_number] = 0 (first) ;AN004; + mov ax,[first_dir_sector] ; ;AN013; + mov [sector_offset],ax ; set [sector_offset] = [first_dir_sec];AC015; + lea bx,DIR_BUF ; set [FRAME_ptr] = DIR_BUF ;AN004; + mov [FRAME_ptr],bx ; ;AN004; +; $do ; until cluster free (NC) ;AN004; +$$DO107: + call Search_Loop ; ;AN004; +; $leave nc,long ; cluster found and moved ;AN004; + JC $$XL2 + JMP $$EN107 +$$XL2: + cmp ax,0ffffh ; ;AN004; +; $if e ; SubDir ;AN004; + JNE $$IF109 + + ; Search DIR returned with BX pointing + ; to the current entry - now update + ; current_cluster to this SubDIRs first + ; cluster + + mov ax,[bx.dir_first] ; get starting cluster for where we ;AN007; + ; want to go + mov bx,[present_cluster] ; get [present_cluster] for frame ;AN004; + ; (where we were) + mov [present_cluster],ax ; [present_cluster] for next pass ;AN007; + xchg ax,bx ; recover old [present_cluster] ;AN007; + mov bx,[FRAME_ptr] ; get FRAME pointer ;AN004; + mov [bx.p_cluster],ax ; save [present_cluster] in frame ;AN004; + mov ax,[sector_offset] ; save [sector_offset]in frame ;AC015; + mov [bx.s_offset],ax ; ;AC015; + mov al,[entry_number] ; save [entry_number] in frame ;AN004; + mov [bx.e_number],al ; ;AN004; + xor ax,ax ; reset - ;AN007; + mov [sector_offset],ax ; [sector_offset] ;AC015; + mov [entry_number],al ; [entry_number] ;AN007; + add bx,SIZE FRAME ; incriment FRAME pointer ;AN004; + lea ax,DIR_SECTOR ; ;AN004; + cmp ax,bx ; ;AN004; +; $if a ; ;AC007; + JNA $$IF110 + mov [FRAME_ptr],bx ; ;AN004; + clc ; no error ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN110 +$$IF110: + stc ; set error flag (CF) ;AN004; +; $endif ; ;AN004; +$$EN110: +; $else long ; ;AN004; + JMP $$EN109 +$$IF109: + cmp ax,0 ; ;AN004; +; $if e,and,long ; end of DIR (CF + 00) and ;AN004; + JE $$XL3 + JMP $$IF114 +$$XL3: +next_level_down: ; ;AN004; + mov bx,[FRAME_ptr] ; recover FRAME_ptr - but remember ** ;AC007; + ; it points to the next available + ; frame - not the last one - so + sub bx,SIZE FRAME ; move back! ;AN007; + lea ax,DIR_BUF ; ;AN004; + cmp ax,bx ; ;AN004; +; $if be ; as long as there are still FRAMEs ;AC007; + JNBE $$IF114 + mov ax,[bx.p_cluster] ; get [present_cluster] from frame ;AN004; + mov [present_cluster],ax ; ;AN004; + mov ax,[bx.s_offset] ; recover [sector_offset] from frame ;AC015; + mov [sector_offset],ax ; ;AC015; + mov al,[bx.e_number] ; recover [entry_number] from frame ;AN004; + mov [entry_number],al ; ;AN004; + mov [FRAME_ptr],bx ; ;AN004; + + ; Now set up at exactly same point + ; as when SubDIR was entered - + ; advance to next entry + + inc al ; ;AN004; + cmp al,[entries_per_sector] ; ;AN004; +; $if b ; ;AN004; + JNB $$IF115 + inc [entry_number] ; ;AN004; + clc ; no error ;AN004; +; $else ; we've left the sector ;AN004; + JMP SHORT $$EN115 +$$IF115: +if not ibmcopyright + xor al, al + mov [entry_number], al ; shall we start at, say, ENTRY ZERO? Hmmmmm? +endif + mov ax,[present_cluster] ; ;AN004; + cmp ax,0 ; in the root ? ;AN004; +; $if ne ; no ;AN004; + JE $$IF117 + mov si,ax ; ;AN004; + mov [cluster_high],1 ; force Upack to load FAT ;AN004; + mov ax,[FAT_sectors] ; get the size right ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov [packet_buffer],OFFSET BUF ; ;AN004; + call Unpack ; to get next cluster # ;AN004; + mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004; + mov [packet_sectors],1 ; set size back ;AN004; + mov [cluster_high],1 ; ensure that FAT will be ;AN004; + ; re-loaded + + mov ax,di ; check if at end ;AN007; + cmp al,end_cluster ; at the end? ;AN007; +; $if nz ; not at end of line ;AN004; + JZ $$IF118 + mov [present_cluster],di ; save it ;AN004; + clc ; ;AN004; +; $else ; we are at the end of a Sub DIR chain ;AN004; + JMP SHORT $$EN118 +$$IF118: + + ; the following is a best attempt fix + ; to a bad design problem ...... (how + ; to get back a level.....??? + +; SEPT 21 - best solution is to check BEFORE putting the entry in the frame +; (not when taking it off !!! ) + + jmp next_level_down ; ;AN004; + +; $endif ; ;AN004; +$$EN118: +; $else ; yes - in the root ;AN004; + JMP SHORT $$EN117 +$$IF117: + mov ax,[sector_offset] ; ;AC015; + inc ax ; ;AN004; + cmp ax,[l_sector_offset] ; ;AC015; +; $if b ; ;AN004; + JNB $$IF122 + inc [sector_offset] ; ;AN004; +if not ibmcopyright + clc ; no error, continue with loop +endif +; $else ; end of the line ;AN004; + JMP SHORT $$EN122 +$$IF122: + stc ; we failed to find it ;AN004; +; $endif ; ;AN004; +$$EN122: +; $endif ; ;AN004; +$$EN117: +; $endif ; ;AN004; +$$EN115: +; $else ; ;AN004; + JMP SHORT $$EN114 +$$IF114: + stc ; set error flag (CF) ;AN004; +; $endif ; ;AN004; +$$EN114: +; $endif ; ;AN004; +$$EN109: +; $if c ; error ;AN004; + JNC $$IF130 + mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN004; +; $endif ; ;AN004; +$$IF130: +; $leave c ; if error ;AN004; + JC $$EN107 +; $enddo long ; ;AN004; + JMP $$DO107 +$$EN107: +; $endif ; ;AN004; +$$IF106: + + ret ; ;AN004; + + Search_DIR ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Search_Loop +;******************************************************************************* +; +;Description: Search_Loop scans through all entries of all sectors of all +; clusters of a given Directory for a specified cluster +; +;Called Procedures: +; +; Unpack - to find a FAT entry for a Cluster # +; Pack - to set a FAT entry for a Cluster # +; Find_Empty_Cluster - find an unused cluster +; Xfer_Data - transfere data from one cluster to another +; Direct_Access - absolute disk i/o +; +;Input: +; +;Output: CF = 0 found and freed [cluster_number] +; CF = 1 - ax = 0 - at end of directory +; ax = (message + class) - error occured +; ax = -1 - SubDir found +; bx = pointer to current entry +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Search_Loop +; +; search till at end of directory - all clusters checked +; search till at end of sectors - in given cluster +; search till at end of sector - all entries checked +; exitif starting cluster = [cluster_number] +; set up for FAT +; call Find_Empty_Cluster +; if no error and +; call Xfer_Data +; reset for DIR +; if no error +; update dir_first_clust +; set up for write +; call Direct_Access to write out the directory +; endif +; orelse +; leave if entry is a subdirectory (ah = ffh) +; advace to next entry +; zero ax +; endloop if past end of sector +; set fail flag (CF) +; endsrch +; exit if [current_cluster] found (NC) +; orelse +; leave if subdirectory found (CF + FF) +; if sectors left to read +; set up to read +; call Direct_Access to read sector +; else +; set error flag (CF) +; zero ax (end of sectors) +; endif +; endloop if error +; endsrch +; leave if [current_cluster] found (NC) +; leave if SubDir found (CF + FF) +; leave if Error (CF + message) +; get [current_cluster] # +; call Unpack to get next cluster # +; exitif no more clusters +; zero ax (end of clusters) +; set error flag (CF) +; orelse +; convert cluster # to logical sector # +; update [current_sector] +; endloop +; endsrch +; +; ret +; +; END Search_Loop +; +;******************- END OF PSEUDOCODE -************************************** + + public Search_Loop + + Search_Loop PROC NEAR + + mov ax,[present_cluster] ; initailize for search ;AN004; + cmp ax,0 ; ;AN004; +; $if ne ; ;AN004; + JE $$IF135 + call cluster_2_sector ; convert it to a sector ;AN004; + add ax,[sector_offset] ; ;AC015; +; $if c ; ;AN004; + JNC $$IF136 + inc dx ; ;AN004; +; $endif ; ;AN004; +$$IF136: +; $else ; ;AN004; + JMP SHORT $$EN135 +$$IF135: + mov ax,[sector_offset] ;[sector_offset] = current root sector ;AC015; + xor dx,dx ; ;AN004; +; $endif ; ;AN004; +$$EN135: + mov [packet],ax ; ;AN004; + mov [packet+2],dx ; ;AN004; + xor ah,ah ; ;AN004; + call Direct_Access ; to read the DIR ;AN004; + mov al,SIZE dir_entry ; ;AN004; + mov cl,[entry_number] ; ;AN004; + mul cl ; ;AN004; + lea bx,DIR_SECTOR ; ;AN004; + add bx,ax ; BX now points to the DIR entry ;AN004; +; $search ; till at end of directory ;AN004; +$$DO140: + ; - all clusters checked +; $search ; till at end of sectors ;AN004; +$$DO141: + ; - in given cluster +; $search ; till at end of sector ;AN004; +$$DO142: + ; - all entries checked + cmp BYTE PTR [bx],deleted ; make sure the entry is valid !!! ;AN019; +; $if e ; if it is not - ;AN019; + JNE $$IF143 + xor ax,ax ; ;AN019: + mov [bx.dir_first],ax ; zap the starting cluster ;AN019; + mov [bx.dir_attr],al ; zap the attribute ;AN019; +; $endif ; ;AN019; +$$IF143: + mov ax,[bx.dir_first] ; ;AN004; + cmp ax,[current_cluster] ; ;AN004; +; $exitif e,and,long ; starting cluster = [current_cluster] ;AN004; + JE $$XL4 + JMP $$IF142 +$$XL4: + cmp BYTE PTR [bx],deleted ; make sure the entry is valid !!! ;AN007; +; $exitif ne,and,long ; and entry is not deleted ;AN007; + JNE $$XL5 + JMP $$IF142 +$$XL5: + cmp BYTE PTR [bx],dot ; ;AN007; +; $exitif ne,long ; and entry is not a . or .. name ;AN007; + JNE $$XL6 + JMP $$IF142 +$$XL6: + test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN007; +; $if nz ;if entry is a subdirectory ;AN007; + JZ $$IF146 + inc [DIR_cluster] ; signal special processing ;AN007; + ; Xfere_Data will use this later - + ; 0 = not a sub DIR + ; 1 = do Sub DIR processing and + ; update [DIR_cluster] to the + ; same value as [empty_cluster] +; $endif ; ;AN007; +$$IF146: + mov ax,[packet] ; save pointer to this DIR ;AN007; + mov [dir_sector_low],ax ; ;AN007; + mov ax,[packet+2] ; ;AN007; + mov [dir_sector_hi],ax ; ;AN007; + mov [source_ptr],bx ; save pointer ;AN004; + mov [cluster_high],1 ; force Upack to load FAT ;AN004; + mov ax,[FAT_sectors] ; get the size right ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov [packet],1 ; ;AN004; + mov [packet+2],0 ; ;AN004; + mov [packet_buffer],OFFSET BUF ; ;AN004; + call Find_Empty_Cluster ; ;AN004; +; $if nc,and ; no errors so far ;AN004; + JC $$IF148 + mov si,[empty_cluster] ; ;AN004; + mov dx,[next_cluster] ; ;AN004; + call PACK ; ;AN004; +; $if nc,and ; no errors so far ;AN004; + JC $$IF148 + mov si,[current_cluster] ; ;AN004; + xor dx,dx ; make it empty ;AN004; + call PACK ; ;AN004; +; $if nc ; no errors so far ;AN004; + JC $$IF148 + cmp [bigfat],0 ; ;AN004; +; $if ne ; ;AN004; + JE $$IF149 + mov [cluster_high],1 ; ensure that FAT will be updated ;AN004; + call Unpack ; ;AN004; +; $else ; must manualy write out 12 bit FATS ;AN004; + JMP SHORT $$EN149 +$$IF149: + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + mov [packet],1 ; start with the first FAT ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; + mov ax,[FSIZE] ; ;AN004; + add [packet],ax ; advance to second FAT ;AN004; + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; +; $endif ; ;AN004; +$$EN149: +; $endif ; ;AN004; +$$IF148: +; $if nc,and ; no error and ;AN004; + JC $$IF153 + call Xfer_Data ; ;AN004; +; $if nc ; no error ;AN004; + JC $$IF153 + mov ax,[empty_cluster] ; update dir_first_clust ;AN004; + mov bx,[source_ptr] ; recover pointer ;AN004; + mov [bx.dir_first],ax ; ;AN004; + mov [packet_sectors],1 ; set size back ;AN004; + mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004; + mov ax,[dir_sector_low] ; reset DIR sector ;AN007; + mov [packet],ax ; ;AN007; + mov ax,[dir_sector_hi] ; ;AN007; + mov [packet+2],ax ; ;AN007; + xor ah,ah ; set up for write ;AN004; + dec ah ; ;AN004; + call Direct_Access ; to write out the directory ;AN004; +; $if nc,and ; ;AN004; + JC $$IF154 + cmp [DIR_cluster],0 ; is a DIR being processed ? ;AN007; +; $if ne ; ;AN007; + JE $$IF154 + call Sub_DIR_Loop ; update any children ;AN007; +; $endif ; ;AN007; +$$IF154: +; $if nc ; if no errors ;AN007; + JC $$IF156 + mov ax,[FAT_sectors] ;only read needed sectors ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov [packet],1 ; ;AN004; + mov [packet_buffer],OFFSET BUF ; point to FAT buffer ;AN004; + mov [cluster_high],clusters_loaded ; ;AN004; + mov [cluster_low],0 ; ;AN004; + xor cx,cx ; ;AN004; + mov di,cx ; ;AN004; + dec di ; ;AN004; + mov cl,[num_of_FATS] ; ;AN004; + ; ;AN004; + call Load_FAT ; restore FAT ;AN004; + ; ;AN004; + push es ; update DPB first cluster ;AN004; + mov bx,ds ; ;AN004; + mov es,bx ; ;AN004; + lds bx,[THIS_DPB] ; ;AN004; + + ASSUME ds:nothing,es:DATA + + mov [bx.dpb_next_free],2 ; ;AN004; + mov ax,es ; ;AN004; + mov ds,ax ; ;AN004; + pop es ; ;AN004; + + ASSUME DS:data, es:nothing + +; $endif ; ;AN004; +$$IF156: +; $endif ; ;AN004; +$$IF153: +; $orelse ; ;AN004; + JMP SHORT $$SR142 +$$IF142: + xor ax,ax ; get ready in case ----- ;AN007; + cmp BYTE PTR [bx],0 ; at the end of the dir? ;AN007; +; $leave e ; then no point in continuing ;AN007; + JE $$EN142 + dec ax ; get ready in case we fail ;AN004; + test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN004; +; $leave nz, and ;if entry is a subdirectory (ah = ffh) ;AN004; + JZ $$LL161 + cmp byte ptr [bx],dot ; but not a DOT ;AN007; +; $leave ne ; ;AN007; + JNE $$EN142 +$$LL161: + xor ax,ax ; zero ax ;AN004; + add bx,SIZE dir_entry ; advace to next entry ;AN004; + inc [entry_number] ; ;AN004; + cmp bx,OFFSET BUF ; are we out of sector ? ;AN004; +; $endloop ae,long ;if past end of sector ;AN004; + JAE $$XL7 + JMP $$DO142 +$$XL7: +$$EN142: + stc ; set fail flag (CF) ;AN004; +; $endsrch ; ;AN004; +$$SR142: +; $exitif nc ;[current_cluster] found (NC) ;AN004; + JC $$IF141 +; $orelse ; ;AN004; + JMP SHORT $$SR141 +$$IF141: + + ; we have CF = 1 and could have: + ; AX = 0 - + ; AX = 1 to fffe + ; AX = ffff + ; so - leave if anything other than + ; AX = 0 (out of stuff) + +; $leave c,and ; if not out of stuff ;AN004; + JNC $$LL166 + cmp ax,0 ; ;AN009; + stc ; restore carry flag! ;AN007; +; $leave nz ; ------ leave ! ;AN009; + JNZ $$EN141 +$$LL166: + mov ax,[sector_offset] ; ;AC015; + inc ax ; ;AN004; + cmp [present_cluster],0 ; are we in the root? ;AN007; +; $if e ; if so - ;AN004; + JNE $$IF167 + cmp ax,[l_sector_offset] ; use root sectors ;AC013; +; $else ; else - ;AN004; + JMP SHORT $$EN167 +$$IF167: + cmp ax,[CSIZE] ; use sectors per cluster ;AN004; +; $endif ; ;AN004; +$$EN167: +; $if b ; sectors left to read ;AN004; + JNB $$IF170 + add [packet],1 ; advance to the next sector ;AN004; +; $if c ; ;AN004; + JNC $$IF171 + inc [packet+2] ; adjust high word if needed ;AN004; +; $endif ; ;AN004; +$$IF171: + xor ah,ah ; set up to read ;AN004; + mov [entry_number],ah ; ;AN004; + inc [sector_offset] ; ;AN004; + call Direct_Access ; to read sector ;AN004; + lea bx,DIR_SECTOR ; set index to start of sector ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN170 +$$IF170: + xor ax,ax ; zero ax (end of sectors) ;AN004; + stc ; set error flag (CF) ;AN004; +; $endif ; ;AN004; +$$EN170: +; $endloop c,long ; if error ;AN004; + JC $$XL8 + JMP $$DO141 +$$XL8: +$$EN141: +; $endsrch ; ;AN004; +$$SR141: +; $leave nc ; if [current_cluster] found (NC) ;AN004; + JNC $$EN140 +; $leave c,and ;if SubDir found (CF + FF) ;AN004; + JNC $$LL178 + cmp ax,0 ; ;AN004; + stc ; set carry ;AN007; +; $leave nz ; if Error (CF + messageor FFFFh) ;AN004; + JNZ $$EN140 +$$LL178: + + ;-------------------------------------- + ; CF = 1 and AX = 0 means - no critical + ; errors + ; - no Sub DIR + ; found + ; inner SEARCH is out of sectors + ; - so advance to the next cluster + ;-------------------------------------- + mov si,[present_cluster] ; get [present_cluster] # ;AN004; + cmp si,0 ; end of the root ? ;AN004; +; $if nz ; ;AN004; + JZ $$IF179 + mov [cluster_high],1 ; force Upack to load FAT ;AN004; + mov ax,FAT_sectors ; get the size right ;AN004; + mov [packet_sectors],ax ; ;AN004; + mov [packet_buffer],OFFSET BUF ; ;AN004; + call Unpack ; to get next cluster # ;AN004; + mov [packet_sectors],1 ; set size back ;AN004; + mov [cluster_high],1 ; ensure that FAT will be re-loaded ;AN004; + mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004; + mov ax,di ; ;AN007; + cmp al,end_cluster ; ;AN007; +; $endif ; ;AN004; +$$IF179: +; $exitif z ; no more clusters ;AN004; + JNZ $$IF140 + xor ax,ax ; zero ax (end of clusters) ;AN004; + stc ; set error flag (CF) ;AN004; +; $orelse ; ;AN004; + JMP SHORT $$SR140 +$$IF140: + mov [present_cluster],di ; ;AN004; + mov ax,di ; set up for cluster_2_sector ;AN004; + call cluster_2_sector ; convert cluster # to logical sector #;AN004; + mov [packet],ax ; ;AN004; + mov [packet+2],dx ; ;AN004; + xor ax,ax ; ;AN004; + mov [sector_offset],ax ; reset [sector_offset] ;AC015; + mov [entry_number],ah ; reset [entry_number] ;AN004; + call Direct_Access ; to read sector ;AN004; + lea bx,DIR_SECTOR ; set pointer ;AN004; +; $endloop c,long ; end loop if read fails ;AN004; + JC $$XL9 + JMP $$DO140 +$$XL9: +$$EN140: +; $endsrch ; ;AN004; +$$SR140: + + ret ; ;AN004; + + Search_Loop ENDP + + BREAK + +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Sub_DIR_Loop +;******************************************************************************* +; +;Description: Sub_DIR_Loop scans through all entries of a subdirectory looking +; child subdirectories. If found, their parent [dir_first] entries +; (the .. entry) are updated to point to the correct cluster +; +;Called Procedures: +; +; Unpack - to find a FAT entry for a Cluster # +; Direct_Access - absolute disk i/o +; +;Input: [empty_cluster] - new parent Sub DIR cluster # +; [DIR_cluster] - current cluster of DIR being looped +; +;Output: CF = 0 at end of directory +; CF = 1 a read/write error occured +; +;Change History: Created 10/07/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Sub_DIR _Loop +; +; get DIR_cluster +; call cluster_2_sector +; update packet +; set for read +; reset entry pointer +; reset sector count +; call Direct_Access +; if no error +; search till at end of directory - all clusters checked +; search till at end of sectors - in given cluster +; search till at end of sector - all entries checked +; leave if null entry +; if entry is not deleted and +; if this entry is a subdir and +; if this is a true entry and +; save current sector +; save current entry +; get start cluster +; call cluster_2_sector +; set for read +; call Direct_Access +; if no errors and +; update pointer to parent +; set for write +; call Direct_Access +; if no errors and +; recover current sector +; recover current entry +; if no errors +; call Direct_Access +; endif +; exitif error (CF) +; orelse +; advance to next entry +; endloop if past end of sector +; clear error flag +; endsrch +; leave if error +; advance to next sector (packet) +; incriment sector count +; exitif past end of cluster +; clear error flag +; orelse +; reset entry pointer +; set for read +; call Direct_Access +; endloop if error +; endsrch +; leave if error +; get DIR_cluster +; call UNPACK to find next Sub DIR cluster +; exitif at end of chain +; clear error flag +; orelse +; update DIR_cluster +; call cluster_2_sector +; update packet +; set for read +; call Direct_Access +; leave if error +; reset entry pointer +; reset sector count +; endloop +; endsrch +; endif +; reset Sub_DIR_cluster to 0 +; +; ret +; +; END Sub_DIR_Loop +; +;******************- END OF PSEUDOCODE -************************************** + + public Sub_DIR_Loop + + Sub_DIR_Loop PROC NEAR + + mov ax,[DIR_cluster] ; get DIR_cluster ;AN007; + call cluster_2_sector ; to convert to a logical sector ;AN007; + mov [packet],ax ; update packet ;AN007; + mov [packet+2],dx ; ;AN007; + xor ax,ax ; set for read ;AN007; + call Direct_Access ; to read the first sector of the DIR ;AN007; +; $if nc,long ; if no error ;AN007; + JNC $$XL10 + JMP $$IF185 +$$XL10: + mov [sector_count],1 ; reset sector count ;AN007; + lea bx,DIR_SECTOR ; reset entry pointer ;AN007; +; $search ; till at end of directory ;AN007; +$$DO186: + ; - all clusters checked ;AN007; +; $search ; till at end of sectors ;AN007; +$$DO187: + ; - in given cluster ;AN007; +; $search ; till at end of sector ;AN007; +$$DO188: + ; - all entries checked ;AN007; + mov [dir_offset],bx ; reset entry pointer ;AN007; + cmp BYTE PTR [bx],0 ; null entry (00)? ;AN007; +; $leave z ; if null entry ;AN007; + JZ $$EN188 + cmp BYTE PTR [bx],deleted ; deleted entry (E5)? ;AN007; +; $if ne,and ; if entry is not deleted and ;AN007; + JE $$IF190 + test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN007; +; $if nz,and ; if this entry is a subdir and ;AN007; + JZ $$IF190 + cmp BYTE PTR [bx],dot ; dot entry (2E)? ;AN007; +; $if ne,and ; this is a true entry and ;AN007; + JE $$IF190 + mov ax,[packet] ; save current sector ;AN007; + mov [dir_sector_low],ax ; ;AN007; + mov ax,[packet+2] ; ;AN007; + mov [dir_sector_hi],ax ; ;AN007; + mov ax,[bx.dir_first] ; get start cluster ;AN007; + call cluster_2_sector ; convert to sector ;AN007; + mov [packet],ax ; update packet ;AN007; + mov [packet+2],dx ; ;AN007; + xor ax,ax ; set for read ;AN007; + call Direct_Access ; to read it in ;AN007; +; $if nc,and ; no errors and ;AN007; + JC $$IF190 + mov ax,[empty_cluster] ; update pointer to parent ;AN007; + lea bx,DIR_SECTOR ; ;AN007; + mov [bx + dir_first + size dir_entry],ax ; ;AN007; + xor ax,ax ; set for write ;AN007; + dec ax ; ;AN007; + call Direct_Access ; to write it back ;AN007; +; $if nc,and ; if no errors and ;AN007; + JC $$IF190 + mov ax,[dir_sector_low] ; ;AN007; + mov [packet],ax ; recover current sector ;AN007; + mov ax,[dir_sector_hi] ; ;AN007; + mov [packet+2],ax ; ;AN007; +; $if nc ; if no errors ;AN007; + JC $$IF190 + call Direct_Access ; to continue where we left off ;AN007; +; $endif ; ;AN007; +$$IF190: +; $exitif c ; quit if error (CF) ;AN007; + JNC $$IF188 +; $orelse ; ;AN007; + JMP SHORT $$SR188 +$$IF188: + mov bx,[dir_offset] ; recover current entry ;AN007; + add bx,SIZE dir_entry ; advance to next entry ;AN007; + cmp bx,OFFSET BUF ; ;AN007; +; $endloop a ; if past end of sector ;AN007; + JNA $$DO188 +$$EN188: + clc ; clear error flag ;AN007; +; $endsrch ; ;AN007; +$$SR188: +; $leave c ; if error - quit ;AN007; + JC $$EN187 + xor ax,ax ; ;AN007; + mov ax,[CSIZE] ; incriment sector count ;AN007; + inc [sector_count] ; ;AN007; + cmp [sector_count],al ; ;AN007; +; $exitif a ; past end of cluster ;AN007; + JNA $$IF187 + clc ; clear error flag ;AN007; + mov [sector_count],1 ; reset sector count ;AN007; +; $orelse ; ;AN007; + JMP SHORT $$SR187 +$$IF187: + xor ax,ax ; set for read ;AN007; + add WORD PTR [packet],1 ; advance to next sector (packet) ;AN007; + adc [packet+2],ax ; look after carry ;AN007; + call Direct_Access ; to read in next sector ;AN007; + lea bx,DIR_SECTOR ; reset entry pointer ;AN007; +; $endloop c,long ; if error - quit ;AN007; + JC $$XL11 + JMP $$DO187 +$$XL11: +$$EN187: +; $endsrch ; ;AN007; +$$SR187: +; $leave c ; if error - quit ;AN007; + JC $$EN186 + mov si,[DIR_cluster] ; get DIR_cluster ;AN007; + push [packet_sectors] ; save current packet stuff ;AN007; + push [packet_buffer] ; ;AN007; + mov ax,[FAT_sectors] ; update packet to FAT ;AN007; + mov [packet_sectors],ax ; ;AN007; + mov [packet_buffer],OFFSET BUF ; ;AN007; + mov [cluster_high],1 ; force FAT to be reloaded - if needed ;AN007; + call UNPACK ; to find next Sub DIR cluster ;AN007; + pop [packet_buffer] ; recover packet to DIR ;AN007; + pop [packet_sectors] ; ;AN007; + mov ax,di ; ;AN007; + cmp al,end_cluster ; ;AN007; +; $exitif e ; at end of chain ;AN007; + JNE $$IF186 + clc ; clear error flag ;AN007; +; $orelse ; ;AN007; + JMP SHORT $$SR186 +$$IF186: + mov [DIR_cluster],ax ; ;AN007; + call cluster_2_sector ; to convert to sector ;AN007; + mov [packet],ax ; update packet ;AN007; + mov [packet+2],dx ; ;AN007; + xor ax,ax ; set for read ;AN007; + call Direct_Access ; to read first sector of next cluster ;AN007; +; $leave c ; if error ;AN007; + JC $$EN186 + lea bx,DIR_SECTOR ; reset entry pointer ;AN007; + mov [sector_count],1 ; reset sector count ;AN007; +; $endloop long ; ;AN007; + JMP $$DO186 +$$EN186: +; $endsrch ; ;AN007; +$$SR186: +; $endif ; ;AN007; +$$IF185: + mov [DIR_cluster],0 ; reset Sub_DIR_cluster to 0 ;AN007; + + ret ; ;AN007; + + Sub_DIR_Loop ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Unpack +;******************************************************************************* +; +;Description: Read an entry in the FAT +; +;Called Procedures: +; +; Check_FAT - to make sure right part of FAT is loaded (16 bit only) +; +;Input: Cluster number in SI +; +;Output: Return contents in DI +; xX destroyed +; ZF set if cluster is free +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Unpack +; +; if 16 bit FAT +; call Check_FAT +; multiply # by 2 +; read value +; check if empty +; else +; multiply # by 2 +; read value +; if not word alligned +; shift to allign +; endif +; mask off unused portion (set ZF if empty) +; endif +; +; ret +; +; END Unpack +; +;******************- END OF PSEUDOCODE -************************************** + + public Unpack + + Unpack PROC NEAR + + lea bx,BUF ; ;AN004; + mov di,si ; ;AN004; + cmp [BIGFAT],0 ; ;AN004; +; $if nz ; if 16 bit FAT ;AN004; + JZ $$IF208 + push si ; ;AN004; + call Check_FAT ; make sure right part of FAT loaded ;AN004; +; $if nc ; ;AN004; + JC $$IF209 + mov di,si ; Check_FAT ajusts si ;AN004; + shl di,1 ; Mult by 2 ;AN004; + mov di,WORD PTR [di+bx] ; ;AN004; + or di,di ; Set zero ;AN004; + clc ; ;AN004; +; $endif ; ;AN004; +$$IF209: + pop si ; ;AN004; +; $else ; is 12 bit fat ;AN004; + JMP SHORT $$EN208 +$$IF208: + shr di,1 ; ;AN004; + add di,si ; Mult by 1.5 ;AN004; + mov di,WORD PTR [di+bx] ; ;AN004; + test si,1 ; ;AN004; +; $if nz ; not allign on cluster ;AN004; + JZ $$IF212 + shr di,1 ; ;AN004; + shr di,1 ; ;AN004; + shr di,1 ; ;AN004; + shr di,1 ; ;AN004; +; $endif ; ;AN004; +$$IF212: + and di,0FFFh ; ;AN004; +; $endif ; ;AN004; +$$EN208: + + + ret ; ;AN004; + + Unpack ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Pack +;******************************************************************************* +; +;Description: Change an entry in the FAT +; +;Called Procedures: +; +; Check_FAT - to make sure right part of FAT is loaded (16 bit only) +; +;Input: si - cluster number to be packed +; dx - data to be placed in cluster (si) +; +;Output: bx,dx destroyed +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Pack +; +; if 16 bit FAT +; call Check_FAT +; convert cluster # to offset +; add offset of FAT +; store value +; else +; convert cluster # to offset +; add offset of FAT +; recover current entry word +; if not alligned on word boundary +; shift to allign +; mask off value to be replaced (byte) +; else +; mask off value to be replaced (word) +; endif +; combine new value and ballace +; store the entry +; +; ret +; +; END Pack +; +;******************- END OF PSEUDOCODE -************************************** + + public Pack + + Pack PROC NEAR + + lea bx,BUF ; ;AN004; + push si ; ;AN004; + mov di,si ; ;AN004; + cmp [BIGFAT],0 ; ;AN004; +; $if nz ; 16 bit FAT ;AN004; + JZ $$IF215 + call Check_FAT ; make sure the part of the FAT we want;AN004; + ; is loaded & ajust offset to match ;AN004; + shl si,1 ; convert cluster # to offset ;AN004; + add si,bx ; add offset of FAT ;AN004; + mov [si],dx ; store value ;AN004; + mov [FAT_changed],1 ; the fat has been changed ;AN004; +; $else ; its 12 bit FAT ;AN004; + JMP SHORT $$EN215 +$$IF215: + shr si,1 ; ;AN004; + add si,bx ; ;AN004; + add si,di ; ;AN004; + shr di,1 ; ;AN004; + mov di,[si] ; ;AN004; +; $if c ; no alligned ;AN004; + JNC $$IF217 + shl dx,1 ; ;AN004; + shl dx,1 ; ;AN004; + shl dx,1 ; ;AN004; + shl dx,1 ; ;AN004; + and di,0Fh ; ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN217 +$$IF217: + and di,0F000h ; ;AN004; +; $endif ; ;AN004; +$$EN217: + or di,dx ; ;AN004; + mov [si],di ; ;AN004; +; $endif ; ;AN004; +$$EN215: + pop si ; ;AN004; + + ret ; ;AN004; + + Pack ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +;Routine name: Check_FAT +;******************************************************************************* +; +;Description: Check that the protion of the FAT that is referenced in SI +; is presently in memory. +; +; Only 12 sectors of the FAT are kept in memory. If the requested +; cluster does not fall within that range, 12 sectors of the FAT +; are read into memory - the first cluster will contain the entry +; of interest. +; +;Called Procedures: +; +; none +; +;Input: si - cluster number to be checked +; [FAT_changed] = 0 - no need to write out FAT before changing +; = x - must write before reading. +; +; +;Output: appropriate block of FAT in BUF +; si ajusted to match +; NB: BX, DX preserved (for UNPACK) +; +;Change History: Created 7/01/87 FG +; +;******************* END OF SPECIFICATIONS ************************************* +;******************+ START OF PSEUDOCODE +************************************** +; +; START Check_FAT +; +; +; ret +; +; END Check_FAT +; +;******************- END OF PSEUDOCODE -************************************** + + public Check_FAT + + Check_FAT PROC NEAR + + push bx + cmp si,[cluster_low] ; ;AN004; +; $if ae,and ; ;AN004; + JNAE $$IF221 + cmp si,[cluster_high] ; ;AN004; +; $if be ; ;AN004; + JNBE $$IF221 + sub si,[cluster_low] ; ;AN004; +; $else ; the cluster is outside the range + JMP SHORT $$EN221 +$$IF221: + ; of the part of the FAT presently loaded. + ; convert cluster # into sector + offset + ; by dividing the cluster # by # of entries + ; per sector IE: sector = 512 bytes + ; cluster entry = 2 bytes + ; then # of entries/sector = 256 + + cmp [FAT_changed],0 ; ;AN004; +; $if ne ; ;AN004; + JE $$IF223 + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; + mov ax,[FSIZE] ; ;AN004; + cmp [FAT_2],0 ; ;AN004; +; $if e ; ;AN004; + JNE $$IF224 + add [packet],ax ; ;AN004; +; $else ; ;AN004; + JMP SHORT $$EN224 +$$IF224: + sub [packet],ax ; ;AN004; + mov [FAT_2],0 ; packet points to FAT #2 ;AN004; +; $endif ; ;AN004; +$$EN224: + xor ah,ah ; ;AN004; + dec ah ; ;AN004; + call Direct_Access ; write it out - ignore errors ;AN004; + mov [FAT_changed],0 ; FAT now cleared ;AN004; +; $endif ; ;AN004; +$$IF223: + mov ax,si ; ;AN004; + xor cx,cx ; ;AN004; + mov cl,al ; this is a cheap and ;AN004; + mov al,ah ; dirty divide by 256 ;AN004; + xor ah,ah ; ax = result ;AN004; + push ax ; save starting sector ;AN006; + mov si,cx ; cx = remainder ;AN004; + inc ax ; leave room for boot sector ;AN004; + mov [packet],ax ; ;AN004; + mov [packet+2],0 ; ;AN004; + push dx ; ;AN004; + call Direct_Access ; ;AN004; +; $if c ; ;AN004; + JNC $$IF228 + mov ax,[FSIZE] ; ;AN004; + add [packet],ax ; ;AN004; + mov [FAT_2],1 ; packet points to FAT #2 ;AN004; + call Direct_Access ; ;AN004; +; $endif ; ;AN004; +$$IF228: + pop dx ; ;AN004; + pop ax ; recover starting sector ;AN006; +; $if nc ; ;AN004; + JC $$IF230 + xchg al,ah ; convert sector back to cluster ;AN004; + mov [cluster_low],ax ; new bottom of FAT ;AN004; + mov [cluster_high],ax ; ;AN004; + add [cluster_high],clusters_loaded ; new top of FAT ;AN004; +; $endif ; ;AN004; +$$IF230: +; $endif ; ;AN004; +$$EN221: + pop bx + + + ret ; ;AN004; + + Check_FAT ENDP + + CODE ENDS + + END + \ No newline at end of file diff --git a/v4.0/src/CMD/SYS/SYSHDR.INC b/v4.0/src/CMD/SYS/SYSHDR.INC new file mode 100644 index 0000000..896d382 --- /dev/null +++ b/v4.0/src/CMD/SYS/SYSHDR.INC @@ -0,0 +1,427 @@ + page 80,132 +;******************* START OF SPECIFICATIONS *********************************** +; +; MODULE NAME: SYS1.SAL + SYS2.SAL + SYSSR.SAL +; +; DESCRIPTIVE NAME: SYS +; +; FUNCTION: Copies system programs IBMBIO.COM and +; IBMDOS.COM onto a specified media. +; +; ENTRY POINT: +; +; INPUT: +; +; EXIT NORMAL: +; +; EXIT ERROR: +; +; INTERNAL REFERENCES: +; +; ROUTINES: +; +; DATA AREAS: +; +; EXTERNAL REFERENCES: +; +; ROUTINES: +; +; DATA AREAS: +; +; NOTES: Version 4.0 is a MAJOR diversion from all previous versions of DOS. +; +; In all older versions of SYS the target diskette, HAD to meet the +; following criteria in order to be SYSed: +; - there must be enough physical room for IBMBIO and +; IBMDOS. +; - the first data cluster (#2) had to be either not +; used - or owned by IBMBIO allready on the disk +; - The first 2 root DIR entries had to be unused, deleted +; or owned by IBMBIO and IBMDOS. +; +; 4.0 SYS is far less restrictive. +; - there must still be enough physical room for IBMBIO +; and IBMDOS. +; - SYS will free up all required data clusters required +; by IBMBIO. +; - The 2 root DIR entries for IBMDOS and IBMBIO may +; be anywhere in the root. SYS will move entrys +; in order for IBMBIO and IBMDOS to be in their proper +; positions. +; *** NOTE **** - Sys will operate on DOS 3.2, 3.3 and 4.0. +; This has reqired a HARD CODED lower bound - DOS_low +; that is set in this file to 3.20 +; +; REVISION HISTORY: Ax000 Version 4.0 05/01/87 - first release FG +; Ax001 4.0 PTR P324 D Love +; Ax002 4.0 PTR P583 FG +; Ax003 4.0 DCR D4 - sys anything,anywhere FG +; Ax004 4.0 DCR D201 - extended arbib change FG +; Ax005 4.0 PTR P1334 - 1.2 MB + system hang FG +; Ax006 4.0 PTR P1403 - BIO & DOS wrong spots FG +; Ax007 4.0 PTR P1404,5 - DIR search error FG +; Ax008 4.0 PTR P1406 - IOCTL to INT 21-69 FG +; Ax009 4.0 PTR P1637 - full 720KB error FG +; Ax010 4.0 PTR P1764 - single file error FG +; Ax011 4.0 PTR P1772 - IBMBIO cluster chain FG +; Ax012 4.0 PTR P1710 - ASSIGN or SUBST invalid FG +; Ax013 4.0 PTR P1872 - ROOT restoration problem FG +; Ax014 4.0 PTR P1884 - more ROOT problems FG +; Ax015 4.0 PTR P2165 - ROOT DIR above #100h sec.FG +; Ax016 4.0 DCR D304 - change in BOOT.INC FG +; Ax017 4.0 PTR P2356 - HILDA error message FG +; Ax018 4.0 PTR P2769 - no system on default drv FG +; Ax019 4.0 DCR D380 - run on current VER -1 FG +; Ax020 4.0 PTR P3028 - run using PATHGEN FG +; Ax021 4.0 DCR D494 - add "source" & DOS 3.2 FG +; Ax022 4.0 PTR P3728 - wrong network message FG +; Ax023 4.0 DCR D503 - Version is now 4.0 FG +; Ax024 4.0 PTM P3905 - fix parse error format FG +; Ax025 4.0 PTM P4118 - fix message error FG +; +; PRE-VERSION 4.0 HISTORY: +; +; 1.6 05/21/82 Added rev number message +; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP +; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to +; 1.0 1.1 disks. +; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir. +; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0 +; system calls +; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on +; destination because of IBM problem with SYSing to +; unformatted disks which are really formatted. Prints +; NoDest message for ridic IBM reasons, should have a +; better message. +; 1.82 08/12/83 ARR ZIBOed again. Mark fails to check for errors on +; his file I/O. Results in SYS saying system +; transferred when it hasn't been. +; 1.83 09/08/83 EKE Added code to quit if sys called on a drive across +; a net. +; 1.84 09/09/83 CHRISP grabbed against his will to make this stupid +; program write out a boot sector +; 1.85 10/18/83 NP Printf to print messages and it's now an .EXE file +; 1.86 11/8/83 MZ fix hard file output of boot sector +; 1.87 5/1/84 MZ make sys prompt for system disk in default drive. +; 3.20 11/9/84 RS make sys write out a correct boot sector for the +; version of DOS. It grabs the boot sector off the system +; disk and inserts the correct BPB. +; Uses IOCTL Get Device Parms to get BPB for a Hard drive. +; 3.20 08/5/85 RS Allow FAT ID byte of 0F0H for 'strange' media +; layouts. These come about because of /T /N switches in +; FORMAT. +; 3.20 09/16/85 Incorporate tables of filenames to allow system files +; used by other OEMs to be SYSed onto disks formatted on +; other MSDOS systems. Allows the flexibility to replace +; system files for one OEM by system files for another. +; +; +; 3.30 06/04/86 MT removes initial check for IBMBIO and DOS - not needed +; because of later search of dirs +; 3.30 06/16/86 MT only force part of IBMBIO contig - do this by assuming +; contig part smaller than 1.10 BIOS +; 3.30 06/16/86 MT Check diks space for enough room to install BIO and DOS +; +; Label: "The DOS SHARE Utility" +; "Version 4.00 (C) Copyright 1988 Microsoft +; "Licenced Material - Program Property of Microsoft" +; +;******************* END OF SPECIFICATIONS ************************************* + BREAK +;******************+ START OF PSEUDOCODE +************************************** +; +;ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄ¿ +;³ Main ÃÄÄ´Init_Input_OutputÃÄÄÄÄ´SysLoadMsg³ (DOS version check) +;ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Parse_Command_Line³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôValidate_Target_DriveôCheck_Default_Drive³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ôCheck_Target_Drive³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Check_For_Network³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôGet_System_FilesÃÄÄÄÄÄ´Prompt_For_Media³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ôCheck_Removable³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄ¿ +; ³ ôOpen_File³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Fill_Memory³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôCheck_SYS_ConditionsÃÄ´Verify_File_System³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄ Ä Ä Ä Ä Ä Ä Ä ¿ +; ³ ôRead_DirectoryÃÄÄÄÄÄÄÄÄÄ´Prompt_For_Media³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄ Ä Ä Ä Ä Ä Ä Ä Ù +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ôVerify_File_Location³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Determine_Free_SpaceÃÄÄÄ´Get_Cluster³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôDo_SYSÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´Create_SystemÃÄÄÄÄÄÄÄÄÄÄ´Create_File³ +; ³ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄ Ä Ä Ä Ä Ä¿ +; ³ ôFill_Memory³ +; ³ ³ÀÄ Ä Ä Ä Ä ÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Dump_Memory³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôDo_EndÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´Close_Files³ +; ³ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Write_Boot_RecordÃÄÄÄÄÄ´Create_Serial_ID³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄ¿ +; ³ À´FAT_Size³ +; ³ ÀÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; À´Message ÃÄÄÄÄÄÄÄÄÄÄÄÄ´Get_DOS_Error³ +; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; +;******************- END OF PSEUDOCODE -************************************** + BREAK + ;--------------------------------------- + ; NOTE: Structures used by SYS include: + ; + ; find_buf - DTA mapper + ; a_bpb - EBPB struc + ; dir_entry - Directory struc + ; A_DeviceParameters - IOCtl struc + ; BootForm - Boot Rec struc + ;--------------------------------------- + + +; INCLUDE DOSSYM.INC ;also defines version of dos +.xlist +.xcref + INCLUDE DOSSYM.INC +.cref +.list + + +; INCLUDE IOCTL.INC ; Get / Set Device Parameters IOCTL +.xlist +.xcref + INCLUDE IOCTL.INC +.cref +.list + + +; INCLUDE BOOTFORM.INC ; Boot Record Structure +.xlist +.xcref + INCLUDE BOOTFORM.INC +.cref + + +; INCLUDE PATHMAC.INC ; PATH macro for PATHGEN +.xlist +.xcref + INCLUDE PATHMAC.INC +.cref +.list + +IBMJAPVER EQU FALSE ; this and the following are mutually +IBMVER EQU TRUE ; exclusive + +CODE SEGMENT PARA PUBLIC +CODE ENDS + +DATA SEGMENT PARA PUBLIC +DATA ENDS + +; $SALUT (4,25,30,41) + ;-------------------------------------- + ; constants + ;-------------------------------------- + +DOS_low equ 0300h + 20 ; 3 in high reg, 20 in low reg. ;AN023; +not_used equ 0 ; filler for INT 21's +num_2_letter equ 040h ; turn dirve number to letter +dev_local equ 9 ; IOCtl - get device parameters +removable equ 01h ; for testing removeability +net_drive equ 01000h ; for testing net drive +DOS_system_atrib equ 7 ; DOS system file atributes +DOS_volume_atrib equ 8 ; DOS volume label atribute +error_RC equ 1 ; error return code +any_error equ 255 ; mask for detecting errors +success equ 0 ; successful completion of SYS +LSeek_EOF equ 2 ; seek relative to eof +LSeek_Start equ 0 ; seek relative to beginning +old_type_media equ 26 ; DOS extended error - old type media +file_not_found equ 2 ; DOS extended error - file not found +file_spec_length equ 11 ; length of file name +empty equ 0 ; empty directory entry +deleted equ 0E5h ; entry is deleted +SetAtrib equ 01h ; set file attributes +set equ 1 ; set file date and time +BIG_FAT_THRESHOLD equ 4086 ; size break for FAT12 - FAT16 +PRELOAD equ 1 ; normal preload +return_error equ 1 ; SYS return error code +FQ_DOS_DIR_CON_INP equ 07h ; Flush Queue / Direct CON in no echo +hard_drive equ 0F8H ; Media Descriptor for Hard drive +first_drive equ 80H ; first physical hard drive number +noerror equ 0 ; no errors +FAT_sect_size equ 12 ; FAT sector count +dot equ 02Eh ; Sub DIR DOT +bad_sector equ 0F7h ; FAT bad sector mark +end_cluster equ 0FFh ; FAT last cluster mark +not_found equ 0FFh ; current cluster not yet found +cluster_ent_per_sect equ 512/2 ; (bytes/sector) / (bytes/cluster entry) + ; = cluster entries / sector +clusters_loaded equ cluster_ent_per_sect * FAT_sect_size ; = # of cluster + ; entries loaded in 12 sectors. + +FAT_BUF equ 512 * 13 ; This space is used to do a number + ; of tasks. It existes at the START + ; of BUF. It is used as a 1 sector + ; buffer for processing DIR sector + ; manipulation. It is also used to + ; process the FAT. NOTE: a 12 bit fat + ; has a max. of FFFh (4K) entries - or + ; 6K of space - or 12 sectors (512 bytes) + ; an extra 512 bytes is added for safety + + ;---------------------------------------- + ; definition of the MODE bits + ; for an extended open + ;---------------------------------------- + +; BITS DEFINED FOR THE MODE WORD +; FORMAT = 0WF0000CISSS0AAA +; Write ÄÄÄÄÄÄÄÄÄÄÄÙ³ ³³³ ÀÄÄÄ Access code +; 0 = no commit ³ ³³³ 0 = read +; 1 = auto commit ³ ³³³ 1 = write +; ³ ³³³ 2 = read/write +; Fail action ÄÄÄÄÄÄÄÄÄÄÄÄÙ ³³³ 3 = execute +; 0 = INT 24h ³³³ 4 = FCB +; 1 = return error ³³³ +; ³³ÀÄÄÄ Sharing mode +; Code Page support ÄÄÄÄÄÄÄÄÙ³ 0 = compatability +; 0 = validate code page ³ 1 = deny read/write +; 1 = no code page check ³ 2 = deny write +; ³ 3 = deny read +; ³ 4 = deny none +; Inherit +; 0 = pass handle to child +; 1 = no inherit +; +MODE_COM equ 0100000000000000b ; Auto Commit +MODE_NO24 equ 0010000000000000b ; No 24 - return error +MODE_NOCP equ 0000000100000000b ; No 24 - return error +MODE_NOINH equ 0000000010000000b ; No child procees access +; Sharing mode +;MODE_SH_COMP equ 0000000000000000b 0 = compatability +MODE_SH_D_RW equ 0000000000010000b ; 1 = deny read/write +MODE_SH_D_W equ 0000000000100000b ; 2 = deny write +MODE_SH_D_R equ 0000000000110000b ; 3 = deny read +MODE_SH_D_NONE equ 0000000001000000b ; 4 = deny none +; Access code +;MODE_AC_R equ 0000000000000000b 0 = read +MODE_AC_W equ 0000000000000001b ; 1 = write +MODE_AC_RW equ 0000000000000010b ; 2 = read/write +MODE_AC_EXE equ 0000000000000011b ; 3 = execute +MODE_AC_FCB equ 0000000000000100b ; 4 = FCB + +open_mode equ MODE_NO24+MODE_NOCP+MODE_NOINH+MODE_SH_D_RW+ MODE_AC_RW + +;------------------------------------------------- +; Message Skeleton File +;------------------------------------------------- + +;util SYS + +;class 1 + +;use EXTEND15 ; INVALID DRIVE + +;class 2 + +;use PARSE1 ;1 - Too many operands +;use PARSE2 ;2 - Required operand missing + ;3 - Not in switch list provided + ;4 - Not in keyword list provided + ;6 - Out of range specified + ;7 - Not in value list provided + ;8 - Not in string list provided +;use PARSE9 ;9 - Invalid Parameter + +;class A + +;use 1 COMMON1 + +;class B + +;def 7 "No room for system on destination disk",CR,LF ; Old +;def 8 "Ivalid path or System files not found",CR,LF ; New +;use 9 COMMON30 ; System transferred - Old +;def 10 "No system on default drive",CR,LF ; Old +;def 11 "Can not specify default drive",CR,LF ; New +;def 12 "Write failure, diskette unusable",CR,LF ; New +;use 19 COMMON25 ; Invalid path ; New + +;class C + +;use 13 COMMON12 ; Cannot %1 to a Network drive - Old +;def 14 "Insert system disk in drive %1",CR,LF ; Old +;use 15 COMMON19 ; Insert destination disk in drive %1 - Old +;def 16 "Not able to SYS to %1 file system",CR,LF ; New +;use 18 COMMON14 ; Cannot %1 a SUBSTed or ASSIGNed drive - NEW + +;class D + +;use 17 COMMON28 ; Press any key to continue. . . - Old + +;end + + ;---------------------------------------- + ; Message Number Equates + ;---------------------------------------- + +util equ 0ffh ; all Utility messages +DOS_error equ 1 ; DOS error CLASS +PARSE_error equ 2 ; PARSE error CLASS +util_B equ 0bh ; Utility CLASS B messages + ; (plain message) +util_C equ 0ch ; Utility CLASS C messages + ; (insert message) +util_D equ 0dh ; Utility CLASS D messages + ; (wait message) +extended_15 equ 15 ; DOS extended error 15 +reqd_missing equ 2 ; PARSE error 2 + + ; CLASS B + +no_room equ 7 ; No room for system on destination disk Old +system_not_found equ 8 ; Invalid path or System files not found Old +done equ 9 ; System transferred Old +no_sys_on_def equ 10 ; No system on default drive Old +not_on_default equ 11 ; Can not specify default drive New +write_fail equ 12 ; Write failure, diskette unusable New +bad_path equ 19 ; Invalid path + ; CLASS C + +cant_network equ 13 ; Cannot %1 to a Network drive Old +sys_disk equ 14 ; Insert system disk in drive %1 Old +dest_disk equ 15 ; Insert destination disk in drive %1 Old +cant_sys equ 16 ; Not able to SYS to %1 file system New +cant_assign equ 18 ; Cannot %1 a SUBSTed or ASSIGNed drive Old + + ; CLASS D + +press_key equ 17 ; Press any key to continue. . . Change + + BREAK diff --git a/v4.0/src/CMD/SYS/SYSSR.ASM b/v4.0/src/CMD/SYS/SYSSR.ASM new file mode 100644 index 0000000..f54f233 --- /dev/null +++ b/v4.0/src/CMD/SYS/SYSSR.ASM @@ -0,0 +1,82 @@ + INCLUDE SYSHDR.INC + +; include SYSMSG.INC + +.xlist +.xcref + + include SYSMSG.INC ; ;AN000; + +.cref +.list + + MSG_UTILNAME ; ;AN000; + +CODE SEGMENT PARA PUBLIC + +ASSUME CS:CODE,DS:nothing,ES:nothing + + PUBLIC SYSDISPMSG, SYSLOADMSG, SYSPARSE + PUBLIC Data_Space + +;;dcl MSG_SERVICES ; ;AN000; + +; MSG_SERVICES ;AN000; + +.xlist +.xcref + + MSG_SERVICES ; ;AN000; + +.cref +.list + +; MSG_SERVICES + +.xlist +.xcref + + MSG_SERVICES ; ;AN000; + +.cref +.list + + +false = 0 ; ;AN000; + +DateSW equ false ; ;AN000; +TimeSW equ false ; ;AN000; +CmpxSW equ false ; ;AN000; +KeySW equ false ; ;AN000; +QusSW equ false ; ;AN000; +Val1SW equ false ; ;AN000; +Val2SW equ false ; ;AN000; +Val3SW equ false ; ;AN000; +SwSW equ false ; ;AN000; +NumSW equ false ; ;AN000; +CAPSW equ false ; Perform CAPS if specified ;AN000; + + +ASSUME CS:CODE,DS:CODE,ES:nothing + +; include parse.asm + +;xlist +;xcref + +include parse.asm ; ;AN000; + +.cref +.list + +Data_Space LABEL BYTE ; ;AN000; + + + +CODE Ends + +include msgdcl.inc + + End + + \ No newline at end of file -- cgit v1.2.3