     1                                  ;	SCCSID = @(#)util.asm	1.1 85/04/10
     2                                  ;TITLE   UTIL - Handle utilities
     3                                  ;NAME    UTIL
     4                                  ;
     5                                  ; Handle related utilities for MSDOS 2.X.
     6                                  ;
     7                                  ;   pJFNFromHandle  written
     8                                  ;   SFFromHandle    written
     9                                  ;   SFFromSFN       written
    10                                  ;   JFNFree         written
    11                                  ;   SFNFree         written
    12                                  ;
    13                                  ;   Modification history:
    14                                  ;
    15                                  ;       Created: MZ 1 April 1983
    16                                  ;
    17                                  
    18                                  [list -]
    18          ******************       warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi]
    14                              <4> [list -]
    14                              <3> [list -]
     3                              <2> 
     4                              <2> addsection DOSSTART, align=16 PUBLIC class=DOSSTART
     5                              <2> ; (no prior section) ; DOSSTART		ENDS
     6                              <2> 
     7                              <2> addsection DOSSTARTJUMP, align=1 PUBLIC class=START
     8                              <2> ; (no prior section) ; DOSSTARTJUMP		ENDS
     9                              <2> 
    10                              <2> addsection CONSTANTS, align=2 PUBLIC class=CONST
    11                              <2> ; (no prior section) ; CONSTANTS	ENDS
    12                              <2> 
    13                              <2> addsection DATA, align=2 PUBLIC class=DATA
    14                              <2> ; (no prior section) ; DATA		ENDS
    15                              <2> 
    16                              <2> addsection TABLE, align=2 PUBLIC class=TABLE
    17                              <2> ; (no prior section) ; TABLE		ENDS
    18                              <2> 
    19                              <2> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE
    20                              <2> ; (no prior section) ; DOSDATATABLE		ENDS
    21                              <2> 
    22                              <2> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE
    23                              <2> ; (no prior section) ; DOSDATACODE		ENDS
    24                              <2> 
    25                              <2> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA
    26                              <2> 
    27                              <2> addsection LAST, align=16 PUBLIC class=LAST
    28                              <2> ; (no prior section) ; LAST		ENDS
    29                              <2> 
    30                              <2> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST
     8                              <1> 
     9                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
    10                              <1> 
    11                              <1> section LAST
    12                              <1> ; (no prior section) ; LAST		ENDS
    23                                  
    24                                  [list +]
    25                                  section DOSCODECODE
    26                                  [list -]
    26          ******************       warning: out: ... for DOS Version 4.00 ... [-w+user]
    26          ******************       warning: out: BPB.INC... [-w+user]
    26          ******************       warning: out: ... CLONE version build switch on ... [-w+user]
    26          ******************       warning: out: DEVSYM.INC... [-w+user]
    33                                  ;.sall
    34                                  
    35                                  	I_need  CurrentPDB,WORD         ; current process data block location
    36                                  	I_need  SFT_Addr,DWORD          ; pointer to beginning of table
    37                                  	I_Need  PROC_ID,WORD            ; current process ID
    38                                  	I_Need  USER_ID,WORD            ; current user ID
    39                                  %if debug
    40                                  	I_need  BugLev,WORD
    41                                  	I_need  BugTyp,WORD
    42                                  %include "bugtyp.nas"
    43                                  %endif
    44                                  
    45                                  BREAK   <pJFNFromHandle - return pointer to JFN table entry>
    46                                  
    47                                  ;
    48                                  ;   pJFNFromHandle - Given a handle, return the pointer to the JFN location
    49                                  ;       in the user's data space
    50                                  ;   Inputs:     BX - Handle
    51                                  ;   Outputs:    Carry Set
    52                                  ;                   AX has error code
    53                                  ;               Carry reset
    54                                  ;                   ES:DI point to the handle spot
    55                                  ;   Registers modified:
    56                                  ;               If no error, ES:DI, else AX,ES
    57                                  procedure   pJFNFromHandle,NEAR
    57          ******************       warning: proc pJFNFromHandle... [-w+user]
    58                                  	ASSUME  DS:NOTHING,ES:NOTHING,SS:DOSGROUP
    59 00000000 368E06[0000]            	MOV     ES,[ss:CurrentPDB]         ; get user process data block
    60                                   assume es:PSP
    61 00000005 263B1E3200              	CMP     BX,[ES:PDB_JFN_Length]  ; is handle greater than allocated
    62 0000000A 7204                    	JB      JFNAdd                  ; no, get offset
    63                                  	fmt     TypAccess,LevSFN,<"$p: Illegal JFN %x\n">,<BX>
    64 0000000C B006                    	MOV     AL,error_invalid_handle ; appropriate error
    65                                  ReturnCarry:
    66 0000000E F9                      	STC                             ; signal error
    67 0000000F C3                      	return                          ; go back
    68 00000010 26C43E3400              JFNAdd: LES     DI,[ES:PDB_JFN_Pointer] ; get pointer to beginning of table
    69                                   assume es:nothing
    70 00000015 01DF                    	ADD     DI,BX                   ; add in offset
    71                                  ReturnNoCarry:
    72 00000017 F8                      	CLC                             ; no holes
    73 00000018 C3                      	return                          ; bye!
    74                                  EndProc pJFNFromHandle
    75                                  
    76                                  BREAK <SFFromHandle - return pointer (or error) to SF entry from handle>
    77                                  
    78                                  ;
    79                                  ; SFFromHandle - Given a handle, get JFN and then index into SF table
    80                                  ;
    81                                  ;   Input:      BX has handle
    82                                  ;   Output:     Carry Set
    83                                  ;                   AX has error code
    84                                  ;               Carry Reset
    85                                  ;                   ES:DI has pointer to SF entry
    86                                  ;   Registers modified: If error, AX,ES, else ES:DI
    87                                  procedure   SFFromHandle,NEAR
    87          ******************       warning: proc SFFromHandle... [-w+user]
    88                                  	ASSUME  DS:NOTHING,ES:NOTHING,SS:DOSGROUP
    89 00000019 E8E4FF                  	CALL    pJFNFromHandle          ; get jfn pointer
    90 0000001C 72FA                    	retc                            ; return if error
    91 0000001E 26803DFF                	CMP     BYTE PTR [ES:DI],-1     ; unused handle
    92 00000022 7504                    	JNZ     GetSF                   ; nope, suck out SF
    93                                  	fmt     TypAccess,LevSFN,<"$p: Illegal SFN $x:$x\n">,<ES,DI>
    94 00000024 B006                    	MOV     AL,error_invalid_handle ; appropriate error
    95 00000026 EBE6                    	jump    ReturnCarry             ; signal it
    96                                  GetSF:
    97 00000028 53                      	SaveReg <BX>                    ; save handle
    98 00000029 268A1D                  	MOV     BL,BYTE PTR [ES:DI]     ; get SFN
    99 0000002C 30FF                    	XOR     BH,BH                   ; ignore upper half
   100 0000002E E80200                  	CALL    SFFromSFN               ; get real sf spot
   101 00000031 5B                      	RestoreReg  <BX>                ; restore
   102 00000032 C3                      	return                          ; say goodbye
   103                                  EndProc SFFromHandle
   104                                  
   105                                  BREAK <SFFromSFN - index into SF table for SFN>
   106                                  
   107                                  ;
   108                                  ; SFFromSFN - index into SF tables for SFN.
   109                                  ;
   110                                  ;   Input:      BX has SF index
   111                                  ;   Output:     ES:DI points to SF entry
   112                                  ;   Registers modified: ES:DI, BX only
   113                                  procedure   SFFromSFN,NEAR
   113          ******************       warning: proc SFFromSFN... [-w+user]
   114                                  	ASSUME  DS:NOTHING,ES:NOTHING,SS:DOSGROUP
   115 00000033 36C43E[0000]            	LES     DI,[ss:SFT_Addr]           ; get pointer to beginning of table
   116                                  ScanLoop:
   117 00000038 263B5D04                	CMP     BX,[ES:DI + SFCount]      ; is handle in this table?
   118 0000003C 720F                    	JB      GetOffset               ; yes, go grab it
   119 0000003E 262B5D04                	SUB     BX,[ES:DI + SFCount]
   120 00000042 26C43D                  	LES     DI,[ES:DI + SFLink]       ; get next table segment
   121 00000045 83FFFF                  	CMP     DI,-1                   ; end of tables?
   122 00000048 75EE                    	JNZ     ScanLoop                ; no, try again
   123 0000004A F9                      	STC                             ; error...
   124 0000004B EB0D                    	JMP     SHORT Restore           ; go restore
   125                                  GetOffset:
   126 0000004D 50                      	SaveReg <AX>                    ; save AX
   127                                  SF_Entry_struc_size equ sf_entry_struc_size	; NASM port equate
   128 0000004E B83B00                  	MOV     AX,SF_Entry_struc_size        ; put it in a nice place
   129 00000051 F6E3                    	MUL     BL                      ; times size
   130 00000053 01C7                    	ADD     DI,AX                   ; offset by size
   131 00000055 58                      	RestoreReg  <AX>                ; get world back
   132 00000056 83C706                  	ADD     DI,SFTable              ; offset into structure
   133 00000059 F8                      	CLC                             ; no holes
   134                                  Restore:
   135 0000005A C3                      	return                          ; bye!
   136                                  EndProc SFFromSFN
   137                                  
   138                                  BREAK <JFNFree - return a jfn pointer if one is free>
   139                                  
   140                                  ;
   141                                  ; JFNFree - scan through the JFN table and return a pointer to a free slot
   142                                  ;
   143                                  ;   Input:  None.
   144                                  ;   Output: Carry Set
   145                                  ;               AX has error code, BX,ES,DI garbage
   146                                  ;           Carry Reset
   147                                  ;               BX has new handle, ES:DI is pointer to JFN slot
   148                                  ;   Registers modified: As above only.
   149                                  procedure   JFNFree,NEAR
   149          ******************       warning: proc JFNFree... [-w+user]
   150                                  	ASSUME  DS:NOTHING,ES:NOTHING,SS:DOSGROUP
   151 0000005B 31DB                    	XOR     BX,BX                   ; try starting low
   152                                  JFNScan:
   153 0000005D E8A0FF                  	CALL    pJFNFromHandle          ; get the appropriate handle
   154 00000060 7209                    	JC      JFNNone                 ; no more handles
   155 00000062 26803DFF                	CMP     BYTE PTR [ES:DI],-1     ; free?
   156 00000066 7405                    	JZ      JFNFound                ; yes, carry is clear
   157 00000068 43                      	INC     BX                      ; no, next handle
   158 00000069 EBF2                    	JMP     JFNScan                 ; and try again
   159                                  JFNNone:
   160 0000006B B004                    	MOV     AL,error_too_many_open_files
   161                                  JFNFound:
   162 0000006D C3                      	return                          ; bye
   163                                  EndProc JFNFree
   164                                  
   165                                  BREAK <SFNFree - find a free SFN>
   166                                  
   167                                  ;
   168                                  ;   SFNFree - scan through the sf table looking for free entries
   169                                  ;   Inputs:     none
   170                                  ;   Outputs:    Carry Set - AX has error code, BX destroyed
   171                                  ;               Carry Clear - BX has SFN
   172                                  ;                   ES:DI - pointer to SFT
   173                                  ;                   SFT_ref_count is set to 1
   174                                  ;   Registers modified: none
   175                                  
   176                                  Procedure SFNFree,NEAR
   176          ******************       warning: proc SFNFree... [-w+user]
   177                                  	ASSUME  DS:NOTHING,ES:NOTHING,SS:DOSGROUP
   178 0000006E 31DB                    	XOR     BX,BX                   ; start at beginning
   179                                  SFNFreeLoop:
   180 00000070 53                      	SaveReg <BX>                    ; Next call zaps BX
   181 00000071 E8BFFF                  	CALL    SFFromSFN               ; get the potential handle
   182 00000074 5B                      	RestoreReg  <BX>
   183 00000075 7305                    	JNC     SFNCheck                ; no carry, check to see if its free
   184 00000077 B004                    	MOV     AL,error_too_many_open_files    ; appropriate error
   185 00000079 EB42                    	JMP     SFNDone
   186 0000007B 90                      	nop	; identicalise
   187                                  SFNCheck:
   188                                  sf_Ref_Count equ sf_ref_count	; NASM port equate
   189 0000007C 26833D00                	CMP     word [ES:DI + sf_Ref_Count],0  ; free?
   190                                  %IFN DEBUG
   191 00000080 7421                    	JZ      SFNGot                  ; yep, got return him
   192                                  %ELSE
   193                                  	JNZ     NoGot
   194                                  	JMP     SFNGot
   195                                  NoGot:
   196                                  %ENDIF
   197 00000082 26833DFF                	CMP     word [ES:DI + sf_ref_count],sf_busy
   198 00000086 7518                    	JNZ     SFNNext                 ; not marked busy...
   199                                  	fmt     TypAccess,LevSFN,<"$p: SFT $x:$x($x)is busy, owner $x:$x\n">,<ES,DI,BX,[ES:DI].sf_UID,[ES:DI].sf_pid>
   200 00000088 53                      	SaveReg <BX>
   201                                  User_ID equ USER_ID	; NASM port label
   202 00000089 368B1E[0000]            	MOV     BX,[ss:User_ID]
   203 0000008E 26395D2F                	CMP     [ES:DI + sf_UID],BX
   204 00000092 750B                    	JNZ     SFNNextP
   205                                  Proc_ID equ PROC_ID	; NASM port label
   206 00000094 368B1E[0000]            	MOV     BX,[ss:Proc_ID]
   207 00000099 26395D31                	CMP     [ES:DI + sf_PID],BX
   208 0000009D 7405                    	JZ      SFNGotP
   209                                  SFNNextP:
   210                                  	fmt     TypAccess,LevSFN,<"$p: SFT unusable\n">
   211 0000009F 5B                      	RestoreReg  <BX>
   212                                  SFNNext:
   213 000000A0 43                      	INC     BX                      ; no, try next sf number
   214 000000A1 EBCD                    	JMP     SFNFreeLoop             ; and go until it fails
   215                                  SFNGot:
   216 000000A3 53                      	SaveReg <BX>
   217                                  SFNGotP:
   218 000000A4 F8                      	CLC                             ; no error
   219                                  	fmt     TypAccess,LevSFN,<"$p: SFT $x:$x($x) marked busy\n">,<ES,DI,BX>
   220 000000A5 26C705FFFF              	MOV     word [ES:DI + sf_ref_count],sf_busy    ; make sure that this is allocated
   221 000000AA 368B1E[0000]            	MOV     BX,[ss:User_ID]
   222 000000AF 26895D2F                	MOV     [ES:DI + sf_UID],BX
   223 000000B3 368B1E[0000]            	MOV     BX,[ss:Proc_ID]
   224 000000B8 26895D31                	MOV     [ES:DI + sf_PID],BX
   225 000000BC 5B                      	RestoreReg  <BX>
   226                                  SFNDone:
   227 000000BD C3                      	return                          ; bye
   228                                  EndProc SFNFree
   229                                  
   230                                  END
